@stacksjs/ts-cloud 0.7.95 → 0.7.96
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 +55 -55
- package/dist/bin/dashboard-server.js +38 -38
- package/dist/{chunk-xp3txtg9.js → chunk-80apz7eb.js} +12 -2
- package/dist/{chunk-3d4204h1.js → chunk-ws3r73x9.js} +1 -1
- package/dist/deploy/index.js +2 -2
- package/dist/drivers/index.js +1 -1
- package/dist/index.js +2 -2
- package/dist/ui/access-denied.html +2 -2
- package/dist/ui/account/automation.html +3 -3
- package/dist/ui/account/security.html +2 -2
- package/dist/ui/applications/compose.html +4 -4
- package/dist/ui/applications/new.html +2 -2
- package/dist/ui/data/backups.html +4 -4
- package/dist/ui/data/services.html +4 -4
- package/dist/ui/data/volumes.html +4 -4
- package/dist/ui/index.html +4 -4
- package/dist/ui/integrations.html +2 -2
- package/dist/ui/operations/alerts.html +4 -4
- package/dist/ui/operations/configuration.html +4 -4
- package/dist/ui/operations/jobs.html +4 -4
- package/dist/ui/operations/maintenance.html +3 -3
- package/dist/ui/operations/observability.html +4 -4
- package/dist/ui/operations/previews.html +4 -4
- package/dist/ui/operations/queue.html +4 -4
- package/dist/ui/operations/regions.html +4 -4
- package/dist/ui/operations/releases.html +4 -4
- package/dist/ui/operations/workloads.html +4 -4
- package/dist/ui/server/actions.html +3 -3
- package/dist/ui/server/activity.html +2 -2
- package/dist/ui/server/capacity.html +4 -4
- package/dist/ui/server/database.html +4 -4
- package/dist/ui/server/deployments.html +4 -4
- package/dist/ui/server/diagnostics.html +2 -2
- package/dist/ui/server/firewall.html +4 -4
- package/dist/ui/server/fleet.html +4 -4
- package/dist/ui/server/logs.html +4 -4
- package/dist/ui/server/metrics.html +4 -4
- package/dist/ui/server/services.html +2 -2
- package/dist/ui/server/sites.html +4 -4
- package/dist/ui/server/ssh-keys.html +4 -4
- package/dist/ui/server/team.html +4 -4
- package/dist/ui/serverless/alarms.html +3 -3
- package/dist/ui/serverless/data.html +4 -4
- package/dist/ui/serverless/functions.html +3 -3
- package/dist/ui/serverless/logs.html +4 -4
- package/dist/ui/serverless/metrics.html +2 -2
- package/dist/ui/serverless/queues.html +4 -4
- package/dist/ui/serverless/secrets.html +4 -4
- package/dist/ui/serverless/traces.html +4 -4
- package/dist/ui/serverless.html +4 -4
- package/package.json +3 -3
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{createRequire as Ng}from"node:module";var hg=Object.defineProperty;var Rg=(t)=>t;function Sg(t,e){this[t]=Rg.bind(null,e)}var ER=(t,e)=>{for(var r in e)hg(t,r,{get:e[r],enumerable:!0,configurable:!0,set:Sg.bind(e,r)})};var
|
|
1
|
+
import{createRequire as Ng}from"node:module";var hg=Object.defineProperty;var Rg=(t)=>t;function Sg(t,e){this[t]=Rg.bind(null,e)}var ER=(t,e)=>{for(var r in e)hg(t,r,{get:e[r],enumerable:!0,configurable:!0,set:Sg.bind(e,r)})};var gr=(t,e)=>()=>(t&&(e=t(t=0)),e);var Ee=Ng(import.meta.url);import{isAbsolute as jg,join as cR,relative as aJ}from"node:path";function ug(t,e){this[t]=Lg.bind(null,e)}function _R(t){let e=typeof t==="string"?new URL(t):t,{hostname:r,pathname:d}=e;if(r.endsWith(".on.aws")){let _=r.match(/^[^.]+\.lambda-url\.([^.]+)\.on\.aws$/);if(_)return{service:"lambda",region:_[1]};return{service:"",region:""}}if(r.endsWith(".r2.cloudflarestorage.com"))return{service:"s3",region:"auto"};if(r.endsWith(".backblazeb2.com")){let _=r.match(/^(?:[^.]+\.)?s3\.([^.]+)\.backblazeb2\.com$/);if(_)return{service:"s3",region:_[1]};return{service:"",region:""}}let E=r.replace("dualstack.","").match(/([^.]+)\.(?:([^.]+)\.)?amazonaws\.com(?:\.cn)?$/);if(!E)return{service:"",region:""};let n=E[1],c=E[2]||"";if(c==="us-gov")c="us-gov-west-1";else if(c==="s3"||c==="s3-accelerate")c="us-east-1",n="s3";else if(n==="iot")if(r.startsWith("iot."))n="execute-api";else if(r.startsWith("data.jobs.iot."))n="iot-jobs-data";else n=d==="/mqtt"?"iotdevicegateway":"iotdata";else if(n==="autoscaling");else if(!c&&n.startsWith("s3-"))c=n.slice(3).replace(/^fips-|^external-1/,""),n="s3";else if(n.endsWith("-fips"))n=n.slice(0,-5);else if(c&&/-\d$/.test(n)&&!/-\d$/.test(c))[n,c]=[c,n];return n=ju[n]||n,{service:n,region:c||"us-east-1"}}function TR(t){let{method:e,url:r,body:d="",accessKeyId:E,secretAccessKey:n,sessionToken:c,signQuery:_=!1,expiresIn:T=86400,datetime:i}=t,h=new URL(r),R=h.hostname,N=_R(h),A=t.service||N.service,u=t.region||N.region;if(!A)throw Error("Could not detect service from URL. Please provide service explicitly.");if(!u)throw Error("Could not detect region from URL. Please provide region explicitly.");let f=i||new Date().toISOString().replace(/[:-]|\.\d{3}/g,""),w=f.substring(0,8),I=[w,u,A,"aws4_request"].join("/"),a="AWS4-HMAC-SHA256";if(_)return lg({urlObj:h,method:e,body:d,accessKeyId:E,secretAccessKey:n,sessionToken:c,service:A,region:u,timestamp:f,date:w,credentialScope:I,algorithm:a,expiresIn:T,cache:t.cache});let P=h.pathname||"/",j=TT(h.searchParams),H={host:R,"x-amz-date":f,...t.headers};if(c)H["x-amz-security-token"]=c;let F=Object.keys(H).some(($)=>$.toLowerCase()==="content-type");if(d&&!F)H["content-type"]="application/x-amz-json-1.0";if(A==="s3"&&!H["x-amz-content-sha256"])H["x-amz-content-sha256"]=jc(d);let B=Uu(H),Z=wu(H),o=H["x-amz-content-sha256"]||jc(d),tt=[e,iT(P),j,B,Z,o].join(`
|
|
2
2
|
`),q=jc(tt),ht=[a,f,I,q].join(`
|
|
3
3
|
`),Et=t.cache??AE,It=$u(n,w,u,A,ht,Et),ft=[`${a} Credential=${E}/${I}`,`SignedHeaders=${Z}`,`Signature=${It}`].join(", ");return H.authorization=ft,{url:r,method:e,headers:H,body:d||void 0}}async function iR(t){let{method:e,url:r,body:d="",accessKeyId:E,secretAccessKey:n,sessionToken:c,signQuery:_=!1,expiresIn:T=86400,datetime:i}=t,h=new URL(r),R=h.hostname,N=_R(h),A=t.service||N.service,u=t.region||N.region;if(!A)throw Error("Could not detect service from URL. Please provide service explicitly.");if(!u)throw Error("Could not detect region from URL. Please provide region explicitly.");let f=i||new Date().toISOString().replace(/[:-]|\.\d{3}/g,""),w=f.substring(0,8),I=[w,u,A,"aws4_request"].join("/"),a="AWS4-HMAC-SHA256";if(_)return Ig({urlObj:h,method:e,body:d,accessKeyId:E,secretAccessKey:n,sessionToken:c,service:A,region:u,timestamp:f,date:w,credentialScope:I,algorithm:a,expiresIn:T,cache:t.cache});let P=h.pathname||"/",j=TT(h.searchParams),H={host:R,"x-amz-date":f,...t.headers};if(c)H["x-amz-security-token"]=c;let F=Object.keys(H).some((W)=>W.toLowerCase()==="content-type");if(d&&!F)H["content-type"]="application/x-amz-json-1.0";let B=await dT(d);if(A==="s3"&&!H["x-amz-content-sha256"])H["x-amz-content-sha256"]=B;let Z=Uu(H),o=wu(H),tt=H["x-amz-content-sha256"]||B,q=[e,iT(P),j,Z,o,tt].join(`
|
|
4
4
|
`),ht=await dT(q),Et=[a,f,I,ht].join(`
|
|
@@ -2749,7 +2749,7 @@ catch (error) {
|
|
|
2749
2749
|
|
|
2750
2750
|
return { statusCode: 200, body: 'OK' };
|
|
2751
2751
|
};
|
|
2752
|
-
`,Vg,Kg,Rn,Zg,lR,IR,$H,yH,XH,aH,PH,jH,zH,FH,BH,JH;var Ht=
|
|
2752
|
+
`,Vg,Kg,Rn,Zg,lR,IR,$H,yH,XH,aH,PH,jH,zH,FH,BH,JH;var Ht=gr(async()=>{Ag=Object.defineProperty;Cg={};NE(Cg,{signRequestAsync:()=>iR,signRequest:()=>TR,parseXMLResponse:()=>gg,parseJSONResponse:()=>$g,makeAWSRequestOnce:()=>Ug,makeAWSRequestAsync:()=>wg,makeAWSRequest:()=>au,isWebCryptoAvailable:()=>Pg,isNodeCryptoAvailable:()=>ag,getSigningKeyCacheSize:()=>Xg,detectServiceRegion:()=>_R,createPresignedUrlAsync:()=>fg,createPresignedUrl:()=>Dg,clearSigningKeyCache:()=>yg});hT=Og(async()=>{try{Sn=await import("node:crypto")}catch{}AE=new Map,ju={appstream2:"appstream",cloudhsmv2:"cloudhsm",email:"ses",marketplace:"aws-marketplace",mobile:"AWSMobileHubService",pinpoint:"mobiletargeting",queue:"sqs","git-codecommit":"codecommit","mturk-requester-sandbox":"mturk-requester","personalize-runtime":"personalize"}});rT={Ref:(t)=>({Ref:t}),GetAtt:(t,e)=>({"Fn::GetAtt":[t,e]}),Sub:(t,e)=>{if(e)return{"Fn::Sub":[t,e]};return{"Fn::Sub":t}},Join:(t,e)=>({"Fn::Join":[t,e]}),Select:(t,e)=>({"Fn::Select":[t,e]}),Split:(t,e)=>({"Fn::Split":[t,e]}),GetAZs:(t="")=>({"Fn::GetAZs":t}),ImportValue:(t)=>({"Fn::ImportValue":t}),If:(t,e,r)=>({"Fn::If":[t,e,r]}),Equals:(t,e)=>({"Fn::Equals":[t,e]}),And:(...t)=>({"Fn::And":t}),Or:(...t)=>({"Fn::Or":t}),Not:(t)=>({"Fn::Not":[t]}),Base64:(t)=>({"Fn::Base64":t})};vr=class vr{static createDistribution(t){let{slug:e,environment:r,origin:d,customDomain:E,certificateArn:n,errorPages:c,cachePolicy:_,edgeFunctions:T,http3:i=!1,comment:h}=t,R=Yr({slug:e,environment:r,resourceType:"cdn"}),N=ir(R),A={Id:"DefaultOrigin",DomainName:d.domainName,OriginPath:d.originPath||""},u;if(d.type==="s3"){let w=`${N}OAC`;u={Type:"AWS::CloudFront::OriginAccessControl",Properties:{OriginAccessControlConfig:{Name:`${R}-oac`,Description:`Origin Access Control for ${R}`,OriginAccessControlOriginType:"s3",SigningBehavior:"always",SigningProtocol:"sigv4"}}},A.OriginAccessControlId=rT.Ref(w)}else if(d.type==="alb"||d.type==="custom")A.CustomOriginConfig={HTTPPort:80,HTTPSPort:443,OriginProtocolPolicy:"https-only"};let f={Type:"AWS::CloudFront::Distribution",Properties:{DistributionConfig:{Enabled:!0,Comment:h||`CDN for ${R}`,DefaultRootObject:"index.html",Origins:[A],DefaultCacheBehavior:{TargetOriginId:"DefaultOrigin",ViewerProtocolPolicy:"redirect-to-https",AllowedMethods:["GET","HEAD","OPTIONS"],CachedMethods:["GET","HEAD","OPTIONS"],Compress:!0},PriceClass:"PriceClass_100",HttpVersion:i?"http2and3":"http2"}}};if(E&&n)f.Properties.DistributionConfig.Aliases=[E],f.Properties.DistributionConfig.ViewerCertificate={AcmCertificateArn:n,SslSupportMethod:"sni-only",MinimumProtocolVersion:"TLSv1.2_2021"};if(c&&c.length>0)f.Properties.DistributionConfig.CustomErrorResponses=c.map((w)=>({ErrorCode:w.errorCode,ResponseCode:w.responseCode,ResponsePagePath:w.responsePagePath}));if(T&&T.length>0)f.Properties.DistributionConfig.DefaultCacheBehavior.LambdaFunctionAssociations=T.map((w)=>({EventType:w.event,LambdaFunctionARN:w.functionArn}));return{distribution:f,originAccessControl:u,logicalId:N}}static setCustomDomain(t,e,r){return t.Properties.DistributionConfig.Aliases=[e],t.Properties.DistributionConfig.ViewerCertificate={AcmCertificateArn:r,SslSupportMethod:"sni-only",MinimumProtocolVersion:"TLSv1.2_2021"},t}static setErrorPages(t,e){return t.Properties.DistributionConfig.CustomErrorResponses=e.map((r)=>({ErrorCode:r.errorCode,ResponseCode:r.responseCode,ResponsePagePath:r.responsePagePath})),t}static enableHttp3(t){return t.Properties.DistributionConfig.HttpVersion="http2and3",t}static addEdgeFunction(t,e,r){if(!t.Properties.DistributionConfig.DefaultCacheBehavior.LambdaFunctionAssociations)t.Properties.DistributionConfig.DefaultCacheBehavior.LambdaFunctionAssociations=[];return t.Properties.DistributionConfig.DefaultCacheBehavior.LambdaFunctionAssociations.push({EventType:e,LambdaFunctionARN:r}),t}static setCachePolicy(t,e){return t.Properties.DistributionConfig.Comment=`${t.Properties.DistributionConfig.Comment||""} (TTL: ${e.default||86400}s)`,t}static createSpaDistribution(t){return vr.createDistribution({...t,errorPages:[{errorCode:404,responseCode:200,responsePagePath:"/index.html"},{errorCode:403,responseCode:200,responsePagePath:"/index.html"}]})}static createDocsOriginRequestFunction(t){let{slug:e,environment:r}=t,d=Yr({slug:e,environment:r,resourceType:"edge-docs"}),E=ir(d),n=ir(`${d}-role`),c=ir(`${d}-version`),_={Type:"AWS::IAM::Role",Properties:{RoleName:`${d}-role`,AssumeRolePolicyDocument:{Version:"2012-10-17",Statement:[{Effect:"Allow",Principal:{Service:["lambda.amazonaws.com","edgelambda.amazonaws.com"]},Action:"sts:AssumeRole"}]},ManagedPolicyArns:["arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"]}},T=`
|
|
2753
2753
|
'use strict';
|
|
2754
2754
|
|
|
2755
2755
|
exports.handler = async (event) => {
|
|
@@ -3938,11 +3938,11 @@ async function sendFallbackSms(to, message) {
|
|
|
3938
3938
|
};
|
|
3939
3939
|
}
|
|
3940
3940
|
`;static createMediaBucket(t){return{[`${t.slug}MmsMediaBucket`]:{Type:"AWS::S3::Bucket",Properties:{BucketName:`${t.slug}-mms-media`,LifecycleConfiguration:{Rules:[{Id:"DeleteOldMedia",Status:"Enabled",ExpirationInDays:30}]},CorsConfiguration:{CorsRules:[{AllowedOrigins:["*"],AllowedMethods:["GET"],AllowedHeaders:["*"],MaxAge:3600}]}}}}}static createMmsSenderLambda(t){return{[`${t.slug}MmsSenderLambda`]:{Type:"AWS::Lambda::Function",Properties:{FunctionName:`${t.slug}-mms-sender`,Runtime:"nodejs20.x",Handler:"index.handler",Role:t.roleArn,Timeout:60,MemorySize:512,Code:{ZipFile:lR.MmsSenderCode},Environment:{Variables:{MEDIA_BUCKET:t.mediaBucket,MESSAGE_LOG_TABLE:t.messageLogTable,ORIGINATION_NUMBER:t.originationNumber||""}}}}}}static SupportedMediaTypes={image:["image/jpeg","image/png","image/gif"],video:["video/mp4","video/3gpp"],audio:["audio/mpeg","audio/wav"]};static MediaSizeLimits={image:1048576,video:5242880,audio:1048576}};IR=class IR{static ChatbotProcessorCode=["const { DynamoDBClient, GetItemCommand, PutItemCommand, UpdateItemCommand, ScanCommand } = require('@aws-sdk/client-dynamodb');","const { BedrockRuntimeClient, InvokeModelCommand } = require('@aws-sdk/client-bedrock-runtime');","const { SNSClient, PublishCommand } = require('@aws-sdk/client-sns');","","const dynamodb = new DynamoDBClient({});","const bedrock = new BedrockRuntimeClient({});","const sns = new SNSClient({});","","const SESSIONS_TABLE = process.env.SESSIONS_TABLE;","const RULES_TABLE = process.env.RULES_TABLE;","const CHATBOT_CONFIG = JSON.parse(process.env.CHATBOT_CONFIG || '{}');","","exports.handler = async (event) => {"," console.log('Chatbot event:', JSON.stringify(event, null, 2));"," for (const record of event.Records) {"," try {"," const message = JSON.parse(record.Sns?.Message || record.body || '{}');"," const { originationNumber, messageBody } = message;"," if (!originationNumber || !messageBody) continue;"," const response = await processMessage(originationNumber, messageBody.trim());"," await sendResponse(originationNumber, response);"," } catch (error) {"," console.error('Error:', error);"," }"," }"," return { statusCode: 200 };","};","","async function processMessage(phoneNumber, message) {"," const rules = await getRules();"," const lowerMessage = message.toLowerCase();"," for (const rule of rules) {"," for (const pattern of rule.patterns) {"," if (new RegExp(pattern, 'i').test(lowerMessage)) {"," return rule.response;"," }"," }"," }"," return CHATBOT_CONFIG.fallbackMessage || 'Sorry, I did not understand. Please try again.';","}","","async function getRules() {"," const result = await dynamodb.send(new ScanCommand({ TableName: RULES_TABLE }));"," return (result.Items || []).map(item => ({"," patterns: JSON.parse(item.patterns?.S || '[]'),"," response: item.response?.S || '',"," })).sort((a, b) => (a.priority || 0) - (b.priority || 0));","}","","async function sendResponse(phoneNumber, message) {"," await sns.send(new PublishCommand({"," PhoneNumber: phoneNumber,"," Message: message.substring(0, 1600),"," MessageAttributes: {"," 'AWS.SNS.SMS.SMSType': { DataType: 'String', StringValue: 'Transactional' },"," },"," }));","}"].join(`
|
|
3941
|
-
`);static createSessionsTable(t){return{[`${t.slug}ChatbotSessionsTable`]:{Type:"AWS::DynamoDB::Table",Properties:{TableName:`${t.slug}-chatbot-sessions`,BillingMode:"PAY_PER_REQUEST",AttributeDefinitions:[{AttributeName:"phoneNumber",AttributeType:"S"}],KeySchema:[{AttributeName:"phoneNumber",KeyType:"HASH"}],TimeToLiveSpecification:{AttributeName:"ttl",Enabled:!0}}}}}static createRulesTable(t){return{[`${t.slug}ChatbotRulesTable`]:{Type:"AWS::DynamoDB::Table",Properties:{TableName:`${t.slug}-chatbot-rules`,BillingMode:"PAY_PER_REQUEST",AttributeDefinitions:[{AttributeName:"id",AttributeType:"S"}],KeySchema:[{AttributeName:"id",KeyType:"HASH"}]}}}}static createChatbotProcessorLambda(t){return{[`${t.slug}ChatbotProcessorLambda`]:{Type:"AWS::Lambda::Function",Properties:{FunctionName:`${t.slug}-chatbot-processor`,Runtime:"nodejs20.x",Handler:"index.handler",Role:t.roleArn,Timeout:30,MemorySize:256,Code:{ZipFile:IR.ChatbotProcessorCode},Environment:{Variables:{SESSIONS_TABLE:t.sessionsTable,RULES_TABLE:t.rulesTable,CHATBOT_CONFIG:JSON.stringify(t.chatbotConfig),ORIGINATION_NUMBER:t.originationNumber||""}}}}}}static DefaultRules=[{id:"greeting",priority:1,patterns:["^(hi|hello|hey|howdy)$","^good (morning|afternoon|evening)"],response:"Hello! How can I help you today?"},{id:"help",priority:2,patterns:["^help$","what can you do","how does this work"],response:"I can help with: 1) Account info 2) Support 3) Hours. Reply with a number."},{id:"hours",priority:3,patterns:["hours","open","when are you"],response:"We are open Mon-Fri 9am-5pm EST. Closed weekends."},{id:"thanks",priority:4,patterns:["^(thanks|thank you|thx)"],response:"You're welcome! Is there anything else I can help with?"},{id:"bye",priority:5,patterns:["^(bye|goodbye|quit|exit|stop)$"],response:"Goodbye! Text us anytime if you need help.",action:"end"}]};$H=new jO;yH=new zO;XH=new FO;aH=new BO,PH=(()=>{let t=[];for(let e=0;e<256;e++){let r=e;for(let d=0;d<8;d++)r=r&1?3988292384^r>>>1:r>>>1;t[e]=r>>>0}return t})();jH=new HO;zH=new WO;FH=new vO;BH=new QO;JH=new YO});class B0{customEntities={};useHtmlEntities;constructor(t=!1){this.useHtmlEntities=t}addEntity(t,e){this.customEntities[t]=e}decodeEntities(t){let e=t.indexOf("&");if(e===-1)return t;let r=t.length,d="",E=0;while(e!==-1&&e<r){if(e>E)d+=t.substring(E,e);let n=t.indexOf(";",e+1);if(n===-1||n-e>32){d+="&",E=e+1,e=t.indexOf("&",E);continue}let c=t.substring(e+1,n);if(c.charCodeAt(0)===35){let _=c.length,T=0,i=!1;if(_>2&&(c.charCodeAt(1)===120||c.charCodeAt(1)===88)){i=!0;for(let h=2;h<_;h++){let R=c.charCodeAt(h);if(R>=48&&R<=57)T=T<<4|R-48;else if(R>=65&&R<=70)T=T<<4|R-55;else if(R>=97&&R<=102)T=T<<4|R-87;else{i=!1;break}}}else if(_>1){i=!0;for(let h=1;h<_;h++){let R=c.charCodeAt(h);if(R>=48&&R<=57)T=T*10+(R-48);else{i=!1;break}}}if(i)d+=String.fromCodePoint(T);else d+=t.substring(e,n+1)}else{let _=this.customEntities[c];if(_===void 0){let T=c.length;if(T>=2&&T<=4){let i=c.charCodeAt(0);if(i===108&&T===2&&c.charCodeAt(1)===116)_="<";else if(i===103&&T===2&&c.charCodeAt(1)===116)_=">";else if(i===97&&T===3&&c.charCodeAt(1)===109&&c.charCodeAt(2)===112)_="&";else if(i===113&&T===4)_=c==="quot"?'"':void 0;else if(i===97&&T===4)_=c==="apos"?"'":void 0}if(_===void 0)_=fy[c]??(this.useHtmlEntities?Uy[c]:void 0)}if(_!==void 0)d+=_;else d+=t.substring(e,n+1)}E=n+1,e=t.indexOf("&",E)}if(E<r)d+=t.substring(E);return d}}function Ar(t){return t===32||t===9||t===10||t===13}function FS(t){return t>=65&&t<=90||t>=97&&t<=122||t===95||t===58||t>=192&&t<=214||t>=216&&t<=246||t>=248&&t<=767||t>=880&&t<=893||t>=895&&t<=8191||t>=8204&&t<=8205||t>=8304&&t<=8591||t>=11264&&t<=12271||t>=12289&&t<=55295||t>=63744&&t<=64975||t>=65008&&t<=65533}function J0(t){return FS(t)||t===45||t===46||t>=48&&t<=57||t===183||t>=768&&t<=879||t>=8255&&t<=8256}function z0(t,e){return t.charCodeAt(e)===91&&t.charCodeAt(e+1)===67&&t.charCodeAt(e+2)===68&&t.charCodeAt(e+3)===65&&t.charCodeAt(e+4)===84&&t.charCodeAt(e+5)===65&&t.charCodeAt(e+6)===91}function F0(t,e){let r=t.charCodeAt(e),d=t.charCodeAt(e+1),E=t.charCodeAt(e+2),n=t.charCodeAt(e+3),c=t.charCodeAt(e+4),_=t.charCodeAt(e+5),T=t.charCodeAt(e+6);return(r===68||r===100)&&(d===79||d===111)&&(E===67||E===99)&&(n===84||n===116)&&(c===89||c===121)&&(_===80||_===112)&&(T===69||T===101)}function Xy(t,e,r){if(e>=r||!FS(t.charCodeAt(e)))return e;e++;while(e<r&&J0(t.charCodeAt(e)))e++;return e}class BS{options;entityDecoder;unpairedSet;exactStopNodes;wildcardStopSuffixes;needsJPath;_ignoreAttributes=!0;_textNodeName="#text";_commentPropName=!1;_cdataPropName=!1;_piPropName=!1;_alwaysCreateTextNode=!1;_trimValues=!0;_processEntities=!0;_parseTagValue=!0;_parseAttributeValue=!1;_removeNSPrefix=!1;_attrPrefix="@_";_attrsGroupName=!1;_ignorePiTags=!1;_ignoreDeclaration=!1;constructor(t){this.options={...wy,...t},this.entityDecoder=new B0(this.options.htmlEntities),this.unpairedSet=new Set(this.options.unpairedTags),this.exactStopNodes=new Set,this.wildcardStopSuffixes=[];for(let e of this.options.stopNodes)if(e.startsWith("*."))this.wildcardStopSuffixes.push(e.substring(2));else this.exactStopNodes.add(e);this._ignoreAttributes=this.options.ignoreAttributes,this._textNodeName=this.options.textNodeName,this._commentPropName=this.options.commentPropName,this._cdataPropName=this.options.cdataPropName,this._piPropName=this.options.piPropName,this._alwaysCreateTextNode=this.options.alwaysCreateTextNode,this._trimValues=this.options.trimValues,this._processEntities=this.options.processEntities,this._parseTagValue=this.options.parseTagValue,this._parseAttributeValue=this.options.parseAttributeValue,this._removeNSPrefix=this.options.removeNSPrefix,this._attrPrefix=this.options.attributeNamePrefix,this._attrsGroupName=this.options.attributesGroupName,this._ignorePiTags=this.options.ignorePiTags,this._ignoreDeclaration=this.options.ignoreDeclaration,this.needsJPath=this.options.stopNodes.length>0||this.options.isArray!==void 0||this.options.updateTag!==void 0||this.options.tagValueProcessor!==void 0||this.options.attributeValueProcessor!==void 0}addEntity(t,e){this.entityDecoder.addEntity(t,e)}parse(t){if(t instanceof Uint8Array)t=new TextDecoder().decode(t);let e=t;if(this.options.preserveOrder)return this.parseOrdered(e);return this.parseUnordered(e)}parseUnordered(t){let e={},r=t.length,d=0;if(r>0&&t.charCodeAt(0)===65279)d=1;return d=this.parseChildren(t,d,r,e,"",[]),e}parseOrdered(t){let e=t.length,r=0;if(e>0&&t.charCodeAt(0)===65279)r=1;let d=[];return this.parseChildrenOrdered(t,r,e,d,""),d}readTagName(t,e,r){return Xy(t,e,r)}extractTagName(t,e,r){let d=t.substring(e,r);if(this._removeNSPrefix){let E=d.indexOf(":");if(E!==-1)d=d.substring(E+1)}if(this.options.transformTagName)d=this.options.transformTagName(d);return d}parseAttributes(t,e,r,d,E){let n=0,c=this._removeNSPrefix,_=this.options.transformAttributeName,T=this._trimValues,i=this._processEntities,h=this.options.attributeValueProcessor;while(e<r){let R=t.charCodeAt(e);while(R===32||R===9||R===10||R===13){if(e++,e>=r)break;R=t.charCodeAt(e)}if(e>=r)break;if(R===62||R===47)break;let N=e;if(!FS(R))break;e++;while(e<r&&J0(t.charCodeAt(e)))e++;let A=t.substring(N,e);if(c){let u=A.indexOf(":");if(u!==-1)A=A.substring(u+1)}if(_)A=_(A);while(e<r&&Ar(t.charCodeAt(e)))e++;if(e<r&&t.charCodeAt(e)===61){e++;while(e<r&&Ar(t.charCodeAt(e)))e++;if(e>=r)break;let u=t.charCodeAt(e);if(u===34||u===39){e++;let f=e;while(e<r&&t.charCodeAt(e)!==u)e++;let w=t.substring(f,e);if(T&&w.length>0){let I=w.charCodeAt(0),a=w.charCodeAt(w.length-1);if(I<=32||a<=32)w=w.trim()}if(i)w=this.entityDecoder.decodeEntities(w);if(h)w=h(A,w,d)??w;if(E[A]=w,n++,e<r)e++}}else E[A]="true",n++}return n>0?-e-1:e}processTagValue(t,e,r,d,E){if(this._trimValues){let n=t.length;if(n>0){let c=t.charCodeAt(0),_=t.charCodeAt(n-1);if(c<=32||_<=32)t=t.trim()}}if(this._processEntities)t=this.entityDecoder.decodeEntities(t);if(this.options.tagValueProcessor){let n=this.options.tagValueProcessor(e,t,r,d,E);if(n!==void 0)t=n}if(!t)return t;if(this._parseTagValue)return this.parseValue(t);return t}parseValue(t){if(t==="true")return!0;if(t==="false")return!1;if(!t)return t;let e=t.charCodeAt(0);if(!(e>=48&&e<=57||e===43||e===45||e===46))return t;let d=this.options.numberParseOptions;if(d.skipLike?.test(t))return t;if(d.hex&&e===48&&gy.test(t))return Number.parseInt(t,16);if(t.length>1&&e===48&&t.charCodeAt(1)!==46){if(d.leadingZeros)return t}if(d.scientific&&$y.test(t)){let E=Number(t);if(!Number.isNaN(E))return E}if(yy.test(t)){let E=Number(t);if(!Number.isNaN(E))return E}return t}parseAttributeValue(t){if(!this._parseAttributeValue)return t;return this.parseValue(t)}isStopNode(t){if(this.exactStopNodes.has(t))return!0;for(let e of this.wildcardStopSuffixes)if(t.endsWith(`.${e}`)||t===e)return!0;return!1}readStopNodeContent(t,e,r,d){let E=`</${d}`,n=t.indexOf(E,e);if(n===-1)return{content:t.substring(e),pos:r};let c=t.substring(e,n),_=n+E.length;while(_<r&&t.charCodeAt(_)!==62)_++;if(_<r)_++;return{content:c,pos:_}}addToObj(t,e,r,d,E,n){let c=t[e];if(c!==void 0)if(!Array.isArray(c))t[e]=[c,r];else c.push(r);else if(this.options.isArray?.(e,d,E,n))t[e]=[r];else t[e]=r}flushText(t,e,r,d){if(!t&&!e)return;let E=this._textNodeName;if(e){let n=t;if(n&&this._processEntities)n=this.entityDecoder.decodeEntities(n);let c=e+n;if(this._trimValues&&c.length>0){let _=c.charCodeAt(0),T=c.charCodeAt(c.length-1);if(_<=32||T<=32)c=c.trim()}if(this.options.tagValueProcessor){let _=this.options.tagValueProcessor(E,c,r,!1,!0);if(_!==void 0)c=_}if(c){let _=this._parseTagValue?this.parseValue(c):c;if(_!==void 0&&_!=="")this.addToObj(d,E,_,r,!0,!1)}}else{let n=this.processTagValue(t,E,r,!1,!0);if(n!==void 0&&n!=="")this.addToObj(d,E,n,r,!0,!1)}}parseChildren(t,e,r,d,E,n){let c="",_="",T=this.needsJPath;while(e<r){if(t.charCodeAt(e)!==60){let I=e;e++;while(e<r&&t.charCodeAt(e)!==60)e++;if(!c)c=t.substring(I,e);else c+=t.substring(I,e);continue}if(e+1>=r)break;let h=t.charCodeAt(e+1);if(h===33&&e+3<r&&t.charCodeAt(e+2)===45&&t.charCodeAt(e+3)===45){if(c||_)this.flushText(c,_,E,d),c="",_="";e+=4;let I=t.indexOf("-->",e);if(I===-1){e=r;break}if(this._commentPropName){let a=t.substring(e,I);this.addToObj(d,this._commentPropName,a,E,!0,!1)}e=I+3;continue}if(h===33&&e+8<r&&z0(t,e+2)){e+=9;let I=t.indexOf("]]>",e);if(I===-1){e=r;break}let a=t.substring(e,I);if(this._cdataPropName)this.flushText(c,_,E,d),c="",_="",this.addToObj(d,this._cdataPropName,a,E,!0,!1);else{if(c){let P=c;if(this._processEntities)P=this.entityDecoder.decodeEntities(P);_+=P,c=""}_+=a}e=I+3;continue}if(h===33&&e+9<r&&F0(t,e+2)){e+=9;let I=1;while(e<r&&I>0){let a=t.charCodeAt(e);if(a===60)I++;else if(a===62)I--;e++}continue}if(h===63){e+=2;let I=e;while(e<r&&!Ar(t.charCodeAt(e))&&t.charCodeAt(e)!==63)e++;let a=t.substring(I,e),P=t.indexOf("?>",e);if(P===-1){e=r;break}let j=t.substring(e,P).trim();if(a==="xml"){if(!this._ignoreDeclaration&&this._piPropName){let H=this.parsePiAttributes(j);this.addToObj(d,this._piPropName,{[a]:H},E,!0,!1)}}else if(!this._ignorePiTags&&this._piPropName)this.addToObj(d,this._piPropName,{[a]:j},E,!0,!1);e=P+2;continue}if(h===47){if(c||_)this.flushText(c,_,E,d),c="",_="";e+=2;let I=e,a=this.readTagName(t,e,r),P=this.extractTagName(t,I,a);e=a;while(e<r&&Ar(t.charCodeAt(e)))e++;if(e<r&&t.charCodeAt(e)===62)e++;if(n.length>0&&n[n.length-1]===P){n.pop();continue}return e}if(c||_)this.flushText(c,_,E,d),c="",_="";e++;let R=e,N=this.readTagName(t,e,r),A=this.extractTagName(t,R,N);if(!A){e=N+1;continue}e=N;let u=T?E?`${E}.${A}`:A:"",f={},w=!1;if(!this._ignoreAttributes){let I=this.parseAttributes(t,e,r,u,f);if(I<0)e=-I-1,w=!0;else e=I}else while(e<r){let I=t.charCodeAt(e);if(I===62||I===47)break;if(I===34||I===39){e++;while(e<r&&t.charCodeAt(e)!==I)e++}e++}if(this.options.updateTag){if(this.options.updateTag(A,u,f)===!1){while(e<r&&Ar(t.charCodeAt(e)))e++;if(e<r&&t.charCodeAt(e)===47)e+=2;else if(e<r&&t.charCodeAt(e)===62){e++;let a=`</${A}>`,P=t.indexOf(a,e);if(P!==-1)e=P+a.length}continue}}while(e<r&&Ar(t.charCodeAt(e)))e++;if(e<r&&t.charCodeAt(e)===47){if(e+=2,w||this._alwaysCreateTextNode){let I={};if(w)this.applyAttributes(I,f,u);if(this._alwaysCreateTextNode)I[this._textNodeName]="";this.addToObj(d,A,I,u,!0,!1)}else this.addToObj(d,A,"",u,!0,!1);continue}if(e<r&&t.charCodeAt(e)===62){if(e++,this.unpairedSet.has(A)){if(w){let j={};this.applyAttributes(j,f,u),this.addToObj(d,A,j,u,!0,!1)}else this.addToObj(d,A,"",u,!0,!1);n.push(A);continue}if(this.exactStopNodes.size>0||this.wildcardStopSuffixes.length>0){if(this.isStopNode(u)){let j=this.readStopNodeContent(t,e,r,A),H={};if(w)this.applyAttributes(H,f,u);if(j.content)H[this._textNodeName]=j.content;this.addToObj(d,A,H,u,!0,!1),e=j.pos;continue}}let I={};if(w)this.applyAttributes(I,f,u);e=this.parseChildren(t,e,r,I,u,n);let a=this._textNodeName,P=I[a];if(!w&&!this._alwaysCreateTextNode){let j=!0;for(let H in I)if(H!==a){j=!1;break}if(j){this.addToObj(d,A,P!==void 0?P:"",u,!0,!1);continue}}this.addToObj(d,A,I,u,!1,!1)}}if(c||_)this.flushText(c,_,E,d);return e}parseChildrenOrdered(t,e,r,d,E){let n="",c=this.needsJPath;while(e<r){if(t.charCodeAt(e)!==60){let w=e;e++;while(e<r&&t.charCodeAt(e)!==60)e++;if(!n)n=t.substring(w,e);else n+=t.substring(w,e);continue}if(e+1>=r)break;let T=t.charCodeAt(e+1);if(T===33&&e+3<r&&t.charCodeAt(e+2)===45&&t.charCodeAt(e+3)===45){if(n){let I=this.processTagValue(n,this._textNodeName,E,!1,!0);if(I!==void 0&&I!=="")d.push({[this._textNodeName]:I});n=""}e+=4;let w=t.indexOf("-->",e);if(w===-1){e=r;break}if(this._commentPropName)d.push({[this._commentPropName]:[{[this._textNodeName]:t.substring(e,w)}]});e=w+3;continue}if(T===33&&e+8<r&&z0(t,e+2)){e+=9;let w=t.indexOf("]]>",e);if(w===-1){e=r;break}let I=t.substring(e,w);if(this._cdataPropName){if(n){let a=this.processTagValue(n,this._textNodeName,E,!1,!0);if(a!==void 0&&a!=="")d.push({[this._textNodeName]:a});n=""}d.push({[this._cdataPropName]:[{[this._textNodeName]:I}]})}else n+=I;e=w+3;continue}if(T===33&&e+9<r&&F0(t,e+2)){e+=9;let w=1;while(e<r&&w>0){let I=t.charCodeAt(e);if(I===60)w++;else if(I===62)w--;e++}continue}if(T===63){e+=2;let w=t.indexOf("?>",e);if(w===-1){e=r;break}e=w+2;continue}if(T===47){if(n){let I=this.processTagValue(n,this._textNodeName,E,!1,!0);if(I!==void 0&&I!=="")d.push({[this._textNodeName]:I});n=""}e+=2,e=this.readTagName(t,e,r);while(e<r&&Ar(t.charCodeAt(e)))e++;if(e<r&&t.charCodeAt(e)===62)e++;return e}if(n){let w=this.processTagValue(n,this._textNodeName,E,!1,!0);if(w!==void 0&&w!=="")d.push({[this._textNodeName]:w});n=""}e++;let i=e,h=this.readTagName(t,e,r),R=this.extractTagName(t,i,h);if(!R){e=h+1;continue}e=h;let N=c?E?`${E}.${R}`:R:"",A={},u=!1;if(!this._ignoreAttributes){let w=this.parseAttributes(t,e,r,N,A);if(w<0)e=-w-1,u=!0;else e=w}else while(e<r){let w=t.charCodeAt(e);if(w===62||w===47)break;if(w===34||w===39){e++;while(e<r&&t.charCodeAt(e)!==w)e++}e++}while(e<r&&Ar(t.charCodeAt(e)))e++;let f={[R]:[]};if(u){f[":@"]={};for(let I in A)f[":@"][this._attrPrefix+I]=this.parseAttributeValue(A[I])}if(e<r&&t.charCodeAt(e)===47){e+=2,d.push(f);continue}if(e<r&&t.charCodeAt(e)===62)e++,e=this.parseChildrenOrdered(t,e,r,f[R],N),d.push(f)}if(n){let _=this.processTagValue(n,this._textNodeName,E,!1,!0);if(_!==void 0&&_!=="")d.push({[this._textNodeName]:_})}return e}applyAttributes(t,e,r){let d=this._attrPrefix;if(this._attrsGroupName){let E={};for(let n in e)E[d+n]=this.parseAttributeValue(e[n]);t[this._attrsGroupName]=E}else for(let E in e)t[d+E]=this.parseAttributeValue(e[E])}parsePiAttributes(t){let e={},r=0,d=t.length;while(r<d){while(r<d&&Ar(t.charCodeAt(r)))r++;if(r>=d)break;let E=r;while(r<d&&!Ar(t.charCodeAt(r))&&t.charCodeAt(r)!==61)r++;let n=t.substring(E,r);if(!n)break;while(r<d&&Ar(t.charCodeAt(r)))r++;if(r<d&&t.charCodeAt(r)===61){r++;while(r<d&&Ar(t.charCodeAt(r)))r++;if(r<d){let c=t.charCodeAt(r);if(c===34||c===39){r++;let _=r;while(r<d&&t.charCodeAt(r)!==c)r++;if(e[n]=t.substring(_,r),r<d)r++}}}}return e}}var fy,Uy,d_,wy,gy,$y,yy;var H0=wr(()=>{fy={amp:"&",lt:"<",gt:">",quot:'"',apos:"'"},Uy={nbsp:" ",copy:"©",reg:"®",trade:"™",euro:"€",pound:"£",yen:"¥",cent:"¢",deg:"°",micro:"µ",middot:"·",bull:"•",hellip:"…",prime:"′",Prime:"″",laquo:"«",raquo:"»",lsquo:"‘",rsquo:"’",ldquo:"“",rdquo:"”",ndash:"–",mdash:"—",iexcl:"¡",iquest:"¿",sect:"§",para:"¶",dagger:"†",Dagger:"‡",lsaquo:"‹",rsaquo:"›",oline:"‾",frasl:"⁄",ensp:" ",emsp:" ",thinsp:" ",zwnj:"",zwj:"",lrm:"",rlm:"",times:"×",divide:"÷",plusmn:"±",ne:"≠",le:"≤",ge:"≥",infin:"∞",fnof:"ƒ",Alpha:"Α",Beta:"Β",Gamma:"Γ",Delta:"Δ",Epsilon:"Ε",Zeta:"Ζ",Eta:"Η",Theta:"Θ",Iota:"Ι",Kappa:"Κ",Lambda:"Λ",Mu:"Μ",Nu:"Ν",Xi:"Ξ",Omicron:"Ο",Pi:"Π",Rho:"Ρ",Sigma:"Σ",Tau:"Τ",Upsilon:"Υ",Phi:"Φ",Chi:"Χ",Psi:"Ψ",Omega:"Ω",alpha:"α",beta:"β",gamma:"γ",delta:"δ",epsilon:"ε",zeta:"ζ",eta:"η",theta:"θ",iota:"ι",kappa:"κ",lambda:"λ",mu:"μ",nu:"ν",xi:"ξ",omicron:"ο",pi:"π",rho:"ρ",sigmaf:"ς",sigma:"σ",tau:"τ",upsilon:"υ",phi:"φ",chi:"χ",psi:"ψ",omega:"ω",thetasym:"ϑ",upsih:"ϒ",piv:"ϖ",larr:"←",uarr:"↑",rarr:"→",darr:"↓",harr:"↔",crarr:"↵",lArr:"⇐",uArr:"⇑",rArr:"⇒",dArr:"⇓",hArr:"⇔",forall:"∀",part:"∂",exist:"∃",empty:"∅",nabla:"∇",isin:"∈",notin:"∉",ni:"∋",prod:"∏",sum:"∑",minus:"−",lowast:"∗",radic:"√",prop:"∝",ang:"∠",and:"∧",or:"∨",cap:"∩",cup:"∪",int:"∫",there4:"∴",sim:"∼",cong:"≅",asymp:"≈",equiv:"≡",sub:"⊂",sup:"⊃",nsub:"⊄",sube:"⊆",supe:"⊇",oplus:"⊕",otimes:"⊗",perp:"⊥",sdot:"⋅",lceil:"⌈",rceil:"⌉",lfloor:"⌊",rfloor:"⌋",lang:"〈",rang:"〉",loz:"◊",spades:"♠",clubs:"♣",hearts:"♥",diams:"♦",Agrave:"À",Aacute:"Á",Acirc:"Â",Atilde:"Ã",Auml:"Ä",Aring:"Å",AElig:"Æ",Ccedil:"Ç",Egrave:"È",Eacute:"É",Ecirc:"Ê",Euml:"Ë",Igrave:"Ì",Iacute:"Í",Icirc:"Î",Iuml:"Ï",ETH:"Ð",Ntilde:"Ñ",Ograve:"Ò",Oacute:"Ó",Ocirc:"Ô",Otilde:"Õ",Ouml:"Ö",Oslash:"Ø",Ugrave:"Ù",Uacute:"Ú",Ucirc:"Û",Uuml:"Ü",Yacute:"Ý",THORN:"Þ",szlig:"ß",agrave:"à",aacute:"á",acirc:"â",atilde:"ã",auml:"ä",aring:"å",aelig:"æ",ccedil:"ç",egrave:"è",eacute:"é",ecirc:"ê",euml:"ë",igrave:"ì",iacute:"í",icirc:"î",iuml:"ï",eth:"ð",ntilde:"ñ",ograve:"ò",oacute:"ó",ocirc:"ô",otilde:"õ",ouml:"ö",oslash:"ø",ugrave:"ù",uacute:"ú",ucirc:"û",uuml:"ü",yacute:"ý",thorn:"þ",yuml:"ÿ",OElig:"Œ",oelig:"œ",Scaron:"Š",scaron:"š",Yuml:"Ÿ",circ:"ˆ",tilde:"˜"};d_=[];d_[38]="&";d_[60]="<";d_[62]=">";d_[34]=""";d_[39]="'";wy={attributeNamePrefix:"@_",attributesGroupName:!1,textNodeName:"#text",ignoreAttributes:!0,removeNSPrefix:!1,allowBooleanAttributes:!1,alwaysCreateTextNode:!1,trimValues:!0,parseTagValue:!0,parseAttributeValue:!1,processEntities:!0,htmlEntities:!1,commentPropName:!1,cdataPropName:!1,piPropName:!1,preserveOrder:!1,stopNodes:[],unpairedTags:[],isArray:void 0,tagValueProcessor:void 0,attributeValueProcessor:void 0,updateTag:void 0,numberParseOptions:{hex:!0,leadingZeros:!0,scientific:!0},ignorePiTags:!1,transformAttributeName:void 0,transformTagName:void 0,ignoreDeclaration:!1};gy=/^0x[\da-fA-F]+$/,$y=/^[+-]?\d+(\.\d+)?[eE][+-]?\d+$/,yy=/^[+-]?(\d+\.?\d*|\.\d+)$/});var Y0={};ER(Y0,{resolveS3Endpoint:()=>E_,detectCredentialSource:()=>Py,buildQueryParams:()=>Qt,AWSClient:()=>dt});import*as Yd from"node:crypto";import{existsSync as W0,readFileSync as ay}from"node:fs";import{homedir as v0}from"node:os";import{join as Q0}from"node:path";function E_(t){let e=t.endpoint||`s3.${t.region}.amazonaws.com`,r=new URL(/^https?:\/\//i.test(e)?e:`https://${e}`);if(r.protocol!=="http:"&&r.protocol!=="https:"||r.pathname!=="/"&&r.pathname!==""||r.search||r.hash||r.username||r.password)throw Error("S3 endpoint must be an HTTP(S) origin without a path");let d=r.protocol.slice(0,-1),E=r.host;if(!t.bucket)return{protocol:d,host:E,path:t.path};if(t.forcePathStyle){let n=t.path==="/"?`/${t.bucket}`:`/${t.bucket}${t.path}`;return{protocol:d,host:E,path:n}}return{protocol:d,host:`${t.bucket}.${E}`,path:t.path}}class dt{credentials;config;cache;xmlParser;constructor(t,e){this.config={maxRetries:3,retryDelay:1000,cacheEnabled:!0,defaultCacheTTL:60000,...e},this.credentials=t||this.loadCredentials(),this.cache=new Map,this.xmlParser=new BS({ignoreAttributes:!1,attributeNamePrefix:"@_",textNodeName:"#text",parseAttributeValue:!0,trimValues:!0})}loadCredentials(){let t=process.env.AWS_ACCESS_KEY_ID,e=process.env.AWS_SECRET_ACCESS_KEY,r=process.env.AWS_SESSION_TOKEN;if(t&&e)return{accessKeyId:t,secretAccessKey:e,sessionToken:r};let d=this.loadCredentialsFromFile();if(d)return d;return{accessKeyId:"",secretAccessKey:""}}loadCredentialsFromFile(){let t=this.config?.profile||process.env.AWS_PROFILE||"default",e=process.env.AWS_SHARED_CREDENTIALS_FILE||Q0(v0(),".aws","credentials");if(!W0(e))return null;try{let r=ay(e,"utf-8"),d=this.parseCredentialsFile(r,t);if(d.accessKeyId&&d.secretAccessKey)return d}catch{}return null}parseCredentialsFile(t,e){let r=t.split(`
|
|
3941
|
+
`);static createSessionsTable(t){return{[`${t.slug}ChatbotSessionsTable`]:{Type:"AWS::DynamoDB::Table",Properties:{TableName:`${t.slug}-chatbot-sessions`,BillingMode:"PAY_PER_REQUEST",AttributeDefinitions:[{AttributeName:"phoneNumber",AttributeType:"S"}],KeySchema:[{AttributeName:"phoneNumber",KeyType:"HASH"}],TimeToLiveSpecification:{AttributeName:"ttl",Enabled:!0}}}}}static createRulesTable(t){return{[`${t.slug}ChatbotRulesTable`]:{Type:"AWS::DynamoDB::Table",Properties:{TableName:`${t.slug}-chatbot-rules`,BillingMode:"PAY_PER_REQUEST",AttributeDefinitions:[{AttributeName:"id",AttributeType:"S"}],KeySchema:[{AttributeName:"id",KeyType:"HASH"}]}}}}static createChatbotProcessorLambda(t){return{[`${t.slug}ChatbotProcessorLambda`]:{Type:"AWS::Lambda::Function",Properties:{FunctionName:`${t.slug}-chatbot-processor`,Runtime:"nodejs20.x",Handler:"index.handler",Role:t.roleArn,Timeout:30,MemorySize:256,Code:{ZipFile:IR.ChatbotProcessorCode},Environment:{Variables:{SESSIONS_TABLE:t.sessionsTable,RULES_TABLE:t.rulesTable,CHATBOT_CONFIG:JSON.stringify(t.chatbotConfig),ORIGINATION_NUMBER:t.originationNumber||""}}}}}}static DefaultRules=[{id:"greeting",priority:1,patterns:["^(hi|hello|hey|howdy)$","^good (morning|afternoon|evening)"],response:"Hello! How can I help you today?"},{id:"help",priority:2,patterns:["^help$","what can you do","how does this work"],response:"I can help with: 1) Account info 2) Support 3) Hours. Reply with a number."},{id:"hours",priority:3,patterns:["hours","open","when are you"],response:"We are open Mon-Fri 9am-5pm EST. Closed weekends."},{id:"thanks",priority:4,patterns:["^(thanks|thank you|thx)"],response:"You're welcome! Is there anything else I can help with?"},{id:"bye",priority:5,patterns:["^(bye|goodbye|quit|exit|stop)$"],response:"Goodbye! Text us anytime if you need help.",action:"end"}]};$H=new jO;yH=new zO;XH=new FO;aH=new BO,PH=(()=>{let t=[];for(let e=0;e<256;e++){let r=e;for(let d=0;d<8;d++)r=r&1?3988292384^r>>>1:r>>>1;t[e]=r>>>0}return t})();jH=new HO;zH=new WO;FH=new vO;BH=new QO;JH=new YO});class B0{customEntities={};useHtmlEntities;constructor(t=!1){this.useHtmlEntities=t}addEntity(t,e){this.customEntities[t]=e}decodeEntities(t){let e=t.indexOf("&");if(e===-1)return t;let r=t.length,d="",E=0;while(e!==-1&&e<r){if(e>E)d+=t.substring(E,e);let n=t.indexOf(";",e+1);if(n===-1||n-e>32){d+="&",E=e+1,e=t.indexOf("&",E);continue}let c=t.substring(e+1,n);if(c.charCodeAt(0)===35){let _=c.length,T=0,i=!1;if(_>2&&(c.charCodeAt(1)===120||c.charCodeAt(1)===88)){i=!0;for(let h=2;h<_;h++){let R=c.charCodeAt(h);if(R>=48&&R<=57)T=T<<4|R-48;else if(R>=65&&R<=70)T=T<<4|R-55;else if(R>=97&&R<=102)T=T<<4|R-87;else{i=!1;break}}}else if(_>1){i=!0;for(let h=1;h<_;h++){let R=c.charCodeAt(h);if(R>=48&&R<=57)T=T*10+(R-48);else{i=!1;break}}}if(i)d+=String.fromCodePoint(T);else d+=t.substring(e,n+1)}else{let _=this.customEntities[c];if(_===void 0){let T=c.length;if(T>=2&&T<=4){let i=c.charCodeAt(0);if(i===108&&T===2&&c.charCodeAt(1)===116)_="<";else if(i===103&&T===2&&c.charCodeAt(1)===116)_=">";else if(i===97&&T===3&&c.charCodeAt(1)===109&&c.charCodeAt(2)===112)_="&";else if(i===113&&T===4)_=c==="quot"?'"':void 0;else if(i===97&&T===4)_=c==="apos"?"'":void 0}if(_===void 0)_=fy[c]??(this.useHtmlEntities?Uy[c]:void 0)}if(_!==void 0)d+=_;else d+=t.substring(e,n+1)}E=n+1,e=t.indexOf("&",E)}if(E<r)d+=t.substring(E);return d}}function Ar(t){return t===32||t===9||t===10||t===13}function FS(t){return t>=65&&t<=90||t>=97&&t<=122||t===95||t===58||t>=192&&t<=214||t>=216&&t<=246||t>=248&&t<=767||t>=880&&t<=893||t>=895&&t<=8191||t>=8204&&t<=8205||t>=8304&&t<=8591||t>=11264&&t<=12271||t>=12289&&t<=55295||t>=63744&&t<=64975||t>=65008&&t<=65533}function J0(t){return FS(t)||t===45||t===46||t>=48&&t<=57||t===183||t>=768&&t<=879||t>=8255&&t<=8256}function z0(t,e){return t.charCodeAt(e)===91&&t.charCodeAt(e+1)===67&&t.charCodeAt(e+2)===68&&t.charCodeAt(e+3)===65&&t.charCodeAt(e+4)===84&&t.charCodeAt(e+5)===65&&t.charCodeAt(e+6)===91}function F0(t,e){let r=t.charCodeAt(e),d=t.charCodeAt(e+1),E=t.charCodeAt(e+2),n=t.charCodeAt(e+3),c=t.charCodeAt(e+4),_=t.charCodeAt(e+5),T=t.charCodeAt(e+6);return(r===68||r===100)&&(d===79||d===111)&&(E===67||E===99)&&(n===84||n===116)&&(c===89||c===121)&&(_===80||_===112)&&(T===69||T===101)}function Xy(t,e,r){if(e>=r||!FS(t.charCodeAt(e)))return e;e++;while(e<r&&J0(t.charCodeAt(e)))e++;return e}class BS{options;entityDecoder;unpairedSet;exactStopNodes;wildcardStopSuffixes;needsJPath;_ignoreAttributes=!0;_textNodeName="#text";_commentPropName=!1;_cdataPropName=!1;_piPropName=!1;_alwaysCreateTextNode=!1;_trimValues=!0;_processEntities=!0;_parseTagValue=!0;_parseAttributeValue=!1;_removeNSPrefix=!1;_attrPrefix="@_";_attrsGroupName=!1;_ignorePiTags=!1;_ignoreDeclaration=!1;constructor(t){this.options={...wy,...t},this.entityDecoder=new B0(this.options.htmlEntities),this.unpairedSet=new Set(this.options.unpairedTags),this.exactStopNodes=new Set,this.wildcardStopSuffixes=[];for(let e of this.options.stopNodes)if(e.startsWith("*."))this.wildcardStopSuffixes.push(e.substring(2));else this.exactStopNodes.add(e);this._ignoreAttributes=this.options.ignoreAttributes,this._textNodeName=this.options.textNodeName,this._commentPropName=this.options.commentPropName,this._cdataPropName=this.options.cdataPropName,this._piPropName=this.options.piPropName,this._alwaysCreateTextNode=this.options.alwaysCreateTextNode,this._trimValues=this.options.trimValues,this._processEntities=this.options.processEntities,this._parseTagValue=this.options.parseTagValue,this._parseAttributeValue=this.options.parseAttributeValue,this._removeNSPrefix=this.options.removeNSPrefix,this._attrPrefix=this.options.attributeNamePrefix,this._attrsGroupName=this.options.attributesGroupName,this._ignorePiTags=this.options.ignorePiTags,this._ignoreDeclaration=this.options.ignoreDeclaration,this.needsJPath=this.options.stopNodes.length>0||this.options.isArray!==void 0||this.options.updateTag!==void 0||this.options.tagValueProcessor!==void 0||this.options.attributeValueProcessor!==void 0}addEntity(t,e){this.entityDecoder.addEntity(t,e)}parse(t){if(t instanceof Uint8Array)t=new TextDecoder().decode(t);let e=t;if(this.options.preserveOrder)return this.parseOrdered(e);return this.parseUnordered(e)}parseUnordered(t){let e={},r=t.length,d=0;if(r>0&&t.charCodeAt(0)===65279)d=1;return d=this.parseChildren(t,d,r,e,"",[]),e}parseOrdered(t){let e=t.length,r=0;if(e>0&&t.charCodeAt(0)===65279)r=1;let d=[];return this.parseChildrenOrdered(t,r,e,d,""),d}readTagName(t,e,r){return Xy(t,e,r)}extractTagName(t,e,r){let d=t.substring(e,r);if(this._removeNSPrefix){let E=d.indexOf(":");if(E!==-1)d=d.substring(E+1)}if(this.options.transformTagName)d=this.options.transformTagName(d);return d}parseAttributes(t,e,r,d,E){let n=0,c=this._removeNSPrefix,_=this.options.transformAttributeName,T=this._trimValues,i=this._processEntities,h=this.options.attributeValueProcessor;while(e<r){let R=t.charCodeAt(e);while(R===32||R===9||R===10||R===13){if(e++,e>=r)break;R=t.charCodeAt(e)}if(e>=r)break;if(R===62||R===47)break;let N=e;if(!FS(R))break;e++;while(e<r&&J0(t.charCodeAt(e)))e++;let A=t.substring(N,e);if(c){let u=A.indexOf(":");if(u!==-1)A=A.substring(u+1)}if(_)A=_(A);while(e<r&&Ar(t.charCodeAt(e)))e++;if(e<r&&t.charCodeAt(e)===61){e++;while(e<r&&Ar(t.charCodeAt(e)))e++;if(e>=r)break;let u=t.charCodeAt(e);if(u===34||u===39){e++;let f=e;while(e<r&&t.charCodeAt(e)!==u)e++;let w=t.substring(f,e);if(T&&w.length>0){let I=w.charCodeAt(0),a=w.charCodeAt(w.length-1);if(I<=32||a<=32)w=w.trim()}if(i)w=this.entityDecoder.decodeEntities(w);if(h)w=h(A,w,d)??w;if(E[A]=w,n++,e<r)e++}}else E[A]="true",n++}return n>0?-e-1:e}processTagValue(t,e,r,d,E){if(this._trimValues){let n=t.length;if(n>0){let c=t.charCodeAt(0),_=t.charCodeAt(n-1);if(c<=32||_<=32)t=t.trim()}}if(this._processEntities)t=this.entityDecoder.decodeEntities(t);if(this.options.tagValueProcessor){let n=this.options.tagValueProcessor(e,t,r,d,E);if(n!==void 0)t=n}if(!t)return t;if(this._parseTagValue)return this.parseValue(t);return t}parseValue(t){if(t==="true")return!0;if(t==="false")return!1;if(!t)return t;let e=t.charCodeAt(0);if(!(e>=48&&e<=57||e===43||e===45||e===46))return t;let d=this.options.numberParseOptions;if(d.skipLike?.test(t))return t;if(d.hex&&e===48&&gy.test(t))return Number.parseInt(t,16);if(t.length>1&&e===48&&t.charCodeAt(1)!==46){if(d.leadingZeros)return t}if(d.scientific&&$y.test(t)){let E=Number(t);if(!Number.isNaN(E))return E}if(yy.test(t)){let E=Number(t);if(!Number.isNaN(E))return E}return t}parseAttributeValue(t){if(!this._parseAttributeValue)return t;return this.parseValue(t)}isStopNode(t){if(this.exactStopNodes.has(t))return!0;for(let e of this.wildcardStopSuffixes)if(t.endsWith(`.${e}`)||t===e)return!0;return!1}readStopNodeContent(t,e,r,d){let E=`</${d}`,n=t.indexOf(E,e);if(n===-1)return{content:t.substring(e),pos:r};let c=t.substring(e,n),_=n+E.length;while(_<r&&t.charCodeAt(_)!==62)_++;if(_<r)_++;return{content:c,pos:_}}addToObj(t,e,r,d,E,n){let c=t[e];if(c!==void 0)if(!Array.isArray(c))t[e]=[c,r];else c.push(r);else if(this.options.isArray?.(e,d,E,n))t[e]=[r];else t[e]=r}flushText(t,e,r,d){if(!t&&!e)return;let E=this._textNodeName;if(e){let n=t;if(n&&this._processEntities)n=this.entityDecoder.decodeEntities(n);let c=e+n;if(this._trimValues&&c.length>0){let _=c.charCodeAt(0),T=c.charCodeAt(c.length-1);if(_<=32||T<=32)c=c.trim()}if(this.options.tagValueProcessor){let _=this.options.tagValueProcessor(E,c,r,!1,!0);if(_!==void 0)c=_}if(c){let _=this._parseTagValue?this.parseValue(c):c;if(_!==void 0&&_!=="")this.addToObj(d,E,_,r,!0,!1)}}else{let n=this.processTagValue(t,E,r,!1,!0);if(n!==void 0&&n!=="")this.addToObj(d,E,n,r,!0,!1)}}parseChildren(t,e,r,d,E,n){let c="",_="",T=this.needsJPath;while(e<r){if(t.charCodeAt(e)!==60){let I=e;e++;while(e<r&&t.charCodeAt(e)!==60)e++;if(!c)c=t.substring(I,e);else c+=t.substring(I,e);continue}if(e+1>=r)break;let h=t.charCodeAt(e+1);if(h===33&&e+3<r&&t.charCodeAt(e+2)===45&&t.charCodeAt(e+3)===45){if(c||_)this.flushText(c,_,E,d),c="",_="";e+=4;let I=t.indexOf("-->",e);if(I===-1){e=r;break}if(this._commentPropName){let a=t.substring(e,I);this.addToObj(d,this._commentPropName,a,E,!0,!1)}e=I+3;continue}if(h===33&&e+8<r&&z0(t,e+2)){e+=9;let I=t.indexOf("]]>",e);if(I===-1){e=r;break}let a=t.substring(e,I);if(this._cdataPropName)this.flushText(c,_,E,d),c="",_="",this.addToObj(d,this._cdataPropName,a,E,!0,!1);else{if(c){let P=c;if(this._processEntities)P=this.entityDecoder.decodeEntities(P);_+=P,c=""}_+=a}e=I+3;continue}if(h===33&&e+9<r&&F0(t,e+2)){e+=9;let I=1;while(e<r&&I>0){let a=t.charCodeAt(e);if(a===60)I++;else if(a===62)I--;e++}continue}if(h===63){e+=2;let I=e;while(e<r&&!Ar(t.charCodeAt(e))&&t.charCodeAt(e)!==63)e++;let a=t.substring(I,e),P=t.indexOf("?>",e);if(P===-1){e=r;break}let j=t.substring(e,P).trim();if(a==="xml"){if(!this._ignoreDeclaration&&this._piPropName){let H=this.parsePiAttributes(j);this.addToObj(d,this._piPropName,{[a]:H},E,!0,!1)}}else if(!this._ignorePiTags&&this._piPropName)this.addToObj(d,this._piPropName,{[a]:j},E,!0,!1);e=P+2;continue}if(h===47){if(c||_)this.flushText(c,_,E,d),c="",_="";e+=2;let I=e,a=this.readTagName(t,e,r),P=this.extractTagName(t,I,a);e=a;while(e<r&&Ar(t.charCodeAt(e)))e++;if(e<r&&t.charCodeAt(e)===62)e++;if(n.length>0&&n[n.length-1]===P){n.pop();continue}return e}if(c||_)this.flushText(c,_,E,d),c="",_="";e++;let R=e,N=this.readTagName(t,e,r),A=this.extractTagName(t,R,N);if(!A){e=N+1;continue}e=N;let u=T?E?`${E}.${A}`:A:"",f={},w=!1;if(!this._ignoreAttributes){let I=this.parseAttributes(t,e,r,u,f);if(I<0)e=-I-1,w=!0;else e=I}else while(e<r){let I=t.charCodeAt(e);if(I===62||I===47)break;if(I===34||I===39){e++;while(e<r&&t.charCodeAt(e)!==I)e++}e++}if(this.options.updateTag){if(this.options.updateTag(A,u,f)===!1){while(e<r&&Ar(t.charCodeAt(e)))e++;if(e<r&&t.charCodeAt(e)===47)e+=2;else if(e<r&&t.charCodeAt(e)===62){e++;let a=`</${A}>`,P=t.indexOf(a,e);if(P!==-1)e=P+a.length}continue}}while(e<r&&Ar(t.charCodeAt(e)))e++;if(e<r&&t.charCodeAt(e)===47){if(e+=2,w||this._alwaysCreateTextNode){let I={};if(w)this.applyAttributes(I,f,u);if(this._alwaysCreateTextNode)I[this._textNodeName]="";this.addToObj(d,A,I,u,!0,!1)}else this.addToObj(d,A,"",u,!0,!1);continue}if(e<r&&t.charCodeAt(e)===62){if(e++,this.unpairedSet.has(A)){if(w){let j={};this.applyAttributes(j,f,u),this.addToObj(d,A,j,u,!0,!1)}else this.addToObj(d,A,"",u,!0,!1);n.push(A);continue}if(this.exactStopNodes.size>0||this.wildcardStopSuffixes.length>0){if(this.isStopNode(u)){let j=this.readStopNodeContent(t,e,r,A),H={};if(w)this.applyAttributes(H,f,u);if(j.content)H[this._textNodeName]=j.content;this.addToObj(d,A,H,u,!0,!1),e=j.pos;continue}}let I={};if(w)this.applyAttributes(I,f,u);e=this.parseChildren(t,e,r,I,u,n);let a=this._textNodeName,P=I[a];if(!w&&!this._alwaysCreateTextNode){let j=!0;for(let H in I)if(H!==a){j=!1;break}if(j){this.addToObj(d,A,P!==void 0?P:"",u,!0,!1);continue}}this.addToObj(d,A,I,u,!1,!1)}}if(c||_)this.flushText(c,_,E,d);return e}parseChildrenOrdered(t,e,r,d,E){let n="",c=this.needsJPath;while(e<r){if(t.charCodeAt(e)!==60){let w=e;e++;while(e<r&&t.charCodeAt(e)!==60)e++;if(!n)n=t.substring(w,e);else n+=t.substring(w,e);continue}if(e+1>=r)break;let T=t.charCodeAt(e+1);if(T===33&&e+3<r&&t.charCodeAt(e+2)===45&&t.charCodeAt(e+3)===45){if(n){let I=this.processTagValue(n,this._textNodeName,E,!1,!0);if(I!==void 0&&I!=="")d.push({[this._textNodeName]:I});n=""}e+=4;let w=t.indexOf("-->",e);if(w===-1){e=r;break}if(this._commentPropName)d.push({[this._commentPropName]:[{[this._textNodeName]:t.substring(e,w)}]});e=w+3;continue}if(T===33&&e+8<r&&z0(t,e+2)){e+=9;let w=t.indexOf("]]>",e);if(w===-1){e=r;break}let I=t.substring(e,w);if(this._cdataPropName){if(n){let a=this.processTagValue(n,this._textNodeName,E,!1,!0);if(a!==void 0&&a!=="")d.push({[this._textNodeName]:a});n=""}d.push({[this._cdataPropName]:[{[this._textNodeName]:I}]})}else n+=I;e=w+3;continue}if(T===33&&e+9<r&&F0(t,e+2)){e+=9;let w=1;while(e<r&&w>0){let I=t.charCodeAt(e);if(I===60)w++;else if(I===62)w--;e++}continue}if(T===63){e+=2;let w=t.indexOf("?>",e);if(w===-1){e=r;break}e=w+2;continue}if(T===47){if(n){let I=this.processTagValue(n,this._textNodeName,E,!1,!0);if(I!==void 0&&I!=="")d.push({[this._textNodeName]:I});n=""}e+=2,e=this.readTagName(t,e,r);while(e<r&&Ar(t.charCodeAt(e)))e++;if(e<r&&t.charCodeAt(e)===62)e++;return e}if(n){let w=this.processTagValue(n,this._textNodeName,E,!1,!0);if(w!==void 0&&w!=="")d.push({[this._textNodeName]:w});n=""}e++;let i=e,h=this.readTagName(t,e,r),R=this.extractTagName(t,i,h);if(!R){e=h+1;continue}e=h;let N=c?E?`${E}.${R}`:R:"",A={},u=!1;if(!this._ignoreAttributes){let w=this.parseAttributes(t,e,r,N,A);if(w<0)e=-w-1,u=!0;else e=w}else while(e<r){let w=t.charCodeAt(e);if(w===62||w===47)break;if(w===34||w===39){e++;while(e<r&&t.charCodeAt(e)!==w)e++}e++}while(e<r&&Ar(t.charCodeAt(e)))e++;let f={[R]:[]};if(u){f[":@"]={};for(let I in A)f[":@"][this._attrPrefix+I]=this.parseAttributeValue(A[I])}if(e<r&&t.charCodeAt(e)===47){e+=2,d.push(f);continue}if(e<r&&t.charCodeAt(e)===62)e++,e=this.parseChildrenOrdered(t,e,r,f[R],N),d.push(f)}if(n){let _=this.processTagValue(n,this._textNodeName,E,!1,!0);if(_!==void 0&&_!=="")d.push({[this._textNodeName]:_})}return e}applyAttributes(t,e,r){let d=this._attrPrefix;if(this._attrsGroupName){let E={};for(let n in e)E[d+n]=this.parseAttributeValue(e[n]);t[this._attrsGroupName]=E}else for(let E in e)t[d+E]=this.parseAttributeValue(e[E])}parsePiAttributes(t){let e={},r=0,d=t.length;while(r<d){while(r<d&&Ar(t.charCodeAt(r)))r++;if(r>=d)break;let E=r;while(r<d&&!Ar(t.charCodeAt(r))&&t.charCodeAt(r)!==61)r++;let n=t.substring(E,r);if(!n)break;while(r<d&&Ar(t.charCodeAt(r)))r++;if(r<d&&t.charCodeAt(r)===61){r++;while(r<d&&Ar(t.charCodeAt(r)))r++;if(r<d){let c=t.charCodeAt(r);if(c===34||c===39){r++;let _=r;while(r<d&&t.charCodeAt(r)!==c)r++;if(e[n]=t.substring(_,r),r<d)r++}}}}return e}}var fy,Uy,d_,wy,gy,$y,yy;var H0=gr(()=>{fy={amp:"&",lt:"<",gt:">",quot:'"',apos:"'"},Uy={nbsp:" ",copy:"©",reg:"®",trade:"™",euro:"€",pound:"£",yen:"¥",cent:"¢",deg:"°",micro:"µ",middot:"·",bull:"•",hellip:"…",prime:"′",Prime:"″",laquo:"«",raquo:"»",lsquo:"‘",rsquo:"’",ldquo:"“",rdquo:"”",ndash:"–",mdash:"—",iexcl:"¡",iquest:"¿",sect:"§",para:"¶",dagger:"†",Dagger:"‡",lsaquo:"‹",rsaquo:"›",oline:"‾",frasl:"⁄",ensp:" ",emsp:" ",thinsp:" ",zwnj:"",zwj:"",lrm:"",rlm:"",times:"×",divide:"÷",plusmn:"±",ne:"≠",le:"≤",ge:"≥",infin:"∞",fnof:"ƒ",Alpha:"Α",Beta:"Β",Gamma:"Γ",Delta:"Δ",Epsilon:"Ε",Zeta:"Ζ",Eta:"Η",Theta:"Θ",Iota:"Ι",Kappa:"Κ",Lambda:"Λ",Mu:"Μ",Nu:"Ν",Xi:"Ξ",Omicron:"Ο",Pi:"Π",Rho:"Ρ",Sigma:"Σ",Tau:"Τ",Upsilon:"Υ",Phi:"Φ",Chi:"Χ",Psi:"Ψ",Omega:"Ω",alpha:"α",beta:"β",gamma:"γ",delta:"δ",epsilon:"ε",zeta:"ζ",eta:"η",theta:"θ",iota:"ι",kappa:"κ",lambda:"λ",mu:"μ",nu:"ν",xi:"ξ",omicron:"ο",pi:"π",rho:"ρ",sigmaf:"ς",sigma:"σ",tau:"τ",upsilon:"υ",phi:"φ",chi:"χ",psi:"ψ",omega:"ω",thetasym:"ϑ",upsih:"ϒ",piv:"ϖ",larr:"←",uarr:"↑",rarr:"→",darr:"↓",harr:"↔",crarr:"↵",lArr:"⇐",uArr:"⇑",rArr:"⇒",dArr:"⇓",hArr:"⇔",forall:"∀",part:"∂",exist:"∃",empty:"∅",nabla:"∇",isin:"∈",notin:"∉",ni:"∋",prod:"∏",sum:"∑",minus:"−",lowast:"∗",radic:"√",prop:"∝",ang:"∠",and:"∧",or:"∨",cap:"∩",cup:"∪",int:"∫",there4:"∴",sim:"∼",cong:"≅",asymp:"≈",equiv:"≡",sub:"⊂",sup:"⊃",nsub:"⊄",sube:"⊆",supe:"⊇",oplus:"⊕",otimes:"⊗",perp:"⊥",sdot:"⋅",lceil:"⌈",rceil:"⌉",lfloor:"⌊",rfloor:"⌋",lang:"〈",rang:"〉",loz:"◊",spades:"♠",clubs:"♣",hearts:"♥",diams:"♦",Agrave:"À",Aacute:"Á",Acirc:"Â",Atilde:"Ã",Auml:"Ä",Aring:"Å",AElig:"Æ",Ccedil:"Ç",Egrave:"È",Eacute:"É",Ecirc:"Ê",Euml:"Ë",Igrave:"Ì",Iacute:"Í",Icirc:"Î",Iuml:"Ï",ETH:"Ð",Ntilde:"Ñ",Ograve:"Ò",Oacute:"Ó",Ocirc:"Ô",Otilde:"Õ",Ouml:"Ö",Oslash:"Ø",Ugrave:"Ù",Uacute:"Ú",Ucirc:"Û",Uuml:"Ü",Yacute:"Ý",THORN:"Þ",szlig:"ß",agrave:"à",aacute:"á",acirc:"â",atilde:"ã",auml:"ä",aring:"å",aelig:"æ",ccedil:"ç",egrave:"è",eacute:"é",ecirc:"ê",euml:"ë",igrave:"ì",iacute:"í",icirc:"î",iuml:"ï",eth:"ð",ntilde:"ñ",ograve:"ò",oacute:"ó",ocirc:"ô",otilde:"õ",ouml:"ö",oslash:"ø",ugrave:"ù",uacute:"ú",ucirc:"û",uuml:"ü",yacute:"ý",thorn:"þ",yuml:"ÿ",OElig:"Œ",oelig:"œ",Scaron:"Š",scaron:"š",Yuml:"Ÿ",circ:"ˆ",tilde:"˜"};d_=[];d_[38]="&";d_[60]="<";d_[62]=">";d_[34]=""";d_[39]="'";wy={attributeNamePrefix:"@_",attributesGroupName:!1,textNodeName:"#text",ignoreAttributes:!0,removeNSPrefix:!1,allowBooleanAttributes:!1,alwaysCreateTextNode:!1,trimValues:!0,parseTagValue:!0,parseAttributeValue:!1,processEntities:!0,htmlEntities:!1,commentPropName:!1,cdataPropName:!1,piPropName:!1,preserveOrder:!1,stopNodes:[],unpairedTags:[],isArray:void 0,tagValueProcessor:void 0,attributeValueProcessor:void 0,updateTag:void 0,numberParseOptions:{hex:!0,leadingZeros:!0,scientific:!0},ignorePiTags:!1,transformAttributeName:void 0,transformTagName:void 0,ignoreDeclaration:!1};gy=/^0x[\da-fA-F]+$/,$y=/^[+-]?\d+(\.\d+)?[eE][+-]?\d+$/,yy=/^[+-]?(\d+\.?\d*|\.\d+)$/});var Y0={};ER(Y0,{resolveS3Endpoint:()=>E_,detectCredentialSource:()=>Py,buildQueryParams:()=>Qt,AWSClient:()=>dt});import*as Yd from"node:crypto";import{existsSync as W0,readFileSync as ay}from"node:fs";import{homedir as v0}from"node:os";import{join as Q0}from"node:path";function E_(t){let e=t.endpoint||`s3.${t.region}.amazonaws.com`,r=new URL(/^https?:\/\//i.test(e)?e:`https://${e}`);if(r.protocol!=="http:"&&r.protocol!=="https:"||r.pathname!=="/"&&r.pathname!==""||r.search||r.hash||r.username||r.password)throw Error("S3 endpoint must be an HTTP(S) origin without a path");let d=r.protocol.slice(0,-1),E=r.host;if(!t.bucket)return{protocol:d,host:E,path:t.path};if(t.forcePathStyle){let n=t.path==="/"?`/${t.bucket}`:`/${t.bucket}${t.path}`;return{protocol:d,host:E,path:n}}return{protocol:d,host:`${t.bucket}.${E}`,path:t.path}}class dt{credentials;config;cache;xmlParser;constructor(t,e){this.config={maxRetries:3,retryDelay:1000,cacheEnabled:!0,defaultCacheTTL:60000,...e},this.credentials=t||this.loadCredentials(),this.cache=new Map,this.xmlParser=new BS({ignoreAttributes:!1,attributeNamePrefix:"@_",textNodeName:"#text",parseAttributeValue:!0,trimValues:!0})}loadCredentials(){let t=process.env.AWS_ACCESS_KEY_ID,e=process.env.AWS_SECRET_ACCESS_KEY,r=process.env.AWS_SESSION_TOKEN;if(t&&e)return{accessKeyId:t,secretAccessKey:e,sessionToken:r};let d=this.loadCredentialsFromFile();if(d)return d;return{accessKeyId:"",secretAccessKey:""}}loadCredentialsFromFile(){let t=this.config?.profile||process.env.AWS_PROFILE||"default",e=process.env.AWS_SHARED_CREDENTIALS_FILE||Q0(v0(),".aws","credentials");if(!W0(e))return null;try{let r=ay(e,"utf-8"),d=this.parseCredentialsFile(r,t);if(d.accessKeyId&&d.secretAccessKey)return d}catch{}return null}parseCredentialsFile(t,e){let r=t.split(`
|
|
3942
3942
|
`),d="",E="",n="",c;for(let _ of r){let T=_.trim();if(!T||T.startsWith("#"))continue;let i=T.match(/^\[([^\]]+)\]$/);if(i){d=i[1];continue}if(d===e){let[h,...R]=T.split("="),N=R.join("=").trim();if(h.trim()==="aws_access_key_id")E=N;else if(h.trim()==="aws_secret_access_key")n=N;else if(h.trim()==="aws_session_token")c=N}}return{accessKeyId:E,secretAccessKey:n,sessionToken:c}}ec2CredentialsCache;async getCredentials(){let t=process.env.AWS_ACCESS_KEY_ID,e=process.env.AWS_SECRET_ACCESS_KEY;if(t&&e)return{accessKeyId:t,secretAccessKey:e,sessionToken:process.env.AWS_SESSION_TOKEN};let r=this.loadCredentialsFromFile();if(r)return r;if(this.ec2CredentialsCache){let d=Date.now();if(this.ec2CredentialsCache.expiration>d+300000)return this.ec2CredentialsCache.credentials}try{let E=await(await fetch("http://169.254.169.254/latest/api/token",{method:"PUT",headers:{"X-aws-ec2-metadata-token-ttl-seconds":"21600"}})).text(),c=await(await fetch("http://169.254.169.254/latest/meta-data/iam/security-credentials/",{headers:{"X-aws-ec2-metadata-token":E}})).text(),T=await(await fetch(`http://169.254.169.254/latest/meta-data/iam/security-credentials/${c}`,{headers:{"X-aws-ec2-metadata-token":E}})).json(),i={accessKeyId:T.AccessKeyId,secretAccessKey:T.SecretAccessKey,sessionToken:T.Token};return this.ec2CredentialsCache={credentials:i,expiration:new Date(T.Expiration).getTime()},i}catch(d){throw Error("AWS credentials not found. Set AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment variables, or run on an EC2 instance with an IAM role.")}}async request(t){if(t.method==="GET"&&this.config.cacheEnabled&&t.cacheKey){let d=this.getFromCache(t.cacheKey);if(d!==null)return d}let e=t.retries??this.config.maxRetries??3,r=null;for(let d=0;d<=e;d++)try{let E=await this.makeRequest(t);if(t.method==="GET"&&this.config.cacheEnabled&&t.cacheKey)this.setInCache(t.cacheKey,E,t.cacheTTL??this.config.defaultCacheTTL??60000);return E}catch(E){if(r=E,!this.shouldRetry(E))throw E;if(d===e)throw E;let c=this.calculateRetryDelay(d);await this.sleep(c)}throw r||Error("Request failed after retries")}async makeRequest(t){let e=t.credentials||(this.credentials?.accessKeyId?this.credentials:await this.getCredentials());if(!e||!e.accessKeyId||!e.secretAccessKey)throw Error("AWS credentials not provided");let r=this.buildUrl(t),d=this.signRequest(t,e),E=await fetch(r,{method:t.method,headers:d,body:t.body}),n=await E.text();if(!E.ok)throw this.parseError(n,E.status,E.headers);if(!n||n.trim()===""){if(t.returnHeaders)return{body:null,headers:this.headersToObject(E.headers)};return null}if(t.rawResponse){if(t.returnHeaders)return{body:n,headers:this.headersToObject(E.headers)};return n}let c;if(n.startsWith("<"))c=this.parseXmlResponse(n);else try{c=JSON.parse(n)}catch{c=n}if(t.returnHeaders)return{body:c,headers:this.headersToObject(E.headers)};return c}headersToObject(t){let e={};return t.forEach((r,d)=>{e[d]=r}),e}buildUrl(t){let{service:e,region:r,queryParams:d}=t,{path:E}=t,n,c="https";if(e==="s3"){let T=E_({region:r,path:E,bucket:t.bucket,endpoint:this.config.endpoint,forcePathStyle:this.config.forcePathStyle});c=T.protocol,n=T.host,E=T.path}else if(e==="cloudfront")n="cloudfront.amazonaws.com";else if(e==="iam")n="iam.amazonaws.com";else if(e==="route53")n="route53.amazonaws.com";else if(e==="route53domains")n="route53domains.us-east-1.amazonaws.com";else if(e==="ecr")n=`api.ecr.${r}.amazonaws.com`;else if(e==="ses")n=`email.${r}.amazonaws.com`;else n=`${e}.${r}.amazonaws.com`;let _=`${c}://${n}${E}`;if(d&&Object.keys(d).length>0){let T=Object.keys(d).map((i)=>`${this.uriEncode(i)}=${this.uriEncode(d[i])}`).join("&");_+=`?${T}`}return _}signRequest(t,e){let{service:r,region:d,method:E,queryParams:n,body:c}=t,{path:_}=t,T=new Date,i=this.getAmzDate(T),h=this.getDateStamp(T),R;if(r==="s3"){let q=E_({region:d,path:_,bucket:t.bucket,endpoint:this.config.endpoint,forcePathStyle:this.config.forcePathStyle});R=q.host,_=q.path}else if(r==="cloudfront")R="cloudfront.amazonaws.com";else if(r==="iam")R="iam.amazonaws.com";else if(r==="route53")R="route53.amazonaws.com";else if(r==="route53domains")R="route53domains.us-east-1.amazonaws.com";else if(r==="ecr")R=`api.ecr.${d}.amazonaws.com`;else if(r==="ses")R=`email.${d}.amazonaws.com`;else R=`${r}.${d}.amazonaws.com`;let N={host:R,"x-amz-date":i,...t.headers||{}};if(e.sessionToken)N["x-amz-security-token"]=e.sessionToken;if(c){if(!Object.keys(N).some((ht)=>ht.toLowerCase()==="content-type"))N["content-type"]="application/x-www-form-urlencoded";N["content-length"]=Buffer.byteLength(c).toString()}let A=this.sha256(c||"");N["x-amz-content-sha256"]=A;let u=_,f=n?Object.keys(n).sort().map((q)=>`${this.uriEncode(q)}=${this.uriEncode(n[q])}`).join("&"):"",w=Object.keys(N).sort((q,ht)=>q.toLowerCase().localeCompare(ht.toLowerCase())),I=w.map((q)=>`${q.toLowerCase()}:${N[q].trim()}
|
|
3943
3943
|
`).join(""),a=w.map((q)=>q.toLowerCase()).join(";"),P=[E,u,f,I,a,A].join(`
|
|
3944
3944
|
`),j="AWS4-HMAC-SHA256",H=r;if(r==="email")H="ses";let F=`${h}/${d}/${H}/aws4_request`,B=[j,i,F,this.sha256(P)].join(`
|
|
3945
|
-
`),Z=this.getSignatureKey(e.secretAccessKey,h,d,H),o=this.hmac(Z,B),tt=`${j} Credential=${e.accessKeyId}/${F}, SignedHeaders=${a}, Signature=${o}`;return{...N,Authorization:tt}}getAmzDate(t){return t.toISOString().replace(/[:-]|\.\d{3}/g,"")}getDateStamp(t){return t.toISOString().slice(0,10).replace(/-/g,"")}uriEncode(t){return encodeURIComponent(t).replace(/[!'()*]/g,(e)=>`%${e.charCodeAt(0).toString(16).toUpperCase()}`)}sha256(t){return Yd.createHash("sha256").update(t,"utf8").digest("hex")}hmac(t,e){return Yd.createHmac("sha256",t).update(e,"utf8").digest("hex")}getSignatureKey(t,e,r,d){let E=Yd.createHmac("sha256",`AWS4${t}`).update(e).digest(),n=Yd.createHmac("sha256",E).update(r).digest(),c=Yd.createHmac("sha256",n).update(d).digest();return Yd.createHmac("sha256",c).update("aws4_request").digest()}parseXmlResponse(t){try{let e=this.xmlParser.parse(t);if(e.ErrorResponse)throw this.createErrorFromXml(e.ErrorResponse.Error);let r=Object.keys(e);if(r.length===1)return e[r[0]];return e}catch(e){if(e.code||e.statusCode)throw e;return{}}}parseError(t,e,r){let d=Error();if(d.statusCode=e,d.requestId=r.get("x-amzn-requestid")||r.get("x-amz-request-id")||void 0,t.startsWith("<"))try{let E=this.xmlParser.parse(t);if(E.ErrorResponse?.Error){let n=E.ErrorResponse.Error;return d.code=n.Code,d.message=`AWS Error [${n.Code}]: ${n.Message||"Unknown error"}`,d.type=n.Type,d}if(E.Error)return d.code=E.Error.Code,d.message=`AWS Error [${E.Error.Code}]: ${E.Error.Message||"Unknown error"}`,d}catch{}try{let E=JSON.parse(t);if(E.__type||E.code)return d.code=E.__type||E.code,d.message=`AWS Error [${d.code}]: ${E.message||E.Message||"Unknown error"}`,d}catch{}return d.message=`AWS API Error (${e}): ${t}`,d}createErrorFromXml(t){let e=Error();return e.code=t.Code,e.message=`AWS Error [${t.Code}]: ${t.Message||"Unknown error"}`,e.type=t.Type,e}isRetryableError(t){return["RequestTimeout","RequestTimeoutException","PriorRequestNotComplete","ConnectionError","ThrottlingException","Throttling","TooManyRequestsException","ProvisionedThroughputExceededException","RequestLimitExceeded","BandwidthLimitExceeded","SlowDown","ServiceUnavailable","ServiceUnavailableException","InternalError","InternalFailure","InternalServerError","InternalServiceException","TransientError","TransientFailure","IDPCommunicationErrorException","NetworkError","ConnectionRefusedException","EC2ThrottledException","503 Slow Down","500 InternalError"].includes(t)}isRetryableStatusCode(t){return t>=500||t===429}shouldRetry(t){if(t.name==="FetchError"||t.name==="TypeError"||t.code==="ECONNRESET")return!0;if(t.code&&this.isRetryableError(t.code))return!0;if(t.statusCode&&this.isRetryableStatusCode(t.statusCode))return!0;if(t.statusCode&&t.statusCode>=400&&t.statusCode<500&&t.statusCode!==429)return!1;if(t.statusCode)return!1;return!0}calculateRetryDelay(t){let e=this.config.retryDelay??1000,r=30000,d=Math.min(e*2**t,30000),E=Math.random()*0.3*d;return d+E}sleep(t){return new Promise((e)=>setTimeout(e,t))}getFromCache(t){let e=this.cache.get(t);if(!e)return null;if(Date.now()>e.expires)return this.cache.delete(t),null;return e.data}setInCache(t,e,r){this.cache.set(t,{data:e,expires:Date.now()+r})}clearCache(){this.cache.clear()}clearExpiredCache(){let t=Date.now();for(let[e,r]of this.cache.entries())if(t>r.expires)this.cache.delete(e)}}function Qt(t){let e={};for(let[r,d]of Object.entries(t)){if(d===void 0||d===null)continue;if(Array.isArray(d))d.forEach((E,n)=>{e[`${r}.${n+1}`]=String(E)});else if(typeof d==="object")for(let[E,n]of Object.entries(d))e[`${r}.${E}`]=String(n);else e[r]=String(d)}return e}function Py(){let t=process.env.AWS_ACCESS_KEY_ID,e=process.env.AWS_SECRET_ACCESS_KEY,r=t==="",d=e==="";if(t&&e)return{source:"env",emptyEnvKey:r,emptyEnvSecret:d,description:"environment variables (AWS_ACCESS_KEY_ID + AWS_SECRET_ACCESS_KEY)"};let E=process.env.AWS_PROFILE||"default",n=process.env.AWS_SHARED_CREDENTIALS_FILE||Q0(v0(),".aws","credentials");if(W0(n))return{source:"file",profile:E,emptyEnvKey:r,emptyEnvSecret:d,description:`~/.aws/credentials (profile: ${E})`};return{source:"ec2",emptyEnvKey:r,emptyEnvSecret:d,description:"EC2 instance metadata service (IMDSv2)"}}var Lt=wr(()=>{H0()});function jy(t,e){let r=[`Action=${t}`,"Version=2010-05-08"];for(let[d,E]of Object.entries(e)){if(E===void 0||E===null)continue;if(Array.isArray(E))E.forEach((n,c)=>{if(typeof n==="object"&&n!==null)for(let[_,T]of Object.entries(n))r.push(`${d}.member.${c+1}.${_}=${encodeURIComponent(String(T))}`);else r.push(`${d}.member.${c+1}=${encodeURIComponent(String(n))}`)});else if(typeof E==="object"){for(let[n,c]of Object.entries(E))if(c!==void 0&&c!==null)r.push(`${d}.${n}=${encodeURIComponent(String(c))}`)}else r.push(`${d}=${encodeURIComponent(String(E))}`)}return r.join("&")}function J(t,e){let r=new RegExp(`<${e}>([^<]*)</${e}>`),d=t.match(r);return d?d[1]:void 0}function Xe(t,e,r){let d=new RegExp(`<${e}>([\\s\\S]*?)</${e}>`),E=t.match(d);if(!E)return[];let n=[],c=new RegExp(`<${r}>([\\s\\S]*?)</${r}>`,"g"),_;while((_=c.exec(E[1]))!==null)n.push(_[1]);return n}class ZT{client;region;constructor(t="us-east-1",e){this.client=new dt(void 0,{profile:e}),this.region=t}async request(t,e={}){let r=jy(t,e);return await this.client.request({service:"iam",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:r})}async createUser(t){let e=await this.request("CreateUser",t);return this.parseUser(e)}async getUser(t={}){let e=await this.request("GetUser",t);return this.parseUser(e)}async listUsers(t={}){let e=await this.request("ListUsers",t),r=this.parseUsers(e),d=J(e,"IsTruncated")==="true",E=J(e,"Marker");return{Users:r,IsTruncated:d,Marker:E}}async updateUser(t){await this.request("UpdateUser",t)}async deleteUser(t){await this.request("DeleteUser",t)}parseUser(t){return{UserName:J(t,"UserName")||"",UserId:J(t,"UserId")||"",Arn:J(t,"Arn")||"",Path:J(t,"Path"),CreateDate:J(t,"CreateDate"),PasswordLastUsed:J(t,"PasswordLastUsed")}}parseUsers(t){return Xe(t,"Users","member").map((r)=>({UserName:J(r,"UserName")||"",UserId:J(r,"UserId")||"",Arn:J(r,"Arn")||"",Path:J(r,"Path"),CreateDate:J(r,"CreateDate"),PasswordLastUsed:J(r,"PasswordLastUsed")}))}async createGroup(t){let e=await this.request("CreateGroup",t);return this.parseGroup(e)}async getGroup(t){let e=await this.request("GetGroup",t),r=this.parseGroup(e),d=this.parseUsers(e),E=J(e,"IsTruncated")==="true",n=J(e,"Marker");return{Group:r,Users:d,IsTruncated:E,Marker:n}}async listGroups(t={}){let e=await this.request("ListGroups",t),r=this.parseGroups(e),d=J(e,"IsTruncated")==="true",E=J(e,"Marker");return{Groups:r,IsTruncated:d,Marker:E}}async updateGroup(t){await this.request("UpdateGroup",t)}async deleteGroup(t){await this.request("DeleteGroup",t)}async addUserToGroup(t){await this.request("AddUserToGroup",t)}async removeUserFromGroup(t){await this.request("RemoveUserFromGroup",t)}async listGroupsForUser(t){let e=await this.request("ListGroupsForUser",t),r=this.parseGroups(e),d=J(e,"IsTruncated")==="true",E=J(e,"Marker");return{Groups:r,IsTruncated:d,Marker:E}}parseGroup(t){return{GroupName:J(t,"GroupName")||"",GroupId:J(t,"GroupId")||"",Arn:J(t,"Arn")||"",Path:J(t,"Path"),CreateDate:J(t,"CreateDate")}}parseGroups(t){return Xe(t,"Groups","member").map((r)=>({GroupName:J(r,"GroupName")||"",GroupId:J(r,"GroupId")||"",Arn:J(r,"Arn")||"",Path:J(r,"Path"),CreateDate:J(r,"CreateDate")}))}async createRole(t){let e=await this.request("CreateRole",t);return this.parseRole(e)}async getRole(t){let e=await this.request("GetRole",t);return this.parseRole(e)}async listRoles(t={}){let e=await this.request("ListRoles",t),r=this.parseRoles(e),d=J(e,"IsTruncated")==="true",E=J(e,"Marker");return{Roles:r,IsTruncated:d,Marker:E}}async updateRole(t){await this.request("UpdateRole",t)}async updateRoleDescription(t){let e=await this.request("UpdateRoleDescription",t);return this.parseRole(e)}async updateAssumeRolePolicy(t){await this.request("UpdateAssumeRolePolicy",t)}async deleteRole(t){await this.request("DeleteRole",t)}async tagRole(t){await this.request("TagRole",t)}async untagRole(t){await this.request("UntagRole",t)}async listRoleTags(t){let e=await this.request("ListRoleTags",t),r=this.parseTags(e),d=J(e,"IsTruncated")==="true",E=J(e,"Marker");return{Tags:r,IsTruncated:d,Marker:E}}parseRole(t){return{RoleName:J(t,"RoleName")||"",RoleId:J(t,"RoleId")||"",Arn:J(t,"Arn")||"",Path:J(t,"Path"),CreateDate:J(t,"CreateDate"),AssumeRolePolicyDocument:J(t,"AssumeRolePolicyDocument"),Description:J(t,"Description"),MaxSessionDuration:J(t,"MaxSessionDuration")?Number.parseInt(J(t,"MaxSessionDuration"),10):void 0}}parseRoles(t){return Xe(t,"Roles","member").map((r)=>({RoleName:J(r,"RoleName")||"",RoleId:J(r,"RoleId")||"",Arn:J(r,"Arn")||"",Path:J(r,"Path"),CreateDate:J(r,"CreateDate"),AssumeRolePolicyDocument:J(r,"AssumeRolePolicyDocument"),Description:J(r,"Description"),MaxSessionDuration:J(r,"MaxSessionDuration")?Number.parseInt(J(r,"MaxSessionDuration"),10):void 0}))}parseTags(t){return Xe(t,"Tags","member").map((r)=>({Key:J(r,"Key")||"",Value:J(r,"Value")||""}))}async createPolicy(t){let e=await this.request("CreatePolicy",t);return this.parsePolicy(e)}async getPolicy(t){let e=await this.request("GetPolicy",t);return this.parsePolicy(e)}async getPolicyVersion(t){let e=await this.request("GetPolicyVersion",t);return{VersionId:J(e,"VersionId")||"",IsDefaultVersion:J(e,"IsDefaultVersion")==="true",CreateDate:J(e,"CreateDate"),Document:J(e,"Document")}}async listPolicies(t={}){let e=await this.request("ListPolicies",t),r=this.parsePolicies(e),d=J(e,"IsTruncated")==="true",E=J(e,"Marker");return{Policies:r,IsTruncated:d,Marker:E}}async listPolicyVersions(t){let e=await this.request("ListPolicyVersions",t),r=this.parsePolicyVersions(e),d=J(e,"IsTruncated")==="true",E=J(e,"Marker");return{Versions:r,IsTruncated:d,Marker:E}}async createPolicyVersion(t){let e=await this.request("CreatePolicyVersion",t);return{VersionId:J(e,"VersionId")||"",IsDefaultVersion:J(e,"IsDefaultVersion")==="true",CreateDate:J(e,"CreateDate")}}async deletePolicyVersion(t){await this.request("DeletePolicyVersion",t)}async setDefaultPolicyVersion(t){await this.request("SetDefaultPolicyVersion",t)}async deletePolicy(t){await this.request("DeletePolicy",t)}async attachUserPolicy(t){await this.request("AttachUserPolicy",t)}async detachUserPolicy(t){await this.request("DetachUserPolicy",t)}async attachGroupPolicy(t){await this.request("AttachGroupPolicy",t)}async detachGroupPolicy(t){await this.request("DetachGroupPolicy",t)}async attachRolePolicy(t){await this.request("AttachRolePolicy",t)}async detachRolePolicy(t){await this.request("DetachRolePolicy",t)}async listAttachedUserPolicies(t){let e=await this.request("ListAttachedUserPolicies",t),r=this.parseAttachedPolicies(e),d=J(e,"IsTruncated")==="true",E=J(e,"Marker");return{AttachedPolicies:r,IsTruncated:d,Marker:E}}async listAttachedGroupPolicies(t){let e=await this.request("ListAttachedGroupPolicies",t),r=this.parseAttachedPolicies(e),d=J(e,"IsTruncated")==="true",E=J(e,"Marker");return{AttachedPolicies:r,IsTruncated:d,Marker:E}}async listAttachedRolePolicies(t){let e=await this.request("ListAttachedRolePolicies",t),r=this.parseAttachedPolicies(e),d=J(e,"IsTruncated")==="true",E=J(e,"Marker");return{AttachedPolicies:r,IsTruncated:d,Marker:E}}parsePolicy(t){return{PolicyName:J(t,"PolicyName")||"",PolicyId:J(t,"PolicyId")||"",Arn:J(t,"Arn")||"",Path:J(t,"Path"),DefaultVersionId:J(t,"DefaultVersionId"),AttachmentCount:J(t,"AttachmentCount")?Number.parseInt(J(t,"AttachmentCount"),10):void 0,PermissionsBoundaryUsageCount:J(t,"PermissionsBoundaryUsageCount")?Number.parseInt(J(t,"PermissionsBoundaryUsageCount"),10):void 0,IsAttachable:J(t,"IsAttachable")==="true",Description:J(t,"Description"),CreateDate:J(t,"CreateDate"),UpdateDate:J(t,"UpdateDate")}}parsePolicies(t){return Xe(t,"Policies","member").map((r)=>({PolicyName:J(r,"PolicyName")||"",PolicyId:J(r,"PolicyId")||"",Arn:J(r,"Arn")||"",Path:J(r,"Path"),DefaultVersionId:J(r,"DefaultVersionId"),AttachmentCount:J(r,"AttachmentCount")?Number.parseInt(J(r,"AttachmentCount"),10):void 0,PermissionsBoundaryUsageCount:J(r,"PermissionsBoundaryUsageCount")?Number.parseInt(J(r,"PermissionsBoundaryUsageCount"),10):void 0,IsAttachable:J(r,"IsAttachable")==="true",Description:J(r,"Description"),CreateDate:J(r,"CreateDate"),UpdateDate:J(r,"UpdateDate")}))}parsePolicyVersions(t){return Xe(t,"Versions","member").map((r)=>({VersionId:J(r,"VersionId")||"",IsDefaultVersion:J(r,"IsDefaultVersion")==="true",CreateDate:J(r,"CreateDate")}))}parseAttachedPolicies(t){return Xe(t,"AttachedPolicies","member").map((r)=>({PolicyName:J(r,"PolicyName")||"",PolicyArn:J(r,"PolicyArn")||""}))}async putUserPolicy(t){await this.request("PutUserPolicy",t)}async getUserPolicy(t){let e=await this.request("GetUserPolicy",t);return{UserName:J(e,"UserName")||"",PolicyName:J(e,"PolicyName")||"",PolicyDocument:decodeURIComponent(J(e,"PolicyDocument")||"")}}async deleteUserPolicy(t){await this.request("DeleteUserPolicy",t)}async listUserPolicies(t){let e=await this.request("ListUserPolicies",t),r=Xe(e,"PolicyNames","member"),d=J(e,"IsTruncated")==="true",E=J(e,"Marker");return{PolicyNames:r,IsTruncated:d,Marker:E}}async putGroupPolicy(t){await this.request("PutGroupPolicy",t)}async getGroupPolicy(t){let e=await this.request("GetGroupPolicy",t);return{GroupName:J(e,"GroupName")||"",PolicyName:J(e,"PolicyName")||"",PolicyDocument:decodeURIComponent(J(e,"PolicyDocument")||"")}}async deleteGroupPolicy(t){await this.request("DeleteGroupPolicy",t)}async listGroupPolicies(t){let e=await this.request("ListGroupPolicies",t),r=Xe(e,"PolicyNames","member"),d=J(e,"IsTruncated")==="true",E=J(e,"Marker");return{PolicyNames:r,IsTruncated:d,Marker:E}}async putRolePolicy(t){await this.request("PutRolePolicy",t)}async getRolePolicy(t){let e=await this.request("GetRolePolicy",t);return{RoleName:J(e,"RoleName")||"",PolicyName:J(e,"PolicyName")||"",PolicyDocument:decodeURIComponent(J(e,"PolicyDocument")||"")}}async deleteRolePolicy(t){await this.request("DeleteRolePolicy",t)}async listRolePolicies(t){let e=await this.request("ListRolePolicies",t),r=Xe(e,"PolicyNames","member"),d=J(e,"IsTruncated")==="true",E=J(e,"Marker");return{PolicyNames:r,IsTruncated:d,Marker:E}}async createAccessKey(t={}){let e=await this.request("CreateAccessKey",t);if(typeof e==="object"){let r=e?.CreateAccessKeyResult?.AccessKey||e?.AccessKey;if(r)return{AccessKey:{UserName:r.UserName||"",AccessKeyId:r.AccessKeyId||"",Status:r.Status||"Active",SecretAccessKey:r.SecretAccessKey||"",CreateDate:r.CreateDate}}}return{AccessKey:{UserName:J(e,"UserName")||"",AccessKeyId:J(e,"AccessKeyId")||"",Status:J(e,"Status")||"Active",SecretAccessKey:J(e,"SecretAccessKey")||"",CreateDate:J(e,"CreateDate")}}}async listAccessKeys(t={}){let e=await this.request("ListAccessKeys",t),r=this.parseAccessKeys(e),d=J(e,"IsTruncated")==="true",E=J(e,"Marker");return{AccessKeyMetadata:r,IsTruncated:d,Marker:E}}async updateAccessKey(t){await this.request("UpdateAccessKey",t)}async deleteAccessKey(t){await this.request("DeleteAccessKey",t)}async getAccessKeyLastUsed(t){let e=await this.request("GetAccessKeyLastUsed",t);return{UserName:J(e,"UserName")||"",AccessKeyLastUsed:{LastUsedDate:J(e,"LastUsedDate"),ServiceName:J(e,"ServiceName"),Region:J(e,"Region")}}}parseAccessKeys(t){return Xe(t,"AccessKeyMetadata","member").map((r)=>({UserName:J(r,"UserName"),AccessKeyId:J(r,"AccessKeyId")||"",Status:J(r,"Status")||"Active",CreateDate:J(r,"CreateDate")}))}async createInstanceProfile(t){let e=await this.request("CreateInstanceProfile",t);return this.parseInstanceProfile(e)}async getInstanceProfile(t){let e=await this.request("GetInstanceProfile",t);return this.parseInstanceProfile(e)}async listInstanceProfiles(t={}){let e=await this.request("ListInstanceProfiles",t),r=this.parseInstanceProfiles(e),d=J(e,"IsTruncated")==="true",E=J(e,"Marker");return{InstanceProfiles:r,IsTruncated:d,Marker:E}}async listInstanceProfilesForRole(t){let e=await this.request("ListInstanceProfilesForRole",t),r=this.parseInstanceProfiles(e),d=J(e,"IsTruncated")==="true",E=J(e,"Marker");return{InstanceProfiles:r,IsTruncated:d,Marker:E}}async addRoleToInstanceProfile(t){await this.request("AddRoleToInstanceProfile",t)}async removeRoleFromInstanceProfile(t){await this.request("RemoveRoleFromInstanceProfile",t)}async deleteInstanceProfile(t){await this.request("DeleteInstanceProfile",t)}parseInstanceProfile(t){return{InstanceProfileName:J(t,"InstanceProfileName")||"",InstanceProfileId:J(t,"InstanceProfileId")||"",Arn:J(t,"Arn")||"",Path:J(t,"Path"),CreateDate:J(t,"CreateDate")}}parseInstanceProfiles(t){return Xe(t,"InstanceProfiles","member").map((r)=>({InstanceProfileName:J(r,"InstanceProfileName")||"",InstanceProfileId:J(r,"InstanceProfileId")||"",Arn:J(r,"Arn")||"",Path:J(r,"Path"),CreateDate:J(r,"CreateDate")}))}async getAccountPasswordPolicy(){let t=await this.request("GetAccountPasswordPolicy");return{MinimumPasswordLength:J(t,"MinimumPasswordLength")?Number.parseInt(J(t,"MinimumPasswordLength"),10):void 0,RequireSymbols:J(t,"RequireSymbols")==="true",RequireNumbers:J(t,"RequireNumbers")==="true",RequireUppercaseCharacters:J(t,"RequireUppercaseCharacters")==="true",RequireLowercaseCharacters:J(t,"RequireLowercaseCharacters")==="true",AllowUsersToChangePassword:J(t,"AllowUsersToChangePassword")==="true",ExpirePasswords:J(t,"ExpirePasswords")==="true",MaxPasswordAge:J(t,"MaxPasswordAge")?Number.parseInt(J(t,"MaxPasswordAge"),10):void 0,PasswordReusePrevention:J(t,"PasswordReusePrevention")?Number.parseInt(J(t,"PasswordReusePrevention"),10):void 0,HardExpiry:J(t,"HardExpiry")==="true"}}async updateAccountPasswordPolicy(t){await this.request("UpdateAccountPasswordPolicy",t)}async deleteAccountPasswordPolicy(){await this.request("DeleteAccountPasswordPolicy")}async getAccountSummary(){let t=await this.request("GetAccountSummary"),e={},r=Xe(t,"SummaryMap","entry");for(let d of r){let E=J(d,"key"),n=J(d,"value");if(E&&n)e[E]=Number.parseInt(n,10)}return e}async listAccountAliases(){let t=await this.request("ListAccountAliases"),e=Xe(t,"AccountAliases","member"),r=J(t,"IsTruncated")==="true",d=J(t,"Marker");return{AccountAliases:e,IsTruncated:r,Marker:d}}async createAccountAlias(t){await this.request("CreateAccountAlias",t)}async deleteAccountAlias(t){await this.request("DeleteAccountAlias",t)}async simulatePrincipalPolicy(t){let e=await this.request("SimulatePrincipalPolicy",t);return this.parseSimulationResults(e)}parseSimulationResults(t){let r=Xe(t,"EvaluationResults","member").map((n)=>{let _=Xe(n,"MatchedStatements","member").map((T)=>({SourcePolicyId:J(T,"SourcePolicyId"),SourcePolicyType:J(T,"SourcePolicyType")}));return{EvalActionName:J(n,"EvalActionName")||"",EvalResourceName:J(n,"EvalResourceName"),EvalDecision:J(n,"EvalDecision")||"",MatchedStatements:_.length>0?_:void 0}}),d=J(t,"IsTruncated")==="true",E=J(t,"Marker");return{EvaluationResults:r,IsTruncated:d,Marker:E}}}var kT=wr(()=>{Lt()});var Md;var n_=wr(()=>{Lt();Md=class Md{client;region;constructor(t="us-east-1"){this.region=t,this.client=new dt}async createHostedZone(t){let e=t.CallerReference||`${Date.now()}-${Math.random().toString(36).slice(2)}`,r=`<?xml version="1.0" encoding="UTF-8"?>
|
|
3945
|
+
`),Z=this.getSignatureKey(e.secretAccessKey,h,d,H),o=this.hmac(Z,B),tt=`${j} Credential=${e.accessKeyId}/${F}, SignedHeaders=${a}, Signature=${o}`;return{...N,Authorization:tt}}getAmzDate(t){return t.toISOString().replace(/[:-]|\.\d{3}/g,"")}getDateStamp(t){return t.toISOString().slice(0,10).replace(/-/g,"")}uriEncode(t){return encodeURIComponent(t).replace(/[!'()*]/g,(e)=>`%${e.charCodeAt(0).toString(16).toUpperCase()}`)}sha256(t){return Yd.createHash("sha256").update(t,"utf8").digest("hex")}hmac(t,e){return Yd.createHmac("sha256",t).update(e,"utf8").digest("hex")}getSignatureKey(t,e,r,d){let E=Yd.createHmac("sha256",`AWS4${t}`).update(e).digest(),n=Yd.createHmac("sha256",E).update(r).digest(),c=Yd.createHmac("sha256",n).update(d).digest();return Yd.createHmac("sha256",c).update("aws4_request").digest()}parseXmlResponse(t){try{let e=this.xmlParser.parse(t);if(e.ErrorResponse)throw this.createErrorFromXml(e.ErrorResponse.Error);let r=Object.keys(e);if(r.length===1)return e[r[0]];return e}catch(e){if(e.code||e.statusCode)throw e;return{}}}parseError(t,e,r){let d=Error();if(d.statusCode=e,d.requestId=r.get("x-amzn-requestid")||r.get("x-amz-request-id")||void 0,t.startsWith("<"))try{let E=this.xmlParser.parse(t);if(E.ErrorResponse?.Error){let n=E.ErrorResponse.Error;return d.code=n.Code,d.message=`AWS Error [${n.Code}]: ${n.Message||"Unknown error"}`,d.type=n.Type,d}if(E.Error)return d.code=E.Error.Code,d.message=`AWS Error [${E.Error.Code}]: ${E.Error.Message||"Unknown error"}`,d}catch{}try{let E=JSON.parse(t);if(E.__type||E.code)return d.code=E.__type||E.code,d.message=`AWS Error [${d.code}]: ${E.message||E.Message||"Unknown error"}`,d}catch{}return d.message=`AWS API Error (${e}): ${t}`,d}createErrorFromXml(t){let e=Error();return e.code=t.Code,e.message=`AWS Error [${t.Code}]: ${t.Message||"Unknown error"}`,e.type=t.Type,e}isRetryableError(t){return["RequestTimeout","RequestTimeoutException","PriorRequestNotComplete","ConnectionError","ThrottlingException","Throttling","TooManyRequestsException","ProvisionedThroughputExceededException","RequestLimitExceeded","BandwidthLimitExceeded","SlowDown","ServiceUnavailable","ServiceUnavailableException","InternalError","InternalFailure","InternalServerError","InternalServiceException","TransientError","TransientFailure","IDPCommunicationErrorException","NetworkError","ConnectionRefusedException","EC2ThrottledException","503 Slow Down","500 InternalError"].includes(t)}isRetryableStatusCode(t){return t>=500||t===429}shouldRetry(t){if(t.name==="FetchError"||t.name==="TypeError"||t.code==="ECONNRESET")return!0;if(t.code&&this.isRetryableError(t.code))return!0;if(t.statusCode&&this.isRetryableStatusCode(t.statusCode))return!0;if(t.statusCode&&t.statusCode>=400&&t.statusCode<500&&t.statusCode!==429)return!1;if(t.statusCode)return!1;return!0}calculateRetryDelay(t){let e=this.config.retryDelay??1000,r=30000,d=Math.min(e*2**t,30000),E=Math.random()*0.3*d;return d+E}sleep(t){return new Promise((e)=>setTimeout(e,t))}getFromCache(t){let e=this.cache.get(t);if(!e)return null;if(Date.now()>e.expires)return this.cache.delete(t),null;return e.data}setInCache(t,e,r){this.cache.set(t,{data:e,expires:Date.now()+r})}clearCache(){this.cache.clear()}clearExpiredCache(){let t=Date.now();for(let[e,r]of this.cache.entries())if(t>r.expires)this.cache.delete(e)}}function Qt(t){let e={};for(let[r,d]of Object.entries(t)){if(d===void 0||d===null)continue;if(Array.isArray(d))d.forEach((E,n)=>{e[`${r}.${n+1}`]=String(E)});else if(typeof d==="object")for(let[E,n]of Object.entries(d))e[`${r}.${E}`]=String(n);else e[r]=String(d)}return e}function Py(){let t=process.env.AWS_ACCESS_KEY_ID,e=process.env.AWS_SECRET_ACCESS_KEY,r=t==="",d=e==="";if(t&&e)return{source:"env",emptyEnvKey:r,emptyEnvSecret:d,description:"environment variables (AWS_ACCESS_KEY_ID + AWS_SECRET_ACCESS_KEY)"};let E=process.env.AWS_PROFILE||"default",n=process.env.AWS_SHARED_CREDENTIALS_FILE||Q0(v0(),".aws","credentials");if(W0(n))return{source:"file",profile:E,emptyEnvKey:r,emptyEnvSecret:d,description:`~/.aws/credentials (profile: ${E})`};return{source:"ec2",emptyEnvKey:r,emptyEnvSecret:d,description:"EC2 instance metadata service (IMDSv2)"}}var Lt=gr(()=>{H0()});function jy(t,e){let r=[`Action=${t}`,"Version=2010-05-08"];for(let[d,E]of Object.entries(e)){if(E===void 0||E===null)continue;if(Array.isArray(E))E.forEach((n,c)=>{if(typeof n==="object"&&n!==null)for(let[_,T]of Object.entries(n))r.push(`${d}.member.${c+1}.${_}=${encodeURIComponent(String(T))}`);else r.push(`${d}.member.${c+1}=${encodeURIComponent(String(n))}`)});else if(typeof E==="object"){for(let[n,c]of Object.entries(E))if(c!==void 0&&c!==null)r.push(`${d}.${n}=${encodeURIComponent(String(c))}`)}else r.push(`${d}=${encodeURIComponent(String(E))}`)}return r.join("&")}function J(t,e){let r=new RegExp(`<${e}>([^<]*)</${e}>`),d=t.match(r);return d?d[1]:void 0}function Xe(t,e,r){let d=new RegExp(`<${e}>([\\s\\S]*?)</${e}>`),E=t.match(d);if(!E)return[];let n=[],c=new RegExp(`<${r}>([\\s\\S]*?)</${r}>`,"g"),_;while((_=c.exec(E[1]))!==null)n.push(_[1]);return n}class ZT{client;region;constructor(t="us-east-1",e){this.client=new dt(void 0,{profile:e}),this.region=t}async request(t,e={}){let r=jy(t,e);return await this.client.request({service:"iam",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:r})}async createUser(t){let e=await this.request("CreateUser",t);return this.parseUser(e)}async getUser(t={}){let e=await this.request("GetUser",t);return this.parseUser(e)}async listUsers(t={}){let e=await this.request("ListUsers",t),r=this.parseUsers(e),d=J(e,"IsTruncated")==="true",E=J(e,"Marker");return{Users:r,IsTruncated:d,Marker:E}}async updateUser(t){await this.request("UpdateUser",t)}async deleteUser(t){await this.request("DeleteUser",t)}parseUser(t){return{UserName:J(t,"UserName")||"",UserId:J(t,"UserId")||"",Arn:J(t,"Arn")||"",Path:J(t,"Path"),CreateDate:J(t,"CreateDate"),PasswordLastUsed:J(t,"PasswordLastUsed")}}parseUsers(t){return Xe(t,"Users","member").map((r)=>({UserName:J(r,"UserName")||"",UserId:J(r,"UserId")||"",Arn:J(r,"Arn")||"",Path:J(r,"Path"),CreateDate:J(r,"CreateDate"),PasswordLastUsed:J(r,"PasswordLastUsed")}))}async createGroup(t){let e=await this.request("CreateGroup",t);return this.parseGroup(e)}async getGroup(t){let e=await this.request("GetGroup",t),r=this.parseGroup(e),d=this.parseUsers(e),E=J(e,"IsTruncated")==="true",n=J(e,"Marker");return{Group:r,Users:d,IsTruncated:E,Marker:n}}async listGroups(t={}){let e=await this.request("ListGroups",t),r=this.parseGroups(e),d=J(e,"IsTruncated")==="true",E=J(e,"Marker");return{Groups:r,IsTruncated:d,Marker:E}}async updateGroup(t){await this.request("UpdateGroup",t)}async deleteGroup(t){await this.request("DeleteGroup",t)}async addUserToGroup(t){await this.request("AddUserToGroup",t)}async removeUserFromGroup(t){await this.request("RemoveUserFromGroup",t)}async listGroupsForUser(t){let e=await this.request("ListGroupsForUser",t),r=this.parseGroups(e),d=J(e,"IsTruncated")==="true",E=J(e,"Marker");return{Groups:r,IsTruncated:d,Marker:E}}parseGroup(t){return{GroupName:J(t,"GroupName")||"",GroupId:J(t,"GroupId")||"",Arn:J(t,"Arn")||"",Path:J(t,"Path"),CreateDate:J(t,"CreateDate")}}parseGroups(t){return Xe(t,"Groups","member").map((r)=>({GroupName:J(r,"GroupName")||"",GroupId:J(r,"GroupId")||"",Arn:J(r,"Arn")||"",Path:J(r,"Path"),CreateDate:J(r,"CreateDate")}))}async createRole(t){let e=await this.request("CreateRole",t);return this.parseRole(e)}async getRole(t){let e=await this.request("GetRole",t);return this.parseRole(e)}async listRoles(t={}){let e=await this.request("ListRoles",t),r=this.parseRoles(e),d=J(e,"IsTruncated")==="true",E=J(e,"Marker");return{Roles:r,IsTruncated:d,Marker:E}}async updateRole(t){await this.request("UpdateRole",t)}async updateRoleDescription(t){let e=await this.request("UpdateRoleDescription",t);return this.parseRole(e)}async updateAssumeRolePolicy(t){await this.request("UpdateAssumeRolePolicy",t)}async deleteRole(t){await this.request("DeleteRole",t)}async tagRole(t){await this.request("TagRole",t)}async untagRole(t){await this.request("UntagRole",t)}async listRoleTags(t){let e=await this.request("ListRoleTags",t),r=this.parseTags(e),d=J(e,"IsTruncated")==="true",E=J(e,"Marker");return{Tags:r,IsTruncated:d,Marker:E}}parseRole(t){return{RoleName:J(t,"RoleName")||"",RoleId:J(t,"RoleId")||"",Arn:J(t,"Arn")||"",Path:J(t,"Path"),CreateDate:J(t,"CreateDate"),AssumeRolePolicyDocument:J(t,"AssumeRolePolicyDocument"),Description:J(t,"Description"),MaxSessionDuration:J(t,"MaxSessionDuration")?Number.parseInt(J(t,"MaxSessionDuration"),10):void 0}}parseRoles(t){return Xe(t,"Roles","member").map((r)=>({RoleName:J(r,"RoleName")||"",RoleId:J(r,"RoleId")||"",Arn:J(r,"Arn")||"",Path:J(r,"Path"),CreateDate:J(r,"CreateDate"),AssumeRolePolicyDocument:J(r,"AssumeRolePolicyDocument"),Description:J(r,"Description"),MaxSessionDuration:J(r,"MaxSessionDuration")?Number.parseInt(J(r,"MaxSessionDuration"),10):void 0}))}parseTags(t){return Xe(t,"Tags","member").map((r)=>({Key:J(r,"Key")||"",Value:J(r,"Value")||""}))}async createPolicy(t){let e=await this.request("CreatePolicy",t);return this.parsePolicy(e)}async getPolicy(t){let e=await this.request("GetPolicy",t);return this.parsePolicy(e)}async getPolicyVersion(t){let e=await this.request("GetPolicyVersion",t);return{VersionId:J(e,"VersionId")||"",IsDefaultVersion:J(e,"IsDefaultVersion")==="true",CreateDate:J(e,"CreateDate"),Document:J(e,"Document")}}async listPolicies(t={}){let e=await this.request("ListPolicies",t),r=this.parsePolicies(e),d=J(e,"IsTruncated")==="true",E=J(e,"Marker");return{Policies:r,IsTruncated:d,Marker:E}}async listPolicyVersions(t){let e=await this.request("ListPolicyVersions",t),r=this.parsePolicyVersions(e),d=J(e,"IsTruncated")==="true",E=J(e,"Marker");return{Versions:r,IsTruncated:d,Marker:E}}async createPolicyVersion(t){let e=await this.request("CreatePolicyVersion",t);return{VersionId:J(e,"VersionId")||"",IsDefaultVersion:J(e,"IsDefaultVersion")==="true",CreateDate:J(e,"CreateDate")}}async deletePolicyVersion(t){await this.request("DeletePolicyVersion",t)}async setDefaultPolicyVersion(t){await this.request("SetDefaultPolicyVersion",t)}async deletePolicy(t){await this.request("DeletePolicy",t)}async attachUserPolicy(t){await this.request("AttachUserPolicy",t)}async detachUserPolicy(t){await this.request("DetachUserPolicy",t)}async attachGroupPolicy(t){await this.request("AttachGroupPolicy",t)}async detachGroupPolicy(t){await this.request("DetachGroupPolicy",t)}async attachRolePolicy(t){await this.request("AttachRolePolicy",t)}async detachRolePolicy(t){await this.request("DetachRolePolicy",t)}async listAttachedUserPolicies(t){let e=await this.request("ListAttachedUserPolicies",t),r=this.parseAttachedPolicies(e),d=J(e,"IsTruncated")==="true",E=J(e,"Marker");return{AttachedPolicies:r,IsTruncated:d,Marker:E}}async listAttachedGroupPolicies(t){let e=await this.request("ListAttachedGroupPolicies",t),r=this.parseAttachedPolicies(e),d=J(e,"IsTruncated")==="true",E=J(e,"Marker");return{AttachedPolicies:r,IsTruncated:d,Marker:E}}async listAttachedRolePolicies(t){let e=await this.request("ListAttachedRolePolicies",t),r=this.parseAttachedPolicies(e),d=J(e,"IsTruncated")==="true",E=J(e,"Marker");return{AttachedPolicies:r,IsTruncated:d,Marker:E}}parsePolicy(t){return{PolicyName:J(t,"PolicyName")||"",PolicyId:J(t,"PolicyId")||"",Arn:J(t,"Arn")||"",Path:J(t,"Path"),DefaultVersionId:J(t,"DefaultVersionId"),AttachmentCount:J(t,"AttachmentCount")?Number.parseInt(J(t,"AttachmentCount"),10):void 0,PermissionsBoundaryUsageCount:J(t,"PermissionsBoundaryUsageCount")?Number.parseInt(J(t,"PermissionsBoundaryUsageCount"),10):void 0,IsAttachable:J(t,"IsAttachable")==="true",Description:J(t,"Description"),CreateDate:J(t,"CreateDate"),UpdateDate:J(t,"UpdateDate")}}parsePolicies(t){return Xe(t,"Policies","member").map((r)=>({PolicyName:J(r,"PolicyName")||"",PolicyId:J(r,"PolicyId")||"",Arn:J(r,"Arn")||"",Path:J(r,"Path"),DefaultVersionId:J(r,"DefaultVersionId"),AttachmentCount:J(r,"AttachmentCount")?Number.parseInt(J(r,"AttachmentCount"),10):void 0,PermissionsBoundaryUsageCount:J(r,"PermissionsBoundaryUsageCount")?Number.parseInt(J(r,"PermissionsBoundaryUsageCount"),10):void 0,IsAttachable:J(r,"IsAttachable")==="true",Description:J(r,"Description"),CreateDate:J(r,"CreateDate"),UpdateDate:J(r,"UpdateDate")}))}parsePolicyVersions(t){return Xe(t,"Versions","member").map((r)=>({VersionId:J(r,"VersionId")||"",IsDefaultVersion:J(r,"IsDefaultVersion")==="true",CreateDate:J(r,"CreateDate")}))}parseAttachedPolicies(t){return Xe(t,"AttachedPolicies","member").map((r)=>({PolicyName:J(r,"PolicyName")||"",PolicyArn:J(r,"PolicyArn")||""}))}async putUserPolicy(t){await this.request("PutUserPolicy",t)}async getUserPolicy(t){let e=await this.request("GetUserPolicy",t);return{UserName:J(e,"UserName")||"",PolicyName:J(e,"PolicyName")||"",PolicyDocument:decodeURIComponent(J(e,"PolicyDocument")||"")}}async deleteUserPolicy(t){await this.request("DeleteUserPolicy",t)}async listUserPolicies(t){let e=await this.request("ListUserPolicies",t),r=Xe(e,"PolicyNames","member"),d=J(e,"IsTruncated")==="true",E=J(e,"Marker");return{PolicyNames:r,IsTruncated:d,Marker:E}}async putGroupPolicy(t){await this.request("PutGroupPolicy",t)}async getGroupPolicy(t){let e=await this.request("GetGroupPolicy",t);return{GroupName:J(e,"GroupName")||"",PolicyName:J(e,"PolicyName")||"",PolicyDocument:decodeURIComponent(J(e,"PolicyDocument")||"")}}async deleteGroupPolicy(t){await this.request("DeleteGroupPolicy",t)}async listGroupPolicies(t){let e=await this.request("ListGroupPolicies",t),r=Xe(e,"PolicyNames","member"),d=J(e,"IsTruncated")==="true",E=J(e,"Marker");return{PolicyNames:r,IsTruncated:d,Marker:E}}async putRolePolicy(t){await this.request("PutRolePolicy",t)}async getRolePolicy(t){let e=await this.request("GetRolePolicy",t);return{RoleName:J(e,"RoleName")||"",PolicyName:J(e,"PolicyName")||"",PolicyDocument:decodeURIComponent(J(e,"PolicyDocument")||"")}}async deleteRolePolicy(t){await this.request("DeleteRolePolicy",t)}async listRolePolicies(t){let e=await this.request("ListRolePolicies",t),r=Xe(e,"PolicyNames","member"),d=J(e,"IsTruncated")==="true",E=J(e,"Marker");return{PolicyNames:r,IsTruncated:d,Marker:E}}async createAccessKey(t={}){let e=await this.request("CreateAccessKey",t);if(typeof e==="object"){let r=e?.CreateAccessKeyResult?.AccessKey||e?.AccessKey;if(r)return{AccessKey:{UserName:r.UserName||"",AccessKeyId:r.AccessKeyId||"",Status:r.Status||"Active",SecretAccessKey:r.SecretAccessKey||"",CreateDate:r.CreateDate}}}return{AccessKey:{UserName:J(e,"UserName")||"",AccessKeyId:J(e,"AccessKeyId")||"",Status:J(e,"Status")||"Active",SecretAccessKey:J(e,"SecretAccessKey")||"",CreateDate:J(e,"CreateDate")}}}async listAccessKeys(t={}){let e=await this.request("ListAccessKeys",t),r=this.parseAccessKeys(e),d=J(e,"IsTruncated")==="true",E=J(e,"Marker");return{AccessKeyMetadata:r,IsTruncated:d,Marker:E}}async updateAccessKey(t){await this.request("UpdateAccessKey",t)}async deleteAccessKey(t){await this.request("DeleteAccessKey",t)}async getAccessKeyLastUsed(t){let e=await this.request("GetAccessKeyLastUsed",t);return{UserName:J(e,"UserName")||"",AccessKeyLastUsed:{LastUsedDate:J(e,"LastUsedDate"),ServiceName:J(e,"ServiceName"),Region:J(e,"Region")}}}parseAccessKeys(t){return Xe(t,"AccessKeyMetadata","member").map((r)=>({UserName:J(r,"UserName"),AccessKeyId:J(r,"AccessKeyId")||"",Status:J(r,"Status")||"Active",CreateDate:J(r,"CreateDate")}))}async createInstanceProfile(t){let e=await this.request("CreateInstanceProfile",t);return this.parseInstanceProfile(e)}async getInstanceProfile(t){let e=await this.request("GetInstanceProfile",t);return this.parseInstanceProfile(e)}async listInstanceProfiles(t={}){let e=await this.request("ListInstanceProfiles",t),r=this.parseInstanceProfiles(e),d=J(e,"IsTruncated")==="true",E=J(e,"Marker");return{InstanceProfiles:r,IsTruncated:d,Marker:E}}async listInstanceProfilesForRole(t){let e=await this.request("ListInstanceProfilesForRole",t),r=this.parseInstanceProfiles(e),d=J(e,"IsTruncated")==="true",E=J(e,"Marker");return{InstanceProfiles:r,IsTruncated:d,Marker:E}}async addRoleToInstanceProfile(t){await this.request("AddRoleToInstanceProfile",t)}async removeRoleFromInstanceProfile(t){await this.request("RemoveRoleFromInstanceProfile",t)}async deleteInstanceProfile(t){await this.request("DeleteInstanceProfile",t)}parseInstanceProfile(t){return{InstanceProfileName:J(t,"InstanceProfileName")||"",InstanceProfileId:J(t,"InstanceProfileId")||"",Arn:J(t,"Arn")||"",Path:J(t,"Path"),CreateDate:J(t,"CreateDate")}}parseInstanceProfiles(t){return Xe(t,"InstanceProfiles","member").map((r)=>({InstanceProfileName:J(r,"InstanceProfileName")||"",InstanceProfileId:J(r,"InstanceProfileId")||"",Arn:J(r,"Arn")||"",Path:J(r,"Path"),CreateDate:J(r,"CreateDate")}))}async getAccountPasswordPolicy(){let t=await this.request("GetAccountPasswordPolicy");return{MinimumPasswordLength:J(t,"MinimumPasswordLength")?Number.parseInt(J(t,"MinimumPasswordLength"),10):void 0,RequireSymbols:J(t,"RequireSymbols")==="true",RequireNumbers:J(t,"RequireNumbers")==="true",RequireUppercaseCharacters:J(t,"RequireUppercaseCharacters")==="true",RequireLowercaseCharacters:J(t,"RequireLowercaseCharacters")==="true",AllowUsersToChangePassword:J(t,"AllowUsersToChangePassword")==="true",ExpirePasswords:J(t,"ExpirePasswords")==="true",MaxPasswordAge:J(t,"MaxPasswordAge")?Number.parseInt(J(t,"MaxPasswordAge"),10):void 0,PasswordReusePrevention:J(t,"PasswordReusePrevention")?Number.parseInt(J(t,"PasswordReusePrevention"),10):void 0,HardExpiry:J(t,"HardExpiry")==="true"}}async updateAccountPasswordPolicy(t){await this.request("UpdateAccountPasswordPolicy",t)}async deleteAccountPasswordPolicy(){await this.request("DeleteAccountPasswordPolicy")}async getAccountSummary(){let t=await this.request("GetAccountSummary"),e={},r=Xe(t,"SummaryMap","entry");for(let d of r){let E=J(d,"key"),n=J(d,"value");if(E&&n)e[E]=Number.parseInt(n,10)}return e}async listAccountAliases(){let t=await this.request("ListAccountAliases"),e=Xe(t,"AccountAliases","member"),r=J(t,"IsTruncated")==="true",d=J(t,"Marker");return{AccountAliases:e,IsTruncated:r,Marker:d}}async createAccountAlias(t){await this.request("CreateAccountAlias",t)}async deleteAccountAlias(t){await this.request("DeleteAccountAlias",t)}async simulatePrincipalPolicy(t){let e=await this.request("SimulatePrincipalPolicy",t);return this.parseSimulationResults(e)}parseSimulationResults(t){let r=Xe(t,"EvaluationResults","member").map((n)=>{let _=Xe(n,"MatchedStatements","member").map((T)=>({SourcePolicyId:J(T,"SourcePolicyId"),SourcePolicyType:J(T,"SourcePolicyType")}));return{EvalActionName:J(n,"EvalActionName")||"",EvalResourceName:J(n,"EvalResourceName"),EvalDecision:J(n,"EvalDecision")||"",MatchedStatements:_.length>0?_:void 0}}),d=J(t,"IsTruncated")==="true",E=J(t,"Marker");return{EvaluationResults:r,IsTruncated:d,Marker:E}}}var kT=gr(()=>{Lt()});var Md;var n_=gr(()=>{Lt();Md=class Md{client;region;constructor(t="us-east-1"){this.region=t,this.client=new dt}async createHostedZone(t){let e=t.CallerReference||`${Date.now()}-${Math.random().toString(36).slice(2)}`,r=`<?xml version="1.0" encoding="UTF-8"?>
|
|
3946
3946
|
<CreateHostedZoneRequest xmlns="https://route53.amazonaws.com/doc/2013-04-01/">
|
|
3947
3947
|
<Name>${t.Name}</Name>
|
|
3948
3948
|
<CallerReference>${e}</CallerReference>`;if(t.HostedZoneConfig){if(r+=`
|
|
@@ -4080,7 +4080,7 @@ host:${c}
|
|
|
4080
4080
|
<Quiet>true</Quiet>
|
|
4081
4081
|
${e.map((E)=>`<Object><Key>${E.Key}</Key>${E.VersionId?`<VersionId>${E.VersionId}</VersionId>`:""}</Object>`).join(`
|
|
4082
4082
|
`)}
|
|
4083
|
-
</Delete>`,d=it.createHash("md5").update(r).digest("base64");await this.client.request({service:"s3",region:this.region,method:"POST",path:`/${t}`,queryParams:{delete:""},body:r,headers:{"Content-Type":"application/xml","Content-MD5":d}})}}var tr=wr(()=>{Lt()});class bT{client;region;constructor(t="us-east-1",e){this.region=t,this.client=new dt(e)}async createEmailIdentity(t){return await this.client.request({service:"email",region:this.region,method:"POST",path:"/v2/email/identities",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)})}async getEmailIdentity(t){let e=await this.client.request({service:"email",region:this.region,method:"GET",path:`/v2/email/identities/${encodeURIComponent(t)}`,headers:{"Content-Type":"application/json"}});return{IdentityType:e.IdentityType,IdentityName:t,SendingEnabled:e.VerifiedForSendingStatus,VerificationStatus:e.VerificationStatus,DkimAttributes:e.DkimAttributes,MailFromAttributes:e.MailFromAttributes}}async putEmailIdentityMailFromAttributes(t,e){await this.client.request({service:"email",region:this.region,method:"PUT",path:`/v2/email/identities/${encodeURIComponent(t)}/mail-from`,headers:{"Content-Type":"application/json"},body:JSON.stringify(e)})}async listEmailIdentities(t){let e="/v2/email/identities",r=[];if(t?.PageSize)r.push(`PageSize=${t.PageSize}`);if(t?.NextToken)r.push(`NextToken=${encodeURIComponent(t.NextToken)}`);if(r.length>0)e+=`?${r.join("&")}`;let d=await this.client.request({service:"email",region:this.region,method:"GET",path:e,headers:{"Content-Type":"application/json"}});return{EmailIdentities:d.EmailIdentities,NextToken:d.NextToken}}async deleteEmailIdentity(t){await this.client.request({service:"email",region:this.region,method:"DELETE",path:`/v2/email/identities/${encodeURIComponent(t)}`,headers:{"Content-Type":"application/json"}})}async putEmailIdentityDkimAttributes(t){await this.client.request({service:"email",region:this.region,method:"PUT",path:`/v2/email/identities/${encodeURIComponent(t.EmailIdentity)}/dkim`,headers:{"Content-Type":"application/json"},body:JSON.stringify({SigningEnabled:t.SigningEnabled})})}async sendEmail(t){return{MessageId:(await this.client.request({service:"email",region:this.region,method:"POST",path:"/v2/email/outbound-emails",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)})).MessageId}}async sendBulkEmail(t){return{BulkEmailEntryResults:(await this.client.request({service:"email",region:this.region,method:"POST",path:"/v2/email/outbound-bulk-emails",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)})).BulkEmailEntryResults}}async createEmailTemplate(t){await this.client.request({service:"email",region:this.region,method:"POST",path:"/v2/email/templates",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)})}async getEmailTemplate(t){return await this.client.request({service:"email",region:this.region,method:"GET",path:`/v2/email/templates/${encodeURIComponent(t)}`,headers:{"Content-Type":"application/json"}})}async deleteEmailTemplate(t){await this.client.request({service:"email",region:this.region,method:"DELETE",path:`/v2/email/templates/${encodeURIComponent(t)}`,headers:{"Content-Type":"application/json"}})}async listEmailTemplates(t){let e="/v2/email/templates",r=[];if(t?.PageSize)r.push(`PageSize=${t.PageSize}`);if(t?.NextToken)r.push(`NextToken=${encodeURIComponent(t.NextToken)}`);if(r.length>0)e+=`?${r.join("&")}`;return await this.client.request({service:"email",region:this.region,method:"GET",path:e,headers:{"Content-Type":"application/json"}})}async getSendStatistics(){return{SendDataPoints:(await this.client.request({service:"ses",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:"Action=GetSendStatistics&Version=2010-12-01"})).GetSendStatisticsResponse?.GetSendStatisticsResult?.SendDataPoints?.member}}async getSendQuota(){let e=(await this.client.request({service:"ses",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:"Action=GetSendQuota&Version=2010-12-01"})).GetSendQuotaResponse?.GetSendQuotaResult;return{Max24HourSend:e?.Max24HourSend?Number(e.Max24HourSend):void 0,MaxSendRate:e?.MaxSendRate?Number(e.MaxSendRate):void 0,SentLast24Hours:e?.SentLast24Hours?Number(e.SentLast24Hours):void 0}}async verifyDomain(t){let e=await this.createEmailIdentity({EmailIdentity:t});return{dkimTokens:e.DkimAttributes?.Tokens,verificationStatus:e.DkimAttributes?.Status}}async sendSimpleEmail(t){let e=Array.isArray(t.to)?t.to:[t.to],r=t.replyTo?Array.isArray(t.replyTo)?t.replyTo:[t.replyTo]:void 0,d={};if(t.text)d.Text={Data:t.text};if(t.html)d.Html={Data:t.html};return this.sendEmail({FromEmailAddress:t.from,Destination:{ToAddresses:e},Content:{Simple:{Subject:{Data:t.subject},Body:d}},ReplyToAddresses:r})}async sendTemplatedEmail(t){let e=Array.isArray(t.to)?t.to:[t.to],r=t.replyTo?Array.isArray(t.replyTo)?t.replyTo:[t.replyTo]:void 0;return this.sendEmail({FromEmailAddress:t.from,Destination:{ToAddresses:e},Content:{Template:{TemplateName:t.templateName,TemplateData:JSON.stringify(t.templateData)}},ReplyToAddresses:r})}async getDkimRecords(t){let e=await this.getEmailIdentity(t);if(!e.DkimAttributes?.Tokens)return[];return e.DkimAttributes.Tokens.map((r)=>({name:`${r}._domainkey.${t}`,type:"CNAME",value:`${r}.dkim.amazonses.com`}))}async isDomainVerified(t){try{let e=await this.getEmailIdentity(t);return e.VerificationStatus==="SUCCESS"&&e.SendingEnabled===!0}catch{return!1}}async waitForDomainVerification(t,e=60,r=30000){for(let d=0;d<e;d++){if(await this.isDomainVerified(t))return!0;await new Promise((n)=>setTimeout(n,r))}return!1}buildFormBody(t){return Object.entries(t).filter(([,r])=>r!==void 0).map(([r,d])=>`${encodeURIComponent(r)}=${encodeURIComponent(d)}`).join("&")}async createReceiptRuleSet(t){await this.client.request({service:"ses",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:this.buildFormBody({Action:"CreateReceiptRuleSet",Version:"2010-12-01",RuleSetName:t})})}async deleteReceiptRuleSet(t){await this.client.request({service:"ses",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:this.buildFormBody({Action:"DeleteReceiptRuleSet",Version:"2010-12-01",RuleSetName:t})})}async setActiveReceiptRuleSet(t){await this.client.request({service:"ses",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:this.buildFormBody({Action:"SetActiveReceiptRuleSet",Version:"2010-12-01",RuleSetName:t})})}async listReceiptRuleSets(t){let e={Action:"ListReceiptRuleSets",Version:"2010-12-01"};if(t)e.NextToken=t;let r=await this.client.request({service:"ses",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:this.buildFormBody(e)}),d=r?.ListReceiptRuleSetsResponse?.ListReceiptRuleSetsResult||r?.ListReceiptRuleSetsResult,E=d?.RuleSets?.member;return{RuleSets:Array.isArray(E)?E:E?[E]:[],NextToken:d?.NextToken}}async describeReceiptRuleSet(t){let e=await this.client.request({service:"ses",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:this.buildFormBody({Action:"DescribeReceiptRuleSet",Version:"2010-12-01",RuleSetName:t})}),r=e?.DescribeReceiptRuleSetResponse?.DescribeReceiptRuleSetResult||e?.DescribeReceiptRuleSetResult,d=r?.Rules?.member;return{Metadata:r?.Metadata,Rules:Array.isArray(d)?d:d?[d]:[]}}async createReceiptRule(t){let e={Action:"CreateReceiptRule",Version:"2010-12-01",RuleSetName:t.RuleSetName,"Rule.Name":t.Rule.Name,"Rule.Enabled":t.Rule.Enabled!==!1?"true":"false"};if(t.Rule.TlsPolicy)e["Rule.TlsPolicy"]=t.Rule.TlsPolicy;if(t.Rule.ScanEnabled!==void 0)e["Rule.ScanEnabled"]=t.Rule.ScanEnabled?"true":"false";if(t.After)e.After=t.After;if(t.Rule.Recipients)t.Rule.Recipients.forEach((r,d)=>{e[`Rule.Recipients.member.${d+1}`]=r});t.Rule.Actions.forEach((r,d)=>{let E=d+1;if(r.S3Action){if(e[`Rule.Actions.member.${E}.S3Action.BucketName`]=r.S3Action.BucketName,r.S3Action.ObjectKeyPrefix)e[`Rule.Actions.member.${E}.S3Action.ObjectKeyPrefix`]=r.S3Action.ObjectKeyPrefix;if(r.S3Action.KmsKeyArn)e[`Rule.Actions.member.${E}.S3Action.KmsKeyArn`]=r.S3Action.KmsKeyArn}if(r.LambdaAction)e[`Rule.Actions.member.${E}.LambdaAction.FunctionArn`]=r.LambdaAction.FunctionArn,e[`Rule.Actions.member.${E}.LambdaAction.InvocationType`]=r.LambdaAction.InvocationType||"Event";if(r.SNSAction){if(e[`Rule.Actions.member.${E}.SNSAction.TopicArn`]=r.SNSAction.TopicArn,r.SNSAction.Encoding)e[`Rule.Actions.member.${E}.SNSAction.Encoding`]=r.SNSAction.Encoding}if(r.StopAction){if(e[`Rule.Actions.member.${E}.StopAction.Scope`]=r.StopAction.Scope,r.StopAction.TopicArn)e[`Rule.Actions.member.${E}.StopAction.TopicArn`]=r.StopAction.TopicArn}}),await this.client.request({service:"ses",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:this.buildFormBody(e)})}async deleteReceiptRule(t,e){await this.client.request({service:"ses",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:this.buildFormBody({Action:"DeleteReceiptRule",Version:"2010-12-01",RuleSetName:t,RuleName:e})})}async receiptRuleSetExists(t){try{return await this.describeReceiptRuleSet(t),!0}catch(e){if(e.code==="RuleSetDoesNotExist"||e.statusCode===400)return!1;throw e}}async getActiveReceiptRuleSet(){let t=await this.client.request({service:"ses",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:this.buildFormBody({Action:"DescribeActiveReceiptRuleSet",Version:"2010-12-01"})}),e=t?.DescribeActiveReceiptRuleSetResponse?.DescribeActiveReceiptRuleSetResult||t?.DescribeActiveReceiptRuleSetResult;if(!e?.Metadata)return null;let r=e?.Rules?.member;return{Metadata:e?.Metadata,Rules:Array.isArray(r)?r:r?[r]:[]}}async updateReceiptRule(t){let e={Action:"UpdateReceiptRule",Version:"2010-12-01",RuleSetName:t.RuleSetName,"Rule.Name":t.Rule.Name};if(t.Rule.Enabled!==void 0)e["Rule.Enabled"]=t.Rule.Enabled?"true":"false";if(t.Rule.TlsPolicy)e["Rule.TlsPolicy"]=t.Rule.TlsPolicy;if(t.Rule.ScanEnabled!==void 0)e["Rule.ScanEnabled"]=t.Rule.ScanEnabled?"true":"false";if(t.Rule.Recipients)t.Rule.Recipients.forEach((r,d)=>{e[`Rule.Recipients.member.${d+1}`]=r});t.Rule.Actions.forEach((r,d)=>{let E=d+1;if(r.S3Action){if(e[`Rule.Actions.member.${E}.S3Action.BucketName`]=r.S3Action.BucketName,r.S3Action.ObjectKeyPrefix)e[`Rule.Actions.member.${E}.S3Action.ObjectKeyPrefix`]=r.S3Action.ObjectKeyPrefix;if(r.S3Action.KmsKeyArn)e[`Rule.Actions.member.${E}.S3Action.KmsKeyArn`]=r.S3Action.KmsKeyArn}if(r.LambdaAction)e[`Rule.Actions.member.${E}.LambdaAction.FunctionArn`]=r.LambdaAction.FunctionArn,e[`Rule.Actions.member.${E}.LambdaAction.InvocationType`]=r.LambdaAction.InvocationType||"Event";if(r.SNSAction){if(e[`Rule.Actions.member.${E}.SNSAction.TopicArn`]=r.SNSAction.TopicArn,r.SNSAction.Encoding)e[`Rule.Actions.member.${E}.SNSAction.Encoding`]=r.SNSAction.Encoding}if(r.StopAction){if(e[`Rule.Actions.member.${E}.StopAction.Scope`]=r.StopAction.Scope,r.StopAction.TopicArn)e[`Rule.Actions.member.${E}.StopAction.TopicArn`]=r.StopAction.TopicArn}}),await this.client.request({service:"ses",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:this.buildFormBody(e)})}async sendRawEmail(t){let e=Buffer.from(t.rawMessage).toString("base64"),r={Action:"SendRawEmail",Version:"2010-12-01",Source:t.source,"RawMessage.Data":e};t.destinations.forEach((n,c)=>{r[`Destinations.member.${c+1}`]=n});let d=await this.client.request({service:"ses",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:this.buildFormBody(r)});return{MessageId:(d?.SendRawEmailResponse?.SendRawEmailResult||d?.SendRawEmailResult)?.MessageId}}async getSuppressedDestination(t){try{return(await this.client.request({service:"ses",region:this.region,method:"GET",path:`/v2/email/suppression/addresses/${encodeURIComponent(t)}`}))?.SuppressedDestination||null}catch(e){if(e.message?.includes("404")||e.message?.includes("NotFoundException"))return null;throw e}}async deleteSuppressedDestination(t){await this.client.request({service:"ses",region:this.region,method:"DELETE",path:`/v2/email/suppression/addresses/${encodeURIComponent(t)}`})}}var xT=wr(()=>{Lt()});var HS={};ER(HS,{email:()=>Jy,EmailClient:()=>JS});class JS{ses;s3;iam;route53;region;domain;defaultFrom;constructor(t={}){this.region=t.region||"us-east-1",this.domain=t.domain,this.defaultFrom=t.defaultFrom,this.ses=new bT(this.region),this.s3=new pt(this.region),this.iam=new ZT(this.region),this.route53=new Md(this.region)}async send(t){let e=t.from||this.defaultFrom;if(!e)throw Error("From address is required. Set defaultFrom in constructor or provide from in options.");let r=t.fromName?`${t.fromName} <${e}>`:e,d=Array.isArray(t.to)?t.to:[t.to];if(!t.attachments||t.attachments.length===0)return{messageId:(await this.ses.sendSimpleEmail({from:r,to:d,subject:t.subject,text:t.text,html:t.html,replyTo:t.replyTo})).MessageId||""};let E=this.buildRawEmail(t,r,d);return{messageId:(await this.ses.sendEmail({FromEmailAddress:r,Destination:{ToAddresses:d,CcAddresses:t.cc?Array.isArray(t.cc)?t.cc:[t.cc]:void 0,BccAddresses:t.bcc?Array.isArray(t.bcc)?t.bcc:[t.bcc]:void 0},Content:{Raw:{Data:Buffer.from(E).toString("base64")}}})).MessageId||""}}async sendTemplate(t){let e=t.from||this.defaultFrom;if(!e)throw Error("From address is required");let r=t.fromName?`${t.fromName} <${e}>`:e;return{messageId:(await this.ses.sendTemplatedEmail({from:r,to:t.to,templateName:t.templateName,templateData:t.templateData,replyTo:t.replyTo})).MessageId||""}}async sendBulk(t){let e=t.from||this.defaultFrom;if(!e)throw Error("From address is required");let r=t.recipients.map((E)=>({Destination:{ToAddresses:Array.isArray(E.to)?E.to:[E.to]},ReplacementEmailContent:E.templateData?{ReplacementTemplate:{ReplacementTemplateData:JSON.stringify(E.templateData)}}:void 0}));return{results:(await this.ses.sendBulkEmail({FromEmailAddress:e,BulkEmailEntries:r,DefaultContent:{Template:{TemplateName:t.templateName,TemplateData:JSON.stringify(t.defaultTemplateData)}}})).BulkEmailEntryResults?.map((E)=>({status:E.Status||"UNKNOWN",messageId:E.MessageId,error:E.Error}))||[]}}async setupDomain(t){let e;try{e=await this.ses.getEmailIdentity(t)}catch{let d=await this.ses.createEmailIdentity({EmailIdentity:t});e={VerificationStatus:d.DkimAttributes?.Status,DkimAttributes:d.DkimAttributes,SendingEnabled:d.VerifiedForSendingStatus}}try{await this.ses.putEmailIdentityDkimAttributes({EmailIdentity:t,SigningEnabled:!0})}catch{}try{await this.ses.putEmailIdentityMailFromAttributes(t,{MailFromDomain:`mail.${t}`,BehaviorOnMxFailure:"USE_DEFAULT_VALUE"})}catch{}let r=await this.ses.getDkimRecords(t);return{domainVerified:e.SendingEnabled===!0,dkimStatus:e.DkimAttributes?.Status||"UNKNOWN",dkimTokens:e.DkimAttributes?.Tokens,mailFromStatus:e.MailFromAttributes?.MailFromDomainStatus}}async getDnsRecords(t){let e=[],r=await this.ses.getDkimRecords(t);for(let d of r)e.push({type:d.type,name:d.name,value:d.value,ttl:1800});return e.push({type:"MX",name:t,value:`inbound-smtp.${this.region}.amazonaws.com`,priority:10,ttl:3600}),e.push({type:"MX",name:`mail.${t}`,value:`feedback-smtp.${this.region}.amazonses.com`,priority:10,ttl:3600}),e.push({type:"TXT",name:`mail.${t}`,value:"v=spf1 include:amazonses.com ~all",ttl:3600}),e.push({type:"TXT",name:`_dmarc.${t}`,value:`v=DMARC1;p=quarantine;pct=25;rua=mailto:dmarcreports@${t}`,ttl:3600}),e}async isDomainReady(t){try{let e=await this.ses.getEmailIdentity(t);return e.SendingEnabled===!0&&e.DkimAttributes?.Status==="SUCCESS"}catch{return!1}}async setupReceiving(t){let e={Version:"2012-10-17",Statement:[{Sid:"AllowSESPuts",Effect:"Allow",Principal:{Service:"ses.amazonaws.com"},Action:"s3:PutObject",Resource:`arn:aws:s3:::${t.bucketName}/*`,Condition:{StringEquals:{"AWS:SourceAccount":t.accountId}}}]};await this.s3.putBucketPolicy(t.bucketName,e);try{await this.ses.createReceiptRuleSet(t.ruleSetName)}catch(d){if(!d.message?.includes("already exists")&&d.code!=="AlreadyExists")throw d}let r=[{S3Action:{BucketName:t.bucketName,ObjectKeyPrefix:t.prefix||"inbox/"}}];if(t.lambdaArn)r.push({LambdaAction:{FunctionArn:t.lambdaArn,InvocationType:"Event"}});try{await this.ses.createReceiptRule({RuleSetName:t.ruleSetName,Rule:{Name:t.ruleName,Enabled:!0,TlsPolicy:"Optional",Recipients:t.recipients||[t.domain],ScanEnabled:t.scanEnabled!==!1,Actions:r}})}catch(d){if(d.message?.includes("already exists"))await this.ses.deleteReceiptRule(t.ruleSetName,t.ruleName),await this.ses.createReceiptRule({RuleSetName:t.ruleSetName,Rule:{Name:t.ruleName,Enabled:!0,TlsPolicy:"Optional",Recipients:t.recipients||[t.domain],ScanEnabled:t.scanEnabled!==!1,Actions:r}});else throw d}await this.ses.setActiveReceiptRuleSet(t.ruleSetName)}async getIncomingEmails(t){return(await this.s3.list({bucket:t.bucket,prefix:t.prefix||"incoming/",maxKeys:t.maxResults||100})).map((r)=>({key:r.Key||"",lastModified:r.LastModified||"",size:r.Size||0}))}async readEmail(t){return await this.s3.getObject(t.bucket,t.key)}async createSmtpCredentials(t){let e=`ses-smtp-${t.username.replace(/[^a-zA-Z0-9]/g,"-")}`,{AWSClient:r}=await Promise.resolve().then(() => (Lt(),Y0)),d=new r,E=(h,R)=>{let N={Action:h,Version:"2010-05-08",...R};return Object.entries(N).map(([A,u])=>`${encodeURIComponent(A)}=${encodeURIComponent(u)}`).join("&")};try{await d.request({service:"iam",region:"us-east-1",method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:E("CreateUser",{UserName:e})})}catch(h){if(!h.message?.includes("EntityAlreadyExists"))throw h}let n={Version:"2012-10-17",Statement:[{Effect:"Allow",Action:"ses:SendRawEmail",Resource:"*",Condition:{StringLike:{"ses:FromAddress":`*@${t.domain}`}}}]},c=`ses-smtp-policy-${t.domain.replace(/\./g,"-")}`;try{await d.request({service:"iam",region:"us-east-1",method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:E("PutUserPolicy",{UserName:e,PolicyName:c,PolicyDocument:JSON.stringify(n)})})}catch{}let T=(await d.request({service:"iam",region:"us-east-1",method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:E("CreateAccessKey",{UserName:e})}))?.CreateAccessKeyResult?.AccessKey;if(!T?.AccessKeyId||!T?.SecretAccessKey)throw Error("Failed to create access key");let i=this.deriveSmtpPassword(T.SecretAccessKey);return{username:T.AccessKeyId,password:i,server:`email-smtp.${this.region}.amazonaws.com`,port:587}}deriveSmtpPassword(t){let e=Ee("node:crypto"),r="SendRawEmail",d=Buffer.from([4]),E=e.createHmac("sha256",`AWS4${t}`).update("11111111").digest();return E=e.createHmac("sha256",E).update(this.region).digest(),E=e.createHmac("sha256",E).update("ses").digest(),E=e.createHmac("sha256",E).update("aws4_request").digest(),E=e.createHmac("sha256",E).update("SendRawEmail").digest(),Buffer.concat([d,E]).toString("base64")}async createTemplate(t){await this.ses.createEmailTemplate({TemplateName:t.name,TemplateContent:{Subject:t.subject,Text:t.text,Html:t.html}})}async getTemplate(t){try{let e=await this.ses.getEmailTemplate(t);return{name:e.TemplateName||t,subject:e.TemplateContent?.Subject,text:e.TemplateContent?.Text,html:e.TemplateContent?.Html}}catch{return null}}async deleteTemplate(t){await this.ses.deleteEmailTemplate(t)}async listTemplates(){return(await this.ses.listEmailTemplates()).TemplatesMetadata?.map((e)=>({name:e.TemplateName||"",createdAt:e.CreatedTimestamp}))||[]}async deploy(t){let e=`${t.appName}-${t.environment}-email-rules`,r=`${t.appName}-inbound-email`,d=t.storage?.bucketName||`${t.appName}-${t.environment}-email`,E=await this.setupDomain(t.domain);if(!(await this.s3.listBuckets()).Buckets?.some((T)=>T.Name===d))await this.s3.createBucket(d);await this.setupReceiving({domain:t.domain,ruleSetName:e,ruleName:r,bucketName:d,prefix:t.storage?.prefix||"inbox/",accountId:t.accountId,recipients:t.catchAll?[t.domain]:t.mailboxes,scanEnabled:!0});let _=await this.getDnsRecords(t.domain);return{success:!0,domainVerified:E.domainVerified,dkimStatus:E.dkimStatus,receiptRuleSet:e,storageBucket:d,dnsRecords:_}}async undeploy(t){let e=`${t.appName}-${t.environment}-email-rules`,r=`${t.appName}-inbound-email`,d=`${t.appName}-${t.environment}-email`;try{await this.ses.deleteReceiptRule(e,r)}catch{}try{await this.ses.deleteReceiptRuleSet(e)}catch{}if(t.deleteBucket)try{await this.s3.emptyAndDeleteBucket(d)}catch{}}async getSendingStats(){let t=await this.ses.getSendQuota();return{sentLast24Hours:t.SentLast24Hours||0,maxSendRate:t.MaxSendRate||0,max24HourSend:t.Max24HourSend||0}}buildRawEmail(t,e,r){let d=`----=_Part_${Date.now()}_${Math.random().toString(36).substring(2)}`,E="";if(E+=`From: ${e}\r
|
|
4083
|
+
</Delete>`,d=it.createHash("md5").update(r).digest("base64");await this.client.request({service:"s3",region:this.region,method:"POST",path:`/${t}`,queryParams:{delete:""},body:r,headers:{"Content-Type":"application/xml","Content-MD5":d}})}}var tr=gr(()=>{Lt()});class bT{client;region;constructor(t="us-east-1",e){this.region=t,this.client=new dt(e)}async createEmailIdentity(t){return await this.client.request({service:"email",region:this.region,method:"POST",path:"/v2/email/identities",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)})}async getEmailIdentity(t){let e=await this.client.request({service:"email",region:this.region,method:"GET",path:`/v2/email/identities/${encodeURIComponent(t)}`,headers:{"Content-Type":"application/json"}});return{IdentityType:e.IdentityType,IdentityName:t,SendingEnabled:e.VerifiedForSendingStatus,VerificationStatus:e.VerificationStatus,DkimAttributes:e.DkimAttributes,MailFromAttributes:e.MailFromAttributes}}async putEmailIdentityMailFromAttributes(t,e){await this.client.request({service:"email",region:this.region,method:"PUT",path:`/v2/email/identities/${encodeURIComponent(t)}/mail-from`,headers:{"Content-Type":"application/json"},body:JSON.stringify(e)})}async listEmailIdentities(t){let e="/v2/email/identities",r=[];if(t?.PageSize)r.push(`PageSize=${t.PageSize}`);if(t?.NextToken)r.push(`NextToken=${encodeURIComponent(t.NextToken)}`);if(r.length>0)e+=`?${r.join("&")}`;let d=await this.client.request({service:"email",region:this.region,method:"GET",path:e,headers:{"Content-Type":"application/json"}});return{EmailIdentities:d.EmailIdentities,NextToken:d.NextToken}}async deleteEmailIdentity(t){await this.client.request({service:"email",region:this.region,method:"DELETE",path:`/v2/email/identities/${encodeURIComponent(t)}`,headers:{"Content-Type":"application/json"}})}async putEmailIdentityDkimAttributes(t){await this.client.request({service:"email",region:this.region,method:"PUT",path:`/v2/email/identities/${encodeURIComponent(t.EmailIdentity)}/dkim`,headers:{"Content-Type":"application/json"},body:JSON.stringify({SigningEnabled:t.SigningEnabled})})}async sendEmail(t){return{MessageId:(await this.client.request({service:"email",region:this.region,method:"POST",path:"/v2/email/outbound-emails",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)})).MessageId}}async sendBulkEmail(t){return{BulkEmailEntryResults:(await this.client.request({service:"email",region:this.region,method:"POST",path:"/v2/email/outbound-bulk-emails",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)})).BulkEmailEntryResults}}async createEmailTemplate(t){await this.client.request({service:"email",region:this.region,method:"POST",path:"/v2/email/templates",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)})}async getEmailTemplate(t){return await this.client.request({service:"email",region:this.region,method:"GET",path:`/v2/email/templates/${encodeURIComponent(t)}`,headers:{"Content-Type":"application/json"}})}async deleteEmailTemplate(t){await this.client.request({service:"email",region:this.region,method:"DELETE",path:`/v2/email/templates/${encodeURIComponent(t)}`,headers:{"Content-Type":"application/json"}})}async listEmailTemplates(t){let e="/v2/email/templates",r=[];if(t?.PageSize)r.push(`PageSize=${t.PageSize}`);if(t?.NextToken)r.push(`NextToken=${encodeURIComponent(t.NextToken)}`);if(r.length>0)e+=`?${r.join("&")}`;return await this.client.request({service:"email",region:this.region,method:"GET",path:e,headers:{"Content-Type":"application/json"}})}async getSendStatistics(){return{SendDataPoints:(await this.client.request({service:"ses",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:"Action=GetSendStatistics&Version=2010-12-01"})).GetSendStatisticsResponse?.GetSendStatisticsResult?.SendDataPoints?.member}}async getSendQuota(){let e=(await this.client.request({service:"ses",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:"Action=GetSendQuota&Version=2010-12-01"})).GetSendQuotaResponse?.GetSendQuotaResult;return{Max24HourSend:e?.Max24HourSend?Number(e.Max24HourSend):void 0,MaxSendRate:e?.MaxSendRate?Number(e.MaxSendRate):void 0,SentLast24Hours:e?.SentLast24Hours?Number(e.SentLast24Hours):void 0}}async verifyDomain(t){let e=await this.createEmailIdentity({EmailIdentity:t});return{dkimTokens:e.DkimAttributes?.Tokens,verificationStatus:e.DkimAttributes?.Status}}async sendSimpleEmail(t){let e=Array.isArray(t.to)?t.to:[t.to],r=t.replyTo?Array.isArray(t.replyTo)?t.replyTo:[t.replyTo]:void 0,d={};if(t.text)d.Text={Data:t.text};if(t.html)d.Html={Data:t.html};return this.sendEmail({FromEmailAddress:t.from,Destination:{ToAddresses:e},Content:{Simple:{Subject:{Data:t.subject},Body:d}},ReplyToAddresses:r})}async sendTemplatedEmail(t){let e=Array.isArray(t.to)?t.to:[t.to],r=t.replyTo?Array.isArray(t.replyTo)?t.replyTo:[t.replyTo]:void 0;return this.sendEmail({FromEmailAddress:t.from,Destination:{ToAddresses:e},Content:{Template:{TemplateName:t.templateName,TemplateData:JSON.stringify(t.templateData)}},ReplyToAddresses:r})}async getDkimRecords(t){let e=await this.getEmailIdentity(t);if(!e.DkimAttributes?.Tokens)return[];return e.DkimAttributes.Tokens.map((r)=>({name:`${r}._domainkey.${t}`,type:"CNAME",value:`${r}.dkim.amazonses.com`}))}async isDomainVerified(t){try{let e=await this.getEmailIdentity(t);return e.VerificationStatus==="SUCCESS"&&e.SendingEnabled===!0}catch{return!1}}async waitForDomainVerification(t,e=60,r=30000){for(let d=0;d<e;d++){if(await this.isDomainVerified(t))return!0;await new Promise((n)=>setTimeout(n,r))}return!1}buildFormBody(t){return Object.entries(t).filter(([,r])=>r!==void 0).map(([r,d])=>`${encodeURIComponent(r)}=${encodeURIComponent(d)}`).join("&")}async createReceiptRuleSet(t){await this.client.request({service:"ses",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:this.buildFormBody({Action:"CreateReceiptRuleSet",Version:"2010-12-01",RuleSetName:t})})}async deleteReceiptRuleSet(t){await this.client.request({service:"ses",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:this.buildFormBody({Action:"DeleteReceiptRuleSet",Version:"2010-12-01",RuleSetName:t})})}async setActiveReceiptRuleSet(t){await this.client.request({service:"ses",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:this.buildFormBody({Action:"SetActiveReceiptRuleSet",Version:"2010-12-01",RuleSetName:t})})}async listReceiptRuleSets(t){let e={Action:"ListReceiptRuleSets",Version:"2010-12-01"};if(t)e.NextToken=t;let r=await this.client.request({service:"ses",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:this.buildFormBody(e)}),d=r?.ListReceiptRuleSetsResponse?.ListReceiptRuleSetsResult||r?.ListReceiptRuleSetsResult,E=d?.RuleSets?.member;return{RuleSets:Array.isArray(E)?E:E?[E]:[],NextToken:d?.NextToken}}async describeReceiptRuleSet(t){let e=await this.client.request({service:"ses",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:this.buildFormBody({Action:"DescribeReceiptRuleSet",Version:"2010-12-01",RuleSetName:t})}),r=e?.DescribeReceiptRuleSetResponse?.DescribeReceiptRuleSetResult||e?.DescribeReceiptRuleSetResult,d=r?.Rules?.member;return{Metadata:r?.Metadata,Rules:Array.isArray(d)?d:d?[d]:[]}}async createReceiptRule(t){let e={Action:"CreateReceiptRule",Version:"2010-12-01",RuleSetName:t.RuleSetName,"Rule.Name":t.Rule.Name,"Rule.Enabled":t.Rule.Enabled!==!1?"true":"false"};if(t.Rule.TlsPolicy)e["Rule.TlsPolicy"]=t.Rule.TlsPolicy;if(t.Rule.ScanEnabled!==void 0)e["Rule.ScanEnabled"]=t.Rule.ScanEnabled?"true":"false";if(t.After)e.After=t.After;if(t.Rule.Recipients)t.Rule.Recipients.forEach((r,d)=>{e[`Rule.Recipients.member.${d+1}`]=r});t.Rule.Actions.forEach((r,d)=>{let E=d+1;if(r.S3Action){if(e[`Rule.Actions.member.${E}.S3Action.BucketName`]=r.S3Action.BucketName,r.S3Action.ObjectKeyPrefix)e[`Rule.Actions.member.${E}.S3Action.ObjectKeyPrefix`]=r.S3Action.ObjectKeyPrefix;if(r.S3Action.KmsKeyArn)e[`Rule.Actions.member.${E}.S3Action.KmsKeyArn`]=r.S3Action.KmsKeyArn}if(r.LambdaAction)e[`Rule.Actions.member.${E}.LambdaAction.FunctionArn`]=r.LambdaAction.FunctionArn,e[`Rule.Actions.member.${E}.LambdaAction.InvocationType`]=r.LambdaAction.InvocationType||"Event";if(r.SNSAction){if(e[`Rule.Actions.member.${E}.SNSAction.TopicArn`]=r.SNSAction.TopicArn,r.SNSAction.Encoding)e[`Rule.Actions.member.${E}.SNSAction.Encoding`]=r.SNSAction.Encoding}if(r.StopAction){if(e[`Rule.Actions.member.${E}.StopAction.Scope`]=r.StopAction.Scope,r.StopAction.TopicArn)e[`Rule.Actions.member.${E}.StopAction.TopicArn`]=r.StopAction.TopicArn}}),await this.client.request({service:"ses",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:this.buildFormBody(e)})}async deleteReceiptRule(t,e){await this.client.request({service:"ses",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:this.buildFormBody({Action:"DeleteReceiptRule",Version:"2010-12-01",RuleSetName:t,RuleName:e})})}async receiptRuleSetExists(t){try{return await this.describeReceiptRuleSet(t),!0}catch(e){if(e.code==="RuleSetDoesNotExist"||e.statusCode===400)return!1;throw e}}async getActiveReceiptRuleSet(){let t=await this.client.request({service:"ses",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:this.buildFormBody({Action:"DescribeActiveReceiptRuleSet",Version:"2010-12-01"})}),e=t?.DescribeActiveReceiptRuleSetResponse?.DescribeActiveReceiptRuleSetResult||t?.DescribeActiveReceiptRuleSetResult;if(!e?.Metadata)return null;let r=e?.Rules?.member;return{Metadata:e?.Metadata,Rules:Array.isArray(r)?r:r?[r]:[]}}async updateReceiptRule(t){let e={Action:"UpdateReceiptRule",Version:"2010-12-01",RuleSetName:t.RuleSetName,"Rule.Name":t.Rule.Name};if(t.Rule.Enabled!==void 0)e["Rule.Enabled"]=t.Rule.Enabled?"true":"false";if(t.Rule.TlsPolicy)e["Rule.TlsPolicy"]=t.Rule.TlsPolicy;if(t.Rule.ScanEnabled!==void 0)e["Rule.ScanEnabled"]=t.Rule.ScanEnabled?"true":"false";if(t.Rule.Recipients)t.Rule.Recipients.forEach((r,d)=>{e[`Rule.Recipients.member.${d+1}`]=r});t.Rule.Actions.forEach((r,d)=>{let E=d+1;if(r.S3Action){if(e[`Rule.Actions.member.${E}.S3Action.BucketName`]=r.S3Action.BucketName,r.S3Action.ObjectKeyPrefix)e[`Rule.Actions.member.${E}.S3Action.ObjectKeyPrefix`]=r.S3Action.ObjectKeyPrefix;if(r.S3Action.KmsKeyArn)e[`Rule.Actions.member.${E}.S3Action.KmsKeyArn`]=r.S3Action.KmsKeyArn}if(r.LambdaAction)e[`Rule.Actions.member.${E}.LambdaAction.FunctionArn`]=r.LambdaAction.FunctionArn,e[`Rule.Actions.member.${E}.LambdaAction.InvocationType`]=r.LambdaAction.InvocationType||"Event";if(r.SNSAction){if(e[`Rule.Actions.member.${E}.SNSAction.TopicArn`]=r.SNSAction.TopicArn,r.SNSAction.Encoding)e[`Rule.Actions.member.${E}.SNSAction.Encoding`]=r.SNSAction.Encoding}if(r.StopAction){if(e[`Rule.Actions.member.${E}.StopAction.Scope`]=r.StopAction.Scope,r.StopAction.TopicArn)e[`Rule.Actions.member.${E}.StopAction.TopicArn`]=r.StopAction.TopicArn}}),await this.client.request({service:"ses",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:this.buildFormBody(e)})}async sendRawEmail(t){let e=Buffer.from(t.rawMessage).toString("base64"),r={Action:"SendRawEmail",Version:"2010-12-01",Source:t.source,"RawMessage.Data":e};t.destinations.forEach((n,c)=>{r[`Destinations.member.${c+1}`]=n});let d=await this.client.request({service:"ses",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:this.buildFormBody(r)});return{MessageId:(d?.SendRawEmailResponse?.SendRawEmailResult||d?.SendRawEmailResult)?.MessageId}}async getSuppressedDestination(t){try{return(await this.client.request({service:"ses",region:this.region,method:"GET",path:`/v2/email/suppression/addresses/${encodeURIComponent(t)}`}))?.SuppressedDestination||null}catch(e){if(e.message?.includes("404")||e.message?.includes("NotFoundException"))return null;throw e}}async deleteSuppressedDestination(t){await this.client.request({service:"ses",region:this.region,method:"DELETE",path:`/v2/email/suppression/addresses/${encodeURIComponent(t)}`})}}var xT=gr(()=>{Lt()});var HS={};ER(HS,{email:()=>Jy,EmailClient:()=>JS});class JS{ses;s3;iam;route53;region;domain;defaultFrom;constructor(t={}){this.region=t.region||"us-east-1",this.domain=t.domain,this.defaultFrom=t.defaultFrom,this.ses=new bT(this.region),this.s3=new pt(this.region),this.iam=new ZT(this.region),this.route53=new Md(this.region)}async send(t){let e=t.from||this.defaultFrom;if(!e)throw Error("From address is required. Set defaultFrom in constructor or provide from in options.");let r=t.fromName?`${t.fromName} <${e}>`:e,d=Array.isArray(t.to)?t.to:[t.to];if(!t.attachments||t.attachments.length===0)return{messageId:(await this.ses.sendSimpleEmail({from:r,to:d,subject:t.subject,text:t.text,html:t.html,replyTo:t.replyTo})).MessageId||""};let E=this.buildRawEmail(t,r,d);return{messageId:(await this.ses.sendEmail({FromEmailAddress:r,Destination:{ToAddresses:d,CcAddresses:t.cc?Array.isArray(t.cc)?t.cc:[t.cc]:void 0,BccAddresses:t.bcc?Array.isArray(t.bcc)?t.bcc:[t.bcc]:void 0},Content:{Raw:{Data:Buffer.from(E).toString("base64")}}})).MessageId||""}}async sendTemplate(t){let e=t.from||this.defaultFrom;if(!e)throw Error("From address is required");let r=t.fromName?`${t.fromName} <${e}>`:e;return{messageId:(await this.ses.sendTemplatedEmail({from:r,to:t.to,templateName:t.templateName,templateData:t.templateData,replyTo:t.replyTo})).MessageId||""}}async sendBulk(t){let e=t.from||this.defaultFrom;if(!e)throw Error("From address is required");let r=t.recipients.map((E)=>({Destination:{ToAddresses:Array.isArray(E.to)?E.to:[E.to]},ReplacementEmailContent:E.templateData?{ReplacementTemplate:{ReplacementTemplateData:JSON.stringify(E.templateData)}}:void 0}));return{results:(await this.ses.sendBulkEmail({FromEmailAddress:e,BulkEmailEntries:r,DefaultContent:{Template:{TemplateName:t.templateName,TemplateData:JSON.stringify(t.defaultTemplateData)}}})).BulkEmailEntryResults?.map((E)=>({status:E.Status||"UNKNOWN",messageId:E.MessageId,error:E.Error}))||[]}}async setupDomain(t){let e;try{e=await this.ses.getEmailIdentity(t)}catch{let d=await this.ses.createEmailIdentity({EmailIdentity:t});e={VerificationStatus:d.DkimAttributes?.Status,DkimAttributes:d.DkimAttributes,SendingEnabled:d.VerifiedForSendingStatus}}try{await this.ses.putEmailIdentityDkimAttributes({EmailIdentity:t,SigningEnabled:!0})}catch{}try{await this.ses.putEmailIdentityMailFromAttributes(t,{MailFromDomain:`mail.${t}`,BehaviorOnMxFailure:"USE_DEFAULT_VALUE"})}catch{}let r=await this.ses.getDkimRecords(t);return{domainVerified:e.SendingEnabled===!0,dkimStatus:e.DkimAttributes?.Status||"UNKNOWN",dkimTokens:e.DkimAttributes?.Tokens,mailFromStatus:e.MailFromAttributes?.MailFromDomainStatus}}async getDnsRecords(t){let e=[],r=await this.ses.getDkimRecords(t);for(let d of r)e.push({type:d.type,name:d.name,value:d.value,ttl:1800});return e.push({type:"MX",name:t,value:`inbound-smtp.${this.region}.amazonaws.com`,priority:10,ttl:3600}),e.push({type:"MX",name:`mail.${t}`,value:`feedback-smtp.${this.region}.amazonses.com`,priority:10,ttl:3600}),e.push({type:"TXT",name:`mail.${t}`,value:"v=spf1 include:amazonses.com ~all",ttl:3600}),e.push({type:"TXT",name:`_dmarc.${t}`,value:`v=DMARC1;p=quarantine;pct=25;rua=mailto:dmarcreports@${t}`,ttl:3600}),e}async isDomainReady(t){try{let e=await this.ses.getEmailIdentity(t);return e.SendingEnabled===!0&&e.DkimAttributes?.Status==="SUCCESS"}catch{return!1}}async setupReceiving(t){let e={Version:"2012-10-17",Statement:[{Sid:"AllowSESPuts",Effect:"Allow",Principal:{Service:"ses.amazonaws.com"},Action:"s3:PutObject",Resource:`arn:aws:s3:::${t.bucketName}/*`,Condition:{StringEquals:{"AWS:SourceAccount":t.accountId}}}]};await this.s3.putBucketPolicy(t.bucketName,e);try{await this.ses.createReceiptRuleSet(t.ruleSetName)}catch(d){if(!d.message?.includes("already exists")&&d.code!=="AlreadyExists")throw d}let r=[{S3Action:{BucketName:t.bucketName,ObjectKeyPrefix:t.prefix||"inbox/"}}];if(t.lambdaArn)r.push({LambdaAction:{FunctionArn:t.lambdaArn,InvocationType:"Event"}});try{await this.ses.createReceiptRule({RuleSetName:t.ruleSetName,Rule:{Name:t.ruleName,Enabled:!0,TlsPolicy:"Optional",Recipients:t.recipients||[t.domain],ScanEnabled:t.scanEnabled!==!1,Actions:r}})}catch(d){if(d.message?.includes("already exists"))await this.ses.deleteReceiptRule(t.ruleSetName,t.ruleName),await this.ses.createReceiptRule({RuleSetName:t.ruleSetName,Rule:{Name:t.ruleName,Enabled:!0,TlsPolicy:"Optional",Recipients:t.recipients||[t.domain],ScanEnabled:t.scanEnabled!==!1,Actions:r}});else throw d}await this.ses.setActiveReceiptRuleSet(t.ruleSetName)}async getIncomingEmails(t){return(await this.s3.list({bucket:t.bucket,prefix:t.prefix||"incoming/",maxKeys:t.maxResults||100})).map((r)=>({key:r.Key||"",lastModified:r.LastModified||"",size:r.Size||0}))}async readEmail(t){return await this.s3.getObject(t.bucket,t.key)}async createSmtpCredentials(t){let e=`ses-smtp-${t.username.replace(/[^a-zA-Z0-9]/g,"-")}`,{AWSClient:r}=await Promise.resolve().then(() => (Lt(),Y0)),d=new r,E=(h,R)=>{let N={Action:h,Version:"2010-05-08",...R};return Object.entries(N).map(([A,u])=>`${encodeURIComponent(A)}=${encodeURIComponent(u)}`).join("&")};try{await d.request({service:"iam",region:"us-east-1",method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:E("CreateUser",{UserName:e})})}catch(h){if(!h.message?.includes("EntityAlreadyExists"))throw h}let n={Version:"2012-10-17",Statement:[{Effect:"Allow",Action:"ses:SendRawEmail",Resource:"*",Condition:{StringLike:{"ses:FromAddress":`*@${t.domain}`}}}]},c=`ses-smtp-policy-${t.domain.replace(/\./g,"-")}`;try{await d.request({service:"iam",region:"us-east-1",method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:E("PutUserPolicy",{UserName:e,PolicyName:c,PolicyDocument:JSON.stringify(n)})})}catch{}let T=(await d.request({service:"iam",region:"us-east-1",method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:E("CreateAccessKey",{UserName:e})}))?.CreateAccessKeyResult?.AccessKey;if(!T?.AccessKeyId||!T?.SecretAccessKey)throw Error("Failed to create access key");let i=this.deriveSmtpPassword(T.SecretAccessKey);return{username:T.AccessKeyId,password:i,server:`email-smtp.${this.region}.amazonaws.com`,port:587}}deriveSmtpPassword(t){let e=Ee("node:crypto"),r="SendRawEmail",d=Buffer.from([4]),E=e.createHmac("sha256",`AWS4${t}`).update("11111111").digest();return E=e.createHmac("sha256",E).update(this.region).digest(),E=e.createHmac("sha256",E).update("ses").digest(),E=e.createHmac("sha256",E).update("aws4_request").digest(),E=e.createHmac("sha256",E).update("SendRawEmail").digest(),Buffer.concat([d,E]).toString("base64")}async createTemplate(t){await this.ses.createEmailTemplate({TemplateName:t.name,TemplateContent:{Subject:t.subject,Text:t.text,Html:t.html}})}async getTemplate(t){try{let e=await this.ses.getEmailTemplate(t);return{name:e.TemplateName||t,subject:e.TemplateContent?.Subject,text:e.TemplateContent?.Text,html:e.TemplateContent?.Html}}catch{return null}}async deleteTemplate(t){await this.ses.deleteEmailTemplate(t)}async listTemplates(){return(await this.ses.listEmailTemplates()).TemplatesMetadata?.map((e)=>({name:e.TemplateName||"",createdAt:e.CreatedTimestamp}))||[]}async deploy(t){let e=`${t.appName}-${t.environment}-email-rules`,r=`${t.appName}-inbound-email`,d=t.storage?.bucketName||`${t.appName}-${t.environment}-email`,E=await this.setupDomain(t.domain);if(!(await this.s3.listBuckets()).Buckets?.some((T)=>T.Name===d))await this.s3.createBucket(d);await this.setupReceiving({domain:t.domain,ruleSetName:e,ruleName:r,bucketName:d,prefix:t.storage?.prefix||"inbox/",accountId:t.accountId,recipients:t.catchAll?[t.domain]:t.mailboxes,scanEnabled:!0});let _=await this.getDnsRecords(t.domain);return{success:!0,domainVerified:E.domainVerified,dkimStatus:E.dkimStatus,receiptRuleSet:e,storageBucket:d,dnsRecords:_}}async undeploy(t){let e=`${t.appName}-${t.environment}-email-rules`,r=`${t.appName}-inbound-email`,d=`${t.appName}-${t.environment}-email`;try{await this.ses.deleteReceiptRule(e,r)}catch{}try{await this.ses.deleteReceiptRuleSet(e)}catch{}if(t.deleteBucket)try{await this.s3.emptyAndDeleteBucket(d)}catch{}}async getSendingStats(){let t=await this.ses.getSendQuota();return{sentLast24Hours:t.SentLast24Hours||0,maxSendRate:t.MaxSendRate||0,max24HourSend:t.Max24HourSend||0}}buildRawEmail(t,e,r){let d=`----=_Part_${Date.now()}_${Math.random().toString(36).substring(2)}`,E="";if(E+=`From: ${e}\r
|
|
4084
4084
|
`,E+=`To: ${r.join(", ")}\r
|
|
4085
4085
|
`,t.cc){let n=Array.isArray(t.cc)?t.cc:[t.cc];E+=`Cc: ${n.join(", ")}\r
|
|
4086
4086
|
`}if(E+=`Subject: ${t.subject}\r
|
|
@@ -4112,9 +4112,9 @@ host:${c}
|
|
|
4112
4112
|
`,E+=`\r
|
|
4113
4113
|
`,E+=`${n.content}\r
|
|
4114
4114
|
`;return E+=`--${d}--\r
|
|
4115
|
-
`,E}}var Jy;var qT=wr(()=>{kT();n_();tr();xT();Jy=new JS});var p0={};ER(p0,{RDSClient:()=>nd});class nd{client;region;constructor(t="us-east-1"){this.region=t,this.client=new dt}async describeDBInstances(t){let e={Action:"DescribeDBInstances",Version:"2014-10-31"};if(t?.DBInstanceIdentifier)e.DBInstanceIdentifier=t.DBInstanceIdentifier;if(t?.MaxRecords)e.MaxRecords=t.MaxRecords;if(t?.Marker)e.Marker=t.Marker;if(t?.Filters)t.Filters.forEach((c,_)=>{e[`Filters.Filter.${_+1}.Name`]=c.Name,c.Values.forEach((T,i)=>{e[`Filters.Filter.${_+1}.Values.Value.${i+1}`]=T})});let r=new URLSearchParams(Qt(e)).toString(),d=await this.client.request({service:"rds",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:r}),E=d.DescribeDBInstancesResult||d,n=E.DBInstances?.DBInstance||[];if(!Array.isArray(n))n=n?[n]:[];return{DBInstances:n,Marker:E.Marker}}async describeDBInstance(t){return(await this.describeDBInstances({DBInstanceIdentifier:t})).DBInstances?.[0]}async describeDBClusters(t){let e={Action:"DescribeDBClusters",Version:"2014-10-31"};if(t?.DBClusterIdentifier)e.DBClusterIdentifier=t.DBClusterIdentifier;if(t?.MaxRecords)e.MaxRecords=t.MaxRecords;if(t?.Marker)e.Marker=t.Marker;if(t?.Filters)t.Filters.forEach((c,_)=>{e[`Filters.Filter.${_+1}.Name`]=c.Name,c.Values.forEach((T,i)=>{e[`Filters.Filter.${_+1}.Values.Value.${i+1}`]=T})});let r=new URLSearchParams(Qt(e)).toString(),d=await this.client.request({service:"rds",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:r}),E=d.DescribeDBClustersResult||d,n=E.DBClusters?.DBCluster||[];if(!Array.isArray(n))n=n?[n]:[];return{DBClusters:n,Marker:E.Marker}}async describeDBSnapshots(t){let e={Action:"DescribeDBSnapshots",Version:"2014-10-31"};if(t?.DBInstanceIdentifier)e.DBInstanceIdentifier=t.DBInstanceIdentifier;if(t?.DBSnapshotIdentifier)e.DBSnapshotIdentifier=t.DBSnapshotIdentifier;if(t?.SnapshotType)e.SnapshotType=t.SnapshotType;if(t?.MaxRecords)e.MaxRecords=t.MaxRecords;if(t?.Marker)e.Marker=t.Marker;let r=new URLSearchParams(Qt(e)).toString(),d=await this.client.request({service:"rds",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:r}),E=d.DescribeDBSnapshotsResult||d,n=E.DBSnapshots?.DBSnapshot||[];if(!Array.isArray(n))n=n?[n]:[];return{DBSnapshots:n,Marker:E.Marker}}async describeDBSubnetGroups(t){let e={Action:"DescribeDBSubnetGroups",Version:"2014-10-31"};if(t?.DBSubnetGroupName)e.DBSubnetGroupName=t.DBSubnetGroupName;if(t?.MaxRecords)e.MaxRecords=t.MaxRecords;if(t?.Marker)e.Marker=t.Marker;let r=new URLSearchParams(Qt(e)).toString(),d=await this.client.request({service:"rds",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:r}),E=d.DescribeDBSubnetGroupsResult||d,n=E.DBSubnetGroups?.DBSubnetGroup||[];if(!Array.isArray(n))n=n?[n]:[];return{DBSubnetGroups:n,Marker:E.Marker}}async createDBInstance(t){let e={Action:"CreateDBInstance",Version:"2014-10-31",DBInstanceIdentifier:t.DBInstanceIdentifier,DBInstanceClass:t.DBInstanceClass,Engine:t.Engine};if(t.DBClusterIdentifier)e.DBClusterIdentifier=t.DBClusterIdentifier;if(t.MasterUsername)e.MasterUsername=t.MasterUsername;if(t.MasterUserPassword)e.MasterUserPassword=t.MasterUserPassword;if(t.DBName)e.DBName=t.DBName;if(t.AllocatedStorage)e.AllocatedStorage=t.AllocatedStorage;if(t.DBSubnetGroupName)e.DBSubnetGroupName=t.DBSubnetGroupName;if(t.AvailabilityZone)e.AvailabilityZone=t.AvailabilityZone;if(t.PreferredMaintenanceWindow)e.PreferredMaintenanceWindow=t.PreferredMaintenanceWindow;if(t.PreferredBackupWindow)e.PreferredBackupWindow=t.PreferredBackupWindow;if(t.BackupRetentionPeriod!==void 0)e.BackupRetentionPeriod=t.BackupRetentionPeriod;if(t.MultiAZ!==void 0)e.MultiAZ=t.MultiAZ;if(t.EngineVersion)e.EngineVersion=t.EngineVersion;if(t.AutoMinorVersionUpgrade!==void 0)e.AutoMinorVersionUpgrade=t.AutoMinorVersionUpgrade;if(t.LicenseModel)e.LicenseModel=t.LicenseModel;if(t.PubliclyAccessible!==void 0)e.PubliclyAccessible=t.PubliclyAccessible;if(t.StorageType)e.StorageType=t.StorageType;if(t.StorageEncrypted!==void 0)e.StorageEncrypted=t.StorageEncrypted;if(t.KmsKeyId)e.KmsKeyId=t.KmsKeyId;if(t.DeletionProtection!==void 0)e.DeletionProtection=t.DeletionProtection;if(t.VpcSecurityGroupIds)t.VpcSecurityGroupIds.forEach((n,c)=>{e[`VpcSecurityGroupIds.VpcSecurityGroupId.${c+1}`]=n});if(t.Tags)t.Tags.forEach((n,c)=>{e[`Tags.Tag.${c+1}.Key`]=n.Key,e[`Tags.Tag.${c+1}.Value`]=n.Value});let r=new URLSearchParams(Qt(e)).toString(),d=await this.client.request({service:"rds",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:r});return{DBInstance:(d.CreateDBInstanceResult||d).DBInstance}}async createDBCluster(t){let e={Action:"CreateDBCluster",Version:"2014-10-31",DBClusterIdentifier:t.DBClusterIdentifier,Engine:t.Engine};if(t.EngineVersion)e.EngineVersion=t.EngineVersion;if(t.MasterUsername)e.MasterUsername=t.MasterUsername;if(t.MasterUserPassword)e.MasterUserPassword=t.MasterUserPassword;if(t.DatabaseName)e.DatabaseName=t.DatabaseName;if(t.DBSubnetGroupName)e.DBSubnetGroupName=t.DBSubnetGroupName;if(t.BackupRetentionPeriod!==void 0)e.BackupRetentionPeriod=t.BackupRetentionPeriod;if(t.StorageEncrypted!==void 0)e.StorageEncrypted=t.StorageEncrypted;if(t.KmsKeyId)e.KmsKeyId=t.KmsKeyId;if(t.DeletionProtection!==void 0)e.DeletionProtection=t.DeletionProtection;if(t.ServerlessV2ScalingConfiguration)e["ServerlessV2ScalingConfiguration.MinCapacity"]=t.ServerlessV2ScalingConfiguration.MinCapacity,e["ServerlessV2ScalingConfiguration.MaxCapacity"]=t.ServerlessV2ScalingConfiguration.MaxCapacity;t.VpcSecurityGroupIds?.forEach((E,n)=>{e[`VpcSecurityGroupIds.VpcSecurityGroupId.${n+1}`]=E});let r=await this.client.request({service:"rds",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(Qt(e)).toString()});return{DBCluster:(r.CreateDBClusterResult||r).DBCluster}}async deleteDBInstance(t){let e={Action:"DeleteDBInstance",Version:"2014-10-31",DBInstanceIdentifier:t.DBInstanceIdentifier};if(t.SkipFinalSnapshot!==void 0)e.SkipFinalSnapshot=t.SkipFinalSnapshot;if(t.FinalDBSnapshotIdentifier)e.FinalDBSnapshotIdentifier=t.FinalDBSnapshotIdentifier;if(t.DeleteAutomatedBackups!==void 0)e.DeleteAutomatedBackups=t.DeleteAutomatedBackups;let r=new URLSearchParams(Qt(e)).toString(),d=await this.client.request({service:"rds",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:r});return{DBInstance:(d.DeleteDBInstanceResult||d).DBInstance}}async modifyDBInstance(t){let e={Action:"ModifyDBInstance",Version:"2014-10-31",DBInstanceIdentifier:t.DBInstanceIdentifier};if(t.DBInstanceClass)e.DBInstanceClass=t.DBInstanceClass;if(t.AllocatedStorage)e.AllocatedStorage=t.AllocatedStorage;if(t.MasterUserPassword)e.MasterUserPassword=t.MasterUserPassword;if(t.BackupRetentionPeriod!==void 0)e.BackupRetentionPeriod=t.BackupRetentionPeriod;if(t.PreferredBackupWindow)e.PreferredBackupWindow=t.PreferredBackupWindow;if(t.PreferredMaintenanceWindow)e.PreferredMaintenanceWindow=t.PreferredMaintenanceWindow;if(t.MultiAZ!==void 0)e.MultiAZ=t.MultiAZ;if(t.EngineVersion)e.EngineVersion=t.EngineVersion;if(t.AutoMinorVersionUpgrade!==void 0)e.AutoMinorVersionUpgrade=t.AutoMinorVersionUpgrade;if(t.PubliclyAccessible!==void 0)e.PubliclyAccessible=t.PubliclyAccessible;if(t.ApplyImmediately!==void 0)e.ApplyImmediately=t.ApplyImmediately;if(t.StorageType)e.StorageType=t.StorageType;if(t.DeletionProtection!==void 0)e.DeletionProtection=t.DeletionProtection;if(t.VpcSecurityGroupIds)t.VpcSecurityGroupIds.forEach((n,c)=>{e[`VpcSecurityGroupIds.VpcSecurityGroupId.${c+1}`]=n});let r=new URLSearchParams(Qt(e)).toString(),d=await this.client.request({service:"rds",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:r});return{DBInstance:(d.ModifyDBInstanceResult||d).DBInstance}}async modifyDBCluster(t){let e={Action:"ModifyDBCluster",Version:"2014-10-31",DBClusterIdentifier:t.DBClusterIdentifier};if(t.ServerlessV2ScalingConfiguration)e["ServerlessV2ScalingConfiguration.MinCapacity"]=t.ServerlessV2ScalingConfiguration.MinCapacity,e["ServerlessV2ScalingConfiguration.MaxCapacity"]=t.ServerlessV2ScalingConfiguration.MaxCapacity;if(t.BackupRetentionPeriod!==void 0)e.BackupRetentionPeriod=t.BackupRetentionPeriod;if(t.EngineVersion)e.EngineVersion=t.EngineVersion;if(t.MasterUserPassword)e.MasterUserPassword=t.MasterUserPassword;if(t.DeletionProtection!==void 0)e.DeletionProtection=t.DeletionProtection;if(t.ApplyImmediately!==void 0)e.ApplyImmediately=t.ApplyImmediately;let r=new URLSearchParams(Qt(e)).toString(),d=await this.client.request({service:"rds",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:r});return{DBCluster:(d.ModifyDBClusterResult||d).DBCluster}}async rebootDBCluster(t){let e={Action:"FailoverDBCluster",Version:"2014-10-31",DBClusterIdentifier:t},r=await this.client.request({service:"rds",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(Qt(e)).toString()});return{DBCluster:(r.FailoverDBClusterResult||r).DBCluster}}async createDBClusterSnapshot(t,e){let r={Action:"CreateDBClusterSnapshot",Version:"2014-10-31",DBClusterIdentifier:t,DBClusterSnapshotIdentifier:e};return this.client.request({service:"rds",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(Qt(r)).toString()})}async describeDBClusterSnapshots(t={}){let e={Action:"DescribeDBClusterSnapshots",Version:"2014-10-31",...t},r=await this.client.request({service:"rds",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(Qt(e)).toString()}),d=r.DescribeDBClusterSnapshotsResult||r,E=d.DBClusterSnapshots?.DBClusterSnapshot??d.DBClusterSnapshots??[];return{DBClusterSnapshots:Array.isArray(E)?E:[E]}}async deleteDBClusterSnapshot(t){await this.client.request({service:"rds",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(Qt({Action:"DeleteDBClusterSnapshot",Version:"2014-10-31",DBClusterSnapshotIdentifier:t})).toString()})}async deleteDBCluster(t,e){let r={Action:"DeleteDBCluster",Version:"2014-10-31",DBClusterIdentifier:t,SkipFinalSnapshot:!e};if(e)r.FinalDBSnapshotIdentifier=e;let d=await this.client.request({service:"rds",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(Qt(r)).toString()});return{DBCluster:(d.DeleteDBClusterResult||d).DBCluster}}async restoreDBClusterToPointInTime(t){let e={Action:"RestoreDBClusterToPointInTime",Version:"2014-10-31",DBClusterIdentifier:t.DBClusterIdentifier,SourceDBClusterIdentifier:t.SourceDBClusterIdentifier};if(t.RestoreToTime)e.RestoreToTime=t.RestoreToTime.toISOString();if(t.UseLatestRestorableTime)e.UseLatestRestorableTime=!0;if(t.DBSubnetGroupName)e.DBSubnetGroupName=t.DBSubnetGroupName;if(t.VpcSecurityGroupIds)t.VpcSecurityGroupIds.forEach((n,c)=>{e[`VpcSecurityGroupIds.VpcSecurityGroupId.${c+1}`]=n});let r=new URLSearchParams(Qt(e)).toString(),d=await this.client.request({service:"rds",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:r});return{DBCluster:(d.RestoreDBClusterToPointInTimeResult||d).DBCluster}}async restoreDBClusterFromSnapshot(t){let e={Action:"RestoreDBClusterFromSnapshot",Version:"2014-10-31",DBClusterIdentifier:t.DBClusterIdentifier,SnapshotIdentifier:t.SnapshotIdentifier,Engine:t.Engine};if(t.EngineVersion)e.EngineVersion=t.EngineVersion;if(t.DBSubnetGroupName)e.DBSubnetGroupName=t.DBSubnetGroupName;if(t.DeletionProtection!==void 0)e.DeletionProtection=t.DeletionProtection;if(t.VpcSecurityGroupIds?.forEach((E,n)=>{e[`VpcSecurityGroupIds.VpcSecurityGroupId.${n+1}`]=E}),t.ServerlessV2ScalingConfiguration)e["ServerlessV2ScalingConfiguration.MinCapacity"]=t.ServerlessV2ScalingConfiguration.MinCapacity,e["ServerlessV2ScalingConfiguration.MaxCapacity"]=t.ServerlessV2ScalingConfiguration.MaxCapacity;let r=await this.client.request({service:"rds",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(Qt(e)).toString()});return{DBCluster:(r.RestoreDBClusterFromSnapshotResult||r).DBCluster}}async startDBInstance(t){let r=new URLSearchParams(Qt({Action:"StartDBInstance",Version:"2014-10-31",DBInstanceIdentifier:t})).toString(),d=await this.client.request({service:"rds",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:r});return{DBInstance:(d.StartDBInstanceResult||d).DBInstance}}async stopDBInstance(t){let e={Action:"StopDBInstance",Version:"2014-10-31",DBInstanceIdentifier:t.DBInstanceIdentifier};if(t.DBSnapshotIdentifier)e.DBSnapshotIdentifier=t.DBSnapshotIdentifier;let r=new URLSearchParams(Qt(e)).toString(),d=await this.client.request({service:"rds",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:r});return{DBInstance:(d.StopDBInstanceResult||d).DBInstance}}async rebootDBInstance(t){let e={Action:"RebootDBInstance",Version:"2014-10-31",DBInstanceIdentifier:t.DBInstanceIdentifier};if(t.ForceFailover!==void 0)e.ForceFailover=t.ForceFailover;let r=new URLSearchParams(Qt(e)).toString(),d=await this.client.request({service:"rds",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:r});return{DBInstance:(d.RebootDBInstanceResult||d).DBInstance}}async createDBSnapshot(t){let e={Action:"CreateDBSnapshot",Version:"2014-10-31",DBInstanceIdentifier:t.DBInstanceIdentifier,DBSnapshotIdentifier:t.DBSnapshotIdentifier};if(t.Tags)t.Tags.forEach((n,c)=>{e[`Tags.Tag.${c+1}.Key`]=n.Key,e[`Tags.Tag.${c+1}.Value`]=n.Value});let r=new URLSearchParams(Qt(e)).toString(),d=await this.client.request({service:"rds",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:r});return{DBSnapshot:(d.CreateDBSnapshotResult||d).DBSnapshot}}async deleteDBSnapshot(t){let r=new URLSearchParams(Qt({Action:"DeleteDBSnapshot",Version:"2014-10-31",DBSnapshotIdentifier:t})).toString(),d=await this.client.request({service:"rds",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:r});return{DBSnapshot:(d.DeleteDBSnapshotResult||d).DBSnapshot}}async restoreDBInstanceFromDBSnapshot(t){let e={Action:"RestoreDBInstanceFromDBSnapshot",Version:"2014-10-31",DBInstanceIdentifier:t.DBInstanceIdentifier,DBSnapshotIdentifier:t.DBSnapshotIdentifier};if(t.DBInstanceClass)e.DBInstanceClass=t.DBInstanceClass;if(t.Port)e.Port=t.Port;if(t.AvailabilityZone)e.AvailabilityZone=t.AvailabilityZone;if(t.DBSubnetGroupName)e.DBSubnetGroupName=t.DBSubnetGroupName;if(t.MultiAZ!==void 0)e.MultiAZ=t.MultiAZ;if(t.PubliclyAccessible!==void 0)e.PubliclyAccessible=t.PubliclyAccessible;if(t.AutoMinorVersionUpgrade!==void 0)e.AutoMinorVersionUpgrade=t.AutoMinorVersionUpgrade;if(t.StorageType)e.StorageType=t.StorageType;if(t.DeletionProtection!==void 0)e.DeletionProtection=t.DeletionProtection;if(t.VpcSecurityGroupIds)t.VpcSecurityGroupIds.forEach((n,c)=>{e[`VpcSecurityGroupIds.VpcSecurityGroupId.${c+1}`]=n});if(t.Tags)t.Tags.forEach((n,c)=>{e[`Tags.Tag.${c+1}.Key`]=n.Key,e[`Tags.Tag.${c+1}.Value`]=n.Value});let r=new URLSearchParams(Qt(e)).toString(),d=await this.client.request({service:"rds",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:r});return{DBInstance:(d.RestoreDBInstanceFromDBSnapshotResult||d).DBInstance}}async waitForDBInstanceAvailable(t,e=60,r=30000){for(let d=0;d<e;d++){let E=await this.describeDBInstance(t);if(E?.DBInstanceStatus==="available")return E;if(["deleted","failed","incompatible-restore","incompatible-parameters"].includes(E?.DBInstanceStatus||""))throw Error(`DB instance ${t} is in terminal state: ${E?.DBInstanceStatus}`);await new Promise((n)=>setTimeout(n,r))}throw Error(`Timeout waiting for DB instance ${t} to become available`)}async waitForDBInstanceDeleted(t,e=60,r=30000){for(let d=0;d<e;d++)try{let E=await this.describeDBInstance(t);if(E?.DBInstanceStatus==="deleting"){await new Promise((n)=>setTimeout(n,r));continue}throw Error(`DB instance ${t} is in state: ${E?.DBInstanceStatus}`)}catch(E){if(E.code==="DBInstanceNotFound"||E.code==="DBInstanceNotFoundFault")return;throw E}throw Error(`Timeout waiting for DB instance ${t} to be deleted`)}}var Pn=wr(()=>{Lt()});var VD=wr(()=>{Lt()});function H_(t){console.log(`${sE.green}✓${sE.reset} ${t}`)}function Xh(t){console.log(`${sE.cyan}→${sE.reset} ${t}`)}function DL(t){console.log(`
|
|
4115
|
+
`,E}}var Jy;var qT=gr(()=>{kT();n_();tr();xT();Jy=new JS});var p0={};ER(p0,{RDSClient:()=>nd});class nd{client;region;constructor(t="us-east-1"){this.region=t,this.client=new dt}async describeDBInstances(t){let e={Action:"DescribeDBInstances",Version:"2014-10-31"};if(t?.DBInstanceIdentifier)e.DBInstanceIdentifier=t.DBInstanceIdentifier;if(t?.MaxRecords)e.MaxRecords=t.MaxRecords;if(t?.Marker)e.Marker=t.Marker;if(t?.Filters)t.Filters.forEach((c,_)=>{e[`Filters.Filter.${_+1}.Name`]=c.Name,c.Values.forEach((T,i)=>{e[`Filters.Filter.${_+1}.Values.Value.${i+1}`]=T})});let r=new URLSearchParams(Qt(e)).toString(),d=await this.client.request({service:"rds",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:r}),E=d.DescribeDBInstancesResult||d,n=E.DBInstances?.DBInstance||[];if(!Array.isArray(n))n=n?[n]:[];return{DBInstances:n,Marker:E.Marker}}async describeDBInstance(t){return(await this.describeDBInstances({DBInstanceIdentifier:t})).DBInstances?.[0]}async describeDBClusters(t){let e={Action:"DescribeDBClusters",Version:"2014-10-31"};if(t?.DBClusterIdentifier)e.DBClusterIdentifier=t.DBClusterIdentifier;if(t?.MaxRecords)e.MaxRecords=t.MaxRecords;if(t?.Marker)e.Marker=t.Marker;if(t?.Filters)t.Filters.forEach((c,_)=>{e[`Filters.Filter.${_+1}.Name`]=c.Name,c.Values.forEach((T,i)=>{e[`Filters.Filter.${_+1}.Values.Value.${i+1}`]=T})});let r=new URLSearchParams(Qt(e)).toString(),d=await this.client.request({service:"rds",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:r}),E=d.DescribeDBClustersResult||d,n=E.DBClusters?.DBCluster||[];if(!Array.isArray(n))n=n?[n]:[];return{DBClusters:n,Marker:E.Marker}}async describeDBSnapshots(t){let e={Action:"DescribeDBSnapshots",Version:"2014-10-31"};if(t?.DBInstanceIdentifier)e.DBInstanceIdentifier=t.DBInstanceIdentifier;if(t?.DBSnapshotIdentifier)e.DBSnapshotIdentifier=t.DBSnapshotIdentifier;if(t?.SnapshotType)e.SnapshotType=t.SnapshotType;if(t?.MaxRecords)e.MaxRecords=t.MaxRecords;if(t?.Marker)e.Marker=t.Marker;let r=new URLSearchParams(Qt(e)).toString(),d=await this.client.request({service:"rds",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:r}),E=d.DescribeDBSnapshotsResult||d,n=E.DBSnapshots?.DBSnapshot||[];if(!Array.isArray(n))n=n?[n]:[];return{DBSnapshots:n,Marker:E.Marker}}async describeDBSubnetGroups(t){let e={Action:"DescribeDBSubnetGroups",Version:"2014-10-31"};if(t?.DBSubnetGroupName)e.DBSubnetGroupName=t.DBSubnetGroupName;if(t?.MaxRecords)e.MaxRecords=t.MaxRecords;if(t?.Marker)e.Marker=t.Marker;let r=new URLSearchParams(Qt(e)).toString(),d=await this.client.request({service:"rds",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:r}),E=d.DescribeDBSubnetGroupsResult||d,n=E.DBSubnetGroups?.DBSubnetGroup||[];if(!Array.isArray(n))n=n?[n]:[];return{DBSubnetGroups:n,Marker:E.Marker}}async createDBInstance(t){let e={Action:"CreateDBInstance",Version:"2014-10-31",DBInstanceIdentifier:t.DBInstanceIdentifier,DBInstanceClass:t.DBInstanceClass,Engine:t.Engine};if(t.DBClusterIdentifier)e.DBClusterIdentifier=t.DBClusterIdentifier;if(t.MasterUsername)e.MasterUsername=t.MasterUsername;if(t.MasterUserPassword)e.MasterUserPassword=t.MasterUserPassword;if(t.DBName)e.DBName=t.DBName;if(t.AllocatedStorage)e.AllocatedStorage=t.AllocatedStorage;if(t.DBSubnetGroupName)e.DBSubnetGroupName=t.DBSubnetGroupName;if(t.AvailabilityZone)e.AvailabilityZone=t.AvailabilityZone;if(t.PreferredMaintenanceWindow)e.PreferredMaintenanceWindow=t.PreferredMaintenanceWindow;if(t.PreferredBackupWindow)e.PreferredBackupWindow=t.PreferredBackupWindow;if(t.BackupRetentionPeriod!==void 0)e.BackupRetentionPeriod=t.BackupRetentionPeriod;if(t.MultiAZ!==void 0)e.MultiAZ=t.MultiAZ;if(t.EngineVersion)e.EngineVersion=t.EngineVersion;if(t.AutoMinorVersionUpgrade!==void 0)e.AutoMinorVersionUpgrade=t.AutoMinorVersionUpgrade;if(t.LicenseModel)e.LicenseModel=t.LicenseModel;if(t.PubliclyAccessible!==void 0)e.PubliclyAccessible=t.PubliclyAccessible;if(t.StorageType)e.StorageType=t.StorageType;if(t.StorageEncrypted!==void 0)e.StorageEncrypted=t.StorageEncrypted;if(t.KmsKeyId)e.KmsKeyId=t.KmsKeyId;if(t.DeletionProtection!==void 0)e.DeletionProtection=t.DeletionProtection;if(t.VpcSecurityGroupIds)t.VpcSecurityGroupIds.forEach((n,c)=>{e[`VpcSecurityGroupIds.VpcSecurityGroupId.${c+1}`]=n});if(t.Tags)t.Tags.forEach((n,c)=>{e[`Tags.Tag.${c+1}.Key`]=n.Key,e[`Tags.Tag.${c+1}.Value`]=n.Value});let r=new URLSearchParams(Qt(e)).toString(),d=await this.client.request({service:"rds",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:r});return{DBInstance:(d.CreateDBInstanceResult||d).DBInstance}}async createDBCluster(t){let e={Action:"CreateDBCluster",Version:"2014-10-31",DBClusterIdentifier:t.DBClusterIdentifier,Engine:t.Engine};if(t.EngineVersion)e.EngineVersion=t.EngineVersion;if(t.MasterUsername)e.MasterUsername=t.MasterUsername;if(t.MasterUserPassword)e.MasterUserPassword=t.MasterUserPassword;if(t.DatabaseName)e.DatabaseName=t.DatabaseName;if(t.DBSubnetGroupName)e.DBSubnetGroupName=t.DBSubnetGroupName;if(t.BackupRetentionPeriod!==void 0)e.BackupRetentionPeriod=t.BackupRetentionPeriod;if(t.StorageEncrypted!==void 0)e.StorageEncrypted=t.StorageEncrypted;if(t.KmsKeyId)e.KmsKeyId=t.KmsKeyId;if(t.DeletionProtection!==void 0)e.DeletionProtection=t.DeletionProtection;if(t.ServerlessV2ScalingConfiguration)e["ServerlessV2ScalingConfiguration.MinCapacity"]=t.ServerlessV2ScalingConfiguration.MinCapacity,e["ServerlessV2ScalingConfiguration.MaxCapacity"]=t.ServerlessV2ScalingConfiguration.MaxCapacity;t.VpcSecurityGroupIds?.forEach((E,n)=>{e[`VpcSecurityGroupIds.VpcSecurityGroupId.${n+1}`]=E});let r=await this.client.request({service:"rds",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(Qt(e)).toString()});return{DBCluster:(r.CreateDBClusterResult||r).DBCluster}}async deleteDBInstance(t){let e={Action:"DeleteDBInstance",Version:"2014-10-31",DBInstanceIdentifier:t.DBInstanceIdentifier};if(t.SkipFinalSnapshot!==void 0)e.SkipFinalSnapshot=t.SkipFinalSnapshot;if(t.FinalDBSnapshotIdentifier)e.FinalDBSnapshotIdentifier=t.FinalDBSnapshotIdentifier;if(t.DeleteAutomatedBackups!==void 0)e.DeleteAutomatedBackups=t.DeleteAutomatedBackups;let r=new URLSearchParams(Qt(e)).toString(),d=await this.client.request({service:"rds",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:r});return{DBInstance:(d.DeleteDBInstanceResult||d).DBInstance}}async modifyDBInstance(t){let e={Action:"ModifyDBInstance",Version:"2014-10-31",DBInstanceIdentifier:t.DBInstanceIdentifier};if(t.DBInstanceClass)e.DBInstanceClass=t.DBInstanceClass;if(t.AllocatedStorage)e.AllocatedStorage=t.AllocatedStorage;if(t.MasterUserPassword)e.MasterUserPassword=t.MasterUserPassword;if(t.BackupRetentionPeriod!==void 0)e.BackupRetentionPeriod=t.BackupRetentionPeriod;if(t.PreferredBackupWindow)e.PreferredBackupWindow=t.PreferredBackupWindow;if(t.PreferredMaintenanceWindow)e.PreferredMaintenanceWindow=t.PreferredMaintenanceWindow;if(t.MultiAZ!==void 0)e.MultiAZ=t.MultiAZ;if(t.EngineVersion)e.EngineVersion=t.EngineVersion;if(t.AutoMinorVersionUpgrade!==void 0)e.AutoMinorVersionUpgrade=t.AutoMinorVersionUpgrade;if(t.PubliclyAccessible!==void 0)e.PubliclyAccessible=t.PubliclyAccessible;if(t.ApplyImmediately!==void 0)e.ApplyImmediately=t.ApplyImmediately;if(t.StorageType)e.StorageType=t.StorageType;if(t.DeletionProtection!==void 0)e.DeletionProtection=t.DeletionProtection;if(t.VpcSecurityGroupIds)t.VpcSecurityGroupIds.forEach((n,c)=>{e[`VpcSecurityGroupIds.VpcSecurityGroupId.${c+1}`]=n});let r=new URLSearchParams(Qt(e)).toString(),d=await this.client.request({service:"rds",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:r});return{DBInstance:(d.ModifyDBInstanceResult||d).DBInstance}}async modifyDBCluster(t){let e={Action:"ModifyDBCluster",Version:"2014-10-31",DBClusterIdentifier:t.DBClusterIdentifier};if(t.ServerlessV2ScalingConfiguration)e["ServerlessV2ScalingConfiguration.MinCapacity"]=t.ServerlessV2ScalingConfiguration.MinCapacity,e["ServerlessV2ScalingConfiguration.MaxCapacity"]=t.ServerlessV2ScalingConfiguration.MaxCapacity;if(t.BackupRetentionPeriod!==void 0)e.BackupRetentionPeriod=t.BackupRetentionPeriod;if(t.EngineVersion)e.EngineVersion=t.EngineVersion;if(t.MasterUserPassword)e.MasterUserPassword=t.MasterUserPassword;if(t.DeletionProtection!==void 0)e.DeletionProtection=t.DeletionProtection;if(t.ApplyImmediately!==void 0)e.ApplyImmediately=t.ApplyImmediately;let r=new URLSearchParams(Qt(e)).toString(),d=await this.client.request({service:"rds",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:r});return{DBCluster:(d.ModifyDBClusterResult||d).DBCluster}}async rebootDBCluster(t){let e={Action:"FailoverDBCluster",Version:"2014-10-31",DBClusterIdentifier:t},r=await this.client.request({service:"rds",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(Qt(e)).toString()});return{DBCluster:(r.FailoverDBClusterResult||r).DBCluster}}async createDBClusterSnapshot(t,e){let r={Action:"CreateDBClusterSnapshot",Version:"2014-10-31",DBClusterIdentifier:t,DBClusterSnapshotIdentifier:e};return this.client.request({service:"rds",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(Qt(r)).toString()})}async describeDBClusterSnapshots(t={}){let e={Action:"DescribeDBClusterSnapshots",Version:"2014-10-31",...t},r=await this.client.request({service:"rds",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(Qt(e)).toString()}),d=r.DescribeDBClusterSnapshotsResult||r,E=d.DBClusterSnapshots?.DBClusterSnapshot??d.DBClusterSnapshots??[];return{DBClusterSnapshots:Array.isArray(E)?E:[E]}}async deleteDBClusterSnapshot(t){await this.client.request({service:"rds",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(Qt({Action:"DeleteDBClusterSnapshot",Version:"2014-10-31",DBClusterSnapshotIdentifier:t})).toString()})}async deleteDBCluster(t,e){let r={Action:"DeleteDBCluster",Version:"2014-10-31",DBClusterIdentifier:t,SkipFinalSnapshot:!e};if(e)r.FinalDBSnapshotIdentifier=e;let d=await this.client.request({service:"rds",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(Qt(r)).toString()});return{DBCluster:(d.DeleteDBClusterResult||d).DBCluster}}async restoreDBClusterToPointInTime(t){let e={Action:"RestoreDBClusterToPointInTime",Version:"2014-10-31",DBClusterIdentifier:t.DBClusterIdentifier,SourceDBClusterIdentifier:t.SourceDBClusterIdentifier};if(t.RestoreToTime)e.RestoreToTime=t.RestoreToTime.toISOString();if(t.UseLatestRestorableTime)e.UseLatestRestorableTime=!0;if(t.DBSubnetGroupName)e.DBSubnetGroupName=t.DBSubnetGroupName;if(t.VpcSecurityGroupIds)t.VpcSecurityGroupIds.forEach((n,c)=>{e[`VpcSecurityGroupIds.VpcSecurityGroupId.${c+1}`]=n});let r=new URLSearchParams(Qt(e)).toString(),d=await this.client.request({service:"rds",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:r});return{DBCluster:(d.RestoreDBClusterToPointInTimeResult||d).DBCluster}}async restoreDBClusterFromSnapshot(t){let e={Action:"RestoreDBClusterFromSnapshot",Version:"2014-10-31",DBClusterIdentifier:t.DBClusterIdentifier,SnapshotIdentifier:t.SnapshotIdentifier,Engine:t.Engine};if(t.EngineVersion)e.EngineVersion=t.EngineVersion;if(t.DBSubnetGroupName)e.DBSubnetGroupName=t.DBSubnetGroupName;if(t.DeletionProtection!==void 0)e.DeletionProtection=t.DeletionProtection;if(t.VpcSecurityGroupIds?.forEach((E,n)=>{e[`VpcSecurityGroupIds.VpcSecurityGroupId.${n+1}`]=E}),t.ServerlessV2ScalingConfiguration)e["ServerlessV2ScalingConfiguration.MinCapacity"]=t.ServerlessV2ScalingConfiguration.MinCapacity,e["ServerlessV2ScalingConfiguration.MaxCapacity"]=t.ServerlessV2ScalingConfiguration.MaxCapacity;let r=await this.client.request({service:"rds",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(Qt(e)).toString()});return{DBCluster:(r.RestoreDBClusterFromSnapshotResult||r).DBCluster}}async startDBInstance(t){let r=new URLSearchParams(Qt({Action:"StartDBInstance",Version:"2014-10-31",DBInstanceIdentifier:t})).toString(),d=await this.client.request({service:"rds",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:r});return{DBInstance:(d.StartDBInstanceResult||d).DBInstance}}async stopDBInstance(t){let e={Action:"StopDBInstance",Version:"2014-10-31",DBInstanceIdentifier:t.DBInstanceIdentifier};if(t.DBSnapshotIdentifier)e.DBSnapshotIdentifier=t.DBSnapshotIdentifier;let r=new URLSearchParams(Qt(e)).toString(),d=await this.client.request({service:"rds",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:r});return{DBInstance:(d.StopDBInstanceResult||d).DBInstance}}async rebootDBInstance(t){let e={Action:"RebootDBInstance",Version:"2014-10-31",DBInstanceIdentifier:t.DBInstanceIdentifier};if(t.ForceFailover!==void 0)e.ForceFailover=t.ForceFailover;let r=new URLSearchParams(Qt(e)).toString(),d=await this.client.request({service:"rds",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:r});return{DBInstance:(d.RebootDBInstanceResult||d).DBInstance}}async createDBSnapshot(t){let e={Action:"CreateDBSnapshot",Version:"2014-10-31",DBInstanceIdentifier:t.DBInstanceIdentifier,DBSnapshotIdentifier:t.DBSnapshotIdentifier};if(t.Tags)t.Tags.forEach((n,c)=>{e[`Tags.Tag.${c+1}.Key`]=n.Key,e[`Tags.Tag.${c+1}.Value`]=n.Value});let r=new URLSearchParams(Qt(e)).toString(),d=await this.client.request({service:"rds",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:r});return{DBSnapshot:(d.CreateDBSnapshotResult||d).DBSnapshot}}async deleteDBSnapshot(t){let r=new URLSearchParams(Qt({Action:"DeleteDBSnapshot",Version:"2014-10-31",DBSnapshotIdentifier:t})).toString(),d=await this.client.request({service:"rds",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:r});return{DBSnapshot:(d.DeleteDBSnapshotResult||d).DBSnapshot}}async restoreDBInstanceFromDBSnapshot(t){let e={Action:"RestoreDBInstanceFromDBSnapshot",Version:"2014-10-31",DBInstanceIdentifier:t.DBInstanceIdentifier,DBSnapshotIdentifier:t.DBSnapshotIdentifier};if(t.DBInstanceClass)e.DBInstanceClass=t.DBInstanceClass;if(t.Port)e.Port=t.Port;if(t.AvailabilityZone)e.AvailabilityZone=t.AvailabilityZone;if(t.DBSubnetGroupName)e.DBSubnetGroupName=t.DBSubnetGroupName;if(t.MultiAZ!==void 0)e.MultiAZ=t.MultiAZ;if(t.PubliclyAccessible!==void 0)e.PubliclyAccessible=t.PubliclyAccessible;if(t.AutoMinorVersionUpgrade!==void 0)e.AutoMinorVersionUpgrade=t.AutoMinorVersionUpgrade;if(t.StorageType)e.StorageType=t.StorageType;if(t.DeletionProtection!==void 0)e.DeletionProtection=t.DeletionProtection;if(t.VpcSecurityGroupIds)t.VpcSecurityGroupIds.forEach((n,c)=>{e[`VpcSecurityGroupIds.VpcSecurityGroupId.${c+1}`]=n});if(t.Tags)t.Tags.forEach((n,c)=>{e[`Tags.Tag.${c+1}.Key`]=n.Key,e[`Tags.Tag.${c+1}.Value`]=n.Value});let r=new URLSearchParams(Qt(e)).toString(),d=await this.client.request({service:"rds",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:r});return{DBInstance:(d.RestoreDBInstanceFromDBSnapshotResult||d).DBInstance}}async waitForDBInstanceAvailable(t,e=60,r=30000){for(let d=0;d<e;d++){let E=await this.describeDBInstance(t);if(E?.DBInstanceStatus==="available")return E;if(["deleted","failed","incompatible-restore","incompatible-parameters"].includes(E?.DBInstanceStatus||""))throw Error(`DB instance ${t} is in terminal state: ${E?.DBInstanceStatus}`);await new Promise((n)=>setTimeout(n,r))}throw Error(`Timeout waiting for DB instance ${t} to become available`)}async waitForDBInstanceDeleted(t,e=60,r=30000){for(let d=0;d<e;d++)try{let E=await this.describeDBInstance(t);if(E?.DBInstanceStatus==="deleting"){await new Promise((n)=>setTimeout(n,r));continue}throw Error(`DB instance ${t} is in state: ${E?.DBInstanceStatus}`)}catch(E){if(E.code==="DBInstanceNotFound"||E.code==="DBInstanceNotFoundFault")return;throw E}throw Error(`Timeout waiting for DB instance ${t} to be deleted`)}}var Pn=gr(()=>{Lt()});var VD=gr(()=>{Lt()});function H_(t){console.log(`${sE.green}✓${sE.reset} ${t}`)}function Xh(t){console.log(`${sE.cyan}→${sE.reset} ${t}`)}function DL(t){console.log(`
|
|
4116
4116
|
${sE.bright}${sE.cyan}${t}${sE.reset}
|
|
4117
|
-
`)}var sE,T3;var xf=wr(()=>{sE={reset:"\x1B[0m",bright:"\x1B[1m",dim:"\x1B[2m",red:"\x1B[31m",green:"\x1B[32m",yellow:"\x1B[33m",blue:"\x1B[34m",magenta:"\x1B[35m",cyan:"\x1B[36m",white:"\x1B[37m",gray:"\x1B[90m"};T3=!!(process.env.CI||process.env.GITHUB_ACTIONS||process.env.BUILDKITE||process.env.CIRCLECI||process.env.GITLAB_CI)});import q_ from"node:process";await Ht();import{createHash as VB}from"node:crypto";import{existsSync as Ud,mkdtempSync as eu,readdirSync as Yw,rmSync as dn,statSync as qw}from"node:fs";import{readFile as mr,writeFile as en}from"node:fs/promises";import{tmpdir as qh}from"node:os";import{dirname as KB,extname as x_,join as Wt,normalize as ZB,relative as kB,resolve as bB,sep as xB}from"node:path";import{fileURLToPath as qB}from"node:url";import{createCipheriv as kg,createDecipheriv as bg,createHash as bO,randomBytes as xg}from"node:crypto";var me=(t)=>{if(typeof t!=="string")return{};try{return JSON.parse(t)}catch{return{}}},Kt=(t)=>typeof t==="string"?t:void 0,wR=(t)=>Number(t)===1,Mr=(t,e,r,d)=>{let E=Number(t);return Number.isFinite(E)?Math.min(d,Math.max(r,Math.floor(E))):e},MO=(t)=>bO("sha256").update(t).digest("hex").slice(0,16);function GO(t){return{id:String(t.id),projectId:String(t.project_id),environmentId:Kt(t.environment_id),resourceId:Kt(t.resource_id),name:String(t.name),kind:String(t.kind),target:String(t.target),config:me(t.config),intervalSeconds:Number(t.interval_seconds),timeoutSeconds:Number(t.timeout_seconds),failureThreshold:Number(t.failure_threshold),recoveryThreshold:Number(t.recovery_threshold),regions:me(t.regions),enabled:wR(t.enabled),version:Number(t.version),createdAt:String(t.created_at),updatedAt:String(t.updated_at)}}function VO(t){return{id:String(t.id),checkId:String(t.check_id),status:String(t.status),agent:String(t.agent),region:Kt(t.region),statusCode:t.status_code==null?void 0:Number(t.status_code),message:Kt(t.message),timings:me(t.timings),checkedAt:String(t.checked_at)}}function KO(t){return{id:String(t.id),projectId:String(t.project_id),environmentId:Kt(t.environment_id),resourceId:Kt(t.resource_id),healthCheckId:Kt(t.health_check_id),name:String(t.name),signal:String(t.signal),operator:String(t.operator),threshold:t.threshold==null?void 0:Number(t.threshold),recoveryThreshold:t.recovery_threshold==null?void 0:Number(t.recovery_threshold),windowMs:Number(t.window_ms),consecutive:Number(t.consecutive),recoveryConsecutive:Number(t.recovery_consecutive),noDataPolicy:String(t.no_data_policy),severity:String(t.severity),groupBy:me(t.group_by),labels:me(t.labels),enabled:wR(t.enabled),version:Number(t.version),createdAt:String(t.created_at),updatedAt:String(t.updated_at)}}function fR(t){return{id:String(t.id),ruleId:String(t.rule_id),projectId:String(t.project_id),environmentId:Kt(t.environment_id),resourceId:Kt(t.resource_id),dedupKey:String(t.dedup_key),groupKey:String(t.group_key),state:String(t.state),severity:String(t.severity),title:String(t.title),evidence:me(t.evidence),failureCount:Number(t.failure_count),recoveryCount:Number(t.recovery_count),occurrenceCount:Number(t.occurrence_count),ownerActorId:Kt(t.owner_actor_id),acknowledgedByActorId:Kt(t.acknowledged_by_actor_id),acknowledgedAt:Kt(t.acknowledged_at),firstSeenAt:String(t.first_seen_at),lastSeenAt:String(t.last_seen_at),firingAt:Kt(t.firing_at),resolvedAt:Kt(t.resolved_at),silencedUntil:Kt(t.silenced_until),updatedAt:String(t.updated_at)}}function ZO(t){return{id:String(t.id),organizationId:String(t.organization_id),name:String(t.name),kind:String(t.kind),config:me(t.config),credentialFingerprint:Kt(t.credential_fingerprint),hasCredential:!!t.credential_ciphertext,status:String(t.status),version:Number(t.version),lastTestedAt:Kt(t.last_tested_at),lastError:Kt(t.last_error),createdAt:String(t.created_at),updatedAt:String(t.updated_at)}}function kO(t){return{id:String(t.id),organizationId:String(t.organization_id),name:String(t.name),priority:Number(t.priority),matcher:me(t.matcher),channelIds:me(t.channel_ids),quietHours:t.quiet_hours?me(t.quiet_hours):void 0,groupWaitSeconds:Number(t.group_wait_seconds),reminderSeconds:t.reminder_seconds==null?void 0:Number(t.reminder_seconds),escalation:me(t.escalation),template:Kt(t.template),rateLimitPerMinute:Number(t.rate_limit_per_minute),enabled:wR(t.enabled),version:Number(t.version),createdAt:String(t.created_at),updatedAt:String(t.updated_at)}}function UR(t){return{id:String(t.id),alertId:Kt(t.alert_id),channelId:String(t.channel_id),routeId:Kt(t.route_id),eventType:String(t.event_type),idempotencyKey:String(t.idempotency_key),state:String(t.state),attempt:Number(t.attempt),maxAttempts:Number(t.max_attempts),nextAttemptAt:Kt(t.next_attempt_at),responseStatus:t.response_status==null?void 0:Number(t.response_status),error:Kt(t.error),payload:me(t.payload),createdAt:String(t.created_at),updatedAt:String(t.updated_at),deliveredAt:Kt(t.delivered_at)}}class gR{controlPlane;options;key;constructor(t,e){this.controlPlane=t;this.options=e;this.key=bO("sha256").update(e.encryptionKey).digest()}now(){return(this.options.now?.()??new Date).toISOString()}encrypt(t){let e=xg(12),r=kg("aes-256-gcm",this.key,e),d=Buffer.concat([r.update(t,"utf8"),r.final()]);return`v1.${e.toString("base64url")}.${r.getAuthTag().toString("base64url")}.${d.toString("base64url")}`}decrypt(t){let[,e,r,d]=t.split("."),E=bg("aes-256-gcm",this.key,Buffer.from(e,"base64url"));return E.setAuthTag(Buffer.from(r,"base64url")),Buffer.concat([E.update(Buffer.from(d,"base64url")),E.final()]).toString("utf8")}createHealthCheck(t){if(!t.name.trim())throw Error("Health checks require a name.");if(!["http","tcp","command"].includes(t.kind))throw Error("Unsupported health check kind.");if(t.kind==="http"&&!/^https?:\/\//.test(t.target)||t.kind==="tcp"&&!/^[a-zA-Z0-9.-]+$/.test(t.target)||t.kind==="command"&&!t.config.command?.length)throw Error("Health check target is invalid.");let e=crypto.randomUUID(),r=this.now();return this.controlPlane.database.run("INSERT INTO health_checks (id,project_id,environment_id,resource_id,name,kind,target,config,interval_seconds,timeout_seconds,failure_threshold,recovery_threshold,regions,enabled,version,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",[e,t.projectId,t.environmentId??null,t.resourceId??null,t.name.trim().slice(0,100),t.kind,t.target,JSON.stringify(t.config),Mr(t.intervalSeconds,60,10,86400),Mr(t.timeoutSeconds,10,1,300),Mr(t.failureThreshold,3,1,100),Mr(t.recoveryThreshold,2,1,100),JSON.stringify(t.regions.slice(0,20)),t.enabled?1:0,1,r,r]),this.getHealthCheck(e)}getHealthCheck(t){let e=this.controlPlane.database.query("SELECT * FROM health_checks WHERE id=?").get(t);return e?GO(e):void 0}listHealthChecks(t,e){return this.controlPlane.database.query(`SELECT * FROM health_checks WHERE project_id=?${e?" AND environment_id=?":""} ORDER BY updated_at DESC`).all(t,...e?[e]:[]).map(GO)}setHealthCheckEnabled(t,e){this.controlPlane.database.run("UPDATE health_checks SET enabled=?,version=version+1,updated_at=? WHERE id=?",[e?1:0,this.now(),t]);let r=this.getHealthCheck(t);if(!r)throw Error("Health check was not found.");return r}appendHealthResult(t){let e=crypto.randomUUID();return this.controlPlane.database.run("INSERT INTO health_results (id,check_id,status,agent,region,status_code,message,timings,checked_at) VALUES (?,?,?,?,?,?,?,?,?)",[e,t.checkId,t.status,t.agent.slice(0,100),t.region??null,t.statusCode??null,t.message?.slice(0,1000)??null,JSON.stringify(t.timings),t.checkedAt]),VO(this.controlPlane.database.query("SELECT * FROM health_results WHERE id=?").get(e))}listHealthResults(t,e=100){return this.controlPlane.database.query("SELECT * FROM health_results WHERE check_id=? ORDER BY checked_at DESC LIMIT ?").all(t,Math.min(1000,Math.max(1,e))).map(VO)}createRule(t){if(!t.name.trim())throw Error("Alert rules require a name.");if(t.operator!=="unhealthy"&&t.threshold==null)throw Error("Metric alert rules require a threshold.");let e=crypto.randomUUID(),r=this.now();return this.controlPlane.database.run("INSERT INTO alert_rules (id,project_id,environment_id,resource_id,health_check_id,name,signal,operator,threshold,recovery_threshold,window_ms,consecutive,recovery_consecutive,no_data_policy,severity,group_by,labels,enabled,version,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",[e,t.projectId,t.environmentId??null,t.resourceId??null,t.healthCheckId??null,t.name.trim().slice(0,120),t.signal,t.operator,t.threshold??null,t.recoveryThreshold??null,Mr(t.windowMs,300000,1e4,2678400000),Mr(t.consecutive,3,1,100),Mr(t.recoveryConsecutive,2,1,100),t.noDataPolicy,t.severity,JSON.stringify(t.groupBy.slice(0,20)),JSON.stringify(t.labels),t.enabled?1:0,1,r,r]),this.getRule(e)}getRule(t){let e=this.controlPlane.database.query("SELECT * FROM alert_rules WHERE id=?").get(t);return e?KO(e):void 0}listRules(t,e){return this.controlPlane.database.query(`SELECT * FROM alert_rules WHERE project_id=?${e?" AND environment_id=?":""} ORDER BY updated_at DESC`).all(t,...e?[e]:[]).map(KO)}setRuleEnabled(t,e){this.controlPlane.database.run("UPDATE alert_rules SET enabled=?,version=version+1,updated_at=? WHERE id=?",[e?1:0,this.now(),t]);let r=this.getRule(t);if(!r)throw Error("Alert rule was not found.");return r}getAlertByDedup(t){let e=this.controlPlane.database.query("SELECT * FROM alerts WHERE dedup_key=?").get(t);return e?fR(e):void 0}getAlert(t){let e=this.controlPlane.database.query("SELECT * FROM alerts WHERE id=?").get(t);return e?fR(e):void 0}listAlerts(t,e={}){let r=["project_id=?"],d=[t];if(e.environmentId)r.push("environment_id=?"),d.push(e.environmentId);if(e.states?.length)r.push(`state IN (${e.states.map(()=>"?").join(",")})`),d.push(...e.states);return this.controlPlane.database.query(`SELECT * FROM alerts WHERE ${r.join(" AND ")} ORDER BY updated_at DESC LIMIT ?`).all(...d,Math.min(1000,e.limit??200)).map(fR)}saveAlert(t,e,r){return this.controlPlane.database.run("INSERT INTO alerts (id,rule_id,project_id,environment_id,resource_id,dedup_key,group_key,state,severity,title,evidence,failure_count,recovery_count,occurrence_count,owner_actor_id,acknowledged_by_actor_id,acknowledged_at,first_seen_at,last_seen_at,firing_at,resolved_at,silenced_until,updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) ON CONFLICT(id) DO UPDATE SET state=excluded.state,severity=excluded.severity,title=excluded.title,evidence=excluded.evidence,failure_count=excluded.failure_count,recovery_count=excluded.recovery_count,occurrence_count=excluded.occurrence_count,owner_actor_id=excluded.owner_actor_id,acknowledged_by_actor_id=excluded.acknowledged_by_actor_id,acknowledged_at=excluded.acknowledged_at,last_seen_at=excluded.last_seen_at,firing_at=excluded.firing_at,resolved_at=excluded.resolved_at,silenced_until=excluded.silenced_until,updated_at=excluded.updated_at",[t.id,t.ruleId,t.projectId,t.environmentId??null,t.resourceId??null,t.dedupKey,t.groupKey,t.state,t.severity,t.title,JSON.stringify(t.evidence),t.failureCount,t.recoveryCount,t.occurrenceCount,t.ownerActorId??null,t.acknowledgedByActorId??null,t.acknowledgedAt??null,t.firstSeenAt,t.lastSeenAt,t.firingAt??null,t.resolvedAt??null,t.silencedUntil??null,t.updatedAt]),this.controlPlane.database.run("INSERT INTO alert_events (id,alert_id,type,actor_id,payload,created_at) VALUES (?,?,?,?,?,?)",[crypto.randomUUID(),t.id,e,r??null,JSON.stringify({state:t.state,severity:t.severity,evidence:t.evidence}),t.updatedAt]),this.getAlert(t.id)}acknowledge(t,e){let r=this.getAlert(t);if(!r)throw Error("Alert was not found.");let d=this.now();return this.saveAlert({...r,acknowledgedByActorId:e,acknowledgedAt:d,updatedAt:d},"acknowledged",e)}assign(t,e,r){let d=this.getAlert(t);if(!d)throw Error("Alert was not found.");let E=this.now();return this.saveAlert({...d,ownerActorId:e,updatedAt:E},"assigned",r)}silenceAlert(t,e,r){let d=this.getAlert(t);if(!d)throw Error("Alert was not found.");let E=new Date(e);if(!Number.isFinite(E.getTime())||E<=new Date)throw Error("Silence end must be in the future.");let n=this.now();return this.saveAlert({...d,state:"silenced",silencedUntil:E.toISOString(),updatedAt:n},"silenced",r)}createSilence(t){let e=new Date(t.startsAt),r=new Date(t.endsAt);if(!Number.isFinite(e.getTime())||!Number.isFinite(r.getTime())||e>=r)throw Error("Silence window is invalid.");try{new Intl.DateTimeFormat("en",{timeZone:t.timezone}).format(e)}catch{throw Error("Silence timezone is invalid.")}let d=crypto.randomUUID();return this.controlPlane.database.run("INSERT INTO alert_silences (id,project_id,environment_id,resource_id,matcher,reason,starts_at,ends_at,timezone,created_by_actor_id,created_at) VALUES (?,?,?,?,?,?,?,?,?,?,?)",[d,t.projectId,t.environmentId??null,t.resourceId??null,JSON.stringify(t.matcher??{}),t.reason.slice(0,500),e.toISOString(),r.toISOString(),t.timezone,t.actorId??null,this.now()]),d}isSilenced(t,e,r){return this.controlPlane.database.query("SELECT * FROM alert_silences WHERE project_id=? AND starts_at<=? AND ends_at>?").all(t.projectId,r,r).some((E)=>{if(E.environment_id&&E.environment_id!==t.environmentId)return!1;if(E.resource_id&&E.resource_id!==t.resourceId)return!1;let n=me(E.matcher);return Object.entries(n).every(([c,_])=>e[c]===_)})}createChannel(t){if(!t.name.trim())throw Error("Notification channels require a name.");let e=crypto.randomUUID(),r=this.now(),d=t.credential?.trim();return this.controlPlane.database.run("INSERT INTO notification_channels (id,organization_id,name,kind,config,credential_ciphertext,credential_fingerprint,status,version,created_by_actor_id,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?)",[e,t.organizationId,t.name.trim().slice(0,100),t.kind,JSON.stringify(t.config??{}),d?this.encrypt(d):null,d?MO(d):null,"active",1,t.actorId??null,r,r]),this.getChannel(e)}getChannel(t){let e=this.controlPlane.database.query("SELECT * FROM notification_channels WHERE id=?").get(t);return e?ZO(e):void 0}channelCredential(t){let e=this.controlPlane.database.query("SELECT credential_ciphertext FROM notification_channels WHERE id=?").get(t);return e?.credential_ciphertext?this.decrypt(String(e.credential_ciphertext)):void 0}listChannels(t){return this.controlPlane.database.query("SELECT * FROM notification_channels WHERE organization_id=? ORDER BY updated_at DESC").all(t).map(ZO)}rotateChannel(t,e){let r=this.now();this.controlPlane.database.run("UPDATE notification_channels SET credential_ciphertext=?,credential_fingerprint=?,status='active',last_error=NULL,version=version+1,updated_at=? WHERE id=?",[this.encrypt(e),MO(e),r,t]);let d=this.getChannel(t);if(!d)throw Error("Notification channel was not found.");return d}setChannelStatus(t,e,r){this.controlPlane.database.run("UPDATE notification_channels SET status=?,last_error=?,updated_at=? WHERE id=?",[e,r?.slice(0,1000)??null,this.now(),t]);let d=this.getChannel(t);if(!d)throw Error("Notification channel was not found.");return d}markChannelTest(t,e,r){let d=this.now();return this.controlPlane.database.run("UPDATE notification_channels SET status=?,last_tested_at=?,last_error=?,updated_at=? WHERE id=?",[e?"active":"failing",d,r?.slice(0,1000)??null,d,t]),this.getChannel(t)}createRoute(t){let e=crypto.randomUUID(),r=this.now();return this.controlPlane.database.run("INSERT INTO notification_routes (id,organization_id,name,priority,matcher,channel_ids,quiet_hours,group_wait_seconds,reminder_seconds,escalation,template,rate_limit_per_minute,enabled,version,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",[e,t.organizationId,t.name.trim().slice(0,100),t.priority,JSON.stringify(t.matcher),JSON.stringify(t.channelIds),t.quietHours?JSON.stringify(t.quietHours):null,Mr(t.groupWaitSeconds,30,0,86400),t.reminderSeconds??null,JSON.stringify(t.escalation),t.template?.trim().slice(0,2000)??null,Mr(t.rateLimitPerMinute,60,1,1e4),t.enabled?1:0,1,r,r]),this.getRoute(e)}getRoute(t){let e=this.controlPlane.database.query("SELECT * FROM notification_routes WHERE id=?").get(t);return e?kO(e):void 0}listRoutes(t){return this.controlPlane.database.query("SELECT * FROM notification_routes WHERE organization_id=? ORDER BY priority DESC,created_at ASC").all(t).map(kO)}countRouteDeliveries(t,e){return Number(this.controlPlane.database.query("SELECT COUNT(*) count FROM notification_deliveries WHERE route_id=? AND created_at>=?").get(t,e)?.count??0)}setRouteEnabled(t,e){this.controlPlane.database.run("UPDATE notification_routes SET enabled=?,version=version+1,updated_at=? WHERE id=?",[e?1:0,this.now(),t]);let r=this.getRoute(t);if(!r)throw Error("Notification route was not found.");return r}createDelivery(t){let e=this.controlPlane.database.query("SELECT * FROM notification_deliveries WHERE idempotency_key=?").get(t.idempotencyKey);if(e)return UR(e);let r=crypto.randomUUID(),d=this.now();return this.controlPlane.database.run("INSERT INTO notification_deliveries (id,alert_id,channel_id,route_id,event_type,idempotency_key,state,attempt,max_attempts,next_attempt_at,payload,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)",[r,t.alertId??null,t.channelId,t.routeId??null,t.eventType,t.idempotencyKey,"pending",0,Mr(t.maxAttempts,3,1,10),t.nextAttemptAt??null,JSON.stringify(t.payload),d,d]),this.getDelivery(r)}getDelivery(t){let e=this.controlPlane.database.query("SELECT * FROM notification_deliveries WHERE id=?").get(t);return e?UR(e):void 0}listDeliveries(t={}){let e=[],r=[];if(t.alertId)e.push("alert_id=?"),r.push(t.alertId);if(t.states?.length)e.push(`state IN (${t.states.map(()=>"?").join(",")})`),r.push(...t.states);return this.controlPlane.database.query(`SELECT * FROM notification_deliveries${e.length?" WHERE "+e.join(" AND "):""} ORDER BY updated_at DESC LIMIT ?`).all(...r,Math.min(1000,t.limit??200)).map(UR)}updateDelivery(t,e){return this.controlPlane.database.run("UPDATE notification_deliveries SET state=?,attempt=?,next_attempt_at=?,response_status=?,error=?,delivered_at=?,updated_at=? WHERE id=?",[e.state,e.attempt,e.nextAttemptAt??null,e.responseStatus??null,e.error?.slice(0,1000)??null,e.deliveredAt??null,this.now(),t]),this.getDelivery(t)}}import{createHash as _1}from"node:crypto";var rd=36,$R=[{version:1,name:"core_control_plane",sql:`
|
|
4117
|
+
`)}var sE,T3;var xf=gr(()=>{sE={reset:"\x1B[0m",bright:"\x1B[1m",dim:"\x1B[2m",red:"\x1B[31m",green:"\x1B[32m",yellow:"\x1B[33m",blue:"\x1B[34m",magenta:"\x1B[35m",cyan:"\x1B[36m",white:"\x1B[37m",gray:"\x1B[90m"};T3=!!(process.env.CI||process.env.GITHUB_ACTIONS||process.env.BUILDKITE||process.env.CIRCLECI||process.env.GITLAB_CI)});import q_ from"node:process";await Ht();import{createHash as VB}from"node:crypto";import{existsSync as Ud,mkdtempSync as eu,readdirSync as Yw,rmSync as dn,statSync as qw}from"node:fs";import{readFile as mr,writeFile as en}from"node:fs/promises";import{tmpdir as qh}from"node:os";import{dirname as KB,extname as x_,join as Wt,normalize as ZB,relative as kB,resolve as bB,sep as xB}from"node:path";import{fileURLToPath as qB}from"node:url";import{createCipheriv as kg,createDecipheriv as bg,createHash as bO,randomBytes as xg}from"node:crypto";var me=(t)=>{if(typeof t!=="string")return{};try{return JSON.parse(t)}catch{return{}}},Kt=(t)=>typeof t==="string"?t:void 0,wR=(t)=>Number(t)===1,Mr=(t,e,r,d)=>{let E=Number(t);return Number.isFinite(E)?Math.min(d,Math.max(r,Math.floor(E))):e},MO=(t)=>bO("sha256").update(t).digest("hex").slice(0,16);function GO(t){return{id:String(t.id),projectId:String(t.project_id),environmentId:Kt(t.environment_id),resourceId:Kt(t.resource_id),name:String(t.name),kind:String(t.kind),target:String(t.target),config:me(t.config),intervalSeconds:Number(t.interval_seconds),timeoutSeconds:Number(t.timeout_seconds),failureThreshold:Number(t.failure_threshold),recoveryThreshold:Number(t.recovery_threshold),regions:me(t.regions),enabled:wR(t.enabled),version:Number(t.version),createdAt:String(t.created_at),updatedAt:String(t.updated_at)}}function VO(t){return{id:String(t.id),checkId:String(t.check_id),status:String(t.status),agent:String(t.agent),region:Kt(t.region),statusCode:t.status_code==null?void 0:Number(t.status_code),message:Kt(t.message),timings:me(t.timings),checkedAt:String(t.checked_at)}}function KO(t){return{id:String(t.id),projectId:String(t.project_id),environmentId:Kt(t.environment_id),resourceId:Kt(t.resource_id),healthCheckId:Kt(t.health_check_id),name:String(t.name),signal:String(t.signal),operator:String(t.operator),threshold:t.threshold==null?void 0:Number(t.threshold),recoveryThreshold:t.recovery_threshold==null?void 0:Number(t.recovery_threshold),windowMs:Number(t.window_ms),consecutive:Number(t.consecutive),recoveryConsecutive:Number(t.recovery_consecutive),noDataPolicy:String(t.no_data_policy),severity:String(t.severity),groupBy:me(t.group_by),labels:me(t.labels),enabled:wR(t.enabled),version:Number(t.version),createdAt:String(t.created_at),updatedAt:String(t.updated_at)}}function fR(t){return{id:String(t.id),ruleId:String(t.rule_id),projectId:String(t.project_id),environmentId:Kt(t.environment_id),resourceId:Kt(t.resource_id),dedupKey:String(t.dedup_key),groupKey:String(t.group_key),state:String(t.state),severity:String(t.severity),title:String(t.title),evidence:me(t.evidence),failureCount:Number(t.failure_count),recoveryCount:Number(t.recovery_count),occurrenceCount:Number(t.occurrence_count),ownerActorId:Kt(t.owner_actor_id),acknowledgedByActorId:Kt(t.acknowledged_by_actor_id),acknowledgedAt:Kt(t.acknowledged_at),firstSeenAt:String(t.first_seen_at),lastSeenAt:String(t.last_seen_at),firingAt:Kt(t.firing_at),resolvedAt:Kt(t.resolved_at),silencedUntil:Kt(t.silenced_until),updatedAt:String(t.updated_at)}}function ZO(t){return{id:String(t.id),organizationId:String(t.organization_id),name:String(t.name),kind:String(t.kind),config:me(t.config),credentialFingerprint:Kt(t.credential_fingerprint),hasCredential:!!t.credential_ciphertext,status:String(t.status),version:Number(t.version),lastTestedAt:Kt(t.last_tested_at),lastError:Kt(t.last_error),createdAt:String(t.created_at),updatedAt:String(t.updated_at)}}function kO(t){return{id:String(t.id),organizationId:String(t.organization_id),name:String(t.name),priority:Number(t.priority),matcher:me(t.matcher),channelIds:me(t.channel_ids),quietHours:t.quiet_hours?me(t.quiet_hours):void 0,groupWaitSeconds:Number(t.group_wait_seconds),reminderSeconds:t.reminder_seconds==null?void 0:Number(t.reminder_seconds),escalation:me(t.escalation),template:Kt(t.template),rateLimitPerMinute:Number(t.rate_limit_per_minute),enabled:wR(t.enabled),version:Number(t.version),createdAt:String(t.created_at),updatedAt:String(t.updated_at)}}function UR(t){return{id:String(t.id),alertId:Kt(t.alert_id),channelId:String(t.channel_id),routeId:Kt(t.route_id),eventType:String(t.event_type),idempotencyKey:String(t.idempotency_key),state:String(t.state),attempt:Number(t.attempt),maxAttempts:Number(t.max_attempts),nextAttemptAt:Kt(t.next_attempt_at),responseStatus:t.response_status==null?void 0:Number(t.response_status),error:Kt(t.error),payload:me(t.payload),createdAt:String(t.created_at),updatedAt:String(t.updated_at),deliveredAt:Kt(t.delivered_at)}}class gR{controlPlane;options;key;constructor(t,e){this.controlPlane=t;this.options=e;this.key=bO("sha256").update(e.encryptionKey).digest()}now(){return(this.options.now?.()??new Date).toISOString()}encrypt(t){let e=xg(12),r=kg("aes-256-gcm",this.key,e),d=Buffer.concat([r.update(t,"utf8"),r.final()]);return`v1.${e.toString("base64url")}.${r.getAuthTag().toString("base64url")}.${d.toString("base64url")}`}decrypt(t){let[,e,r,d]=t.split("."),E=bg("aes-256-gcm",this.key,Buffer.from(e,"base64url"));return E.setAuthTag(Buffer.from(r,"base64url")),Buffer.concat([E.update(Buffer.from(d,"base64url")),E.final()]).toString("utf8")}createHealthCheck(t){if(!t.name.trim())throw Error("Health checks require a name.");if(!["http","tcp","command"].includes(t.kind))throw Error("Unsupported health check kind.");if(t.kind==="http"&&!/^https?:\/\//.test(t.target)||t.kind==="tcp"&&!/^[a-zA-Z0-9.-]+$/.test(t.target)||t.kind==="command"&&!t.config.command?.length)throw Error("Health check target is invalid.");let e=crypto.randomUUID(),r=this.now();return this.controlPlane.database.run("INSERT INTO health_checks (id,project_id,environment_id,resource_id,name,kind,target,config,interval_seconds,timeout_seconds,failure_threshold,recovery_threshold,regions,enabled,version,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",[e,t.projectId,t.environmentId??null,t.resourceId??null,t.name.trim().slice(0,100),t.kind,t.target,JSON.stringify(t.config),Mr(t.intervalSeconds,60,10,86400),Mr(t.timeoutSeconds,10,1,300),Mr(t.failureThreshold,3,1,100),Mr(t.recoveryThreshold,2,1,100),JSON.stringify(t.regions.slice(0,20)),t.enabled?1:0,1,r,r]),this.getHealthCheck(e)}getHealthCheck(t){let e=this.controlPlane.database.query("SELECT * FROM health_checks WHERE id=?").get(t);return e?GO(e):void 0}listHealthChecks(t,e){return this.controlPlane.database.query(`SELECT * FROM health_checks WHERE project_id=?${e?" AND environment_id=?":""} ORDER BY updated_at DESC`).all(t,...e?[e]:[]).map(GO)}setHealthCheckEnabled(t,e){this.controlPlane.database.run("UPDATE health_checks SET enabled=?,version=version+1,updated_at=? WHERE id=?",[e?1:0,this.now(),t]);let r=this.getHealthCheck(t);if(!r)throw Error("Health check was not found.");return r}appendHealthResult(t){let e=crypto.randomUUID();return this.controlPlane.database.run("INSERT INTO health_results (id,check_id,status,agent,region,status_code,message,timings,checked_at) VALUES (?,?,?,?,?,?,?,?,?)",[e,t.checkId,t.status,t.agent.slice(0,100),t.region??null,t.statusCode??null,t.message?.slice(0,1000)??null,JSON.stringify(t.timings),t.checkedAt]),VO(this.controlPlane.database.query("SELECT * FROM health_results WHERE id=?").get(e))}listHealthResults(t,e=100){return this.controlPlane.database.query("SELECT * FROM health_results WHERE check_id=? ORDER BY checked_at DESC LIMIT ?").all(t,Math.min(1000,Math.max(1,e))).map(VO)}createRule(t){if(!t.name.trim())throw Error("Alert rules require a name.");if(t.operator!=="unhealthy"&&t.threshold==null)throw Error("Metric alert rules require a threshold.");let e=crypto.randomUUID(),r=this.now();return this.controlPlane.database.run("INSERT INTO alert_rules (id,project_id,environment_id,resource_id,health_check_id,name,signal,operator,threshold,recovery_threshold,window_ms,consecutive,recovery_consecutive,no_data_policy,severity,group_by,labels,enabled,version,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",[e,t.projectId,t.environmentId??null,t.resourceId??null,t.healthCheckId??null,t.name.trim().slice(0,120),t.signal,t.operator,t.threshold??null,t.recoveryThreshold??null,Mr(t.windowMs,300000,1e4,2678400000),Mr(t.consecutive,3,1,100),Mr(t.recoveryConsecutive,2,1,100),t.noDataPolicy,t.severity,JSON.stringify(t.groupBy.slice(0,20)),JSON.stringify(t.labels),t.enabled?1:0,1,r,r]),this.getRule(e)}getRule(t){let e=this.controlPlane.database.query("SELECT * FROM alert_rules WHERE id=?").get(t);return e?KO(e):void 0}listRules(t,e){return this.controlPlane.database.query(`SELECT * FROM alert_rules WHERE project_id=?${e?" AND environment_id=?":""} ORDER BY updated_at DESC`).all(t,...e?[e]:[]).map(KO)}setRuleEnabled(t,e){this.controlPlane.database.run("UPDATE alert_rules SET enabled=?,version=version+1,updated_at=? WHERE id=?",[e?1:0,this.now(),t]);let r=this.getRule(t);if(!r)throw Error("Alert rule was not found.");return r}getAlertByDedup(t){let e=this.controlPlane.database.query("SELECT * FROM alerts WHERE dedup_key=?").get(t);return e?fR(e):void 0}getAlert(t){let e=this.controlPlane.database.query("SELECT * FROM alerts WHERE id=?").get(t);return e?fR(e):void 0}listAlerts(t,e={}){let r=["project_id=?"],d=[t];if(e.environmentId)r.push("environment_id=?"),d.push(e.environmentId);if(e.states?.length)r.push(`state IN (${e.states.map(()=>"?").join(",")})`),d.push(...e.states);return this.controlPlane.database.query(`SELECT * FROM alerts WHERE ${r.join(" AND ")} ORDER BY updated_at DESC LIMIT ?`).all(...d,Math.min(1000,e.limit??200)).map(fR)}saveAlert(t,e,r){return this.controlPlane.database.run("INSERT INTO alerts (id,rule_id,project_id,environment_id,resource_id,dedup_key,group_key,state,severity,title,evidence,failure_count,recovery_count,occurrence_count,owner_actor_id,acknowledged_by_actor_id,acknowledged_at,first_seen_at,last_seen_at,firing_at,resolved_at,silenced_until,updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) ON CONFLICT(id) DO UPDATE SET state=excluded.state,severity=excluded.severity,title=excluded.title,evidence=excluded.evidence,failure_count=excluded.failure_count,recovery_count=excluded.recovery_count,occurrence_count=excluded.occurrence_count,owner_actor_id=excluded.owner_actor_id,acknowledged_by_actor_id=excluded.acknowledged_by_actor_id,acknowledged_at=excluded.acknowledged_at,last_seen_at=excluded.last_seen_at,firing_at=excluded.firing_at,resolved_at=excluded.resolved_at,silenced_until=excluded.silenced_until,updated_at=excluded.updated_at",[t.id,t.ruleId,t.projectId,t.environmentId??null,t.resourceId??null,t.dedupKey,t.groupKey,t.state,t.severity,t.title,JSON.stringify(t.evidence),t.failureCount,t.recoveryCount,t.occurrenceCount,t.ownerActorId??null,t.acknowledgedByActorId??null,t.acknowledgedAt??null,t.firstSeenAt,t.lastSeenAt,t.firingAt??null,t.resolvedAt??null,t.silencedUntil??null,t.updatedAt]),this.controlPlane.database.run("INSERT INTO alert_events (id,alert_id,type,actor_id,payload,created_at) VALUES (?,?,?,?,?,?)",[crypto.randomUUID(),t.id,e,r??null,JSON.stringify({state:t.state,severity:t.severity,evidence:t.evidence}),t.updatedAt]),this.getAlert(t.id)}acknowledge(t,e){let r=this.getAlert(t);if(!r)throw Error("Alert was not found.");let d=this.now();return this.saveAlert({...r,acknowledgedByActorId:e,acknowledgedAt:d,updatedAt:d},"acknowledged",e)}assign(t,e,r){let d=this.getAlert(t);if(!d)throw Error("Alert was not found.");let E=this.now();return this.saveAlert({...d,ownerActorId:e,updatedAt:E},"assigned",r)}silenceAlert(t,e,r){let d=this.getAlert(t);if(!d)throw Error("Alert was not found.");let E=new Date(e);if(!Number.isFinite(E.getTime())||E<=new Date)throw Error("Silence end must be in the future.");let n=this.now();return this.saveAlert({...d,state:"silenced",silencedUntil:E.toISOString(),updatedAt:n},"silenced",r)}createSilence(t){let e=new Date(t.startsAt),r=new Date(t.endsAt);if(!Number.isFinite(e.getTime())||!Number.isFinite(r.getTime())||e>=r)throw Error("Silence window is invalid.");try{new Intl.DateTimeFormat("en",{timeZone:t.timezone}).format(e)}catch{throw Error("Silence timezone is invalid.")}let d=crypto.randomUUID();return this.controlPlane.database.run("INSERT INTO alert_silences (id,project_id,environment_id,resource_id,matcher,reason,starts_at,ends_at,timezone,created_by_actor_id,created_at) VALUES (?,?,?,?,?,?,?,?,?,?,?)",[d,t.projectId,t.environmentId??null,t.resourceId??null,JSON.stringify(t.matcher??{}),t.reason.slice(0,500),e.toISOString(),r.toISOString(),t.timezone,t.actorId??null,this.now()]),d}isSilenced(t,e,r){return this.controlPlane.database.query("SELECT * FROM alert_silences WHERE project_id=? AND starts_at<=? AND ends_at>?").all(t.projectId,r,r).some((E)=>{if(E.environment_id&&E.environment_id!==t.environmentId)return!1;if(E.resource_id&&E.resource_id!==t.resourceId)return!1;let n=me(E.matcher);return Object.entries(n).every(([c,_])=>e[c]===_)})}createChannel(t){if(!t.name.trim())throw Error("Notification channels require a name.");let e=crypto.randomUUID(),r=this.now(),d=t.credential?.trim();return this.controlPlane.database.run("INSERT INTO notification_channels (id,organization_id,name,kind,config,credential_ciphertext,credential_fingerprint,status,version,created_by_actor_id,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?)",[e,t.organizationId,t.name.trim().slice(0,100),t.kind,JSON.stringify(t.config??{}),d?this.encrypt(d):null,d?MO(d):null,"active",1,t.actorId??null,r,r]),this.getChannel(e)}getChannel(t){let e=this.controlPlane.database.query("SELECT * FROM notification_channels WHERE id=?").get(t);return e?ZO(e):void 0}channelCredential(t){let e=this.controlPlane.database.query("SELECT credential_ciphertext FROM notification_channels WHERE id=?").get(t);return e?.credential_ciphertext?this.decrypt(String(e.credential_ciphertext)):void 0}listChannels(t){return this.controlPlane.database.query("SELECT * FROM notification_channels WHERE organization_id=? ORDER BY updated_at DESC").all(t).map(ZO)}rotateChannel(t,e){let r=this.now();this.controlPlane.database.run("UPDATE notification_channels SET credential_ciphertext=?,credential_fingerprint=?,status='active',last_error=NULL,version=version+1,updated_at=? WHERE id=?",[this.encrypt(e),MO(e),r,t]);let d=this.getChannel(t);if(!d)throw Error("Notification channel was not found.");return d}setChannelStatus(t,e,r){this.controlPlane.database.run("UPDATE notification_channels SET status=?,last_error=?,updated_at=? WHERE id=?",[e,r?.slice(0,1000)??null,this.now(),t]);let d=this.getChannel(t);if(!d)throw Error("Notification channel was not found.");return d}markChannelTest(t,e,r){let d=this.now();return this.controlPlane.database.run("UPDATE notification_channels SET status=?,last_tested_at=?,last_error=?,updated_at=? WHERE id=?",[e?"active":"failing",d,r?.slice(0,1000)??null,d,t]),this.getChannel(t)}createRoute(t){let e=crypto.randomUUID(),r=this.now();return this.controlPlane.database.run("INSERT INTO notification_routes (id,organization_id,name,priority,matcher,channel_ids,quiet_hours,group_wait_seconds,reminder_seconds,escalation,template,rate_limit_per_minute,enabled,version,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",[e,t.organizationId,t.name.trim().slice(0,100),t.priority,JSON.stringify(t.matcher),JSON.stringify(t.channelIds),t.quietHours?JSON.stringify(t.quietHours):null,Mr(t.groupWaitSeconds,30,0,86400),t.reminderSeconds??null,JSON.stringify(t.escalation),t.template?.trim().slice(0,2000)??null,Mr(t.rateLimitPerMinute,60,1,1e4),t.enabled?1:0,1,r,r]),this.getRoute(e)}getRoute(t){let e=this.controlPlane.database.query("SELECT * FROM notification_routes WHERE id=?").get(t);return e?kO(e):void 0}listRoutes(t){return this.controlPlane.database.query("SELECT * FROM notification_routes WHERE organization_id=? ORDER BY priority DESC,created_at ASC").all(t).map(kO)}countRouteDeliveries(t,e){return Number(this.controlPlane.database.query("SELECT COUNT(*) count FROM notification_deliveries WHERE route_id=? AND created_at>=?").get(t,e)?.count??0)}setRouteEnabled(t,e){this.controlPlane.database.run("UPDATE notification_routes SET enabled=?,version=version+1,updated_at=? WHERE id=?",[e?1:0,this.now(),t]);let r=this.getRoute(t);if(!r)throw Error("Notification route was not found.");return r}createDelivery(t){let e=this.controlPlane.database.query("SELECT * FROM notification_deliveries WHERE idempotency_key=?").get(t.idempotencyKey);if(e)return UR(e);let r=crypto.randomUUID(),d=this.now();return this.controlPlane.database.run("INSERT INTO notification_deliveries (id,alert_id,channel_id,route_id,event_type,idempotency_key,state,attempt,max_attempts,next_attempt_at,payload,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)",[r,t.alertId??null,t.channelId,t.routeId??null,t.eventType,t.idempotencyKey,"pending",0,Mr(t.maxAttempts,3,1,10),t.nextAttemptAt??null,JSON.stringify(t.payload),d,d]),this.getDelivery(r)}getDelivery(t){let e=this.controlPlane.database.query("SELECT * FROM notification_deliveries WHERE id=?").get(t);return e?UR(e):void 0}listDeliveries(t={}){let e=[],r=[];if(t.alertId)e.push("alert_id=?"),r.push(t.alertId);if(t.states?.length)e.push(`state IN (${t.states.map(()=>"?").join(",")})`),r.push(...t.states);return this.controlPlane.database.query(`SELECT * FROM notification_deliveries${e.length?" WHERE "+e.join(" AND "):""} ORDER BY updated_at DESC LIMIT ?`).all(...r,Math.min(1000,t.limit??200)).map(UR)}updateDelivery(t,e){return this.controlPlane.database.run("UPDATE notification_deliveries SET state=?,attempt=?,next_attempt_at=?,response_status=?,error=?,delivered_at=?,updated_at=? WHERE id=?",[e.state,e.attempt,e.nextAttemptAt??null,e.responseStatus??null,e.error?.slice(0,1000)??null,e.deliveredAt??null,this.now(),t]),this.getDelivery(t)}}import{createHash as _1}from"node:crypto";var rd=36,$R=[{version:1,name:"core_control_plane",sql:`
|
|
4118
4118
|
CREATE TABLE projects (
|
|
4119
4119
|
id TEXT PRIMARY KEY,
|
|
4120
4120
|
slug TEXT NOT NULL UNIQUE,
|
|
@@ -5487,12 +5487,12 @@ volumes:
|
|
|
5487
5487
|
volumes:
|
|
5488
5488
|
wordpress-data: {}
|
|
5489
5489
|
database-data: {}
|
|
5490
|
-
`}];function XT(){return AC.map(({source:t,...e})=>({...e,source:`builtin:${e.id}`,lastVerifiedAt:K1,builtin:!0,checksum:V1("sha256").update(t).digest("hex"),exposedServices:[...e.exposedServices],inputs:e.inputs.map((r)=>({...r}))}))}function LC(t,e,r,d){let E=AC.find((c)=>c.id===t&&(!d||c.version===d));if(!E)throw Error(`Compose template ${t}${d?`@${d}`:""} was not found`);let n=E.source;for(let c of E.inputs){let _=e[c.name]??("default"in c?c.default:void 0);if(c.required&&!_)throw Error(`Template input ${c.name} is required`);if(_&&!/^[A-Za-z0-9._:/@+-]{1,255}$/.test(_))throw Error(`Template input ${c.name} contains unsupported characters`);n=n.replaceAll(`{{${c.name}}}`,_??"")}return Gc(n,r)}var uC=/^[a-z0-9][a-z0-9_.-]{0,62}$/;function lE(t){return`'${t.replaceAll("'","'\\''")}'`}function OC(t){return`${t.metadata.slug}-${t.metadata.environmentId.slice(0,8)}`.replace(/[^a-z0-9_-]/g,"-").slice(0,63)}function CC(t,e,r=200){if(!uC.test(e))throw Error("Unsafe Compose service name");let d=OC(t);return`docker compose --project-name ${lE(d)} --file ${lE(`/opt/ts-cloud/compose/${d}/compose.yaml`)} logs --no-color --timestamps --tail ${Math.max(1,Math.min(2000,Math.floor(r)))} ${lE(e)}`}function lC(t,e,r=["sh"]){if(!uC.test(e)||!r.length||r.some((E)=>E.includes("\x00")||E.length>1024))throw Error("Unsafe Compose shell request");let d=OC(t);return`docker compose --project-name ${lE(d)} --file ${lE(`/opt/ts-cloud/compose/${d}/compose.yaml`)} exec ${lE(e)} ${r.map(lE).join(" ")}`}import{mkdir as mR,readdir as h$,rm as R$,stat as S$}from"node:fs/promises";import{basename as N$,resolve as aC,sep as A$}from"node:path";class Vc extends Error{constructor(){super("Operation cancellation was requested")}}class aT extends Error{timeoutSeconds;constructor(t){super(`Operation exceeded its ${t}s timeout`);this.timeoutSeconds=t}}class
|
|
5490
|
+
`}];function XT(){return AC.map(({source:t,...e})=>({...e,source:`builtin:${e.id}`,lastVerifiedAt:K1,builtin:!0,checksum:V1("sha256").update(t).digest("hex"),exposedServices:[...e.exposedServices],inputs:e.inputs.map((r)=>({...r}))}))}function LC(t,e,r,d){let E=AC.find((c)=>c.id===t&&(!d||c.version===d));if(!E)throw Error(`Compose template ${t}${d?`@${d}`:""} was not found`);let n=E.source;for(let c of E.inputs){let _=e[c.name]??("default"in c?c.default:void 0);if(c.required&&!_)throw Error(`Template input ${c.name} is required`);if(_&&!/^[A-Za-z0-9._:/@+-]{1,255}$/.test(_))throw Error(`Template input ${c.name} contains unsupported characters`);n=n.replaceAll(`{{${c.name}}}`,_??"")}return Gc(n,r)}var uC=/^[a-z0-9][a-z0-9_.-]{0,62}$/;function lE(t){return`'${t.replaceAll("'","'\\''")}'`}function OC(t){return`${t.metadata.slug}-${t.metadata.environmentId.slice(0,8)}`.replace(/[^a-z0-9_-]/g,"-").slice(0,63)}function CC(t,e,r=200){if(!uC.test(e))throw Error("Unsafe Compose service name");let d=OC(t);return`docker compose --project-name ${lE(d)} --file ${lE(`/opt/ts-cloud/compose/${d}/compose.yaml`)} logs --no-color --timestamps --tail ${Math.max(1,Math.min(2000,Math.floor(r)))} ${lE(e)}`}function lC(t,e,r=["sh"]){if(!uC.test(e)||!r.length||r.some((E)=>E.includes("\x00")||E.length>1024))throw Error("Unsafe Compose shell request");let d=OC(t);return`docker compose --project-name ${lE(d)} --file ${lE(`/opt/ts-cloud/compose/${d}/compose.yaml`)} exec ${lE(e)} ${r.map(lE).join(" ")}`}import{mkdir as mR,readdir as h$,rm as R$,stat as S$}from"node:fs/promises";import{basename as N$,resolve as aC,sep as A$}from"node:path";class Vc extends Error{constructor(){super("Operation cancellation was requested")}}class aT extends Error{timeoutSeconds;constructor(t){super(`Operation exceeded its ${t}s timeout`);this.timeoutSeconds=t}}class $r extends Error{errorClass;constructor(t,e){super(t);this.errorClass=e}}var PT={project:2,environment:1,provider:2,builds:1},Z1=30,IC=16384,k1=["succeeded","failed","cancelled","timed_out"],ZR=new Map,DC=new WeakMap;function fC(t){if(t.path===":memory:"){let d=DC.get(t);if(d)return d;let E=new Set;return DC.set(t,E),E}let e=ZR.get(t.path);if(e)return e;let r=new Set;return ZR.set(t.path,r),r}function IE(t){return typeof t==="string"&&t?t:void 0}function b1(t){try{let e=JSON.parse(String(t));return Array.isArray(e)?e.map(String):[]}catch{return[]}}function x1(t){return{operationId:String(t.operation_id),lockKey:IE(t.lock_key),providerKey:IE(t.provider_key),buildSlot:Number(t.build_slot)===1,maxAttempts:Number(t.max_attempts),availableAt:String(t.available_at),timeoutSeconds:Number(t.timeout_seconds),heartbeatAt:IE(t.heartbeat_at),currentStep:IE(t.current_step),blockedReason:IE(t.blocked_reason),retryClasses:b1(t.retry_classes),resumePolicy:String(t.resume_policy),cancellationMode:String(t.cancellation_mode),retentionUntil:String(t.retention_until),createdAt:String(t.created_at),updatedAt:String(t.updated_at)}}function UC(t){return{sequence:Number(t.sequence),id:String(t.id),operationId:String(t.operation_id),stream:String(t.stream),step:IE(t.step),message:String(t.message),redacted:Number(t.redacted)===1,truncated:Number(t.truncated)===1,createdAt:String(t.created_at)}}function Sr(t,e,r){return Number.isFinite(t)?Math.min(r,Math.max(1,Math.floor(t))):e}class gt{controlPlane;nowFn;idFn;workerId;leaseMs;limits;constructor(t,e={}){this.controlPlane=t;this.workerId=e.workerId??`worker:${process.pid}:${crypto.randomUUID()}`,this.leaseMs=Sr(e.leaseMs,60000,3600000),this.nowFn=e.now??(()=>new Date),this.idFn=e.id??(()=>crypto.randomUUID());let r=t.getSetting("queue.concurrency");this.limits={project:Sr(e.limits?.project??r?.project,PT.project,100),environment:Sr(e.limits?.environment??r?.environment,PT.environment,100),provider:Sr(e.limits?.provider??r?.provider,PT.provider,100),builds:Sr(e.limits?.builds??r?.builds,PT.builds,100)}}now(){return this.nowFn().toISOString()}leaseExpiry(){return new Date(this.nowFn().getTime()+this.leaseMs).toISOString()}enqueue(t){let e=this.controlPlane.createOperation(t);if(this.getJob(e.id))return this.view(e.id);let d=this.now(),E=Sr(t.maxAttempts,1,20),n=Sr(t.timeoutSeconds,1800,86400),c=Sr(t.retentionDays,Z1,3650),_=t.availableAt?new Date(t.availableAt).toISOString():d,T=new Date(this.nowFn().getTime()+c*24*60*60*1000).toISOString();this.controlPlane.database.run(`INSERT OR IGNORE INTO operation_jobs (operation_id, lock_key, provider_key, build_slot, max_attempts, available_at, timeout_seconds, retry_classes, resume_policy, cancellation_mode, retention_until, created_at, updated_at)
|
|
5491
5491
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,[e.id,t.lockKey??t.resourceId??null,t.providerKey??null,t.buildSlot?1:0,E,_,n,JSON.stringify([...new Set(t.retryClasses??[])]),t.resumePolicy??"fail",t.cancellationMode??"cooperative",T,d,d]),this.appendLog(e.id,"Queued for durable execution.",{stream:"system"});let i=this.view(e.id);return this.notifyAvailable(),i}onAvailable(t){let e=fC(this.controlPlane);return e.add(t),()=>{if(e.delete(t),e.size===0&&this.controlPlane.path!==":memory:")ZR.delete(this.controlPlane.path)}}notifyAvailable(){for(let t of fC(this.controlPlane))t()}getJob(t){let e=this.controlPlane.database.query("SELECT * FROM operation_jobs WHERE operation_id=?").get(t);return e?x1(e):void 0}view(t){let e=this.controlPlane.getOperation(t),r=this.getJob(t);if(!e||!r)return;let d;if(e.state==="queued")d={ahead:Number(this.controlPlane.database.query("SELECT COUNT(*) AS count FROM operations o JOIN operation_jobs j ON j.operation_id=o.id WHERE o.state='queued' AND j.available_at<=? AND (o.priority>? OR (o.priority=? AND o.created_at<?))").get(this.now(),e.priority,e.priority,e.createdAt)?.count??0),precision:"bounded"};return{operation:e,job:r,approximatePosition:d}}list(t={}){return this.controlPlane.listOperations({projectId:t.projectId,state:t.state,limit:t.limit??200}).map((e)=>this.view(e.id)).filter((e)=>!!e)}configureConcurrency(t,e={}){let r={project:Sr(t.project,this.limits.project,100),environment:Sr(t.environment,this.limits.environment,100),provider:Sr(t.provider,this.limits.provider,100),builds:Sr(t.builds,this.limits.builds,100)};return Object.assign(this.limits,r),this.controlPlane.setSetting("queue.concurrency",r),this.controlPlane.appendEvent({organizationId:e.organizationId,actorId:e.actorId,type:"queue.concurrency.updated",level:"warning",payload:r}),r}runningCount(t,e){return Number(this.controlPlane.database.query(t).get(...e)?.count??0)}blockReason(t,e){if(e.lockKey){if(this.controlPlane.database.query("SELECT * FROM operation_locks WHERE lock_key=? AND operation_id!=? AND lease_expires_at>?").get(e.lockKey,t.id,this.now()))return`resource_lock:${e.lockKey}`}if(t.projectId&&this.runningCount("SELECT COUNT(*) AS count FROM operations WHERE state='running' AND project_id=?",[t.projectId])>=this.limits.project)return"project_concurrency";if(t.environmentId&&this.runningCount("SELECT COUNT(*) AS count FROM operations WHERE state='running' AND environment_id=?",[t.environmentId])>=this.limits.environment)return"environment_concurrency";if(e.providerKey&&this.runningCount("SELECT COUNT(*) AS count FROM operations o JOIN operation_jobs j ON j.operation_id=o.id WHERE o.state='running' AND j.provider_key=?",[e.providerKey])>=this.limits.provider)return"provider_concurrency";if(e.buildSlot&&this.runningCount("SELECT COUNT(*) AS count FROM operations o JOIN operation_jobs j ON j.operation_id=o.id WHERE o.state='running' AND j.build_slot=1",[])>=this.limits.builds)return"build_concurrency";return}claim(t){return this.controlPlane.transaction(()=>{let e=this.now();this.controlPlane.database.run("DELETE FROM operation_locks WHERE lease_expires_at<=?",[e]);let r=this.controlPlane.getOperation(t),d=r?this.getJob(r.id):void 0;if(!r||!d||r.state!=="queued"||d.availableAt>e)return;if(r.cancelRequestedAt){this.controlPlane.transitionOperation(r.id,{to:"cancelled",expectedVersion:r.version,output:{cancelledBeforeStart:!0}}),this.appendLog(r.id,"Cancelled before execution began.",{stream:"system"});return}let E=this.blockReason(r,d);if(E){this.controlPlane.database.run("UPDATE operation_jobs SET blocked_reason=?, updated_at=? WHERE operation_id=?",[E,e,r.id]);return}let n=this.controlPlane.claimOperation(r.id,this.workerId,this.leaseMs);if(!n)return;let c=n.leaseExpiresAt??this.leaseExpiry();if(d.lockKey)this.controlPlane.database.run("INSERT INTO operation_locks (lock_key, operation_id, lease_owner, lease_expires_at, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?)",[d.lockKey,r.id,this.workerId,c,e,e]);return this.controlPlane.database.run("UPDATE operation_jobs SET heartbeat_at=?, blocked_reason=NULL, updated_at=? WHERE operation_id=?",[e,e,r.id]),this.appendLog(r.id,`Claimed by ${this.workerId}; attempt ${n.attempt}.`,{stream:"system"}),this.view(r.id)})}claimNext(t){let e=this.now(),r=t?.length?`AND o.kind IN (${t.map(()=>"?").join(",")})`:"",d=this.controlPlane.database.query(`SELECT o.id FROM operations o JOIN operation_jobs j ON j.operation_id=o.id WHERE o.state='queued' AND j.available_at<=? ${r} ORDER BY o.priority DESC, o.created_at ASC, o.rowid ASC LIMIT 100`).all(e,...t??[]);for(let E of d){let n=this.claim(String(E.id));if(n)return n}return}heartbeat(t,e){let r=this.controlPlane.getOperation(t);if(!r||r.state!=="running"||r.leaseOwner!==this.workerId)throw Error("Operation lease is not owned by this worker");let d=this.now(),E=this.leaseExpiry(),n=this.getJob(t);if(this.controlPlane.database.run("UPDATE operations SET lease_expires_at=?, updated_at=?, version=version+1 WHERE id=? AND state='running' AND lease_owner=? AND version=?",[E,d,t,this.workerId,r.version]).changes!==1)throw Error("Operation lease changed before heartbeat");if(this.controlPlane.database.run("UPDATE operation_jobs SET heartbeat_at=?, current_step=COALESCE(?, current_step), updated_at=? WHERE operation_id=?",[d,e??null,d,t]),n?.lockKey)this.controlPlane.database.run("UPDATE operation_locks SET lease_expires_at=?, updated_at=? WHERE lock_key=? AND operation_id=? AND lease_owner=?",[E,d,n.lockKey,t,this.workerId]);if(e&&e!==n?.currentStep)this.controlPlane.appendEvent({projectId:r.projectId,operationId:t,resourceId:r.resourceId,actorId:r.actorId,correlationId:r.correlationId,type:"operation.step",payload:{step:e}})}appendLog(t,e,r={}){if(!this.getJob(t))throw Error(`Queue job ${t} was not found`);let d=e,E=!1;for(let h of r.secrets??[])if(h&&d.includes(h))d=d.split(h).join("[REDACTED]"),E=!0;let n=ut({message:d});if(n.message!==d)E=!0;d=n.message??"[output unavailable]";let c=Buffer.from(d),_=c.byteLength>IC;if(_)d=`${c.subarray(0,IC-32).toString("utf8")}
|
|
5492
|
-
[output truncated]`;let T=this.idFn(),i=this.now();return this.controlPlane.database.run("INSERT INTO operation_logs (id, operation_id, stream, step, message, redacted, truncated, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?)",[T,t,r.stream??"stdout",r.step??null,d,E?1:0,_?1:0,i]),UC(this.controlPlane.database.query("SELECT * FROM operation_logs WHERE id=?").get(T))}logs(t,e={}){let r=Math.min(1000,Math.max(1,e.limit??200));return this.controlPlane.database.query("SELECT * FROM operation_logs WHERE operation_id=? AND sequence>? ORDER BY sequence ASC LIMIT ?").all(t,e.after??0,r).map(UC)}requestCancellation(t,e){let r=this.controlPlane.getOperation(t);if(!r||k1.includes(r.state))throw Error("Only queued or running operations can be cancelled");let d=this.controlPlane.requestCancellation(t);if(this.controlPlane.appendEvent({projectId:r.projectId,operationId:t,resourceId:r.resourceId,actorId:e,correlationId:r.correlationId,type:"operation.cancellation_requested",level:"warning",payload:{state:r.state}}),this.appendLog(t,r.state==="queued"?"Cancellation accepted before execution.":"Cancellation requested; waiting for the current provider step.",{stream:"system"}),d.state==="queued")return this.finish(t,"cancelled",{cancelledBeforeStart:!0});return d}retry(t,e,r={}){let d=this.controlPlane.getOperation(t),E=this.getJob(t);if(!d||!E||!["failed","cancelled","timed_out"].includes(d.state))throw Error("Only failed, cancelled, or timed-out queue jobs can be retried");if(d.attempt>=E.maxAttempts)throw Error(`Operation reached its ${E.maxAttempts}-attempt limit`);if(!E.retryClasses.includes(e))throw Error(`Retry class ${e} is not allowed for this operation`);let n=this.controlPlane.transitionOperation(t,{to:"queued",expectedVersion:d.version,error:`Retry requested after ${e}`}),c=new Date(this.nowFn().getTime()+Math.max(0,r.delayMs??0)).toISOString();this.controlPlane.database.run("UPDATE operations SET cancel_requested_at=NULL, finished_at=NULL WHERE id=?",[t]),this.controlPlane.database.run("UPDATE operation_jobs SET available_at=?, blocked_reason=NULL, updated_at=? WHERE operation_id=?",[c,this.now(),t]),this.controlPlane.appendEvent({projectId:d.projectId,operationId:t,resourceId:d.resourceId,actorId:r.actorId,correlationId:d.correlationId,type:"operation.retry_requested",payload:{errorClass:e,availableAt:c,nextAttempt:d.attempt+1}}),this.appendLog(t,`Retry queued for error class ${e}.`,{stream:"system"});let _=this.controlPlane.getOperation(n.id);return this.notifyAvailable(),_}release(t){this.controlPlane.database.run("DELETE FROM operation_locks WHERE operation_id=?",[t])}finish(t,e,r={},d){let E=this.controlPlane.getOperation(t);if(!E)throw Error(`Operation ${t} was not found`);let n=this.controlPlane.transitionOperation(t,{to:e,expectedVersion:E.version,output:r,error:d});return this.release(t),n}complete(t,e={}){let r=this.controlPlane.getOperation(t);if(!r||r.state!=="running"||r.leaseOwner!==this.workerId)throw Error("Only the lease owner can complete a running operation");return this.appendLog(t,"Operation completed successfully.",{stream:"system"}),this.finish(t,"succeeded",e)}fail(t,e,r={}){let d=this.controlPlane.getOperation(t);if(!d||d.state!=="running"||d.leaseOwner!==this.workerId)throw Error("Only the lease owner can fail a running operation");return this.appendLog(t,e,{stream:"stderr"}),this.finish(t,"failed",r,e)}async runOne(t){let e=this.claimNext(Object.keys(t));if(!e)return{handled:!1};let{operation:r,job:d}=e,E=t[r.kind];if(!E)return{handled:!1};let n=new AbortController,c=!1,_=setTimeout(()=>{c=!0,n.abort(new aT(d.timeoutSeconds))},d.timeoutSeconds*1000),T=setInterval(()=>{try{this.heartbeat(r.id)}catch{}},Math.max(250,Math.floor(this.leaseMs/3))),i=setInterval(()=>{if(this.controlPlane.getOperation(r.id)?.cancelRequestedAt)n.abort(new Vc)},100),h={operation:r,signal:n.signal,log:(R,N)=>this.appendLog(r.id,R,N),checkpoint:(R,N)=>{this.heartbeat(r.id,R),this.appendLog(r.id,N??R,{stream:"step",step:R})},heartbeat:()=>this.heartbeat(r.id),cancellationRequested:()=>!!this.controlPlane.getOperation(r.id)?.cancelRequestedAt,throwIfCancellationRequested:()=>{if(this.controlPlane.getOperation(r.id)?.cancelRequestedAt)throw new Vc}};try{let R=await Promise.race([E(h),new Promise((u,f)=>n.signal.addEventListener("abort",()=>f(n.signal.reason),{once:!0}))]);if(this.controlPlane.getOperation(r.id).cancelRequestedAt){let u=d.cancellationMode==="provider_non_cancellable";return this.appendLog(r.id,u?"Provider step completed after cancellation was requested; reconciliation is required.":"Operation cancelled cooperatively.",{stream:"system"}),{handled:!0,operation:this.finish(r.id,"cancelled",{providerCompleted:u,reconciliationRequired:u}),terminalState:"cancelled"}}return{handled:!0,operation:this.complete(r.id,R??{}),terminalState:"succeeded"}}catch(R){if(c||R instanceof aT)return this.appendLog(r.id,`Timed out after ${d.timeoutSeconds}s.`,{stream:"system"}),{handled:!0,operation:this.finish(r.id,"timed_out",{reconciliationRequired:d.cancellationMode==="provider_non_cancellable"},R instanceof Error?R.message:String(R)),terminalState:"timed_out"};if(R instanceof Vc||this.controlPlane.getOperation(r.id)?.cancelRequestedAt)return{handled:!0,operation:this.finish(r.id,"cancelled",{cooperativelyCancelled:!0}),terminalState:"cancelled"};if(R instanceof gr&&d.retryClasses.includes(R.errorClass)&&r.attempt<d.maxAttempts){let u=this.controlPlane.getOperation(r.id);this.controlPlane.transitionOperation(r.id,{to:"queued",expectedVersion:u.version,error:R.message});let f=Math.min(60000,1000*2**Math.max(0,r.attempt-1)),w=new Date(this.nowFn().getTime()+f).toISOString();return this.controlPlane.database.run("UPDATE operation_jobs SET available_at=?, blocked_reason=?, updated_at=? WHERE operation_id=?",[w,`retry_backoff:${R.errorClass}`,this.now(),r.id]),this.release(r.id),this.appendLog(r.id,`Retryable ${R.errorClass} failure; next attempt is delayed.`,{stream:"system"}),{handled:!0,operation:this.controlPlane.getOperation(r.id),requeued:!0}}let N=R instanceof Error?R.message:String(R);return this.appendLog(r.id,N,{stream:"stderr"}),{handled:!0,operation:this.finish(r.id,"failed",{},N),terminalState:"failed"}}finally{clearTimeout(_),clearInterval(T),clearInterval(i)}}recoverExpired(){let t=this.controlPlane.database.query("SELECT o.id FROM operations o JOIN operation_jobs j ON j.operation_id=o.id WHERE o.state='running' AND (o.lease_expires_at IS NULL OR o.lease_expires_at<=?)").all(this.now()),e={requeued:0,failed:0,cancelled:0};for(let r of t){let d=this.controlPlane.getOperation(String(r.id)),E=this.getJob(d.id);if(this.release(d.id),d.cancelRequestedAt){this.finish(d.id,"cancelled",{recoveredAfterWorkerLoss:!0}),e.cancelled++;continue}if(E.resumePolicy==="requeue"&&d.attempt<E.maxAttempts)this.controlPlane.transitionOperation(d.id,{to:"queued",expectedVersion:d.version,error:"Worker lease expired; safely requeued from the last checkpoint."}),this.controlPlane.database.run("UPDATE operation_jobs SET available_at=?, blocked_reason='worker_restart', updated_at=? WHERE operation_id=?",[this.now(),this.now(),d.id]),this.appendLog(d.id,"Worker lease expired; operation requeued from its persisted checkpoint.",{stream:"system"}),e.requeued++;else this.finish(d.id,"failed",{recoverable:!0,lastCheckpoint:E.currentStep??null},"Worker lease expired; retry explicitly after reconciling provider state."),e.failed++}return e}clearCompleted(t={}){let e=this.now(),r=[e],d=t.projectId?"AND o.project_id=?":"";if(t.projectId)r.push(t.projectId);let E=t.before?"AND o.finished_at<=?":"";if(t.before)r.push(new Date(t.before).toISOString());let n=this.controlPlane.database.query(`SELECT o.id, o.project_id, o.correlation_id FROM operations o JOIN operation_jobs j ON j.operation_id=o.id WHERE o.state IN ('succeeded','failed','cancelled','timed_out') AND j.retention_until<=? ${d} ${E}`).all(...r);for(let c of n)this.controlPlane.appendEvent({projectId:IE(c.project_id),actorId:t.actorId,correlationId:String(c.correlation_id),type:"queue.history.cleared",level:"warning",payload:{operationId:String(c.id),retentionCutoff:e}}),this.controlPlane.database.run("DELETE FROM operations WHERE id=?",[String(c.id)]);return n.length}}function wC(t,e,r){if(!Number.isFinite(t))return e;return Math.min(r,Math.max(1,Math.floor(t)))}class kR{queue;handlers;parallelism;pollIntervalMs;onResult;onError;waits=new Map;nextWaitId=0;lanes=[];running=!1;unsubscribeAvailability;constructor(t,e,r={}){this.queue=t;this.handlers=e;this.parallelism=wC(r.parallelism,4,100),this.pollIntervalMs=wC(r.pollIntervalMs,5000,60000),this.onResult=r.onResult,this.onError=r.onError}get active(){return this.running}start(){if(this.running)return this;return this.running=!0,this.unsubscribeAvailability=this.queue.onAvailable(()=>this.wake()),this.lanes=Array.from({length:this.parallelism},(t,e)=>this.runLane(e)),this}stop(){this.running=!1,this.unsubscribeAvailability?.(),this.unsubscribeAvailability=void 0,this.wake()}wake(){for(let{resolve:t,timer:e}of this.waits.values()){if(e)clearTimeout(e);t()}this.waits.clear()}async settled(){await Promise.allSettled(this.lanes)}async drain(){let t=[];while(!0){let e=await Promise.all(Array.from({length:this.parallelism},()=>this.queue.runOne(this.handlers)));if(t.push(...e.filter((r)=>r.handled)),!e.some((r)=>r.handled))return t}}wait(t){return new Promise((e)=>{let r=++this.nextWaitId,d=t?setTimeout(()=>{this.waits.delete(r),e()},this.pollIntervalMs):void 0;d?.unref?.(),this.waits.set(r,{resolve:e,timer:d})})}async runLane(t){while(this.running){try{let e=await this.queue.runOne(this.handlers);if(!this.running)break;if(e.handled){this.onResult?.(e),this.wake();continue}}catch(e){this.onError?.(e)}await this.wait(t===0)}}}import{createHash as q1}from"node:crypto";var s1=/^[a-f0-9]{40,64}$/i,o1=/^[A-Z][A-Z0-9_]{1,127}$/;function Vr(t){return typeof t==="string"&&t?t:void 0}function ln(t){try{return JSON.parse(String(t))}catch{return{}}}function m1(t){let e=ln(t);return Array.isArray(e)?e.map(String):[]}function bR(t){return{id:String(t.id),projectId:String(t.project_id),resourceId:String(t.resource_id),baseEnvironmentId:String(t.base_environment_id),enabled:Number(t.enabled)===1,branchRule:Vr(t.branch_rule),domainPattern:String(t.domain_pattern),ttlHours:Number(t.ttl_hours),keepCount:Number(t.keep_count),publicAccess:Number(t.public_access)===1,authenticationRequired:Number(t.authentication_required)===1,allowForks:Number(t.allow_forks)===1,inheritedSecrets:m1(t.inherited_secrets),resourceOverrides:ln(t.resource_overrides),databaseStrategy:String(t.database_strategy),maxMonthlyCost:Number(t.max_monthly_cost),maxCpu:Number(t.max_cpu),maxMemoryMb:Number(t.max_memory_mb),cleanupOnClose:Number(t.cleanup_on_close)===1,version:Number(t.version),createdByActorId:Vr(t.created_by_actor_id),createdAt:String(t.created_at),updatedAt:String(t.updated_at)}}function Kc(t){return{id:String(t.id),definitionId:String(t.definition_id),projectId:String(t.project_id),resourceId:String(t.resource_id),baseEnvironmentId:String(t.base_environment_id),identityKey:String(t.identity_key),sourceProvider:Vr(t.source_provider),repository:Vr(t.repository),branch:String(t.branch),pullRequestNumber:t.pull_request_number==null?void 0:Number(t.pull_request_number),fork:Number(t.fork)===1,commitSha:String(t.commit_sha),name:String(t.name),stackName:String(t.stack_name),url:Vr(t.url),status:String(t.status),expiresAt:String(t.expires_at),latestOperationId:Vr(t.latest_operation_id),createdByActorId:Vr(t.created_by_actor_id),costEstimate:t.cost_estimate==null?void 0:Number(t.cost_estimate),desiredState:ln(t.desired_state),observedState:ln(t.observed_state),teardownError:Vr(t.teardown_error),version:Number(t.version),createdAt:String(t.created_at),updatedAt:String(t.updated_at),destroyedAt:Vr(t.destroyed_at)}}function gC(t){return{id:String(t.id),previewId:String(t.preview_id),provider:String(t.provider),providerResourceId:String(t.provider_resource_id),kind:String(t.kind),tags:ln(t.tags),observedState:ln(t.observed_state),discoveredAt:String(t.discovered_at),deletedAt:Vr(t.deleted_at)}}function Fd(t,e,r,d){return Number.isFinite(t)?Math.min(d,Math.max(r,Math.floor(t))):e}function jT(t,e,r,d){return Number.isFinite(t)?Math.min(d,Math.max(r,t)):e}function xR(t){return t.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"").slice(0,28)||"preview"}class Bd{controlPlane;now;id;constructor(t,e={}){this.controlPlane=t;this.now=e.now??(()=>new Date),this.id=e.id??(()=>crypto.randomUUID())}createDefinition(t){let e=this.controlPlane.getResource(t.resourceId),r=this.controlPlane.listEnvironments(t.projectId).find((i)=>i.id===t.baseEnvironmentId);if(!e||e.projectId!==t.projectId||e.environmentId!==r?.id)throw Error("Preview resource and base environment must belong to the same project scope");if(e.kind!=="application")throw Error("Preview environments currently support application resources only");if(!/^https:\/\//.test(t.domainPattern)||!t.domainPattern.includes("{name}"))throw Error("Preview domainPattern must be HTTPS and include {name}");let d=this.getDefinitionForResource(t.resourceId),E=t.publicAccess??d?.publicAccess??!1,n=t.authenticationRequired??d?.authenticationRequired??!0;if(E&&!n)throw Error("Public preview environments require an authentication policy");let c=[...new Set(t.inheritedSecrets??[])];if(c.some((i)=>!o1.test(i)))throw Error("Inherited preview secret names must use uppercase environment-variable identifiers");let _=this.now().toISOString();if(d)return this.controlPlane.database.run("UPDATE preview_definitions SET base_environment_id=?, enabled=1, branch_rule=?, domain_pattern=?, ttl_hours=?, keep_count=?, public_access=?, authentication_required=?, allow_forks=?, inherited_secrets=?, resource_overrides=?, database_strategy=?, max_monthly_cost=?, max_cpu=?, max_memory_mb=?, cleanup_on_close=?, version=version+1, updated_at=? WHERE id=?",[t.baseEnvironmentId,t.branchRule??null,t.domainPattern,Fd(t.ttlHours,d.ttlHours,1,720),Fd(t.keepCount,d.keepCount,1,100),E?1:0,n?1:0,t.allowForks??d.allowForks?1:0,JSON.stringify(t.inheritedSecrets===void 0?d.inheritedSecrets:c),JSON.stringify(ut(t.resourceOverrides??d.resourceOverrides)),t.databaseStrategy??d.databaseStrategy,jT(t.maxMonthlyCost,d.maxMonthlyCost,0,1e4),jT(t.maxCpu,d.maxCpu,0.1,64),Fd(t.maxMemoryMb,d.maxMemoryMb,128,131072),t.cleanupOnClose??d.cleanupOnClose?1:0,_,d.id]),this.controlPlane.appendEvent({projectId:t.projectId,resourceId:t.resourceId,actorId:t.createdByActorId,type:"preview.definition.updated",payload:{definitionId:d.id,baseEnvironmentId:t.baseEnvironmentId,version:d.version+1}}),this.getDefinition(d.id);let T=this.id();return this.controlPlane.database.run("INSERT INTO preview_definitions (id, project_id, resource_id, base_environment_id, enabled, branch_rule, domain_pattern, ttl_hours, keep_count, public_access, authentication_required, allow_forks, inherited_secrets, resource_overrides, database_strategy, max_monthly_cost, max_cpu, max_memory_mb, cleanup_on_close, created_by_actor_id, created_at, updated_at) VALUES (?, ?, ?, ?, 1, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",[T,t.projectId,t.resourceId,t.baseEnvironmentId,t.branchRule??null,t.domainPattern,Fd(t.ttlHours,24,1,720),Fd(t.keepCount,10,1,100),t.publicAccess?1:0,t.authenticationRequired===!1?0:1,t.allowForks?1:0,JSON.stringify(c),JSON.stringify(ut(t.resourceOverrides??{})),t.databaseStrategy??"disabled",jT(t.maxMonthlyCost,25,0,1e4),jT(t.maxCpu,1,0.1,64),Fd(t.maxMemoryMb,1024,128,131072),t.cleanupOnClose===!1?0:1,t.createdByActorId??null,_,_]),this.controlPlane.appendEvent({projectId:t.projectId,resourceId:t.resourceId,actorId:t.createdByActorId,type:"preview.definition.created",payload:{definitionId:T,baseEnvironmentId:t.baseEnvironmentId,ttlHours:Fd(t.ttlHours,24,1,720),inheritedSecretNames:c}}),this.getDefinition(T)}getDefinition(t){let e=this.controlPlane.database.query("SELECT * FROM preview_definitions WHERE id=?").get(t);return e?bR(e):void 0}getDefinitionForResource(t){let e=this.controlPlane.database.query("SELECT * FROM preview_definitions WHERE resource_id=?").get(t);return e?bR(e):void 0}listDefinitions(t){return this.controlPlane.database.query("SELECT * FROM preview_definitions WHERE project_id=? ORDER BY updated_at DESC").all(t).map(bR)}listInstances(t={}){return this.controlPlane.database.query("SELECT * FROM preview_instances ORDER BY created_at DESC").all().map(Kc).filter((r)=>(!t.projectId||r.projectId===t.projectId)&&(!t.definitionId||r.definitionId===t.definitionId)&&(!t.status||r.status===t.status))}getInstance(t){let e=this.controlPlane.database.query("SELECT * FROM preview_instances WHERE id=?").get(t);return e?Kc(e):void 0}findForPullRequest(t,e,r){let d=this.controlPlane.database.query("SELECT * FROM preview_instances WHERE definition_id=? AND identity_key=?").get(t,`pr:${e}:${r}`);return d?Kc(d):void 0}findForBranch(t,e,r){let d=this.controlPlane.database.query("SELECT * FROM preview_instances WHERE definition_id=? AND identity_key=?").get(t,`branch:${e}:${r}`);return d?Kc(d):void 0}upsert(t){let e=this.getDefinition(t.definitionId);if(!e?.enabled)throw Error("Preview environments are not enabled for this application");if(!s1.test(t.commitSha))throw Error("Preview deployment requires an immutable 40-64 character commit SHA");if(t.fork&&!e.allowForks)throw Error("Untrusted fork previews are disabled");let r=t.pullRequestNumber?`pr:${t.repository??"unknown"}:${t.pullRequestNumber}`:`branch:${t.repository??"local"}:${t.branch}`,d=q1("sha256").update(`${e.id}:${r}`).digest("hex").slice(0,8),n=`${(t.pullRequestNumber?`pr-${t.pullRequestNumber}`:xR(t.branch)).slice(0,28)}-${d}`,c=`preview-${n}`.slice(0,63),_=e.domainPattern.replaceAll("{name}",n).replaceAll("{project}",xR(e.projectId)).replaceAll("{branch}",xR(t.branch)).replaceAll("{pr}",String(t.pullRequestNumber??"branch")),T=t.now??this.now(),i=T.toISOString(),h=new Date(T.getTime()+e.ttlHours*60*60*1000).toISOString(),R=this.controlPlane.database.query("SELECT * FROM preview_instances WHERE definition_id=? AND identity_key=?").get(e.id,r);if(R){let u=Kc(R),f=u.commitSha!==t.commitSha||u.status==="destroyed";if(f)this.controlPlane.database.run("UPDATE preview_instances SET commit_sha=?, branch=?, fork=?, status='queued', expires_at=?, url=?, teardown_error=NULL, destroyed_at=NULL, version=version+1, updated_at=? WHERE id=?",[t.commitSha,t.branch,t.fork?1:0,h,_,i,u.id]);return{preview:this.getInstance(u.id),created:!1,changed:f,inheritedSecrets:t.fork?[]:e.inheritedSecrets}}let N=this.id(),A=ut({source:{provider:t.sourceProvider??null,repository:t.repository??null,branch:t.branch,commitSha:t.commitSha,pullRequestNumber:t.pullRequestNumber??null,fork:!!t.fork},policy:{databaseStrategy:e.databaseStrategy,resourceOverrides:e.resourceOverrides,maxMonthlyCost:e.maxMonthlyCost,maxCpu:e.maxCpu,maxMemoryMb:e.maxMemoryMb,publicAccess:e.publicAccess,authenticationRequired:e.authenticationRequired},inheritedSecretNames:t.fork?[]:e.inheritedSecrets});return this.controlPlane.database.run("INSERT INTO preview_instances (id, definition_id, project_id, resource_id, base_environment_id, identity_key, source_provider, repository, branch, pull_request_number, fork, commit_sha, name, stack_name, url, status, expires_at, created_by_actor_id, desired_state, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'queued', ?, ?, ?, ?, ?)",[N,e.id,e.projectId,e.resourceId,e.baseEnvironmentId,r,t.sourceProvider??null,t.repository??null,t.branch,t.pullRequestNumber??null,t.fork?1:0,t.commitSha,n,c,_,h,t.createdByActorId??null,JSON.stringify(A),i,i]),this.controlPlane.appendEvent({projectId:e.projectId,resourceId:e.resourceId,actorId:t.createdByActorId,type:"preview.created",payload:{previewId:N,identityKey:r,commitSha:t.commitSha,expiresAt:h,fork:!!t.fork}}),{preview:this.getInstance(N),created:!0,changed:!0,inheritedSecrets:t.fork?[]:e.inheritedSecrets}}transition(t,e,r={}){let d=this.getInstance(t);if(!d)throw Error(`Preview ${t} was not found`);let E=this.now().toISOString(),n=e==="destroyed"?E:null;return this.controlPlane.database.run("UPDATE preview_instances SET status=?, latest_operation_id=COALESCE(?, latest_operation_id), observed_state=?, teardown_error=?, cost_estimate=COALESCE(?, cost_estimate), destroyed_at=?, version=version+1, updated_at=? WHERE id=?",[e,r.operationId??null,JSON.stringify(ut(r.observedState??d.observedState)),r.teardownError??null,r.costEstimate??null,n,E,t]),this.controlPlane.appendEvent({projectId:d.projectId,resourceId:d.resourceId,operationId:r.operationId,type:`preview.${e}`,level:e==="failed"||e==="cleanup_failed"?"error":"info",payload:{previewId:t,commitSha:d.commitSha,teardownError:r.teardownError??null}}),this.getInstance(t)}extend(t,e){let r=this.getInstance(t),d=r?this.getDefinition(r.definitionId):void 0;if(!r||!d)throw Error(`Preview ${t} was not found`);let E=this.now(),n=Fd(e,d.ttlHours,1,720),c=new Date(Math.max(E.getTime(),new Date(r.expiresAt).getTime())+n*3600000).toISOString();return this.controlPlane.database.run("UPDATE preview_instances SET expires_at=?, version=version+1, updated_at=? WHERE id=?",[c,E.toISOString(),t]),this.getInstance(t)}expired(t=this.now()){return this.listInstances().filter((e)=>["queued","deploying","active","updating","failed","cleanup_failed"].includes(e.status)&&new Date(e.expiresAt)<=t)}recordResource(t){let e=this.getInstance(t.previewId);if(!e)throw Error(`Preview ${t.previewId} was not found`);let r={"ts-cloud:preview":e.id,"ts-cloud:project":e.projectId,"ts-cloud:expires-at":e.expiresAt};for(let[c,_]of Object.entries(r))if(t.tags[c]!==_)throw Error(`Preview resource is missing immutable tag ${c}`);let d=this.id(),E=this.now().toISOString();this.controlPlane.database.run("INSERT INTO preview_resources (id, preview_id, provider, provider_resource_id, kind, tags, observed_state, discovered_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?) ON CONFLICT(preview_id, provider, provider_resource_id) DO UPDATE SET kind=excluded.kind, tags=excluded.tags, observed_state=excluded.observed_state, deleted_at=NULL",[d,e.id,t.provider,t.providerResourceId,t.kind,JSON.stringify(t.tags),JSON.stringify(ut(t.observedState??{})),E]);let n=this.controlPlane.database.query("SELECT * FROM preview_resources WHERE preview_id=? AND provider=? AND provider_resource_id=?").get(e.id,t.provider,t.providerResourceId);return gC(n)}listResources(t){return this.controlPlane.database.query("SELECT * FROM preview_resources WHERE preview_id=? ORDER BY kind, provider_resource_id").all(t).map(gC)}markResourcesDeleted(t){if(!this.getInstance(t))throw Error(`Preview ${t} was not found`);return this.controlPlane.database.run("UPDATE preview_resources SET deleted_at=? WHERE preview_id=? AND deleted_at IS NULL",[this.now().toISOString(),t]).changes}}class Zc{controlPlane;previews;queue;constructor(t){this.controlPlane=t;this.previews=new Bd(t),this.queue=new gt(t)}enqueueDeploy(t,e={}){let r=e.created?"preview.create":"preview.update",d=e.reason==="manual_rebuild"?`:${crypto.randomUUID()}`:"",E=this.queue.enqueue({projectId:t.projectId,environmentId:t.baseEnvironmentId,resourceId:t.resourceId,actorId:e.actorId,kind:r,correlationId:`preview:${t.id}`,idempotencyKey:`preview:${t.id}:${t.commitSha}${d}`,input:{previewId:t.id,reason:e.reason??(e.created?"create":"commit_update"),source:{repository:t.repository??null,branch:t.branch,commitSha:t.commitSha,pullRequestNumber:t.pullRequestNumber??null,fork:t.fork}},lockKey:`preview:${t.id}`,providerKey:"preview",buildSlot:!0,maxAttempts:3,retryClasses:["network","provider_throttled","provider_unavailable"],resumePolicy:"fail",cancellationMode:"provider_non_cancellable",retentionDays:90}).operation;return this.previews.transition(t.id,"queued",{operationId:E.id}),E}enqueueDestroy(t,e,r){if(t.status==="destroyed")throw Error("Preview is already destroyed");let d=this.queue.enqueue({projectId:t.projectId,environmentId:t.baseEnvironmentId,resourceId:t.resourceId,actorId:r,kind:"preview.destroy",correlationId:`preview:${t.id}`,idempotencyKey:`preview:${t.id}:destroy:${e}`,input:{previewId:t.id,reason:e},lockKey:`preview:${t.id}`,providerKey:"preview",maxAttempts:3,retryClasses:["network","provider_throttled","provider_unavailable"],resumePolicy:"fail",cancellationMode:"provider_non_cancellable",retentionDays:90}).operation;return this.previews.transition(t.id,"queued",{operationId:d.id}),d}cleanup(t={}){let e=t.now??new Date,r=new Map,d=this.previews.listInstances().filter((T)=>!["destroyed","destroying"].includes(T.status)),E=(T,i)=>{let h=r.get(T.id)??{preview:T,reasons:[]};if(!h.reasons.includes(i))h.reasons.push(i);r.set(T.id,h)};for(let T of d){if(new Date(T.expiresAt)<=e)E(T,"ttl_expired");if(t.maxAgeHours&&e.getTime()-new Date(T.createdAt).getTime()>=t.maxAgeHours*3600000)E(T,"max_age")}let n=new Map;for(let T of d)n.set(T.definitionId,[...n.get(T.definitionId)??[],T]);for(let[T,i]of n){let h=this.previews.getDefinition(T),R=t.keepCount??h?.keepCount;if(!R)continue;i.sort((N,A)=>A.createdAt.localeCompare(N.createdAt)).slice(R).forEach((N)=>E(N,"keep_count"))}let c=[...r.values()].sort((T,i)=>T.preview.createdAt.localeCompare(i.preview.createdAt)),_=t.dryRun?[]:c.map((T)=>this.enqueueDestroy(T.preview,T.reasons.sort().join("+"),t.actorId));if(c.length)this.controlPlane.appendEvent({actorId:t.actorId,type:t.dryRun?"preview.cleanup.planned":"preview.cleanup.queued",payload:{previewIds:c.map((T)=>T.preview.id),reasons:Object.fromEntries(c.map((T)=>[T.preview.id,T.reasons])),dryRun:!!t.dryRun}});return{candidates:c,operations:_,dryRun:!!t.dryRun}}reconcile(t){let e=[],r=[],d=[];for(let E of t){let n=E.tags["ts-cloud:preview"],c=E.tags["ts-cloud:project"],_=E.tags["ts-cloud:expires-at"];if(!n||!c||!_){d.push(E.providerResourceId);continue}let T=this.previews.getInstance(n);if(!T||T.projectId!==c||T.expiresAt!==_){r.push(E.providerResourceId);continue}if(this.previews.recordResource({...E,previewId:T.id}),E.estimatedMonthlyCost!==void 0)this.previews.transition(T.id,T.status,{costEstimate:E.estimatedMonthlyCost,observedState:{...T.observedState,lastReconciledAt:new Date().toISOString()}});e.push(E.providerResourceId)}if(r.length)this.controlPlane.appendEvent({type:"preview.reconciliation.leaks",level:"error",payload:{providerResourceIds:r}});return{matched:e,unknownPreviewResources:r,ignoredUntagged:d}}}var p1=["deployment.create","deployment.rollback","application.create","deploy.source","deploy.preview","preview.create","preview.update","preview.destroy","compose.deploy","compose.redeploy","compose.start","compose.stop","compose.delete","compose.scale"];function zT(t){return t&&typeof t==="object"&&!Array.isArray(t)?t:{}}function t$(t,e){if(!e.projectId||!e.environmentId)throw Error(`Queued ${e.kind} operation is missing its project or environment scope`);let r=t.listEnvironments(e.projectId).find((c)=>c.id===e.environmentId);if(!r)throw Error(`Environment ${e.environmentId} was not found for queued ${e.kind} operation`);let d=e.resourceId?t.getResource(e.resourceId):void 0;if(e.resourceId&&(!d||d.projectId!==e.projectId||d.environmentId!==e.environmentId))throw Error(`Resource ${e.resourceId} was not found in the queued deployment scope`);let E=zT(e.input);if(e.kind.startsWith("compose.")){let c=typeof E.applicationId==="string"?E.applicationId:void 0,_=c?new DE(t).get(c):e.resourceId?new DE(t).getByResource(e.resourceId):void 0;if(!_||_.projectId!==e.projectId||_.environmentId!==e.environmentId||_.resourceId!==e.resourceId)throw Error("Queued Compose application does not match the operation scope");let T=e.kind.slice(8),i=["compose:apply",_.id,"--action",T,"--env",r.slug];if(typeof E.service==="string"&&E.service)i.push("--service",E.service);if(typeof E.replicas==="number")i.push("--replicas",String(E.replicas));if(E.removeVolumes===!0)i.push("--remove-volumes");return{id:`queue:${e.id}`,label:`${T[0].toUpperCase()}${T.slice(1)} Compose application`,description:`${T} ${_.name}.`,command:i,mutates:!0,target:{environment:r.slug,resource:d?.slug,composeId:_.id}}}if(e.kind.startsWith("preview.")){let c=typeof E.previewId==="string"?E.previewId:void 0,_=c?new Bd(t).getInstance(c):void 0;if(!_)throw Error(`Preview ${c??"(missing)"} was not found for queued ${e.kind}`);if(_.projectId!==e.projectId||_.resourceId!==e.resourceId)throw Error("Queued preview does not match the operation scope");if(e.kind==="preview.destroy")return{id:`queue:${e.id}`,label:"Destroy preview",description:`Destroy ${_.name}.`,command:["stack:delete",_.stackName,"--yes"],mutates:!0,target:{environment:r.slug,resource:d?.slug,previewId:_.id}};return{id:`queue:${e.id}`,label:e.kind==="preview.create"?"Create preview":"Update preview",description:`Deploy ${_.name} at ${_.commitSha}.`,command:["deploy","--stack",_.stackName,"--env",r.slug,"--yes","--skip-dns-verification",...d?["--site",d.slug]:[]],mutates:!0,target:{environment:r.slug,resource:d?.slug,previewId:_.id}}}if(e.kind==="deployment.rollback"){let c=["deploy:rollback"];if(d)c.push(d.slug);if(c.push("--env",r.slug),typeof E.revision==="string"&&E.revision)c.push("--to",E.revision);return{id:`queue:${e.id}`,label:"Rollback deployment",description:`Roll back ${d?.slug??r.slug}.`,command:c,mutates:!0,target:{environment:r.slug,resource:d?.slug}}}let n=["deploy","--env",r.slug,"--yes"];if(d)n.push("--site",d.slug);return{id:`queue:${e.id}`,label:e.kind==="deploy.preview"?"Deploy preview":"Deploy release",description:`Deploy ${d?.slug??r.slug}.`,command:n,mutates:!0,target:{environment:r.slug,resource:d?.slug}}}function e$(t){let e=t.stderr?.trim()||`Deployment process exited with code ${t.exitCode}`;if(/\b(?:429|rate.?limit|throttl)/i.test(e))return new gr(e,"provider_throttled");if(/\b(?:502|503|504|temporar(?:y|ily)|unavailable|provider.?error)/i.test(e))return new gr(e,"provider_unavailable");if(/\b(?:network|econn|enotfound|socket|timed?\s*out|fetch failed|dns)\b/i.test(e))return new gr(e,"network");return Error(e)}function $C(t){let e=async(r)=>{r.checkpoint("prepare","Resolving the persisted deployment target.");let d=t$(t.store,r.operation),E=d.target.previewId?new Bd(t.store):void 0,n=d.target.composeId?new DE(t.store):void 0;if(E&&d.target.previewId)E.transition(d.target.previewId,r.operation.kind==="preview.destroy"?"destroying":r.operation.kind==="preview.update"?"updating":"deploying",{operationId:r.operation.id});if(n&&d.target.composeId)n.transition(d.target.composeId,r.operation.kind==="compose.delete"?"deleting":r.operation.kind==="compose.stop"?"stopped":"deploying",{operationId:r.operation.id});r.log(`Target: ${d.target.resource??"all resources"} in ${d.target.environment}.`,{stream:"system"}),r.throwIfCancellationRequested(),r.checkpoint("execute",`Running cloud ${d.command.join(" ")}.`);let c=await t.execute(d,r);if(!c.ok){if(E&&d.target.previewId)E.transition(d.target.previewId,r.operation.kind==="preview.destroy"?"cleanup_failed":"failed",{operationId:r.operation.id,teardownError:r.operation.kind==="preview.destroy"?c.stderr?.trim()||`Process exited with ${c.exitCode}`:void 0});if(n&&d.target.composeId)n.transition(d.target.composeId,r.operation.kind==="compose.delete"?"degraded":"failed",{operationId:r.operation.id,error:c.stderr?.trim()||`Process exited with ${c.exitCode}`});throw e$(c)}if(r.throwIfCancellationRequested(),E&&d.target.previewId){let _=E.getInstance(d.target.previewId);if(r.operation.kind==="preview.destroy")E.markResourcesDeleted(_.id),E.transition(_.id,"destroyed",{operationId:r.operation.id,observedState:{reconciledResourceIds:E.listResources(_.id).map((T)=>T.providerResourceId),exactCommitSha:_.commitSha}});else{let T=t.store.getResource(_.resourceId)?.provider??"default";E.recordResource({previewId:_.id,provider:T,providerResourceId:_.stackName,kind:"stack",tags:{"ts-cloud:preview":_.id,"ts-cloud:project":_.projectId,"ts-cloud:expires-at":_.expiresAt},observedState:{command:c.command??null,exactCommitSha:_.commitSha}}),E.transition(_.id,"active",{operationId:r.operation.id,observedState:{url:_.url??null,stackName:_.stackName,exactCommitSha:_.commitSha,providerStatus:"deployed"}})}}if(n&&d.target.composeId){let _=n.get(d.target.composeId),T=typeof zT(r.operation.input).service==="string"?String(zT(r.operation.input).service):void 0,i=r.operation.kind==="compose.delete"?"deleted":r.operation.kind==="compose.stop"?"stopped":"running",h=n.transition(_.id,i,{operationId:r.operation.id,services:Object.values(_.manifest.spec.services).filter((R)=>!T||R.name===T).map((R)=>({name:R.name,status:i==="stopped"||i==="deleted"?"stopped":"running",replicas:i==="deleted"?0:R.replicas,healthyReplicas:i==="running"?R.replicas:0,observedState:{command:c.command??null,healthGatePassed:i==="running"}}))});if(i==="deleted")yC(t.store,h,zT(r.operation.input).removeVolumes===!0)}return r.checkpoint("finalize","Deployment command completed; persisting the terminal result."),{command:c.command??`cloud ${d.command.join(" ")}`,exitCode:c.exitCode,environment:d.target.environment,resource:d.target.resource??null}};return Object.fromEntries(p1.map((r)=>[r,e]))}var qR=/^[a-z0-9][a-z0-9_.-]{1,62}$/,r$=/^0?[0-7]{3}$/,d$=["/","/boot","/dev","/etc","/proc","/root","/run","/sys","/var/run","/var/lib/docker","/var/lib/containers"],E$=["create","attach","detach","resize","snapshot","restore","delete","adopt","usage"],n$=(t)=>t&&typeof t==="object"&&!Array.isArray(t)?t:{};function c$(t){return Object.fromEntries(E$.map((e)=>[e,{supported:!1,reason:t}]))}function sR(t,e={}){let r=c$("This storage driver does not support the operation.");for(let d of t)r[d]={supported:!0};return{...r,...e}}function _$(t){if(!t.startsWith("/")||t.includes("\x00")||t.split("/").includes(".."))throw Error("Mount target must be an absolute normalized path without traversal.");let e=t.replace(/\/+$/,"")||"/";if(d$.some((r)=>e===r||e.startsWith(`${r}/`)))throw Error(`Mount target ${t} is a protected host or runtime path.`)}function T$(t){if(_$(t.targetPath),t.uid!=null&&(!Number.isInteger(t.uid)||t.uid<0))throw Error("Mount UID must be a non-negative integer.");if(t.gid!=null&&(!Number.isInteger(t.gid)||t.gid<0))throw Error("Mount GID must be a non-negative integer.");if(t.mode&&!r$.test(t.mode))throw Error("Mount mode must be a three or four digit octal value.");if(t.propagation&&!["private","rprivate","shared","rshared","slave","rslave"].includes(t.propagation))throw Error("Unsupported mount propagation mode.")}class oR{store;drivers;now;queue;constructor(t,e,r,d=()=>new Date){this.store=t;this.drivers=e;this.now=d;this.queue=r??new gt(t.controlPlane)}driver(t,e){let r=this.drivers.find((d)=>d.provider===t&&d.type===e);if(!r)throw Error(`No ${t} ${e} volume driver is configured.`);return r}capability(t,e){let r=t.capabilities[e];if(!r?.supported)throw Error(r?.reason??`${e} is unsupported for this volume.`)}queueMutation(t,e,r,d,E){return this.queue.enqueue({projectId:t.projectId,environmentId:t.environmentId,resourceId:E??t.resourceId,actorId:d,kind:e,idempotencyKey:`${e}:${t.id}:v${t.version}:${JSON.stringify(r)}`,correlationId:`volume:${t.id}`,input:{volumeId:t.id,...r},lockKey:E?`resource:${E}`:`volume:${t.id}`,providerKey:t.provider,maxAttempts:3,retryClasses:["network","provider_throttled","provider_unavailable"],resumePolicy:"fail",cancellationMode:"provider_non_cancellable",retentionDays:365}).operation}create(t){if(!qR.test(t.name))throw Error("Volume names must be 2-63 lowercase letters, numbers, dots, dashes, or underscores.");if(t.capacityBytes!=null&&(!Number.isSafeInteger(t.capacityBytes)||t.capacityBytes<=0))throw Error("Volume capacity must be a positive byte count.");let e=this.store.controlPlane.getProject(t.projectId),r=t.environmentId?this.store.controlPlane.listEnvironments(t.projectId).find((i)=>i.id===t.environmentId):void 0,d=t.resourceId?this.store.controlPlane.getResource(t.resourceId):void 0;if(!e||e.organizationId!==t.organizationId)throw Error("Volume project does not belong to the organization.");if(t.environmentId&&!r)throw Error("Volume environment does not belong to the project.");if(d&&(d.projectId!==t.projectId||d.environmentId!==t.environmentId||d.kind!=="volume"))throw Error("Volume resource does not belong to the selected scope.");let E=d??this.store.controlPlane.createResource({projectId:t.projectId,environmentId:t.environmentId,kind:"volume",slug:t.name,name:t.name,provider:t.provider,desiredState:{type:t.type,capacityBytes:t.capacityBytes??null,filesystem:t.filesystem??null,encrypted:!!t.encrypted}}),n=this.driver(t.provider,t.type),c=n.capabilities(),_=this.store.create({organizationId:t.organizationId,projectId:t.projectId,environmentId:t.environmentId,resourceId:E.id,name:t.name,provider:t.provider,type:t.type,status:"pending",capacityBytes:t.capacityBytes,filesystem:t.filesystem,encrypted:!!t.encrypted,capabilities:c,desiredState:t.desiredState??{},observedState:{}}),T=this.queueMutation(_,"volume.create",{},t.actorId);return this.store.audit({organizationId:_.organizationId,projectId:_.projectId,environmentId:_.environmentId,actorId:t.actorId,type:"volume.create.queued",volumeId:_.id,payload:{name:_.name,type:_.type}}),{volume:_,operation:T}}attach(t,e){let r=this.store.get(t);if(!r)throw Error("Volume was not found.");this.capability(r,"attach"),T$(e);let d=this.store.controlPlane.getResource(e.resourceId);if(!d||d.projectId!==r.projectId||d.environmentId!==r.environmentId)throw Error("Cross-project or cross-environment volume attachments are forbidden.");let E=this.store.upsertAttachment({volumeId:t,resourceId:e.resourceId,targetPath:e.targetPath,readOnly:!!e.readOnly,uid:e.uid,gid:e.gid,mode:e.mode,propagation:e.propagation??"private",driverOptions:e.driverOptions??{},desiredState:"attached",observedState:"pending"}),n=this.queueMutation(r,"volume.attach",{attachmentId:E.id},e.actorId,e.resourceId);return this.store.updateAttachment(E.id,{operationId:n.id}),this.store.update(r.id,r.version,{status:"attaching"}),this.store.audit({organizationId:r.organizationId,projectId:r.projectId,environmentId:r.environmentId,actorId:e.actorId,type:"volume.attach.queued",volumeId:t,payload:{resourceId:e.resourceId,targetPath:e.targetPath}}),{volume:this.store.get(r.id),attachment:this.store.attachment(E.id),operation:n}}detach(t,e,r={}){let d=this.store.get(t),E=this.store.attachment(e);if(!d||!E||E.volumeId!==t)throw Error("Volume attachment was not found.");if(this.capability(d,"detach"),E.observedState==="attached"&&(!r.drained||!r.unmounted))throw Error("Detach requires completed workload drain and filesystem unmount checkpoints.");if(r.force&&r.confirmation!==`detach ${d.name}`)throw Error(`Force detach requires confirmation: detach ${d.name}`);let n=this.store.updateAttachment(e,{desiredState:"detached"}),c=this.queueMutation(d,"volume.detach",{attachmentId:e,force:!!r.force},r.actorId,E.resourceId);return this.store.updateAttachment(e,{operationId:c.id}),this.store.update(d.id,d.version,{status:"detaching"}),{volume:this.store.get(t),attachment:n,operation:c}}resize(t,e,r={}){let d=this.store.get(t);if(!d)throw Error("Volume was not found.");if(this.capability(d,"resize"),!Number.isSafeInteger(e)||e<=0)throw Error("Volume capacity must be a positive byte count.");if(d.capacityBytes!=null&&e<d.capacityBytes)throw Error("Volume shrinking is not supported because it can corrupt data.");let E=d.capabilities.resize;if(E.minimumBytes&&e<E.minimumBytes)throw Error(`Minimum supported capacity is ${E.minimumBytes} bytes.`);if(E.maximumBytes&&e>E.maximumBytes)throw Error(`Maximum supported capacity is ${E.maximumBytes} bytes.`);if(E.online===!1&&!r.drained)throw Error("This resize requires a completed workload drain checkpoint.");let n=this.store.update(t,d.version,{status:"resizing",desiredState:{...d.desiredState,capacityBytes:e}}),c=this.queueMutation(n,"volume.resize",{capacityBytes:e},r.actorId);return{volume:n,operation:c}}snapshot(t,e={}){let r=this.store.get(t);if(!r)throw Error("Volume was not found.");this.capability(r,"snapshot");let d=this.store.createSnapshot({volumeId:t,name:e.name??`${r.name}-${this.now().toISOString().replace(/[:.]/g,"-")}`,status:"pending",encrypted:r.encrypted,metadata:{}}),E=this.store.update(t,r.version,{status:"snapshotting"}),n=this.queueMutation(E,"volume.snapshot",{snapshotId:d.id},e.actorId);return{volume:E,snapshot:d,operation:n}}restore(t,e){let r=this.store.snapshot(t),d=r?this.store.get(r.volumeId):void 0;if(!r||!d||r.status!=="available")throw Error("An available volume snapshot is required for restore.");if(this.capability(d,"restore"),!qR.test(e.name))throw Error("Restored volume names must be 2-63 lowercase letters, numbers, dots, dashes, or underscores.");let E=this.store.controlPlane.createResource({projectId:d.projectId,environmentId:d.environmentId,kind:"volume",slug:e.name,name:e.name,provider:d.provider,desiredState:{restoreFromSnapshotId:r.id}}),n=this.store.create({organizationId:d.organizationId,projectId:d.projectId,environmentId:d.environmentId,resourceId:E.id,name:e.name,provider:d.provider,type:d.type,status:"pending",capacityBytes:r.sizeBytes??d.capacityBytes,filesystem:d.filesystem,encrypted:r.encrypted,capabilities:d.capabilities,desiredState:{restoreFromSnapshotId:r.id,sourceVolumeId:d.id},observedState:{}}),c=this.queueMutation(n,"volume.restore",{snapshotId:r.id,sourceVolumeId:d.id},e.actorId);return{volume:n,snapshot:r,operation:c}}delete(t,e){let r=this.store.get(t);if(!r)throw Error("Volume was not found.");this.capability(r,"delete");let d=this.store.attachments(t).filter((_)=>_.desiredState==="attached"||_.observedState==="attached");if(d.length)throw Error(`Detach ${d.length} active consumer(s) before deleting this volume.`);if(!e.recentAuthAt||this.now().getTime()-new Date(e.recentAuthAt).getTime()>900000)throw Error("Volume deletion requires authentication verified within the last 15 minutes.");if(e.confirmation!==r.name)throw Error(`Type ${r.name} to confirm permanent volume deletion.`);if(!(r.lastBackupAt&&this.now().getTime()-new Date(r.lastBackupAt).getTime()<=86400000)&&(!e.backupOverride||e.backupOverrideConfirmation!==`delete without backup ${r.name}`))throw Error(`A verified backup from the last 24 hours is required, or confirm: delete without backup ${r.name}`);let n=this.store.update(t,r.version,{status:"deleting"}),c=this.queueMutation(n,"volume.delete",{backupOverride:!!e.backupOverride},e.actorId);return{volume:n,operation:c}}async discover(t){let e=new Set;for(let r of this.drivers)for(let d of await r.discover(t.projectId,t.environmentId)){let E=this.store.list({projectId:t.projectId,environmentId:t.environmentId}).find((c)=>c.provider===r.provider&&c.providerId===d.providerId);if(E){e.add(E.id),this.store.update(E.id,E.version,{capacityBytes:d.capacityBytes,usedBytes:d.usedBytes,filesystem:d.filesystem,encrypted:d.encrypted??E.encrypted,observedState:d.raw??{},status:E.status==="orphaned"?"available":E.status,orphanedAt:void 0});continue}let n=this.store.create({organizationId:t.organizationId,projectId:t.projectId,environmentId:t.environmentId,name:`orphan-${d.providerId}`.toLowerCase().replace(/[^a-z0-9_.-]/g,"-").slice(0,63),provider:r.provider,providerId:d.providerId,type:r.type,status:"orphaned",capacityBytes:d.capacityBytes,usedBytes:d.usedBytes,filesystem:d.filesystem,encrypted:!!d.encrypted,capabilities:r.capabilities(),desiredState:{},observedState:d.raw??{},orphanedAt:this.now().toISOString()});e.add(n.id)}return this.store.list({projectId:t.projectId,environmentId:t.environmentId})}adopt(t,e){let r=this.store.get(t);if(!r||r.status!=="orphaned")throw Error("Only discovered orphan volumes can be adopted.");if(!qR.test(e.name))throw Error("Volume names must be 2-63 lowercase letters, numbers, dots, dashes, or underscores.");let d=this.store.update(t,r.version,{name:e.name,status:"available",adoptedAt:this.now().toISOString(),orphanedAt:void 0});return this.store.audit({organizationId:r.organizationId,projectId:r.projectId,environmentId:r.environmentId,actorId:e.actorId,type:"volume.adopted",volumeId:t,payload:{providerId:r.providerId??null}}),d}}function i$(t){let e=n$(t.input);if(typeof e.volumeId!=="string")throw Error("Queued volume operation is missing its volume identity.");return{volumeId:e.volumeId,sourceVolumeId:typeof e.sourceVolumeId==="string"?e.sourceVolumeId:void 0,attachmentId:typeof e.attachmentId==="string"?e.attachmentId:void 0,snapshotId:typeof e.snapshotId==="string"?e.snapshotId:void 0,capacityBytes:typeof e.capacityBytes==="number"?e.capacityBytes:void 0,force:e.force===!0}}function XC(t,e){let r=(E)=>{let n=e.find((c)=>c.provider===E.provider&&c.type===E.type);if(!n)throw Error(`No ${E.provider} ${E.type} volume driver is configured.`);return n},d=async(E)=>{let n=i$(E.operation),c=t.get(n.volumeId);if(!c)throw Error("Queued volume was not found.");let _=r(c);E.checkpoint("preflight","Validating persistent volume identity and capabilities."),E.throwIfCancellationRequested();let T;if(E.operation.kind==="volume.create")T=await _.create(c),t.update(c.id,c.version,{providerId:T.providerId,capacityBytes:T.capacityBytes??c.capacityBytes,usedBytes:T.usedBytes,filesystem:T.filesystem??c.filesystem,encrypted:T.encrypted??c.encrypted,observedState:T.raw??{},status:"available"});else if(E.operation.kind==="volume.attach"){let i=n.attachmentId?t.attachment(n.attachmentId):void 0;if(!i)throw Error("Queued volume attachment was not found.");await _.attach(c,i),t.updateAttachment(i.id,{observedState:"attached",lastError:void 0}),t.update(c.id,c.version,{status:"attached"})}else if(E.operation.kind==="volume.detach"){let i=n.attachmentId?t.attachment(n.attachmentId):void 0;if(!i)throw Error("Queued volume attachment was not found.");await _.detach(c,i,{force:n.force}),t.updateAttachment(i.id,{observedState:"detached",lastError:void 0});let h=t.attachments(c.id).some((R)=>R.id!==i.id&&R.observedState==="attached");t.update(c.id,c.version,{status:h?"attached":"available"})}else if(E.operation.kind==="volume.resize"){if(!n.capacityBytes)throw Error("Queued volume resize is missing its capacity.");T=await _.resize(c,n.capacityBytes),t.update(c.id,c.version,{capacityBytes:T.capacityBytes??n.capacityBytes,usedBytes:T.usedBytes??c.usedBytes,observedState:T.raw??c.observedState,status:t.attachments(c.id).some((i)=>i.observedState==="attached")?"attached":"available"})}else if(E.operation.kind==="volume.snapshot"){let i=n.snapshotId?t.snapshot(n.snapshotId):void 0;if(!i)throw Error("Queued volume snapshot was not found.");let h=await _.snapshot(c,i);t.updateSnapshot(i.id,{...h,status:"available"}),t.update(c.id,c.version,{status:t.attachments(c.id).some((R)=>R.observedState==="attached")?"attached":"available",lastBackupAt:new Date().toISOString()})}else if(E.operation.kind==="volume.restore"){let i=n.snapshotId?t.snapshot(n.snapshotId):void 0,h=n.sourceVolumeId?t.get(n.sourceVolumeId):void 0;if(!i||!h)throw Error("Queued volume restore source was not found.");T=await _.restore(h,i,c),t.update(c.id,c.version,{providerId:T.providerId,capacityBytes:T.capacityBytes??c.capacityBytes,usedBytes:T.usedBytes,filesystem:T.filesystem??c.filesystem,encrypted:T.encrypted??c.encrypted,observedState:T.raw??{},status:"available"})}else if(E.operation.kind==="volume.delete")await _.delete(c),t.update(c.id,c.version,{status:"deleted",deletedAt:new Date().toISOString()});return E.checkpoint("finalize","Persisted observed volume state."),{volumeId:c.id,status:t.get(c.id)?.status??"deleted"}};return Object.fromEntries(["volume.create","volume.attach","volume.detach","volume.resize","volume.snapshot","volume.restore","volume.delete"].map((E)=>[E,d]))}var L$=async(t)=>{let e=Bun.spawn(["docker",...t],{stdout:"pipe",stderr:"pipe"}),[r,d,E]=await Promise.all([e.exited,new Response(e.stdout).text(),new Response(e.stderr).text()]);return{code:r,stdout:d,stderr:E}},In=/^[A-Za-z0-9][A-Za-z0-9_.-]{1,127}$/;class kc{command;provider="docker";type="docker";constructor(t=L$){this.command=t}capabilities(){return sR(["create","attach","detach","delete","adopt","usage"],{resize:{supported:!1,reason:"Docker named volumes do not expose a portable capacity resize operation."},snapshot:{supported:!1,reason:"Attach a volume backup policy to create verified recovery points."},restore:{supported:!1,reason:"Restore this volume from its verified backup recovery point."}})}async run(t,e=!1){let r=await this.command(t);if(r.code!==0&&!e)throw Error(`Docker volume command failed: ${r.stderr.trim()||r.code}`);return r.stdout}async inspect(t){let e=await this.run(["volume","inspect",t],!0);if(!e.trim())return;let r;try{r=JSON.parse(e)[0]}catch{return}return{providerId:String(r.Name??t),raw:{driver:String(r.Driver??"local"),mountpoint:String(r.Mountpoint??""),labels:r.Labels??{}}}}async discover(t,e){let r=await this.run(["volume","ls","--format","{{.Name}}"]),d=[];for(let E of r.split(`
|
|
5492
|
+
[output truncated]`;let T=this.idFn(),i=this.now();return this.controlPlane.database.run("INSERT INTO operation_logs (id, operation_id, stream, step, message, redacted, truncated, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?)",[T,t,r.stream??"stdout",r.step??null,d,E?1:0,_?1:0,i]),UC(this.controlPlane.database.query("SELECT * FROM operation_logs WHERE id=?").get(T))}logs(t,e={}){let r=Math.min(1000,Math.max(1,e.limit??200));return this.controlPlane.database.query("SELECT * FROM operation_logs WHERE operation_id=? AND sequence>? ORDER BY sequence ASC LIMIT ?").all(t,e.after??0,r).map(UC)}requestCancellation(t,e){let r=this.controlPlane.getOperation(t);if(!r||k1.includes(r.state))throw Error("Only queued or running operations can be cancelled");let d=this.controlPlane.requestCancellation(t);if(this.controlPlane.appendEvent({projectId:r.projectId,operationId:t,resourceId:r.resourceId,actorId:e,correlationId:r.correlationId,type:"operation.cancellation_requested",level:"warning",payload:{state:r.state}}),this.appendLog(t,r.state==="queued"?"Cancellation accepted before execution.":"Cancellation requested; waiting for the current provider step.",{stream:"system"}),d.state==="queued")return this.finish(t,"cancelled",{cancelledBeforeStart:!0});return d}retry(t,e,r={}){let d=this.controlPlane.getOperation(t),E=this.getJob(t);if(!d||!E||!["failed","cancelled","timed_out"].includes(d.state))throw Error("Only failed, cancelled, or timed-out queue jobs can be retried");if(d.attempt>=E.maxAttempts)throw Error(`Operation reached its ${E.maxAttempts}-attempt limit`);if(!E.retryClasses.includes(e))throw Error(`Retry class ${e} is not allowed for this operation`);let n=this.controlPlane.transitionOperation(t,{to:"queued",expectedVersion:d.version,error:`Retry requested after ${e}`}),c=new Date(this.nowFn().getTime()+Math.max(0,r.delayMs??0)).toISOString();this.controlPlane.database.run("UPDATE operations SET cancel_requested_at=NULL, finished_at=NULL WHERE id=?",[t]),this.controlPlane.database.run("UPDATE operation_jobs SET available_at=?, blocked_reason=NULL, updated_at=? WHERE operation_id=?",[c,this.now(),t]),this.controlPlane.appendEvent({projectId:d.projectId,operationId:t,resourceId:d.resourceId,actorId:r.actorId,correlationId:d.correlationId,type:"operation.retry_requested",payload:{errorClass:e,availableAt:c,nextAttempt:d.attempt+1}}),this.appendLog(t,`Retry queued for error class ${e}.`,{stream:"system"});let _=this.controlPlane.getOperation(n.id);return this.notifyAvailable(),_}release(t){this.controlPlane.database.run("DELETE FROM operation_locks WHERE operation_id=?",[t])}finish(t,e,r={},d){let E=this.controlPlane.getOperation(t);if(!E)throw Error(`Operation ${t} was not found`);let n=this.controlPlane.transitionOperation(t,{to:e,expectedVersion:E.version,output:r,error:d});return this.release(t),n}complete(t,e={}){let r=this.controlPlane.getOperation(t);if(!r||r.state!=="running"||r.leaseOwner!==this.workerId)throw Error("Only the lease owner can complete a running operation");return this.appendLog(t,"Operation completed successfully.",{stream:"system"}),this.finish(t,"succeeded",e)}fail(t,e,r={}){let d=this.controlPlane.getOperation(t);if(!d||d.state!=="running"||d.leaseOwner!==this.workerId)throw Error("Only the lease owner can fail a running operation");return this.appendLog(t,e,{stream:"stderr"}),this.finish(t,"failed",r,e)}async runOne(t){let e=this.claimNext(Object.keys(t));if(!e)return{handled:!1};let{operation:r,job:d}=e,E=t[r.kind];if(!E)return{handled:!1};let n=new AbortController,c=!1,_=setTimeout(()=>{c=!0,n.abort(new aT(d.timeoutSeconds))},d.timeoutSeconds*1000),T=setInterval(()=>{try{this.heartbeat(r.id)}catch{}},Math.max(250,Math.floor(this.leaseMs/3))),i=setInterval(()=>{if(this.controlPlane.getOperation(r.id)?.cancelRequestedAt)n.abort(new Vc)},100),h={operation:r,signal:n.signal,log:(R,N)=>this.appendLog(r.id,R,N),checkpoint:(R,N)=>{this.heartbeat(r.id,R),this.appendLog(r.id,N??R,{stream:"step",step:R})},heartbeat:()=>this.heartbeat(r.id),cancellationRequested:()=>!!this.controlPlane.getOperation(r.id)?.cancelRequestedAt,throwIfCancellationRequested:()=>{if(this.controlPlane.getOperation(r.id)?.cancelRequestedAt)throw new Vc}};try{let R=await Promise.race([E(h),new Promise((u,f)=>n.signal.addEventListener("abort",()=>f(n.signal.reason),{once:!0}))]);if(this.controlPlane.getOperation(r.id).cancelRequestedAt){let u=d.cancellationMode==="provider_non_cancellable";return this.appendLog(r.id,u?"Provider step completed after cancellation was requested; reconciliation is required.":"Operation cancelled cooperatively.",{stream:"system"}),{handled:!0,operation:this.finish(r.id,"cancelled",{providerCompleted:u,reconciliationRequired:u}),terminalState:"cancelled"}}return{handled:!0,operation:this.complete(r.id,R??{}),terminalState:"succeeded"}}catch(R){if(c||R instanceof aT)return this.appendLog(r.id,`Timed out after ${d.timeoutSeconds}s.`,{stream:"system"}),{handled:!0,operation:this.finish(r.id,"timed_out",{reconciliationRequired:d.cancellationMode==="provider_non_cancellable"},R instanceof Error?R.message:String(R)),terminalState:"timed_out"};if(R instanceof Vc||this.controlPlane.getOperation(r.id)?.cancelRequestedAt)return{handled:!0,operation:this.finish(r.id,"cancelled",{cooperativelyCancelled:!0}),terminalState:"cancelled"};if(R instanceof $r&&d.retryClasses.includes(R.errorClass)&&r.attempt<d.maxAttempts){let u=this.controlPlane.getOperation(r.id);this.controlPlane.transitionOperation(r.id,{to:"queued",expectedVersion:u.version,error:R.message});let f=Math.min(60000,1000*2**Math.max(0,r.attempt-1)),w=new Date(this.nowFn().getTime()+f).toISOString();return this.controlPlane.database.run("UPDATE operation_jobs SET available_at=?, blocked_reason=?, updated_at=? WHERE operation_id=?",[w,`retry_backoff:${R.errorClass}`,this.now(),r.id]),this.release(r.id),this.appendLog(r.id,`Retryable ${R.errorClass} failure; next attempt is delayed.`,{stream:"system"}),{handled:!0,operation:this.controlPlane.getOperation(r.id),requeued:!0}}let N=R instanceof Error?R.message:String(R);return this.appendLog(r.id,N,{stream:"stderr"}),{handled:!0,operation:this.finish(r.id,"failed",{},N),terminalState:"failed"}}finally{clearTimeout(_),clearInterval(T),clearInterval(i)}}recoverExpired(){let t=this.controlPlane.database.query("SELECT o.id FROM operations o JOIN operation_jobs j ON j.operation_id=o.id WHERE o.state='running' AND (o.lease_expires_at IS NULL OR o.lease_expires_at<=?)").all(this.now()),e={requeued:0,failed:0,cancelled:0};for(let r of t){let d=this.controlPlane.getOperation(String(r.id)),E=this.getJob(d.id);if(this.release(d.id),d.cancelRequestedAt){this.finish(d.id,"cancelled",{recoveredAfterWorkerLoss:!0}),e.cancelled++;continue}if(E.resumePolicy==="requeue"&&d.attempt<E.maxAttempts)this.controlPlane.transitionOperation(d.id,{to:"queued",expectedVersion:d.version,error:"Worker lease expired; safely requeued from the last checkpoint."}),this.controlPlane.database.run("UPDATE operation_jobs SET available_at=?, blocked_reason='worker_restart', updated_at=? WHERE operation_id=?",[this.now(),this.now(),d.id]),this.appendLog(d.id,"Worker lease expired; operation requeued from its persisted checkpoint.",{stream:"system"}),e.requeued++;else this.finish(d.id,"failed",{recoverable:!0,lastCheckpoint:E.currentStep??null},"Worker lease expired; retry explicitly after reconciling provider state."),e.failed++}return e}clearCompleted(t={}){let e=this.now(),r=[e],d=t.projectId?"AND o.project_id=?":"";if(t.projectId)r.push(t.projectId);let E=t.before?"AND o.finished_at<=?":"";if(t.before)r.push(new Date(t.before).toISOString());let n=this.controlPlane.database.query(`SELECT o.id, o.project_id, o.correlation_id FROM operations o JOIN operation_jobs j ON j.operation_id=o.id WHERE o.state IN ('succeeded','failed','cancelled','timed_out') AND j.retention_until<=? ${d} ${E}`).all(...r);for(let c of n)this.controlPlane.appendEvent({projectId:IE(c.project_id),actorId:t.actorId,correlationId:String(c.correlation_id),type:"queue.history.cleared",level:"warning",payload:{operationId:String(c.id),retentionCutoff:e}}),this.controlPlane.database.run("DELETE FROM operations WHERE id=?",[String(c.id)]);return n.length}}function wC(t,e,r){if(!Number.isFinite(t))return e;return Math.min(r,Math.max(1,Math.floor(t)))}class kR{queue;handlers;parallelism;pollIntervalMs;onResult;onError;waits=new Map;nextWaitId=0;lanes=[];running=!1;unsubscribeAvailability;constructor(t,e,r={}){this.queue=t;this.handlers=e;this.parallelism=wC(r.parallelism,4,100),this.pollIntervalMs=wC(r.pollIntervalMs,5000,60000),this.onResult=r.onResult,this.onError=r.onError}get active(){return this.running}start(){if(this.running)return this;return this.running=!0,this.unsubscribeAvailability=this.queue.onAvailable(()=>this.wake()),this.lanes=Array.from({length:this.parallelism},(t,e)=>this.runLane(e)),this}stop(){this.running=!1,this.unsubscribeAvailability?.(),this.unsubscribeAvailability=void 0,this.wake()}wake(){for(let{resolve:t,timer:e}of this.waits.values()){if(e)clearTimeout(e);t()}this.waits.clear()}async settled(){await Promise.allSettled(this.lanes)}async drain(){let t=[];while(!0){let e=await Promise.all(Array.from({length:this.parallelism},()=>this.queue.runOne(this.handlers)));if(t.push(...e.filter((r)=>r.handled)),!e.some((r)=>r.handled))return t}}wait(t){return new Promise((e)=>{let r=++this.nextWaitId,d=t?setTimeout(()=>{this.waits.delete(r),e()},this.pollIntervalMs):void 0;d?.unref?.(),this.waits.set(r,{resolve:e,timer:d})})}async runLane(t){while(this.running){try{let e=await this.queue.runOne(this.handlers);if(!this.running)break;if(e.handled){this.onResult?.(e),this.wake();continue}}catch(e){this.onError?.(e)}await this.wait(t===0)}}}import{createHash as q1}from"node:crypto";var s1=/^[a-f0-9]{40,64}$/i,o1=/^[A-Z][A-Z0-9_]{1,127}$/;function Vr(t){return typeof t==="string"&&t?t:void 0}function ln(t){try{return JSON.parse(String(t))}catch{return{}}}function m1(t){let e=ln(t);return Array.isArray(e)?e.map(String):[]}function bR(t){return{id:String(t.id),projectId:String(t.project_id),resourceId:String(t.resource_id),baseEnvironmentId:String(t.base_environment_id),enabled:Number(t.enabled)===1,branchRule:Vr(t.branch_rule),domainPattern:String(t.domain_pattern),ttlHours:Number(t.ttl_hours),keepCount:Number(t.keep_count),publicAccess:Number(t.public_access)===1,authenticationRequired:Number(t.authentication_required)===1,allowForks:Number(t.allow_forks)===1,inheritedSecrets:m1(t.inherited_secrets),resourceOverrides:ln(t.resource_overrides),databaseStrategy:String(t.database_strategy),maxMonthlyCost:Number(t.max_monthly_cost),maxCpu:Number(t.max_cpu),maxMemoryMb:Number(t.max_memory_mb),cleanupOnClose:Number(t.cleanup_on_close)===1,version:Number(t.version),createdByActorId:Vr(t.created_by_actor_id),createdAt:String(t.created_at),updatedAt:String(t.updated_at)}}function Kc(t){return{id:String(t.id),definitionId:String(t.definition_id),projectId:String(t.project_id),resourceId:String(t.resource_id),baseEnvironmentId:String(t.base_environment_id),identityKey:String(t.identity_key),sourceProvider:Vr(t.source_provider),repository:Vr(t.repository),branch:String(t.branch),pullRequestNumber:t.pull_request_number==null?void 0:Number(t.pull_request_number),fork:Number(t.fork)===1,commitSha:String(t.commit_sha),name:String(t.name),stackName:String(t.stack_name),url:Vr(t.url),status:String(t.status),expiresAt:String(t.expires_at),latestOperationId:Vr(t.latest_operation_id),createdByActorId:Vr(t.created_by_actor_id),costEstimate:t.cost_estimate==null?void 0:Number(t.cost_estimate),desiredState:ln(t.desired_state),observedState:ln(t.observed_state),teardownError:Vr(t.teardown_error),version:Number(t.version),createdAt:String(t.created_at),updatedAt:String(t.updated_at),destroyedAt:Vr(t.destroyed_at)}}function gC(t){return{id:String(t.id),previewId:String(t.preview_id),provider:String(t.provider),providerResourceId:String(t.provider_resource_id),kind:String(t.kind),tags:ln(t.tags),observedState:ln(t.observed_state),discoveredAt:String(t.discovered_at),deletedAt:Vr(t.deleted_at)}}function Fd(t,e,r,d){return Number.isFinite(t)?Math.min(d,Math.max(r,Math.floor(t))):e}function jT(t,e,r,d){return Number.isFinite(t)?Math.min(d,Math.max(r,t)):e}function xR(t){return t.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"").slice(0,28)||"preview"}class Bd{controlPlane;now;id;constructor(t,e={}){this.controlPlane=t;this.now=e.now??(()=>new Date),this.id=e.id??(()=>crypto.randomUUID())}createDefinition(t){let e=this.controlPlane.getResource(t.resourceId),r=this.controlPlane.listEnvironments(t.projectId).find((i)=>i.id===t.baseEnvironmentId);if(!e||e.projectId!==t.projectId||e.environmentId!==r?.id)throw Error("Preview resource and base environment must belong to the same project scope");if(e.kind!=="application")throw Error("Preview environments currently support application resources only");if(!/^https:\/\//.test(t.domainPattern)||!t.domainPattern.includes("{name}"))throw Error("Preview domainPattern must be HTTPS and include {name}");let d=this.getDefinitionForResource(t.resourceId),E=t.publicAccess??d?.publicAccess??!1,n=t.authenticationRequired??d?.authenticationRequired??!0;if(E&&!n)throw Error("Public preview environments require an authentication policy");let c=[...new Set(t.inheritedSecrets??[])];if(c.some((i)=>!o1.test(i)))throw Error("Inherited preview secret names must use uppercase environment-variable identifiers");let _=this.now().toISOString();if(d)return this.controlPlane.database.run("UPDATE preview_definitions SET base_environment_id=?, enabled=1, branch_rule=?, domain_pattern=?, ttl_hours=?, keep_count=?, public_access=?, authentication_required=?, allow_forks=?, inherited_secrets=?, resource_overrides=?, database_strategy=?, max_monthly_cost=?, max_cpu=?, max_memory_mb=?, cleanup_on_close=?, version=version+1, updated_at=? WHERE id=?",[t.baseEnvironmentId,t.branchRule??null,t.domainPattern,Fd(t.ttlHours,d.ttlHours,1,720),Fd(t.keepCount,d.keepCount,1,100),E?1:0,n?1:0,t.allowForks??d.allowForks?1:0,JSON.stringify(t.inheritedSecrets===void 0?d.inheritedSecrets:c),JSON.stringify(ut(t.resourceOverrides??d.resourceOverrides)),t.databaseStrategy??d.databaseStrategy,jT(t.maxMonthlyCost,d.maxMonthlyCost,0,1e4),jT(t.maxCpu,d.maxCpu,0.1,64),Fd(t.maxMemoryMb,d.maxMemoryMb,128,131072),t.cleanupOnClose??d.cleanupOnClose?1:0,_,d.id]),this.controlPlane.appendEvent({projectId:t.projectId,resourceId:t.resourceId,actorId:t.createdByActorId,type:"preview.definition.updated",payload:{definitionId:d.id,baseEnvironmentId:t.baseEnvironmentId,version:d.version+1}}),this.getDefinition(d.id);let T=this.id();return this.controlPlane.database.run("INSERT INTO preview_definitions (id, project_id, resource_id, base_environment_id, enabled, branch_rule, domain_pattern, ttl_hours, keep_count, public_access, authentication_required, allow_forks, inherited_secrets, resource_overrides, database_strategy, max_monthly_cost, max_cpu, max_memory_mb, cleanup_on_close, created_by_actor_id, created_at, updated_at) VALUES (?, ?, ?, ?, 1, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",[T,t.projectId,t.resourceId,t.baseEnvironmentId,t.branchRule??null,t.domainPattern,Fd(t.ttlHours,24,1,720),Fd(t.keepCount,10,1,100),t.publicAccess?1:0,t.authenticationRequired===!1?0:1,t.allowForks?1:0,JSON.stringify(c),JSON.stringify(ut(t.resourceOverrides??{})),t.databaseStrategy??"disabled",jT(t.maxMonthlyCost,25,0,1e4),jT(t.maxCpu,1,0.1,64),Fd(t.maxMemoryMb,1024,128,131072),t.cleanupOnClose===!1?0:1,t.createdByActorId??null,_,_]),this.controlPlane.appendEvent({projectId:t.projectId,resourceId:t.resourceId,actorId:t.createdByActorId,type:"preview.definition.created",payload:{definitionId:T,baseEnvironmentId:t.baseEnvironmentId,ttlHours:Fd(t.ttlHours,24,1,720),inheritedSecretNames:c}}),this.getDefinition(T)}getDefinition(t){let e=this.controlPlane.database.query("SELECT * FROM preview_definitions WHERE id=?").get(t);return e?bR(e):void 0}getDefinitionForResource(t){let e=this.controlPlane.database.query("SELECT * FROM preview_definitions WHERE resource_id=?").get(t);return e?bR(e):void 0}listDefinitions(t){return this.controlPlane.database.query("SELECT * FROM preview_definitions WHERE project_id=? ORDER BY updated_at DESC").all(t).map(bR)}listInstances(t={}){return this.controlPlane.database.query("SELECT * FROM preview_instances ORDER BY created_at DESC").all().map(Kc).filter((r)=>(!t.projectId||r.projectId===t.projectId)&&(!t.definitionId||r.definitionId===t.definitionId)&&(!t.status||r.status===t.status))}getInstance(t){let e=this.controlPlane.database.query("SELECT * FROM preview_instances WHERE id=?").get(t);return e?Kc(e):void 0}findForPullRequest(t,e,r){let d=this.controlPlane.database.query("SELECT * FROM preview_instances WHERE definition_id=? AND identity_key=?").get(t,`pr:${e}:${r}`);return d?Kc(d):void 0}findForBranch(t,e,r){let d=this.controlPlane.database.query("SELECT * FROM preview_instances WHERE definition_id=? AND identity_key=?").get(t,`branch:${e}:${r}`);return d?Kc(d):void 0}upsert(t){let e=this.getDefinition(t.definitionId);if(!e?.enabled)throw Error("Preview environments are not enabled for this application");if(!s1.test(t.commitSha))throw Error("Preview deployment requires an immutable 40-64 character commit SHA");if(t.fork&&!e.allowForks)throw Error("Untrusted fork previews are disabled");let r=t.pullRequestNumber?`pr:${t.repository??"unknown"}:${t.pullRequestNumber}`:`branch:${t.repository??"local"}:${t.branch}`,d=q1("sha256").update(`${e.id}:${r}`).digest("hex").slice(0,8),n=`${(t.pullRequestNumber?`pr-${t.pullRequestNumber}`:xR(t.branch)).slice(0,28)}-${d}`,c=`preview-${n}`.slice(0,63),_=e.domainPattern.replaceAll("{name}",n).replaceAll("{project}",xR(e.projectId)).replaceAll("{branch}",xR(t.branch)).replaceAll("{pr}",String(t.pullRequestNumber??"branch")),T=t.now??this.now(),i=T.toISOString(),h=new Date(T.getTime()+e.ttlHours*60*60*1000).toISOString(),R=this.controlPlane.database.query("SELECT * FROM preview_instances WHERE definition_id=? AND identity_key=?").get(e.id,r);if(R){let u=Kc(R),f=u.commitSha!==t.commitSha||u.status==="destroyed";if(f)this.controlPlane.database.run("UPDATE preview_instances SET commit_sha=?, branch=?, fork=?, status='queued', expires_at=?, url=?, teardown_error=NULL, destroyed_at=NULL, version=version+1, updated_at=? WHERE id=?",[t.commitSha,t.branch,t.fork?1:0,h,_,i,u.id]);return{preview:this.getInstance(u.id),created:!1,changed:f,inheritedSecrets:t.fork?[]:e.inheritedSecrets}}let N=this.id(),A=ut({source:{provider:t.sourceProvider??null,repository:t.repository??null,branch:t.branch,commitSha:t.commitSha,pullRequestNumber:t.pullRequestNumber??null,fork:!!t.fork},policy:{databaseStrategy:e.databaseStrategy,resourceOverrides:e.resourceOverrides,maxMonthlyCost:e.maxMonthlyCost,maxCpu:e.maxCpu,maxMemoryMb:e.maxMemoryMb,publicAccess:e.publicAccess,authenticationRequired:e.authenticationRequired},inheritedSecretNames:t.fork?[]:e.inheritedSecrets});return this.controlPlane.database.run("INSERT INTO preview_instances (id, definition_id, project_id, resource_id, base_environment_id, identity_key, source_provider, repository, branch, pull_request_number, fork, commit_sha, name, stack_name, url, status, expires_at, created_by_actor_id, desired_state, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'queued', ?, ?, ?, ?, ?)",[N,e.id,e.projectId,e.resourceId,e.baseEnvironmentId,r,t.sourceProvider??null,t.repository??null,t.branch,t.pullRequestNumber??null,t.fork?1:0,t.commitSha,n,c,_,h,t.createdByActorId??null,JSON.stringify(A),i,i]),this.controlPlane.appendEvent({projectId:e.projectId,resourceId:e.resourceId,actorId:t.createdByActorId,type:"preview.created",payload:{previewId:N,identityKey:r,commitSha:t.commitSha,expiresAt:h,fork:!!t.fork}}),{preview:this.getInstance(N),created:!0,changed:!0,inheritedSecrets:t.fork?[]:e.inheritedSecrets}}transition(t,e,r={}){let d=this.getInstance(t);if(!d)throw Error(`Preview ${t} was not found`);let E=this.now().toISOString(),n=e==="destroyed"?E:null;return this.controlPlane.database.run("UPDATE preview_instances SET status=?, latest_operation_id=COALESCE(?, latest_operation_id), observed_state=?, teardown_error=?, cost_estimate=COALESCE(?, cost_estimate), destroyed_at=?, version=version+1, updated_at=? WHERE id=?",[e,r.operationId??null,JSON.stringify(ut(r.observedState??d.observedState)),r.teardownError??null,r.costEstimate??null,n,E,t]),this.controlPlane.appendEvent({projectId:d.projectId,resourceId:d.resourceId,operationId:r.operationId,type:`preview.${e}`,level:e==="failed"||e==="cleanup_failed"?"error":"info",payload:{previewId:t,commitSha:d.commitSha,teardownError:r.teardownError??null}}),this.getInstance(t)}extend(t,e){let r=this.getInstance(t),d=r?this.getDefinition(r.definitionId):void 0;if(!r||!d)throw Error(`Preview ${t} was not found`);let E=this.now(),n=Fd(e,d.ttlHours,1,720),c=new Date(Math.max(E.getTime(),new Date(r.expiresAt).getTime())+n*3600000).toISOString();return this.controlPlane.database.run("UPDATE preview_instances SET expires_at=?, version=version+1, updated_at=? WHERE id=?",[c,E.toISOString(),t]),this.getInstance(t)}expired(t=this.now()){return this.listInstances().filter((e)=>["queued","deploying","active","updating","failed","cleanup_failed"].includes(e.status)&&new Date(e.expiresAt)<=t)}recordResource(t){let e=this.getInstance(t.previewId);if(!e)throw Error(`Preview ${t.previewId} was not found`);let r={"ts-cloud:preview":e.id,"ts-cloud:project":e.projectId,"ts-cloud:expires-at":e.expiresAt};for(let[c,_]of Object.entries(r))if(t.tags[c]!==_)throw Error(`Preview resource is missing immutable tag ${c}`);let d=this.id(),E=this.now().toISOString();this.controlPlane.database.run("INSERT INTO preview_resources (id, preview_id, provider, provider_resource_id, kind, tags, observed_state, discovered_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?) ON CONFLICT(preview_id, provider, provider_resource_id) DO UPDATE SET kind=excluded.kind, tags=excluded.tags, observed_state=excluded.observed_state, deleted_at=NULL",[d,e.id,t.provider,t.providerResourceId,t.kind,JSON.stringify(t.tags),JSON.stringify(ut(t.observedState??{})),E]);let n=this.controlPlane.database.query("SELECT * FROM preview_resources WHERE preview_id=? AND provider=? AND provider_resource_id=?").get(e.id,t.provider,t.providerResourceId);return gC(n)}listResources(t){return this.controlPlane.database.query("SELECT * FROM preview_resources WHERE preview_id=? ORDER BY kind, provider_resource_id").all(t).map(gC)}markResourcesDeleted(t){if(!this.getInstance(t))throw Error(`Preview ${t} was not found`);return this.controlPlane.database.run("UPDATE preview_resources SET deleted_at=? WHERE preview_id=? AND deleted_at IS NULL",[this.now().toISOString(),t]).changes}}class Zc{controlPlane;previews;queue;constructor(t){this.controlPlane=t;this.previews=new Bd(t),this.queue=new gt(t)}enqueueDeploy(t,e={}){let r=e.created?"preview.create":"preview.update",d=e.reason==="manual_rebuild"?`:${crypto.randomUUID()}`:"",E=this.queue.enqueue({projectId:t.projectId,environmentId:t.baseEnvironmentId,resourceId:t.resourceId,actorId:e.actorId,kind:r,correlationId:`preview:${t.id}`,idempotencyKey:`preview:${t.id}:${t.commitSha}${d}`,input:{previewId:t.id,reason:e.reason??(e.created?"create":"commit_update"),source:{repository:t.repository??null,branch:t.branch,commitSha:t.commitSha,pullRequestNumber:t.pullRequestNumber??null,fork:t.fork}},lockKey:`preview:${t.id}`,providerKey:"preview",buildSlot:!0,maxAttempts:3,retryClasses:["network","provider_throttled","provider_unavailable"],resumePolicy:"fail",cancellationMode:"provider_non_cancellable",retentionDays:90}).operation;return this.previews.transition(t.id,"queued",{operationId:E.id}),E}enqueueDestroy(t,e,r){if(t.status==="destroyed")throw Error("Preview is already destroyed");let d=this.queue.enqueue({projectId:t.projectId,environmentId:t.baseEnvironmentId,resourceId:t.resourceId,actorId:r,kind:"preview.destroy",correlationId:`preview:${t.id}`,idempotencyKey:`preview:${t.id}:destroy:${e}`,input:{previewId:t.id,reason:e},lockKey:`preview:${t.id}`,providerKey:"preview",maxAttempts:3,retryClasses:["network","provider_throttled","provider_unavailable"],resumePolicy:"fail",cancellationMode:"provider_non_cancellable",retentionDays:90}).operation;return this.previews.transition(t.id,"queued",{operationId:d.id}),d}cleanup(t={}){let e=t.now??new Date,r=new Map,d=this.previews.listInstances().filter((T)=>!["destroyed","destroying"].includes(T.status)),E=(T,i)=>{let h=r.get(T.id)??{preview:T,reasons:[]};if(!h.reasons.includes(i))h.reasons.push(i);r.set(T.id,h)};for(let T of d){if(new Date(T.expiresAt)<=e)E(T,"ttl_expired");if(t.maxAgeHours&&e.getTime()-new Date(T.createdAt).getTime()>=t.maxAgeHours*3600000)E(T,"max_age")}let n=new Map;for(let T of d)n.set(T.definitionId,[...n.get(T.definitionId)??[],T]);for(let[T,i]of n){let h=this.previews.getDefinition(T),R=t.keepCount??h?.keepCount;if(!R)continue;i.sort((N,A)=>A.createdAt.localeCompare(N.createdAt)).slice(R).forEach((N)=>E(N,"keep_count"))}let c=[...r.values()].sort((T,i)=>T.preview.createdAt.localeCompare(i.preview.createdAt)),_=t.dryRun?[]:c.map((T)=>this.enqueueDestroy(T.preview,T.reasons.sort().join("+"),t.actorId));if(c.length)this.controlPlane.appendEvent({actorId:t.actorId,type:t.dryRun?"preview.cleanup.planned":"preview.cleanup.queued",payload:{previewIds:c.map((T)=>T.preview.id),reasons:Object.fromEntries(c.map((T)=>[T.preview.id,T.reasons])),dryRun:!!t.dryRun}});return{candidates:c,operations:_,dryRun:!!t.dryRun}}reconcile(t){let e=[],r=[],d=[];for(let E of t){let n=E.tags["ts-cloud:preview"],c=E.tags["ts-cloud:project"],_=E.tags["ts-cloud:expires-at"];if(!n||!c||!_){d.push(E.providerResourceId);continue}let T=this.previews.getInstance(n);if(!T||T.projectId!==c||T.expiresAt!==_){r.push(E.providerResourceId);continue}if(this.previews.recordResource({...E,previewId:T.id}),E.estimatedMonthlyCost!==void 0)this.previews.transition(T.id,T.status,{costEstimate:E.estimatedMonthlyCost,observedState:{...T.observedState,lastReconciledAt:new Date().toISOString()}});e.push(E.providerResourceId)}if(r.length)this.controlPlane.appendEvent({type:"preview.reconciliation.leaks",level:"error",payload:{providerResourceIds:r}});return{matched:e,unknownPreviewResources:r,ignoredUntagged:d}}}var p1=["deployment.create","deployment.rollback","application.create","deploy.source","deploy.preview","preview.create","preview.update","preview.destroy","compose.deploy","compose.redeploy","compose.start","compose.stop","compose.delete","compose.scale"];function zT(t){return t&&typeof t==="object"&&!Array.isArray(t)?t:{}}function t$(t,e){if(!e.projectId||!e.environmentId)throw Error(`Queued ${e.kind} operation is missing its project or environment scope`);let r=t.listEnvironments(e.projectId).find((c)=>c.id===e.environmentId);if(!r)throw Error(`Environment ${e.environmentId} was not found for queued ${e.kind} operation`);let d=e.resourceId?t.getResource(e.resourceId):void 0;if(e.resourceId&&(!d||d.projectId!==e.projectId||d.environmentId!==e.environmentId))throw Error(`Resource ${e.resourceId} was not found in the queued deployment scope`);let E=zT(e.input);if(e.kind.startsWith("compose.")){let c=typeof E.applicationId==="string"?E.applicationId:void 0,_=c?new DE(t).get(c):e.resourceId?new DE(t).getByResource(e.resourceId):void 0;if(!_||_.projectId!==e.projectId||_.environmentId!==e.environmentId||_.resourceId!==e.resourceId)throw Error("Queued Compose application does not match the operation scope");let T=e.kind.slice(8),i=["compose:apply",_.id,"--action",T,"--env",r.slug];if(typeof E.service==="string"&&E.service)i.push("--service",E.service);if(typeof E.replicas==="number")i.push("--replicas",String(E.replicas));if(E.removeVolumes===!0)i.push("--remove-volumes");return{id:`queue:${e.id}`,label:`${T[0].toUpperCase()}${T.slice(1)} Compose application`,description:`${T} ${_.name}.`,command:i,mutates:!0,target:{environment:r.slug,resource:d?.slug,composeId:_.id}}}if(e.kind.startsWith("preview.")){let c=typeof E.previewId==="string"?E.previewId:void 0,_=c?new Bd(t).getInstance(c):void 0;if(!_)throw Error(`Preview ${c??"(missing)"} was not found for queued ${e.kind}`);if(_.projectId!==e.projectId||_.resourceId!==e.resourceId)throw Error("Queued preview does not match the operation scope");if(e.kind==="preview.destroy")return{id:`queue:${e.id}`,label:"Destroy preview",description:`Destroy ${_.name}.`,command:["stack:delete",_.stackName,"--yes"],mutates:!0,target:{environment:r.slug,resource:d?.slug,previewId:_.id}};return{id:`queue:${e.id}`,label:e.kind==="preview.create"?"Create preview":"Update preview",description:`Deploy ${_.name} at ${_.commitSha}.`,command:["deploy","--stack",_.stackName,"--env",r.slug,"--yes","--skip-dns-verification",...d?["--site",d.slug]:[]],mutates:!0,target:{environment:r.slug,resource:d?.slug,previewId:_.id}}}if(e.kind==="deployment.rollback"){let c=["deploy:rollback"];if(d)c.push(d.slug);if(c.push("--env",r.slug),typeof E.revision==="string"&&E.revision)c.push("--to",E.revision);return{id:`queue:${e.id}`,label:"Rollback deployment",description:`Roll back ${d?.slug??r.slug}.`,command:c,mutates:!0,target:{environment:r.slug,resource:d?.slug}}}let n=["deploy","--env",r.slug,"--yes"];if(d)n.push("--site",d.slug);return{id:`queue:${e.id}`,label:e.kind==="deploy.preview"?"Deploy preview":"Deploy release",description:`Deploy ${d?.slug??r.slug}.`,command:n,mutates:!0,target:{environment:r.slug,resource:d?.slug}}}function e$(t){let e=t.stderr?.trim()||`Deployment process exited with code ${t.exitCode}`;if(/\b(?:429|rate.?limit|throttl)/i.test(e))return new $r(e,"provider_throttled");if(/\b(?:502|503|504|temporar(?:y|ily)|unavailable|provider.?error)/i.test(e))return new $r(e,"provider_unavailable");if(/\b(?:network|econn|enotfound|socket|timed?\s*out|fetch failed|dns)\b/i.test(e))return new $r(e,"network");return Error(e)}function $C(t){let e=async(r)=>{r.checkpoint("prepare","Resolving the persisted deployment target.");let d=t$(t.store,r.operation),E=d.target.previewId?new Bd(t.store):void 0,n=d.target.composeId?new DE(t.store):void 0;if(E&&d.target.previewId)E.transition(d.target.previewId,r.operation.kind==="preview.destroy"?"destroying":r.operation.kind==="preview.update"?"updating":"deploying",{operationId:r.operation.id});if(n&&d.target.composeId)n.transition(d.target.composeId,r.operation.kind==="compose.delete"?"deleting":r.operation.kind==="compose.stop"?"stopped":"deploying",{operationId:r.operation.id});r.log(`Target: ${d.target.resource??"all resources"} in ${d.target.environment}.`,{stream:"system"}),r.throwIfCancellationRequested(),r.checkpoint("execute",`Running cloud ${d.command.join(" ")}.`);let c=await t.execute(d,r);if(!c.ok){if(E&&d.target.previewId)E.transition(d.target.previewId,r.operation.kind==="preview.destroy"?"cleanup_failed":"failed",{operationId:r.operation.id,teardownError:r.operation.kind==="preview.destroy"?c.stderr?.trim()||`Process exited with ${c.exitCode}`:void 0});if(n&&d.target.composeId)n.transition(d.target.composeId,r.operation.kind==="compose.delete"?"degraded":"failed",{operationId:r.operation.id,error:c.stderr?.trim()||`Process exited with ${c.exitCode}`});throw e$(c)}if(r.throwIfCancellationRequested(),E&&d.target.previewId){let _=E.getInstance(d.target.previewId);if(r.operation.kind==="preview.destroy")E.markResourcesDeleted(_.id),E.transition(_.id,"destroyed",{operationId:r.operation.id,observedState:{reconciledResourceIds:E.listResources(_.id).map((T)=>T.providerResourceId),exactCommitSha:_.commitSha}});else{let T=t.store.getResource(_.resourceId)?.provider??"default";E.recordResource({previewId:_.id,provider:T,providerResourceId:_.stackName,kind:"stack",tags:{"ts-cloud:preview":_.id,"ts-cloud:project":_.projectId,"ts-cloud:expires-at":_.expiresAt},observedState:{command:c.command??null,exactCommitSha:_.commitSha}}),E.transition(_.id,"active",{operationId:r.operation.id,observedState:{url:_.url??null,stackName:_.stackName,exactCommitSha:_.commitSha,providerStatus:"deployed"}})}}if(n&&d.target.composeId){let _=n.get(d.target.composeId),T=typeof zT(r.operation.input).service==="string"?String(zT(r.operation.input).service):void 0,i=r.operation.kind==="compose.delete"?"deleted":r.operation.kind==="compose.stop"?"stopped":"running",h=n.transition(_.id,i,{operationId:r.operation.id,services:Object.values(_.manifest.spec.services).filter((R)=>!T||R.name===T).map((R)=>({name:R.name,status:i==="stopped"||i==="deleted"?"stopped":"running",replicas:i==="deleted"?0:R.replicas,healthyReplicas:i==="running"?R.replicas:0,observedState:{command:c.command??null,healthGatePassed:i==="running"}}))});if(i==="deleted")yC(t.store,h,zT(r.operation.input).removeVolumes===!0)}return r.checkpoint("finalize","Deployment command completed; persisting the terminal result."),{command:c.command??`cloud ${d.command.join(" ")}`,exitCode:c.exitCode,environment:d.target.environment,resource:d.target.resource??null}};return Object.fromEntries(p1.map((r)=>[r,e]))}var qR=/^[a-z0-9][a-z0-9_.-]{1,62}$/,r$=/^0?[0-7]{3}$/,d$=["/","/boot","/dev","/etc","/proc","/root","/run","/sys","/var/run","/var/lib/docker","/var/lib/containers"],E$=["create","attach","detach","resize","snapshot","restore","delete","adopt","usage"],n$=(t)=>t&&typeof t==="object"&&!Array.isArray(t)?t:{};function c$(t){return Object.fromEntries(E$.map((e)=>[e,{supported:!1,reason:t}]))}function sR(t,e={}){let r=c$("This storage driver does not support the operation.");for(let d of t)r[d]={supported:!0};return{...r,...e}}function _$(t){if(!t.startsWith("/")||t.includes("\x00")||t.split("/").includes(".."))throw Error("Mount target must be an absolute normalized path without traversal.");let e=t.replace(/\/+$/,"")||"/";if(d$.some((r)=>e===r||e.startsWith(`${r}/`)))throw Error(`Mount target ${t} is a protected host or runtime path.`)}function T$(t){if(_$(t.targetPath),t.uid!=null&&(!Number.isInteger(t.uid)||t.uid<0))throw Error("Mount UID must be a non-negative integer.");if(t.gid!=null&&(!Number.isInteger(t.gid)||t.gid<0))throw Error("Mount GID must be a non-negative integer.");if(t.mode&&!r$.test(t.mode))throw Error("Mount mode must be a three or four digit octal value.");if(t.propagation&&!["private","rprivate","shared","rshared","slave","rslave"].includes(t.propagation))throw Error("Unsupported mount propagation mode.")}class oR{store;drivers;now;queue;constructor(t,e,r,d=()=>new Date){this.store=t;this.drivers=e;this.now=d;this.queue=r??new gt(t.controlPlane)}driver(t,e){let r=this.drivers.find((d)=>d.provider===t&&d.type===e);if(!r)throw Error(`No ${t} ${e} volume driver is configured.`);return r}capability(t,e){let r=t.capabilities[e];if(!r?.supported)throw Error(r?.reason??`${e} is unsupported for this volume.`)}queueMutation(t,e,r,d,E){return this.queue.enqueue({projectId:t.projectId,environmentId:t.environmentId,resourceId:E??t.resourceId,actorId:d,kind:e,idempotencyKey:`${e}:${t.id}:v${t.version}:${JSON.stringify(r)}`,correlationId:`volume:${t.id}`,input:{volumeId:t.id,...r},lockKey:E?`resource:${E}`:`volume:${t.id}`,providerKey:t.provider,maxAttempts:3,retryClasses:["network","provider_throttled","provider_unavailable"],resumePolicy:"fail",cancellationMode:"provider_non_cancellable",retentionDays:365}).operation}create(t){if(!qR.test(t.name))throw Error("Volume names must be 2-63 lowercase letters, numbers, dots, dashes, or underscores.");if(t.capacityBytes!=null&&(!Number.isSafeInteger(t.capacityBytes)||t.capacityBytes<=0))throw Error("Volume capacity must be a positive byte count.");let e=this.store.controlPlane.getProject(t.projectId),r=t.environmentId?this.store.controlPlane.listEnvironments(t.projectId).find((i)=>i.id===t.environmentId):void 0,d=t.resourceId?this.store.controlPlane.getResource(t.resourceId):void 0;if(!e||e.organizationId!==t.organizationId)throw Error("Volume project does not belong to the organization.");if(t.environmentId&&!r)throw Error("Volume environment does not belong to the project.");if(d&&(d.projectId!==t.projectId||d.environmentId!==t.environmentId||d.kind!=="volume"))throw Error("Volume resource does not belong to the selected scope.");let E=d??this.store.controlPlane.createResource({projectId:t.projectId,environmentId:t.environmentId,kind:"volume",slug:t.name,name:t.name,provider:t.provider,desiredState:{type:t.type,capacityBytes:t.capacityBytes??null,filesystem:t.filesystem??null,encrypted:!!t.encrypted}}),n=this.driver(t.provider,t.type),c=n.capabilities(),_=this.store.create({organizationId:t.organizationId,projectId:t.projectId,environmentId:t.environmentId,resourceId:E.id,name:t.name,provider:t.provider,type:t.type,status:"pending",capacityBytes:t.capacityBytes,filesystem:t.filesystem,encrypted:!!t.encrypted,capabilities:c,desiredState:t.desiredState??{},observedState:{}}),T=this.queueMutation(_,"volume.create",{},t.actorId);return this.store.audit({organizationId:_.organizationId,projectId:_.projectId,environmentId:_.environmentId,actorId:t.actorId,type:"volume.create.queued",volumeId:_.id,payload:{name:_.name,type:_.type}}),{volume:_,operation:T}}attach(t,e){let r=this.store.get(t);if(!r)throw Error("Volume was not found.");this.capability(r,"attach"),T$(e);let d=this.store.controlPlane.getResource(e.resourceId);if(!d||d.projectId!==r.projectId||d.environmentId!==r.environmentId)throw Error("Cross-project or cross-environment volume attachments are forbidden.");let E=this.store.upsertAttachment({volumeId:t,resourceId:e.resourceId,targetPath:e.targetPath,readOnly:!!e.readOnly,uid:e.uid,gid:e.gid,mode:e.mode,propagation:e.propagation??"private",driverOptions:e.driverOptions??{},desiredState:"attached",observedState:"pending"}),n=this.queueMutation(r,"volume.attach",{attachmentId:E.id},e.actorId,e.resourceId);return this.store.updateAttachment(E.id,{operationId:n.id}),this.store.update(r.id,r.version,{status:"attaching"}),this.store.audit({organizationId:r.organizationId,projectId:r.projectId,environmentId:r.environmentId,actorId:e.actorId,type:"volume.attach.queued",volumeId:t,payload:{resourceId:e.resourceId,targetPath:e.targetPath}}),{volume:this.store.get(r.id),attachment:this.store.attachment(E.id),operation:n}}detach(t,e,r={}){let d=this.store.get(t),E=this.store.attachment(e);if(!d||!E||E.volumeId!==t)throw Error("Volume attachment was not found.");if(this.capability(d,"detach"),E.observedState==="attached"&&(!r.drained||!r.unmounted))throw Error("Detach requires completed workload drain and filesystem unmount checkpoints.");if(r.force&&r.confirmation!==`detach ${d.name}`)throw Error(`Force detach requires confirmation: detach ${d.name}`);let n=this.store.updateAttachment(e,{desiredState:"detached"}),c=this.queueMutation(d,"volume.detach",{attachmentId:e,force:!!r.force},r.actorId,E.resourceId);return this.store.updateAttachment(e,{operationId:c.id}),this.store.update(d.id,d.version,{status:"detaching"}),{volume:this.store.get(t),attachment:n,operation:c}}resize(t,e,r={}){let d=this.store.get(t);if(!d)throw Error("Volume was not found.");if(this.capability(d,"resize"),!Number.isSafeInteger(e)||e<=0)throw Error("Volume capacity must be a positive byte count.");if(d.capacityBytes!=null&&e<d.capacityBytes)throw Error("Volume shrinking is not supported because it can corrupt data.");let E=d.capabilities.resize;if(E.minimumBytes&&e<E.minimumBytes)throw Error(`Minimum supported capacity is ${E.minimumBytes} bytes.`);if(E.maximumBytes&&e>E.maximumBytes)throw Error(`Maximum supported capacity is ${E.maximumBytes} bytes.`);if(E.online===!1&&!r.drained)throw Error("This resize requires a completed workload drain checkpoint.");let n=this.store.update(t,d.version,{status:"resizing",desiredState:{...d.desiredState,capacityBytes:e}}),c=this.queueMutation(n,"volume.resize",{capacityBytes:e},r.actorId);return{volume:n,operation:c}}snapshot(t,e={}){let r=this.store.get(t);if(!r)throw Error("Volume was not found.");this.capability(r,"snapshot");let d=this.store.createSnapshot({volumeId:t,name:e.name??`${r.name}-${this.now().toISOString().replace(/[:.]/g,"-")}`,status:"pending",encrypted:r.encrypted,metadata:{}}),E=this.store.update(t,r.version,{status:"snapshotting"}),n=this.queueMutation(E,"volume.snapshot",{snapshotId:d.id},e.actorId);return{volume:E,snapshot:d,operation:n}}restore(t,e){let r=this.store.snapshot(t),d=r?this.store.get(r.volumeId):void 0;if(!r||!d||r.status!=="available")throw Error("An available volume snapshot is required for restore.");if(this.capability(d,"restore"),!qR.test(e.name))throw Error("Restored volume names must be 2-63 lowercase letters, numbers, dots, dashes, or underscores.");let E=this.store.controlPlane.createResource({projectId:d.projectId,environmentId:d.environmentId,kind:"volume",slug:e.name,name:e.name,provider:d.provider,desiredState:{restoreFromSnapshotId:r.id}}),n=this.store.create({organizationId:d.organizationId,projectId:d.projectId,environmentId:d.environmentId,resourceId:E.id,name:e.name,provider:d.provider,type:d.type,status:"pending",capacityBytes:r.sizeBytes??d.capacityBytes,filesystem:d.filesystem,encrypted:r.encrypted,capabilities:d.capabilities,desiredState:{restoreFromSnapshotId:r.id,sourceVolumeId:d.id},observedState:{}}),c=this.queueMutation(n,"volume.restore",{snapshotId:r.id,sourceVolumeId:d.id},e.actorId);return{volume:n,snapshot:r,operation:c}}delete(t,e){let r=this.store.get(t);if(!r)throw Error("Volume was not found.");this.capability(r,"delete");let d=this.store.attachments(t).filter((_)=>_.desiredState==="attached"||_.observedState==="attached");if(d.length)throw Error(`Detach ${d.length} active consumer(s) before deleting this volume.`);if(!e.recentAuthAt||this.now().getTime()-new Date(e.recentAuthAt).getTime()>900000)throw Error("Volume deletion requires authentication verified within the last 15 minutes.");if(e.confirmation!==r.name)throw Error(`Type ${r.name} to confirm permanent volume deletion.`);if(!(r.lastBackupAt&&this.now().getTime()-new Date(r.lastBackupAt).getTime()<=86400000)&&(!e.backupOverride||e.backupOverrideConfirmation!==`delete without backup ${r.name}`))throw Error(`A verified backup from the last 24 hours is required, or confirm: delete without backup ${r.name}`);let n=this.store.update(t,r.version,{status:"deleting"}),c=this.queueMutation(n,"volume.delete",{backupOverride:!!e.backupOverride},e.actorId);return{volume:n,operation:c}}async discover(t){let e=new Set;for(let r of this.drivers)for(let d of await r.discover(t.projectId,t.environmentId)){let E=this.store.list({projectId:t.projectId,environmentId:t.environmentId}).find((c)=>c.provider===r.provider&&c.providerId===d.providerId);if(E){e.add(E.id),this.store.update(E.id,E.version,{capacityBytes:d.capacityBytes,usedBytes:d.usedBytes,filesystem:d.filesystem,encrypted:d.encrypted??E.encrypted,observedState:d.raw??{},status:E.status==="orphaned"?"available":E.status,orphanedAt:void 0});continue}let n=this.store.create({organizationId:t.organizationId,projectId:t.projectId,environmentId:t.environmentId,name:`orphan-${d.providerId}`.toLowerCase().replace(/[^a-z0-9_.-]/g,"-").slice(0,63),provider:r.provider,providerId:d.providerId,type:r.type,status:"orphaned",capacityBytes:d.capacityBytes,usedBytes:d.usedBytes,filesystem:d.filesystem,encrypted:!!d.encrypted,capabilities:r.capabilities(),desiredState:{},observedState:d.raw??{},orphanedAt:this.now().toISOString()});e.add(n.id)}return this.store.list({projectId:t.projectId,environmentId:t.environmentId})}adopt(t,e){let r=this.store.get(t);if(!r||r.status!=="orphaned")throw Error("Only discovered orphan volumes can be adopted.");if(!qR.test(e.name))throw Error("Volume names must be 2-63 lowercase letters, numbers, dots, dashes, or underscores.");let d=this.store.update(t,r.version,{name:e.name,status:"available",adoptedAt:this.now().toISOString(),orphanedAt:void 0});return this.store.audit({organizationId:r.organizationId,projectId:r.projectId,environmentId:r.environmentId,actorId:e.actorId,type:"volume.adopted",volumeId:t,payload:{providerId:r.providerId??null}}),d}}function i$(t){let e=n$(t.input);if(typeof e.volumeId!=="string")throw Error("Queued volume operation is missing its volume identity.");return{volumeId:e.volumeId,sourceVolumeId:typeof e.sourceVolumeId==="string"?e.sourceVolumeId:void 0,attachmentId:typeof e.attachmentId==="string"?e.attachmentId:void 0,snapshotId:typeof e.snapshotId==="string"?e.snapshotId:void 0,capacityBytes:typeof e.capacityBytes==="number"?e.capacityBytes:void 0,force:e.force===!0}}function XC(t,e){let r=(E)=>{let n=e.find((c)=>c.provider===E.provider&&c.type===E.type);if(!n)throw Error(`No ${E.provider} ${E.type} volume driver is configured.`);return n},d=async(E)=>{let n=i$(E.operation),c=t.get(n.volumeId);if(!c)throw Error("Queued volume was not found.");let _=r(c);E.checkpoint("preflight","Validating persistent volume identity and capabilities."),E.throwIfCancellationRequested();let T;if(E.operation.kind==="volume.create")T=await _.create(c),t.update(c.id,c.version,{providerId:T.providerId,capacityBytes:T.capacityBytes??c.capacityBytes,usedBytes:T.usedBytes,filesystem:T.filesystem??c.filesystem,encrypted:T.encrypted??c.encrypted,observedState:T.raw??{},status:"available"});else if(E.operation.kind==="volume.attach"){let i=n.attachmentId?t.attachment(n.attachmentId):void 0;if(!i)throw Error("Queued volume attachment was not found.");await _.attach(c,i),t.updateAttachment(i.id,{observedState:"attached",lastError:void 0}),t.update(c.id,c.version,{status:"attached"})}else if(E.operation.kind==="volume.detach"){let i=n.attachmentId?t.attachment(n.attachmentId):void 0;if(!i)throw Error("Queued volume attachment was not found.");await _.detach(c,i,{force:n.force}),t.updateAttachment(i.id,{observedState:"detached",lastError:void 0});let h=t.attachments(c.id).some((R)=>R.id!==i.id&&R.observedState==="attached");t.update(c.id,c.version,{status:h?"attached":"available"})}else if(E.operation.kind==="volume.resize"){if(!n.capacityBytes)throw Error("Queued volume resize is missing its capacity.");T=await _.resize(c,n.capacityBytes),t.update(c.id,c.version,{capacityBytes:T.capacityBytes??n.capacityBytes,usedBytes:T.usedBytes??c.usedBytes,observedState:T.raw??c.observedState,status:t.attachments(c.id).some((i)=>i.observedState==="attached")?"attached":"available"})}else if(E.operation.kind==="volume.snapshot"){let i=n.snapshotId?t.snapshot(n.snapshotId):void 0;if(!i)throw Error("Queued volume snapshot was not found.");let h=await _.snapshot(c,i);t.updateSnapshot(i.id,{...h,status:"available"}),t.update(c.id,c.version,{status:t.attachments(c.id).some((R)=>R.observedState==="attached")?"attached":"available",lastBackupAt:new Date().toISOString()})}else if(E.operation.kind==="volume.restore"){let i=n.snapshotId?t.snapshot(n.snapshotId):void 0,h=n.sourceVolumeId?t.get(n.sourceVolumeId):void 0;if(!i||!h)throw Error("Queued volume restore source was not found.");T=await _.restore(h,i,c),t.update(c.id,c.version,{providerId:T.providerId,capacityBytes:T.capacityBytes??c.capacityBytes,usedBytes:T.usedBytes,filesystem:T.filesystem??c.filesystem,encrypted:T.encrypted??c.encrypted,observedState:T.raw??{},status:"available"})}else if(E.operation.kind==="volume.delete")await _.delete(c),t.update(c.id,c.version,{status:"deleted",deletedAt:new Date().toISOString()});return E.checkpoint("finalize","Persisted observed volume state."),{volumeId:c.id,status:t.get(c.id)?.status??"deleted"}};return Object.fromEntries(["volume.create","volume.attach","volume.detach","volume.resize","volume.snapshot","volume.restore","volume.delete"].map((E)=>[E,d]))}var L$=async(t)=>{let e=Bun.spawn(["docker",...t],{stdout:"pipe",stderr:"pipe"}),[r,d,E]=await Promise.all([e.exited,new Response(e.stdout).text(),new Response(e.stderr).text()]);return{code:r,stdout:d,stderr:E}},In=/^[A-Za-z0-9][A-Za-z0-9_.-]{1,127}$/;class kc{command;provider="docker";type="docker";constructor(t=L$){this.command=t}capabilities(){return sR(["create","attach","detach","delete","adopt","usage"],{resize:{supported:!1,reason:"Docker named volumes do not expose a portable capacity resize operation."},snapshot:{supported:!1,reason:"Attach a volume backup policy to create verified recovery points."},restore:{supported:!1,reason:"Restore this volume from its verified backup recovery point."}})}async run(t,e=!1){let r=await this.command(t);if(r.code!==0&&!e)throw Error(`Docker volume command failed: ${r.stderr.trim()||r.code}`);return r.stdout}async inspect(t){let e=await this.run(["volume","inspect",t],!0);if(!e.trim())return;let r;try{r=JSON.parse(e)[0]}catch{return}return{providerId:String(r.Name??t),raw:{driver:String(r.Driver??"local"),mountpoint:String(r.Mountpoint??""),labels:r.Labels??{}}}}async discover(t,e){let r=await this.run(["volume","ls","--format","{{.Name}}"]),d=[];for(let E of r.split(`
|
|
5493
5493
|
`).map((n)=>n.trim()).filter(In.test.bind(In))){let n=await this.inspect(E);if(n)d.push(n)}return d}async create(t){let e=typeof t.desiredState.nativeName==="string"?t.desiredState.nativeName:t.name;if(!In.test(e))throw Error("Docker volume name is invalid.");return await this.run(["volume","create","--label",`ts-cloud.volume=${t.id}`,"--label",`ts-cloud.project=${t.projectId}`,e]),await this.inspect(e)??{providerId:e}}async attach(t,e){}async detach(t,e){}async resize(){throw Error(this.capabilities().resize.reason)}async snapshot(){throw Error(this.capabilities().snapshot.reason)}async restore(t,e,r){throw Error(this.capabilities().restore.reason)}async delete(t){if(!t.providerId||!In.test(t.providerId))throw Error("Docker volume provider identity is missing or invalid.");await this.run(["volume","rm",t.providerId])}async usage(t){let e=await this.run(["system","df","-v","--format","{{json .}}"],!0),r=e.split(`
|
|
5494
|
-
`).find((d)=>d.includes(`"Name":"${t.providerId}"`));if(!r)return{};try{let d=JSON.parse(r);return{usedBytes:typeof d.Size==="number"?d.Size:void 0}}catch{return{}}}}class pR{provider="server";type="server_path";root;constructor(t){this.root=aC(t)}capabilities(){return sR(["create","attach","detach","delete","adopt","usage"],{resize:{supported:!1,reason:"Server paths use the capacity of their containing filesystem."},snapshot:{supported:!1,reason:"Attach a filesystem backup policy for verified recovery points."},restore:{supported:!1,reason:"Restore a filesystem recovery point into a new managed path."}})}path(t){if(!In.test(t))throw Error("Server path volume name is invalid.");let e=aC(this.root,t);if(!e.startsWith(`${this.root}${A$}`)||N$(e)!==t)throw Error("Server path escaped the managed volume root.");return e}async discover(t,e){return await mR(this.root,{recursive:!0,mode:488}),(await h$(this.root,{withFileTypes:!0})).filter((d)=>d.isDirectory()&&In.test(d.name)).map((d)=>({providerId:d.name,raw:{path:this.path(d.name)}}))}async create(t){let e=typeof t.desiredState.nativeName==="string"?t.desiredState.nativeName:t.name,r=this.path(e);return await mR(this.root,{recursive:!0,mode:488}),await mR(r,{recursive:!1,mode:488}),{providerId:e,filesystem:"host",raw:{path:r}}}async attach(t,e){}async detach(t,e){}async resize(){throw Error(this.capabilities().resize.reason)}async snapshot(){throw Error(this.capabilities().snapshot.reason)}async restore(t,e,r){throw Error(this.capabilities().restore.reason)}async delete(t){if(!t.providerId)throw Error("Server path provider identity is unavailable.");await R$(this.path(t.providerId),{recursive:!0,force:!1})}async usage(t){if(!t.providerId)return{};return{usedBytes:(await S$(this.path(t.providerId))).size}}}var ye=(t)=>t==null?void 0:String(t),bc=(t,e)=>{try{return JSON.parse(String(t))}catch{return e}},eS=(t)=>Number(t)===1,Dn=(t)=>t().toISOString();function PC(t){return{id:String(t.id),organizationId:String(t.organization_id),projectId:String(t.project_id),environmentId:ye(t.environment_id),resourceId:ye(t.resource_id),name:String(t.name),provider:String(t.provider),providerId:ye(t.provider_id),type:String(t.type),status:String(t.status),capacityBytes:t.capacity_bytes==null?void 0:Number(t.capacity_bytes),usedBytes:t.used_bytes==null?void 0:Number(t.used_bytes),filesystem:ye(t.filesystem),encrypted:eS(t.encrypted),capabilities:bc(t.capabilities,{}),desiredState:bc(t.desired_state,{}),observedState:bc(t.observed_state,{}),backupPolicyId:ye(t.backup_policy_id),lastBackupAt:ye(t.last_backup_at),orphanedAt:ye(t.orphaned_at),adoptedAt:ye(t.adopted_at),version:Number(t.version),createdAt:String(t.created_at),updatedAt:String(t.updated_at),deletedAt:ye(t.deleted_at)}}function tS(t){return{id:String(t.id),volumeId:String(t.volume_id),resourceId:String(t.resource_id),targetPath:String(t.target_path),readOnly:eS(t.read_only),uid:t.uid==null?void 0:Number(t.uid),gid:t.gid==null?void 0:Number(t.gid),mode:ye(t.mode),propagation:String(t.propagation),driverOptions:bc(t.driver_options,{}),desiredState:String(t.desired_state),observedState:String(t.observed_state),operationId:ye(t.operation_id),lastError:ye(t.last_error),version:Number(t.version),createdAt:String(t.created_at),updatedAt:String(t.updated_at)}}function jC(t){return{id:String(t.id),volumeId:String(t.volume_id),recoveryPointId:ye(t.recovery_point_id),providerId:ye(t.provider_id),name:String(t.name),status:String(t.status),sizeBytes:t.size_bytes==null?void 0:Number(t.size_bytes),encrypted:eS(t.encrypted),checksum:ye(t.checksum),metadata:bc(t.metadata,{}),createdAt:String(t.created_at),updatedAt:String(t.updated_at),deletedAt:ye(t.deleted_at)}}class fn{controlPlane;now;id;constructor(t,e=()=>new Date,r=()=>crypto.randomUUID()){this.controlPlane=t;this.now=e;this.id=r}get(t){let e=this.controlPlane.database.query("SELECT * FROM persistent_volumes WHERE id=?").get(t);return e?PC(e):void 0}list(t){let e=["project_id=?"],r=[t.projectId];if(t.environmentId)e.push("environment_id=?"),r.push(t.environmentId);if(!t.includeDeleted)e.push("deleted_at IS NULL");return this.controlPlane.database.query(`SELECT * FROM persistent_volumes WHERE ${e.join(" AND ")} ORDER BY name`).all(...r).map(PC)}create(t){let e=Dn(this.now),r=t.id??this.id();return this.controlPlane.database.run("INSERT INTO persistent_volumes (id,organization_id,project_id,environment_id,resource_id,name,provider,provider_id,type,status,capacity_bytes,used_bytes,filesystem,encrypted,capabilities,desired_state,observed_state,backup_policy_id,last_backup_at,orphaned_at,adopted_at,created_at,updated_at,deleted_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",[r,t.organizationId,t.projectId,t.environmentId??null,t.resourceId??null,t.name,t.provider,t.providerId??null,t.type,t.status,t.capacityBytes??null,t.usedBytes??null,t.filesystem??null,t.encrypted?1:0,JSON.stringify(t.capabilities),JSON.stringify(t.desiredState),JSON.stringify(t.observedState),t.backupPolicyId??null,t.lastBackupAt??null,t.orphanedAt??null,t.adoptedAt??null,e,e,t.deletedAt??null]),this.get(r)}update(t,e,r){let d=this.get(t);if(!d||d.version!==e)throw Error("Volume changed before this operation could be applied.");let E={...d,...r,updatedAt:Dn(this.now)};if(this.controlPlane.database.run("UPDATE persistent_volumes SET environment_id=?,resource_id=?,name=?,provider=?,provider_id=?,type=?,status=?,capacity_bytes=?,used_bytes=?,filesystem=?,encrypted=?,capabilities=?,desired_state=?,observed_state=?,backup_policy_id=?,last_backup_at=?,orphaned_at=?,adopted_at=?,deleted_at=?,version=version+1,updated_at=? WHERE id=? AND version=?",[E.environmentId??null,E.resourceId??null,E.name,E.provider,E.providerId??null,E.type,E.status,E.capacityBytes??null,E.usedBytes??null,E.filesystem??null,E.encrypted?1:0,JSON.stringify(E.capabilities),JSON.stringify(E.desiredState),JSON.stringify(E.observedState),E.backupPolicyId??null,E.lastBackupAt??null,E.orphanedAt??null,E.adoptedAt??null,E.deletedAt??null,E.updatedAt,t,e]).changes!==1)throw Error("Volume changed before this operation could be applied.");return this.get(t)}attachments(t){return this.controlPlane.database.query("SELECT * FROM volume_attachments WHERE volume_id=? ORDER BY target_path").all(t).map(tS)}attachment(t){let e=this.controlPlane.database.query("SELECT * FROM volume_attachments WHERE id=?").get(t);return e?tS(e):void 0}upsertAttachment(t){let e=this.controlPlane.database.query("SELECT * FROM volume_attachments WHERE volume_id=? AND resource_id=? AND target_path=?").get(t.volumeId,t.resourceId,t.targetPath),r=Dn(this.now);if(e){let E=tS(e);return this.controlPlane.database.run("UPDATE volume_attachments SET read_only=?,uid=?,gid=?,mode=?,propagation=?,driver_options=?,desired_state=?,observed_state=?,operation_id=?,last_error=?,version=version+1,updated_at=? WHERE id=?",[t.readOnly?1:0,t.uid??null,t.gid??null,t.mode??null,t.propagation,JSON.stringify(t.driverOptions),t.desiredState,t.observedState,t.operationId??null,t.lastError??null,r,E.id]),this.attachment(E.id)}let d=t.id??this.id();return this.controlPlane.database.run("INSERT INTO volume_attachments (id,volume_id,resource_id,target_path,read_only,uid,gid,mode,propagation,driver_options,desired_state,observed_state,operation_id,last_error,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",[d,t.volumeId,t.resourceId,t.targetPath,t.readOnly?1:0,t.uid??null,t.gid??null,t.mode??null,t.propagation,JSON.stringify(t.driverOptions),t.desiredState,t.observedState,t.operationId??null,t.lastError??null,r,r]),this.attachment(d)}updateAttachment(t,e){let r=this.attachment(t);if(!r)throw Error("Volume attachment was not found.");let d={...r,...e};return this.controlPlane.database.run("UPDATE volume_attachments SET desired_state=?,observed_state=?,operation_id=?,last_error=?,version=version+1,updated_at=? WHERE id=?",[d.desiredState,d.observedState,d.operationId??null,d.lastError??null,Dn(this.now),t]),this.attachment(t)}snapshots(t){return this.controlPlane.database.query("SELECT * FROM volume_snapshots WHERE volume_id=? AND deleted_at IS NULL ORDER BY created_at DESC").all(t).map(jC)}snapshot(t){let e=this.controlPlane.database.query("SELECT * FROM volume_snapshots WHERE id=?").get(t);return e?jC(e):void 0}createSnapshot(t){let e=t.id??this.id(),r=Dn(this.now);return this.controlPlane.database.run("INSERT INTO volume_snapshots (id,volume_id,recovery_point_id,provider_id,name,status,size_bytes,encrypted,checksum,metadata,created_at,updated_at,deleted_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)",[e,t.volumeId,t.recoveryPointId??null,t.providerId??null,t.name,t.status,t.sizeBytes??null,t.encrypted?1:0,t.checksum??null,JSON.stringify(t.metadata),r,r,t.deletedAt??null]),this.snapshot(e)}updateSnapshot(t,e){let r=this.snapshot(t);if(!r)throw Error("Volume snapshot was not found.");let d={...r,...e};return this.controlPlane.database.run("UPDATE volume_snapshots SET recovery_point_id=?,provider_id=?,name=?,status=?,size_bytes=?,encrypted=?,checksum=?,metadata=?,deleted_at=?,updated_at=? WHERE id=?",[d.recoveryPointId??null,d.providerId??null,d.name,d.status,d.sizeBytes??null,d.encrypted?1:0,d.checksum??null,JSON.stringify(d.metadata),d.deletedAt??null,Dn(this.now),t]),this.snapshot(t)}inventory(t,e){return this.list({projectId:t,environmentId:e}).map((r)=>{let d=this.attachments(r.id),E=this.snapshots(r.id),n=r.lastBackupAt?Date.now()-new Date(r.lastBackupAt).getTime():1/0;return{...r,attachments:d,snapshots:E,orphaned:r.status==="orphaned",usagePercent:r.capacityBytes&&r.usedBytes!=null?Math.round(r.usedBytes/r.capacityBytes*1000)/10:void 0,backupState:r.backupPolicyId?n<=86400000?"protected":"stale":"unprotected"}})}audit(t){this.controlPlane.appendEvent({organizationId:t.organizationId,projectId:t.projectId,resourceId:this.get(t.volumeId)?.resourceId,actorId:t.actorId,type:t.type,level:"warning",payload:{volumeId:t.volumeId,environmentId:t.environmentId??null,...t.payload}})}}function rS(t,e){let r=t.getProject(e.projectId);if(!r?.organizationId)return;let d=new fn(t),E=new kc,n=new Set(e.manifest.spec.volumes),c=new Set;for(let _ of n){let T=`${e.slug}-${_}`.toLowerCase().replace(/[^a-z0-9_.-]/g,"-").slice(0,63),i=d.list({projectId:e.projectId,environmentId:e.environmentId,includeDeleted:!0}).find((A)=>A.name===T);if(i?.deletedAt)throw Error(`Compose volume ${T} was permanently deleted; rename it before redeploying.`);let h=i?.resourceId?t.getResource(i.resourceId):t.createResource({projectId:e.projectId,environmentId:e.environmentId,kind:"volume",slug:T,name:T,provider:"docker",providerId:T,desiredState:{composeApplicationId:e.id,composeVolume:_}}),R=i??d.create({organizationId:r.organizationId,projectId:e.projectId,environmentId:e.environmentId,resourceId:h?.id,name:T,provider:"docker",providerId:T,type:"docker",status:"available",encrypted:!1,capabilities:E.capabilities(),desiredState:{composeApplicationId:e.id,composeVolume:_,nativeName:T},observedState:{}});c.add(R.id);let N=new Map;for(let A of Object.values(e.manifest.spec.services))for(let u of A.volumes.filter((f)=>f.source===_)){let f=N.get(u.target)??[];f.push(A.name),N.set(u.target,f),d.upsertAttachment({volumeId:R.id,resourceId:e.resourceId,targetPath:u.target,readOnly:u.readOnly,propagation:"private",driverOptions:{composeServices:f},desiredState:"attached",observedState:"pending"})}}for(let _ of d.list({projectId:e.projectId,environmentId:e.environmentId}).filter((T)=>T.desiredState.composeApplicationId===e.id&&!c.has(T.id)))for(let T of d.attachments(_.id))d.updateAttachment(T.id,{desiredState:"detached"})}function yC(t,e,r){let d=new fn(t);for(let E of d.list({projectId:e.projectId,environmentId:e.environmentId}).filter((n)=>n.desiredState.composeApplicationId===e.id)){for(let n of d.attachments(E.id))d.updateAttachment(n.id,{desiredState:"detached",observedState:"detached"});d.update(E.id,E.version,{status:r?"deleted":"available",deletedAt:r?new Date().toISOString():void 0})}}function Un(t){return typeof t==="string"&&t?t:void 0}function dS(t,e){try{return JSON.parse(String(t))}catch{return e}}function FT(t){return{id:String(t.id),resourceId:String(t.resource_id),projectId:String(t.project_id),environmentId:String(t.environment_id),name:String(t.name),slug:String(t.slug),status:String(t.status),sourceKind:String(t.source_kind),sourceHash:String(t.source_hash),redactedSource:String(t.redacted_source),manifest:dS(t.manifest,{}),diagnostics:dS(t.diagnostics,[]),templateId:Un(t.template_id),templateVersion:Un(t.template_version),latestOperationId:Un(t.latest_operation_id),createdByActorId:Un(t.created_by_actor_id),version:Number(t.version),createdAt:String(t.created_at),updatedAt:String(t.updated_at),deletedAt:Un(t.deleted_at)}}function u$(t){return{applicationId:String(t.application_id),serviceName:String(t.service_name),status:String(t.status),replicas:Number(t.replicas),healthyReplicas:Number(t.healthy_replicas),latestOperationId:Un(t.latest_operation_id),observedState:dS(t.observed_state,{}),updatedAt:String(t.updated_at)}}class DE{controlPlane;now;id;constructor(t,e={}){this.controlPlane=t;this.now=e.now??(()=>new Date),this.id=e.id??(()=>crypto.randomUUID())}persist(t,e){if(!t.valid)throw Error(`Compose definition contains ${t.diagnostics.filter((u)=>u.severity==="error").length} blocking diagnostic(s)`);let{projectId:r,environmentId:d,name:E,slug:n}=t.manifest.metadata;if(!this.controlPlane.listEnvironments(r).find((u)=>u.id===d))throw Error("Compose project and environment scope was not found");let _=this.getBySlug(r,d,n),T=this.now().toISOString(),i=JSON.stringify(t.manifest),h=JSON.stringify(ut(t.diagnostics));if(_){if(_.status==="deleted")throw Error("A deleted Compose application cannot be overwritten; choose another slug");let u=this.controlPlane.getResource(_.resourceId);if(!u)throw Error("Compose application resource was not found");this.controlPlane.updateResource(u.id,u.version,{name:E,provider:u.provider,providerId:u.providerId,desiredState:t.manifest,discoveredState:u.discoveredState,metadata:{sourceKind:e.sourceKind,templateId:e.templateId??null,templateVersion:e.templateVersion??null,sourceHash:t.sourceHash}}),this.controlPlane.database.run("UPDATE compose_applications SET name=?, status='ready', source_kind=?, source_hash=?, redacted_source=?, manifest=?, diagnostics=?, template_id=?, template_version=?, version=version+1, updated_at=? WHERE id=?",[E,e.sourceKind,t.sourceHash,t.redactedSource,i,h,e.templateId??null,e.templateVersion??null,T,_.id]);let f=Object.keys(t.manifest.spec.services);if(f.length)this.controlPlane.database.run(`DELETE FROM compose_service_states WHERE application_id=? AND service_name NOT IN (${f.map(()=>"?").join(",")})`,[_.id,...f]);for(let I of Object.values(t.manifest.spec.services))this.controlPlane.database.run("INSERT INTO compose_service_states (application_id, service_name, status, replicas, healthy_replicas, observed_state, updated_at) VALUES (?, ?, 'pending', ?, 0, '{}', ?) ON CONFLICT(application_id, service_name) DO UPDATE SET replicas=excluded.replicas, updated_at=excluded.updated_at",[_.id,I.name,I.replicas,T]);this.controlPlane.appendEvent({projectId:r,resourceId:_.resourceId,actorId:e.createdByActorId,type:"compose.application.updated",payload:{applicationId:_.id,sourceHash:t.sourceHash,diagnosticCount:t.diagnostics.length,templateId:e.templateId??null,templateVersion:e.templateVersion??null}});let w=this.get(_.id);return rS(this.controlPlane,w),w}let R=this.controlPlane.createResource({projectId:r,environmentId:d,kind:"compose_application",slug:n,name:E,desiredState:t.manifest,metadata:{sourceKind:e.sourceKind,templateId:e.templateId??null,templateVersion:e.templateVersion??null,sourceHash:t.sourceHash}}),N=this.id();this.controlPlane.database.run("INSERT INTO compose_applications (id, resource_id, project_id, environment_id, name, slug, status, source_kind, source_hash, redacted_source, manifest, diagnostics, template_id, template_version, created_by_actor_id, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, 'ready', ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",[N,R.id,r,d,E,n,e.sourceKind,t.sourceHash,t.redactedSource,i,h,e.templateId??null,e.templateVersion??null,e.createdByActorId??null,T,T]);for(let u of Object.values(t.manifest.spec.services))this.controlPlane.database.run("INSERT INTO compose_service_states (application_id, service_name, status, replicas, healthy_replicas, observed_state, updated_at) VALUES (?, ?, 'pending', ?, 0, '{}', ?)",[N,u.name,u.replicas,T]);this.controlPlane.appendEvent({projectId:r,resourceId:R.id,actorId:e.createdByActorId,type:"compose.application.created",payload:{applicationId:N,sourceHash:t.sourceHash,serviceNames:Object.keys(t.manifest.spec.services),templateId:e.templateId??null}});let A=this.get(N);return rS(this.controlPlane,A),A}import(t,e){let r=Gc(t,e);return{application:this.persist(r,{sourceKind:"compose",createdByActorId:e.createdByActorId}),parsed:r}}fromTemplate(t,e,r){let d=LC(t,e,r,r.version);return{application:this.persist(d,{sourceKind:"template",templateId:t,templateVersion:r.version??"1.0.0",createdByActorId:r.createdByActorId}),parsed:d}}preview(t,e){return Gc(t,e)}get(t){let e=this.controlPlane.database.query("SELECT * FROM compose_applications WHERE id=?").get(t);return e?FT(e):void 0}getByResource(t){let e=this.controlPlane.database.query("SELECT * FROM compose_applications WHERE resource_id=?").get(t);return e?FT(e):void 0}getBySlug(t,e,r){let d=this.controlPlane.database.query("SELECT * FROM compose_applications WHERE project_id=? AND environment_id=? AND slug=?").get(t,e,r);return d?FT(d):void 0}list(t={}){return this.controlPlane.database.query("SELECT * FROM compose_applications ORDER BY updated_at DESC").all().map(FT).filter((e)=>(!t.projectId||e.projectId===t.projectId)&&(!t.environmentId||e.environmentId===t.environmentId)&&(t.includeDeleted||e.status!=="deleted"))}services(t){return this.controlPlane.database.query("SELECT * FROM compose_service_states WHERE application_id=? ORDER BY service_name").all(t).map(u$)}transition(t,e,r={}){let d=this.get(t);if(!d)throw Error(`Compose application ${t} was not found`);let E=this.now().toISOString(),n=e==="deleted"?E:null;this.controlPlane.database.run("UPDATE compose_applications SET status=?, latest_operation_id=COALESCE(?, latest_operation_id), version=version+1, updated_at=?, deleted_at=? WHERE id=?",[e,r.operationId??null,E,n,t]);for(let c of r.services??[])if(d.manifest.spec.services[c.name])this.controlPlane.database.run("INSERT INTO compose_service_states (application_id, service_name, status, replicas, healthy_replicas, latest_operation_id, observed_state, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?) ON CONFLICT(application_id, service_name) DO UPDATE SET status=excluded.status, replicas=excluded.replicas, healthy_replicas=excluded.healthy_replicas, latest_operation_id=excluded.latest_operation_id, observed_state=excluded.observed_state, updated_at=excluded.updated_at",[t,c.name,c.status,c.replicas??d.manifest.spec.services[c.name].replicas,c.healthyReplicas??0,r.operationId??null,JSON.stringify(ut(c.observedState??{})),E]);return this.controlPlane.appendEvent({projectId:d.projectId,resourceId:d.resourceId,operationId:r.operationId,type:`compose.application.${e}`,level:e==="failed"||e==="degraded"?"error":"info",payload:{applicationId:t,error:r.error??null}}),this.get(t)}}class xc{controlPlane;applications;queue;constructor(t){this.controlPlane=t;this.applications=new DE(t),this.queue=new gt(t)}enqueue(t,e,r={}){if(t.status==="deleted")throw Error("Deleted Compose applications cannot be operated");if(r.service&&!t.manifest.spec.services[r.service])throw Error(`Compose service ${r.service} was not found`);if(e==="delete"){let E=r.removeVolumes?`${t.slug} delete volumes`:t.slug;if(r.confirmation!==E)throw Error(`Type ${E} to confirm ${r.removeVolumes?"persistent data removal":"stack deletion"}`)}if(e==="scale"&&(!r.service||!Number.isInteger(r.replicas)||r.replicas<0||r.replicas>100))throw Error("Scale requires a service and 0-100 replicas");let d=this.queue.enqueue({projectId:t.projectId,environmentId:t.environmentId,resourceId:t.resourceId,actorId:r.actorId,kind:`compose.${e}`,idempotencyKey:`compose:${t.id}:${e}:${r.service??"stack"}:${r.replicas??""}:${t.version}`,correlationId:`compose:${t.id}`,input:{applicationId:t.id,service:r.service??null,replicas:r.replicas??null,removeVolumes:!!r.removeVolumes},lockKey:`compose:${t.id}`,providerKey:this.controlPlane.getResource(t.resourceId)?.provider??"default",buildSlot:e==="deploy"||e==="redeploy",maxAttempts:3,retryClasses:["network","provider_throttled","provider_unavailable"],resumePolicy:"fail",cancellationMode:"provider_non_cancellable",retentionDays:90}).operation;return this.applications.transition(t.id,e==="delete"?"deleting":e==="stop"?"stopped":e==="start"?"deploying":e==="scale"?t.status:"deploying",{operationId:d.id}),d}}import{lstatSync as O$,readdirSync as C$,readFileSync as l$}from"node:fs";import{relative as I$,resolve as zC,sep as D$}from"node:path";function f$(t){return new Map(t.map((e)=>[e.path.replace(/^\.\//,"").replace(/\\/g,"/"),e]))}function fE(t,e,r){return{path:t,reason:e,weight:r}}function FC(t){try{return t?.content?JSON.parse(t.content):{}}catch{return{}}}function wn(t,e,r,d,E,n){return{framework:t,strategy:e,confidence:r,evidence:d,defaults:{build:E,runtime:{target:e==="static"?"serverless":e==="serverless"?"serverless":e==="dockerfile"||e==="prebuilt_image"?"container":"server",architecture:"x86_64",port:e==="static"||e==="serverless"?void 0:3000,healthCheck:e==="static"?void 0:{protocol:"http",path:"/health"}}},description:n}}function gn(t){let e=f$(t.slice(0,1e4)),r=[];if(e.has("Dockerfile"))r.push(wn("dockerfile","dockerfile",0.99,[fE("Dockerfile","A root Dockerfile defines an explicit reproducible build.",1)],{kind:"dockerfile",context:".",dockerfile:"Dockerfile"},"Build the repository with its Dockerfile and run the resulting OCI image."));let d=FC(e.get("composer.json"));if(e.has("artisan")&&d.require?.["laravel/framework"])r.push(wn("laravel","server",0.98,[fE("artisan","Laravel Artisan entrypoint is present.",0.45),fE("composer.json","Requires laravel/framework.",0.55)],{kind:"server",runtime:"php",runtimeVersion:"8.3",installCommand:"composer install --no-dev --prefer-dist --optimize-autoloader",buildCommand:"php artisan config:cache && php artisan route:cache && php artisan view:cache",startCommand:"php artisan serve --host=0.0.0.0 --port=$PORT"},"Install a production Composer tree, warm Laravel caches, and run the HTTP application."));else if(e.has("composer.json"))r.push(wn("php","server",0.82,[fE("composer.json","Composer metadata identifies a PHP application.",0.8)],{kind:"server",runtime:"php",runtimeVersion:"8.3",installCommand:"composer install --no-dev --prefer-dist --optimize-autoloader",startCommand:"php -S 0.0.0.0:$PORT -t public"},"Install Composer dependencies and run the configured PHP document root."));let E=FC(e.get("package.json"));if(e.has("package.json")){let n=e.has("bun.lock")||e.has("bun.lockb")||E.engines?.bun,c=n?"bun":"node",_=n?"bun":"node",T=[fE("package.json",`Defines ${E.scripts?.build?"build and ":""}${E.scripts?.start?"start ":""}scripts.`,0.55)];if(n)T.push(fE(e.has("bun.lock")?"bun.lock":e.has("bun.lockb")?"bun.lockb":"package.json","Pins the Bun package manager/runtime.",0.35));let i=!!(E.dependencies?.vite||E.devDependencies?.vite||E.dependencies?.["@stacksjs/bunpress"]||E.devDependencies?.["@stacksjs/bunpress"])&&!E.scripts?.start,h=i?{kind:"static",installCommand:`${c} install --frozen-lockfile`,buildCommand:`${c} run build`,publishDirectory:"dist"}:{kind:"server",runtime:c,installCommand:`${c} install --frozen-lockfile`,buildCommand:E.scripts?.build?`${c} run build`:void 0,startCommand:E.scripts?.start?`${c} run start`:c==="bun"?"bun run index.ts":"node index.js"};r.push(wn(_,h.kind,Math.min(0.94,T.reduce((R,N)=>R+N.weight,0)),T,h,i?"Install dependencies, build static assets, and publish the output directory.":`Install dependencies, build if configured, and start the ${c} server.`))}if(!r.length&&(e.has("index.html")||e.has("public/index.html")))r.push(wn("static","static",0.78,[fE(e.has("index.html")?"index.html":"public/index.html","A static HTML entrypoint is present.",0.78)],{kind:"static",publishDirectory:e.has("index.html")?".":"public"},"Publish the static directory without a runtime process."));if(!r.length)r.push(wn("unknown","buildpack",0.2,[],{kind:"buildpack",runtime:"node"},"No supported framework signature was conclusive; choose commands and runtime manually."));return r.sort((n,c)=>c.confidence-n.confidence||n.framework.localeCompare(c.framework))}function ES(t,e={}){let r=zC(t),d=e.maxFiles??1e4,E=e.maxContentBytes??262144,n=[],c=new Set(["Dockerfile","package.json","composer.json","index.html","public/index.html","bun.lock","bun.lockb","artisan"]),_=new Set([".git",".ts-cloud",".cache",".next",".nuxt",".output",".turbo",".bun","node_modules","vendor","pantry","dist","build","coverage"]),T=(i)=>{for(let h of C$(i).sort()){if(_.has(h))continue;let R=zC(i,h),N=I$(r,R).split(D$).join("/");if(!N||N.startsWith("../"))throw Error("Detection path escaped the application root");let A=O$(R);if(A.isSymbolicLink())throw Error(`Detection refuses symbolic links: ${N}`);if(A.isDirectory())T(R);else if(A.isFile()){if(n.length>=d)throw Error("Application file-count limit exceeded");let u={path:N,size:A.size};if(c.has(N)&&A.size<=E)u.content=l$(R,"utf8");n.push(u)}}};return T(r),n}function cS(t){if(Array.isArray(t))return`[${t.map(cS).join(",")}]`;if(t&&typeof t==="object")return`{${Object.entries(t).filter(([,e])=>e!==void 0).sort(([e],[r])=>e.localeCompare(r)).map(([e,r])=>`${JSON.stringify(e)}:${cS(r)}`).join(",")}}`;return JSON.stringify(t)??"null"}function qc(t){return!!t&&!t.startsWith("/")&&!t.split("/").includes("..")&&!/[\0\r\n]/.test(t)}function Ke(t,e,r,d){return{path:t,code:e,message:r,alternatives:d}}function nS(t){return JSON.parse(JSON.stringify(t))}function U$(t){let e=Object.fromEntries(Object.entries(t.environment??{}).map(([r,d])=>[r,typeof d==="string"?d:`\${${d.secretRef}}`]));if(t.build.kind==="prebuilt_image"||t.build.kind==="dockerfile")return nS({infrastructure:{containers:{[t.slug]:{source:t.source,build:t.build,port:t.runtime.port,cpu:t.runtime.cpu,memory:t.runtime.memoryMb,architecture:t.runtime.architecture,healthCheck:t.runtime.healthCheck,environment:e}}}});if(t.runtime.target==="serverless"||t.build.kind==="serverless")return nS({serverless:{apps:{[t.slug]:{source:t.source,build:t.build,architecture:t.runtime.architecture,environment:e,domain:t.domain}}}});return nS({sites:{[t.slug]:{source:t.source,build:t.build,port:t.runtime.port,architecture:t.runtime.architecture,healthCheck:t.runtime.healthCheck,env:e,domain:t.domain?.hostname}}})}function $r(t,e=[]){let r=[],d=(u)=>/(?:secret|token|password|passwd|private[_-]?key|api[_-]?key)/i.test(u),E=Object.fromEntries(Object.entries(t.environment??{}).map(([u,f])=>{if(typeof f==="string"&&d(u))return r.push(Ke(`environment.${u}`,"write_only_secret_required",`${u} must be supplied through the write-only secrets boundary.`)),[u,{secretRef:u}];return[u,f]})),n=t.build;if(t.build.kind==="dockerfile"&&t.build.buildArgs){let u=Object.fromEntries(Object.entries(t.build.buildArgs).map(([f,w])=>{if(d(f))return r.push(Ke(`build.buildArgs.${f}`,"write_only_build_secret_required",`${f} must be declared in secretNames instead of buildArgs.`)),[f,"[REDACTED]"];return[f,w]}));n={...t.build,buildArgs:u}}if(!/^[a-z0-9][a-z0-9-]{1,62}$/.test(t.slug))r.push(Ke("slug","invalid_slug","Slug must contain 2-63 lowercase letters, numbers, or hyphens."));if(!qc((t.source.kind==="git"?t.source.monorepoRoot:t.source.kind==="local"?t.source.root:".")??"."))r.push(Ke("source","unsafe_source_root","Source root must stay inside the source tree."));if(t.source.kind==="git"&&t.source.sparsePaths?.some((u)=>!qc(u)))r.push(Ke("source.sparsePaths","unsafe_sparse_path","Sparse checkout paths must stay inside the repository."));if(t.build.kind==="dockerfile"&&(!qc(t.build.context)||!qc(t.build.dockerfile)))r.push(Ke("build","unsafe_docker_path","Docker context and Dockerfile must stay inside the source tree."));if(t.build.kind==="static"&&!qc(t.build.publishDirectory))r.push(Ke("build.publishDirectory","invalid_publish_directory","A safe static publish directory is required."));if(t.build.kind==="server"&&!t.build.startCommand.trim())r.push(Ke("build.startCommand","missing_start_command","A server start command is required.",["Use static output","Use a Dockerfile"]));if(t.source.kind==="image"&&t.build.kind!=="prebuilt_image")r.push(Ke("build.kind","image_requires_prebuilt","An OCI image source must use the prebuilt-image strategy.",["Select prebuilt image"]));if(t.build.kind==="prebuilt_image"&&t.runtime.target!=="container")r.push(Ke("runtime.target","image_requires_container","Prebuilt images require the container runtime target.",["Select container target"]));if(t.runtime.target==="serverless"&&t.build.kind==="dockerfile")r.push(Ke("runtime.target","unsupported_serverless_dockerfile","Dockerfile builds currently target the container service path.",["Select container target","Select serverless package"]));if(t.runtime.port!==void 0&&(!Number.isInteger(t.runtime.port)||t.runtime.port<1||t.runtime.port>65535))r.push(Ke("runtime.port","invalid_port","Port must be an integer from 1 to 65535."));let c=t.runtime.healthCheck;if(c&&c.protocol!=="tcp"&&(!c.path||!c.path.startsWith("/")||/[\r\n]/.test(c.path)))r.push(Ke("runtime.healthCheck.path","invalid_health_path","HTTP health checks require a path beginning with /."));if(t.domain?.hostname&&(!/^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z]{2,63}$/i.test(t.domain.hostname)||t.domain.hostname.includes("..")))r.push(Ke("domain.hostname","invalid_domain","Domain must be a valid DNS hostname."));let _=Object.values(E).flatMap((u)=>typeof u==="object"?[u.secretRef]:[]),T=[...new Set([...t.requiredSecretNames??[],...t.build.kind==="dockerfile"?t.build.secretNames??[]:[],..._])].sort(),i=new Set(e),h=T.filter((u)=>!i.has(u)),R={apiVersion:"ts-cloud.dev/v1",kind:"Application",metadata:{name:t.name,slug:t.slug,projectId:t.projectId,environmentId:t.environmentId},spec:{source:t.source,build:n,runtime:t.runtime,environment:E,domain:t.domain}},N=[...new Set([t.source.kind==="git"?"git:read":t.source.kind==="image"?"registry:pull":t.source.kind==="artifact"?"artifact:inspect":"filesystem:read",t.runtime.target==="container"?"containers":t.runtime.target==="serverless"?"serverless":"servers",t.domain?"dns":""])].filter(Boolean).sort(),A=[...new Set([t.runtime.target,t.runtime.cpu?`${t.runtime.cpu} vCPU`:"",t.runtime.memoryMb?`${t.runtime.memoryMb} MB memory`:"",(t.runtime.minInstances??0)>0?`${t.runtime.minInstances} minimum instances`:"scales from zero where supported",t.domain?"managed DNS/TLS":""])].filter(Boolean);return{valid:r.length===0&&h.length===0,issues:r,missingSecrets:h,manifest:R,configPatch:U$({...t,build:n,environment:E}),capabilityRequirements:N,costDrivers:A,serializedManifest:`${cS(R)}
|
|
5495
|
-
`}}function BC(t){let e=t.replace(/\\/g,"/");return!!e&&!e.startsWith("/")&&!/^[A-Za-z]:\//.test(e)&&!e.split("/").includes("..")&&!/[\0\r\n]/.test(e)}function JC(t,e,r={}){let d=r.maxBytes??104857600,E=r.maxEntries??1e4,n=r.maxExpandedBytes??524288000;if(t.byteLength>d)throw Error("Archive exceeds the compressed size limit");let c=new DataView(t.buffer,t.byteOffset,t.byteLength),_=[],T=0;if(e.toLowerCase().endsWith(".zip")||t[0]===80&&t[1]===75){let h=0;while(h+30<=t.length){let R=c.getUint32(h,!0);if(R===33639248||R===101010256)break;if(R!==67324752)throw Error("Malformed ZIP local header");let N=c.getUint16(h+6,!0),A=c.getUint32(h+18,!0),u=c.getUint32(h+22,!0),f=c.getUint16(h+26,!0),w=c.getUint16(h+28,!0);if(N&8)throw Error("ZIP data descriptors are not accepted for uploaded artifacts");let I=new TextDecoder().decode(t.subarray(h+30,h+30+f));if(!BC(I))throw Error(`Unsafe archive path: ${I}`);if(_.push(I),T+=u,_.length>E||T>n)throw Error("Archive expansion limit exceeded");h+=30+f+w+A}return{format:"zip",entries:_.length,expandedBytes:T,paths:_}}if(!e.toLowerCase().match(/\.(?:tar|tar\.gz|tgz)$/))throw Error("Only ZIP and uncompressed TAR artifacts are supported");let i=0;while(i+512<=t.length){let h=t.subarray(i,i+512);if(h.every((f)=>f===0))break;let R=(f,w)=>new TextDecoder().decode(h.subarray(f,f+w)).replace(/\0.*$/,""),N=`${R(345,155)}${R(345,155)?"/":""}${R(0,100)}`,A=Number.parseInt(R(124,12).trim()||"0",8),u=String.fromCharCode(h[156]??0);if(!BC(N))throw Error(`Unsafe archive path: ${N}`);if(u==="1"||u==="2")throw Error(`Archive links are not accepted: ${N}`);if(!Number.isFinite(A)||A<0)throw Error("Malformed TAR entry size");if(_.push(N),T+=A,_.length>E||T>n)throw Error("Archive expansion limit exceeded");i+=512+Math.ceil(A/512)*512}return{format:"tar",entries:_.length,expandedBytes:T,paths:_}}var HC=new Set(["source","build","runtime","environment","domain","review"]);function WC(t,e){try{return typeof t==="string"?JSON.parse(t):e}catch{return e}}function vC(t){return/(?:secret|token|password|passwd|private[_-]?key|api[_-]?key)/i.test(t)}function QC(t){for(let[r,d]of Object.entries(t.environment??{}))if(typeof d==="string"&&vC(r)&&d)throw Error(`${r} must be stored through the write-only secrets boundary`);if(t.build.kind==="dockerfile"){for(let[r,d]of Object.entries(t.build.buildArgs??{}))if(vC(r)&&d)throw Error(`${r} must be declared as a build secret name`)}let e=JSON.stringify(t);if(/https?:\/\/[^/@\s]+:[^/@\s]+@/i.test(e))throw Error("Drafts cannot contain credential-bearing URLs")}function YC(t){return{id:String(t.id),organizationId:String(t.organization_id),projectId:String(t.project_id),schemaVersion:Number(t.schema_version),name:String(t.name),step:String(t.step),input:WC(t.input,{}),suppliedSecretNames:WC(t.supplied_secret_names,[]),status:String(t.status),version:Number(t.version),createdByActorId:t.created_by_actor_id?String(t.created_by_actor_id):void 0,createdAt:String(t.created_at),updatedAt:String(t.updated_at)}}class _S{controlPlane;nowFn;idFn;constructor(t,e={}){this.controlPlane=t;this.nowFn=e.now??(()=>new Date),this.idFn=e.id??(()=>crypto.randomUUID())}now(){return this.nowFn().toISOString()}create(t){if(QC(t.draft),t.draft.projectId!==t.projectId)throw Error("Draft project does not match its storage scope");let e=this.controlPlane.getProject(t.projectId);if(!e||e.organizationId!==t.organizationId)throw Error("Draft project was not found");let r=this.idFn(),d=this.now(),E=t.step??"source";if(!HC.has(E))throw Error("Invalid draft step");let n=[...new Set(t.suppliedSecretNames??[])].sort(),c=$r(t.draft,n).valid?"ready":"draft";return this.controlPlane.database.run("INSERT INTO application_drafts (id, organization_id, project_id, schema_version, name, step, input, supplied_secret_names, status, created_by_actor_id, created_at, updated_at) VALUES (?, ?, ?, 1, ?, ?, ?, ?, ?, ?, ?, ?)",[r,t.organizationId,t.projectId,t.name.trim().slice(0,100),E,JSON.stringify(t.draft),JSON.stringify(n),c,t.actorId??null,d,d]),this.controlPlane.appendEvent({organizationId:t.organizationId,projectId:t.projectId,actorId:t.actorId,type:"application.draft.created",payload:{draftId:r,step:E,status:c,requiredSecretNames:t.draft.requiredSecretNames??[]}}),this.get(r)}get(t){let e=this.controlPlane.database.query("SELECT * FROM application_drafts WHERE id=?").get(t);return e?YC(e):void 0}list(t){return this.controlPlane.database.query("SELECT * FROM application_drafts WHERE project_id=? ORDER BY updated_at DESC").all(t).map(YC)}update(t,e,r){let d=this.get(t);if(!d||d.version!==e)throw Error(`Application draft ${t} changed since version ${e}`);if(!HC.has(r.step))throw Error("Invalid draft step");if(r.draft.projectId!==d.projectId)throw Error("Draft project cannot be changed");QC(r.draft);let E=[...new Set(r.suppliedSecretNames??d.suppliedSecretNames)].sort(),n=$r(r.draft,E).valid?"ready":"draft",c=this.now();if(this.controlPlane.database.run("UPDATE application_drafts SET name=?, step=?, input=?, supplied_secret_names=?, status=?, version=version+1, updated_at=? WHERE id=? AND version=?",[r.draft.name.slice(0,100),r.step,JSON.stringify(r.draft),JSON.stringify(E),n,c,t,e]).changes!==1)throw Error(`Application draft ${t} changed since version ${e}`);return this.controlPlane.appendEvent({organizationId:d.organizationId,projectId:d.projectId,actorId:r.actorId,type:"application.draft.updated",payload:{draftId:t,fromVersion:e,toVersion:e+1,step:r.step,status:n}}),this.get(t)}markApplied(t,e,r){let d=this.get(t);if(!d||d.version!==e)throw Error(`Application draft ${t} changed since version ${e}`);let E=$r(d.input,d.suppliedSecretNames);if(!E.valid)throw Error(`Draft is not deployable: ${[...E.issues.map((c)=>c.message),...E.missingSecrets.map((c)=>`Missing secret ${c}`)].join("; ")}`);let n=this.now();return this.controlPlane.database.run("UPDATE application_drafts SET status='applied', step='review', version=version+1, updated_at=? WHERE id=? AND version=?",[n,t,e]),this.controlPlane.appendEvent({organizationId:d.organizationId,projectId:d.projectId,actorId:r,type:"application.draft.applied",payload:ut({draftId:t,manifest:E.manifest})}),this.get(t)}}import{createCipheriv as w$,createDecipheriv as g$,createHash as VC,randomBytes as $$}from"node:crypto";function sc(t){return typeof t==="string"&&t?t:void 0}function TS(t){return VC("sha256").update(t).digest("hex").slice(0,16)}function MC(t){let e=new URL(t.includes("://")?t:`https://${t}`);if(e.protocol!=="https:"&&!["localhost","127.0.0.1","::1"].includes(e.hostname))throw Error("Registry host must use HTTPS");if(e.username||e.password||e.search||e.hash)throw Error("Registry host cannot contain credentials");return`${e.protocol}//${e.host}`}function y$(t){return{id:String(t.id),organizationId:String(t.organization_id),provider:String(t.provider),name:String(t.name),host:String(t.host),credentialConfigured:!!t.credential_ciphertext,credentialFingerprint:sc(t.credential_fingerprint),credentialExpiresAt:sc(t.credential_expires_at),status:String(t.status),healthMessage:sc(t.health_message),lastTestedAt:sc(t.last_tested_at),version:Number(t.version),createdByActorId:sc(t.created_by_actor_id),createdAt:String(t.created_at),updatedAt:String(t.updated_at)}}class iS{controlPlane;key;nowFn;idFn;constructor(t,e){this.controlPlane=t;if(!e.encryptionKey)throw Error("Registry encryption key is required");this.key=VC("sha256").update(`ts-cloud:registry:${e.encryptionKey}`).digest(),this.nowFn=e.now??(()=>new Date),this.idFn=e.id??(()=>crypto.randomUUID())}now(){return this.nowFn().toISOString()}encrypt(t){let e=$$(12),r=w$("aes-256-gcm",this.key,e),d=Buffer.concat([r.update(t,"utf8"),r.final()]);return`v1.${e.toString("base64url")}.${r.getAuthTag().toString("base64url")}.${d.toString("base64url")}`}decrypt(t){let[e,r,d,E]=t.split(".");if(e!=="v1"||!r||!d||!E)throw Error("Registry credential envelope is invalid");let n=g$("aes-256-gcm",this.key,Buffer.from(r,"base64url"));return n.setAuthTag(Buffer.from(d,"base64url")),Buffer.concat([n.update(Buffer.from(E,"base64url")),n.final()]).toString("utf8")}current(t){let e=y$(t);return e.status!=="disconnected"&&e.credentialExpiresAt&&new Date(e.credentialExpiresAt).getTime()<=this.nowFn().getTime()?{...e,status:"expired",healthMessage:"Registry credential expired; rotate it before pulling images."}:e}create(t){if(!["docker_hub","ghcr","ecr","gcr","generic"].includes(t.provider))throw Error("A supported registry provider is required");let e=t.credential?JSON.stringify(t.credential):void 0,r=this.idFn(),d=this.now();return this.controlPlane.database.run("INSERT INTO registry_connections (id, organization_id, provider, name, host, credential_ciphertext, credential_fingerprint, credential_expires_at, created_by_actor_id, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",[r,t.organizationId,t.provider,t.name.trim().slice(0,80),MC(t.host),e?this.encrypt(e):null,e?TS(e):null,t.credentialExpiresAt??null,t.actorId??null,d,d]),this.controlPlane.appendEvent({organizationId:t.organizationId,actorId:t.actorId,type:"registry.connection.created",payload:{connectionId:r,provider:t.provider,host:MC(t.host),credentialConfigured:!!e}}),this.get(r)}get(t){let e=this.controlPlane.database.query("SELECT * FROM registry_connections WHERE id=?").get(t);return e?this.current(e):void 0}list(t){return this.controlPlane.database.query("SELECT * FROM registry_connections WHERE organization_id=? ORDER BY name").all(t).map((e)=>this.current(e))}credential(t){let e=this.controlPlane.database.query("SELECT credential_ciphertext FROM registry_connections WHERE id=?").get(t);return e?.credential_ciphertext?JSON.parse(this.decrypt(String(e.credential_ciphertext))):void 0}rotate(t,e,r={}){let d=this.get(t);if(!d||d.status==="disconnected")throw Error("Registry connection was not found");let E=JSON.stringify(e);return this.controlPlane.database.run("UPDATE registry_connections SET credential_ciphertext=?, credential_fingerprint=?, credential_expires_at=?, status='pending', health_message=NULL, version=version+1, updated_at=? WHERE id=?",[this.encrypt(E),TS(E),r.expiresAt??null,this.now(),t]),this.controlPlane.appendEvent({organizationId:d.organizationId,actorId:r.actorId,type:"registry.credential.rotated",payload:{connectionId:t,fingerprint:TS(E),expiresAt:r.expiresAt??null}}),this.get(t)}disconnect(t,e){let r=this.get(t);if(!r)throw Error("Registry connection was not found");return this.controlPlane.database.run("UPDATE registry_connections SET credential_ciphertext=NULL, credential_fingerprint=NULL, status='disconnected', health_message='Disconnected by an administrator', version=version+1, updated_at=? WHERE id=?",[this.now(),t]),this.controlPlane.appendEvent({organizationId:r.organizationId,actorId:e,type:"registry.connection.disconnected",level:"warning",payload:{connectionId:t}}),this.get(t)}async test(t,e={}){let r=this.get(t);if(!r||["disconnected","expired"].includes(r.status))throw Error("Active registry connection was not found");let d=this.credential(t),E=e.fetch??fetch,n=new AbortController,c=setTimeout(()=>n.abort(),e.timeoutMs??15000),_=d?.token?`Bearer ${d.token}`:d?.username||d?.password?`Basic ${Buffer.from(`${d.username??""}:${d.password??""}`).toString("base64")}`:void 0;try{let T=await E(`${r.host}/v2/`,{method:"GET",redirect:"error",signal:n.signal,headers:_?{Authorization:_}:void 0}),i=T.headers.get("www-authenticate")??"";if(T.status===401&&i.startsWith("Bearer ")&&d){let N=Object.fromEntries([...i.slice(7).matchAll(/(\w+)="([^"]+)"/g)].map((I)=>[I[1],I[2]])),A=new URL(N.realm??"");if(A.protocol!=="https:")throw Error("Registry authentication realm must use HTTPS");if(N.service)A.searchParams.set("service",N.service);if(e.image)A.searchParams.set("scope",`repository:${KC(e.image).repository}:pull`);let u=await E(A,{signal:n.signal,redirect:"error",headers:_?{Authorization:_}:void 0});if(!u.ok)throw Error(`Registry authentication failed (${u.status})`);let f=await u.json(),w=f.token??f.access_token;if(!w)throw Error("Registry did not return an access token");T=e.image?await GC(E,r.host,e.image,w,n.signal):await E(`${r.host}/v2/`,{signal:n.signal,redirect:"error",headers:{Authorization:`Bearer ${w}`}})}else if(T.ok&&e.image)T=await GC(E,r.host,e.image,d?.token,n.signal,_);let h=T.ok?"healthy":"degraded",R=T.ok?e.image?"Registry image is readable.":"Registry connection is healthy.":`Registry request failed (${T.status})`;return this.controlPlane.database.run("UPDATE registry_connections SET status=?, health_message=?, last_tested_at=?, version=version+1, updated_at=? WHERE id=?",[h,R,this.now(),this.now(),t]),this.get(t)}catch(T){let i=n.signal.aborted?"Registry request timed out.":T instanceof Error?T.message:"Registry test failed";return this.controlPlane.database.run("UPDATE registry_connections SET status='degraded', health_message=?, last_tested_at=?, version=version+1, updated_at=? WHERE id=?",[i.slice(0,1000),this.now(),this.now(),t]),this.get(t)}finally{clearTimeout(c)}}}function KC(t){let e=t.replace(/^https?:\/\//,""),r=e.indexOf("/");if(r<1)throw Error("Image must include registry/repository");let d=e.slice(r+1),E=d.lastIndexOf("@"),n=d.lastIndexOf(":"),c=E>=0?E:n>d.lastIndexOf("/")?n:-1,_=c>=0?d.slice(0,c):d,T=c>=0?d.slice(c+1):"latest";if(!/^[A-Za-z0-9_.\/-]+$/.test(_)||!/^[A-Za-z0-9_.:+-]+$/.test(T))throw Error("Image reference is invalid");return{repository:_,reference:T}}async function GC(t,e,r,d,E,n){let c=KC(r);return t(`${e}/v2/${c.repository}/manifests/${encodeURIComponent(c.reference)}`,{method:"HEAD",redirect:"error",signal:E,headers:{Accept:"application/vnd.oci.image.manifest.v1+json, application/vnd.docker.distribution.manifest.v2+json",...d?{Authorization:`Bearer ${d}`}:n?{Authorization:n}:{}}})}await Ht();import{createHash as X$}from"node:crypto";import{chmodSync as ZC,existsSync as kC,mkdirSync as a$,renameSync as P$,unlinkSync as bC,writeFileSync as j$}from"node:fs";import{basename as z$,join as F$}from"node:path";function hS(t){return{id:String(t.id),organizationId:String(t.organization_id),projectId:String(t.project_id),filename:String(t.filename),sha256:String(t.sha256),size:Number(t.size),format:String(t.format),entryCount:Number(t.entry_count),expandedBytes:Number(t.expanded_bytes),createdByActorId:t.created_by_actor_id?String(t.created_by_actor_id):void 0,createdAt:String(t.created_at)}}class RS{controlPlane;root;idFn;nowFn;constructor(t,e){this.controlPlane=t;this.root=ne(e.cwd,"artifacts"),this.idFn=e.id??(()=>crypto.randomUUID()),this.nowFn=e.now??(()=>new Date)}create(t){let e=this.controlPlane.getProject(t.projectId);if(!e||e.organizationId!==t.organizationId)throw Error("Artifact project was not found");let r=z$(t.filename).slice(0,200);if(!r||r!==t.filename)throw Error("Artifact filename must not contain a path");let d=JC(t.bytes,r),E=X$("sha256").update(t.bytes).digest("hex"),n=this.controlPlane.database.query("SELECT * FROM application_artifacts WHERE project_id=? AND sha256=?").get(t.projectId,E);if(n)return hS(n);let c=this.idFn();a$(this.root,{recursive:!0,mode:448}),ZC(this.root,448);let _=F$(this.root,`${c}.archive`),T=`${_}.partial`;try{j$(T,t.bytes,{mode:384,flag:"wx"}),P$(T,_),ZC(_,384),this.controlPlane.database.run("INSERT INTO application_artifacts (id, organization_id, project_id, filename, storage_path, sha256, size, format, entry_count, expanded_bytes, created_by_actor_id, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",[c,t.organizationId,t.projectId,r,_,E,t.bytes.byteLength,d.format,d.entries,d.expandedBytes,t.actorId??null,this.nowFn().toISOString()])}catch(i){if(kC(T))bC(T);if(kC(_))bC(_);throw i}return this.controlPlane.appendEvent({organizationId:t.organizationId,projectId:t.projectId,actorId:t.actorId,type:"application.artifact.created",payload:{artifactId:c,filename:r,sha256:E,size:t.bytes.byteLength,entries:d.entries}}),this.get(c)}get(t){let e=this.controlPlane.database.query("SELECT * FROM application_artifacts WHERE id=?").get(t);return e?hS(e):void 0}list(t){return this.controlPlane.database.query("SELECT * FROM application_artifacts WHERE project_id=? ORDER BY created_at DESC").all(t).map(hS)}}function BT(t){let e=t.drafts.get(t.draftId);if(!e||e.version!==t.expectedVersion)throw Error(`Application draft ${t.draftId} changed since version ${t.expectedVersion}`);if(e.status==="applied")throw Error("Application draft was already applied");let r=t.controlPlane.getProject(e.projectId),d=r?t.controlPlane.listEnvironments(r.id).find((i)=>i.id===e.input.environmentId):void 0;if(!r||!d||d.projectId!==r.id||r.organizationId!==e.organizationId)throw Error("Draft deployment scope was not found");if(t.confirmEnvironment!==d.slug)throw Error(`Type ${d.slug} to confirm this deployment target`);let E=$r(e.input,e.suppliedSecretNames);if(!E.valid)throw Error(`Application plan is invalid: ${[...E.issues.map((i)=>i.message),...E.missingSecrets.map((i)=>`Missing secret ${i}`)].join("; ")}`);let n=t.controlPlane.listResources(r.id,d.id).find((i)=>i.kind==="application"&&i.slug===e.input.slug),c=JSON.parse(JSON.stringify({manifest:E.manifest,configPatch:E.configPatch})),_=n?t.controlPlane.updateResource(n.id,n.version,{name:e.input.name,desiredState:c}):t.controlPlane.createResource({projectId:r.id,environmentId:d.id,kind:"application",slug:e.input.slug,name:e.input.name,desiredState:c,metadata:{source:"application-onboarding",draftId:e.id}}),T=new gt(t.controlPlane).enqueue({projectId:r.id,environmentId:d.id,resourceId:_.id,actorId:t.actorId,kind:"application.create",idempotencyKey:`application-draft:${e.id}:v${e.version}`,correlationId:`application-draft:${e.id}`,input:c,lockKey:`resource:${_.id}`,providerKey:_.provider??"default",buildSlot:e.input.build.kind!=="prebuilt_image",maxAttempts:3,retryClasses:["network","provider_throttled","provider_unavailable"],resumePolicy:"fail",cancellationMode:"provider_non_cancellable",retentionDays:90}).operation;return t.drafts.markApplied(e.id,e.version,t.actorId),t.controlPlane.appendEvent({organizationId:e.organizationId,projectId:r.id,resourceId:_.id,operationId:T.id,actorId:t.actorId,type:"application.create.queued",payload:{draftId:e.id,environment:d.slug,strategy:e.input.build.kind,costDrivers:E.costDrivers}}),{plan:E,resource:_,operation:T}}function oc(t){let e=["static","compute","serverless_zip","serverless_image"].includes(t.kind),r=["container","compose"].includes(t.kind)&&(t.replicas??1)>1,d=t.kind==="container"||t.kind==="serverless_zip"||t.kind==="serverless_image",E=(n,c)=>c&&(n==="atomic"?t.kind==="static"||t.hasHealthGate:t.hasHealthGate);return[{strategy:"atomic",supported:E("atomic",e),explanation:e?t.hasHealthGate||t.kind==="static"?"Activate an immutable version with an atomic pointer/alias switch.":"Atomic activation needs a readiness gate for this runtime.":"This driver has no atomic pointer or alias primitive.",capacityMultiplier:1,costImpact:"none",rollback:"Switch the pointer/alias back to the previous immutable release."},{strategy:"rolling",supported:E("rolling",r),explanation:r?t.hasHealthGate?"Replace healthy replicas within the configured capacity envelope.":"Rolling activation requires a health/readiness gate.":"Rolling activation requires a capable container/Compose driver and at least two replicas.",capacityMultiplier:1.5,costImpact:"temporary",rollback:"Stop replacement and restore the prior task/service definition."},{strategy:"blue_green",supported:E("blue_green",d),explanation:d?t.hasHealthGate?"Provision a complete green target and switch traffic after health passes.":"Blue-green requires a health gate before traffic can switch.":"The provider does not expose two traffic-addressable revisions.",capacityMultiplier:2,costImpact:"temporary",rollback:"Return all traffic to the preserved blue target."},{strategy:"canary",supported:E("canary",d),explanation:d?t.hasHealthGate?"Shift bounded traffic steps while evaluating health.":"Canary requires a health gate and measurable traffic target.":"The provider does not expose weighted traffic primitives.",capacityMultiplier:1.25,costImpact:"temporary",rollback:"Set canary weight to zero and preserve its diagnostics."}]}function JT(t,e){let r=oc(t).find((d)=>d.strategy===e);if(!r.supported)throw Error(`${e} is unavailable: ${r.explanation}`);return r}import{createHash as B$}from"node:crypto";var J$=/^sha256:[a-f0-9]{64}$/,H$=/^[a-f0-9]{40,64}$/i;function Kr(t){return typeof t==="string"&&t?t:void 0}function UE(t,e){try{return JSON.parse(String(t))}catch{return e}}function xC(t){return{id:String(t.id),organizationId:String(t.organization_id),digest:String(t.digest),kind:String(t.kind),uri:String(t.uri),size:Number(t.size),mediaType:String(t.media_type),provenance:UE(t.provenance,{}),attestation:UE(t.attestation,{}),verifiedAt:String(t.verified_at),createdAt:String(t.created_at)}}function qC(t){return{id:String(t.id),organizationId:String(t.organization_id),projectId:String(t.project_id),environmentId:String(t.environment_id),resourceId:String(t.resource_id),artifactId:String(t.artifact_id),kind:String(t.kind),sourceSha:Kr(t.source_sha),configHash:String(t.config_hash),manifest:UE(t.manifest,{}),provenance:UE(t.provenance,{}),strategy:String(t.strategy),status:String(t.status),healthGate:t.health_gate==null?void 0:UE(t.health_gate,void 0),hooks:UE(t.hooks,{migrations:"none",preActivate:[],postActivate:[]}),drainSeconds:Number(t.drain_seconds),graceSeconds:Number(t.grace_seconds),automaticRollback:Number(t.automatic_rollback)===1,rollbackAttempts:Number(t.rollback_attempts),previousReleaseId:Kr(t.previous_release_id),promotedFromReleaseId:Kr(t.promoted_from_release_id),actorId:Kr(t.actor_id),trigger:String(t.trigger),pinned:Number(t.pinned)===1,pinReason:Kr(t.pin_reason),activatedAt:Kr(t.activated_at),failedAt:Kr(t.failed_at),createdAt:String(t.created_at),updatedAt:String(t.updated_at)}}function W$(t){return{sequence:Number(t.sequence),id:String(t.id),releaseId:String(t.release_id),fromStatus:Kr(t.from_status),toStatus:String(t.to_status),trafficPercent:t.traffic_percent==null?void 0:Number(t.traffic_percent),health:UE(t.health,{}),message:String(t.message),operationId:Kr(t.operation_id),createdAt:String(t.created_at)}}function v$(t,e){let r=[],d=(E,n,c)=>{if(JSON.stringify(n)===JSON.stringify(c))return;if(n&&c&&typeof n==="object"&&typeof c==="object"&&!Array.isArray(n)&&!Array.isArray(c)){for(let _ of[...new Set([...Object.keys(n),...Object.keys(c)])].sort())d(E?`${E}.${_}`:_,n[_],c[_]);return}r.push({path:E,...n!==void 0?{before:n}:{},...c!==void 0?{after:c}:{}})};return d("",t,e),r}class SS{controlPlane;now;id;constructor(t,e={}){this.controlPlane=t;this.now=e.now??(()=>new Date),this.id=e.id??(()=>crypto.randomUUID())}registerArtifact(t){if(!J$.test(t.digest)||!/^(?:s3|https|oci|file):/.test(t.uri)||!Number.isInteger(t.size)||t.size<0)throw Error("Artifact requires a SHA-256 digest, supported immutable URI, and non-negative byte size");let e=this.controlPlane.database.query("SELECT * FROM release_artifacts WHERE organization_id=? AND digest=?").get(t.organizationId,t.digest);if(e)return xC(e);let r=this.id(),d=this.now().toISOString();return this.controlPlane.database.run("INSERT INTO release_artifacts (id, organization_id, digest, kind, uri, size, media_type, provenance, attestation, verified_at, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",[r,t.organizationId,t.digest,t.kind,t.uri,t.size,t.mediaType??"application/octet-stream",JSON.stringify(ut(t.provenance??{})),JSON.stringify(ut(t.attestation??{})),d,d]),this.getArtifact(r)}getArtifact(t){let e=this.controlPlane.database.query("SELECT * FROM release_artifacts WHERE id=?").get(t);return e?xC(e):void 0}create(t){let e=this.getArtifact(t.artifactId),r=this.controlPlane.getResource(t.resourceId),d=this.controlPlane.listEnvironments(t.projectId).find((R)=>R.id===t.environmentId);if(!e||e.organizationId!==t.organizationId||e.kind!==t.kind)throw Error("Release artifact does not match the organization and deployable kind");if(!r||r.projectId!==t.projectId||r.environmentId!==t.environmentId||!d)throw Error("Release target scope does not match the resource");if(t.sourceSha&&!H$.test(t.sourceSha))throw Error("Release source must be an immutable commit SHA");JT({kind:t.kind,provider:r.provider,hasHealthGate:!!t.healthGate,replicas:t.replicas},t.strategy);let E=ut(t.config),n=B$("sha256").update(JSON.stringify(E)).digest("hex"),c=this.active(t.resourceId),_=this.id(),T=this.now().toISOString(),i=t.approvalRequired?"awaiting_approval":"built",h=t.hooks??{migrations:"none",preActivate:[],postActivate:[]};return this.controlPlane.database.run("INSERT INTO releases (id, organization_id, project_id, environment_id, resource_id, artifact_id, kind, source_sha, config_hash, manifest, provenance, strategy, status, health_gate, hooks, drain_seconds, grace_seconds, automatic_rollback, previous_release_id, promoted_from_release_id, actor_id, trigger, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",[_,t.organizationId,t.projectId,t.environmentId,t.resourceId,t.artifactId,t.kind,t.sourceSha??null,n,JSON.stringify(ut(t.manifest)),JSON.stringify(ut(t.provenance??{})),t.strategy,i,t.healthGate?JSON.stringify(t.healthGate):null,JSON.stringify(h),Math.max(0,Math.min(3600,Math.floor(t.drainSeconds??30))),Math.max(0,Math.min(3600,Math.floor(t.graceSeconds??30))),t.automaticRollback===!1?0:1,c?.id??null,t.promotedFromReleaseId??null,t.actorId??null,t.trigger??"manual",T,T]),this.recordTransition(_,void 0,i,{message:t.promotedFromReleaseId?"Immutable artifact promoted without rebuild.":"Immutable release record created."}),this.get(_)}get(t){let e=this.controlPlane.database.query("SELECT * FROM releases WHERE id=?").get(t);return e?qC(e):void 0}list(t={}){return this.controlPlane.database.query("SELECT * FROM releases ORDER BY created_at DESC, rowid DESC").all().map(qC).filter((e)=>(!t.projectId||e.projectId===t.projectId)&&(!t.environmentId||e.environmentId===t.environmentId)&&(!t.resourceId||e.resourceId===t.resourceId)&&(!t.status||e.status===t.status))}active(t){return this.list({resourceId:t,status:"active"})[0]}transitions(t){return this.controlPlane.database.query("SELECT * FROM release_transitions WHERE release_id=? ORDER BY sequence").all(t).map(W$)}recordTransition(t,e,r,d){this.controlPlane.database.run("INSERT INTO release_transitions (id, release_id, from_status, to_status, traffic_percent, health, message, operation_id, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)",[this.id(),t,e??null,r,d.trafficPercent??null,JSON.stringify(ut(d.health??{})),d.message.slice(0,1000),d.operationId??null,this.now().toISOString()])}progress(t,e){let r=this.get(t);if(!r)throw Error(`Release ${t} was not found`);return this.recordTransition(t,r.status,r.status,e),this.transitions(t).at(-1)}transition(t,e,r){let d=this.get(t);if(!d)throw Error(`Release ${t} was not found`);if(!{built:["awaiting_approval","activating","failed"],awaiting_approval:["built","failed"],activating:["active","failed","rolled_back"],active:["superseded","failed","rolled_back"],failed:["activating","rolled_back"],rolled_back:["activating"],superseded:["activating"]}[d.status].includes(e))throw Error(`Invalid release transition ${d.status} → ${e}`);let n=this.now().toISOString();if(e==="active"){let c=this.active(d.resourceId);if(c&&c.id!==t)this.controlPlane.database.run("UPDATE releases SET status='superseded', updated_at=? WHERE id=?",[n,c.id]),this.recordTransition(c.id,"active","superseded",{message:`Superseded by ${t}.`,operationId:r.operationId})}return this.controlPlane.database.run("UPDATE releases SET status=?, rollback_attempts=rollback_attempts+?, activated_at=CASE WHEN ?='active' THEN ? ELSE activated_at END, failed_at=CASE WHEN ?='failed' THEN ? ELSE failed_at END, updated_at=? WHERE id=?",[e,e==="rolled_back"?1:0,e,n,e,n,n,t]),this.recordTransition(t,d.status,e,r),this.get(t)}approve(t,e){let r=this.get(t);if(!r||r.status!=="awaiting_approval")throw Error("Release is not awaiting approval");let d=this.id(),E=this.now().toISOString();return this.controlPlane.database.run("INSERT INTO release_approvals (id, release_id, environment_id, decision, actor_id, comment, created_at) VALUES (?, ?, ?, ?, ?, ?, ?)",[d,t,r.environmentId,e.decision,e.actorId,e.comment?.slice(0,1000)??null,E]),this.transition(t,e.decision==="approved"?"built":"failed",{message:e.decision==="approved"?"Environment gate approved.":"Environment gate rejected."})}approvals(t){return this.controlPlane.database.query("SELECT * FROM release_approvals WHERE release_id=? ORDER BY created_at").all(t).map((e)=>({id:String(e.id),releaseId:String(e.release_id),environmentId:String(e.environment_id),decision:String(e.decision),actorId:String(e.actor_id),comment:Kr(e.comment),createdAt:String(e.created_at)}))}promote(t,e){let r=this.get(t);if(!r||!["active","superseded"].includes(r.status))throw Error("Only a tested active/superseded release can be promoted");return this.create({organizationId:r.organizationId,projectId:r.projectId,environmentId:e.targetEnvironmentId,resourceId:e.targetResourceId,artifactId:r.artifactId,kind:r.kind,sourceSha:r.sourceSha,config:e.config,manifest:r.manifest,provenance:r.provenance,strategy:e.strategy??r.strategy,healthGate:e.healthGate??r.healthGate,hooks:r.hooks,drainSeconds:r.drainSeconds,graceSeconds:r.graceSeconds,automaticRollback:r.automaticRollback,promotedFromReleaseId:r.id,actorId:e.actorId,trigger:"promotion",approvalRequired:e.approvalRequired})}compare(t,e){let r=this.get(t),d=this.get(e);if(!r||!d)throw Error("Both releases are required for comparison");return{artifactChanged:r.artifactId!==d.artifactId,sourceChanged:r.sourceSha!==d.sourceSha,configChanged:r.configHash!==d.configHash,manifestChanges:v$(r.manifest,d.manifest),dataCaveat:d.hooks.migrations==="none"?"No database migration is recorded.":`Database hooks are ${d.hooks.migrations}; release rollback does not roll back data.`}}pin(t,e,r){if(!this.get(t))throw Error("Release was not found");return this.controlPlane.database.run("UPDATE releases SET pinned=?, pin_reason=?, updated_at=? WHERE id=?",[e?1:0,e?r?.slice(0,500)??"operator":null,this.now().toISOString(),t]),this.get(t)}retentionCandidates(t){let e=Math.max(1,Math.min(100,Math.floor(t.keepPerResource??10))),r=new Map;for(let d of this.list()){let E=r.get(d.resourceId)??[];E.push(d),r.set(d.resourceId,E)}return[...r.values()].flatMap((d)=>d.slice(e)).filter((d)=>new Date(d.createdAt)<t.before&&!d.pinned&&!["active","activating","awaiting_approval"].includes(d.status)&&!this.list().some((E)=>E.previousReleaseId===d.id&&["active","activating"].includes(E.status)))}}class wE{controlPlane;releases;queue;constructor(t){this.controlPlane=t;this.releases=new SS(t),this.queue=new gt(t)}enqueueActivation(t,e={}){let r=this.releases.get(t.id);if(!r)throw Error("Release was not found");if(!["built","failed","rolled_back","superseded"].includes(r.status))throw Error(`Release ${r.status} cannot be activated`);let d=e.action??"activate",E=this.queue.enqueue({projectId:r.projectId,environmentId:r.environmentId,resourceId:r.resourceId,actorId:e.actorId,kind:`release.${d}`,idempotencyKey:`release:${r.id}:${d}:${r.rollbackAttempts}`,correlationId:`release:${r.id}`,input:{releaseId:r.id,targetReleaseId:e.targetReleaseId??null},lockKey:`resource:${r.resourceId}`,providerKey:this.controlPlane.getResource(r.resourceId)?.provider??"default",maxAttempts:r.automaticRollback?2:1,retryClasses:["network","provider_throttled","provider_unavailable"],resumePolicy:"fail",cancellationMode:"provider_non_cancellable",retentionDays:365}).operation;return this.releases.transition(r.id,"activating",{message:`${d} queued.`,operationId:E.id,trafficPercent:0}),E}completeHealthGate(t,e){let r=this.releases.get(t);if(!r||r.status!=="activating")throw Error("Release is not activating");if(e.healthy)return{release:this.releases.transition(r.id,"active",{message:e.message??"Health gate passed; activation completed.",operationId:e.operationId,trafficPercent:100,health:e.health})};let d=this.releases.transition(r.id,"failed",{message:e.message??"Health gate failed.",operationId:e.operationId,trafficPercent:0,health:e.health}),E=r.previousReleaseId?this.releases.get(r.previousReleaseId):void 0;if(!r.automaticRollback||r.rollbackAttempts>=1||!E)return{release:d};let n=this.queue.enqueue({projectId:r.projectId,environmentId:r.environmentId,resourceId:r.resourceId,kind:"release.rollback",idempotencyKey:`release:${r.id}:automatic-rollback`,correlationId:`release:${r.id}`,input:{releaseId:r.id,targetReleaseId:E.id,automatic:!0},lockKey:`resource:${r.resourceId}`,providerKey:this.controlPlane.getResource(r.resourceId)?.provider??"default",maxAttempts:1,retryClasses:[],resumePolicy:"fail",cancellationMode:"provider_non_cancellable",retentionDays:365}).operation;return{release:d,rollbackOperation:n}}enqueueRollback(t,e={}){let r=this.releases.get(t.id);if(!r||r.status!=="active")throw Error("Only the active release can be rolled back");let d=e.targetReleaseId?this.releases.get(e.targetReleaseId):r.previousReleaseId?this.releases.get(r.previousReleaseId):void 0;if(!d||d.resourceId!==r.resourceId||!["superseded","active"].includes(d.status))throw Error("Rollback requires a preserved prior release for the same resource");return this.queue.enqueue({projectId:r.projectId,environmentId:r.environmentId,resourceId:r.resourceId,actorId:e.actorId,kind:"release.rollback",idempotencyKey:`release:${r.id}:manual-rollback:${d.id}`,correlationId:`release:${r.id}`,input:{releaseId:r.id,targetReleaseId:d.id,automatic:!1},lockKey:`resource:${r.resourceId}`,providerKey:this.controlPlane.getResource(r.resourceId)?.provider??"default",maxAttempts:1,retryClasses:[],resumePolicy:"fail",cancellationMode:"provider_non_cancellable",retentionDays:365}).operation}}function Q$(t){if(t.strategy==="canary")return[5,25,50,100].map((e,r)=>({step:`canary-${e}`,trafficPercent:e,waitSeconds:r===3?t.drainSeconds:t.graceSeconds,requiresHealth:!0}));if(t.strategy==="blue_green")return[{step:"green-health",trafficPercent:0,waitSeconds:t.graceSeconds,requiresHealth:!0},{step:"traffic-switch",trafficPercent:100,waitSeconds:t.drainSeconds,requiresHealth:!0}];if(t.strategy==="rolling")return[{step:"rolling-replacement",trafficPercent:50,waitSeconds:t.graceSeconds,requiresHealth:!0},{step:"rolling-complete",trafficPercent:100,waitSeconds:t.drainSeconds,requiresHealth:!0}];return[{step:"immutable-switch",trafficPercent:100,waitSeconds:t.drainSeconds,requiresHealth:!!t.healthGate}]}async function sC(t,e){if(e.release.artifactId!==e.artifact.id)throw Error("Release activation artifact identity changed");JT({kind:e.release.kind,hasHealthGate:!!e.release.healthGate,replicas:Number(e.release.manifest?.replicas)||void 0},e.release.strategy);let r=t.capability(e);if(!r.supported)throw Error(`${e.release.strategy} is unavailable in ${t.name}: ${r.explanation}`);return t.activate({...e,transitions:Q$(e.release)})}async function oC(t,e){if(!e.previous)throw Error("Rollback requires the preserved previous release");return t.rollback({...e,transitions:[{step:"rollback",trafficPercent:0,waitSeconds:e.release.drainSeconds,requiresHealth:!0}]})}var Y$=["release.activate","release.rollback"];function M$(t){return t&&typeof t==="object"&&!Array.isArray(t)?t:{}}function mC(t){let e=new wE(t.store),r=async(d)=>{let E=M$(d.operation.input),n=typeof E.releaseId==="string"?E.releaseId:"",c=e.releases.get(n);if(!c)throw Error(`Queued release ${n||"(missing)"} was not found`);if(c.projectId!==d.operation.projectId||c.environmentId!==d.operation.environmentId||c.resourceId!==d.operation.resourceId)throw Error("Queued release does not match the operation scope");let _=e.releases.getArtifact(c.artifactId);if(!_||_.digest!==e.releases.getArtifact(c.artifactId)?.digest)throw Error("Immutable release artifact is unavailable");let T=typeof E.targetReleaseId==="string"&&E.targetReleaseId?E.targetReleaseId:c.previousReleaseId,i=T?e.releases.get(T):void 0;if(i&&(i.resourceId!==c.resourceId||i.artifactId===c.artifactId&&i.id===c.id))throw Error("Rollback target does not match the release resource");let h=await t.resolveDriver(c);d.checkpoint("verify",`Verifying ${_.digest} and ${c.configHash} for ${h.name}.`),d.log(`Artifact ${_.digest}; source ${c.sourceSha??"not recorded"}; config ${c.configHash}.`,{stream:"system"}),d.throwIfCancellationRequested();let R;try{R=d.operation.kind==="release.rollback"?await oC(h,{release:c,artifact:_,previous:i}):await sC(h,{release:c,artifact:_,previous:i})}catch(N){if(d.operation.kind==="release.activate"&&e.releases.get(c.id)?.status==="activating")e.completeHealthGate(c.id,{healthy:!1,operationId:d.operation.id,message:N instanceof Error?N.message:String(N)});throw N}for(let N of R.transitions)e.releases.progress(c.id,{message:`${d.operation.kind==="release.rollback"?"Rollback":"Activation"} traffic at ${N.trafficPercent}%.`,trafficPercent:N.trafficPercent,health:N.observed,operationId:d.operation.id}),d.log(`Traffic ${N.trafficPercent}%: ${N.healthy?"healthy":"unhealthy"}.`,{stream:N.healthy?"step":"stderr",step:"health"});if(d.checkpoint("health","Evaluating the provider health result."),!R.activated||!R.healthy){if(d.operation.kind==="release.activate"&&e.releases.get(c.id)?.status==="activating")e.completeHealthGate(c.id,{healthy:!1,operationId:d.operation.id,health:{resourceVersions:R.resourceVersions},message:R.error??"Provider health gate failed."});throw Error(R.error??`${h.name} reported an unhealthy release`)}if(d.operation.kind==="release.activate"&&c.healthGate?.name){if(!t.resolveHealthGate)throw e.completeHealthGate(c.id,{healthy:!1,operationId:d.operation.id,message:`Named health gate ${c.healthGate.name} is not available to this worker.`}),Error(`Named health gate ${c.healthGate.name} is unavailable`);d.checkpoint("named-health-gate",`Waiting on ${c.healthGate.name}.`);let N=await t.resolveHealthGate(c.healthGate.name,c);if(d.log(`${c.healthGate.name}: ${N.healthy?"healthy":"unhealthy"}${N.message?` — ${N.message}`:""}.`,{stream:N.healthy?"step":"stderr",step:"health"}),!N.healthy)throw e.completeHealthGate(c.id,{healthy:!1,operationId:d.operation.id,health:N.evidence,message:N.message??`Named health gate ${c.healthGate.name} failed.`}),Error(N.message??`Named health gate ${c.healthGate.name} failed`)}if(d.operation.kind==="release.rollback"){let N=e.releases.get(c.id);if(N.status!=="rolled_back")e.releases.transition(N.id,"rolled_back",{message:`Traffic restored through ${h.name}.`,operationId:d.operation.id,trafficPercent:0,health:{resourceVersions:R.resourceVersions}});if(i&&i.status!=="active"){let A=i.status==="activating"?i:e.releases.transition(i.id,"activating",{message:"Rollback target restoring traffic.",operationId:d.operation.id,trafficPercent:0});e.releases.transition(A.id,"active",{message:"Previous immutable release restored.",operationId:d.operation.id,trafficPercent:100,health:{resourceVersions:R.resourceVersions}})}}else e.completeHealthGate(c.id,{healthy:!0,operationId:d.operation.id,health:{providerVersion:R.providerVersion??null,resourceVersions:R.resourceVersions},message:"Provider activation and health gates completed."});return d.checkpoint("finalize","Persisted the terminal release state."),{releaseId:c.id,artifactDigest:_.digest,provider:h.name,providerVersion:R.providerVersion??null,resourceVersions:R.resourceVersions,status:e.releases.get(c.id).status}};return Object.fromEntries(Y$.map((d)=>[d,r]))}import{createCipheriv as G$,createDecipheriv as V$,createHash as d0,randomBytes as NS}from"node:crypto";var E0={github:{repositories:!0,branches:!0,tags:!0,webhooks:!0,pullRequests:!0,tokenRefresh:!0,deployKeys:!0},gitlab:{repositories:!0,branches:!0,tags:!0,webhooks:!0,pullRequests:!0,tokenRefresh:!0,deployKeys:!0},bitbucket:{repositories:!0,branches:!0,tags:!0,webhooks:!0,pullRequests:!0,tokenRefresh:!0,deployKeys:!0},gitea:{repositories:!0,branches:!0,tags:!0,webhooks:!0,pullRequests:!0,tokenRefresh:!1,deployKeys:!0},generic_https:{repositories:!1,branches:!0,tags:!0,webhooks:!1,pullRequests:!1,tokenRefresh:!1,deployKeys:!1},generic_ssh:{repositories:!1,branches:!0,tags:!0,webhooks:!1,pullRequests:!1,tokenRefresh:!1,deployKeys:!0}};function vt(t){return typeof t==="string"&&t?t:void 0}function $E(t,e){try{return typeof t==="string"?JSON.parse(t):e}catch{return e}}function Zr(t){return JSON.stringify(ut(t))}function gE(t){return d0("sha256").update(t).digest("hex")}function pC(t){let e=t.trim().replace(/\/$/,""),r=new URL(e.includes("://")?e:`https://${e}`);if(r.username||r.password||r.search||r.hash)throw Error("Source host cannot contain credentials, a query, or a fragment");if(r.protocol!=="https:"&&!(r.protocol==="http:"&&["localhost","127.0.0.1","::1"].includes(r.hostname)))throw Error("Source host must use HTTPS");return`${r.protocol}//${r.host}${r.pathname.replace(/\/$/,"")}`}function t0(t){let e=t.trim();if(e.length<2||e.length>80)throw Error("Connection name must contain 2-80 characters");return e}function AS(t){let e=t.trim().replace(/^\/+|\/+$/g,"");if(!/^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/.test(e))throw Error("Repository must use owner/name format");return e}function e0(t){let e=t.trim()||".";if(e.startsWith("/")||e.split("/").includes("..")||/[\0\r\n]/.test(e))throw Error("Monorepo root must stay inside the repository");return e.replace(/^\.\//,"")||"."}function HT(t){return[...new Set((t??[]).map((e)=>e.trim()).filter(Boolean))].slice(0,100)}function K$(t){let e=t.trim();if(/\r|\n/.test(e)||/https?:\/\/[^/@\s]+:[^/@\s]+@/i.test(e))throw Error("Clone URL cannot contain credentials or control characters");if(!/^(?:https?:\/\/|ssh:\/\/|git@[A-Za-z0-9.-]+:)/.test(e))throw Error("Clone URL must use HTTPS or SSH");return e}function Z$(t){return{id:String(t.id),organizationId:String(t.organization_id),provider:String(t.provider),name:String(t.name),host:String(t.host),owner:vt(t.owner),authKind:String(t.auth_kind),credentialConfigured:!!t.credential_ciphertext,credentialFingerprint:vt(t.credential_fingerprint),grantedScopes:$E(t.granted_scopes,[]),capabilities:$E(t.capabilities,E0[String(t.provider)]),status:String(t.status),healthMessage:vt(t.health_message),lastTestedAt:vt(t.last_tested_at),lastSyncedAt:vt(t.last_synced_at),credentialExpiresAt:vt(t.credential_expires_at),version:Number(t.version),createdByActorId:vt(t.created_by_actor_id),createdAt:String(t.created_at),updatedAt:String(t.updated_at)}}function LS(t){return{id:String(t.id),connectionId:String(t.connection_id),providerRepositoryId:String(t.provider_repository_id),fullName:String(t.full_name),cloneUrl:String(t.clone_url),defaultBranch:String(t.default_branch),visibility:String(t.visibility),archived:Number(t.archived)===1,metadata:$E(t.metadata,{}),syncedAt:String(t.synced_at)}}function r0(t){return{id:String(t.id),projectId:String(t.project_id),environmentId:vt(t.environment_id),resourceId:vt(t.resource_id),connectionId:String(t.connection_id),repositoryId:vt(t.repository_id),repositoryFullName:String(t.repository_full_name),defaultBranch:String(t.default_branch),branchRule:vt(t.branch_rule),tagRule:vt(t.tag_rule),monorepoRoot:String(t.monorepo_root),includePaths:$E(t.include_paths,[]),excludePaths:$E(t.exclude_paths,[]),submodules:Number(t.submodules)===1,cloneDepth:t.clone_depth==null?void 0:Number(t.clone_depth),deployKeyId:vt(t.deploy_key_id),autoDeploy:Number(t.auto_deploy)===1,pullRequestPreviews:Number(t.pull_request_previews)===1,status:String(t.status),disabledReason:vt(t.disabled_reason),version:Number(t.version),createdByActorId:vt(t.created_by_actor_id),createdAt:String(t.created_at),updatedAt:String(t.updated_at)}}function uS(t){return{id:String(t.id),connectionId:String(t.connection_id),name:String(t.name),publicKey:String(t.public_key),publicKeyFingerprint:String(t.public_key_fingerprint),host:String(t.host),hostKey:String(t.host_key),hostKeyFingerprint:String(t.host_key_fingerprint),createdByActorId:vt(t.created_by_actor_id),createdAt:String(t.created_at),updatedAt:String(t.updated_at)}}function OS(t){return{id:String(t.id),connectionId:String(t.connection_id),repositoryId:vt(t.repository_id),repositoryFullName:String(t.repository_full_name),providerWebhookId:vt(t.provider_webhook_id),events:$E(t.events,[]),status:String(t.status),healthMessage:vt(t.health_message),lastDeliveryAt:vt(t.last_delivery_at),lastReconciledAt:vt(t.last_reconciled_at),createdAt:String(t.created_at),updatedAt:String(t.updated_at)}}function CS(t){return{id:String(t.id),connectionId:String(t.connection_id),webhookId:String(t.webhook_id),providerDeliveryId:String(t.provider_delivery_id),event:String(t.event),action:vt(t.action),commitSha:vt(t.commit_sha),signatureStatus:String(t.signature_status),status:String(t.status),payloadSummary:$E(t.payload_summary,{}),operationId:vt(t.operation_id),error:vt(t.error),receivedAt:String(t.received_at),processedAt:vt(t.processed_at)}}class lS{controlPlane;key;nowFn;idFn;constructor(t,e={}){this.controlPlane=t;this.key=e.encryptionKey?d0("sha256").update(e.encryptionKey).digest():void 0,this.nowFn=e.now??(()=>new Date),this.idFn=e.id??(()=>crypto.randomUUID())}now(){return this.nowFn().toISOString()}run(t,e){this.controlPlane.database.run(t,e)}encrypt(t){if(!this.key)throw Error("Source credential encryption key is not configured");let e=NS(12),r=G$("aes-256-gcm",this.key,e),d=Buffer.concat([r.update(t,"utf8"),r.final()]);return`v1.${e.toString("base64url")}.${r.getAuthTag().toString("base64url")}.${d.toString("base64url")}`}decrypt(t){if(!this.key)throw Error("Source credential encryption key is not configured");let[e,r,d,E]=t.split(".");if(e!=="v1"||!r||!d||!E)throw Error("Encrypted source credential is unavailable");let n=V$("aes-256-gcm",this.key,Buffer.from(r,"base64url"));return n.setAuthTag(Buffer.from(d,"base64url")),Buffer.concat([n.update(Buffer.from(E,"base64url")),n.final()]).toString("utf8")}createConnection(t){if(!this.controlPlane.getOrganization(t.organizationId))throw Error("Source connection organization was not found");let e=this.now(),r=this.idFn(),d=t.credential?JSON.stringify(t.credential):void 0;return this.run(`INSERT INTO source_connections (id, organization_id, provider, name, host, owner, auth_kind, credential_ciphertext, credential_fingerprint, granted_scopes, capabilities, status, credential_expires_at, created_by_actor_id, created_at, updated_at)
|
|
5494
|
+
`).find((d)=>d.includes(`"Name":"${t.providerId}"`));if(!r)return{};try{let d=JSON.parse(r);return{usedBytes:typeof d.Size==="number"?d.Size:void 0}}catch{return{}}}}class pR{provider="server";type="server_path";root;constructor(t){this.root=aC(t)}capabilities(){return sR(["create","attach","detach","delete","adopt","usage"],{resize:{supported:!1,reason:"Server paths use the capacity of their containing filesystem."},snapshot:{supported:!1,reason:"Attach a filesystem backup policy for verified recovery points."},restore:{supported:!1,reason:"Restore a filesystem recovery point into a new managed path."}})}path(t){if(!In.test(t))throw Error("Server path volume name is invalid.");let e=aC(this.root,t);if(!e.startsWith(`${this.root}${A$}`)||N$(e)!==t)throw Error("Server path escaped the managed volume root.");return e}async discover(t,e){return await mR(this.root,{recursive:!0,mode:488}),(await h$(this.root,{withFileTypes:!0})).filter((d)=>d.isDirectory()&&In.test(d.name)).map((d)=>({providerId:d.name,raw:{path:this.path(d.name)}}))}async create(t){let e=typeof t.desiredState.nativeName==="string"?t.desiredState.nativeName:t.name,r=this.path(e);return await mR(this.root,{recursive:!0,mode:488}),await mR(r,{recursive:!1,mode:488}),{providerId:e,filesystem:"host",raw:{path:r}}}async attach(t,e){}async detach(t,e){}async resize(){throw Error(this.capabilities().resize.reason)}async snapshot(){throw Error(this.capabilities().snapshot.reason)}async restore(t,e,r){throw Error(this.capabilities().restore.reason)}async delete(t){if(!t.providerId)throw Error("Server path provider identity is unavailable.");await R$(this.path(t.providerId),{recursive:!0,force:!1})}async usage(t){if(!t.providerId)return{};return{usedBytes:(await S$(this.path(t.providerId))).size}}}var ye=(t)=>t==null?void 0:String(t),bc=(t,e)=>{try{return JSON.parse(String(t))}catch{return e}},eS=(t)=>Number(t)===1,Dn=(t)=>t().toISOString();function PC(t){return{id:String(t.id),organizationId:String(t.organization_id),projectId:String(t.project_id),environmentId:ye(t.environment_id),resourceId:ye(t.resource_id),name:String(t.name),provider:String(t.provider),providerId:ye(t.provider_id),type:String(t.type),status:String(t.status),capacityBytes:t.capacity_bytes==null?void 0:Number(t.capacity_bytes),usedBytes:t.used_bytes==null?void 0:Number(t.used_bytes),filesystem:ye(t.filesystem),encrypted:eS(t.encrypted),capabilities:bc(t.capabilities,{}),desiredState:bc(t.desired_state,{}),observedState:bc(t.observed_state,{}),backupPolicyId:ye(t.backup_policy_id),lastBackupAt:ye(t.last_backup_at),orphanedAt:ye(t.orphaned_at),adoptedAt:ye(t.adopted_at),version:Number(t.version),createdAt:String(t.created_at),updatedAt:String(t.updated_at),deletedAt:ye(t.deleted_at)}}function tS(t){return{id:String(t.id),volumeId:String(t.volume_id),resourceId:String(t.resource_id),targetPath:String(t.target_path),readOnly:eS(t.read_only),uid:t.uid==null?void 0:Number(t.uid),gid:t.gid==null?void 0:Number(t.gid),mode:ye(t.mode),propagation:String(t.propagation),driverOptions:bc(t.driver_options,{}),desiredState:String(t.desired_state),observedState:String(t.observed_state),operationId:ye(t.operation_id),lastError:ye(t.last_error),version:Number(t.version),createdAt:String(t.created_at),updatedAt:String(t.updated_at)}}function jC(t){return{id:String(t.id),volumeId:String(t.volume_id),recoveryPointId:ye(t.recovery_point_id),providerId:ye(t.provider_id),name:String(t.name),status:String(t.status),sizeBytes:t.size_bytes==null?void 0:Number(t.size_bytes),encrypted:eS(t.encrypted),checksum:ye(t.checksum),metadata:bc(t.metadata,{}),createdAt:String(t.created_at),updatedAt:String(t.updated_at),deletedAt:ye(t.deleted_at)}}class fn{controlPlane;now;id;constructor(t,e=()=>new Date,r=()=>crypto.randomUUID()){this.controlPlane=t;this.now=e;this.id=r}get(t){let e=this.controlPlane.database.query("SELECT * FROM persistent_volumes WHERE id=?").get(t);return e?PC(e):void 0}list(t){let e=["project_id=?"],r=[t.projectId];if(t.environmentId)e.push("environment_id=?"),r.push(t.environmentId);if(!t.includeDeleted)e.push("deleted_at IS NULL");return this.controlPlane.database.query(`SELECT * FROM persistent_volumes WHERE ${e.join(" AND ")} ORDER BY name`).all(...r).map(PC)}create(t){let e=Dn(this.now),r=t.id??this.id();return this.controlPlane.database.run("INSERT INTO persistent_volumes (id,organization_id,project_id,environment_id,resource_id,name,provider,provider_id,type,status,capacity_bytes,used_bytes,filesystem,encrypted,capabilities,desired_state,observed_state,backup_policy_id,last_backup_at,orphaned_at,adopted_at,created_at,updated_at,deleted_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",[r,t.organizationId,t.projectId,t.environmentId??null,t.resourceId??null,t.name,t.provider,t.providerId??null,t.type,t.status,t.capacityBytes??null,t.usedBytes??null,t.filesystem??null,t.encrypted?1:0,JSON.stringify(t.capabilities),JSON.stringify(t.desiredState),JSON.stringify(t.observedState),t.backupPolicyId??null,t.lastBackupAt??null,t.orphanedAt??null,t.adoptedAt??null,e,e,t.deletedAt??null]),this.get(r)}update(t,e,r){let d=this.get(t);if(!d||d.version!==e)throw Error("Volume changed before this operation could be applied.");let E={...d,...r,updatedAt:Dn(this.now)};if(this.controlPlane.database.run("UPDATE persistent_volumes SET environment_id=?,resource_id=?,name=?,provider=?,provider_id=?,type=?,status=?,capacity_bytes=?,used_bytes=?,filesystem=?,encrypted=?,capabilities=?,desired_state=?,observed_state=?,backup_policy_id=?,last_backup_at=?,orphaned_at=?,adopted_at=?,deleted_at=?,version=version+1,updated_at=? WHERE id=? AND version=?",[E.environmentId??null,E.resourceId??null,E.name,E.provider,E.providerId??null,E.type,E.status,E.capacityBytes??null,E.usedBytes??null,E.filesystem??null,E.encrypted?1:0,JSON.stringify(E.capabilities),JSON.stringify(E.desiredState),JSON.stringify(E.observedState),E.backupPolicyId??null,E.lastBackupAt??null,E.orphanedAt??null,E.adoptedAt??null,E.deletedAt??null,E.updatedAt,t,e]).changes!==1)throw Error("Volume changed before this operation could be applied.");return this.get(t)}attachments(t){return this.controlPlane.database.query("SELECT * FROM volume_attachments WHERE volume_id=? ORDER BY target_path").all(t).map(tS)}attachment(t){let e=this.controlPlane.database.query("SELECT * FROM volume_attachments WHERE id=?").get(t);return e?tS(e):void 0}upsertAttachment(t){let e=this.controlPlane.database.query("SELECT * FROM volume_attachments WHERE volume_id=? AND resource_id=? AND target_path=?").get(t.volumeId,t.resourceId,t.targetPath),r=Dn(this.now);if(e){let E=tS(e);return this.controlPlane.database.run("UPDATE volume_attachments SET read_only=?,uid=?,gid=?,mode=?,propagation=?,driver_options=?,desired_state=?,observed_state=?,operation_id=?,last_error=?,version=version+1,updated_at=? WHERE id=?",[t.readOnly?1:0,t.uid??null,t.gid??null,t.mode??null,t.propagation,JSON.stringify(t.driverOptions),t.desiredState,t.observedState,t.operationId??null,t.lastError??null,r,E.id]),this.attachment(E.id)}let d=t.id??this.id();return this.controlPlane.database.run("INSERT INTO volume_attachments (id,volume_id,resource_id,target_path,read_only,uid,gid,mode,propagation,driver_options,desired_state,observed_state,operation_id,last_error,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",[d,t.volumeId,t.resourceId,t.targetPath,t.readOnly?1:0,t.uid??null,t.gid??null,t.mode??null,t.propagation,JSON.stringify(t.driverOptions),t.desiredState,t.observedState,t.operationId??null,t.lastError??null,r,r]),this.attachment(d)}updateAttachment(t,e){let r=this.attachment(t);if(!r)throw Error("Volume attachment was not found.");let d={...r,...e};return this.controlPlane.database.run("UPDATE volume_attachments SET desired_state=?,observed_state=?,operation_id=?,last_error=?,version=version+1,updated_at=? WHERE id=?",[d.desiredState,d.observedState,d.operationId??null,d.lastError??null,Dn(this.now),t]),this.attachment(t)}snapshots(t){return this.controlPlane.database.query("SELECT * FROM volume_snapshots WHERE volume_id=? AND deleted_at IS NULL ORDER BY created_at DESC").all(t).map(jC)}snapshot(t){let e=this.controlPlane.database.query("SELECT * FROM volume_snapshots WHERE id=?").get(t);return e?jC(e):void 0}createSnapshot(t){let e=t.id??this.id(),r=Dn(this.now);return this.controlPlane.database.run("INSERT INTO volume_snapshots (id,volume_id,recovery_point_id,provider_id,name,status,size_bytes,encrypted,checksum,metadata,created_at,updated_at,deleted_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)",[e,t.volumeId,t.recoveryPointId??null,t.providerId??null,t.name,t.status,t.sizeBytes??null,t.encrypted?1:0,t.checksum??null,JSON.stringify(t.metadata),r,r,t.deletedAt??null]),this.snapshot(e)}updateSnapshot(t,e){let r=this.snapshot(t);if(!r)throw Error("Volume snapshot was not found.");let d={...r,...e};return this.controlPlane.database.run("UPDATE volume_snapshots SET recovery_point_id=?,provider_id=?,name=?,status=?,size_bytes=?,encrypted=?,checksum=?,metadata=?,deleted_at=?,updated_at=? WHERE id=?",[d.recoveryPointId??null,d.providerId??null,d.name,d.status,d.sizeBytes??null,d.encrypted?1:0,d.checksum??null,JSON.stringify(d.metadata),d.deletedAt??null,Dn(this.now),t]),this.snapshot(t)}inventory(t,e){return this.list({projectId:t,environmentId:e}).map((r)=>{let d=this.attachments(r.id),E=this.snapshots(r.id),n=r.lastBackupAt?Date.now()-new Date(r.lastBackupAt).getTime():1/0;return{...r,attachments:d,snapshots:E,orphaned:r.status==="orphaned",usagePercent:r.capacityBytes&&r.usedBytes!=null?Math.round(r.usedBytes/r.capacityBytes*1000)/10:void 0,backupState:r.backupPolicyId?n<=86400000?"protected":"stale":"unprotected"}})}audit(t){this.controlPlane.appendEvent({organizationId:t.organizationId,projectId:t.projectId,resourceId:this.get(t.volumeId)?.resourceId,actorId:t.actorId,type:t.type,level:"warning",payload:{volumeId:t.volumeId,environmentId:t.environmentId??null,...t.payload}})}}function rS(t,e){let r=t.getProject(e.projectId);if(!r?.organizationId)return;let d=new fn(t),E=new kc,n=new Set(e.manifest.spec.volumes),c=new Set;for(let _ of n){let T=`${e.slug}-${_}`.toLowerCase().replace(/[^a-z0-9_.-]/g,"-").slice(0,63),i=d.list({projectId:e.projectId,environmentId:e.environmentId,includeDeleted:!0}).find((A)=>A.name===T);if(i?.deletedAt)throw Error(`Compose volume ${T} was permanently deleted; rename it before redeploying.`);let h=i?.resourceId?t.getResource(i.resourceId):t.createResource({projectId:e.projectId,environmentId:e.environmentId,kind:"volume",slug:T,name:T,provider:"docker",providerId:T,desiredState:{composeApplicationId:e.id,composeVolume:_}}),R=i??d.create({organizationId:r.organizationId,projectId:e.projectId,environmentId:e.environmentId,resourceId:h?.id,name:T,provider:"docker",providerId:T,type:"docker",status:"available",encrypted:!1,capabilities:E.capabilities(),desiredState:{composeApplicationId:e.id,composeVolume:_,nativeName:T},observedState:{}});c.add(R.id);let N=new Map;for(let A of Object.values(e.manifest.spec.services))for(let u of A.volumes.filter((f)=>f.source===_)){let f=N.get(u.target)??[];f.push(A.name),N.set(u.target,f),d.upsertAttachment({volumeId:R.id,resourceId:e.resourceId,targetPath:u.target,readOnly:u.readOnly,propagation:"private",driverOptions:{composeServices:f},desiredState:"attached",observedState:"pending"})}}for(let _ of d.list({projectId:e.projectId,environmentId:e.environmentId}).filter((T)=>T.desiredState.composeApplicationId===e.id&&!c.has(T.id)))for(let T of d.attachments(_.id))d.updateAttachment(T.id,{desiredState:"detached"})}function yC(t,e,r){let d=new fn(t);for(let E of d.list({projectId:e.projectId,environmentId:e.environmentId}).filter((n)=>n.desiredState.composeApplicationId===e.id)){for(let n of d.attachments(E.id))d.updateAttachment(n.id,{desiredState:"detached",observedState:"detached"});d.update(E.id,E.version,{status:r?"deleted":"available",deletedAt:r?new Date().toISOString():void 0})}}function Un(t){return typeof t==="string"&&t?t:void 0}function dS(t,e){try{return JSON.parse(String(t))}catch{return e}}function FT(t){return{id:String(t.id),resourceId:String(t.resource_id),projectId:String(t.project_id),environmentId:String(t.environment_id),name:String(t.name),slug:String(t.slug),status:String(t.status),sourceKind:String(t.source_kind),sourceHash:String(t.source_hash),redactedSource:String(t.redacted_source),manifest:dS(t.manifest,{}),diagnostics:dS(t.diagnostics,[]),templateId:Un(t.template_id),templateVersion:Un(t.template_version),latestOperationId:Un(t.latest_operation_id),createdByActorId:Un(t.created_by_actor_id),version:Number(t.version),createdAt:String(t.created_at),updatedAt:String(t.updated_at),deletedAt:Un(t.deleted_at)}}function u$(t){return{applicationId:String(t.application_id),serviceName:String(t.service_name),status:String(t.status),replicas:Number(t.replicas),healthyReplicas:Number(t.healthy_replicas),latestOperationId:Un(t.latest_operation_id),observedState:dS(t.observed_state,{}),updatedAt:String(t.updated_at)}}class DE{controlPlane;now;id;constructor(t,e={}){this.controlPlane=t;this.now=e.now??(()=>new Date),this.id=e.id??(()=>crypto.randomUUID())}persist(t,e){if(!t.valid)throw Error(`Compose definition contains ${t.diagnostics.filter((u)=>u.severity==="error").length} blocking diagnostic(s)`);let{projectId:r,environmentId:d,name:E,slug:n}=t.manifest.metadata;if(!this.controlPlane.listEnvironments(r).find((u)=>u.id===d))throw Error("Compose project and environment scope was not found");let _=this.getBySlug(r,d,n),T=this.now().toISOString(),i=JSON.stringify(t.manifest),h=JSON.stringify(ut(t.diagnostics));if(_){if(_.status==="deleted")throw Error("A deleted Compose application cannot be overwritten; choose another slug");let u=this.controlPlane.getResource(_.resourceId);if(!u)throw Error("Compose application resource was not found");this.controlPlane.updateResource(u.id,u.version,{name:E,provider:u.provider,providerId:u.providerId,desiredState:t.manifest,discoveredState:u.discoveredState,metadata:{sourceKind:e.sourceKind,templateId:e.templateId??null,templateVersion:e.templateVersion??null,sourceHash:t.sourceHash}}),this.controlPlane.database.run("UPDATE compose_applications SET name=?, status='ready', source_kind=?, source_hash=?, redacted_source=?, manifest=?, diagnostics=?, template_id=?, template_version=?, version=version+1, updated_at=? WHERE id=?",[E,e.sourceKind,t.sourceHash,t.redactedSource,i,h,e.templateId??null,e.templateVersion??null,T,_.id]);let f=Object.keys(t.manifest.spec.services);if(f.length)this.controlPlane.database.run(`DELETE FROM compose_service_states WHERE application_id=? AND service_name NOT IN (${f.map(()=>"?").join(",")})`,[_.id,...f]);for(let I of Object.values(t.manifest.spec.services))this.controlPlane.database.run("INSERT INTO compose_service_states (application_id, service_name, status, replicas, healthy_replicas, observed_state, updated_at) VALUES (?, ?, 'pending', ?, 0, '{}', ?) ON CONFLICT(application_id, service_name) DO UPDATE SET replicas=excluded.replicas, updated_at=excluded.updated_at",[_.id,I.name,I.replicas,T]);this.controlPlane.appendEvent({projectId:r,resourceId:_.resourceId,actorId:e.createdByActorId,type:"compose.application.updated",payload:{applicationId:_.id,sourceHash:t.sourceHash,diagnosticCount:t.diagnostics.length,templateId:e.templateId??null,templateVersion:e.templateVersion??null}});let w=this.get(_.id);return rS(this.controlPlane,w),w}let R=this.controlPlane.createResource({projectId:r,environmentId:d,kind:"compose_application",slug:n,name:E,desiredState:t.manifest,metadata:{sourceKind:e.sourceKind,templateId:e.templateId??null,templateVersion:e.templateVersion??null,sourceHash:t.sourceHash}}),N=this.id();this.controlPlane.database.run("INSERT INTO compose_applications (id, resource_id, project_id, environment_id, name, slug, status, source_kind, source_hash, redacted_source, manifest, diagnostics, template_id, template_version, created_by_actor_id, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, 'ready', ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",[N,R.id,r,d,E,n,e.sourceKind,t.sourceHash,t.redactedSource,i,h,e.templateId??null,e.templateVersion??null,e.createdByActorId??null,T,T]);for(let u of Object.values(t.manifest.spec.services))this.controlPlane.database.run("INSERT INTO compose_service_states (application_id, service_name, status, replicas, healthy_replicas, observed_state, updated_at) VALUES (?, ?, 'pending', ?, 0, '{}', ?)",[N,u.name,u.replicas,T]);this.controlPlane.appendEvent({projectId:r,resourceId:R.id,actorId:e.createdByActorId,type:"compose.application.created",payload:{applicationId:N,sourceHash:t.sourceHash,serviceNames:Object.keys(t.manifest.spec.services),templateId:e.templateId??null}});let A=this.get(N);return rS(this.controlPlane,A),A}import(t,e){let r=Gc(t,e);return{application:this.persist(r,{sourceKind:"compose",createdByActorId:e.createdByActorId}),parsed:r}}fromTemplate(t,e,r){let d=LC(t,e,r,r.version);return{application:this.persist(d,{sourceKind:"template",templateId:t,templateVersion:r.version??"1.0.0",createdByActorId:r.createdByActorId}),parsed:d}}preview(t,e){return Gc(t,e)}get(t){let e=this.controlPlane.database.query("SELECT * FROM compose_applications WHERE id=?").get(t);return e?FT(e):void 0}getByResource(t){let e=this.controlPlane.database.query("SELECT * FROM compose_applications WHERE resource_id=?").get(t);return e?FT(e):void 0}getBySlug(t,e,r){let d=this.controlPlane.database.query("SELECT * FROM compose_applications WHERE project_id=? AND environment_id=? AND slug=?").get(t,e,r);return d?FT(d):void 0}list(t={}){return this.controlPlane.database.query("SELECT * FROM compose_applications ORDER BY updated_at DESC").all().map(FT).filter((e)=>(!t.projectId||e.projectId===t.projectId)&&(!t.environmentId||e.environmentId===t.environmentId)&&(t.includeDeleted||e.status!=="deleted"))}services(t){return this.controlPlane.database.query("SELECT * FROM compose_service_states WHERE application_id=? ORDER BY service_name").all(t).map(u$)}transition(t,e,r={}){let d=this.get(t);if(!d)throw Error(`Compose application ${t} was not found`);let E=this.now().toISOString(),n=e==="deleted"?E:null;this.controlPlane.database.run("UPDATE compose_applications SET status=?, latest_operation_id=COALESCE(?, latest_operation_id), version=version+1, updated_at=?, deleted_at=? WHERE id=?",[e,r.operationId??null,E,n,t]);for(let c of r.services??[])if(d.manifest.spec.services[c.name])this.controlPlane.database.run("INSERT INTO compose_service_states (application_id, service_name, status, replicas, healthy_replicas, latest_operation_id, observed_state, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?) ON CONFLICT(application_id, service_name) DO UPDATE SET status=excluded.status, replicas=excluded.replicas, healthy_replicas=excluded.healthy_replicas, latest_operation_id=excluded.latest_operation_id, observed_state=excluded.observed_state, updated_at=excluded.updated_at",[t,c.name,c.status,c.replicas??d.manifest.spec.services[c.name].replicas,c.healthyReplicas??0,r.operationId??null,JSON.stringify(ut(c.observedState??{})),E]);return this.controlPlane.appendEvent({projectId:d.projectId,resourceId:d.resourceId,operationId:r.operationId,type:`compose.application.${e}`,level:e==="failed"||e==="degraded"?"error":"info",payload:{applicationId:t,error:r.error??null}}),this.get(t)}}class xc{controlPlane;applications;queue;constructor(t){this.controlPlane=t;this.applications=new DE(t),this.queue=new gt(t)}enqueue(t,e,r={}){if(t.status==="deleted")throw Error("Deleted Compose applications cannot be operated");if(r.service&&!t.manifest.spec.services[r.service])throw Error(`Compose service ${r.service} was not found`);if(e==="delete"){let E=r.removeVolumes?`${t.slug} delete volumes`:t.slug;if(r.confirmation!==E)throw Error(`Type ${E} to confirm ${r.removeVolumes?"persistent data removal":"stack deletion"}`)}if(e==="scale"&&(!r.service||!Number.isInteger(r.replicas)||r.replicas<0||r.replicas>100))throw Error("Scale requires a service and 0-100 replicas");let d=this.queue.enqueue({projectId:t.projectId,environmentId:t.environmentId,resourceId:t.resourceId,actorId:r.actorId,kind:`compose.${e}`,idempotencyKey:`compose:${t.id}:${e}:${r.service??"stack"}:${r.replicas??""}:${t.version}`,correlationId:`compose:${t.id}`,input:{applicationId:t.id,service:r.service??null,replicas:r.replicas??null,removeVolumes:!!r.removeVolumes},lockKey:`compose:${t.id}`,providerKey:this.controlPlane.getResource(t.resourceId)?.provider??"default",buildSlot:e==="deploy"||e==="redeploy",maxAttempts:3,retryClasses:["network","provider_throttled","provider_unavailable"],resumePolicy:"fail",cancellationMode:"provider_non_cancellable",retentionDays:90}).operation;return this.applications.transition(t.id,e==="delete"?"deleting":e==="stop"?"stopped":e==="start"?"deploying":e==="scale"?t.status:"deploying",{operationId:d.id}),d}}import{lstatSync as O$,readdirSync as C$,readFileSync as l$}from"node:fs";import{relative as I$,resolve as zC,sep as D$}from"node:path";function f$(t){return new Map(t.map((e)=>[e.path.replace(/^\.\//,"").replace(/\\/g,"/"),e]))}function fE(t,e,r){return{path:t,reason:e,weight:r}}function FC(t){try{return t?.content?JSON.parse(t.content):{}}catch{return{}}}function wn(t,e,r,d,E,n){return{framework:t,strategy:e,confidence:r,evidence:d,defaults:{build:E,runtime:{target:e==="static"?"serverless":e==="serverless"?"serverless":e==="dockerfile"||e==="prebuilt_image"?"container":"server",architecture:"x86_64",port:e==="static"||e==="serverless"?void 0:3000,healthCheck:e==="static"?void 0:{protocol:"http",path:"/health"}}},description:n}}function gn(t){let e=f$(t.slice(0,1e4)),r=[];if(e.has("Dockerfile"))r.push(wn("dockerfile","dockerfile",0.99,[fE("Dockerfile","A root Dockerfile defines an explicit reproducible build.",1)],{kind:"dockerfile",context:".",dockerfile:"Dockerfile"},"Build the repository with its Dockerfile and run the resulting OCI image."));let d=FC(e.get("composer.json"));if(e.has("artisan")&&d.require?.["laravel/framework"])r.push(wn("laravel","server",0.98,[fE("artisan","Laravel Artisan entrypoint is present.",0.45),fE("composer.json","Requires laravel/framework.",0.55)],{kind:"server",runtime:"php",runtimeVersion:"8.3",installCommand:"composer install --no-dev --prefer-dist --optimize-autoloader",buildCommand:"php artisan config:cache && php artisan route:cache && php artisan view:cache",startCommand:"php artisan serve --host=0.0.0.0 --port=$PORT"},"Install a production Composer tree, warm Laravel caches, and run the HTTP application."));else if(e.has("composer.json"))r.push(wn("php","server",0.82,[fE("composer.json","Composer metadata identifies a PHP application.",0.8)],{kind:"server",runtime:"php",runtimeVersion:"8.3",installCommand:"composer install --no-dev --prefer-dist --optimize-autoloader",startCommand:"php -S 0.0.0.0:$PORT -t public"},"Install Composer dependencies and run the configured PHP document root."));let E=FC(e.get("package.json"));if(e.has("package.json")){let n=e.has("bun.lock")||e.has("bun.lockb")||E.engines?.bun,c=n?"bun":"node",_=n?"bun":"node",T=[fE("package.json",`Defines ${E.scripts?.build?"build and ":""}${E.scripts?.start?"start ":""}scripts.`,0.55)];if(n)T.push(fE(e.has("bun.lock")?"bun.lock":e.has("bun.lockb")?"bun.lockb":"package.json","Pins the Bun package manager/runtime.",0.35));let i=!!(E.dependencies?.vite||E.devDependencies?.vite||E.dependencies?.["@stacksjs/bunpress"]||E.devDependencies?.["@stacksjs/bunpress"])&&!E.scripts?.start,h=i?{kind:"static",installCommand:`${c} install --frozen-lockfile`,buildCommand:`${c} run build`,publishDirectory:"dist"}:{kind:"server",runtime:c,installCommand:`${c} install --frozen-lockfile`,buildCommand:E.scripts?.build?`${c} run build`:void 0,startCommand:E.scripts?.start?`${c} run start`:c==="bun"?"bun run index.ts":"node index.js"};r.push(wn(_,h.kind,Math.min(0.94,T.reduce((R,N)=>R+N.weight,0)),T,h,i?"Install dependencies, build static assets, and publish the output directory.":`Install dependencies, build if configured, and start the ${c} server.`))}if(!r.length&&(e.has("index.html")||e.has("public/index.html")))r.push(wn("static","static",0.78,[fE(e.has("index.html")?"index.html":"public/index.html","A static HTML entrypoint is present.",0.78)],{kind:"static",publishDirectory:e.has("index.html")?".":"public"},"Publish the static directory without a runtime process."));if(!r.length)r.push(wn("unknown","buildpack",0.2,[],{kind:"buildpack",runtime:"node"},"No supported framework signature was conclusive; choose commands and runtime manually."));return r.sort((n,c)=>c.confidence-n.confidence||n.framework.localeCompare(c.framework))}function ES(t,e={}){let r=zC(t),d=e.maxFiles??1e4,E=e.maxContentBytes??262144,n=[],c=new Set(["Dockerfile","package.json","composer.json","index.html","public/index.html","bun.lock","bun.lockb","artisan"]),_=new Set([".git",".ts-cloud",".cache",".next",".nuxt",".output",".turbo",".bun","node_modules","vendor","pantry","dist","build","coverage"]),T=(i)=>{for(let h of C$(i).sort()){if(_.has(h))continue;let R=zC(i,h),N=I$(r,R).split(D$).join("/");if(!N||N.startsWith("../"))throw Error("Detection path escaped the application root");let A=O$(R);if(A.isSymbolicLink())throw Error(`Detection refuses symbolic links: ${N}`);if(A.isDirectory())T(R);else if(A.isFile()){if(n.length>=d)throw Error("Application file-count limit exceeded");let u={path:N,size:A.size};if(c.has(N)&&A.size<=E)u.content=l$(R,"utf8");n.push(u)}}};return T(r),n}function cS(t){if(Array.isArray(t))return`[${t.map(cS).join(",")}]`;if(t&&typeof t==="object")return`{${Object.entries(t).filter(([,e])=>e!==void 0).sort(([e],[r])=>e.localeCompare(r)).map(([e,r])=>`${JSON.stringify(e)}:${cS(r)}`).join(",")}}`;return JSON.stringify(t)??"null"}function qc(t){return!!t&&!t.startsWith("/")&&!t.split("/").includes("..")&&!/[\0\r\n]/.test(t)}function Ke(t,e,r,d){return{path:t,code:e,message:r,alternatives:d}}function nS(t){return JSON.parse(JSON.stringify(t))}function U$(t){let e=Object.fromEntries(Object.entries(t.environment??{}).map(([r,d])=>[r,typeof d==="string"?d:`\${${d.secretRef}}`]));if(t.build.kind==="prebuilt_image"||t.build.kind==="dockerfile")return nS({infrastructure:{containers:{[t.slug]:{source:t.source,build:t.build,port:t.runtime.port,cpu:t.runtime.cpu,memory:t.runtime.memoryMb,architecture:t.runtime.architecture,healthCheck:t.runtime.healthCheck,environment:e}}}});if(t.runtime.target==="serverless"||t.build.kind==="serverless")return nS({serverless:{apps:{[t.slug]:{source:t.source,build:t.build,architecture:t.runtime.architecture,environment:e,domain:t.domain}}}});return nS({sites:{[t.slug]:{source:t.source,build:t.build,port:t.runtime.port,architecture:t.runtime.architecture,healthCheck:t.runtime.healthCheck,env:e,domain:t.domain?.hostname}}})}function yr(t,e=[]){let r=[],d=(u)=>/(?:secret|token|password|passwd|private[_-]?key|api[_-]?key)/i.test(u),E=Object.fromEntries(Object.entries(t.environment??{}).map(([u,f])=>{if(typeof f==="string"&&d(u))return r.push(Ke(`environment.${u}`,"write_only_secret_required",`${u} must be supplied through the write-only secrets boundary.`)),[u,{secretRef:u}];return[u,f]})),n=t.build;if(t.build.kind==="dockerfile"&&t.build.buildArgs){let u=Object.fromEntries(Object.entries(t.build.buildArgs).map(([f,w])=>{if(d(f))return r.push(Ke(`build.buildArgs.${f}`,"write_only_build_secret_required",`${f} must be declared in secretNames instead of buildArgs.`)),[f,"[REDACTED]"];return[f,w]}));n={...t.build,buildArgs:u}}if(!/^[a-z0-9][a-z0-9-]{1,62}$/.test(t.slug))r.push(Ke("slug","invalid_slug","Slug must contain 2-63 lowercase letters, numbers, or hyphens."));if(!qc((t.source.kind==="git"?t.source.monorepoRoot:t.source.kind==="local"?t.source.root:".")??"."))r.push(Ke("source","unsafe_source_root","Source root must stay inside the source tree."));if(t.source.kind==="git"&&t.source.sparsePaths?.some((u)=>!qc(u)))r.push(Ke("source.sparsePaths","unsafe_sparse_path","Sparse checkout paths must stay inside the repository."));if(t.build.kind==="dockerfile"&&(!qc(t.build.context)||!qc(t.build.dockerfile)))r.push(Ke("build","unsafe_docker_path","Docker context and Dockerfile must stay inside the source tree."));if(t.build.kind==="static"&&!qc(t.build.publishDirectory))r.push(Ke("build.publishDirectory","invalid_publish_directory","A safe static publish directory is required."));if(t.build.kind==="server"&&!t.build.startCommand.trim())r.push(Ke("build.startCommand","missing_start_command","A server start command is required.",["Use static output","Use a Dockerfile"]));if(t.source.kind==="image"&&t.build.kind!=="prebuilt_image")r.push(Ke("build.kind","image_requires_prebuilt","An OCI image source must use the prebuilt-image strategy.",["Select prebuilt image"]));if(t.build.kind==="prebuilt_image"&&t.runtime.target!=="container")r.push(Ke("runtime.target","image_requires_container","Prebuilt images require the container runtime target.",["Select container target"]));if(t.runtime.target==="serverless"&&t.build.kind==="dockerfile")r.push(Ke("runtime.target","unsupported_serverless_dockerfile","Dockerfile builds currently target the container service path.",["Select container target","Select serverless package"]));if(t.runtime.port!==void 0&&(!Number.isInteger(t.runtime.port)||t.runtime.port<1||t.runtime.port>65535))r.push(Ke("runtime.port","invalid_port","Port must be an integer from 1 to 65535."));let c=t.runtime.healthCheck;if(c&&c.protocol!=="tcp"&&(!c.path||!c.path.startsWith("/")||/[\r\n]/.test(c.path)))r.push(Ke("runtime.healthCheck.path","invalid_health_path","HTTP health checks require a path beginning with /."));if(t.domain?.hostname&&(!/^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z]{2,63}$/i.test(t.domain.hostname)||t.domain.hostname.includes("..")))r.push(Ke("domain.hostname","invalid_domain","Domain must be a valid DNS hostname."));let _=Object.values(E).flatMap((u)=>typeof u==="object"?[u.secretRef]:[]),T=[...new Set([...t.requiredSecretNames??[],...t.build.kind==="dockerfile"?t.build.secretNames??[]:[],..._])].sort(),i=new Set(e),h=T.filter((u)=>!i.has(u)),R={apiVersion:"ts-cloud.dev/v1",kind:"Application",metadata:{name:t.name,slug:t.slug,projectId:t.projectId,environmentId:t.environmentId},spec:{source:t.source,build:n,runtime:t.runtime,environment:E,domain:t.domain}},N=[...new Set([t.source.kind==="git"?"git:read":t.source.kind==="image"?"registry:pull":t.source.kind==="artifact"?"artifact:inspect":"filesystem:read",t.runtime.target==="container"?"containers":t.runtime.target==="serverless"?"serverless":"servers",t.domain?"dns":""])].filter(Boolean).sort(),A=[...new Set([t.runtime.target,t.runtime.cpu?`${t.runtime.cpu} vCPU`:"",t.runtime.memoryMb?`${t.runtime.memoryMb} MB memory`:"",(t.runtime.minInstances??0)>0?`${t.runtime.minInstances} minimum instances`:"scales from zero where supported",t.domain?"managed DNS/TLS":""])].filter(Boolean);return{valid:r.length===0&&h.length===0,issues:r,missingSecrets:h,manifest:R,configPatch:U$({...t,build:n,environment:E}),capabilityRequirements:N,costDrivers:A,serializedManifest:`${cS(R)}
|
|
5495
|
+
`}}function BC(t){let e=t.replace(/\\/g,"/");return!!e&&!e.startsWith("/")&&!/^[A-Za-z]:\//.test(e)&&!e.split("/").includes("..")&&!/[\0\r\n]/.test(e)}function JC(t,e,r={}){let d=r.maxBytes??104857600,E=r.maxEntries??1e4,n=r.maxExpandedBytes??524288000;if(t.byteLength>d)throw Error("Archive exceeds the compressed size limit");let c=new DataView(t.buffer,t.byteOffset,t.byteLength),_=[],T=0;if(e.toLowerCase().endsWith(".zip")||t[0]===80&&t[1]===75){let h=0;while(h+30<=t.length){let R=c.getUint32(h,!0);if(R===33639248||R===101010256)break;if(R!==67324752)throw Error("Malformed ZIP local header");let N=c.getUint16(h+6,!0),A=c.getUint32(h+18,!0),u=c.getUint32(h+22,!0),f=c.getUint16(h+26,!0),w=c.getUint16(h+28,!0);if(N&8)throw Error("ZIP data descriptors are not accepted for uploaded artifacts");let I=new TextDecoder().decode(t.subarray(h+30,h+30+f));if(!BC(I))throw Error(`Unsafe archive path: ${I}`);if(_.push(I),T+=u,_.length>E||T>n)throw Error("Archive expansion limit exceeded");h+=30+f+w+A}return{format:"zip",entries:_.length,expandedBytes:T,paths:_}}if(!e.toLowerCase().match(/\.(?:tar|tar\.gz|tgz)$/))throw Error("Only ZIP and uncompressed TAR artifacts are supported");let i=0;while(i+512<=t.length){let h=t.subarray(i,i+512);if(h.every((f)=>f===0))break;let R=(f,w)=>new TextDecoder().decode(h.subarray(f,f+w)).replace(/\0.*$/,""),N=`${R(345,155)}${R(345,155)?"/":""}${R(0,100)}`,A=Number.parseInt(R(124,12).trim()||"0",8),u=String.fromCharCode(h[156]??0);if(!BC(N))throw Error(`Unsafe archive path: ${N}`);if(u==="1"||u==="2")throw Error(`Archive links are not accepted: ${N}`);if(!Number.isFinite(A)||A<0)throw Error("Malformed TAR entry size");if(_.push(N),T+=A,_.length>E||T>n)throw Error("Archive expansion limit exceeded");i+=512+Math.ceil(A/512)*512}return{format:"tar",entries:_.length,expandedBytes:T,paths:_}}var HC=new Set(["source","build","runtime","environment","domain","review"]);function WC(t,e){try{return typeof t==="string"?JSON.parse(t):e}catch{return e}}function vC(t){return/(?:secret|token|password|passwd|private[_-]?key|api[_-]?key)/i.test(t)}function QC(t){for(let[r,d]of Object.entries(t.environment??{}))if(typeof d==="string"&&vC(r)&&d)throw Error(`${r} must be stored through the write-only secrets boundary`);if(t.build.kind==="dockerfile"){for(let[r,d]of Object.entries(t.build.buildArgs??{}))if(vC(r)&&d)throw Error(`${r} must be declared as a build secret name`)}let e=JSON.stringify(t);if(/https?:\/\/[^/@\s]+:[^/@\s]+@/i.test(e))throw Error("Drafts cannot contain credential-bearing URLs")}function YC(t){return{id:String(t.id),organizationId:String(t.organization_id),projectId:String(t.project_id),schemaVersion:Number(t.schema_version),name:String(t.name),step:String(t.step),input:WC(t.input,{}),suppliedSecretNames:WC(t.supplied_secret_names,[]),status:String(t.status),version:Number(t.version),createdByActorId:t.created_by_actor_id?String(t.created_by_actor_id):void 0,createdAt:String(t.created_at),updatedAt:String(t.updated_at)}}class _S{controlPlane;nowFn;idFn;constructor(t,e={}){this.controlPlane=t;this.nowFn=e.now??(()=>new Date),this.idFn=e.id??(()=>crypto.randomUUID())}now(){return this.nowFn().toISOString()}create(t){if(QC(t.draft),t.draft.projectId!==t.projectId)throw Error("Draft project does not match its storage scope");let e=this.controlPlane.getProject(t.projectId);if(!e||e.organizationId!==t.organizationId)throw Error("Draft project was not found");let r=this.idFn(),d=this.now(),E=t.step??"source";if(!HC.has(E))throw Error("Invalid draft step");let n=[...new Set(t.suppliedSecretNames??[])].sort(),c=yr(t.draft,n).valid?"ready":"draft";return this.controlPlane.database.run("INSERT INTO application_drafts (id, organization_id, project_id, schema_version, name, step, input, supplied_secret_names, status, created_by_actor_id, created_at, updated_at) VALUES (?, ?, ?, 1, ?, ?, ?, ?, ?, ?, ?, ?)",[r,t.organizationId,t.projectId,t.name.trim().slice(0,100),E,JSON.stringify(t.draft),JSON.stringify(n),c,t.actorId??null,d,d]),this.controlPlane.appendEvent({organizationId:t.organizationId,projectId:t.projectId,actorId:t.actorId,type:"application.draft.created",payload:{draftId:r,step:E,status:c,requiredSecretNames:t.draft.requiredSecretNames??[]}}),this.get(r)}get(t){let e=this.controlPlane.database.query("SELECT * FROM application_drafts WHERE id=?").get(t);return e?YC(e):void 0}list(t){return this.controlPlane.database.query("SELECT * FROM application_drafts WHERE project_id=? ORDER BY updated_at DESC").all(t).map(YC)}update(t,e,r){let d=this.get(t);if(!d||d.version!==e)throw Error(`Application draft ${t} changed since version ${e}`);if(!HC.has(r.step))throw Error("Invalid draft step");if(r.draft.projectId!==d.projectId)throw Error("Draft project cannot be changed");QC(r.draft);let E=[...new Set(r.suppliedSecretNames??d.suppliedSecretNames)].sort(),n=yr(r.draft,E).valid?"ready":"draft",c=this.now();if(this.controlPlane.database.run("UPDATE application_drafts SET name=?, step=?, input=?, supplied_secret_names=?, status=?, version=version+1, updated_at=? WHERE id=? AND version=?",[r.draft.name.slice(0,100),r.step,JSON.stringify(r.draft),JSON.stringify(E),n,c,t,e]).changes!==1)throw Error(`Application draft ${t} changed since version ${e}`);return this.controlPlane.appendEvent({organizationId:d.organizationId,projectId:d.projectId,actorId:r.actorId,type:"application.draft.updated",payload:{draftId:t,fromVersion:e,toVersion:e+1,step:r.step,status:n}}),this.get(t)}markApplied(t,e,r){let d=this.get(t);if(!d||d.version!==e)throw Error(`Application draft ${t} changed since version ${e}`);let E=yr(d.input,d.suppliedSecretNames);if(!E.valid)throw Error(`Draft is not deployable: ${[...E.issues.map((c)=>c.message),...E.missingSecrets.map((c)=>`Missing secret ${c}`)].join("; ")}`);let n=this.now();return this.controlPlane.database.run("UPDATE application_drafts SET status='applied', step='review', version=version+1, updated_at=? WHERE id=? AND version=?",[n,t,e]),this.controlPlane.appendEvent({organizationId:d.organizationId,projectId:d.projectId,actorId:r,type:"application.draft.applied",payload:ut({draftId:t,manifest:E.manifest})}),this.get(t)}}import{createCipheriv as w$,createDecipheriv as g$,createHash as VC,randomBytes as $$}from"node:crypto";function sc(t){return typeof t==="string"&&t?t:void 0}function TS(t){return VC("sha256").update(t).digest("hex").slice(0,16)}function MC(t){let e=new URL(t.includes("://")?t:`https://${t}`);if(e.protocol!=="https:"&&!["localhost","127.0.0.1","::1"].includes(e.hostname))throw Error("Registry host must use HTTPS");if(e.username||e.password||e.search||e.hash)throw Error("Registry host cannot contain credentials");return`${e.protocol}//${e.host}`}function y$(t){return{id:String(t.id),organizationId:String(t.organization_id),provider:String(t.provider),name:String(t.name),host:String(t.host),credentialConfigured:!!t.credential_ciphertext,credentialFingerprint:sc(t.credential_fingerprint),credentialExpiresAt:sc(t.credential_expires_at),status:String(t.status),healthMessage:sc(t.health_message),lastTestedAt:sc(t.last_tested_at),version:Number(t.version),createdByActorId:sc(t.created_by_actor_id),createdAt:String(t.created_at),updatedAt:String(t.updated_at)}}class iS{controlPlane;key;nowFn;idFn;constructor(t,e){this.controlPlane=t;if(!e.encryptionKey)throw Error("Registry encryption key is required");this.key=VC("sha256").update(`ts-cloud:registry:${e.encryptionKey}`).digest(),this.nowFn=e.now??(()=>new Date),this.idFn=e.id??(()=>crypto.randomUUID())}now(){return this.nowFn().toISOString()}encrypt(t){let e=$$(12),r=w$("aes-256-gcm",this.key,e),d=Buffer.concat([r.update(t,"utf8"),r.final()]);return`v1.${e.toString("base64url")}.${r.getAuthTag().toString("base64url")}.${d.toString("base64url")}`}decrypt(t){let[e,r,d,E]=t.split(".");if(e!=="v1"||!r||!d||!E)throw Error("Registry credential envelope is invalid");let n=g$("aes-256-gcm",this.key,Buffer.from(r,"base64url"));return n.setAuthTag(Buffer.from(d,"base64url")),Buffer.concat([n.update(Buffer.from(E,"base64url")),n.final()]).toString("utf8")}current(t){let e=y$(t);return e.status!=="disconnected"&&e.credentialExpiresAt&&new Date(e.credentialExpiresAt).getTime()<=this.nowFn().getTime()?{...e,status:"expired",healthMessage:"Registry credential expired; rotate it before pulling images."}:e}create(t){if(!["docker_hub","ghcr","ecr","gcr","generic"].includes(t.provider))throw Error("A supported registry provider is required");let e=t.credential?JSON.stringify(t.credential):void 0,r=this.idFn(),d=this.now();return this.controlPlane.database.run("INSERT INTO registry_connections (id, organization_id, provider, name, host, credential_ciphertext, credential_fingerprint, credential_expires_at, created_by_actor_id, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",[r,t.organizationId,t.provider,t.name.trim().slice(0,80),MC(t.host),e?this.encrypt(e):null,e?TS(e):null,t.credentialExpiresAt??null,t.actorId??null,d,d]),this.controlPlane.appendEvent({organizationId:t.organizationId,actorId:t.actorId,type:"registry.connection.created",payload:{connectionId:r,provider:t.provider,host:MC(t.host),credentialConfigured:!!e}}),this.get(r)}get(t){let e=this.controlPlane.database.query("SELECT * FROM registry_connections WHERE id=?").get(t);return e?this.current(e):void 0}list(t){return this.controlPlane.database.query("SELECT * FROM registry_connections WHERE organization_id=? ORDER BY name").all(t).map((e)=>this.current(e))}credential(t){let e=this.controlPlane.database.query("SELECT credential_ciphertext FROM registry_connections WHERE id=?").get(t);return e?.credential_ciphertext?JSON.parse(this.decrypt(String(e.credential_ciphertext))):void 0}rotate(t,e,r={}){let d=this.get(t);if(!d||d.status==="disconnected")throw Error("Registry connection was not found");let E=JSON.stringify(e);return this.controlPlane.database.run("UPDATE registry_connections SET credential_ciphertext=?, credential_fingerprint=?, credential_expires_at=?, status='pending', health_message=NULL, version=version+1, updated_at=? WHERE id=?",[this.encrypt(E),TS(E),r.expiresAt??null,this.now(),t]),this.controlPlane.appendEvent({organizationId:d.organizationId,actorId:r.actorId,type:"registry.credential.rotated",payload:{connectionId:t,fingerprint:TS(E),expiresAt:r.expiresAt??null}}),this.get(t)}disconnect(t,e){let r=this.get(t);if(!r)throw Error("Registry connection was not found");return this.controlPlane.database.run("UPDATE registry_connections SET credential_ciphertext=NULL, credential_fingerprint=NULL, status='disconnected', health_message='Disconnected by an administrator', version=version+1, updated_at=? WHERE id=?",[this.now(),t]),this.controlPlane.appendEvent({organizationId:r.organizationId,actorId:e,type:"registry.connection.disconnected",level:"warning",payload:{connectionId:t}}),this.get(t)}async test(t,e={}){let r=this.get(t);if(!r||["disconnected","expired"].includes(r.status))throw Error("Active registry connection was not found");let d=this.credential(t),E=e.fetch??fetch,n=new AbortController,c=setTimeout(()=>n.abort(),e.timeoutMs??15000),_=d?.token?`Bearer ${d.token}`:d?.username||d?.password?`Basic ${Buffer.from(`${d.username??""}:${d.password??""}`).toString("base64")}`:void 0;try{let T=await E(`${r.host}/v2/`,{method:"GET",redirect:"error",signal:n.signal,headers:_?{Authorization:_}:void 0}),i=T.headers.get("www-authenticate")??"";if(T.status===401&&i.startsWith("Bearer ")&&d){let N=Object.fromEntries([...i.slice(7).matchAll(/(\w+)="([^"]+)"/g)].map((I)=>[I[1],I[2]])),A=new URL(N.realm??"");if(A.protocol!=="https:")throw Error("Registry authentication realm must use HTTPS");if(N.service)A.searchParams.set("service",N.service);if(e.image)A.searchParams.set("scope",`repository:${KC(e.image).repository}:pull`);let u=await E(A,{signal:n.signal,redirect:"error",headers:_?{Authorization:_}:void 0});if(!u.ok)throw Error(`Registry authentication failed (${u.status})`);let f=await u.json(),w=f.token??f.access_token;if(!w)throw Error("Registry did not return an access token");T=e.image?await GC(E,r.host,e.image,w,n.signal):await E(`${r.host}/v2/`,{signal:n.signal,redirect:"error",headers:{Authorization:`Bearer ${w}`}})}else if(T.ok&&e.image)T=await GC(E,r.host,e.image,d?.token,n.signal,_);let h=T.ok?"healthy":"degraded",R=T.ok?e.image?"Registry image is readable.":"Registry connection is healthy.":`Registry request failed (${T.status})`;return this.controlPlane.database.run("UPDATE registry_connections SET status=?, health_message=?, last_tested_at=?, version=version+1, updated_at=? WHERE id=?",[h,R,this.now(),this.now(),t]),this.get(t)}catch(T){let i=n.signal.aborted?"Registry request timed out.":T instanceof Error?T.message:"Registry test failed";return this.controlPlane.database.run("UPDATE registry_connections SET status='degraded', health_message=?, last_tested_at=?, version=version+1, updated_at=? WHERE id=?",[i.slice(0,1000),this.now(),this.now(),t]),this.get(t)}finally{clearTimeout(c)}}}function KC(t){let e=t.replace(/^https?:\/\//,""),r=e.indexOf("/");if(r<1)throw Error("Image must include registry/repository");let d=e.slice(r+1),E=d.lastIndexOf("@"),n=d.lastIndexOf(":"),c=E>=0?E:n>d.lastIndexOf("/")?n:-1,_=c>=0?d.slice(0,c):d,T=c>=0?d.slice(c+1):"latest";if(!/^[A-Za-z0-9_.\/-]+$/.test(_)||!/^[A-Za-z0-9_.:+-]+$/.test(T))throw Error("Image reference is invalid");return{repository:_,reference:T}}async function GC(t,e,r,d,E,n){let c=KC(r);return t(`${e}/v2/${c.repository}/manifests/${encodeURIComponent(c.reference)}`,{method:"HEAD",redirect:"error",signal:E,headers:{Accept:"application/vnd.oci.image.manifest.v1+json, application/vnd.docker.distribution.manifest.v2+json",...d?{Authorization:`Bearer ${d}`}:n?{Authorization:n}:{}}})}await Ht();import{createHash as X$}from"node:crypto";import{chmodSync as ZC,existsSync as kC,mkdirSync as a$,renameSync as P$,unlinkSync as bC,writeFileSync as j$}from"node:fs";import{basename as z$,join as F$}from"node:path";function hS(t){return{id:String(t.id),organizationId:String(t.organization_id),projectId:String(t.project_id),filename:String(t.filename),sha256:String(t.sha256),size:Number(t.size),format:String(t.format),entryCount:Number(t.entry_count),expandedBytes:Number(t.expanded_bytes),createdByActorId:t.created_by_actor_id?String(t.created_by_actor_id):void 0,createdAt:String(t.created_at)}}class RS{controlPlane;root;idFn;nowFn;constructor(t,e){this.controlPlane=t;this.root=ne(e.cwd,"artifacts"),this.idFn=e.id??(()=>crypto.randomUUID()),this.nowFn=e.now??(()=>new Date)}create(t){let e=this.controlPlane.getProject(t.projectId);if(!e||e.organizationId!==t.organizationId)throw Error("Artifact project was not found");let r=z$(t.filename).slice(0,200);if(!r||r!==t.filename)throw Error("Artifact filename must not contain a path");let d=JC(t.bytes,r),E=X$("sha256").update(t.bytes).digest("hex"),n=this.controlPlane.database.query("SELECT * FROM application_artifacts WHERE project_id=? AND sha256=?").get(t.projectId,E);if(n)return hS(n);let c=this.idFn();a$(this.root,{recursive:!0,mode:448}),ZC(this.root,448);let _=F$(this.root,`${c}.archive`),T=`${_}.partial`;try{j$(T,t.bytes,{mode:384,flag:"wx"}),P$(T,_),ZC(_,384),this.controlPlane.database.run("INSERT INTO application_artifacts (id, organization_id, project_id, filename, storage_path, sha256, size, format, entry_count, expanded_bytes, created_by_actor_id, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",[c,t.organizationId,t.projectId,r,_,E,t.bytes.byteLength,d.format,d.entries,d.expandedBytes,t.actorId??null,this.nowFn().toISOString()])}catch(i){if(kC(T))bC(T);if(kC(_))bC(_);throw i}return this.controlPlane.appendEvent({organizationId:t.organizationId,projectId:t.projectId,actorId:t.actorId,type:"application.artifact.created",payload:{artifactId:c,filename:r,sha256:E,size:t.bytes.byteLength,entries:d.entries}}),this.get(c)}get(t){let e=this.controlPlane.database.query("SELECT * FROM application_artifacts WHERE id=?").get(t);return e?hS(e):void 0}list(t){return this.controlPlane.database.query("SELECT * FROM application_artifacts WHERE project_id=? ORDER BY created_at DESC").all(t).map(hS)}}function BT(t){let e=t.drafts.get(t.draftId);if(!e||e.version!==t.expectedVersion)throw Error(`Application draft ${t.draftId} changed since version ${t.expectedVersion}`);if(e.status==="applied")throw Error("Application draft was already applied");let r=t.controlPlane.getProject(e.projectId),d=r?t.controlPlane.listEnvironments(r.id).find((i)=>i.id===e.input.environmentId):void 0;if(!r||!d||d.projectId!==r.id||r.organizationId!==e.organizationId)throw Error("Draft deployment scope was not found");if(t.confirmEnvironment!==d.slug)throw Error(`Type ${d.slug} to confirm this deployment target`);let E=yr(e.input,e.suppliedSecretNames);if(!E.valid)throw Error(`Application plan is invalid: ${[...E.issues.map((i)=>i.message),...E.missingSecrets.map((i)=>`Missing secret ${i}`)].join("; ")}`);let n=t.controlPlane.listResources(r.id,d.id).find((i)=>i.kind==="application"&&i.slug===e.input.slug),c=JSON.parse(JSON.stringify({manifest:E.manifest,configPatch:E.configPatch})),_=n?t.controlPlane.updateResource(n.id,n.version,{name:e.input.name,desiredState:c}):t.controlPlane.createResource({projectId:r.id,environmentId:d.id,kind:"application",slug:e.input.slug,name:e.input.name,desiredState:c,metadata:{source:"application-onboarding",draftId:e.id}}),T=new gt(t.controlPlane).enqueue({projectId:r.id,environmentId:d.id,resourceId:_.id,actorId:t.actorId,kind:"application.create",idempotencyKey:`application-draft:${e.id}:v${e.version}`,correlationId:`application-draft:${e.id}`,input:c,lockKey:`resource:${_.id}`,providerKey:_.provider??"default",buildSlot:e.input.build.kind!=="prebuilt_image",maxAttempts:3,retryClasses:["network","provider_throttled","provider_unavailable"],resumePolicy:"fail",cancellationMode:"provider_non_cancellable",retentionDays:90}).operation;return t.drafts.markApplied(e.id,e.version,t.actorId),t.controlPlane.appendEvent({organizationId:e.organizationId,projectId:r.id,resourceId:_.id,operationId:T.id,actorId:t.actorId,type:"application.create.queued",payload:{draftId:e.id,environment:d.slug,strategy:e.input.build.kind,costDrivers:E.costDrivers}}),{plan:E,resource:_,operation:T}}function oc(t){let e=["static","compute","serverless_zip","serverless_image"].includes(t.kind),r=["container","compose"].includes(t.kind)&&(t.replicas??1)>1,d=t.kind==="container"||t.kind==="serverless_zip"||t.kind==="serverless_image",E=(n,c)=>c&&(n==="atomic"?t.kind==="static"||t.hasHealthGate:t.hasHealthGate);return[{strategy:"atomic",supported:E("atomic",e),explanation:e?t.hasHealthGate||t.kind==="static"?"Activate an immutable version with an atomic pointer/alias switch.":"Atomic activation needs a readiness gate for this runtime.":"This driver has no atomic pointer or alias primitive.",capacityMultiplier:1,costImpact:"none",rollback:"Switch the pointer/alias back to the previous immutable release."},{strategy:"rolling",supported:E("rolling",r),explanation:r?t.hasHealthGate?"Replace healthy replicas within the configured capacity envelope.":"Rolling activation requires a health/readiness gate.":"Rolling activation requires a capable container/Compose driver and at least two replicas.",capacityMultiplier:1.5,costImpact:"temporary",rollback:"Stop replacement and restore the prior task/service definition."},{strategy:"blue_green",supported:E("blue_green",d),explanation:d?t.hasHealthGate?"Provision a complete green target and switch traffic after health passes.":"Blue-green requires a health gate before traffic can switch.":"The provider does not expose two traffic-addressable revisions.",capacityMultiplier:2,costImpact:"temporary",rollback:"Return all traffic to the preserved blue target."},{strategy:"canary",supported:E("canary",d),explanation:d?t.hasHealthGate?"Shift bounded traffic steps while evaluating health.":"Canary requires a health gate and measurable traffic target.":"The provider does not expose weighted traffic primitives.",capacityMultiplier:1.25,costImpact:"temporary",rollback:"Set canary weight to zero and preserve its diagnostics."}]}function JT(t,e){let r=oc(t).find((d)=>d.strategy===e);if(!r.supported)throw Error(`${e} is unavailable: ${r.explanation}`);return r}import{createHash as B$}from"node:crypto";var J$=/^sha256:[a-f0-9]{64}$/,H$=/^[a-f0-9]{40,64}$/i;function Kr(t){return typeof t==="string"&&t?t:void 0}function UE(t,e){try{return JSON.parse(String(t))}catch{return e}}function xC(t){return{id:String(t.id),organizationId:String(t.organization_id),digest:String(t.digest),kind:String(t.kind),uri:String(t.uri),size:Number(t.size),mediaType:String(t.media_type),provenance:UE(t.provenance,{}),attestation:UE(t.attestation,{}),verifiedAt:String(t.verified_at),createdAt:String(t.created_at)}}function qC(t){return{id:String(t.id),organizationId:String(t.organization_id),projectId:String(t.project_id),environmentId:String(t.environment_id),resourceId:String(t.resource_id),artifactId:String(t.artifact_id),kind:String(t.kind),sourceSha:Kr(t.source_sha),configHash:String(t.config_hash),manifest:UE(t.manifest,{}),provenance:UE(t.provenance,{}),strategy:String(t.strategy),status:String(t.status),healthGate:t.health_gate==null?void 0:UE(t.health_gate,void 0),hooks:UE(t.hooks,{migrations:"none",preActivate:[],postActivate:[]}),drainSeconds:Number(t.drain_seconds),graceSeconds:Number(t.grace_seconds),automaticRollback:Number(t.automatic_rollback)===1,rollbackAttempts:Number(t.rollback_attempts),previousReleaseId:Kr(t.previous_release_id),promotedFromReleaseId:Kr(t.promoted_from_release_id),actorId:Kr(t.actor_id),trigger:String(t.trigger),pinned:Number(t.pinned)===1,pinReason:Kr(t.pin_reason),activatedAt:Kr(t.activated_at),failedAt:Kr(t.failed_at),createdAt:String(t.created_at),updatedAt:String(t.updated_at)}}function W$(t){return{sequence:Number(t.sequence),id:String(t.id),releaseId:String(t.release_id),fromStatus:Kr(t.from_status),toStatus:String(t.to_status),trafficPercent:t.traffic_percent==null?void 0:Number(t.traffic_percent),health:UE(t.health,{}),message:String(t.message),operationId:Kr(t.operation_id),createdAt:String(t.created_at)}}function v$(t,e){let r=[],d=(E,n,c)=>{if(JSON.stringify(n)===JSON.stringify(c))return;if(n&&c&&typeof n==="object"&&typeof c==="object"&&!Array.isArray(n)&&!Array.isArray(c)){for(let _ of[...new Set([...Object.keys(n),...Object.keys(c)])].sort())d(E?`${E}.${_}`:_,n[_],c[_]);return}r.push({path:E,...n!==void 0?{before:n}:{},...c!==void 0?{after:c}:{}})};return d("",t,e),r}class SS{controlPlane;now;id;constructor(t,e={}){this.controlPlane=t;this.now=e.now??(()=>new Date),this.id=e.id??(()=>crypto.randomUUID())}registerArtifact(t){if(!J$.test(t.digest)||!/^(?:s3|https|oci|file):/.test(t.uri)||!Number.isInteger(t.size)||t.size<0)throw Error("Artifact requires a SHA-256 digest, supported immutable URI, and non-negative byte size");let e=this.controlPlane.database.query("SELECT * FROM release_artifacts WHERE organization_id=? AND digest=?").get(t.organizationId,t.digest);if(e)return xC(e);let r=this.id(),d=this.now().toISOString();return this.controlPlane.database.run("INSERT INTO release_artifacts (id, organization_id, digest, kind, uri, size, media_type, provenance, attestation, verified_at, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",[r,t.organizationId,t.digest,t.kind,t.uri,t.size,t.mediaType??"application/octet-stream",JSON.stringify(ut(t.provenance??{})),JSON.stringify(ut(t.attestation??{})),d,d]),this.getArtifact(r)}getArtifact(t){let e=this.controlPlane.database.query("SELECT * FROM release_artifacts WHERE id=?").get(t);return e?xC(e):void 0}create(t){let e=this.getArtifact(t.artifactId),r=this.controlPlane.getResource(t.resourceId),d=this.controlPlane.listEnvironments(t.projectId).find((R)=>R.id===t.environmentId);if(!e||e.organizationId!==t.organizationId||e.kind!==t.kind)throw Error("Release artifact does not match the organization and deployable kind");if(!r||r.projectId!==t.projectId||r.environmentId!==t.environmentId||!d)throw Error("Release target scope does not match the resource");if(t.sourceSha&&!H$.test(t.sourceSha))throw Error("Release source must be an immutable commit SHA");JT({kind:t.kind,provider:r.provider,hasHealthGate:!!t.healthGate,replicas:t.replicas},t.strategy);let E=ut(t.config),n=B$("sha256").update(JSON.stringify(E)).digest("hex"),c=this.active(t.resourceId),_=this.id(),T=this.now().toISOString(),i=t.approvalRequired?"awaiting_approval":"built",h=t.hooks??{migrations:"none",preActivate:[],postActivate:[]};return this.controlPlane.database.run("INSERT INTO releases (id, organization_id, project_id, environment_id, resource_id, artifact_id, kind, source_sha, config_hash, manifest, provenance, strategy, status, health_gate, hooks, drain_seconds, grace_seconds, automatic_rollback, previous_release_id, promoted_from_release_id, actor_id, trigger, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",[_,t.organizationId,t.projectId,t.environmentId,t.resourceId,t.artifactId,t.kind,t.sourceSha??null,n,JSON.stringify(ut(t.manifest)),JSON.stringify(ut(t.provenance??{})),t.strategy,i,t.healthGate?JSON.stringify(t.healthGate):null,JSON.stringify(h),Math.max(0,Math.min(3600,Math.floor(t.drainSeconds??30))),Math.max(0,Math.min(3600,Math.floor(t.graceSeconds??30))),t.automaticRollback===!1?0:1,c?.id??null,t.promotedFromReleaseId??null,t.actorId??null,t.trigger??"manual",T,T]),this.recordTransition(_,void 0,i,{message:t.promotedFromReleaseId?"Immutable artifact promoted without rebuild.":"Immutable release record created."}),this.get(_)}get(t){let e=this.controlPlane.database.query("SELECT * FROM releases WHERE id=?").get(t);return e?qC(e):void 0}list(t={}){return this.controlPlane.database.query("SELECT * FROM releases ORDER BY created_at DESC, rowid DESC").all().map(qC).filter((e)=>(!t.projectId||e.projectId===t.projectId)&&(!t.environmentId||e.environmentId===t.environmentId)&&(!t.resourceId||e.resourceId===t.resourceId)&&(!t.status||e.status===t.status))}active(t){return this.list({resourceId:t,status:"active"})[0]}transitions(t){return this.controlPlane.database.query("SELECT * FROM release_transitions WHERE release_id=? ORDER BY sequence").all(t).map(W$)}recordTransition(t,e,r,d){this.controlPlane.database.run("INSERT INTO release_transitions (id, release_id, from_status, to_status, traffic_percent, health, message, operation_id, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)",[this.id(),t,e??null,r,d.trafficPercent??null,JSON.stringify(ut(d.health??{})),d.message.slice(0,1000),d.operationId??null,this.now().toISOString()])}progress(t,e){let r=this.get(t);if(!r)throw Error(`Release ${t} was not found`);return this.recordTransition(t,r.status,r.status,e),this.transitions(t).at(-1)}transition(t,e,r){let d=this.get(t);if(!d)throw Error(`Release ${t} was not found`);if(!{built:["awaiting_approval","activating","failed"],awaiting_approval:["built","failed"],activating:["active","failed","rolled_back"],active:["superseded","failed","rolled_back"],failed:["activating","rolled_back"],rolled_back:["activating"],superseded:["activating"]}[d.status].includes(e))throw Error(`Invalid release transition ${d.status} → ${e}`);let n=this.now().toISOString();if(e==="active"){let c=this.active(d.resourceId);if(c&&c.id!==t)this.controlPlane.database.run("UPDATE releases SET status='superseded', updated_at=? WHERE id=?",[n,c.id]),this.recordTransition(c.id,"active","superseded",{message:`Superseded by ${t}.`,operationId:r.operationId})}return this.controlPlane.database.run("UPDATE releases SET status=?, rollback_attempts=rollback_attempts+?, activated_at=CASE WHEN ?='active' THEN ? ELSE activated_at END, failed_at=CASE WHEN ?='failed' THEN ? ELSE failed_at END, updated_at=? WHERE id=?",[e,e==="rolled_back"?1:0,e,n,e,n,n,t]),this.recordTransition(t,d.status,e,r),this.get(t)}approve(t,e){let r=this.get(t);if(!r||r.status!=="awaiting_approval")throw Error("Release is not awaiting approval");let d=this.id(),E=this.now().toISOString();return this.controlPlane.database.run("INSERT INTO release_approvals (id, release_id, environment_id, decision, actor_id, comment, created_at) VALUES (?, ?, ?, ?, ?, ?, ?)",[d,t,r.environmentId,e.decision,e.actorId,e.comment?.slice(0,1000)??null,E]),this.transition(t,e.decision==="approved"?"built":"failed",{message:e.decision==="approved"?"Environment gate approved.":"Environment gate rejected."})}approvals(t){return this.controlPlane.database.query("SELECT * FROM release_approvals WHERE release_id=? ORDER BY created_at").all(t).map((e)=>({id:String(e.id),releaseId:String(e.release_id),environmentId:String(e.environment_id),decision:String(e.decision),actorId:String(e.actor_id),comment:Kr(e.comment),createdAt:String(e.created_at)}))}promote(t,e){let r=this.get(t);if(!r||!["active","superseded"].includes(r.status))throw Error("Only a tested active/superseded release can be promoted");return this.create({organizationId:r.organizationId,projectId:r.projectId,environmentId:e.targetEnvironmentId,resourceId:e.targetResourceId,artifactId:r.artifactId,kind:r.kind,sourceSha:r.sourceSha,config:e.config,manifest:r.manifest,provenance:r.provenance,strategy:e.strategy??r.strategy,healthGate:e.healthGate??r.healthGate,hooks:r.hooks,drainSeconds:r.drainSeconds,graceSeconds:r.graceSeconds,automaticRollback:r.automaticRollback,promotedFromReleaseId:r.id,actorId:e.actorId,trigger:"promotion",approvalRequired:e.approvalRequired})}compare(t,e){let r=this.get(t),d=this.get(e);if(!r||!d)throw Error("Both releases are required for comparison");return{artifactChanged:r.artifactId!==d.artifactId,sourceChanged:r.sourceSha!==d.sourceSha,configChanged:r.configHash!==d.configHash,manifestChanges:v$(r.manifest,d.manifest),dataCaveat:d.hooks.migrations==="none"?"No database migration is recorded.":`Database hooks are ${d.hooks.migrations}; release rollback does not roll back data.`}}pin(t,e,r){if(!this.get(t))throw Error("Release was not found");return this.controlPlane.database.run("UPDATE releases SET pinned=?, pin_reason=?, updated_at=? WHERE id=?",[e?1:0,e?r?.slice(0,500)??"operator":null,this.now().toISOString(),t]),this.get(t)}retentionCandidates(t){let e=Math.max(1,Math.min(100,Math.floor(t.keepPerResource??10))),r=new Map;for(let d of this.list()){let E=r.get(d.resourceId)??[];E.push(d),r.set(d.resourceId,E)}return[...r.values()].flatMap((d)=>d.slice(e)).filter((d)=>new Date(d.createdAt)<t.before&&!d.pinned&&!["active","activating","awaiting_approval"].includes(d.status)&&!this.list().some((E)=>E.previousReleaseId===d.id&&["active","activating"].includes(E.status)))}}class wE{controlPlane;releases;queue;constructor(t){this.controlPlane=t;this.releases=new SS(t),this.queue=new gt(t)}enqueueActivation(t,e={}){let r=this.releases.get(t.id);if(!r)throw Error("Release was not found");if(!["built","failed","rolled_back","superseded"].includes(r.status))throw Error(`Release ${r.status} cannot be activated`);let d=e.action??"activate",E=this.queue.enqueue({projectId:r.projectId,environmentId:r.environmentId,resourceId:r.resourceId,actorId:e.actorId,kind:`release.${d}`,idempotencyKey:`release:${r.id}:${d}:${r.rollbackAttempts}`,correlationId:`release:${r.id}`,input:{releaseId:r.id,targetReleaseId:e.targetReleaseId??null},lockKey:`resource:${r.resourceId}`,providerKey:this.controlPlane.getResource(r.resourceId)?.provider??"default",maxAttempts:r.automaticRollback?2:1,retryClasses:["network","provider_throttled","provider_unavailable"],resumePolicy:"fail",cancellationMode:"provider_non_cancellable",retentionDays:365}).operation;return this.releases.transition(r.id,"activating",{message:`${d} queued.`,operationId:E.id,trafficPercent:0}),E}completeHealthGate(t,e){let r=this.releases.get(t);if(!r||r.status!=="activating")throw Error("Release is not activating");if(e.healthy)return{release:this.releases.transition(r.id,"active",{message:e.message??"Health gate passed; activation completed.",operationId:e.operationId,trafficPercent:100,health:e.health})};let d=this.releases.transition(r.id,"failed",{message:e.message??"Health gate failed.",operationId:e.operationId,trafficPercent:0,health:e.health}),E=r.previousReleaseId?this.releases.get(r.previousReleaseId):void 0;if(!r.automaticRollback||r.rollbackAttempts>=1||!E)return{release:d};let n=this.queue.enqueue({projectId:r.projectId,environmentId:r.environmentId,resourceId:r.resourceId,kind:"release.rollback",idempotencyKey:`release:${r.id}:automatic-rollback`,correlationId:`release:${r.id}`,input:{releaseId:r.id,targetReleaseId:E.id,automatic:!0},lockKey:`resource:${r.resourceId}`,providerKey:this.controlPlane.getResource(r.resourceId)?.provider??"default",maxAttempts:1,retryClasses:[],resumePolicy:"fail",cancellationMode:"provider_non_cancellable",retentionDays:365}).operation;return{release:d,rollbackOperation:n}}enqueueRollback(t,e={}){let r=this.releases.get(t.id);if(!r||r.status!=="active")throw Error("Only the active release can be rolled back");let d=e.targetReleaseId?this.releases.get(e.targetReleaseId):r.previousReleaseId?this.releases.get(r.previousReleaseId):void 0;if(!d||d.resourceId!==r.resourceId||!["superseded","active"].includes(d.status))throw Error("Rollback requires a preserved prior release for the same resource");return this.queue.enqueue({projectId:r.projectId,environmentId:r.environmentId,resourceId:r.resourceId,actorId:e.actorId,kind:"release.rollback",idempotencyKey:`release:${r.id}:manual-rollback:${d.id}`,correlationId:`release:${r.id}`,input:{releaseId:r.id,targetReleaseId:d.id,automatic:!1},lockKey:`resource:${r.resourceId}`,providerKey:this.controlPlane.getResource(r.resourceId)?.provider??"default",maxAttempts:1,retryClasses:[],resumePolicy:"fail",cancellationMode:"provider_non_cancellable",retentionDays:365}).operation}}function Q$(t){if(t.strategy==="canary")return[5,25,50,100].map((e,r)=>({step:`canary-${e}`,trafficPercent:e,waitSeconds:r===3?t.drainSeconds:t.graceSeconds,requiresHealth:!0}));if(t.strategy==="blue_green")return[{step:"green-health",trafficPercent:0,waitSeconds:t.graceSeconds,requiresHealth:!0},{step:"traffic-switch",trafficPercent:100,waitSeconds:t.drainSeconds,requiresHealth:!0}];if(t.strategy==="rolling")return[{step:"rolling-replacement",trafficPercent:50,waitSeconds:t.graceSeconds,requiresHealth:!0},{step:"rolling-complete",trafficPercent:100,waitSeconds:t.drainSeconds,requiresHealth:!0}];return[{step:"immutable-switch",trafficPercent:100,waitSeconds:t.drainSeconds,requiresHealth:!!t.healthGate}]}async function sC(t,e){if(e.release.artifactId!==e.artifact.id)throw Error("Release activation artifact identity changed");JT({kind:e.release.kind,hasHealthGate:!!e.release.healthGate,replicas:Number(e.release.manifest?.replicas)||void 0},e.release.strategy);let r=t.capability(e);if(!r.supported)throw Error(`${e.release.strategy} is unavailable in ${t.name}: ${r.explanation}`);return t.activate({...e,transitions:Q$(e.release)})}async function oC(t,e){if(!e.previous)throw Error("Rollback requires the preserved previous release");return t.rollback({...e,transitions:[{step:"rollback",trafficPercent:0,waitSeconds:e.release.drainSeconds,requiresHealth:!0}]})}var Y$=["release.activate","release.rollback"];function M$(t){return t&&typeof t==="object"&&!Array.isArray(t)?t:{}}function mC(t){let e=new wE(t.store),r=async(d)=>{let E=M$(d.operation.input),n=typeof E.releaseId==="string"?E.releaseId:"",c=e.releases.get(n);if(!c)throw Error(`Queued release ${n||"(missing)"} was not found`);if(c.projectId!==d.operation.projectId||c.environmentId!==d.operation.environmentId||c.resourceId!==d.operation.resourceId)throw Error("Queued release does not match the operation scope");let _=e.releases.getArtifact(c.artifactId);if(!_||_.digest!==e.releases.getArtifact(c.artifactId)?.digest)throw Error("Immutable release artifact is unavailable");let T=typeof E.targetReleaseId==="string"&&E.targetReleaseId?E.targetReleaseId:c.previousReleaseId,i=T?e.releases.get(T):void 0;if(i&&(i.resourceId!==c.resourceId||i.artifactId===c.artifactId&&i.id===c.id))throw Error("Rollback target does not match the release resource");let h=await t.resolveDriver(c);d.checkpoint("verify",`Verifying ${_.digest} and ${c.configHash} for ${h.name}.`),d.log(`Artifact ${_.digest}; source ${c.sourceSha??"not recorded"}; config ${c.configHash}.`,{stream:"system"}),d.throwIfCancellationRequested();let R;try{R=d.operation.kind==="release.rollback"?await oC(h,{release:c,artifact:_,previous:i}):await sC(h,{release:c,artifact:_,previous:i})}catch(N){if(d.operation.kind==="release.activate"&&e.releases.get(c.id)?.status==="activating")e.completeHealthGate(c.id,{healthy:!1,operationId:d.operation.id,message:N instanceof Error?N.message:String(N)});throw N}for(let N of R.transitions)e.releases.progress(c.id,{message:`${d.operation.kind==="release.rollback"?"Rollback":"Activation"} traffic at ${N.trafficPercent}%.`,trafficPercent:N.trafficPercent,health:N.observed,operationId:d.operation.id}),d.log(`Traffic ${N.trafficPercent}%: ${N.healthy?"healthy":"unhealthy"}.`,{stream:N.healthy?"step":"stderr",step:"health"});if(d.checkpoint("health","Evaluating the provider health result."),!R.activated||!R.healthy){if(d.operation.kind==="release.activate"&&e.releases.get(c.id)?.status==="activating")e.completeHealthGate(c.id,{healthy:!1,operationId:d.operation.id,health:{resourceVersions:R.resourceVersions},message:R.error??"Provider health gate failed."});throw Error(R.error??`${h.name} reported an unhealthy release`)}if(d.operation.kind==="release.activate"&&c.healthGate?.name){if(!t.resolveHealthGate)throw e.completeHealthGate(c.id,{healthy:!1,operationId:d.operation.id,message:`Named health gate ${c.healthGate.name} is not available to this worker.`}),Error(`Named health gate ${c.healthGate.name} is unavailable`);d.checkpoint("named-health-gate",`Waiting on ${c.healthGate.name}.`);let N=await t.resolveHealthGate(c.healthGate.name,c);if(d.log(`${c.healthGate.name}: ${N.healthy?"healthy":"unhealthy"}${N.message?` — ${N.message}`:""}.`,{stream:N.healthy?"step":"stderr",step:"health"}),!N.healthy)throw e.completeHealthGate(c.id,{healthy:!1,operationId:d.operation.id,health:N.evidence,message:N.message??`Named health gate ${c.healthGate.name} failed.`}),Error(N.message??`Named health gate ${c.healthGate.name} failed`)}if(d.operation.kind==="release.rollback"){let N=e.releases.get(c.id);if(N.status!=="rolled_back")e.releases.transition(N.id,"rolled_back",{message:`Traffic restored through ${h.name}.`,operationId:d.operation.id,trafficPercent:0,health:{resourceVersions:R.resourceVersions}});if(i&&i.status!=="active"){let A=i.status==="activating"?i:e.releases.transition(i.id,"activating",{message:"Rollback target restoring traffic.",operationId:d.operation.id,trafficPercent:0});e.releases.transition(A.id,"active",{message:"Previous immutable release restored.",operationId:d.operation.id,trafficPercent:100,health:{resourceVersions:R.resourceVersions}})}}else e.completeHealthGate(c.id,{healthy:!0,operationId:d.operation.id,health:{providerVersion:R.providerVersion??null,resourceVersions:R.resourceVersions},message:"Provider activation and health gates completed."});return d.checkpoint("finalize","Persisted the terminal release state."),{releaseId:c.id,artifactDigest:_.digest,provider:h.name,providerVersion:R.providerVersion??null,resourceVersions:R.resourceVersions,status:e.releases.get(c.id).status}};return Object.fromEntries(Y$.map((d)=>[d,r]))}import{createCipheriv as G$,createDecipheriv as V$,createHash as d0,randomBytes as NS}from"node:crypto";var E0={github:{repositories:!0,branches:!0,tags:!0,webhooks:!0,pullRequests:!0,tokenRefresh:!0,deployKeys:!0},gitlab:{repositories:!0,branches:!0,tags:!0,webhooks:!0,pullRequests:!0,tokenRefresh:!0,deployKeys:!0},bitbucket:{repositories:!0,branches:!0,tags:!0,webhooks:!0,pullRequests:!0,tokenRefresh:!0,deployKeys:!0},gitea:{repositories:!0,branches:!0,tags:!0,webhooks:!0,pullRequests:!0,tokenRefresh:!1,deployKeys:!0},generic_https:{repositories:!1,branches:!0,tags:!0,webhooks:!1,pullRequests:!1,tokenRefresh:!1,deployKeys:!1},generic_ssh:{repositories:!1,branches:!0,tags:!0,webhooks:!1,pullRequests:!1,tokenRefresh:!1,deployKeys:!0}};function vt(t){return typeof t==="string"&&t?t:void 0}function $E(t,e){try{return typeof t==="string"?JSON.parse(t):e}catch{return e}}function Zr(t){return JSON.stringify(ut(t))}function gE(t){return d0("sha256").update(t).digest("hex")}function pC(t){let e=t.trim().replace(/\/$/,""),r=new URL(e.includes("://")?e:`https://${e}`);if(r.username||r.password||r.search||r.hash)throw Error("Source host cannot contain credentials, a query, or a fragment");if(r.protocol!=="https:"&&!(r.protocol==="http:"&&["localhost","127.0.0.1","::1"].includes(r.hostname)))throw Error("Source host must use HTTPS");return`${r.protocol}//${r.host}${r.pathname.replace(/\/$/,"")}`}function t0(t){let e=t.trim();if(e.length<2||e.length>80)throw Error("Connection name must contain 2-80 characters");return e}function AS(t){let e=t.trim().replace(/^\/+|\/+$/g,"");if(!/^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/.test(e))throw Error("Repository must use owner/name format");return e}function e0(t){let e=t.trim()||".";if(e.startsWith("/")||e.split("/").includes("..")||/[\0\r\n]/.test(e))throw Error("Monorepo root must stay inside the repository");return e.replace(/^\.\//,"")||"."}function HT(t){return[...new Set((t??[]).map((e)=>e.trim()).filter(Boolean))].slice(0,100)}function K$(t){let e=t.trim();if(/\r|\n/.test(e)||/https?:\/\/[^/@\s]+:[^/@\s]+@/i.test(e))throw Error("Clone URL cannot contain credentials or control characters");if(!/^(?:https?:\/\/|ssh:\/\/|git@[A-Za-z0-9.-]+:)/.test(e))throw Error("Clone URL must use HTTPS or SSH");return e}function Z$(t){return{id:String(t.id),organizationId:String(t.organization_id),provider:String(t.provider),name:String(t.name),host:String(t.host),owner:vt(t.owner),authKind:String(t.auth_kind),credentialConfigured:!!t.credential_ciphertext,credentialFingerprint:vt(t.credential_fingerprint),grantedScopes:$E(t.granted_scopes,[]),capabilities:$E(t.capabilities,E0[String(t.provider)]),status:String(t.status),healthMessage:vt(t.health_message),lastTestedAt:vt(t.last_tested_at),lastSyncedAt:vt(t.last_synced_at),credentialExpiresAt:vt(t.credential_expires_at),version:Number(t.version),createdByActorId:vt(t.created_by_actor_id),createdAt:String(t.created_at),updatedAt:String(t.updated_at)}}function LS(t){return{id:String(t.id),connectionId:String(t.connection_id),providerRepositoryId:String(t.provider_repository_id),fullName:String(t.full_name),cloneUrl:String(t.clone_url),defaultBranch:String(t.default_branch),visibility:String(t.visibility),archived:Number(t.archived)===1,metadata:$E(t.metadata,{}),syncedAt:String(t.synced_at)}}function r0(t){return{id:String(t.id),projectId:String(t.project_id),environmentId:vt(t.environment_id),resourceId:vt(t.resource_id),connectionId:String(t.connection_id),repositoryId:vt(t.repository_id),repositoryFullName:String(t.repository_full_name),defaultBranch:String(t.default_branch),branchRule:vt(t.branch_rule),tagRule:vt(t.tag_rule),monorepoRoot:String(t.monorepo_root),includePaths:$E(t.include_paths,[]),excludePaths:$E(t.exclude_paths,[]),submodules:Number(t.submodules)===1,cloneDepth:t.clone_depth==null?void 0:Number(t.clone_depth),deployKeyId:vt(t.deploy_key_id),autoDeploy:Number(t.auto_deploy)===1,pullRequestPreviews:Number(t.pull_request_previews)===1,status:String(t.status),disabledReason:vt(t.disabled_reason),version:Number(t.version),createdByActorId:vt(t.created_by_actor_id),createdAt:String(t.created_at),updatedAt:String(t.updated_at)}}function uS(t){return{id:String(t.id),connectionId:String(t.connection_id),name:String(t.name),publicKey:String(t.public_key),publicKeyFingerprint:String(t.public_key_fingerprint),host:String(t.host),hostKey:String(t.host_key),hostKeyFingerprint:String(t.host_key_fingerprint),createdByActorId:vt(t.created_by_actor_id),createdAt:String(t.created_at),updatedAt:String(t.updated_at)}}function OS(t){return{id:String(t.id),connectionId:String(t.connection_id),repositoryId:vt(t.repository_id),repositoryFullName:String(t.repository_full_name),providerWebhookId:vt(t.provider_webhook_id),events:$E(t.events,[]),status:String(t.status),healthMessage:vt(t.health_message),lastDeliveryAt:vt(t.last_delivery_at),lastReconciledAt:vt(t.last_reconciled_at),createdAt:String(t.created_at),updatedAt:String(t.updated_at)}}function CS(t){return{id:String(t.id),connectionId:String(t.connection_id),webhookId:String(t.webhook_id),providerDeliveryId:String(t.provider_delivery_id),event:String(t.event),action:vt(t.action),commitSha:vt(t.commit_sha),signatureStatus:String(t.signature_status),status:String(t.status),payloadSummary:$E(t.payload_summary,{}),operationId:vt(t.operation_id),error:vt(t.error),receivedAt:String(t.received_at),processedAt:vt(t.processed_at)}}class lS{controlPlane;key;nowFn;idFn;constructor(t,e={}){this.controlPlane=t;this.key=e.encryptionKey?d0("sha256").update(e.encryptionKey).digest():void 0,this.nowFn=e.now??(()=>new Date),this.idFn=e.id??(()=>crypto.randomUUID())}now(){return this.nowFn().toISOString()}run(t,e){this.controlPlane.database.run(t,e)}encrypt(t){if(!this.key)throw Error("Source credential encryption key is not configured");let e=NS(12),r=G$("aes-256-gcm",this.key,e),d=Buffer.concat([r.update(t,"utf8"),r.final()]);return`v1.${e.toString("base64url")}.${r.getAuthTag().toString("base64url")}.${d.toString("base64url")}`}decrypt(t){if(!this.key)throw Error("Source credential encryption key is not configured");let[e,r,d,E]=t.split(".");if(e!=="v1"||!r||!d||!E)throw Error("Encrypted source credential is unavailable");let n=V$("aes-256-gcm",this.key,Buffer.from(r,"base64url"));return n.setAuthTag(Buffer.from(d,"base64url")),Buffer.concat([n.update(Buffer.from(E,"base64url")),n.final()]).toString("utf8")}createConnection(t){if(!this.controlPlane.getOrganization(t.organizationId))throw Error("Source connection organization was not found");let e=this.now(),r=this.idFn(),d=t.credential?JSON.stringify(t.credential):void 0;return this.run(`INSERT INTO source_connections (id, organization_id, provider, name, host, owner, auth_kind, credential_ciphertext, credential_fingerprint, granted_scopes, capabilities, status, credential_expires_at, created_by_actor_id, created_at, updated_at)
|
|
5496
5496
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'pending', ?, ?, ?, ?)`,[r,t.organizationId,t.provider,t0(t.name),pC(t.host),t.owner?.trim()||null,t.authKind??(d?"access_token":"none"),d?this.encrypt(d):null,d?gE(d).slice(0,16):null,Zr([...new Set(t.grantedScopes??[])].sort()),Zr(E0[t.provider]),t.credentialExpiresAt??null,t.createdByActorId??null,e,e]),this.controlPlane.appendEvent({organizationId:t.organizationId,actorId:t.createdByActorId,type:"source.connection.created",payload:{connectionId:r,provider:t.provider,host:pC(t.host),owner:t.owner??null,scopes:t.grantedScopes??[]}}),this.getConnection(r)}getConnection(t){let e=this.controlPlane.database.query("SELECT * FROM source_connections WHERE id = ?").get(t);return e?this.currentConnection(e):void 0}listConnections(t){return this.controlPlane.database.query("SELECT * FROM source_connections WHERE organization_id = ? ORDER BY name").all(t).map((e)=>this.currentConnection(e))}currentConnection(t){let e=Z$(t);if(e.status!=="disconnected"&&e.credentialExpiresAt&&new Date(e.credentialExpiresAt).getTime()<=this.nowFn().getTime())return{...e,status:"expired",healthMessage:"Source credential expired; rotate it before deploying."};return e}getCredential(t){let e=this.controlPlane.database.query("SELECT credential_ciphertext FROM source_connections WHERE id = ?").get(t);return e?.credential_ciphertext?JSON.parse(this.decrypt(String(e.credential_ciphertext))):void 0}rotateCredential(t,e,r={}){let d=this.getConnection(t);if(!d||d.status==="disconnected")throw Error("Active source connection was not found");let E=JSON.stringify(e);return this.run("UPDATE source_connections SET credential_ciphertext = ?, credential_fingerprint = ?, credential_expires_at = ?, status = 'pending', health_message = NULL, version = version + 1, updated_at = ? WHERE id = ?",[this.encrypt(E),gE(E).slice(0,16),r.expiresAt??null,this.now(),t]),this.controlPlane.appendEvent({organizationId:d.organizationId,actorId:r.actorId,type:"source.credential.rotated",payload:{connectionId:t,fingerprint:gE(E).slice(0,16),expiresAt:r.expiresAt??null}}),this.getConnection(t)}updateHealth(t,e){let r=this.getConnection(t);if(!r||["disconnected","expired"].includes(r.status))throw Error("Active source connection was not found");let d=this.now(),E=e.grantedScopes?[...new Set(e.grantedScopes.map((n)=>n.trim()).filter(Boolean))].sort():void 0;if(this.run("UPDATE source_connections SET status = ?, health_message = ?, granted_scopes = COALESCE(?, granted_scopes), last_tested_at = COALESCE(?, last_tested_at), last_synced_at = COALESCE(?, last_synced_at), version = version + 1, updated_at = ? WHERE id = ?",[e.status,e.message?.slice(0,1000)??null,E?Zr(E):null,e.tested?d:null,e.synced?d:null,d,t]),E&&JSON.stringify(E)!==JSON.stringify([...r.grantedScopes].sort()))this.controlPlane.appendEvent({organizationId:r.organizationId,type:"source.connection.scopes_updated",payload:{connectionId:t,grantedScopes:E}});return this.getConnection(t)}upsertRepository(t){let e=this.getConnection(t.connectionId);if(!e||["disconnected","expired"].includes(e.status))throw Error("Active source connection was not found");let r=this.now(),d=this.controlPlane.database.query("SELECT id FROM source_repositories WHERE connection_id = ? AND provider_repository_id = ?").get(t.connectionId,t.providerRepositoryId),E=d?String(d.id):this.idFn();return this.run(`INSERT INTO source_repositories (id, connection_id, provider_repository_id, full_name, clone_url, default_branch, visibility, archived, metadata, synced_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
5497
5497
|
ON CONFLICT(connection_id, provider_repository_id) DO UPDATE SET full_name=excluded.full_name, clone_url=excluded.clone_url, default_branch=excluded.default_branch, visibility=excluded.visibility, archived=excluded.archived, metadata=excluded.metadata, synced_at=excluded.synced_at`,[E,t.connectionId,t.providerRepositoryId,AS(t.fullName),K$(t.cloneUrl),t.defaultBranch.trim()||"main",t.visibility,t.archived?1:0,Zr(t.metadata),r]),LS(this.controlPlane.database.query("SELECT * FROM source_repositories WHERE id = ?").get(E))}listRepositories(t,e,r=100){let d=e?.trim().toLowerCase();return(d?this.controlPlane.database.query("SELECT * FROM source_repositories WHERE connection_id = ? AND lower(full_name) LIKE ? ORDER BY full_name LIMIT ?").all(t,`%${d}%`,Math.min(500,r)):this.controlPlane.database.query("SELECT * FROM source_repositories WHERE connection_id = ? ORDER BY full_name LIMIT ?").all(t,Math.min(500,r))).map(LS)}getRepository(t){let e=this.controlPlane.database.query("SELECT * FROM source_repositories WHERE id = ?").get(t);return e?LS(e):void 0}createDeployKey(t){let e=this.getConnection(t.connectionId);if(!e||["disconnected","expired"].includes(e.status)||!e.capabilities.deployKeys)throw Error("An active deploy-key capable source connection is required");if(!/^ssh-(?:ed25519|rsa)\s+[A-Za-z0-9+/=]+/.test(t.publicKey.trim()))throw Error("A valid SSH public key is required");if(!/BEGIN (?:OPENSSH|RSA) PRIVATE KEY/.test(t.privateKey))throw Error("A valid SSH private key is required");if(!/^(?:ssh-ed25519|ssh-rsa|ecdsa-sha2-nistp\d+)\s+[A-Za-z0-9+/=]+/.test(t.hostKey.trim()))throw Error("A pinned SSH host key is required");let r=this.idFn(),d=this.now(),E=`sha256:${gE(t.publicKey.trim())}`,n=`sha256:${gE(t.hostKey.trim())}`;return this.run("INSERT INTO source_deploy_keys (id, connection_id, name, public_key, public_key_fingerprint, private_key_ciphertext, host, host_key, host_key_fingerprint, created_by_actor_id, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",[r,t.connectionId,t0(t.name),t.publicKey.trim(),E,this.encrypt(t.privateKey),t.host.trim().toLowerCase(),t.hostKey.trim(),n,t.actorId??null,d,d]),this.controlPlane.appendEvent({organizationId:e.organizationId,actorId:t.actorId,type:"source.deploy_key.created",payload:{connectionId:t.connectionId,deployKeyId:r,publicFingerprint:E,hostFingerprint:n}}),uS(this.controlPlane.database.query("SELECT * FROM source_deploy_keys WHERE id = ?").get(r))}getDeployKey(t){let e=this.controlPlane.database.query("SELECT * FROM source_deploy_keys WHERE id = ?").get(t);return e?uS(e):void 0}listDeployKeys(t){return this.controlPlane.database.query("SELECT * FROM source_deploy_keys WHERE connection_id = ? ORDER BY name, created_at").all(t).map(uS)}revokeDeployKey(t,e){let r=this.getDeployKey(t),d=r?this.getConnection(r.connectionId):void 0;if(!r||!d)throw Error("Deploy key was not found");let E=this.listBindings({connectionId:d.id}).filter((c)=>c.deployKeyId===t),n=this.now();return this.controlPlane.database.transaction(()=>{this.run("UPDATE source_bindings SET deploy_key_id=NULL, status='disabled', auto_deploy=0, disabled_reason='Source deploy key was revoked', version=version+1, updated_at=? WHERE deploy_key_id=?",[n,t]),this.run("DELETE FROM source_deploy_keys WHERE id=?",[t])})(),this.controlPlane.appendEvent({organizationId:d.organizationId,actorId:e,type:"source.deploy_key.revoked",level:"warning",payload:{connectionId:d.id,deployKeyId:t,affectedBindingIds:E.map((c)=>c.id)}}),{affectedBindings:E}}getDeployPrivateKey(t){let e=this.controlPlane.database.query("SELECT private_key_ciphertext FROM source_deploy_keys WHERE id = ?").get(t);if(!e)throw Error("Deploy key was not found");return this.decrypt(String(e.private_key_ciphertext))}createBinding(t){let e=this.getConnection(t.connectionId);if(!e||["disconnected","expired"].includes(e.status))throw Error("Active source connection was not found");if(t.repositoryId&&this.getRepository(t.repositoryId)?.connectionId!==e.id)throw Error("Repository does not belong to this connection");if(t.deployKeyId&&this.getDeployKey(t.deployKeyId)?.connectionId!==e.id)throw Error("Deploy key does not belong to this connection");let r=this.idFn(),d=this.now();return this.run(`INSERT INTO source_bindings (id, project_id, environment_id, resource_id, connection_id, repository_id, repository_full_name, default_branch, branch_rule, tag_rule, monorepo_root, include_paths, exclude_paths, submodules, clone_depth, deploy_key_id, auto_deploy, pull_request_previews, status, created_by_actor_id, created_at, updated_at)
|
|
5498
5498
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'active', ?, ?, ?)`,[r,t.projectId,t.environmentId??null,t.resourceId??null,t.connectionId,t.repositoryId??null,AS(t.repositoryFullName),t.defaultBranch?.trim()||"main",t.branchRule?.trim()||null,t.tagRule?.trim()||null,e0(t.monorepoRoot??"."),Zr(HT(t.includePaths)),Zr(HT(t.excludePaths)),t.submodules?1:0,t.cloneDepth??null,t.deployKeyId??null,t.autoDeploy===!1?0:1,t.pullRequestPreviews===!1?0:1,t.actorId??null,d,d]),this.controlPlane.appendEvent({organizationId:e.organizationId,projectId:t.projectId,actorId:t.actorId,type:"source.binding.created",payload:{bindingId:r,connectionId:t.connectionId,repository:t.repositoryFullName,branch:t.defaultBranch??"main"}}),this.getBinding(r)}getBinding(t){let e=this.controlPlane.database.query("SELECT * FROM source_bindings WHERE id = ?").get(t);return e?r0(e):void 0}listBindings(t={}){return this.controlPlane.database.query("SELECT * FROM source_bindings ORDER BY created_at DESC").all().map(r0).filter((r)=>(!t.connectionId||r.connectionId===t.connectionId)&&(!t.projectId||r.projectId===t.projectId)&&(!t.status||r.status===t.status))}updateBinding(t,e,r){let d=this.getBinding(t);if(!d||d.version!==e)throw Error(`Source binding ${t} changed since version ${e}`);let E=this.getConnection(d.connectionId);if((!E||["disconnected","expired"].includes(E.status))&&(r.status==="active"||r.autoDeploy===!0))throw Error("Rotate or reconnect the source credential before enabling this binding");if(r.deployKeyId&&this.getDeployKey(r.deployKeyId)?.connectionId!==d.connectionId)throw Error("Deploy key does not belong to this connection");let n=this.now();if(this.controlPlane.database.run("UPDATE source_bindings SET default_branch=?, branch_rule=?, tag_rule=?, monorepo_root=?, include_paths=?, exclude_paths=?, submodules=?, clone_depth=?, deploy_key_id=?, auto_deploy=?, pull_request_previews=?, status=?, disabled_reason=?, version=version+1, updated_at=? WHERE id=? AND version=?",[r.defaultBranch?.trim()||d.defaultBranch,r.branchRule===void 0?d.branchRule??null:r.branchRule.trim()||null,r.tagRule===void 0?d.tagRule??null:r.tagRule.trim()||null,r.monorepoRoot===void 0?d.monorepoRoot:e0(r.monorepoRoot),Zr(r.includePaths===void 0?d.includePaths:HT(r.includePaths)),Zr(r.excludePaths===void 0?d.excludePaths:HT(r.excludePaths)),r.submodules??d.submodules?1:0,r.cloneDepth===void 0?d.cloneDepth??null:r.cloneDepth,r.deployKeyId===void 0?d.deployKeyId??null:r.deployKeyId,r.autoDeploy??d.autoDeploy?1:0,r.pullRequestPreviews??d.pullRequestPreviews?1:0,r.status??d.status,r.disabledReason===void 0?d.disabledReason??null:r.disabledReason.slice(0,1000),n,t,e]).changes!==1)throw Error(`Source binding ${t} changed since version ${e}`);let _=this.getConnection(d.connectionId);return this.controlPlane.appendEvent({organizationId:_.organizationId,projectId:d.projectId,actorId:r.actorId,type:"source.binding.updated",payload:{bindingId:t,fromVersion:e,toVersion:e+1,status:r.status??d.status}}),this.getBinding(t)}createWebhook(t){let e=this.getConnection(t.connectionId);if(!e||["disconnected","expired"].includes(e.status))throw Error("Active source connection was not found");if(t.repositoryId&&this.getRepository(t.repositoryId)?.connectionId!==e.id)throw Error("Repository does not belong to this connection");let r=this.idFn(),d=this.now(),E=t.endpointToken??NS(24).toString("base64url"),n=t.secret??NS(32).toString("base64url"),c=[...new Set(t.events??["push","pull_request"])].filter((_)=>["push","pull_request"].includes(_));if(!c.length)throw Error("At least one supported webhook event is required");return this.run("INSERT INTO source_webhooks (id, connection_id, repository_id, repository_full_name, endpoint_token_hash, endpoint_token_ciphertext, secret_ciphertext, events, status, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, 'pending', ?, ?)",[r,t.connectionId,t.repositoryId??null,AS(t.repositoryFullName),gE(E),this.encrypt(E),this.encrypt(n),Zr(c),d,d]),this.controlPlane.appendEvent({organizationId:e.organizationId,type:"source.webhook.created",payload:{webhookId:r,connectionId:e.id,repository:t.repositoryFullName,events:c}}),{webhook:{...this.getWebhook(r),endpointToken:E},secret:n}}getWebhook(t){let e=this.controlPlane.database.query("SELECT * FROM source_webhooks WHERE id = ?").get(t);return e?OS(e):void 0}getWebhookByEndpointToken(t){let e=this.controlPlane.database.query("SELECT * FROM source_webhooks WHERE endpoint_token_hash = ?").get(gE(t));return e?OS(e):void 0}getWebhookSecret(t){let e=this.controlPlane.database.query("SELECT secret_ciphertext FROM source_webhooks WHERE id = ?").get(t);if(!e)throw Error("Source webhook was not found");return this.decrypt(String(e.secret_ciphertext))}getWebhookEndpointToken(t){let e=this.controlPlane.database.query("SELECT endpoint_token_ciphertext FROM source_webhooks WHERE id = ?").get(t);if(!e?.endpoint_token_ciphertext)throw Error("Source webhook endpoint token is unavailable");return this.decrypt(String(e.endpoint_token_ciphertext))}listWebhooks(t){return this.controlPlane.database.query("SELECT * FROM source_webhooks WHERE connection_id = ? ORDER BY repository_full_name").all(t).map(OS)}updateWebhookState(t,e){let r=this.getWebhook(t);if(!r)throw Error("Source webhook was not found");let d=this.now();this.run("UPDATE source_webhooks SET provider_webhook_id=COALESCE(?, provider_webhook_id), status=?, health_message=?, last_reconciled_at=COALESCE(?, last_reconciled_at), updated_at=? WHERE id=?",[e.providerWebhookId??null,e.status,e.healthMessage?.slice(0,1000)??null,e.reconciled?d:null,d,t]);let E=this.getConnection(r.connectionId);if(E)this.controlPlane.appendEvent({organizationId:E.organizationId,type:"source.webhook.updated",payload:{webhookId:t,connectionId:E.id,repository:r.repositoryFullName,status:e.status,reconciled:e.reconciled??!1,providerWebhookId:e.providerWebhookId??r.providerWebhookId??null}});return this.getWebhook(t)}getDeliveryByProviderId(t,e){let r=this.controlPlane.database.query("SELECT * FROM source_webhook_deliveries WHERE connection_id = ? AND provider_delivery_id = ?").get(t,e);return r?CS(r):void 0}recordDelivery(t){let e=this.getDeliveryByProviderId(t.connectionId,t.providerDeliveryId);if(e)return{delivery:e,duplicate:!0};let r=this.idFn(),d=this.now();return this.controlPlane.database.transaction(()=>{this.run("INSERT INTO source_webhook_deliveries (id, connection_id, webhook_id, provider_delivery_id, event, action, commit_sha, signature_status, status, payload_summary, operation_id, error, received_at, processed_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",[r,t.connectionId,t.webhookId,t.providerDeliveryId,t.event.slice(0,100),t.action?.slice(0,100)??null,t.commitSha?.slice(0,128)??null,t.signatureStatus,t.status,Zr(t.payloadSummary??{}),t.operationId??null,t.error?.slice(0,2000)??null,d,["enqueued","ignored","rejected","failed"].includes(t.status)?d:null]),this.run("UPDATE source_webhooks SET last_delivery_at=?, updated_at=? WHERE id=?",[d,d,t.webhookId])})(),{delivery:this.getDeliveryByProviderId(t.connectionId,t.providerDeliveryId),duplicate:!1}}updateDelivery(t,e){this.run("UPDATE source_webhook_deliveries SET status=?, operation_id=?, error=?, processed_at=? WHERE id=?",[e.status,e.operationId??null,e.error?.slice(0,2000)??null,this.now(),t]);let r=this.controlPlane.database.query("SELECT * FROM source_webhook_deliveries WHERE id = ?").get(t);if(!r)throw Error("Source webhook delivery was not found");return CS(r)}listDeliveries(t,e=100){return this.controlPlane.database.query("SELECT * FROM source_webhook_deliveries WHERE webhook_id = ? ORDER BY received_at DESC LIMIT ?").all(t,Math.min(500,Math.max(1,e))).map(CS)}disconnectConnection(t,e){let r=this.getConnection(t);if(!r)throw Error("Source connection was not found");let d=this.listBindings({connectionId:t,status:"active"}),E=this.now();return this.controlPlane.database.transaction(()=>{this.run("UPDATE source_connections SET status='disconnected', credential_ciphertext=NULL, health_message='Disconnected by an administrator', version=version+1, updated_at=? WHERE id=?",[E,t]),this.run("UPDATE source_bindings SET status='disabled', auto_deploy=0, disabled_reason='Source connection was disconnected', version=version+1, updated_at=? WHERE connection_id=? AND status='active'",[E,t]),this.run("UPDATE source_webhooks SET status='disabled', health_message='Source connection was disconnected', updated_at=? WHERE connection_id=?",[E,t])})(),this.controlPlane.appendEvent({organizationId:r.organizationId,actorId:e,type:"source.connection.disconnected",level:"warning",payload:{connectionId:t,affectedBindingIds:d.map((n)=>n.id),affectedRepositories:d.map((n)=>n.repositoryFullName)}}),{connection:this.getConnection(t),affectedBindings:d}}}import{createSign as k$}from"node:crypto";class $n extends Error{status;retryAfterSeconds;constructor(t,e,r){super(t);this.status=e;this.retryAfterSeconds=r;this.name="SourceProviderError"}}var c0={repositories:!0,branches:!0,tags:!0,webhooks:!0,pullRequests:!0,tokenRefresh:!0,deployKeys:!0};function Jd(t){let e=Number(t??"1");return Number.isInteger(e)&&e>0?e:1}function Hd(t){return Math.max(1,Math.min(100,t??50))}function Nr(t){let e=t.trim().replace(/^\/+|\/+$/g,"");if(!/^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/.test(e))throw Error("Repository must use owner/name format");return e}function mc(t){let e=new URL(t);if(e.username||e.password||e.protocol!=="https:")throw Error("Webhook endpoint must be credential-free HTTPS");return e.href}function n0(t){return Buffer.from(t).toString("base64url")}function b$(t,e){if(!t.appId||!t.privateKey)throw Error("GitHub App credentials require appId and privateKey");let r=n0(JSON.stringify({alg:"RS256",typ:"JWT"})),d=Math.floor(e.getTime()/1000)-30,E=n0(JSON.stringify({iat:d,exp:d+540,iss:t.appId})),n=k$("RSA-SHA256");return n.update(`${r}.${E}`),n.end(),`${r}.${E}.${n.sign(t.privateKey).toString("base64url")}`}class pc{connection;credential;capabilities=c0;fetchFn;timeoutMs;nowFn;constructor(t,e,r={}){this.connection=t;this.credential=e;this.fetchFn=r.fetch??((d,E)=>globalThis.fetch(d,E)),this.timeoutMs=Math.max(100,r.timeoutMs??20000),this.nowFn=r.now??(()=>new Date)}async request(t,e={}){let r=new URL(`${this.apiRoot().replace(/\/$/,"")}/`),d=new URL(t.replace(/^\//,""),r);if(d.origin!==r.origin)throw Error("Provider pagination cannot leave the configured host");let E=new AbortController,n=setTimeout(()=>E.abort(),this.timeoutMs);try{let c=await this.fetchFn(d,{...e,redirect:"error",signal:E.signal,headers:{Accept:"application/json","User-Agent":"ts-cloud-source/1",...await this.authorization(),...e.headers}});if(!c.ok){let _=Number(c.headers.get("retry-after")??""),T=c.headers.get("x-request-id")??c.headers.get("x-github-request-id");throw new $n(`Source provider request failed (${c.status})${T?` [request ${T}]`:""}`,c.status,Number.isFinite(_)?_:void 0)}if(c.status===204)return{data:void 0,headers:c.headers};return{data:await c.json(),headers:c.headers}}catch(c){if(c instanceof $n)throw c;if(E.signal.aborted)throw new $n(`Source provider request exceeded ${this.timeoutMs}ms`);throw new $n(c instanceof Error?c.message.replace(/(?:token|password|secret)=[^\s&]+/gi,"$1=[REDACTED]"):"Source provider request failed")}finally{clearTimeout(n)}}async deleteWebhook(t,e){await this.request(this.webhookPath(t,e),{method:"DELETE"})}}class _0 extends pc{provider="github";installationToken;apiRoot(){return this.connection.host==="https://github.com"?"https://api.github.com":`${this.connection.host}/api/v3`}async authorization(){if(this.credential?.token)return{Authorization:`Bearer ${this.credential.token}`,"X-GitHub-Api-Version":"2022-11-28"};if(!this.credential?.installationId)return{};if(!this.installationToken||this.installationToken.expiresAt<this.nowFn().getTime()+60000){let t=b$(this.credential,this.nowFn()),e=this.apiRoot().replace(/\/$/,""),r=new AbortController,d=setTimeout(()=>r.abort(),this.timeoutMs);try{let E=await this.fetchFn(`${e}/app/installations/${encodeURIComponent(this.credential.installationId)}/access_tokens`,{method:"POST",signal:r.signal,redirect:"error",headers:{Accept:"application/vnd.github+json",Authorization:`Bearer ${t}`,"X-GitHub-Api-Version":"2022-11-28","User-Agent":"ts-cloud-source/1"}});if(!E.ok)throw new $n(`GitHub App token refresh failed (${E.status})`,E.status);let n=await E.json();this.installationToken={value:n.token,expiresAt:new Date(n.expires_at).getTime()}}finally{clearTimeout(d)}}return{Authorization:`Bearer ${this.installationToken.value}`,"X-GitHub-Api-Version":"2022-11-28"}}async testConnection(){let t=this.credential?.installationId?"/installation/repositories?per_page=1":"/user",{data:e,headers:r}=await this.request(t);return{ok:!0,account:e.login??this.connection.owner,scopes:(r.get("x-oauth-scopes")??this.connection.grantedScopes.join(",")).split(",").map((d)=>d.trim()).filter(Boolean),message:"GitHub connection is healthy"}}async listRepositories(t={}){let e=Hd(t.limit),r=Jd(t.cursor),d=this.credential?.installationId?`/installation/repositories?per_page=${e}&page=${r}`:`/user/repos?per_page=${e}&page=${r}&sort=updated`,{data:E}=await this.request(d),n=Array.isArray(E)?E:E.repositories;return{repositories:(t.search?n.filter((_)=>_.full_name.toLowerCase().includes(t.search.toLowerCase())):n).map((_)=>({providerRepositoryId:String(_.id),fullName:_.full_name,cloneUrl:_.clone_url,defaultBranch:_.default_branch||"main",visibility:_.visibility??(_.private?"private":"public"),archived:!!_.archived,metadata:{}})),nextCursor:n.length===e?String(r+1):void 0}}async refs(t,e,r={}){let d=Hd(r.limit),E=Jd(r.cursor),{data:n}=await this.request(`/repos/${Nr(t)}/${e}?per_page=${d}&page=${E}`);return{refs:n.map((c)=>({name:c.name,commitSha:c.commit.sha,protected:c.protected})),nextCursor:n.length===d?String(E+1):void 0}}listBranches(t,e){return this.refs(t,"branches",e)}listTags(t,e){return this.refs(t,"tags",e)}webhookPath(t,e){return`/repos/${Nr(t)}/hooks${e?`/${encodeURIComponent(e)}`:""}`}hook(t){return{providerWebhookId:String(t.id),active:t.active,events:t.events,url:t.config.url??""}}async createWebhook(t,e){let{data:r}=await this.request(this.webhookPath(t),{method:"POST",body:JSON.stringify({name:"web",active:!0,events:e.events,config:{url:mc(e.url),content_type:"json",secret:e.secret,insecure_ssl:"0"}}),headers:{"Content-Type":"application/json"}});return this.hook(r)}async listWebhooks(t){let{data:e}=await this.request(this.webhookPath(t));return e.map((r)=>this.hook(r))}async updateWebhook(t,e,r){let{data:d}=await this.request(this.webhookPath(t,e),{method:"PATCH",body:JSON.stringify({active:!0,events:r.events,config:{url:mc(r.url),content_type:"json",secret:r.secret,insecure_ssl:"0"}}),headers:{"Content-Type":"application/json"}});return this.hook(d)}async setCommitStatus(t,e,r){await this.request(`/repos/${Nr(t)}/statuses/${encodeURIComponent(e)}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({state:r.state,target_url:r.url,description:r.description.slice(0,140),context:r.context??"ts-cloud/preview"})})}}class T0 extends pc{provider="gitlab";apiRoot(){return`${this.connection.host}/api/v4`}async authorization(){return this.credential?.token?{"PRIVATE-TOKEN":this.credential.token}:{}}async testConnection(){let{data:t}=await this.request("/user");return{ok:!0,account:t.username,scopes:this.connection.grantedScopes,message:"GitLab connection is healthy"}}async listRepositories(t={}){let e=Hd(t.limit),r=Jd(t.cursor),d=t.search?`&search=${encodeURIComponent(t.search)}`:"",{data:E,headers:n}=await this.request(`/projects?membership=true&simple=true&order_by=last_activity_at&per_page=${e}&page=${r}${d}`);return{repositories:E.map((c)=>({providerRepositoryId:String(c.id),fullName:c.path_with_namespace,cloneUrl:c.http_url_to_repo,defaultBranch:c.default_branch??"main",visibility:c.visibility??"unknown",archived:!!c.archived,metadata:{}})),nextCursor:n.get("x-next-page")||void 0}}async refs(t,e,r={}){let d=Hd(r.limit),E=Jd(r.cursor),{data:n,headers:c}=await this.request(`/projects/${encodeURIComponent(Nr(t))}/repository/${e}?per_page=${d}&page=${E}`);return{refs:n.map((_)=>({name:_.name,commitSha:_.commit.id,protected:_.protected})),nextCursor:c.get("x-next-page")||void 0}}listBranches(t,e){return this.refs(t,"branches",e)}listTags(t,e){return this.refs(t,"tags",e)}webhookPath(t,e){return`/projects/${encodeURIComponent(Nr(t))}/hooks${e?`/${encodeURIComponent(e)}`:""}`}hook(t){return{providerWebhookId:String(t.id),active:!0,events:[...t.push_events?["push"]:[],...t.merge_requests_events?["pull_request"]:[]],url:t.url}}body(t){return JSON.stringify({url:mc(t.url),token:t.secret,enable_ssl_verification:!0,push_events:t.events.includes("push"),merge_requests_events:t.events.includes("pull_request")})}async createWebhook(t,e){let{data:r}=await this.request(this.webhookPath(t),{method:"POST",body:this.body(e),headers:{"Content-Type":"application/json"}});return this.hook(r)}async listWebhooks(t){let{data:e}=await this.request(this.webhookPath(t));return e.map((r)=>this.hook(r))}async updateWebhook(t,e,r){let{data:d}=await this.request(this.webhookPath(t,e),{method:"PUT",body:this.body(r),headers:{"Content-Type":"application/json"}});return this.hook(d)}async setCommitStatus(t,e,r){let d=r.state==="failure"||r.state==="error"?"failed":r.state;await this.request(`/projects/${encodeURIComponent(Nr(t))}/statuses/${encodeURIComponent(e)}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({state:d,target_url:r.url,description:r.description.slice(0,255),name:r.context??"ts-cloud/preview"})})}}class i0 extends pc{provider="bitbucket";apiRoot(){return this.connection.host==="https://bitbucket.org"?"https://api.bitbucket.org/2.0":`${this.connection.host}/2.0`}async authorization(){return this.credential?.token?{Authorization:`Bearer ${this.credential.token}`}:{}}async testConnection(){let{data:t}=await this.request("/user");return{ok:!0,account:t.username??t.display_name,scopes:this.connection.grantedScopes,message:"Bitbucket connection is healthy"}}async listRepositories(t={}){if(!this.connection.owner)throw Error("Bitbucket repository discovery requires an owner/workspace");let e=Jd(t.cursor),r=Hd(t.limit),d=t.search?`&q=name~%22${encodeURIComponent(t.search)}%22`:"",{data:E}=await this.request(`/repositories/${encodeURIComponent(this.connection.owner)}?pagelen=${r}&page=${e}${d}`);return{repositories:E.values.map((n)=>({providerRepositoryId:n.uuid,fullName:n.full_name,cloneUrl:n.links.clone.find((c)=>c.name==="https")?.href??n.links.clone[0]?.href??"",defaultBranch:n.mainbranch?.name??"main",visibility:n.is_private?"private":"public",archived:!1,metadata:{}})),nextCursor:E.next?String(e+1):void 0}}async refs(t,e,r={}){let d=Jd(r.cursor),E=Hd(r.limit),{data:n}=await this.request(`/repositories/${Nr(t)}/refs/${e}?pagelen=${E}&page=${d}`);return{refs:n.values.map((c)=>({name:c.name,commitSha:c.target.hash})),nextCursor:n.next?String(d+1):void 0}}listBranches(t,e){return this.refs(t,"branches",e)}listTags(t,e){return this.refs(t,"tags",e)}webhookPath(t,e){return`/repositories/${Nr(t)}/hooks${e?`/${encodeURIComponent(e)}`:""}`}hook(t){return{providerWebhookId:t.uuid,active:t.active,events:t.events.map((e)=>e.replace("repo:push","push").replace("pullrequest:","pull_request:")),url:t.url}}body(t){return JSON.stringify({description:"ts-cloud deploy",url:mc(t.url),active:!0,events:t.events.map((e)=>e==="push"?"repo:push":e.replace("pull_request:","pullrequest:"))})}async createWebhook(t,e){let{data:r}=await this.request(this.webhookPath(t),{method:"POST",body:this.body(e),headers:{"Content-Type":"application/json"}});return this.hook(r)}async listWebhooks(t){let{data:e}=await this.request(this.webhookPath(t));return e.values.map((r)=>this.hook(r))}async updateWebhook(t,e,r){let{data:d}=await this.request(this.webhookPath(t,e),{method:"PUT",body:this.body(r),headers:{"Content-Type":"application/json"}});return this.hook(d)}async setCommitStatus(t,e,r){let d=r.state==="success"?"SUCCESSFUL":r.state==="pending"?"INPROGRESS":"FAILED";await this.request(`/repositories/${Nr(t)}/commit/${encodeURIComponent(e)}/statuses/build/ts-cloud-preview`,{method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({state:d,key:"ts-cloud-preview",name:r.context??"ts-cloud/preview",url:r.url,description:r.description.slice(0,255)})})}}class h0 extends pc{provider="gitea";capabilities={...c0,tokenRefresh:!1};apiRoot(){return`${this.connection.host}/api/v1`}async authorization(){return this.credential?.token?{Authorization:`token ${this.credential.token}`}:{}}async testConnection(){let{data:t}=await this.request("/user");return{ok:!0,account:t.login,scopes:this.connection.grantedScopes,message:"Gitea connection is healthy"}}async listRepositories(t={}){let e=Jd(t.cursor),r=Hd(t.limit),d=t.search?`/repos/search?q=${encodeURIComponent(t.search)}&limit=${r}&page=${e}`:`/user/repos?limit=${r}&page=${e}`,{data:E,headers:n}=await this.request(d),c=Array.isArray(E)?E:E.data;return{repositories:c.map((_)=>({providerRepositoryId:String(_.id),fullName:_.full_name,cloneUrl:_.clone_url,defaultBranch:_.default_branch??"main",visibility:_.private?"private":"public",archived:!!_.archived,metadata:{}})),nextCursor:n.get("x-hasmore")==="true"||c.length===r?String(e+1):void 0}}async refs(t,e,r={}){let d=Jd(r.cursor),E=Hd(r.limit),{data:n}=await this.request(`/repos/${Nr(t)}/${e}?limit=${E}&page=${d}`);return{refs:n.map((c)=>({name:c.name,commitSha:c.commit.id})),nextCursor:n.length===E?String(d+1):void 0}}listBranches(t,e){return this.refs(t,"branches",e)}listTags(t,e){return this.refs(t,"tags",e)}webhookPath(t,e){return`/repos/${Nr(t)}/hooks${e?`/${encodeURIComponent(e)}`:""}`}hook(t){return{providerWebhookId:String(t.id),active:t.active,events:t.events??[],url:t.config.url??""}}body(t){return JSON.stringify({type:"gitea",active:!0,events:t.events,config:{url:mc(t.url),content_type:"json",secret:t.secret,insecure_ssl:"0"}})}async createWebhook(t,e){let{data:r}=await this.request(this.webhookPath(t),{method:"POST",body:this.body(e),headers:{"Content-Type":"application/json"}});return this.hook(r)}async listWebhooks(t){let{data:e}=await this.request(this.webhookPath(t));return e.map((r)=>this.hook(r))}async updateWebhook(t,e,r){let{data:d}=await this.request(this.webhookPath(t,e),{method:"PATCH",body:this.body(r),headers:{"Content-Type":"application/json"}});return this.hook(d)}async setCommitStatus(t,e,r){await this.request(`/repos/${Nr(t)}/statuses/${encodeURIComponent(e)}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({state:r.state,target_url:r.url,description:r.description.slice(0,140),context:r.context??"ts-cloud/preview"})})}}function Wd(t,e,r={}){switch(t.provider){case"github":return new _0(t,e,r);case"gitlab":return new T0(t,e,r);case"bitbucket":return new i0(t,e,r);case"gitea":return new h0(t,e,r);default:throw Error(`${t.provider} uses bounded Git discovery instead of a hosted provider API`)}}import{createHmac as x$,timingSafeEqual as q$}from"node:crypto";function ze(t,e){if(t instanceof Headers)return t.get(e)??void 0;return Object.entries(t).find(([d])=>d.toLowerCase()===e.toLowerCase())?.[1]}function R0(t,e){let r=Buffer.from(t),d=Buffer.from(e);return r.length===d.length&&q$(r,d)}function s$(t,e){return x$("sha256",t).update(e).digest("hex")}function o$(t,e,r,d,E){if(t==="gitlab")return R0(ze(r,"x-gitlab-token")??"",e);let n=t==="github"?ze(r,"x-hub-signature-256"):t==="gitea"?ze(r,"x-gitea-signature"):ze(r,"x-hub-signature")??ze(r,"x-ts-cloud-signature");if(!n)return!1;if(t==="generic_https"||t==="generic_ssh"){let c=Number(ze(r,"x-ts-cloud-timestamp"));if(!Number.isFinite(c)||Math.abs(E.getTime()-c*1000)>300000)return!1}return R0(n.replace(/^sha256=/,""),s$(e,d))}function m$(t,e){return{github:["x-github-delivery"],gitlab:["x-gitlab-event-uuid","x-request-id"],bitbucket:["x-request-uuid"],gitea:["x-gitea-delivery"],generic_https:["x-ts-cloud-delivery"],generic_ssh:["x-ts-cloud-delivery"]}[t].map((d)=>ze(e,d)?.trim()).find(Boolean)}function vd(t){let e=String(t??"").trim().replace(/^\/+|\/+$/g,"");return/^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/.test(e)?e:""}function IS(t){return[...new Set(t.flatMap((e)=>{if(!e||typeof e!=="object")return[];let r=e;return[...r.added??[],...r.modified??[],...r.removed??[]].map(String)}).filter((e)=>e&&!e.includes("\x00")).slice(0,500))]}function p$(t,e,r){let d=t,E=e,n=r;if(d==="github"){let c=ze(E,"x-github-event"),_=vd(n.repository?.full_name);if(c==="push")return{event:"push",repository:_,ref:String(n.ref??""),branch:String(n.ref??"").replace(/^refs\/heads\//,""),tag:String(n.ref??"").startsWith("refs/tags/")?String(n.ref).replace(/^refs\/tags\//,""):void 0,commitSha:String(n.after??n.head_commit?.id??""),changedPaths:IS(n.commits??[]),deleted:n.deleted===!0||/^0{40,64}$/.test(String(n.after??""))};if(c==="pull_request")return{event:"pull_request",action:String(n.action??""),repository:_,branch:String(n.pull_request?.head?.ref??""),commitSha:String(n.pull_request?.head?.sha??""),changedPaths:[],pullRequestNumber:Number(n.number)||void 0,fork:vd(n.pull_request?.head?.repo?.full_name)!==_}}if(d==="gitlab"){let c=String(n.object_kind??"").toLowerCase(),_=vd(n.project?.path_with_namespace);if(c==="push"||c==="tag_push")return{event:"push",repository:_,ref:String(n.ref??""),branch:String(n.ref??"").replace(/^refs\/heads\//,""),tag:c==="tag_push"?String(n.ref??"").replace(/^refs\/tags\//,""):void 0,commitSha:String(n.checkout_sha??n.after??""),changedPaths:IS(n.commits??[]),deleted:/^0{40,64}$/.test(String(n.after??""))};if(c==="merge_request")return{event:"pull_request",action:String(n.object_attributes?.action??n.object_attributes?.state??""),repository:_,branch:String(n.object_attributes?.source_branch??""),commitSha:String(n.object_attributes?.last_commit?.id??""),changedPaths:[],pullRequestNumber:Number(n.object_attributes?.iid)||void 0,fork:n.object_attributes?.source_project_id!==n.object_attributes?.target_project_id}}if(d==="bitbucket"){let c=ze(E,"x-event-key")??"",_=vd(n.repository?.full_name);if(c==="repo:push"){let T=n.push?.changes?.[0]??{},i=T.new??T.old??{},h=T.new?.target??T.old?.target;return{event:"push",repository:_,ref:String(i.name??""),branch:i.type==="branch"?String(i.name):void 0,tag:i.type==="tag"?String(i.name):void 0,commitSha:String(h?.hash??""),changedPaths:[],deleted:T.closed===!0||T.new==null}}if(c.startsWith("pullrequest:"))return{event:"pull_request",action:c.replace("pullrequest:",""),repository:_,branch:String(n.pullrequest?.source?.branch?.name??""),commitSha:String(n.pullrequest?.source?.commit?.hash??""),changedPaths:[],pullRequestNumber:Number(n.pullrequest?.id)||void 0,fork:vd(n.pullrequest?.source?.repository?.full_name)!==_}}if(d==="gitea"){let c=ze(E,"x-gitea-event"),_=vd(n.repository?.full_name);if(c==="push")return{event:"push",repository:_,ref:String(n.ref??""),branch:String(n.ref??"").replace(/^refs\/heads\//,""),tag:String(n.ref??"").startsWith("refs/tags/")?String(n.ref).replace(/^refs\/tags\//,""):void 0,commitSha:String(n.after??""),changedPaths:IS(n.commits??[]),deleted:n.deleted===!0||/^0{40,64}$/.test(String(n.after??""))};if(c==="pull_request")return{event:"pull_request",action:String(n.action??""),repository:_,branch:String(n.pull_request?.head?.ref??""),commitSha:String(n.pull_request?.head?.sha??""),changedPaths:[],pullRequestNumber:Number(n.number)||void 0,fork:vd(n.pull_request?.head?.repo?.full_name)!==_}}if(d==="generic_https"||d==="generic_ssh"){if(n.event!=="push"&&n.event!=="pull_request")return;return{event:n.event,action:typeof n.action==="string"?n.action:void 0,repository:vd(n.repository),ref:typeof n.ref==="string"?n.ref:void 0,branch:typeof n.branch==="string"?n.branch:void 0,tag:typeof n.tag==="string"?n.tag:void 0,commitSha:String(n.commitSha??""),changedPaths:Array.isArray(n.changedPaths)?n.changedPaths.map(String).slice(0,500):[],pullRequestNumber:Number(n.pullRequestNumber)||void 0,fork:n.fork===!0,deleted:n.deleted===!0}}return}function yn(t,e){let r="^";for(let d=0;d<e.length;d++){let E=e[d];if(E==="*"&&e[d+1]==="*")r+=".*",d++;else if(E==="*")r+="[^/]*";else if(E==="?")r+="[^/]";else r+=E.replace(/[|\\{}()[\]^$+?.]/g,"\\$&")}return new RegExp(`${r}$`).test(t)}function ty(t,e){if(e.event==="pull_request")return t.pullRequestPreviews;if(!t.autoDeploy)return!1;if(e.tag)return!!t.tagRule&&yn(e.tag,t.tagRule);return yn(e.branch??"",t.branchRule??t.defaultBranch)}function ey(t,e){if(!e.length)return!0;return e.filter((d)=>!t.excludePaths.some((E)=>yn(d,E))).some((d)=>!t.includePaths.length||t.includePaths.some((E)=>yn(d,E)))}function S0(t,e){return ze(e,t==="github"?"x-github-event":t==="gitlab"?"x-gitlab-event":t==="bitbucket"?"x-event-key":t==="gitea"?"x-gitea-event":"x-ts-cloud-event")??"unknown"}function yE(){return{accepted:!1,duplicate:!1,status:"rejected",operations:[],message:"Webhook unavailable"}}async function N0(t){if(t.rawBody.byteLength>2097152)return yE();let e=t.sources.getWebhookByEndpointToken(t.endpointToken);if(!e||e.status==="disabled")return yE();let r=t.sources.getConnection(e.connectionId);if(!r||r.status==="disconnected"||r.status==="expired")return yE();let d=m$(r.provider,t.headers);if(!d||d.length>200)return yE();if(!o$(r.provider,t.sources.getWebhookSecret(e.id),t.headers,t.rawBody,t.now??new Date))return t.sources.recordDelivery({connectionId:r.id,webhookId:e.id,providerDeliveryId:d,event:S0(r.provider,t.headers),signatureStatus:ze(t.headers,"x-hub-signature-256")||ze(t.headers,"x-gitlab-token")||ze(t.headers,"x-hub-signature")||ze(t.headers,"x-gitea-signature")?"invalid":"missing",status:"rejected",error:"Webhook signature verification failed"}),yE();let n;try{n=JSON.parse(new TextDecoder().decode(t.rawBody))}catch{return yE()}let c=p$(r.provider,t.headers,n);if(!c||!c.repository||!/^[a-f0-9]{7,64}$/i.test(c.commitSha))return t.sources.recordDelivery({connectionId:r.id,webhookId:e.id,providerDeliveryId:d,event:S0(r.provider,t.headers),signatureStatus:"verified",status:"rejected",error:"Unsupported or malformed source event"}),yE();let _=t.sources.recordDelivery({connectionId:r.id,webhookId:e.id,providerDeliveryId:d,event:c.event,action:c.action,commitSha:c.commitSha,signatureStatus:"verified",status:"accepted",payloadSummary:{repository:c.repository,ref:c.ref??null,branch:c.branch??null,tag:c.tag??null,commitSha:c.commitSha,pullRequestNumber:c.pullRequestNumber??null,changedPathCount:c.changedPaths.length}});if(_.duplicate&&_.delivery.status!=="accepted")return{accepted:!0,duplicate:!0,status:"duplicate",operations:[],message:"Delivery already processed"};let T=new Bd(t.controlPlane),i=t.sources.listBindings({connectionId:r.id,status:"active"}).filter((A)=>{if(A.repositoryFullName.toLowerCase()!==c.repository.toLowerCase()||!ey(A,c.changedPaths))return!1;let u=A.resourceId?T.getDefinitionForResource(A.resourceId):void 0,f=c.event==="push"&&!!u?.branchRule&&!!c.branch&&yn(c.branch,u.branchRule);return ty(A,c)||f});if(!i.length)return t.sources.updateDelivery(_.delivery.id,{status:"ignored"}),{accepted:!0,duplicate:_.duplicate,status:"ignored",operations:[],message:"Verified event did not match an active deployment rule"};let h=new gt(t.controlPlane),R=new Set(["closed","merged","declined"]),N=i.flatMap((A)=>{if(c.event==="push"&&A.resourceId&&c.branch){let f=T.getDefinitionForResource(A.resourceId);if(f?.branchRule&&yn(c.branch,f.branchRule)){let w=T.findForBranch(f.id,c.repository,c.branch);if(c.deleted){if(!f.cleanupOnClose||!w||w.status==="destroyed")return[];let j=h.enqueue({projectId:A.projectId,environmentId:A.environmentId,resourceId:A.resourceId,kind:"preview.destroy",idempotencyKey:`preview:${w.id}:branch-delete:${d}`,correlationId:`preview:${w.id}`,input:{previewId:w.id,reason:"branch_deleted",source:{repository:c.repository,commitSha:c.commitSha,branch:c.branch}},lockKey:`preview:${w.id}`,providerKey:r.provider,maxAttempts:3,retryClasses:["network","provider_throttled","provider_unavailable"],resumePolicy:"fail",cancellationMode:"provider_non_cancellable",retentionDays:90}).operation;return T.transition(w.id,"queued",{operationId:j.id}),[j]}let I=T.upsert({definitionId:f.id,sourceProvider:r.provider,repository:c.repository,branch:c.branch,commitSha:c.commitSha});if(!I.changed)return[];let a=I.created?"preview.create":"preview.update",P=h.enqueue({projectId:A.projectId,environmentId:A.environmentId,resourceId:A.resourceId,kind:a,idempotencyKey:`preview:${I.preview.id}:${c.commitSha}`,correlationId:`preview:${I.preview.id}`,input:{previewId:I.preview.id,source:{connectionId:r.id,bindingId:A.id,repository:c.repository,commitSha:c.commitSha,branch:c.branch,monorepoRoot:A.monorepoRoot,submodules:A.submodules,cloneDepth:A.cloneDepth??null}},lockKey:`preview:${I.preview.id}`,providerKey:r.provider,buildSlot:!0,maxAttempts:3,retryClasses:["network","provider_throttled","provider_unavailable"],resumePolicy:"fail",cancellationMode:"provider_non_cancellable",retentionDays:90}).operation;return T.transition(I.preview.id,"queued",{operationId:P.id}),[P]}}if(c.event==="pull_request"&&A.resourceId&&c.pullRequestNumber){let f=T.getDefinitionForResource(A.resourceId);if(f){let w=R.has(String(c.action??"").toLowerCase()),I=T.findForPullRequest(f.id,c.repository,c.pullRequestNumber);if(w){if(!f.cleanupOnClose||!I||I.status==="destroyed")return[];let a=h.enqueue({projectId:A.projectId,environmentId:A.environmentId,resourceId:A.resourceId,kind:"preview.destroy",idempotencyKey:`preview:${I.id}:destroy:${d}`,correlationId:`preview:${I.id}`,input:{previewId:I.id,reason:"pull_request_closed",source:{repository:c.repository,commitSha:c.commitSha,branch:c.branch??null,pullRequestNumber:c.pullRequestNumber}},lockKey:`preview:${I.id}`,providerKey:r.provider,maxAttempts:3,retryClasses:["network","provider_throttled","provider_unavailable"],resumePolicy:"fail",cancellationMode:"provider_non_cancellable",retentionDays:90}).operation;return T.transition(I.id,"queued",{operationId:a.id}),[a]}try{let a=T.upsert({definitionId:f.id,sourceProvider:r.provider,repository:c.repository,branch:c.branch??`pr-${c.pullRequestNumber}`,pullRequestNumber:c.pullRequestNumber,fork:c.fork,commitSha:c.commitSha});if(!a.changed)return[];let P=a.created?"preview.create":"preview.update",j=h.enqueue({projectId:A.projectId,environmentId:A.environmentId,resourceId:A.resourceId,kind:P,idempotencyKey:`preview:${a.preview.id}:${c.commitSha}`,correlationId:`preview:${a.preview.id}`,input:{previewId:a.preview.id,source:{connectionId:r.id,bindingId:A.id,repository:c.repository,commitSha:c.commitSha,branch:c.branch??null,pullRequestNumber:c.pullRequestNumber,fork:!!c.fork,monorepoRoot:A.monorepoRoot,submodules:A.submodules,cloneDepth:A.cloneDepth??null},inheritedSecretNames:a.inheritedSecrets},lockKey:`preview:${a.preview.id}`,providerKey:r.provider,buildSlot:!0,maxAttempts:3,retryClasses:["network","provider_throttled","provider_unavailable"],resumePolicy:"fail",cancellationMode:"provider_non_cancellable",retentionDays:90}).operation;return T.transition(a.preview.id,"queued",{operationId:j.id}),[j]}catch(a){return t.controlPlane.appendEvent({projectId:A.projectId,resourceId:A.resourceId,type:"preview.rejected",level:"warning",payload:{repository:c.repository,pullRequestNumber:c.pullRequestNumber,fork:!!c.fork,reason:a instanceof Error?a.message:String(a)}}),[]}}}let u=c.event==="pull_request"?"deploy.preview":"deploy.source";return[h.enqueue({projectId:A.projectId,environmentId:A.environmentId,resourceId:A.resourceId,kind:u,idempotencyKey:`source:${r.id}:${d}:${A.id}:${c.commitSha}`,correlationId:`source:${d}`,input:{source:{connectionId:r.id,bindingId:A.id,repository:c.repository,commitSha:c.commitSha,branch:c.branch??null,tag:c.tag??null,monorepoRoot:A.monorepoRoot,submodules:A.submodules,cloneDepth:A.cloneDepth??null},preview:c.event==="pull_request"?{number:c.pullRequestNumber??null,action:c.action??null}:null},lockKey:A.resourceId?`resource:${A.resourceId}`:`environment:${A.environmentId??A.projectId}`,providerKey:r.provider,buildSlot:!0,maxAttempts:3,retryClasses:["network","provider_throttled","provider_unavailable"],resumePolicy:"fail",cancellationMode:"provider_non_cancellable",retentionDays:c.event==="pull_request"?14:90}).operation]});if(!N.length)return t.sources.updateDelivery(_.delivery.id,{status:"ignored"}),{accepted:!0,duplicate:_.duplicate,status:"ignored",operations:[],message:"Verified event required no preview lifecycle change"};return t.sources.updateDelivery(_.delivery.id,{status:"enqueued",operationId:N[0]?.id}),t.controlPlane.appendEvent({organizationId:r.organizationId,projectId:i[0]?.projectId,operationId:N[0]?.id,type:"source.webhook.enqueued",payload:{webhookId:e.id,deliveryId:_.delivery.id,repository:c.repository,commitSha:c.commitSha,operationIds:N.map((A)=>A.id)}}),{accepted:!0,duplicate:_.duplicate,status:"enqueued",operations:N,message:`${N.length} deployment operation${N.length===1?"":"s"} enqueued`}}function Xn(t,e){if(!e.endpointToken)throw Error("The webhook endpoint token is only available at creation time");let r=new URL(t);if(r.protocol!=="https:"&&!["localhost","127.0.0.1","::1"].includes(r.hostname))throw Error("Webhook base URL must use HTTPS");return new URL(`/api/source/webhooks/${encodeURIComponent(e.endpointToken)}`,r).href}import{chmodSync as A0,mkdtempSync as ry,rmSync as dy,writeFileSync as L0}from"node:fs";import{tmpdir as Ey}from"node:os";import{join as WT,resolve as ny}from"node:path";function O0(t,e){let r=t.trim();if(/\r|\n|\0/.test(r))throw Error("Git remote contains control characters");if(r.startsWith("https://")){let E=new URL(r);if(E.username||E.password||E.search||E.hash)throw Error("HTTPS Git remotes cannot contain credentials, queries, or fragments");return E.href}let d=r.startsWith("ssh://")?new URL(r).hostname:r.match(/^git@([A-Za-z0-9.-]+):/)?.[1];if(!d)throw Error("Git remote must use credential-free HTTPS or SSH");if(!e||e.host.toLowerCase()!==d.toLowerCase())throw Error("SSH Git remote requires a deploy key with a pinned key for the same host");return r}function cy(t,e,r){let d=t.replaceAll(e,"[REMOTE]").slice(0,4000);for(let E of[r?.token,r?.privateKey])if(E)d=d.replaceAll(E,"[REDACTED]");return d}function _y(t){let e={PATH:process.env.PATH??"/usr/local/bin:/usr/bin:/bin",HOME:"/nonexistent",GIT_TERMINAL_PROMPT:"0",GIT_CONFIG_NOSYSTEM:"1",GIT_OPTIONAL_LOCKS:"0"},r;if(t.credential?.token){let d=t.credential.username??"oauth2";e.GIT_CONFIG_COUNT="1",e.GIT_CONFIG_KEY_0="http.extraHeader",e.GIT_CONFIG_VALUE_0=`Authorization: Basic ${Buffer.from(`${d}:${t.credential.token}`).toString("base64")}`}if(t.deployKey){r=ry(WT(Ey(),"ts-cloud-git-transport-"));let d=WT(r,"key"),E=WT(r,"known_hosts");L0(d,t.deployKey.privateKey,{mode:384}),L0(E,`${t.deployKey.host} ${t.deployKey.hostKey}
|
|
@@ -5506,9 +5506,9 @@ data: ${JSON.stringify(se)}
|
|
|
5506
5506
|
`));let Gt=t.controlPlane.getOperation($.id);if(Gt&&["succeeded","failed","cancelled","timed_out"].includes(Gt.state)&&!r.logs($.id,{after:Rt,limit:1}).length){if(m=!0,ct)clearInterval(ct);ge.enqueue(Q.encode(`event: complete
|
|
5507
5507
|
data: ${JSON.stringify({state:Gt.state,cursor:Rt})}
|
|
5508
5508
|
|
|
5509
|
-
`)),ge.close()}};if(qe(),!m)ct=setInterval(qe,500);R.signal.addEventListener("abort",()=>{if(m=!0,ct)clearInterval(ct);try{ge.close()}catch{}},{once:!0})},cancel(){if(m=!0,ct)clearInterval(ct)}});return new Response(te,{headers:{"content-type":"text/event-stream","cache-control":"no-store","x-accel-buffering":"no","x-request-id":u,...F}})}let St=r.logs($.id,{after:x,limit:Number(A.searchParams.get("limit"))||void 0});B={data:St,cursor:St.at(-1)?.sequence??x,hasMore:St.length>=Math.min(1000,Math.max(1,Number(A.searchParams.get("limit"))||200)),requestId:u}}else if(R.method==="POST"&&q){let $=t.controlPlane.getOperation(decodeURIComponent(q[1]));if(!$)throw new rt("not_found","Operation was not found.",404);let W=$.resourceId?{type:"resource",id:$.resourceId}:$.environmentId?{type:"environment",id:$.environmentId}:$.projectId?{type:"project",id:$.projectId}:{type:"organization"},G=await Z();if(q[2]==="cancel")e.authorize(I,"deployments:cancel",W),B={operation:e.operation(r.requestCancellation($.id,I.actor.id)),requestId:u};else e.authorize(I,"deployments:create",W),B={operation:e.operation(r.retry($.id,String(G.errorClass??"manual"),{delayMs:Number(G.delayMs)||0,actorId:I.actor.id})),requestId:u}}else if(R.method==="GET"&&A.pathname==="/api/v1/source/connections"){if(!t.sources)throw new rt("not_found","Source integrations are unavailable.",404);e.authorize(I,"sources:read",I.token.scope),B=Fe(t.sources.listConnections(I.serviceAccount.organizationId),A,u,["createdAt","id"])}else if(R.method==="GET"&&A.pathname==="/api/v1/source/repositories"){if(!t.sources)throw new rt("not_found","Source integrations are unavailable.",404);e.authorize(I,"sources:read",I.token.scope);let $=t.sources.getConnection(A.searchParams.get("connectionId")??"");if(!$||$.organizationId!==I.serviceAccount.organizationId)throw new rt("not_found","Source connection was not found.",404);if(A.searchParams.get("sync")==="true")e.authorize(I,"sources:manage",{type:"organization"}),await vT(t.sources,$.id,{search:A.searchParams.get("search")??void 0});B=Fe(t.sources.listRepositories($.id,A.searchParams.get("search")??void 0),A,u,["fullName","id"])}else if(R.method==="GET"&&A.pathname==="/api/v1/source/refs"){if(!t.sources)throw new rt("not_found","Source integrations are unavailable.",404);e.authorize(I,"sources:read",I.token.scope);let $=A.searchParams.get("connectionId")??"",W=t.sources.getConnection($);if(!W||W.organizationId!==I.serviceAccount.organizationId)throw new rt("not_found","Source connection was not found.",404);B=await QT(t.sources,{connectionId:$,repository:A.searchParams.get("repository")??"",repositoryId:A.searchParams.get("repositoryId")??void 0,type:A.searchParams.get("type")==="tags"?"tags":"branches",cursor:A.searchParams.get("cursor")??void 0,deployKeyId:A.searchParams.get("deployKeyId")??void 0})}else if(R.method==="POST"&&A.pathname==="/api/v1/application-detections"){e.authorize(I,"applications:manage",I.token.scope);let $=await Z();if(!Array.isArray($.files)||$.files.length>1e4)throw new rt("validation_error","files must contain at most 10,000 entries.",422);B={candidates:gn($.files.map((W)=>({path:String(W.path??""),size:Number(W.size??0),content:typeof W.content==="string"?W.content.slice(0,262144):void 0}))),requestId:u}}else if(R.method==="POST"&&A.pathname==="/api/v1/application-plans"){e.authorize(I,"applications:manage",I.token.scope);let $=await Z();B={plan
|
|
5509
|
+
`)),ge.close()}};if(qe(),!m)ct=setInterval(qe,500);R.signal.addEventListener("abort",()=>{if(m=!0,ct)clearInterval(ct);try{ge.close()}catch{}},{once:!0})},cancel(){if(m=!0,ct)clearInterval(ct)}});return new Response(te,{headers:{"content-type":"text/event-stream","cache-control":"no-store","x-accel-buffering":"no","x-request-id":u,...F}})}let St=r.logs($.id,{after:x,limit:Number(A.searchParams.get("limit"))||void 0});B={data:St,cursor:St.at(-1)?.sequence??x,hasMore:St.length>=Math.min(1000,Math.max(1,Number(A.searchParams.get("limit"))||200)),requestId:u}}else if(R.method==="POST"&&q){let $=t.controlPlane.getOperation(decodeURIComponent(q[1]));if(!$)throw new rt("not_found","Operation was not found.",404);let W=$.resourceId?{type:"resource",id:$.resourceId}:$.environmentId?{type:"environment",id:$.environmentId}:$.projectId?{type:"project",id:$.projectId}:{type:"organization"},G=await Z();if(q[2]==="cancel")e.authorize(I,"deployments:cancel",W),B={operation:e.operation(r.requestCancellation($.id,I.actor.id)),requestId:u};else e.authorize(I,"deployments:create",W),B={operation:e.operation(r.retry($.id,String(G.errorClass??"manual"),{delayMs:Number(G.delayMs)||0,actorId:I.actor.id})),requestId:u}}else if(R.method==="GET"&&A.pathname==="/api/v1/source/connections"){if(!t.sources)throw new rt("not_found","Source integrations are unavailable.",404);e.authorize(I,"sources:read",I.token.scope),B=Fe(t.sources.listConnections(I.serviceAccount.organizationId),A,u,["createdAt","id"])}else if(R.method==="GET"&&A.pathname==="/api/v1/source/repositories"){if(!t.sources)throw new rt("not_found","Source integrations are unavailable.",404);e.authorize(I,"sources:read",I.token.scope);let $=t.sources.getConnection(A.searchParams.get("connectionId")??"");if(!$||$.organizationId!==I.serviceAccount.organizationId)throw new rt("not_found","Source connection was not found.",404);if(A.searchParams.get("sync")==="true")e.authorize(I,"sources:manage",{type:"organization"}),await vT(t.sources,$.id,{search:A.searchParams.get("search")??void 0});B=Fe(t.sources.listRepositories($.id,A.searchParams.get("search")??void 0),A,u,["fullName","id"])}else if(R.method==="GET"&&A.pathname==="/api/v1/source/refs"){if(!t.sources)throw new rt("not_found","Source integrations are unavailable.",404);e.authorize(I,"sources:read",I.token.scope);let $=A.searchParams.get("connectionId")??"",W=t.sources.getConnection($);if(!W||W.organizationId!==I.serviceAccount.organizationId)throw new rt("not_found","Source connection was not found.",404);B=await QT(t.sources,{connectionId:$,repository:A.searchParams.get("repository")??"",repositoryId:A.searchParams.get("repositoryId")??void 0,type:A.searchParams.get("type")==="tags"?"tags":"branches",cursor:A.searchParams.get("cursor")??void 0,deployKeyId:A.searchParams.get("deployKeyId")??void 0})}else if(R.method==="POST"&&A.pathname==="/api/v1/application-detections"){e.authorize(I,"applications:manage",I.token.scope);let $=await Z();if(!Array.isArray($.files)||$.files.length>1e4)throw new rt("validation_error","files must contain at most 10,000 entries.",422);B={candidates:gn($.files.map((W)=>({path:String(W.path??""),size:Number(W.size??0),content:typeof W.content==="string"?W.content.slice(0,262144):void 0}))),requestId:u}}else if(R.method==="POST"&&A.pathname==="/api/v1/application-plans"){e.authorize(I,"applications:manage",I.token.scope);let $=await Z();B={plan:yr($.draft,Array.isArray($.suppliedSecretNames)?$.suppliedSecretNames.map(String):[]),requestId:u}}else if(R.method==="GET"&&A.pathname==="/api/v1/application-drafts"){if(!t.applications)throw new rt("not_found","Application onboarding is unavailable.",404);let $=A.searchParams.get("projectId")??"";e.authorize(I,"applications:read",{type:"project",id:$}),B=Fe(t.applications.drafts.list($),A,u,["updatedAt","id"])}else if(R.method==="POST"&&A.pathname==="/api/v1/application-drafts"){if(!t.applications)throw new rt("not_found","Application onboarding is unavailable.",404);let $=await Z(),W=String($.projectId??$.draft?.projectId??"");e.authorize(I,"applications:manage",{type:"project",id:W});let G=t.controlPlane.getProject(W);if(!G||G.organizationId!==I.serviceAccount.organizationId)throw new rt("not_found","Project was not found.",404);let x=t.applications.drafts.create({organizationId:G.organizationId,projectId:W,name:String($.name??$.draft?.name??"Application draft"),draft:{...$.draft,projectId:W},step:$.step,suppliedSecretNames:Array.isArray($.suppliedSecretNames)?$.suppliedSecretNames.map(String):[],actorId:I.actor.id});return i({draft:x,requestId:u},201,u,F)}else if(R.method==="PATCH"&&A.pathname==="/api/v1/application-drafts"){if(!t.applications)throw new rt("not_found","Application onboarding is unavailable.",404);let $=await Z(),W=t.applications.drafts.get(String($.id??""));if(!W)throw new rt("not_found","Application draft was not found.",404);e.authorize(I,"applications:manage",{type:"project",id:W.projectId}),B={draft:t.applications.drafts.update(W.id,Number($.version),{draft:{...$.draft,projectId:W.projectId},step:$.step,suppliedSecretNames:Array.isArray($.suppliedSecretNames)?$.suppliedSecretNames.map(String):void 0,actorId:I.actor.id}),requestId:u}}else if(R.method==="POST"&&A.pathname==="/api/v1/applications"){if(!t.applications)throw new rt("not_found","Application onboarding is unavailable.",404);let $=R.headers.get("idempotency-key")??"";if(!$)throw new rt("idempotency_required","Idempotency-Key is required for application creation.",428);if(!/^[A-Za-z0-9._:-]{8,128}$/.test($))throw new rt("validation_error","Idempotency-Key must contain 8-128 safe characters.",422);let W=await Z(),G=t.applications.drafts.get(String(W.draftId??""));if(!G)throw new rt("not_found","Application draft was not found.",404);e.authorize(I,"applications:manage",{type:"project",id:G.projectId});let x=iy("sha256").update(`POST
|
|
5510
5510
|
/api/v1/applications
|
|
5511
|
-
${JSON.stringify(W)}`).digest("hex"),St=t.identities.getIdempotency(I.token.id,$);if(St){if(St.requestHash!==x)throw new rt("idempotency_conflict","Idempotency-Key was already used for another request.",409);let Rt=St.operationId?t.controlPlane.getOperation(St.operationId):void 0,ct=Rt?.resourceId?t.controlPlane.getResource(Rt.resourceId):void 0;if(!Rt||!ct)throw new rt("idempotency_unavailable","The original application operation is no longer available.",409);return i({resource:ct,operation:e.operation(Rt),plan
|
|
5511
|
+
${JSON.stringify(W)}`).digest("hex"),St=t.identities.getIdempotency(I.token.id,$);if(St){if(St.requestHash!==x)throw new rt("idempotency_conflict","Idempotency-Key was already used for another request.",409);let Rt=St.operationId?t.controlPlane.getOperation(St.operationId):void 0,ct=Rt?.resourceId?t.controlPlane.getResource(Rt.resourceId):void 0;if(!Rt||!ct)throw new rt("idempotency_unavailable","The original application operation is no longer available.",409);return i({resource:ct,operation:e.operation(Rt),plan:yr(G.input,G.suppliedSecretNames),idempotentReplay:!0,requestId:u},202,u,{...F,"idempotent-replayed":"true"})}let Q=BT({controlPlane:t.controlPlane,drafts:t.applications.drafts,draftId:G.id,expectedVersion:Number(W.version),confirmEnvironment:String(W.confirmEnvironment??""),actorId:I.actor.id});return t.identities.saveIdempotency({tokenId:I.token.id,key:$,requestHash:x,operationId:Q.operation.id,responseStatus:202,responseBody:{draftId:G.id}}),i({resource:Q.resource,operation:e.operation(Q.operation),plan:Q.plan,idempotentReplay:!1,requestId:u},202,u,F)}else if(R.method==="GET"&&A.pathname==="/api/v1/registry-connections"){if(!t.applications)throw new rt("not_found","Application onboarding is unavailable.",404);e.authorize(I,"applications:read",I.token.scope),B=Fe(t.applications.registries.list(I.serviceAccount.organizationId),A,u,["createdAt","id"])}else if(R.method==="POST"&&A.pathname==="/api/v1/registry-connections"){if(!t.applications)throw new rt("not_found","Application onboarding is unavailable.",404);e.authorize(I,"applications:manage",{type:"organization"});let $=await Z(),W=t.applications.registries.create({organizationId:I.serviceAccount.organizationId,provider:$.provider,name:String($.name??"Container registry"),host:String($.host??""),credential:$.token||$.password?{username:typeof $.username==="string"?$.username:void 0,password:typeof $.password==="string"?$.password:void 0,token:typeof $.token==="string"?$.token:void 0}:void 0,credentialExpiresAt:typeof $.credentialExpiresAt==="string"?$.credentialExpiresAt:void 0,actorId:I.actor.id});return i({registry:W,requestId:u},201,u,F)}else if(R.method==="PATCH"&&A.pathname==="/api/v1/registry-connections"){if(!t.applications)throw new rt("not_found","Application onboarding is unavailable.",404);e.authorize(I,"applications:manage",{type:"organization"});let $=await Z(),W=t.applications.registries.get(String($.id??""));if(!W||W.organizationId!==I.serviceAccount.organizationId)throw new rt("not_found","Registry connection was not found.",404);if($.action==="test")B={registry:await t.applications.registries.test(W.id,{image:typeof $.image==="string"?$.image:void 0}),requestId:u};else if($.action==="rotate")B={registry:t.applications.registries.rotate(W.id,{username:$.username,password:$.password,token:$.token},{expiresAt:$.expiresAt,actorId:I.actor.id}),requestId:u};else throw new rt("validation_error","action must be test or rotate.",422)}else if(R.method==="DELETE"&&A.pathname==="/api/v1/registry-connections"){if(!t.applications)throw new rt("not_found","Application onboarding is unavailable.",404);e.authorize(I,"applications:manage",{type:"organization"});let $=await Z(),W=t.applications.registries.get(String($.id??""));if(!W||W.organizationId!==I.serviceAccount.organizationId)throw new rt("not_found","Registry connection was not found.",404);B={registry:t.applications.registries.disconnect(W.id,I.actor.id),requestId:u}}else if(R.method==="POST"&&A.pathname==="/api/v1/application-artifacts"){if(!t.applications?.artifacts)throw new rt("not_found","Application artifact storage is unavailable.",404);let $=R.headers.get("x-project-id")??"";e.authorize(I,"applications:manage",{type:"project",id:$});let W=t.controlPlane.getProject($);if(!W||W.organizationId!==I.serviceAccount.organizationId)throw new rt("not_found","Project was not found.",404);if(Number(R.headers.get("content-length")??0)>104857600)throw new rt("payload_too_large","Artifact exceeds 100 MB.",413);let x=t.applications.artifacts.create({organizationId:W.organizationId,projectId:$,filename:R.headers.get("x-artifact-filename")??"application.zip",bytes:new Uint8Array(await R.arrayBuffer()),actorId:I.actor.id});return i({artifact:x,requestId:u},201,u,F)}else if(R.method==="POST"&&A.pathname==="/api/v1/source/connections"){if(!t.sources)throw new rt("not_found","Source integrations are unavailable.",404);e.authorize(I,"sources:manage",{type:"organization"});let $=await Z(),W=String($.provider??"");if(!["github","gitlab","bitbucket","gitea","generic_https","generic_ssh"].includes(W))throw new rt("validation_error","A supported provider is required.",422);let G=W==="github"&&($.privateKey||$.appId)?{appId:typeof $.appId==="string"?$.appId:void 0,installationId:typeof $.installationId==="string"?$.installationId:void 0,privateKey:typeof $.privateKey==="string"?$.privateKey:void 0}:W!=="generic_ssh"&&$.token?{token:String($.token),username:typeof $.username==="string"?$.username:void 0}:void 0,x,St,Q;return t.controlPlane.database.transaction(()=>{if(x=t.sources.createConnection({organizationId:I.serviceAccount.organizationId,provider:W,name:String($.name??W),host:String($.host??""),owner:typeof $.owner==="string"?$.owner:void 0,authKind:$.authKind,credential:G,createdByActorId:I.actor.id}),typeof $.repositoryUrl==="string"&&typeof $.repositoryFullName==="string")St=t.sources.upsertRepository({connectionId:x.id,providerRepositoryId:`manual:${$.repositoryFullName}`,fullName:$.repositoryFullName,cloneUrl:$.repositoryUrl,defaultBranch:String($.defaultBranch??"main"),visibility:"unknown",archived:!1,metadata:{source:"api"}});if(W==="generic_ssh")Q=t.sources.createDeployKey({connectionId:x.id,name:String($.deployKeyName??"Repository deploy key"),publicKey:String($.publicKey??""),privateKey:String($.deployPrivateKey??""),host:String($.sshHost??""),hostKey:String($.hostKey??""),actorId:I.actor.id})})(),i({connection:x,repository:St,deployKey:Q,requestId:u},201,u,F)}else if(R.method==="POST"&&A.pathname==="/api/v1/source/bindings"){if(!t.sources)throw new rt("not_found","Source integrations are unavailable.",404);let $=await Z(),W=String($.projectId??"");e.authorize(I,"sources:manage",{type:"project",id:W});let G=t.sources.getConnection(String($.connectionId??""));if(!G||G.organizationId!==I.serviceAccount.organizationId)throw new rt("not_found","Source connection was not found.",404);let x=t.sources.createBinding({projectId:W,environmentId:typeof $.environmentId==="string"?$.environmentId:void 0,resourceId:typeof $.resourceId==="string"?$.resourceId:void 0,connectionId:G.id,repositoryId:typeof $.repositoryId==="string"?$.repositoryId:void 0,repositoryFullName:String($.repositoryFullName??""),defaultBranch:String($.defaultBranch??"main"),branchRule:typeof $.branchRule==="string"?$.branchRule:void 0,tagRule:typeof $.tagRule==="string"?$.tagRule:void 0,monorepoRoot:String($.monorepoRoot??"."),includePaths:Array.isArray($.includePaths)?$.includePaths.map(String):[],excludePaths:Array.isArray($.excludePaths)?$.excludePaths.map(String):[],submodules:$.submodules===!0,cloneDepth:typeof $.cloneDepth==="number"?$.cloneDepth:void 0,deployKeyId:typeof $.deployKeyId==="string"&&$.deployKeyId?$.deployKeyId:void 0,autoDeploy:$.autoDeploy!==!1,pullRequestPreviews:$.pullRequestPreviews!==!1,actorId:I.actor.id});return i({binding:x,requestId:u},201,u,F)}else if(R.method==="POST"&&A.pathname==="/api/v1/source/webhooks"){if(!t.sources)throw new rt("not_found","Source integrations are unavailable.",404);e.authorize(I,"sources:manage",{type:"organization"});let $=await Z(),W=t.sources.getConnection(String($.connectionId??""));if(!W||W.organizationId!==I.serviceAccount.organizationId)throw new rt("not_found","Source connection was not found.",404);let G=typeof $.baseUrl==="string"?$.baseUrl:void 0;if(!G)throw new rt("validation_error","baseUrl is required.",422);let x=t.sources.createWebhook({connectionId:W.id,repositoryId:typeof $.repositoryId==="string"?$.repositoryId:void 0,repositoryFullName:String($.repositoryFullName??""),events:Array.isArray($.events)?$.events.map(String):void 0}),St=Xn(G,x.webhook),Q=$.reconcile===!1?x.webhook:await e_(t.sources,x.webhook.id,G);return i({webhook:Q,endpoint:St,endpointRevealOnce:!0,requestId:u},201,u,F)}else if(R.method==="DELETE"&&A.pathname==="/api/v1/source/connections"){if(!t.sources)throw new rt("not_found","Source integrations are unavailable.",404);e.authorize(I,"sources:manage",{type:"organization"});let $=await Z(),W=t.sources.getConnection(String($.id??""));if(!W||W.organizationId!==I.serviceAccount.organizationId)throw new rt("not_found","Source connection was not found.",404);let G=t.sources.listBindings({connectionId:W.id,status:"active"});if($.preview===!0)return i({preview:!0,affectedBindings:G,requestId:u},200,u,F);return i({...t.sources.disconnectConnection(W.id,I.actor.id),requestId:u},200,u,F)}else if(R.method==="GET"&&(A.pathname==="/api/v1/events"||A.pathname==="/api/v1/events/stream")){let $=e.listEvents(I,A.searchParams.get("projectId")??void 0,Number(A.searchParams.get("after"))||void 0);if(A.pathname.endsWith("/stream")){let W=new TextEncoder,G=$.reduce((Rt,ct)=>Math.max(Rt,Number(ct.sequence)),Number(A.searchParams.get("after"))||0),x,St=!1,Q=new ReadableStream({start(Rt){let ct=(m)=>Rt.enqueue(W.encode(`id: ${m.sequence}
|
|
5512
5512
|
event: ${m.type}
|
|
5513
5513
|
data: ${JSON.stringify(m)}
|
|
5514
5514
|
|
|
@@ -5516,20 +5516,20 @@ data: ${JSON.stringify(m)}
|
|
|
5516
5516
|
|
|
5517
5517
|
`));x=setInterval(()=>{if(St)return;let m=t.identities.verifyToken(w,N);if(!m){if(St=!0,x)clearInterval(x);Rt.close();return}try{let te=e.listEvents(m,A.searchParams.get("projectId")??void 0,G);for(let ge of te)ct(ge),G=Math.max(G,Number(ge.sequence));if(!te.length)Rt.enqueue(W.encode(`: heartbeat ${Date.now()}
|
|
5518
5518
|
|
|
5519
|
-
`))}catch{if(St=!0,x)clearInterval(x);Rt.close()}},1000),R.signal.addEventListener("abort",()=>{if(St=!0,x)clearInterval(x);try{Rt.close()}catch{}},{once:!0})},cancel(){if(St=!0,x)clearInterval(x)}});return new Response(Q,{status:200,headers:{"content-type":"text/event-stream","cache-control":"no-store",connection:"keep-alive","x-accel-buffering":"no","x-request-id":u,...F}})}B=Fe($,A,u,["sequence","id"])}else if(R.method==="POST"&&A.pathname==="/api/v1/deployments"){let $=R.headers.get("idempotency-key")??"";if(!$)throw new rt("idempotency_required","Idempotency-Key is required for deployment requests.",428);let W=await R.text();if(W.length>1048576)throw new rt("payload_too_large","Request body exceeds 1 MB.",413);let G;try{G=JSON.parse(W)}catch{throw new rt("invalid_json","Request body must be valid JSON.",400)}if(!G||typeof G.projectId!=="string"||typeof G.environmentId!=="string"||G.action!==void 0&&!["deploy","rollback"].includes(G.action))throw new rt("validation_error","projectId, environmentId, and a valid action are required.",422);let x=e.createDeployment(I,G,$);return i({operation:x.operation,idempotentReplay:x.replay,requestId:u},202,u,{...F,...x.replay?{"idempotent-replayed":"true"}:{}})}else throw new rt("not_found","API resource was not found.",404);return i(B,200,u,F)}catch(B){if(B instanceof rt)return h(B.code,B.message,B.status,u,B.details,F);if(A.pathname.startsWith("/api/v1/source/")||A.pathname.startsWith("/api/v1/application")||A.pathname.startsWith("/api/v1/compose-")||A.pathname==="/api/v1/registry-connections")return h("validation_error",B instanceof Error?B.message:"Integration request could not be completed.",422,u,void 0,F);return h("internal_error","The API request could not be completed.",500,u,void 0,F)}}}import{createCipheriv as Ay,createDecipheriv as Ly,createHash as $0,randomBytes as dd}from"node:crypto";import{createHmac as Sy,timingSafeEqual as Ny}from"node:crypto";var XS="ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";function MT(t){let e=0,r=0,d="";for(let E of t){r=r<<8|E,e+=8;while(e>=5)d+=XS[r>>>e-5&31],e-=5}if(e>0)d+=XS[r<<5-e&31];return d}function I0(t){let e=t.toUpperCase().replace(/[^A-Z2-7]/g,""),r=0,d=0,E=[];for(let n of e){let c=XS.indexOf(n);if(c<0)throw Error("Invalid base32 secret");if(d=d<<5|c,r+=5,r>=8)E.push(d>>>r-8&255),r-=8}return Buffer.from(E)}function D0(t,e,r=6){let d=Buffer.alloc(8);d.writeBigUInt64BE(BigInt(e));let E=Sy("sha1",I0(t)).update(d).digest(),n=E[E.length-1]&15,c=(E[n]&127)<<24|(E[n+1]&255)<<16|(E[n+2]&255)<<8|E[n+3]&255;return String(c%10**r).padStart(r,"0")}function GT(t,e,r=Date.now(),d=1){let E=e.replace(/[\s-]/g,"");if(!/^\d{6}$/.test(E))return;let n=Buffer.from(E),c=Math.floor(r/1000/30);for(let _=-d;_<=d;_++){if(c+_<0)continue;let T=Buffer.from(D0(t,c+_));if(n.length===T.length&&Ny(n,T))return c+_}return}function aS(t){let e=t.issuer?.trim()||"ts-cloud",r=`${e}:${t.account}`;return`otpauth://totp/${encodeURIComponent(r)}?secret=${encodeURIComponent(t.secret)}&issuer=${encodeURIComponent(e)}&algorithm=SHA1&digits=6&period=30`}var y0=1800000,Qd=43200000,X0=3600000,a0=300000,P0=600000;function pe(t){return typeof t==="string"?t:void 0}function j0(t){if(typeof t!=="string")return{};try{return JSON.parse(t)}catch{return{}}}function uy(t){let e=t.trim();if(!/^[a-z0-9][a-z0-9._-]{1,31}$/i.test(e))throw Error("Username must be 2-32 characters: letters, numbers, dot, dash or underscore");return e}function PS(t){if(t===void 0||!t.trim())return;let e=t.trim().toLowerCase();if(!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(e)||e.length>254)throw Error("A valid email address is required");return e}function Oy(t){let e=t.trim().toLowerCase();if(!/^[a-z0-9][a-z0-9-]{1,47}$/.test(e))throw Error("OIDC provider slug must be 2-48 lowercase letters, numbers or dashes");return e}function Cy(t){let e=new URL(t.trim());if(e.search||e.hash||e.username||e.password)throw Error("OIDC issuer cannot contain credentials, a query, or a fragment");if(e.protocol!=="https:"&&!(e.protocol==="http:"&&["127.0.0.1","::1","localhost"].includes(e.hostname)))throw Error("OIDC issuer must use HTTPS");return e.href.replace(/\/$/,"")}function ly(t){let e=[...new Set(t.map((r)=>r.trim().toLowerCase()).filter(Boolean))];if(e.length===0)throw Error("At least one explicit OIDC email domain is required");if(e.some((r)=>!/^[a-z0-9](?:[a-z0-9.-]{0,251}[a-z0-9])?$/.test(r)||!r.includes(".")||r.includes("..")))throw Error("OIDC email domains must be explicit DNS names without wildcards");return e}function Iy(t){let e=[...new Set(["openid",...t??["email","profile"]].map((r)=>r.trim()).filter(Boolean))];if(e.some((r)=>!/^[\x21\x23-\x5B\x5D-\x7E]+$/.test(r)))throw Error("OIDC scopes contain unsupported characters");return e}function
|
|
5519
|
+
`))}catch{if(St=!0,x)clearInterval(x);Rt.close()}},1000),R.signal.addEventListener("abort",()=>{if(St=!0,x)clearInterval(x);try{Rt.close()}catch{}},{once:!0})},cancel(){if(St=!0,x)clearInterval(x)}});return new Response(Q,{status:200,headers:{"content-type":"text/event-stream","cache-control":"no-store",connection:"keep-alive","x-accel-buffering":"no","x-request-id":u,...F}})}B=Fe($,A,u,["sequence","id"])}else if(R.method==="POST"&&A.pathname==="/api/v1/deployments"){let $=R.headers.get("idempotency-key")??"";if(!$)throw new rt("idempotency_required","Idempotency-Key is required for deployment requests.",428);let W=await R.text();if(W.length>1048576)throw new rt("payload_too_large","Request body exceeds 1 MB.",413);let G;try{G=JSON.parse(W)}catch{throw new rt("invalid_json","Request body must be valid JSON.",400)}if(!G||typeof G.projectId!=="string"||typeof G.environmentId!=="string"||G.action!==void 0&&!["deploy","rollback"].includes(G.action))throw new rt("validation_error","projectId, environmentId, and a valid action are required.",422);let x=e.createDeployment(I,G,$);return i({operation:x.operation,idempotentReplay:x.replay,requestId:u},202,u,{...F,...x.replay?{"idempotent-replayed":"true"}:{}})}else throw new rt("not_found","API resource was not found.",404);return i(B,200,u,F)}catch(B){if(B instanceof rt)return h(B.code,B.message,B.status,u,B.details,F);if(A.pathname.startsWith("/api/v1/source/")||A.pathname.startsWith("/api/v1/application")||A.pathname.startsWith("/api/v1/compose-")||A.pathname==="/api/v1/registry-connections")return h("validation_error",B instanceof Error?B.message:"Integration request could not be completed.",422,u,void 0,F);return h("internal_error","The API request could not be completed.",500,u,void 0,F)}}}import{createCipheriv as Ay,createDecipheriv as Ly,createHash as $0,randomBytes as dd}from"node:crypto";import{createHmac as Sy,timingSafeEqual as Ny}from"node:crypto";var XS="ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";function MT(t){let e=0,r=0,d="";for(let E of t){r=r<<8|E,e+=8;while(e>=5)d+=XS[r>>>e-5&31],e-=5}if(e>0)d+=XS[r<<5-e&31];return d}function I0(t){let e=t.toUpperCase().replace(/[^A-Z2-7]/g,""),r=0,d=0,E=[];for(let n of e){let c=XS.indexOf(n);if(c<0)throw Error("Invalid base32 secret");if(d=d<<5|c,r+=5,r>=8)E.push(d>>>r-8&255),r-=8}return Buffer.from(E)}function D0(t,e,r=6){let d=Buffer.alloc(8);d.writeBigUInt64BE(BigInt(e));let E=Sy("sha1",I0(t)).update(d).digest(),n=E[E.length-1]&15,c=(E[n]&127)<<24|(E[n+1]&255)<<16|(E[n+2]&255)<<8|E[n+3]&255;return String(c%10**r).padStart(r,"0")}function GT(t,e,r=Date.now(),d=1){let E=e.replace(/[\s-]/g,"");if(!/^\d{6}$/.test(E))return;let n=Buffer.from(E),c=Math.floor(r/1000/30);for(let _=-d;_<=d;_++){if(c+_<0)continue;let T=Buffer.from(D0(t,c+_));if(n.length===T.length&&Ny(n,T))return c+_}return}function aS(t){let e=t.issuer?.trim()||"ts-cloud",r=`${e}:${t.account}`;return`otpauth://totp/${encodeURIComponent(r)}?secret=${encodeURIComponent(t.secret)}&issuer=${encodeURIComponent(e)}&algorithm=SHA1&digits=6&period=30`}var y0=1800000,Qd=43200000,X0=3600000,a0=300000,P0=600000;function pe(t){return typeof t==="string"?t:void 0}function j0(t){if(typeof t!=="string")return{};try{return JSON.parse(t)}catch{return{}}}function uy(t){let e=t.trim();if(!/^[a-z0-9][a-z0-9._-]{1,31}$/i.test(e))throw Error("Username must be 2-32 characters: letters, numbers, dot, dash or underscore");return e}function PS(t){if(t===void 0||!t.trim())return;let e=t.trim().toLowerCase();if(!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(e)||e.length>254)throw Error("A valid email address is required");return e}function Oy(t){let e=t.trim().toLowerCase();if(!/^[a-z0-9][a-z0-9-]{1,47}$/.test(e))throw Error("OIDC provider slug must be 2-48 lowercase letters, numbers or dashes");return e}function Cy(t){let e=new URL(t.trim());if(e.search||e.hash||e.username||e.password)throw Error("OIDC issuer cannot contain credentials, a query, or a fragment");if(e.protocol!=="https:"&&!(e.protocol==="http:"&&["127.0.0.1","::1","localhost"].includes(e.hostname)))throw Error("OIDC issuer must use HTTPS");return e.href.replace(/\/$/,"")}function ly(t){let e=[...new Set(t.map((r)=>r.trim().toLowerCase()).filter(Boolean))];if(e.length===0)throw Error("At least one explicit OIDC email domain is required");if(e.some((r)=>!/^[a-z0-9](?:[a-z0-9.-]{0,251}[a-z0-9])?$/.test(r)||!r.includes(".")||r.includes("..")))throw Error("OIDC email domains must be explicit DNS names without wildcards");return e}function Iy(t){let e=[...new Set(["openid",...t??["email","profile"]].map((r)=>r.trim()).filter(Boolean))];if(e.some((r)=>!/^[\x21\x23-\x5B\x5D-\x7E]+$/.test(r)))throw Error("OIDC scopes contain unsupported characters");return e}function Xr(t){return $0("sha256").update(t).digest("hex")}function r_(t){return{id:String(t.id),actorId:String(t.actor_id),username:String(t.username),email:pe(t.email),emailVerifiedAt:pe(t.email_verified_at),passwordHash:String(t.password_hash),credentialVersion:Number(t.credential_version),requiresPasswordUpgrade:Number(t.requires_password_upgrade)===1,disabledAt:pe(t.disabled_at),lastLoginAt:pe(t.last_login_at),createdAt:String(t.created_at),updatedAt:String(t.updated_at)}}function f0(t,e){let r=pe(t.consumed_at),d=String(t.expires_at);return{id:String(t.id),identityId:String(t.identity_id),type:String(t.type),metadata:j0(t.metadata),expiresAt:d,consumedAt:r,createdAt:String(t.created_at),state:r?"consumed":d<=e?"expired":"pending"}}function jS(t,e){let r=pe(t.revoked_at),d=String(t.idle_expires_at),E=String(t.absolute_expires_at);return{id:String(t.id),identityId:String(t.identity_id),credentialVersion:Number(t.credential_version),authMethod:String(t.auth_method),userAgent:pe(t.user_agent),networkHint:pe(t.network_hint),createdAt:String(t.created_at),lastUsedAt:String(t.last_used_at),idleExpiresAt:d,absoluteExpiresAt:E,recentAuthAt:String(t.recent_auth_at),mfaAt:pe(t.mfa_at),revokedAt:r,state:r?"revoked":d<=e||E<=e?"expired":"active"}}function U0(t){let e=pe(t.verified_at),r=pe(t.disabled_at);return{id:String(t.id),identityId:String(t.identity_id),type:"totp",label:String(t.label),createdAt:String(t.created_at),verifiedAt:e,disabledAt:r,state:r?"disabled":e?"active":"pending"}}function zS(t,e){let r=pe(t.consumed_at),d=String(t.expires_at),E=Number(t.attempts);return{id:String(t.id),identityId:String(t.identity_id),purpose:String(t.purpose),attempts:E,expiresAt:d,consumedAt:r,createdAt:String(t.created_at),state:r?"consumed":E>=5?"locked":d<=e?"expired":"pending"}}function w0(t){let e=j0(t);return Array.isArray(e)?e.filter((r)=>typeof r==="string"):[]}function VT(t){return{id:String(t.id),organizationId:String(t.organization_id),slug:String(t.slug),name:String(t.name),issuer:String(t.issuer),clientId:String(t.client_id),hasClientSecret:typeof t.client_secret_ciphertext==="string"&&t.client_secret_ciphertext.length>0,scopes:w0(t.scopes),allowedDomains:w0(t.allowed_domains),defaultRole:String(t.default_role),enabled:Number(t.enabled)===1,enforceSso:Number(t.enforce_sso)===1,createdAt:String(t.created_at),updatedAt:String(t.updated_at)}}function g0(t,e){let r=pe(t.consumed_at),d=String(t.expires_at);return{id:String(t.id),providerId:String(t.provider_id),redirectUri:String(t.redirect_uri),returnPath:String(t.return_path),expiresAt:d,consumedAt:r,createdAt:String(t.created_at),state:r?"consumed":d<=e?"expired":"pending"}}function Dy(t){return{id:String(t.id),providerId:String(t.provider_id),identityId:String(t.identity_id),subject:String(t.subject),email:String(t.email),linkedAt:String(t.linked_at),lastLoginAt:String(t.last_login_at)}}class KT{controlPlane;nowFn;idFn;encryptionKey;constructor(t,e={}){this.controlPlane=t;this.nowFn=e.now??(()=>new Date),this.idFn=e.id??(()=>crypto.randomUUID()),this.encryptionKey=e.encryptionKey?$0("sha256").update(e.encryptionKey).digest():void 0}now(){return this.nowFn().toISOString()}run(t,e){this.controlPlane.database.run(t,e)}encrypt(t){if(!this.encryptionKey)throw Error("Authentication encryption key is not configured");let e=dd(12),r=Ay("aes-256-gcm",this.encryptionKey,e),d=Buffer.concat([r.update(t,"utf8"),r.final()]);return`v1.${e.toString("base64url")}.${r.getAuthTag().toString("base64url")}.${d.toString("base64url")}`}decrypt(t){if(!this.encryptionKey)throw Error("Authentication encryption key is not configured");let[e,r,d,E]=t.split(".");if(e!=="v1"||!r||!d||!E)throw Error("Encrypted authentication value is unavailable");let n=Ly("aes-256-gcm",this.encryptionKey,Buffer.from(r,"base64url"));return n.setAuthTag(Buffer.from(d,"base64url")),Buffer.concat([n.update(Buffer.from(E,"base64url")),n.final()]).toString("utf8")}createIdentity(t){if(!this.controlPlane.getActor(t.actorId))throw Error("Authentication actor was not found");let e=uy(t.username),r=PS(t.email),d=t.id??this.idFn(),E=this.now();return this.run(`INSERT INTO auth_identities (id, actor_id, username, email, email_verified_at, password_hash, requires_password_upgrade, created_at, updated_at)
|
|
5520
5520
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,[d,t.actorId,e,r??null,t.emailVerified&&r?E:null,t.passwordHash,t.requiresPasswordUpgrade?1:0,E,E]),this.getIdentity(d)}getIdentity(t){let e=this.controlPlane.database.query("SELECT * FROM auth_identities WHERE id = ?").get(t);return e?r_(e):void 0}getIdentityByActor(t){let e=this.controlPlane.database.query("SELECT * FROM auth_identities WHERE actor_id = ?").get(t);return e?r_(e):void 0}getIdentityByUsername(t){let e=this.controlPlane.database.query("SELECT * FROM auth_identities WHERE username = ? COLLATE NOCASE").get(t.trim());return e?r_(e):void 0}getIdentityByEmail(t){let e=this.controlPlane.database.query("SELECT * FROM auth_identities WHERE email = ? COLLATE NOCASE").get(t.trim().toLowerCase());return e?r_(e):void 0}listIdentities(){return this.controlPlane.database.query("SELECT * FROM auth_identities ORDER BY username COLLATE NOCASE").all().map(r_)}updatePassword(t,e,r={}){if(!this.getIdentity(t))throw Error("Authentication identity was not found");let E=this.now();return this.controlPlane.transaction(()=>{if(this.run(`UPDATE auth_identities SET password_hash = ?, credential_version = credential_version + 1,
|
|
5521
|
-
requires_password_upgrade = ?, updated_at = ? WHERE id = ?`,[e,r.requiresUpgrade?1:0,E,t]),r.revokeSessions!==!1)this.run("UPDATE auth_sessions SET revoked_at = ? WHERE identity_id = ? AND revoked_at IS NULL",[E,t])}),this.getIdentity(t)}rehashPassword(t,e){let r=this.now();this.run("UPDATE auth_identities SET password_hash = ?, requires_password_upgrade = 0, updated_at = ? WHERE id = ?",[e,r,t]);let d=this.getIdentity(t);if(!d)throw Error("Authentication identity was not found");return d}setVerifiedEmail(t,e){let r=PS(e),d=this.now();this.run("UPDATE auth_identities SET email = ?, email_verified_at = ?, updated_at = ? WHERE id = ?",[r,d,d,t]);let E=this.getIdentity(t);if(!E)throw Error("Authentication identity was not found");return E}recordLogin(t){let e=this.now();this.run("UPDATE auth_identities SET last_login_at = ?, updated_at = ? WHERE id = ?",[e,e,t]);let r=this.getIdentity(t);if(!r)throw Error("Authentication identity was not found");return r}setDisabled(t,e){let r=this.now();this.controlPlane.transaction(()=>{if(this.run("UPDATE auth_identities SET disabled_at = ?, credential_version = credential_version + 1, updated_at = ? WHERE id = ?",[e?r:null,r,t]),e)this.run("UPDATE auth_sessions SET revoked_at = ? WHERE identity_id = ? AND revoked_at IS NULL",[r,t])});let d=this.getIdentity(t);if(!d)throw Error("Authentication identity was not found");return d}createActionToken(t,e,r={}){if(!this.getIdentity(t))throw Error("Authentication identity was not found");let d=dd(32).toString("base64url"),E=this.idFn(),n=this.now(),c=new Date(this.nowFn().getTime()+Math.min(86400000,Math.max(60000,r.ttlMs??X0))).toISOString();return this.run("INSERT INTO auth_action_tokens (id, identity_id, type, token_hash, metadata, expires_at, created_at) VALUES (?, ?, ?, ?, ?, ?, ?)",[E,t,e,
|
|
5521
|
+
requires_password_upgrade = ?, updated_at = ? WHERE id = ?`,[e,r.requiresUpgrade?1:0,E,t]),r.revokeSessions!==!1)this.run("UPDATE auth_sessions SET revoked_at = ? WHERE identity_id = ? AND revoked_at IS NULL",[E,t])}),this.getIdentity(t)}rehashPassword(t,e){let r=this.now();this.run("UPDATE auth_identities SET password_hash = ?, requires_password_upgrade = 0, updated_at = ? WHERE id = ?",[e,r,t]);let d=this.getIdentity(t);if(!d)throw Error("Authentication identity was not found");return d}setVerifiedEmail(t,e){let r=PS(e),d=this.now();this.run("UPDATE auth_identities SET email = ?, email_verified_at = ?, updated_at = ? WHERE id = ?",[r,d,d,t]);let E=this.getIdentity(t);if(!E)throw Error("Authentication identity was not found");return E}recordLogin(t){let e=this.now();this.run("UPDATE auth_identities SET last_login_at = ?, updated_at = ? WHERE id = ?",[e,e,t]);let r=this.getIdentity(t);if(!r)throw Error("Authentication identity was not found");return r}setDisabled(t,e){let r=this.now();this.controlPlane.transaction(()=>{if(this.run("UPDATE auth_identities SET disabled_at = ?, credential_version = credential_version + 1, updated_at = ? WHERE id = ?",[e?r:null,r,t]),e)this.run("UPDATE auth_sessions SET revoked_at = ? WHERE identity_id = ? AND revoked_at IS NULL",[r,t])});let d=this.getIdentity(t);if(!d)throw Error("Authentication identity was not found");return d}createActionToken(t,e,r={}){if(!this.getIdentity(t))throw Error("Authentication identity was not found");let d=dd(32).toString("base64url"),E=this.idFn(),n=this.now(),c=new Date(this.nowFn().getTime()+Math.min(86400000,Math.max(60000,r.ttlMs??X0))).toISOString();return this.run("INSERT INTO auth_action_tokens (id, identity_id, type, token_hash, metadata, expires_at, created_at) VALUES (?, ?, ?, ?, ?, ?, ?)",[E,t,e,Xr(d),JSON.stringify(r.metadata??{}),c,n]),{actionToken:this.getActionToken(E),token:d}}getActionToken(t){let e=this.controlPlane.database.query("SELECT * FROM auth_action_tokens WHERE id = ?").get(t);return e?f0(e,this.now()):void 0}consumeActionToken(t,e){return this.controlPlane.transaction(()=>{let r=this.controlPlane.database.query("SELECT * FROM auth_action_tokens WHERE token_hash = ? AND type = ?").get(Xr(t),e);if(!r)throw Error("Action token is invalid");let d=f0(r,this.now());if(d.state!=="pending")throw Error(`Action token is ${d.state}`);if(this.controlPlane.database.run("UPDATE auth_action_tokens SET consumed_at = ? WHERE id = ? AND consumed_at IS NULL AND expires_at > ?",[this.now(),d.id,this.now()]).changes!==1)throw Error("Action token is no longer available");return this.getActionToken(d.id)})}revokeActionTokens(t,e){return this.controlPlane.database.run("UPDATE auth_action_tokens SET consumed_at = ? WHERE identity_id = ? AND type = ? AND consumed_at IS NULL",[this.now(),t,e]).changes}createSession(t){let e=this.getIdentity(t.identityId);if(!e||e.disabledAt)throw Error("Authentication identity is unavailable");let r=this.idFn(),d=dd(32).toString("base64url"),E=`v2.${r}.${d}`,n=this.now(),c=Math.min(86400000,Math.max(60000,t.idleTtlMs??y0)),_=Math.min(2592000000,Math.max(c,t.absoluteTtlMs??Qd));return this.run(`INSERT INTO auth_sessions (id, identity_id, token_hash, credential_version, auth_method, user_agent, network_hint,
|
|
5522
5522
|
created_at, last_used_at, idle_expires_at, absolute_expires_at, recent_auth_at, mfa_at)
|
|
5523
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,[r,e.id,
|
|
5523
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,[r,e.id,Xr(E),e.credentialVersion,t.authMethod??"local",t.userAgent?.slice(0,256)??null,t.networkHint?.slice(0,128)??null,n,n,new Date(this.nowFn().getTime()+c).toISOString(),new Date(this.nowFn().getTime()+_).toISOString(),t.recentAuthAt??n,t.mfaAt??null]),{session:this.getSession(r),token:E}}getSession(t){let e=this.controlPlane.database.query("SELECT * FROM auth_sessions WHERE id = ?").get(t);return e?jS(e,this.now()):void 0}verifySessionToken(t){let e=/^v2\.([^.]+)\.[A-Za-z0-9_-]{40,}$/.exec(t);if(!e)return;let r=this.controlPlane.database.query("SELECT * FROM auth_sessions WHERE id = ? AND token_hash = ?").get(e[1],Xr(t));if(!r)return;let d=jS(r,this.now()),E=this.getIdentity(d.identityId);if(!E||E.disabledAt||d.state!=="active"||d.credentialVersion!==E.credentialVersion)return;let n=this.now(),c=new Date(r.idle_expires_at).getTime()-new Date(r.last_used_at).getTime();return this.run("UPDATE auth_sessions SET last_used_at = ?, idle_expires_at = ? WHERE id = ?",[n,new Date(Math.min(this.nowFn().getTime()+c,new Date(d.absoluteExpiresAt).getTime())).toISOString(),d.id]),{identity:E,session:this.getSession(d.id)}}listSessions(t,e={}){let r=this.controlPlane.database.query("SELECT * FROM auth_sessions WHERE identity_id = ? ORDER BY last_used_at DESC").all(t).map((d)=>jS(d,this.now()));return e.includeInactive?r:r.filter((d)=>d.state==="active")}revokeSession(t,e){return this.controlPlane.database.run("UPDATE auth_sessions SET revoked_at = ? WHERE id = ? AND identity_id = ? AND revoked_at IS NULL",[this.now(),e,t]).changes===1}revokeOtherSessions(t,e){return this.controlPlane.database.run("UPDATE auth_sessions SET revoked_at = ? WHERE identity_id = ? AND id != ? AND revoked_at IS NULL",[this.now(),t,e]).changes}getMfaFactor(t){let e=this.controlPlane.database.query("SELECT * FROM auth_mfa_factors WHERE identity_id = ?").get(t);return e?U0(e):void 0}beginTotpEnrollment(t,e={}){let r=this.getIdentity(t);if(!r)throw Error("Authentication identity was not found");let d=this.getMfaFactor(t);if(d?.state==="active")throw Error("MFA is already enabled");let E=MT(dd(20)),n=e.label?.trim().slice(0,80)||r.email||r.username,c=d?.id??this.idFn(),_=this.now();return this.controlPlane.transaction(()=>{if(d)this.run("UPDATE auth_mfa_factors SET label = ?, secret_ciphertext = ?, created_at = ?, verified_at = NULL, disabled_at = NULL WHERE id = ?",[n,this.encrypt(E),_,c]);else this.run("INSERT INTO auth_mfa_factors (id, identity_id, label, secret_ciphertext, created_at) VALUES (?, ?, ?, ?, ?)",[c,t,n,this.encrypt(E),_]);this.run("DELETE FROM auth_recovery_codes WHERE identity_id = ?",[t])}),{factor:this.getMfaFactor(t),secret:E,uri:aS({secret:E,account:n,issuer:e.issuer})}}verifyTotpEnrollment(t,e){let r=this.controlPlane.database.query("SELECT * FROM auth_mfa_factors WHERE identity_id = ?").get(t);if(!r||U0(r).state!=="pending")throw Error("MFA enrollment is not pending");let d=GT(this.decrypt(String(r.secret_ciphertext)),e,this.nowFn().getTime());if(d===void 0)throw Error("Authenticator code is invalid");let E=Array.from({length:10},()=>{let c=MT(dd(8)).slice(0,12);return`${c.slice(0,4)}-${c.slice(4,8)}-${c.slice(8)}`}),n=this.now();return this.controlPlane.transaction(()=>{this.run("UPDATE auth_mfa_factors SET verified_at = ?, disabled_at = NULL, last_used_step = ? WHERE identity_id = ?",[n,d,t]),this.run("DELETE FROM auth_recovery_codes WHERE identity_id = ?",[t]);for(let c of E)this.run("INSERT INTO auth_recovery_codes (id, identity_id, code_hash, created_at) VALUES (?, ?, ?, ?)",[this.idFn(),t,Xr(`${t}:${c.replace(/-/g,"").toUpperCase()}`),n])}),{factor:this.getMfaFactor(t),recoveryCodes:E}}verifyMfaCode(t,e,r={}){let d=this.controlPlane.database.query("SELECT * FROM auth_mfa_factors WHERE identity_id = ? AND verified_at IS NOT NULL AND disabled_at IS NULL").get(t);if(!d)return{valid:!1};let E=GT(this.decrypt(String(d.secret_ciphertext)),e,this.nowFn().getTime());if(E!==void 0){if(this.controlPlane.database.run("UPDATE auth_mfa_factors SET last_used_step = ? WHERE identity_id = ? AND (last_used_step IS NULL OR last_used_step < ?)",[E,t,E]).changes===1)return{valid:!0,method:"totp"}}let n=e.replace(/[-\s]/g,"").toUpperCase();if(!/^[A-Z2-7]{12}$/.test(n))return{valid:!1};let c=Xr(`${t}:${n}`),_=this.controlPlane.database.query("SELECT * FROM auth_recovery_codes WHERE identity_id = ? AND code_hash = ? AND consumed_at IS NULL").get(t,c);if(!_)return{valid:!1};if(r.consumeRecovery!==!1){if(this.controlPlane.database.run("UPDATE auth_recovery_codes SET consumed_at = ? WHERE id = ? AND consumed_at IS NULL",[this.now(),String(_.id)]).changes!==1)return{valid:!1}}return{valid:!0,method:"recovery"}}remainingRecoveryCodes(t){return Number(this.controlPlane.database.query("SELECT COUNT(*) AS count FROM auth_recovery_codes WHERE identity_id = ? AND consumed_at IS NULL").get(t)?.count??0)}disableMfa(t){let e=this.now();this.controlPlane.transaction(()=>{this.run("UPDATE auth_mfa_factors SET disabled_at = ? WHERE identity_id = ? AND disabled_at IS NULL",[e,t]),this.run("DELETE FROM auth_recovery_codes WHERE identity_id = ?",[t]),this.run("UPDATE auth_mfa_challenges SET consumed_at = ? WHERE identity_id = ? AND consumed_at IS NULL",[e,t])})}createMfaChallenge(t,e){if(this.getMfaFactor(t)?.state!=="active")throw Error("MFA is not enabled");let r=dd(32).toString("base64url"),d=this.idFn(),E=this.now(),n=new Date(this.nowFn().getTime()+a0).toISOString();return this.controlPlane.transaction(()=>{this.run("UPDATE auth_mfa_challenges SET consumed_at = ? WHERE identity_id = ? AND purpose = ? AND consumed_at IS NULL",[E,t,e]),this.run("INSERT INTO auth_mfa_challenges (id, identity_id, purpose, token_hash, expires_at, created_at) VALUES (?, ?, ?, ?, ?, ?)",[d,t,e,Xr(r),n,E])}),{challenge:this.getMfaChallenge(d),token:r}}getMfaChallenge(t){let e=this.controlPlane.database.query("SELECT * FROM auth_mfa_challenges WHERE id = ?").get(t);return e?zS(e,this.now()):void 0}inspectMfaChallengeToken(t,e){let r=this.controlPlane.database.query("SELECT * FROM auth_mfa_challenges WHERE token_hash = ? AND purpose = ?").get(Xr(t),e);return r?zS(r,this.now()):void 0}completeMfaChallenge(t,e,r){let d=this.controlPlane.database.query("SELECT * FROM auth_mfa_challenges WHERE token_hash = ? AND purpose = ?").get(Xr(t),r);if(!d)throw Error("MFA challenge is invalid");let E=zS(d,this.now());if(E.state!=="pending")throw Error(`MFA challenge is ${E.state}`);let n=this.verifyMfaCode(E.identityId,e);if(!n.valid||!n.method)throw this.run("UPDATE auth_mfa_challenges SET attempts = attempts + 1 WHERE id = ?",[E.id]),Error("Authenticator or recovery code is invalid");if(this.controlPlane.database.run("UPDATE auth_mfa_challenges SET consumed_at = ? WHERE id = ? AND consumed_at IS NULL AND attempts < 5 AND expires_at > ?",[this.now(),E.id,this.now()]).changes!==1)throw Error("MFA challenge is no longer available");return{identity:this.getIdentity(E.identityId),challenge:this.getMfaChallenge(E.id),method:n.method}}markSessionStepUp(t,e=!1){let r=this.now();this.run("UPDATE auth_sessions SET recent_auth_at = ?, mfa_at = CASE WHEN ? = 1 THEN ? ELSE mfa_at END WHERE id = ? AND revoked_at IS NULL",[r,e?1:0,r,t]);let d=this.getSession(t);if(!d)throw Error("Authentication session was not found");return d}isRecentlyAuthenticated(t,e=600000){return this.nowFn().getTime()-new Date(t.recentAuthAt).getTime()<=e}upsertOidcProvider(t){if(!this.controlPlane.getOrganization(t.organizationId))throw Error("OIDC provider organization was not found");let e=Oy(t.slug),r=t.name.trim().slice(0,80);if(!r)throw Error("OIDC provider name is required");let d=Cy(t.issuer),E=t.clientId.trim();if(!E||E.length>512)throw Error("OIDC client ID is required");let n=Iy(t.scopes),c=ly(t.allowedDomains),_=t.id?this.getOidcProvider(t.id):this.getOidcProviderBySlug(e),T=this.now();if(_){if(_.organizationId!==t.organizationId)throw Error("OIDC provider belongs to another organization");return this.run(`UPDATE auth_oidc_providers SET slug = ?, name = ?, issuer = ?, client_id = ?,
|
|
5524
5524
|
client_secret_ciphertext = COALESCE(?, client_secret_ciphertext), scopes = ?, allowed_domains = ?,
|
|
5525
5525
|
default_role = ?, enabled = ?, enforce_sso = ?, updated_at = ? WHERE id = ?`,[e,r,d,E,t.clientSecret?this.encrypt(t.clientSecret):null,JSON.stringify(n),JSON.stringify(c),t.defaultRole??_.defaultRole,t.enabled??_.enabled?1:0,t.enforceSso??_.enforceSso?1:0,T,_.id]),this.getOidcProvider(_.id)}if(!t.clientSecret)throw Error("OIDC client secret is required for a new provider");let i=t.id??this.idFn();return this.run(`INSERT INTO auth_oidc_providers (id, organization_id, slug, name, issuer, client_id,
|
|
5526
5526
|
client_secret_ciphertext, scopes, allowed_domains, default_role, enabled, enforce_sso, created_at, updated_at)
|
|
5527
5527
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,[i,t.organizationId,e,r,d,E,this.encrypt(t.clientSecret),JSON.stringify(n),JSON.stringify(c),t.defaultRole??"viewer",t.enabled===!1?0:1,t.enforceSso?1:0,T,T]),this.getOidcProvider(i)}getOidcProvider(t){let e=this.controlPlane.database.query("SELECT * FROM auth_oidc_providers WHERE id = ?").get(t);return e?VT(e):void 0}getOidcProviderBySlug(t){let e=this.controlPlane.database.query("SELECT * FROM auth_oidc_providers WHERE slug = ? COLLATE NOCASE").get(t.trim());return e?VT(e):void 0}listOidcProviders(t,e={}){return(t?this.controlPlane.database.query("SELECT * FROM auth_oidc_providers WHERE organization_id = ? ORDER BY name COLLATE NOCASE").all(t):this.controlPlane.database.query("SELECT * FROM auth_oidc_providers ORDER BY name COLLATE NOCASE").all()).map(VT).filter((d)=>e.includeDisabled||d.enabled)}setOidcProviderEnabled(t,e){let r=this.now();if(this.controlPlane.database.run("UPDATE auth_oidc_providers SET enabled = ?, enforce_sso = CASE WHEN ? = 0 THEN 0 ELSE enforce_sso END, updated_at = ? WHERE id = ?",[e?1:0,e?1:0,r,t]).changes!==1)throw Error("OIDC provider was not found");if(!e)this.run("UPDATE auth_oidc_transactions SET consumed_at = ? WHERE provider_id = ? AND consumed_at IS NULL",[r,t]);return this.getOidcProvider(t)}getOidcProviderCredentials(t){let e=this.controlPlane.database.query("SELECT * FROM auth_oidc_providers WHERE id = ?").get(t);if(!e||typeof e.client_secret_ciphertext!=="string")throw Error("OIDC provider credentials are unavailable");return{provider:VT(e),clientSecret:this.decrypt(e.client_secret_ciphertext)}}beginOidcTransaction(t,e,r){if(!this.getOidcProvider(t)?.enabled)throw Error("OIDC provider is unavailable");let E=this.idFn(),n=dd(32).toString("base64url"),c=dd(32).toString("base64url"),_=dd(64).toString("base64url"),T=this.now(),i=new Date(this.nowFn().getTime()+P0).toISOString();return this.run(`INSERT INTO auth_oidc_transactions (id, provider_id, state_hash, nonce_ciphertext, verifier_ciphertext,
|
|
5528
|
-
redirect_uri, return_path, expires_at, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,[E,t,
|
|
5528
|
+
redirect_uri, return_path, expires_at, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,[E,t,Xr(n),this.encrypt(c),this.encrypt(_),e,r,i,T]),{transaction:this.getOidcTransaction(E),state:n,nonce:c,verifier:_}}getOidcTransaction(t){let e=this.controlPlane.database.query("SELECT * FROM auth_oidc_transactions WHERE id = ?").get(t);return e?g0(e,this.now()):void 0}consumeOidcTransaction(t,e){return this.controlPlane.transaction(()=>{let r=this.controlPlane.database.query("SELECT * FROM auth_oidc_transactions WHERE provider_id = ? AND state_hash = ?").get(t,Xr(e));if(!r)throw Error("OIDC transaction is invalid");let d=g0(r,this.now());if(d.state!=="pending")throw Error(`OIDC transaction is ${d.state}`);if(this.controlPlane.database.run("UPDATE auth_oidc_transactions SET consumed_at = ? WHERE id = ? AND consumed_at IS NULL AND expires_at > ?",[this.now(),d.id,this.now()]).changes!==1)throw Error("OIDC transaction is no longer available");return{transaction:this.getOidcTransaction(d.id),nonce:this.decrypt(String(r.nonce_ciphertext)),verifier:this.decrypt(String(r.verifier_ciphertext))}})}getOidcSubject(t,e){let r=this.controlPlane.database.query("SELECT * FROM auth_oidc_subjects WHERE provider_id = ? AND subject = ?").get(t,e);return r?Dy(r):void 0}linkOidcSubject(t,e,r,d){let E=this.getOidcProvider(t),n=this.getIdentity(e);if(!E||!n)throw Error("OIDC provider or identity was not found");let c=PS(d);if(!r.trim()||r.length>512)throw Error("OIDC subject is invalid");let _=this.getOidcSubject(t,r);if(_&&_.identityId!==e)throw Error("OIDC subject is already linked to another identity");let T=this.now();if(_)return this.run("UPDATE auth_oidc_subjects SET email = ?, last_login_at = ? WHERE id = ?",[c,T,_.id]),this.getOidcSubject(t,r);let i=this.idFn();return this.run("INSERT INTO auth_oidc_subjects (id, provider_id, identity_id, subject, email, linked_at, last_login_at) VALUES (?, ?, ?, ?, ?, ?, ?)",[i,t,e,r,c,T,T]),this.getOidcSubject(t,r)}purgeExpired(){let t=this.now(),e=this.controlPlane.database.run("DELETE FROM auth_action_tokens WHERE expires_at < ? OR consumed_at IS NOT NULL",[t]).changes,r=this.controlPlane.database.run("DELETE FROM auth_sessions WHERE revoked_at IS NOT NULL OR idle_expires_at < ? OR absolute_expires_at < ?",[t,t]).changes;return this.controlPlane.database.run("DELETE FROM auth_mfa_challenges WHERE consumed_at IS NOT NULL OR expires_at < ?",[t]),this.controlPlane.database.run("DELETE FROM auth_oidc_transactions WHERE consumed_at IS NOT NULL OR expires_at < ?",[t]),{actionTokens:e,sessions:r}}}async function c_(t,e){let r=t.notifications?.email?.from;if(!r)return!1;try{let{EmailClient:d}=await Promise.resolve().then(() => (qT(),HS));return await new d({region:t.project.region,defaultFrom:r}).send(e),!0}catch{return!1}}await Ht();import{randomBytes as Hy}from"node:crypto";import{chmodSync as Wy,existsSync as vy,mkdirSync as Qy,readFileSync as Yy,writeFileSync as My}from"node:fs";import{dirname as Gy}from"node:path";function Gd(t){let e=process.env.TS_CLOUD_AUTH_ENCRYPTION_KEY?.trim();if(e)return e;let r=ne(t,"auth-encryption-key");try{if(vy(r)){let E=Yy(r,"utf8").trim();if(E)return E}}catch{}let d=Hy(32).toString("base64url");try{Qy(Gy(r),{recursive:!0,mode:448}),My(r,`${d}
|
|
5529
5529
|
`,{mode:384}),Wy(r,384)}catch{}return d}import{constants as K0,createHash as WS,createPublicKey as Vy,createVerify as Ky,timingSafeEqual as Zy}from"node:crypto";var k0=new Set(["RS256","PS256","ES256"]),Z0=60;function sT(t,e){let r=new URL(t),d=["127.0.0.1","::1","localhost"].includes(r.hostname);if(r.protocol!=="https:"&&!(r.protocol==="http:"&&d))throw Error(`${e} must use HTTPS`);if(r.username||r.password||r.hash)throw Error(`${e} contains unsupported URL components`);return r}function vS(t,e){if(!t||typeof t!=="object"||Array.isArray(t))throw Error(`${e} is invalid`);return t}async function QS(t,e){if(!t.ok)throw Error(`${e} failed with HTTP ${t.status}`);if(!(t.headers.get("content-type")??"").toLowerCase().includes("application/json"))throw Error(`${e} returned an unsupported content type`);if(Number(t.headers.get("content-length")??0)>1048576)throw Error(`${e} response is too large`);let E=await t.text();if(E.length>1048576)throw Error(`${e} response is too large`);try{return vS(JSON.parse(E),e)}catch(n){if(n instanceof Error&&n.message===`${e} is invalid`)throw n;throw Error(`${e} returned invalid JSON`)}}function ky(t,e){let r=WS("sha256").update(t).digest(),d=WS("sha256").update(e).digest();return Zy(r,d)}function b0(t){if(!t)return"/";let e=t.trim();if(!e.startsWith("/")||e.startsWith("//")||e.includes("\\")||/[\r\n]/.test(e))return"/";try{let r=new URL(e,"https://local.invalid");return r.origin==="https://local.invalid"?`${r.pathname}${r.search}${r.hash}`:"/"}catch{return"/"}}async function YS(t,e=fetch){let r=sT(t.issuer,"OIDC issuer"),d=new URL(`${r.pathname.replace(/\/$/,"")}/.well-known/openid-configuration`,r.origin),E=await QS(await e(d,{headers:{accept:"application/json"},redirect:"error",signal:AbortSignal.timeout(1e4)}),"OIDC discovery");if(E.issuer!==t.issuer)throw Error("OIDC discovery issuer does not match the configured issuer");for(let c of["authorization_endpoint","token_endpoint","jwks_uri"]){if(typeof E[c]!=="string")throw Error(`OIDC discovery is missing ${c}`);sT(E[c],`OIDC ${c}`)}if(Array.isArray(E.response_types_supported)&&!E.response_types_supported.includes("code"))throw Error("OIDC provider does not support authorization code flow");if(Array.isArray(E.code_challenge_methods_supported)&&!E.code_challenge_methods_supported.includes("S256"))throw Error("OIDC provider does not support PKCE S256");let n=Array.isArray(E.id_token_signing_alg_values_supported)?E.id_token_signing_alg_values_supported.filter((c)=>typeof c==="string"):[];if(n.length>0&&!n.some((c)=>k0.has(c)))throw Error("OIDC provider does not offer a supported ID-token signing algorithm");return E}async function MS(t,e,r,d,E=fetch){let n=t.getOidcProviderBySlug(e);if(!n?.enabled)throw Error("OIDC provider is unavailable");let c=sT(r,"Application origin").origin,_=await YS(n,E),T=`${c}/auth/oidc/${encodeURIComponent(n.slug)}/callback`,i=t.beginOidcTransaction(n.id,T,b0(d)),h=new URL(_.authorization_endpoint);return h.searchParams.set("response_type","code"),h.searchParams.set("client_id",n.clientId),h.searchParams.set("redirect_uri",T),h.searchParams.set("scope",n.scopes.join(" ")),h.searchParams.set("state",i.state),h.searchParams.set("nonce",i.nonce),h.searchParams.set("code_challenge",WS("sha256").update(i.verifier).digest("base64url")),h.searchParams.set("code_challenge_method","S256"),{authorizationUrl:h.href,expiresAt:i.transaction.expiresAt}}function by(t){if(t.length>32768)throw Error("OIDC ID token is too large");let e=t.split(".");if(e.length!==3||e.some((r)=>!r))throw Error("OIDC ID token is malformed");try{return{header:vS(JSON.parse(Buffer.from(e[0],"base64url").toString("utf8")),"OIDC ID-token header"),claims:vS(JSON.parse(Buffer.from(e[1],"base64url").toString("utf8")),"OIDC ID-token claims"),signingInput:`${e[0]}.${e[1]}`,signature:Buffer.from(e[2],"base64url")}}catch(r){if(r instanceof Error&&r.message.startsWith("OIDC"))throw r;throw Error("OIDC ID token is malformed")}}async function xy(t,e,r){let d=by(t),E=typeof d.header.alg==="string"?d.header.alg:"",n=typeof d.header.kid==="string"?d.header.kid:"";if(!k0.has(E)||!n)throw Error("OIDC ID token uses an unsupported signing key");if(e.id_token_signing_alg_values_supported&&!e.id_token_signing_alg_values_supported.includes(E))throw Error("OIDC ID-token algorithm was not advertised by the provider");let c=await QS(await r(e.jwks_uri,{headers:{accept:"application/json"},redirect:"error",signal:AbortSignal.timeout(1e4)}),"OIDC signing-key request");if(!Array.isArray(c.keys))throw Error("OIDC signing-key response is invalid");let _=c.keys.find((R)=>{if(!R||typeof R!=="object"||Array.isArray(R))return!1;let N=R;return N.kid===n&&(!N.alg||N.alg===E)&&(!N.use||N.use==="sig")});if(!_)throw Error("OIDC ID-token signing key was not found");let T=Vy({key:_,format:"jwk"}),i=Ky("SHA256").update(d.signingInput).end();if(!(E==="PS256"?i.verify({key:T,padding:K0.RSA_PKCS1_PSS_PADDING,saltLength:32},d.signature):E==="ES256"?i.verify({key:T,dsaEncoding:"ieee-p1363"},d.signature):i.verify(T,d.signature)))throw Error("OIDC ID-token signature is invalid");return d.claims}function qy(t,e,r,d){if(t.iss!==e.issuer)throw Error("OIDC ID-token issuer is invalid");let E=typeof t.aud==="string"?[t.aud]:Array.isArray(t.aud)?t.aud.filter((T)=>typeof T==="string"):[];if(!E.includes(e.clientId))throw Error("OIDC ID-token audience is invalid");if((E.length>1||t.azp!==void 0)&&t.azp!==e.clientId)throw Error("OIDC ID-token authorized party is invalid");let n=Math.floor(d.getTime()/1000);if(typeof t.exp!=="number"||t.exp<n-Z0)throw Error("OIDC ID token is expired");if(typeof t.iat!=="number"||t.iat>n+Z0)throw Error("OIDC ID-token issued-at time is invalid");if(typeof t.nonce!=="string"||!ky(t.nonce,r))throw Error("OIDC ID-token nonce is invalid");if(typeof t.sub!=="string"||!t.sub||t.sub.length>512)throw Error("OIDC ID-token subject is invalid");if(t.email_verified!==!0||typeof t.email!=="string")throw Error("OIDC provider did not return a verified email address");let c=t.email.trim().toLowerCase();if(c.length>254||!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(c))throw Error("OIDC provider returned an invalid email address");let _=c.split("@")[1];if(!_||!e.allowedDomains.includes(_))throw Error("OIDC email domain is not allowed for this organization");return{provider:e,subject:t.sub,email:c,name:typeof t.name==="string"?t.name.slice(0,120):void 0,claims:t}}async function GS(t,e,r=fetch){let d=t.getOidcProviderBySlug(e.providerSlug);if(!d?.enabled)throw Error("OIDC provider is unavailable");if(!e.state||e.state.length>512||!e.code||e.code.length>4096)throw Error("OIDC callback is incomplete");let E=sT(e.origin,"Application origin").origin,n=t.consumeOidcTransaction(d.id,e.state),c=`${E}/auth/oidc/${encodeURIComponent(d.slug)}/callback`;if(n.transaction.redirectUri!==c)throw Error("OIDC callback redirect URI does not match the original request");let{clientSecret:_}=t.getOidcProviderCredentials(d.id),T=await YS(d,r),i=new URLSearchParams({grant_type:"authorization_code",code:e.code,redirect_uri:n.transaction.redirectUri,code_verifier:n.verifier}),h={accept:"application/json","content-type":"application/x-www-form-urlencoded"},R=T.token_endpoint_auth_methods_supported??["client_secret_basic"];if(R.includes("client_secret_basic")){let u=(w)=>new URLSearchParams({value:w}).toString().slice(6),f=`${u(d.clientId)}:${u(_)}`;h.authorization=`Basic ${Buffer.from(f).toString("base64")}`}else if(R.includes("client_secret_post"))i.set("client_id",d.clientId),i.set("client_secret",_);else throw Error("OIDC provider does not support a configured client authentication method");let N=await QS(await r(T.token_endpoint,{method:"POST",headers:h,body:i,redirect:"error",signal:AbortSignal.timeout(1e4)}),"OIDC token exchange");if(typeof N.id_token!=="string")throw Error("OIDC token response did not include an ID token");let A=await xy(N.id_token,T,r);return{identity:qy(A,d,n.nonce,e.now??new Date),returnPath:n.transaction.returnPath}}import{createHash as sy,randomBytes as oy}from"node:crypto";var q0=new Set(Gr),s0=7776000000,o0=31536000000,m0=86400000;function Ed(t){return typeof t==="string"?t:void 0}function x0(t){return sy("sha256").update(t).digest("hex")}function my(t){try{let e=JSON.parse(String(t));return Array.isArray(e)?e.filter((r)=>typeof r==="string"&&q0.has(r)):[]}catch{return[]}}function py(t){let e=String(t.scope_type);return e==="organization"?{type:e}:{type:e,id:String(t.scope_id)}}function VS(t){let e=Ed(t.disabled_at);return{id:String(t.id),organizationId:String(t.organization_id),actorId:String(t.actor_id),slug:String(t.slug),name:String(t.name),description:Ed(t.description),createdByActorId:Ed(t.created_by_actor_id),disabledAt:e,createdAt:String(t.created_at),updatedAt:String(t.updated_at),state:e?"disabled":"active"}}function KS(t,e){let r=Ed(t.revoked_at),d=String(t.expires_at);return{id:String(t.id),serviceAccountId:String(t.service_account_id),name:String(t.name),prefix:String(t.token_prefix),capabilities:my(t.capabilities),scope:py(t),expiresAt:d,lastUsedAt:Ed(t.last_used_at),lastNetworkHint:Ed(t.last_network_hint),revokedAt:r,rotatedFromTokenId:Ed(t.rotated_from_token_id),createdByActorId:Ed(t.created_by_actor_id),createdAt:String(t.created_at),updatedAt:String(t.updated_at),state:r?"revoked":d<=e?"expired":"active"}}function tX(t){let e={};try{e=JSON.parse(String(t.response_body))}catch{}return{id:String(t.id),tokenId:String(t.token_id),key:String(t.idempotency_key),requestHash:String(t.request_hash),operationId:Ed(t.operation_id),responseStatus:Number(t.response_status),responseBody:e,expiresAt:String(t.expires_at),createdAt:String(t.created_at)}}class oT{controlPlane;nowFn;idFn;constructor(t,e={}){this.controlPlane=t;this.nowFn=e.now??(()=>new Date),this.idFn=e.id??(()=>crypto.randomUUID())}now(){return this.nowFn().toISOString()}run(t,e){this.controlPlane.database.run(t,e)}createServiceAccount(t){if(!this.controlPlane.getOrganization(t.organizationId))throw Error("Service-account organization was not found");let e=t.slug.trim().toLowerCase();if(!/^[a-z0-9][a-z0-9-]{1,47}$/.test(e))throw Error("Service-account slug must be 2-48 lowercase letters, numbers or dashes");let r=t.name.trim().slice(0,100);if(!r)throw Error("Service-account name is required");let d=this.controlPlane.createActor({kind:"service_account",externalId:`service-account:${t.organizationId}:${e}`,displayName:r,metadata:{source:"api",serviceAccountSlug:e}}),E=this.idFn(),n=this.now();this.run(`INSERT INTO service_accounts (id, organization_id, actor_id, slug, name, description, created_by_actor_id, created_at, updated_at)
|
|
5530
5530
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,[E,t.organizationId,d.id,e,r,t.description?.trim().slice(0,500)||null,t.createdByActorId??null,n,n]);let c=this.controlPlane.createMembership({organizationId:t.organizationId,actorId:d.id,roleTemplate:t.roleTemplate,scope:t.scope,source:"manual",performedByActorId:t.createdByActorId}),_=t.scope??{type:"organization"};return this.controlPlane.appendEvent({organizationId:t.organizationId,actorId:t.createdByActorId,type:"api.service_account.created",payload:{serviceAccountId:E,roleTemplate:t.roleTemplate,scope:{type:_.type,id:_.id??null}}}),{serviceAccount:this.getServiceAccount(E),membership:c}}getServiceAccount(t){let e=this.controlPlane.database.query("SELECT * FROM service_accounts WHERE id = ?").get(t);return e?VS(e):void 0}getServiceAccountBySlug(t,e){let r=this.controlPlane.database.query("SELECT * FROM service_accounts WHERE organization_id = ? AND slug = ? COLLATE NOCASE").get(t,e.trim());return r?VS(r):void 0}listServiceAccounts(t,e={}){return this.controlPlane.database.query("SELECT * FROM service_accounts WHERE organization_id = ? ORDER BY name COLLATE NOCASE").all(t).map(VS).filter((r)=>e.includeDisabled||r.state==="active")}disableServiceAccount(t,e){let r=this.getServiceAccount(t);if(!r)throw Error("Service account was not found");let d=this.now();return this.controlPlane.transaction(()=>{this.run("UPDATE service_accounts SET disabled_at = ?, updated_at = ? WHERE id = ?",[d,d,t]),this.run("UPDATE api_tokens SET revoked_at = ?, updated_at = ? WHERE service_account_id = ? AND revoked_at IS NULL",[d,d,t]);let E=this.controlPlane.getMembershipForActor(r.organizationId,r.actorId);if(E?.status==="active")this.controlPlane.revokeMembership(E.id)}),this.controlPlane.appendEvent({organizationId:r.organizationId,actorId:e,type:"api.service_account.disabled",payload:{serviceAccountId:t}}),this.getServiceAccount(t)}createToken(t){let e=this.getServiceAccount(t.serviceAccountId);if(!e||e.state!=="active")throw Error("Service account is unavailable");let r=this.controlPlane.getMembershipForActor(e.organizationId,e.actorId);if(!r||r.status!=="active")throw Error("Service-account membership is unavailable");let d=[...new Set(t.capabilities)];if(d.length===0||d.some((N)=>!q0.has(N)))throw Error("API token requires valid explicit capabilities");let E=t.scope??r.scope,n=this.controlPlane.resolveAuthorizationTarget(e.organizationId,E);if(!n)throw Error("API token scope was not found in this organization");for(let N of d)if(!Ve({membership:r,grants:this.controlPlane.listGrants(r.id),capability:N,target:n}).allowed)throw Error(`Service-account membership does not grant ${N} at the token scope`);let c=t.expiresAt?new Date(t.expiresAt):new Date(this.nowFn().getTime()+s0);if(!Number.isFinite(c.getTime())||c.getTime()<=this.nowFn().getTime()+60000||c.getTime()>this.nowFn().getTime()+o0)throw Error("API token expiry must be between one minute and one year from now");let _=this.idFn(),T=oy(32).toString("base64url"),i=`tsc_v1.${_}.${T}`,h=`tsc_v1.${_.slice(0,8)}`,R=this.now();return this.run(`INSERT INTO api_tokens (id, service_account_id, name, token_hash, token_prefix, capabilities, scope_type, scope_id,
|
|
5531
5531
|
expires_at, rotated_from_token_id, created_by_actor_id, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,[_,e.id,t.name.trim().slice(0,100)||"API token",x0(i),h,JSON.stringify(d.sort()),E.type,E.type==="organization"?null:E.id??null,c.toISOString(),t.rotatedFromTokenId??null,t.createdByActorId??null,R,R]),this.controlPlane.appendEvent({organizationId:e.organizationId,actorId:t.createdByActorId,type:"api.token.created",payload:{serviceAccountId:e.id,tokenId:_,prefix:h,capabilities:d,scope:{type:E.type,id:E.id??null},expiresAt:c.toISOString(),rotatedFromTokenId:t.rotatedFromTokenId??null}}),{token:this.getToken(_),secret:i}}getToken(t){let e=this.controlPlane.database.query("SELECT * FROM api_tokens WHERE id = ?").get(t);return e?KS(e,this.now()):void 0}listTokens(t,e={}){return this.controlPlane.database.query("SELECT * FROM api_tokens WHERE service_account_id = ? ORDER BY created_at DESC").all(t).map((r)=>KS(r,this.now())).filter((r)=>e.includeInactive||r.state==="active")}verifyToken(t,e){let r=/^tsc_v1\.([^.]+)\.[A-Za-z0-9_-]{40,}$/.exec(t);if(!r)return;let d=this.controlPlane.database.query("SELECT * FROM api_tokens WHERE id = ? AND token_hash = ?").get(r[1],x0(t));if(!d)return;let E=KS(d,this.now()),n=this.getServiceAccount(E.serviceAccountId);if(!n||n.state!=="active"||E.state!=="active")return;let c=this.controlPlane.getActor(n.actorId),_=this.controlPlane.getMembershipForActor(n.organizationId,n.actorId);if(!c||c.disabledAt||!_||_.status!=="active")return;let T=this.now(),i=!E.lastUsedAt||this.nowFn().getTime()-new Date(E.lastUsedAt).getTime()>=3600000;if(this.run("UPDATE api_tokens SET last_used_at = ?, last_network_hint = ?, updated_at = ? WHERE id = ?",[T,e?.slice(0,128)??null,T,E.id]),i)this.controlPlane.appendEvent({organizationId:n.organizationId,actorId:c.id,type:"api.token.used",payload:{serviceAccountId:n.id,tokenId:E.id,prefix:E.prefix}});return{serviceAccount:n,token:this.getToken(E.id),actor:c,membership:_}}rotateToken(t,e){let r=this.getToken(t);if(!r||r.state!=="active")throw Error("Active API token was not found");let d=this.createToken({serviceAccountId:r.serviceAccountId,name:`${r.name} (rotated)`,capabilities:r.capabilities,scope:r.scope,expiresAt:r.expiresAt,createdByActorId:e,rotatedFromTokenId:r.id}),E=this.getServiceAccount(r.serviceAccountId);return this.controlPlane.appendEvent({organizationId:E?.organizationId,actorId:e,type:"api.token.rotated",payload:{serviceAccountId:r.serviceAccountId,previousTokenId:r.id,tokenId:d.token.id}}),d}revokeToken(t,e){let r=this.getToken(t);if(!r)throw Error("API token was not found");if(r.state==="active"){let d=this.now();this.run("UPDATE api_tokens SET revoked_at = ?, updated_at = ? WHERE id = ?",[d,d,t]);let E=this.getServiceAccount(r.serviceAccountId);this.controlPlane.appendEvent({organizationId:E?.organizationId,actorId:e,type:"api.token.revoked",payload:{serviceAccountId:r.serviceAccountId,tokenId:t}})}return this.getToken(t)}getIdempotency(t,e){let r=this.controlPlane.database.query("SELECT * FROM api_idempotency_records WHERE token_id = ? AND idempotency_key = ? AND expires_at > ?").get(t,e,this.now());return r?tX(r):void 0}saveIdempotency(t){if(!/^[A-Za-z0-9._:-]{8,128}$/.test(t.key))throw Error("Idempotency-Key must contain 8-128 safe characters");let e=this.getIdempotency(t.tokenId,t.key);if(e){if(e.requestHash!==t.requestHash)throw Error("Idempotency-Key was already used for a different request");return e}let r=this.idFn(),d=this.now(),E=new Date(this.nowFn().getTime()+m0).toISOString();return this.run(`INSERT INTO api_idempotency_records (id, token_id, idempotency_key, request_hash, operation_id, response_status, response_body, expires_at, created_at)
|
|
5532
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,[r,t.tokenId,t.key,t.requestHash,t.operationId??null,t.responseStatus,JSON.stringify(t.responseBody),E,d]),this.getIdempotency(t.tokenId,t.key)}purgeExpired(){let t=this.now(),e=this.controlPlane.database.run("DELETE FROM api_tokens WHERE (expires_at < ? OR revoked_at IS NOT NULL) AND created_at < ?",[t,new Date(this.nowFn().getTime()-2592000000).toISOString()]).changes,r=this.controlPlane.database.run("DELETE FROM api_idempotency_records WHERE expires_at < ?",[t]).changes;return{tokens:e,idempotency:r}}}Lt();class __{region;client;constructor(t="us-east-1",e=new dt){this.region=t;this.client=e}request(t,e){return this.client.request({service:"backup",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-amz-json-1.1","X-Amz-Target":`CryoControllerFrontendService.${t}`},body:JSON.stringify(e)})}startBackupJob(t){return this.request("StartBackupJob",t)}describeBackupJob(t){return this.request("DescribeBackupJob",{BackupJobId:t})}startRestoreJob(t){return this.request("StartRestoreJob",t)}describeRestoreJob(t){return this.request("DescribeRestoreJob",{RestoreJobId:t})}deleteRecoveryPoint(t,e){return this.request("DeleteRecoveryPoint",{BackupVaultName:t,RecoveryPointArn:e})}}Lt();class T_{client;region;constructor(t="us-east-1",e){this.region=t,this.client=new dt}async describeCacheClusters(t){let e={Action:"DescribeCacheClusters",Version:"2015-02-02",ShowCacheNodeInfo:"true"};if(t)e.CacheClusterId=t;let r=await this.client.request({service:"elasticache",region:this.region,method:"POST",path:"/",body:new URLSearchParams(e).toString()});return{CacheClusters:this.parseCacheClusters(r)}}async describeReplicationGroups(t){let e={Action:"DescribeReplicationGroups",Version:"2015-02-02"};if(t)e.ReplicationGroupId=t;let r=await this.client.request({service:"elasticache",region:this.region,method:"POST",path:"/",body:new URLSearchParams(e).toString()});return{ReplicationGroups:[]}}async createCacheCluster(t){let e={Action:"CreateCacheCluster",Version:"2015-02-02",CacheClusterId:t.cacheClusterId,Engine:t.engine,CacheNodeType:t.cacheNodeType};if(t.numCacheNodes)e.NumCacheNodes=t.numCacheNodes;if(t.engineVersion)e.EngineVersion=t.engineVersion;if(t.port)e.Port=t.port;if(t.securityGroupIds&&t.securityGroupIds.length>0)t.securityGroupIds.forEach((d,E)=>{e[`SecurityGroupIds.member.${E+1}`]=d});if(t.subnetGroupName)e.CacheSubnetGroupName=t.subnetGroupName;if(t.tags&&t.tags.length>0)t.tags.forEach((d,E)=>{e[`Tags.member.${E+1}.Key`]=d.Key,e[`Tags.member.${E+1}.Value`]=d.Value});let r=await this.client.request({service:"elasticache",region:this.region,method:"POST",path:"/",body:new URLSearchParams(e).toString()});return{CacheCluster:this.parseCacheCluster(r)}}async deleteCacheCluster(t,e){let r={Action:"DeleteCacheCluster",Version:"2015-02-02",CacheClusterId:t};if(e)r.FinalSnapshotIdentifier=e;await this.client.request({service:"elasticache",region:this.region,method:"POST",path:"/",body:new URLSearchParams(r).toString()})}async rebootCacheCluster(t,e){let r={Action:"RebootCacheCluster",Version:"2015-02-02",CacheClusterId:t};e.forEach((d,E)=>{r[`CacheNodeIdsToReboot.member.${E+1}`]=d}),await this.client.request({service:"elasticache",region:this.region,method:"POST",path:"/",body:new URLSearchParams(r).toString()})}async describeCacheEngineVersions(t){let e={Action:"DescribeCacheEngineVersions",Version:"2015-02-02"};if(t)e.Engine=t;let r=await this.client.request({service:"elasticache",region:this.region,method:"POST",path:"/",body:new URLSearchParams(e).toString()});return{CacheEngineVersions:[]}}async getCacheStatistics(t){let e=await this.describeCacheClusters(t);if(!e.CacheClusters||e.CacheClusters.length===0)throw Error(`Cache cluster ${t} not found`);return{cpuUtilization:0,evictions:0,hits:0,misses:0,connections:0}}parseCacheClusters(t){if(t.CacheClusterId)return[{CacheClusterId:t.CacheClusterId,CacheClusterStatus:t.CacheClusterStatus||"available",Engine:t.Engine||"redis",EngineVersion:t.EngineVersion||"7.0",CacheNodeType:t.CacheNodeType||"cache.t3.micro",NumCacheNodes:Number.parseInt(t.NumCacheNodes||"1"),CacheClusterCreateTime:t.CacheClusterCreateTime||new Date().toISOString()}];return[]}parseCacheCluster(t){return{CacheClusterId:t.CacheClusterId,CacheClusterStatus:t.CacheClusterStatus||"creating",Engine:t.Engine||"redis",EngineVersion:t.EngineVersion||"7.0",CacheNodeType:t.CacheNodeType||"cache.t3.micro",NumCacheNodes:Number.parseInt(t.NumCacheNodes||"1"),CacheClusterCreateTime:t.CacheClusterCreateTime||new Date().toISOString()}}}Pn();Lt();class aE{client;region;constructor(t="us-east-1",e){this.region=t,this.client=new dt}async createSecret(t){let e={Name:t.Name};if(t.Description)e.Description=t.Description;if(t.KmsKeyId)e.KmsKeyId=t.KmsKeyId;if(t.SecretBinary)e.SecretBinary=t.SecretBinary;if(t.SecretString)e.SecretString=t.SecretString;if(t.Tags&&t.Tags.length>0)e.Tags=t.Tags;if(t.AddReplicaRegions&&t.AddReplicaRegions.length>0)e.AddReplicaRegions=t.AddReplicaRegions;if(t.ForceOverwriteReplicaSecret!==void 0)e.ForceOverwriteReplicaSecret=t.ForceOverwriteReplicaSecret;e.ClientRequestToken=t.ClientRequestToken||crypto.randomUUID();let r=await this.client.request({service:"secretsmanager",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"secretsmanager.CreateSecret","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(e)});return{ARN:r.ARN,Name:r.Name,VersionId:r.VersionId,ReplicationStatus:r.ReplicationStatus}}async updateSecret(t){let e={SecretId:t.SecretId};if(t.Description)e.Description=t.Description;if(t.KmsKeyId)e.KmsKeyId=t.KmsKeyId;if(t.SecretBinary)e.SecretBinary=t.SecretBinary;if(t.SecretString)e.SecretString=t.SecretString;let r=await this.client.request({service:"secretsmanager",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"secretsmanager.UpdateSecret","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(e)});return{ARN:r.ARN,Name:r.Name,VersionId:r.VersionId}}async putSecretValue(t){let e={SecretId:t.SecretId};if(t.SecretBinary)e.SecretBinary=t.SecretBinary;if(t.SecretString)e.SecretString=t.SecretString;if(t.VersionStages&&t.VersionStages.length>0)e.VersionStages=t.VersionStages;if(t.ClientRequestToken)e.ClientRequestToken=t.ClientRequestToken;let r=await this.client.request({service:"secretsmanager",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"secretsmanager.PutSecretValue","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(e)});return{ARN:r.ARN,Name:r.Name,VersionId:r.VersionId,VersionStages:r.VersionStages}}async getSecretValue(t){let e={SecretId:t.SecretId};if(t.VersionId)e.VersionId=t.VersionId;if(t.VersionStage)e.VersionStage=t.VersionStage;let r=await this.client.request({service:"secretsmanager",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"secretsmanager.GetSecretValue","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(e)});return{ARN:r.ARN,Name:r.Name,VersionId:r.VersionId,SecretBinary:r.SecretBinary,SecretString:r.SecretString,VersionStages:r.VersionStages,CreatedDate:r.CreatedDate}}async describeSecret(t){let e={SecretId:t},r=await this.client.request({service:"secretsmanager",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"secretsmanager.DescribeSecret","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(e)});return this.parseSecret(r)}async listSecrets(t){let e={};if(t?.MaxResults)e.MaxResults=t.MaxResults;if(t?.NextToken)e.NextToken=t.NextToken;if(t?.Filters&&t.Filters.length>0)e.Filters=t.Filters;if(t?.SortOrder)e.SortOrder=t.SortOrder;let r=await this.client.request({service:"secretsmanager",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"secretsmanager.ListSecrets","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(e)});return{SecretList:r.SecretList?.map((d)=>this.parseSecret(d)),NextToken:r.NextToken}}async deleteSecret(t){let e={SecretId:t.SecretId};if(t.RecoveryWindowInDays!==void 0)e.RecoveryWindowInDays=t.RecoveryWindowInDays;if(t.ForceDeleteWithoutRecovery!==void 0)e.ForceDeleteWithoutRecovery=t.ForceDeleteWithoutRecovery;let r=await this.client.request({service:"secretsmanager",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"secretsmanager.DeleteSecret","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(e)});return{ARN:r.ARN,Name:r.Name,DeletionDate:r.DeletionDate}}async restoreSecret(t){let e={SecretId:t},r=await this.client.request({service:"secretsmanager",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"secretsmanager.RestoreSecret","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(e)});return{ARN:r.ARN,Name:r.Name}}async rotateSecret(t){let e={SecretId:t.SecretId};if(t.ClientRequestToken)e.ClientRequestToken=t.ClientRequestToken;if(t.RotationLambdaARN)e.RotationLambdaARN=t.RotationLambdaARN;if(t.RotationRules)e.RotationRules=t.RotationRules;if(t.RotateImmediately!==void 0)e.RotateImmediately=t.RotateImmediately;let r=await this.client.request({service:"secretsmanager",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"secretsmanager.RotateSecret","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(e)});return{ARN:r.ARN,Name:r.Name,VersionId:r.VersionId}}async cancelRotateSecret(t){let e={SecretId:t},r=await this.client.request({service:"secretsmanager",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"secretsmanager.CancelRotateSecret","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(e)});return{ARN:r.ARN,Name:r.Name}}async getResourcePolicy(t){let e={SecretId:t},r=await this.client.request({service:"secretsmanager",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"secretsmanager.GetResourcePolicy","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(e)});return{ARN:r.ARN,Name:r.Name,ResourcePolicy:r.ResourcePolicy}}async putResourcePolicy(t){let e={SecretId:t.SecretId,ResourcePolicy:t.ResourcePolicy};if(t.BlockPublicPolicy!==void 0)e.BlockPublicPolicy=t.BlockPublicPolicy;let r=await this.client.request({service:"secretsmanager",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"secretsmanager.PutResourcePolicy","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(e)});return{ARN:r.ARN,Name:r.Name}}async deleteResourcePolicy(t){let e={SecretId:t},r=await this.client.request({service:"secretsmanager",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"secretsmanager.DeleteResourcePolicy","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(e)});return{ARN:r.ARN,Name:r.Name}}async tagResource(t){let e={SecretId:t.SecretId,Tags:t.Tags};await this.client.request({service:"secretsmanager",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"secretsmanager.TagResource","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(e)})}async untagResource(t){let e={SecretId:t.SecretId,TagKeys:t.TagKeys};await this.client.request({service:"secretsmanager",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"secretsmanager.UntagResource","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(e)})}async setString(t,e,r){try{let d=await this.putSecretValue({SecretId:t,SecretString:e});return{ARN:d.ARN,VersionId:d.VersionId}}catch(d){if(d.code==="ResourceNotFoundException"){let E=await this.createSecret({Name:t,SecretString:e,Description:r?.description,KmsKeyId:r?.kmsKeyId,Tags:r?.tags});return{ARN:E.ARN,VersionId:E.VersionId}}throw d}}async setJson(t,e,r){return this.setString(t,JSON.stringify(e),r)}async getString(t){return(await this.getSecretValue({SecretId:t})).SecretString}async getJson(t){let e=await this.getString(t);if(e)return JSON.parse(e);return}async listAll(){let t=[],e;do{let r=await this.listSecrets({NextToken:e});if(r.SecretList)t.push(...r.SecretList);e=r.NextToken}while(e);return t}parseSecret(t){return{ARN:t.ARN,Name:t.Name,Description:t.Description,KmsKeyId:t.KmsKeyId,RotationEnabled:t.RotationEnabled,RotationLambdaARN:t.RotationLambdaARN,RotationRules:t.RotationRules,LastRotatedDate:t.LastRotatedDate,LastChangedDate:t.LastChangedDate,LastAccessedDate:t.LastAccessedDate,DeletedDate:t.DeletedDate,NextRotationDate:t.NextRotationDate,Tags:t.Tags,SecretVersionsToStages:t.SecretVersionsToStages,CreatedDate:t.CreatedDate,PrimaryRegion:t.PrimaryRegion}}}Lt();class jn{client;region;constructor(t="us-east-1",e){this.region=t,this.client=new dt}async putParameter(t){let e={Name:t.Name,Value:t.Value};if(t.Type)e.Type=t.Type;if(t.Description)e.Description=t.Description;if(t.KeyId)e.KeyId=t.KeyId;if(t.Overwrite!==void 0)e.Overwrite=t.Overwrite;if(t.AllowedPattern)e.AllowedPattern=t.AllowedPattern;if(t.Tags&&t.Tags.length>0)e.Tags=t.Tags;if(t.Tier)e.Tier=t.Tier;if(t.DataType)e.DataType=t.DataType;let r=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(e)});return{Version:r.Version,Tier:r.Tier}}async getParameter(t){let e={Name:t.Name};if(t.WithDecryption!==void 0)e.WithDecryption=t.WithDecryption;let r=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(e)});return{Parameter:r.Parameter?this.parseParameter(r.Parameter):void 0}}async getParameters(t){let e={Names:t.Names};if(t.WithDecryption!==void 0)e.WithDecryption=t.WithDecryption;let r=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(e)});return{Parameters:r.Parameters?.map((d)=>this.parseParameter(d)),InvalidParameters:r.InvalidParameters}}async getParametersByPath(t){let e={Path:t.Path};if(t.Recursive!==void 0)e.Recursive=t.Recursive;if(t.WithDecryption!==void 0)e.WithDecryption=t.WithDecryption;if(t.MaxResults)e.MaxResults=t.MaxResults;if(t.NextToken)e.NextToken=t.NextToken;if(t.ParameterFilters&&t.ParameterFilters.length>0)e.ParameterFilters=t.ParameterFilters;let r=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(e)});return{Parameters:r.Parameters?.map((d)=>this.parseParameter(d)),NextToken:r.NextToken}}async deleteParameter(t){let e={Name:t.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(e)})}async deleteParameters(t){let e={Names:t},r=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(e)});return{DeletedParameters:r.DeletedParameters,InvalidParameters:r.InvalidParameters}}async describeParameters(t){let e={};if(t?.Filters&&t.Filters.length>0)e.Filters=t.Filters;if(t?.ParameterFilters&&t.ParameterFilters.length>0)e.ParameterFilters=t.ParameterFilters;if(t?.MaxResults)e.MaxResults=t.MaxResults;if(t?.NextToken)e.NextToken=t.NextToken;let r=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(e)});return{Parameters:r.Parameters?.map((d)=>this.parseParameter(d)),NextToken:r.NextToken}}async getParameterHistory(t){let e={Name:t.Name};if(t.WithDecryption!==void 0)e.WithDecryption=t.WithDecryption;if(t.MaxResults)e.MaxResults=t.MaxResults;if(t.NextToken)e.NextToken=t.NextToken;let r=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(e)});return{Parameters:r.Parameters?.map((d)=>({Name:d.Name,Type:d.Type,KeyId:d.KeyId,LastModifiedDate:d.LastModifiedDate,LastModifiedUser:d.LastModifiedUser,Description:d.Description,Value:d.Value,Version:d.Version,Labels:d.Labels,Tier:d.Tier})),NextToken:r.NextToken}}async labelParameterVersion(t){let e={Name:t.Name,Labels:t.Labels};if(t.ParameterVersion!==void 0)e.ParameterVersion=t.ParameterVersion;let r=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(e)});return{InvalidLabels:r.InvalidLabels,ParameterVersion:r.ParameterVersion}}async addTagsToResource(t){let e={ResourceType:t.ResourceType,ResourceId:t.ResourceId,Tags:t.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(e)})}async removeTagsFromResource(t){let e={ResourceType:t.ResourceType,ResourceId:t.ResourceId,TagKeys:t.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(e)})}async listTagsForResource(t){let e={ResourceType:t.ResourceType,ResourceId:t.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(e)})).TagList}}async setString(t,e,r){return this.putParameter({Name:t,Value:e,Type:"String",Description:r?.description,Overwrite:r?.overwrite??!0,Tags:r?.tags})}async setSecureString(t,e,r){return this.putParameter({Name:t,Value:e,Type:"SecureString",Description:r?.description,Overwrite:r?.overwrite??!0,KeyId:r?.kmsKeyId,Tags:r?.tags})}async getValue(t){return(await this.getParameter({Name:t,WithDecryption:!0})).Parameter?.Value}async getAllByPath(t,e=!0){let r=[],d;do{let E=await this.getParametersByPath({Path:t,Recursive:e,WithDecryption:!0,NextToken:d});if(E.Parameters)r.push(...E.Parameters);d=E.NextToken}while(d);return r}parseParameter(t){return{Name:t.Name,Type:t.Type,Value:t.Value,Version:t.Version,LastModifiedDate:t.LastModifiedDate,ARN:t.ARN,DataType:t.DataType,Description:t.Description,AllowedPattern:t.AllowedPattern,KeyId:t.KeyId,Tier:t.Tier}}async sendCommand(t){if(!t.InstanceIds&&!t.Targets)throw Error("SendCommand requires either InstanceIds or Targets");let e={DocumentName:t.DocumentName};if(t.InstanceIds)e.InstanceIds=t.InstanceIds;if(t.Targets)e.Targets=t.Targets;if(t.Parameters)e.Parameters=t.Parameters;if(t.TimeoutSeconds)e.TimeoutSeconds=t.TimeoutSeconds;if(t.Comment)e.Comment=t.Comment;if(t.OutputS3BucketName)e.OutputS3BucketName=t.OutputS3BucketName;if(t.OutputS3KeyPrefix)e.OutputS3KeyPrefix=t.OutputS3KeyPrefix;let r=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(e)});return{CommandId:r.Command?.CommandId,Status:r.Command?.Status,StatusDetails:r.Command?.StatusDetails}}async getCommandInvocation(t){let e={CommandId:t.CommandId,InstanceId:t.InstanceId},r=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(e)});return{Status:r.Status,StatusDetails:r.StatusDetails,StandardOutputContent:r.StandardOutputContent,StandardErrorContent:r.StandardErrorContent,ResponseCode:r.ResponseCode}}async runShellCommand(t,e,r){let d=await this.sendCommand({InstanceIds:[t],DocumentName:"AWS-RunShellScript",Parameters:{commands:e},TimeoutSeconds:r?.timeoutSeconds||600});if(!d.CommandId)return{success:!1,error:"Failed to send command"};if(r?.waitForCompletion===!1)return{success:!0,status:"Pending"};let E=r?.pollIntervalMs||2000,n=r?.maxWaitMs||300000,c=Date.now();while(Date.now()-c<n){await new Promise((_)=>setTimeout(_,E));try{let _=await this.getCommandInvocation({CommandId:d.CommandId,InstanceId:t});if(_.Status==="Success")return{success:!0,output:_.StandardOutputContent,error:_.StandardErrorContent,status:_.Status};if(_.Status==="Failed"||_.Status==="Cancelled"||_.Status==="TimedOut")return{success:!1,output:_.StandardOutputContent,error:_.StandardErrorContent||_.StatusDetails,status:_.Status}}catch(_){if(!_.message?.includes("InvocationDoesNotExist"))return{success:!1,error:_.message}}}return{success:!1,error:"Command timed out waiting for completion"}}async listCommandInvocations(t){let e={CommandId:t.CommandId};if(t.Details)e.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(e)})).CommandInvocations||[]).map((E)=>({InstanceId:E.InstanceId,Status:E.Status,StatusDetails:E.StatusDetails,StandardOutputContent:E.CommandPlugins?.[0]?.Output,StandardErrorContent:E.CommandPlugins?.[0]?.StandardErrorUrl}))}async sendCommandByTags(t){let e=Object.entries(t.tags).map(([T,i])=>({Key:`tag:${T}`,Values:[i]})),r=await this.sendCommand({Targets:e,DocumentName:"AWS-RunShellScript",Parameters:{commands:t.commands},TimeoutSeconds:t.timeoutSeconds||600,Comment:t.comment});if(!r.CommandId)return{success:!1,instanceCount:0,perInstance:[],error:"Failed to send command"};let d=t.pollIntervalMs||3000,E=t.maxWaitMs||600000,n=Date.now(),c=new Set(["Success","Failed","Cancelled","TimedOut"]),_=[];while(Date.now()-n<E){await new Promise((T)=>setTimeout(T,d));try{if(_=await this.listCommandInvocations({CommandId:r.CommandId,Details:!0}),_.length===0)continue;if(_.every((i)=>c.has(i.Status||""))){let i=_.map((R)=>({instanceId:R.InstanceId,status:R.Status||"Unknown",output:R.StandardOutputContent,error:R.StandardErrorContent||R.StatusDetails})),h=_.every((R)=>R.Status==="Success");return{success:h,instanceCount:_.length,perInstance:i,error:h?void 0:"One or more instances reported a non-success status"}}}catch(T){if(!T.message?.includes("InvocationDoesNotExist"))return{success:!1,instanceCount:0,perInstance:[],error:T.message}}}return{success:!1,instanceCount:_.length,perInstance:_.map((T)=>({instanceId:T.InstanceId,status:T.Status||"Unknown"})),error:"Command timed out waiting for all instances to complete"}}}import{isIP as cl}from"node:net";var eX={every_minute:"* * * * *",every_five_minutes:"*/5 * * * *",hourly:"0 * * * *",daily:"0 0 * * *",weekly:"0 0 * * 0"},rX={JAN:1,FEB:2,MAR:3,APR:4,MAY:5,JUN:6,JUL:7,AUG:8,SEP:9,OCT:10,NOV:11,DEC:12},tl={SUN:0,MON:1,TUE:2,WED:3,THU:4,FRI:5,SAT:6};function el(t){try{return new Intl.DateTimeFormat("en",{timeZone:t}).format(new Date),t}catch{throw Error(`Unknown schedule timezone: ${t}`)}}function mT(t,e,r,d){let E=e[t.toUpperCase()]??Number(t);if(!Number.isInteger(E)||E<r||E>d)throw Error(`Schedule field value ${t} is outside ${r}-${d}.`);return E}function zn(t,e,r,d={},E){if(t==="*"||t==="?")return;let n=new Set;for(let c of t.split(",")){let[_,T]=c.split("/"),i=T?mT(T,{},1,r-e+1):1,h,R;if(_==="*")h=e,R=r;else if(_.includes("-")){let N=_.split("-");h=mT(N[0],d,e,r),R=mT(N[1],d,e,r)}else h=mT(_,d,e,r),R=h;if(R<h)throw Error("Schedule ranges must be ascending.");for(let N=h;N<=R;N+=i)n.add(E?E(N):N===7&&r===7?0:N)}return n}function dX(t,e){let r=Object.fromEntries(new Intl.DateTimeFormat("en-US",{timeZone:e,year:"numeric",month:"numeric",day:"numeric",weekday:"short",hour:"numeric",minute:"numeric",hourCycle:"h23"}).formatToParts(t).map((d)=>[d.type,d.value]));return{minute:Number(r.minute),hour:Number(r.hour),day:Number(r.day),month:Number(r.month),weekday:tl[r.weekday.toUpperCase()],year:Number(r.year),key:`${r.year}-${r.month}-${r.day} ${r.hour}:${r.minute}`}}function rl(t){let r=(t.startsWith("cron(")?t.slice(5,-1).trim():t.trim()).split(/\s+/);if(r.length!==5&&r.length!==6)throw Error("Cron schedules require five standard fields or six EventBridge fields.");let[d,E,n,c,_,T]=r,i=r.length===6;return{minute:zn(d,0,59),hour:zn(E,0,23),day:zn(n,1,31),month:zn(c,1,12,rX),weekday:zn(_,i?1:0,7,tl,i?(h)=>h===7?6:h-1:void 0),year:T?zn(T,1970,2199):void 0,dayWildcard:n==="*"||n==="?",weekdayWildcard:_==="*"||_==="?"}}function EX(t,e){if(!((!e.minute||e.minute.has(t.minute))&&(!e.hour||e.hour.has(t.hour))&&(!e.month||e.month.has(t.month))&&(!e.year||e.year.has(t.year))))return!1;let d=!e.day||e.day.has(t.day),E=!e.weekday||e.weekday.has(t.weekday);return e.dayWildcard?E:e.weekdayWildcard?d:d||E}function dl(t){let e=/^rate\(\s*(\d+)\s+(minute|minutes|hour|hours|day|days)\s*\)$/i.exec(t);if(!e)return;let r=Number(e[1]);if(r<1)throw Error("Rate amount must be positive.");return r*(e[2].toLowerCase().startsWith("minute")?60000:e[2].toLowerCase().startsWith("hour")?3600000:86400000)}function Fn(t){let e=t.trim(),r=eX[e.toLowerCase()]??e;if(!r)throw Error("Schedule expression is required.");let d=dl(r);if(d){let E=d/60000;return{original:e,normalized:`rate(${E} minutes)`,kind:"rate",description:E%1440===0?`Every ${E/1440} day(s)`:E%60===0?`Every ${E/60} hour(s)`:`Every ${E} minute(s)`}}return rl(r),{original:e,normalized:r.startsWith("cron(")?r:`cron(${r})`,kind:"cron",description:`Cron ${r.replace(/^cron\(|\)$/g,"")}`}}function PE(t,e,r=new Date,d=5){let E=Fn(t),n=el(e),c=Math.min(20,Math.max(1,d)),_=dl(E.normalized);if(_)return Array.from({length:c},(A,u)=>new Date(r.getTime()+_*(u+1)).toISOString());let T=rl(E.normalized),i=[],h=new Set,R=new Date(Math.floor(r.getTime()/60000)*60000+60000),N=0;while(i.length<c&&N<1100000){let A=dX(R,n);if(EX(A,T)&&!h.has(A.key))i.push(R.toISOString()),h.add(A.key);R=new Date(R.getTime()+60000),N++}if(i.length<c)throw Error("Schedule produced no runs within the bounded preview horizon.");return i}function jE(t,e="UTC",r=new Date,d=5){let E=Fn(t),n=PE(E.normalized,e,r,d),c=E.kind==="cron"?["Server cron and EventBridge use the same wall-clock preview; provider-specific extensions are retained only when supported."]:["Rate schedules use elapsed-time intervals and are not shifted by DST."];return{...E,timezone:el(e),nextRuns:n,capabilities:{server:E.kind==="cron",eventbridge:!0,notes:c}}}function ZS(t){let e=Fn(t.expression),r=e.normalized.slice(5,-1).trim().split(/\s+/),d=e.kind==="cron"&&r.length===5;if(t.provider==="server")return{provider:"server",supported:d,features:{timezone:!0,flexibleWindow:!1,catchUp:!1,replaceOverlap:!1},notes:[e.kind==="rate"?"Server cron requires a cron expression; use an equivalent cron schedule.":r.length!==5?"EventBridge six-field cron extensions cannot be installed as server cron.":"Cron is reconciled through a root-owned ts-cloud entry.",t.missedRunPolicy==="catch_up"?"Catch-up is handled by the control plane, not cron.":"Missed runs are skipped by cron."]};if(t.provider==="eventbridge")return{provider:"eventbridge",supported:!0,features:{timezone:!0,flexibleWindow:!0,catchUp:!1,replaceOverlap:!1},notes:["Five-field cron is translated explicitly to EventBridge six-field syntax. Flexible windows are provider-native; overlap and catch-up remain control-plane policies."]};if(t.provider==="lambda")return{provider:"lambda",supported:!0,features:{timezone:!0,flexibleWindow:!0,catchUp:!1,replaceOverlap:!1},notes:["The schedule invokes one immutable Lambda target."]};return{provider:"platform",supported:!0,features:{timezone:!0,flexibleWindow:!0,catchUp:!0,replaceOverlap:!0},notes:["The durable control-plane worker enforces all configured policies."]}}function nX(t){if(t.queues===!0)return[{queue:"default",processes:t.queueConcurrency??1}];if(!Array.isArray(t.queues))return[];return t.queues.map((e)=>{if(typeof e==="string")return{queue:e,processes:t.queueConcurrency??1};let[r,d]=Object.entries(e)[0]??["default",t.queueConcurrency??1];return{queue:r,processes:d}})}function kS(t,e,r){let d=new Set,E=new Set,n=new Map(r.resources.map((R)=>[R.slug,R])),c=0,_=0;for(let[R,N]of Object.entries(e.sites??{})){let A=n.get(R);if(N.scheduler){let w=`config:site:${R}:scheduler`;d.add(w),t.upsertConfigJob({organizationId:r.organization.id,projectId:r.project.id,environmentId:r.environment.id,resourceId:A?.id,name:`${R} scheduler`,provider:"server",expression:"* * * * *",timezone:"UTC",flexibleMinutes:0,target:{kind:"dashboard_operation",operationId:`scheduler:run:${R}`},payloadRefs:{},missedRunPolicy:"skip",overlapPolicy:"forbid",retryPolicy:{maxAttempts:3,backoffSeconds:30},timeoutSeconds:300,enabled:!0,origin:"config",sourceKey:w,observedState:{source:"cloud.config.ts"},reconciliationStatus:"pending"}),c++}let u=N,f=Array.isArray(u.queues??u.workers)?u.queues??u.workers:[];for(let[w,I]of f.entries()){let a=typeof I==="string"?{queue:I}:I,P=String(a.queue??a.name??"default"),j=`config:site:${R}:worker:${w}:${P}`;E.add(j),t.upsertWorker({organizationId:r.organization.id,projectId:r.project.id,environmentId:r.environment.id,resourceId:A?.id,name:`${R}:${P}`,provider:"systemd",queue:P,processes:Number(a.processes)||1,timeoutSeconds:Number(a.timeout)||60,restartPolicy:"always",target:{operationId:`worker:restart:${R}`,site:R},enabled:!0,origin:"config",sourceKey:j,observedState:{source:"cloud.config.ts",currentJob:null,failures:0},reconciliationStatus:"pending"}),_++}}let T=e.infrastructure?.compute?.backups;if(T?.enabled)d.add("config:platform:backup"),t.upsertConfigJob({organizationId:r.organization.id,projectId:r.project.id,environmentId:r.environment.id,name:"Scheduled backup",provider:"server",expression:String(T.schedule??"0 2 * * *"),timezone:String(T.timezone??"UTC"),flexibleMinutes:0,target:{kind:"dashboard_operation",operationId:"backup:run"},payloadRefs:{},missedRunPolicy:"skip",overlapPolicy:"forbid",retryPolicy:{maxAttempts:3,backoffSeconds:60},timeoutSeconds:3600,enabled:!0,origin:"config",sourceKey:"config:platform:backup",observedState:{source:"cloud.config.ts"},reconciliationStatus:"pending"}),c++;let i=e.environments?.[r.environment.slug]?.app;if(i){if(i.scheduler!=="off"){let R=`config:serverless:${r.environment.slug}:scheduler`;d.add(R),t.upsertConfigJob({organizationId:r.organization.id,projectId:r.project.id,environmentId:r.environment.id,name:`${r.environment.name} serverless scheduler`,provider:"eventbridge",expression:"rate(1 minute)",timezone:"UTC",flexibleMinutes:0,target:{kind:"serverless_scheduler",action:"schedule:run"},payloadRefs:{},missedRunPolicy:i.scheduler==="sub-minute"?"catch_up":"skip",overlapPolicy:"forbid",retryPolicy:{maxAttempts:3,backoffSeconds:30},timeoutSeconds:i.cliTimeout??900,enabled:!0,origin:"config",sourceKey:R,observedState:{source:"cloud.config.ts",mode:i.scheduler??"on"},reconciliationStatus:"pending"}),c++}for(let{queue:R,processes:N}of nX(i)){let A=`config:serverless:${r.environment.slug}:worker:${R}`;E.add(A),t.upsertWorker({organizationId:r.organization.id,projectId:r.project.id,environmentId:r.environment.id,name:`${r.environment.name}:${R}`,provider:"lambda",queue:R,processes:N,timeoutSeconds:i.queueTimeout??120,restartPolicy:"on_failure",target:{function:"queue",queue:R},enabled:!0,origin:"config",sourceKey:A,observedState:{source:"cloud.config.ts",currentJob:null,failures:0},reconciliationStatus:"pending"}),_++}}let h=0;for(let R of t.list(r.project.id,{environmentId:r.environment.id}).filter((N)=>N.origin==="config"&&N.sourceKey&&!d.has(N.sourceKey)))t.reconcile(R.id,"drifted",{...R.observedState,reason:"Definition is no longer present in configuration; retained for non-destructive review."}),h++;for(let R of t.listWorkers(r.project.id,r.environment.id).filter((N)=>N.origin==="config"&&N.sourceKey&&!E.has(N.sourceKey)))t.reconcileWorker(R.id,"drifted",{...R.observedState,reason:"Definition is no longer present in configuration; retained for non-destructive review."}),h++;return{jobs:c,workers:_,drifted:h}}class bS{store;queue;constructor(t,e={}){this.store=t;this.queue=e.queue??new gt(t.controlPlane)}enqueue(t,e){let r=new Date(e.scheduledFor??this.store.now()).toISOString(),d=`${t.id}:${e.trigger==="manual"?crypto.randomUUID():r}`,E=this.store.activeExecution(t.id);if(E&&t.overlapPolicy==="forbid")return this.store.createExecution({jobId:t.id,trigger:e.trigger,scheduledFor:r,idempotencyKey:d,status:"skipped",output:{reason:"overlap_forbidden",activeExecutionId:E.id}});if(E&&t.overlapPolicy==="replace"&&E.operationId)try{this.queue.requestCancellation(E.operationId,e.actorId)}catch{}let n=this.store.createExecution({jobId:t.id,trigger:e.trigger,scheduledFor:r,idempotencyKey:d,status:"queued",output:{semantics:"at_least_once"}});if(n.operationId)return n;let c=this.queue.enqueue({projectId:t.projectId,environmentId:t.environmentId,resourceId:t.resourceId,actorId:e.actorId,kind:"job.execute",input:{jobId:t.id,executionId:n.id},idempotencyKey:`job-execution:${n.id}`,lockKey:t.overlapPolicy==="allow"?`job-execution:${n.id}`:`job:${t.id}`,maxAttempts:t.retryPolicy.maxAttempts,timeoutSeconds:t.timeoutSeconds,retryClasses:["job_transient"],resumePolicy:"requeue"}).operation;return this.store.attachOperation(n.id,c.id)}tick(t=this.store.now()){let e=[];for(let r of this.store.due(t.toISOString())){let d=r.nextRunAt,E=PE(r.normalizedExpression,r.timezone,t,1)[0];if(r.missedRunPolicy==="catch_up"){let n=d,c=0;while(n<=t.toISOString()&&c<10)e.push(this.enqueue(r,{trigger:n===d?"scheduled":"catch_up",scheduledFor:n})),n=PE(r.normalizedExpression,r.timezone,new Date(n),1)[0],c++}else e.push(this.enqueue(r,{trigger:"scheduled",scheduledFor:d}));this.store.markScheduled(r.id,d,E)}return e}}function El(t){return{"job.execute":async(r)=>{let d=r.operation.input&&typeof r.operation.input==="object"&&!Array.isArray(r.operation.input)?r.operation.input:{},E=t.store.get(String(d.jobId??"")),n=t.store.getExecution(String(d.executionId??""));if(!E||!n)throw Error("Scheduled job execution is no longer available.");t.store.transitionExecution(n.id,"running",{attempt:r.operation.attempt}),r.checkpoint("execute",`Running ${E.name} on ${E.provider}.`),r.log(`Trigger ${n.trigger}; scheduled for ${n.scheduledFor}; semantics at-least-once.`,{stream:"system"});let c=await t.executor(E,E.target,r);if(c.stdout)r.log(c.stdout,{stream:"stdout"});if(c.stderr)r.log(c.stderr,{stream:"stderr"});if(!c.ok){if(t.store.transitionExecution(n.id,r.operation.attempt>=E.retryPolicy.maxAttempts?"dead":"failed",{attempt:r.operation.attempt,error:c.stderr??"Job execution failed."}),c.retryable)throw new gr(c.stderr??"Scheduled job failed transiently.","job_transient");throw Error(c.stderr??"Scheduled job failed.")}return t.store.transitionExecution(n.id,"succeeded",{attempt:r.operation.attempt,output:c.output??{}}),{jobId:E.id,executionId:n.id,provider:E.provider}}}}var ae=(t)=>typeof t==="string"&&t?t:void 0,nl=(t)=>Number(t)===1,zE=(t)=>{try{return JSON.parse(String(t))}catch{return{}}},Vd=(t,e,r,d)=>{let E=Number(t);return Number.isFinite(E)?Math.min(d,Math.max(r,Math.floor(E))):e};function pT(t){return{id:String(t.id),organizationId:String(t.organization_id),projectId:String(t.project_id),environmentId:ae(t.environment_id),resourceId:ae(t.resource_id),name:String(t.name),provider:String(t.provider),expression:String(t.expression),normalizedExpression:String(t.normalized_expression),timezone:String(t.timezone),startsAt:ae(t.starts_at),endsAt:ae(t.ends_at),flexibleMinutes:Number(t.flexible_minutes),target:zE(t.target),payloadRefs:zE(t.payload_refs),missedRunPolicy:String(t.missed_run_policy),overlapPolicy:String(t.overlap_policy),retryPolicy:zE(t.retry_policy),timeoutSeconds:Number(t.timeout_seconds),enabled:nl(t.enabled),origin:String(t.origin),sourceKey:ae(t.source_key),ownerActorId:ae(t.owner_actor_id),observedState:zE(t.observed_state),reconciliationStatus:String(t.reconciliation_status),nextRunAt:ae(t.next_run_at),lastScheduledFor:ae(t.last_scheduled_for),version:Number(t.version),createdAt:String(t.created_at),updatedAt:String(t.updated_at)}}function ti(t){return{id:String(t.id),jobId:String(t.job_id),operationId:ae(t.operation_id),trigger:String(t.trigger),scheduledFor:String(t.scheduled_for),idempotencyKey:String(t.idempotency_key),status:String(t.status),attempt:Number(t.attempt),startedAt:ae(t.started_at),finishedAt:ae(t.finished_at),output:zE(t.output),error:ae(t.error),createdAt:String(t.created_at),updatedAt:String(t.updated_at)}}function xS(t){return{id:String(t.id),organizationId:String(t.organization_id),projectId:String(t.project_id),environmentId:ae(t.environment_id),resourceId:ae(t.resource_id),name:String(t.name),provider:String(t.provider),queue:String(t.queue),processes:Number(t.processes),timeoutSeconds:Number(t.timeout_seconds),restartPolicy:String(t.restart_policy),target:zE(t.target),enabled:nl(t.enabled),origin:String(t.origin),sourceKey:ae(t.source_key),ownerActorId:ae(t.owner_actor_id),observedState:zE(t.observed_state),reconciliationStatus:String(t.reconciliation_status),version:Number(t.version),createdAt:String(t.created_at),updatedAt:String(t.updated_at)}}class qS{controlPlane;options;constructor(t,e={}){this.controlPlane=t;this.options=e}now(){return this.options.now?.()??new Date}create(t){if(!t.name.trim())throw Error("Scheduled jobs require a name.");let e=jE(t.expression,t.timezone,this.now(),1),r=crypto.randomUUID(),d=this.now().toISOString(),E=t.startsAt?new Date(t.startsAt).toISOString():void 0,n=t.endsAt?new Date(t.endsAt).toISOString():void 0;if(E&&n&&E>=n)throw Error("Schedule start must be before end.");let c=e.nextRuns.find((_)=>(!E||_>=E)&&(!n||_<=n));return this.controlPlane.database.run("INSERT INTO scheduled_jobs (id,organization_id,project_id,environment_id,resource_id,name,provider,expression,normalized_expression,timezone,starts_at,ends_at,flexible_minutes,target,payload_refs,missed_run_policy,overlap_policy,retry_policy,timeout_seconds,enabled,origin,source_key,owner_actor_id,observed_state,reconciliation_status,next_run_at,version,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",[r,t.organizationId,t.projectId,t.environmentId??null,t.resourceId??null,t.name.trim().slice(0,120),t.provider,t.expression,e.normalized,t.timezone,E??null,n??null,Vd(t.flexibleMinutes,0,0,1440),JSON.stringify(t.target),JSON.stringify(t.payloadRefs),t.missedRunPolicy,t.overlapPolicy,JSON.stringify({maxAttempts:Vd(t.retryPolicy.maxAttempts,3,1,20),backoffSeconds:Vd(t.retryPolicy.backoffSeconds,30,0,86400),deadLetterRef:t.retryPolicy.deadLetterRef}),Vd(t.timeoutSeconds,900,1,86400),t.enabled?1:0,t.origin,t.sourceKey??null,t.ownerActorId??null,JSON.stringify(t.observedState),t.reconciliationStatus,c??null,1,d,d]),this.get(r)}get(t){let e=this.controlPlane.database.query("SELECT * FROM scheduled_jobs WHERE id=?").get(t);return e?pT(e):void 0}getBySource(t,e,r){let d=this.controlPlane.database.query("SELECT * FROM scheduled_jobs WHERE project_id=? AND environment_id IS ? AND source_key=?").get(t,e??null,r);return d?pT(d):void 0}list(t,e={}){let r=["project_id=?"],d=[t];if(e.environmentId)r.push("environment_id=?"),d.push(e.environmentId);if(e.resourceIds?.length)r.push(`resource_id IN (${e.resourceIds.map(()=>"?").join(",")})`),d.push(...e.resourceIds);if(e.enabled!=null)r.push("enabled=?"),d.push(e.enabled?1:0);return this.controlPlane.database.query(`SELECT * FROM scheduled_jobs WHERE ${r.join(" AND ")} ORDER BY next_run_at IS NULL,next_run_at,name`).all(...d).map(pT)}setEnabled(t,e){this.controlPlane.database.run("UPDATE scheduled_jobs SET enabled=?,version=version+1,updated_at=? WHERE id=?",[e?1:0,this.now().toISOString(),t]);let r=this.get(t);if(!r)throw Error("Scheduled job was not found.");return r}updateSchedule(t,e){let r=this.get(t);if(!r)throw Error("Scheduled job was not found.");let d=e.expression??r.expression,E=e.timezone??r.timezone,n=jE(d,E,this.now(),1),c=this.now().toISOString();return this.controlPlane.database.run("UPDATE scheduled_jobs SET expression=?,normalized_expression=?,timezone=?,missed_run_policy=?,overlap_policy=?,timeout_seconds=?,next_run_at=?,reconciliation_status=?,version=version+1,updated_at=? WHERE id=?",[d,n.normalized,E,e.missedRunPolicy??r.missedRunPolicy,e.overlapPolicy??r.overlapPolicy,Vd(e.timeoutSeconds,r.timeoutSeconds,1,86400),n.nextRuns[0],"pending",c,t]),this.get(t)}remove(t){let e=this.get(t);if(!e)throw Error("Scheduled job was not found.");if(e.origin==="config")throw Error("Config-defined jobs must be removed from configuration, not destructively deleted.");this.controlPlane.database.run("DELETE FROM scheduled_jobs WHERE id=?",[t])}markScheduled(t,e,r){this.controlPlane.database.run("UPDATE scheduled_jobs SET last_scheduled_for=?,next_run_at=?,updated_at=? WHERE id=?",[e,r??null,this.now().toISOString(),t])}reconcile(t,e,r){return this.controlPlane.database.run("UPDATE scheduled_jobs SET reconciliation_status=?,observed_state=?,updated_at=? WHERE id=?",[e,JSON.stringify(r),this.now().toISOString(),t]),this.get(t)}upsertConfigJob(t){let e=this.getBySource(t.projectId,t.environmentId,t.sourceKey);if(!e)return this.create(t);let r=jE(t.expression,t.timezone,this.now(),1),d=this.now().toISOString();if(e.resourceId===t.resourceId&&e.name===t.name&&e.provider===t.provider&&e.expression===t.expression&&e.normalizedExpression===r.normalized&&e.timezone===t.timezone&&JSON.stringify(e.target)===JSON.stringify(t.target)&&JSON.stringify(e.payloadRefs)===JSON.stringify(t.payloadRefs)&&e.missedRunPolicy===t.missedRunPolicy&&e.overlapPolicy===t.overlapPolicy&&JSON.stringify(e.retryPolicy)===JSON.stringify(t.retryPolicy)&&e.timeoutSeconds===t.timeoutSeconds&&e.enabled===t.enabled)return e;return this.controlPlane.database.run("UPDATE scheduled_jobs SET resource_id=?,name=?,provider=?,expression=?,normalized_expression=?,timezone=?,target=?,payload_refs=?,missed_run_policy=?,overlap_policy=?,retry_policy=?,timeout_seconds=?,enabled=?,observed_state=?,reconciliation_status=?,next_run_at=COALESCE(next_run_at,?),version=version+1,updated_at=? WHERE id=?",[t.resourceId??null,t.name,t.provider,t.expression,r.normalized,t.timezone,JSON.stringify(t.target),JSON.stringify(t.payloadRefs),t.missedRunPolicy,t.overlapPolicy,JSON.stringify(t.retryPolicy),t.timeoutSeconds,t.enabled?1:0,JSON.stringify(t.observedState),t.reconciliationStatus,r.nextRuns[0],d,e.id]),this.get(e.id)}due(t=this.now().toISOString()){return this.controlPlane.database.query("SELECT * FROM scheduled_jobs WHERE enabled=1 AND next_run_at IS NOT NULL AND next_run_at<=? AND (starts_at IS NULL OR starts_at<=?) AND (ends_at IS NULL OR ends_at>=?) ORDER BY next_run_at LIMIT 200").all(t,t,t).map(pT)}createExecution(t){let e=this.controlPlane.database.query("SELECT * FROM job_executions WHERE idempotency_key=?").get(t.idempotencyKey);if(e)return ti(e);let r=crypto.randomUUID(),d=this.now().toISOString();return this.controlPlane.database.run("INSERT INTO job_executions (id,job_id,operation_id,trigger,scheduled_for,idempotency_key,status,attempt,output,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?)",[r,t.jobId,t.operationId??null,t.trigger,t.scheduledFor,t.idempotencyKey,t.status,0,JSON.stringify(t.output),d,d]),this.getExecution(r)}getExecution(t){let e=this.controlPlane.database.query("SELECT * FROM job_executions WHERE id=?").get(t);return e?ti(e):void 0}listExecutions(t,e=100){return this.controlPlane.database.query("SELECT * FROM job_executions WHERE job_id=? ORDER BY scheduled_for DESC,created_at DESC LIMIT ?").all(t,Math.min(1000,Math.max(1,e))).map(ti)}activeExecution(t){let e=this.controlPlane.database.query("SELECT * FROM job_executions WHERE job_id=? AND status IN ('queued','running') ORDER BY created_at DESC LIMIT 1").get(t);return e?ti(e):void 0}attachOperation(t,e){return this.controlPlane.database.run("UPDATE job_executions SET operation_id=?,updated_at=? WHERE id=?",[e,this.now().toISOString(),t]),this.getExecution(t)}transitionExecution(t,e,r={}){let d=this.now().toISOString(),E=e==="running"?d:null,n=["succeeded","failed","skipped","dead"].includes(e)?d:null;return this.controlPlane.database.run("UPDATE job_executions SET status=?,attempt=COALESCE(?,attempt),started_at=COALESCE(started_at,?),finished_at=?,output=COALESCE(?,output),error=?,updated_at=? WHERE id=?",[e,r.attempt??null,E,n,r.output?JSON.stringify(r.output):null,r.error?.slice(0,2000)??null,d,t]),this.getExecution(t)}upsertWorker(t){let e=t.sourceKey?this.controlPlane.database.query("SELECT * FROM worker_definitions WHERE project_id=? AND source_key=? AND environment_id IS ?").get(t.projectId,t.sourceKey,t.environmentId??null):void 0,r=e?xS(e):void 0,d=r?.id??crypto.randomUUID(),E=this.now().toISOString(),n=Vd(t.processes,1,0,1000),c=Vd(t.timeoutSeconds,60,1,86400);if(r&&r.resourceId===t.resourceId&&r.name===t.name.slice(0,120)&&r.provider===t.provider&&r.queue===t.queue.slice(0,200)&&r.processes===n&&r.timeoutSeconds===c&&r.restartPolicy===t.restartPolicy&&JSON.stringify(r.target)===JSON.stringify(t.target)&&r.enabled===t.enabled)return r;return this.controlPlane.database.run("INSERT INTO worker_definitions (id,organization_id,project_id,environment_id,resource_id,name,provider,queue,processes,timeout_seconds,restart_policy,target,enabled,origin,source_key,owner_actor_id,observed_state,reconciliation_status,version,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) ON CONFLICT(id) DO UPDATE SET name=excluded.name,resource_id=excluded.resource_id,provider=excluded.provider,queue=excluded.queue,processes=excluded.processes,timeout_seconds=excluded.timeout_seconds,restart_policy=excluded.restart_policy,target=excluded.target,enabled=excluded.enabled,observed_state=excluded.observed_state,reconciliation_status=excluded.reconciliation_status,version=worker_definitions.version+1,updated_at=excluded.updated_at",[d,t.organizationId,t.projectId,t.environmentId??null,t.resourceId??null,t.name.slice(0,120),t.provider,t.queue.slice(0,200),n,c,t.restartPolicy,JSON.stringify(t.target),t.enabled?1:0,t.origin,t.sourceKey??null,t.ownerActorId??null,JSON.stringify(t.observedState),t.reconciliationStatus,1,r?.createdAt??E,E]),this.getWorker(d)}getWorker(t){let e=this.controlPlane.database.query("SELECT * FROM worker_definitions WHERE id=?").get(t);return e?xS(e):void 0}listWorkers(t,e){return this.controlPlane.database.query(`SELECT * FROM worker_definitions WHERE project_id=?${e?" AND environment_id=?":""} ORDER BY name`).all(t,...e?[e]:[]).map(xS)}setWorkerProcesses(t,e){this.controlPlane.database.run("UPDATE worker_definitions SET processes=?,reconciliation_status='pending',version=version+1,updated_at=? WHERE id=?",[Vd(e,1,0,1000),this.now().toISOString(),t]);let r=this.getWorker(t);if(!r)throw Error("Worker was not found.");return r}reconcileWorker(t,e,r){this.controlPlane.database.run("UPDATE worker_definitions SET reconciliation_status=?,observed_state=?,updated_at=? WHERE id=?",[e,JSON.stringify(r),this.now().toISOString(),t]);let d=this.getWorker(t);if(!d)throw Error("Worker was not found.");return d}}var yt=(t)=>t==null?void 0:String(t),ei=(t)=>Number(t)===1,Kd=(t,e)=>{try{return JSON.parse(String(t))}catch{return e}};function _l(t){return{id:String(t.id),organizationId:String(t.organization_id),projectId:String(t.project_id),name:String(t.name),provider:String(t.provider),endpoint:yt(t.endpoint),endpointPolicy:String(t.endpoint_policy),bucket:yt(t.bucket),prefix:String(t.prefix),region:yt(t.region),forcePathStyle:ei(t.force_path_style),credentialRef:yt(t.credential_ref),encryption:String(t.encryption),encryptionKeyRef:yt(t.encryption_key_ref),immutability:Kd(t.immutability,{}),status:String(t.status),lastTestedAt:yt(t.last_tested_at),lastSuccessAt:yt(t.last_success_at),lastFailureAt:yt(t.last_failure_at),lastError:yt(t.last_error),version:Number(t.version),createdAt:String(t.created_at),updatedAt:String(t.updated_at)}}function sS(t){return{id:String(t.id),organizationId:String(t.organization_id),projectId:String(t.project_id),environmentId:yt(t.environment_id),resourceId:yt(t.resource_id),dataServiceId:yt(t.data_service_id),destinationId:String(t.destination_id),name:String(t.name),resourceKind:String(t.resource_kind),schedule:String(t.schedule),timezone:String(t.timezone),retention:Kd(t.retention,{}),compression:String(t.compression),encryption:String(t.encryption),includePatterns:Kd(t.include_patterns,[]),excludePatterns:Kd(t.exclude_patterns,[]),expectedRpoMinutes:Number(t.expected_rpo_minutes),expectedRtoMinutes:Number(t.expected_rto_minutes),healthCheckId:yt(t.health_check_id),enabled:ei(t.enabled),nextRunAt:yt(t.next_run_at),lastRunAt:yt(t.last_run_at),version:Number(t.version),createdAt:String(t.created_at),updatedAt:String(t.updated_at)}}function oS(t){return{id:String(t.id),projectId:String(t.project_id),policyId:yt(t.policy_id),destinationId:String(t.destination_id),resourceId:yt(t.resource_id),dataServiceId:yt(t.data_service_id),backupJobId:yt(t.backup_job_id),kind:String(t.kind),pointInTime:String(t.point_in_time),uri:String(t.uri),sizeBytes:Number(t.size_bytes),checksum:String(t.checksum),manifest:Kd(t.manifest,{}),toolVersion:yt(t.tool_version),engineVersion:yt(t.engine_version),expiresAt:yt(t.expires_at),lockedUntil:yt(t.locked_until),held:ei(t.held),pinned:ei(t.pinned),status:String(t.status),verificationState:String(t.verification_state),verifiedAt:yt(t.verified_at),durationMs:t.duration_ms==null?void 0:Number(t.duration_ms),createdAt:String(t.created_at),updatedAt:String(t.updated_at)}}function mS(t){return{id:String(t.id),projectId:String(t.project_id),policyId:yt(t.policy_id),recoveryPointId:yt(t.recovery_point_id),operationId:yt(t.operation_id),kind:String(t.kind),status:String(t.status),idempotencyKey:String(t.idempotency_key),target:Kd(t.target,{}),restoreMode:yt(t.restore_mode),cancellability:String(t.cancellability),safetyBackupId:yt(t.safety_backup_id),healthResult:t.health_result?Kd(t.health_result,{}):void 0,progress:Kd(t.progress,{}),error:yt(t.error),startedAt:yt(t.started_at),finishedAt:yt(t.finished_at),createdAt:String(t.created_at),updatedAt:String(t.updated_at)}}function cX(t){let e=t.toLowerCase();if(e==="localhost"||e.endsWith(".localhost")||e.endsWith(".local")||e.endsWith(".internal"))return!0;if(cl(e)===6)return e==="::1"||e.startsWith("fe80:");if(cl(e)!==4)return!1;let[r,d]=e.split(".").map(Number);return r===10||r===127||r===0||r===169&&d===254||r===172&&d>=16&&d<=31||r===192&&d===168}function _X(t){if(!/^[a-z0-9][a-z0-9-]{1,62}$/.test(t.name))throw Error("Backup destination names must be 2-63 lowercase letters, numbers, or dashes.");if(t.provider!=="aws_backup"&&!t.bucket)throw Error("S3 backup destinations require a bucket.");if(t.provider==="s3_compatible"&&!t.endpoint)throw Error("S3-compatible destinations require an explicit endpoint.");if(t.provider==="s3_compatible"&&!t.credentialRef)throw Error("S3-compatible destinations require a credential reference.");if(t.encryption!=="provider"&&!t.encryptionKeyRef)throw Error("Client-side encryption requires an encryption key reference.");if(t.endpoint){let e=new URL(t.endpoint);if(e.protocol!=="https:"||e.username||e.password||e.search||e.hash||e.pathname!=="/")throw Error("Backup endpoints must be origin-only HTTPS URLs without credentials, paths, queries, or fragments.");if(cX(e.hostname)&&t.endpointPolicy!=="allow_private")throw Error("Private backup endpoints require endpointPolicy allow_private.")}}class pS{controlPlane;now;constructor(t,e=()=>new Date){this.controlPlane=t;this.now=e}createDestination(t){_X(t);let e=crypto.randomUUID(),r=this.now().toISOString();return this.controlPlane.database.run("INSERT INTO backup_destinations (id,organization_id,project_id,name,provider,endpoint,endpoint_policy,bucket,prefix,region,force_path_style,credential_ref,encryption,encryption_key_ref,immutability,status,last_tested_at,last_success_at,last_failure_at,last_error,version,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",[e,t.organizationId,t.projectId,t.name,t.provider,t.endpoint??null,t.endpointPolicy,t.bucket??null,t.prefix,t.region??null,t.forcePathStyle?1:0,t.credentialRef??null,t.encryption,t.encryptionKeyRef??null,JSON.stringify(t.immutability),t.status,t.lastTestedAt??null,t.lastSuccessAt??null,t.lastFailureAt??null,t.lastError??null,1,r,r]),this.getDestination(e)}getDestination(t){let e=this.controlPlane.database.query("SELECT * FROM backup_destinations WHERE id=?").get(t);return e?_l(e):void 0}listDestinations(t){return this.controlPlane.database.query("SELECT * FROM backup_destinations WHERE project_id=? ORDER BY name").all(t).map(_l)}recordDestinationTest(t,e){let r=this.now().toISOString();return this.controlPlane.database.run("UPDATE backup_destinations SET status=?,last_tested_at=?,last_success_at=CASE WHEN ? THEN ? ELSE last_success_at END,last_failure_at=CASE WHEN ? THEN last_failure_at ELSE ? END,last_error=?,version=version+1,updated_at=? WHERE id=?",[e.ok?"healthy":"failing",r,e.ok?1:0,r,e.ok?1:0,r,e.ok?null:String(e.error??"Destination test failed.").slice(0,1000),r,t]),this.getDestination(t)}createPolicy(t){if(!/^[a-z0-9][a-z0-9-]{1,62}$/.test(t.name))throw Error("Backup policy names must be lowercase slugs.");if(!t.resourceId&&!t.dataServiceId&&!["control_plane","infrastructure"].includes(t.resourceKind))throw Error("A backup policy requires a resource or data service target.");let e=this.getDestination(t.destinationId);if(!e||e.projectId!==t.projectId)throw Error("Backup destination was not found.");if(t.resourceKind==="control_plane"&&e.encryption==="provider")throw Error("Control-plane backups require client-side destination encryption.");if(["logical_database","volume","files","control_plane"].includes(t.resourceKind)&&e.provider==="aws_backup")throw Error(`${t.resourceKind} backups require an object-storage destination.`);if(t.resourceKind==="infrastructure"&&e.provider!=="aws_backup")throw Error("Infrastructure backups require an AWS Backup destination.");let r=Fn(t.schedule),d=PE(r.normalized,t.timezone,this.now(),1)[0],E=crypto.randomUUID(),n=this.now().toISOString();return this.controlPlane.database.run("INSERT INTO backup_policies (id,organization_id,project_id,environment_id,resource_id,data_service_id,destination_id,name,resource_kind,schedule,timezone,retention,compression,encryption,include_patterns,exclude_patterns,expected_rpo_minutes,expected_rto_minutes,health_check_id,enabled,next_run_at,last_run_at,version,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",[E,t.organizationId,t.projectId,t.environmentId??null,t.resourceId??null,t.dataServiceId??null,t.destinationId,t.name,t.resourceKind,r.normalized,t.timezone,JSON.stringify(t.retention),t.compression,t.encryption,JSON.stringify(t.includePatterns),JSON.stringify(t.excludePatterns),t.expectedRpoMinutes,t.expectedRtoMinutes,t.healthCheckId??null,t.enabled?1:0,d,t.lastRunAt??null,1,n,n]),this.getPolicy(E)}getPolicy(t){let e=this.controlPlane.database.query("SELECT * FROM backup_policies WHERE id=?").get(t);return e?sS(e):void 0}listPolicies(t,e){return this.controlPlane.database.query(`SELECT * FROM backup_policies WHERE project_id=?${e?" AND environment_id=?":""} ORDER BY name`).all(t,...e?[e]:[]).map(sS)}duePolicies(t=this.now()){return this.controlPlane.database.query("SELECT * FROM backup_policies WHERE enabled=1 AND next_run_at<=? ORDER BY next_run_at,id").all(t.toISOString()).map(sS)}advancePolicy(t,e){let r=this.getPolicy(t);if(!r)throw Error("Backup policy was not found.");let d=PE(r.schedule,r.timezone,new Date(e),1)[0];return this.controlPlane.database.run("UPDATE backup_policies SET last_run_at=?,next_run_at=?,version=version+1,updated_at=? WHERE id=?",[e,d,this.now().toISOString(),t]),this.getPolicy(t)}createJob(t){let e=this.controlPlane.database.query("SELECT * FROM backup_jobs WHERE idempotency_key=?").get(t.idempotencyKey);if(e)return mS(e);let r=crypto.randomUUID(),d=this.now().toISOString();return this.controlPlane.database.run("INSERT INTO backup_jobs (id,project_id,policy_id,recovery_point_id,operation_id,kind,status,idempotency_key,target,restore_mode,cancellability,safety_backup_id,health_result,progress,error,started_at,finished_at,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",[r,t.projectId,t.policyId??null,t.recoveryPointId??null,t.operationId??null,t.kind,t.status,t.idempotencyKey,JSON.stringify(t.target),t.restoreMode??null,t.cancellability,t.safetyBackupId??null,t.healthResult?JSON.stringify(t.healthResult):null,JSON.stringify(t.progress),t.error??null,t.startedAt??null,t.finishedAt??null,d,d]),this.getJob(r)}getJob(t){let e=this.controlPlane.database.query("SELECT * FROM backup_jobs WHERE id=?").get(t);return e?mS(e):void 0}listJobs(t){return this.controlPlane.database.query("SELECT * FROM backup_jobs WHERE project_id=? ORDER BY created_at DESC").all(t).map(mS)}updateJob(t,e){let r=this.getJob(t);if(!r)throw Error("Backup job was not found.");let d={...r,...e};return this.controlPlane.database.run("UPDATE backup_jobs SET status=?,operation_id=?,recovery_point_id=?,progress=?,health_result=?,error=?,started_at=?,finished_at=?,safety_backup_id=?,updated_at=? WHERE id=?",[d.status,d.operationId??null,d.recoveryPointId??null,JSON.stringify(d.progress),d.healthResult?JSON.stringify(d.healthResult):null,d.error??null,d.startedAt??null,d.finishedAt??null,d.safetyBackupId??null,this.now().toISOString(),t]),this.getJob(t)}createRecoveryPoint(t){if(!/^sha256:[a-f0-9]{64}$/i.test(t.checksum))throw Error("Recovery points require a SHA-256 checksum.");if(typeof t.uri!=="string"||!["s3:","aws-backup:","file:"].some((d)=>t.uri.startsWith(d)))throw Error("Recovery point URI uses an unsupported destination scheme.");let e=crypto.randomUUID(),r=this.now().toISOString();return this.controlPlane.database.run("INSERT INTO recovery_points (id,project_id,policy_id,destination_id,resource_id,data_service_id,backup_job_id,kind,point_in_time,uri,size_bytes,checksum,manifest,tool_version,engine_version,expires_at,locked_until,held,pinned,status,verification_state,verified_at,duration_ms,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",[e,t.projectId,t.policyId??null,t.destinationId,t.resourceId??null,t.dataServiceId??null,t.backupJobId??null,t.kind,t.pointInTime,t.uri,t.sizeBytes,t.checksum,JSON.stringify(t.manifest),t.toolVersion??null,t.engineVersion??null,t.expiresAt??null,t.lockedUntil??null,t.held?1:0,t.pinned?1:0,t.status,t.verificationState,t.verifiedAt??null,t.durationMs??null,r,r]),this.getRecoveryPoint(e)}getRecoveryPoint(t){let e=this.controlPlane.database.query("SELECT * FROM recovery_points WHERE id=?").get(t);return e?oS(e):void 0}listRecoveryPoints(t,e){return this.controlPlane.database.query(`SELECT * FROM recovery_points WHERE project_id=?${e?" AND policy_id=?":""} ORDER BY point_in_time DESC`).all(t,...e?[e]:[]).map(oS)}updateRecoveryPoint(t,e){let r=this.getRecoveryPoint(t);if(!r)throw Error("Recovery point was not found.");let d={...r,...e};return this.controlPlane.database.run("UPDATE recovery_points SET status=?,verification_state=?,verified_at=?,held=?,pinned=?,manifest=?,duration_ms=?,updated_at=? WHERE id=?",[d.status,d.verificationState,d.verifiedAt??null,d.held?1:0,d.pinned?1:0,JSON.stringify(d.manifest),d.durationMs??null,this.now().toISOString(),t]),this.getRecoveryPoint(t)}retentionCandidates(t=this.now()){let e=this.controlPlane.database.query(`SELECT rp.* FROM recovery_points rp
|
|
5532
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,[r,t.tokenId,t.key,t.requestHash,t.operationId??null,t.responseStatus,JSON.stringify(t.responseBody),E,d]),this.getIdempotency(t.tokenId,t.key)}purgeExpired(){let t=this.now(),e=this.controlPlane.database.run("DELETE FROM api_tokens WHERE (expires_at < ? OR revoked_at IS NOT NULL) AND created_at < ?",[t,new Date(this.nowFn().getTime()-2592000000).toISOString()]).changes,r=this.controlPlane.database.run("DELETE FROM api_idempotency_records WHERE expires_at < ?",[t]).changes;return{tokens:e,idempotency:r}}}Lt();class __{region;client;constructor(t="us-east-1",e=new dt){this.region=t;this.client=e}request(t,e){return this.client.request({service:"backup",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-amz-json-1.1","X-Amz-Target":`CryoControllerFrontendService.${t}`},body:JSON.stringify(e)})}startBackupJob(t){return this.request("StartBackupJob",t)}describeBackupJob(t){return this.request("DescribeBackupJob",{BackupJobId:t})}startRestoreJob(t){return this.request("StartRestoreJob",t)}describeRestoreJob(t){return this.request("DescribeRestoreJob",{RestoreJobId:t})}deleteRecoveryPoint(t,e){return this.request("DeleteRecoveryPoint",{BackupVaultName:t,RecoveryPointArn:e})}}Lt();class T_{client;region;constructor(t="us-east-1",e){this.region=t,this.client=new dt}async describeCacheClusters(t){let e={Action:"DescribeCacheClusters",Version:"2015-02-02",ShowCacheNodeInfo:"true"};if(t)e.CacheClusterId=t;let r=await this.client.request({service:"elasticache",region:this.region,method:"POST",path:"/",body:new URLSearchParams(e).toString()});return{CacheClusters:this.parseCacheClusters(r)}}async describeReplicationGroups(t){let e={Action:"DescribeReplicationGroups",Version:"2015-02-02"};if(t)e.ReplicationGroupId=t;let r=await this.client.request({service:"elasticache",region:this.region,method:"POST",path:"/",body:new URLSearchParams(e).toString()});return{ReplicationGroups:[]}}async createCacheCluster(t){let e={Action:"CreateCacheCluster",Version:"2015-02-02",CacheClusterId:t.cacheClusterId,Engine:t.engine,CacheNodeType:t.cacheNodeType};if(t.numCacheNodes)e.NumCacheNodes=t.numCacheNodes;if(t.engineVersion)e.EngineVersion=t.engineVersion;if(t.port)e.Port=t.port;if(t.securityGroupIds&&t.securityGroupIds.length>0)t.securityGroupIds.forEach((d,E)=>{e[`SecurityGroupIds.member.${E+1}`]=d});if(t.subnetGroupName)e.CacheSubnetGroupName=t.subnetGroupName;if(t.tags&&t.tags.length>0)t.tags.forEach((d,E)=>{e[`Tags.member.${E+1}.Key`]=d.Key,e[`Tags.member.${E+1}.Value`]=d.Value});let r=await this.client.request({service:"elasticache",region:this.region,method:"POST",path:"/",body:new URLSearchParams(e).toString()});return{CacheCluster:this.parseCacheCluster(r)}}async deleteCacheCluster(t,e){let r={Action:"DeleteCacheCluster",Version:"2015-02-02",CacheClusterId:t};if(e)r.FinalSnapshotIdentifier=e;await this.client.request({service:"elasticache",region:this.region,method:"POST",path:"/",body:new URLSearchParams(r).toString()})}async rebootCacheCluster(t,e){let r={Action:"RebootCacheCluster",Version:"2015-02-02",CacheClusterId:t};e.forEach((d,E)=>{r[`CacheNodeIdsToReboot.member.${E+1}`]=d}),await this.client.request({service:"elasticache",region:this.region,method:"POST",path:"/",body:new URLSearchParams(r).toString()})}async describeCacheEngineVersions(t){let e={Action:"DescribeCacheEngineVersions",Version:"2015-02-02"};if(t)e.Engine=t;let r=await this.client.request({service:"elasticache",region:this.region,method:"POST",path:"/",body:new URLSearchParams(e).toString()});return{CacheEngineVersions:[]}}async getCacheStatistics(t){let e=await this.describeCacheClusters(t);if(!e.CacheClusters||e.CacheClusters.length===0)throw Error(`Cache cluster ${t} not found`);return{cpuUtilization:0,evictions:0,hits:0,misses:0,connections:0}}parseCacheClusters(t){if(t.CacheClusterId)return[{CacheClusterId:t.CacheClusterId,CacheClusterStatus:t.CacheClusterStatus||"available",Engine:t.Engine||"redis",EngineVersion:t.EngineVersion||"7.0",CacheNodeType:t.CacheNodeType||"cache.t3.micro",NumCacheNodes:Number.parseInt(t.NumCacheNodes||"1"),CacheClusterCreateTime:t.CacheClusterCreateTime||new Date().toISOString()}];return[]}parseCacheCluster(t){return{CacheClusterId:t.CacheClusterId,CacheClusterStatus:t.CacheClusterStatus||"creating",Engine:t.Engine||"redis",EngineVersion:t.EngineVersion||"7.0",CacheNodeType:t.CacheNodeType||"cache.t3.micro",NumCacheNodes:Number.parseInt(t.NumCacheNodes||"1"),CacheClusterCreateTime:t.CacheClusterCreateTime||new Date().toISOString()}}}Pn();Lt();class aE{client;region;constructor(t="us-east-1",e){this.region=t,this.client=new dt}async createSecret(t){let e={Name:t.Name};if(t.Description)e.Description=t.Description;if(t.KmsKeyId)e.KmsKeyId=t.KmsKeyId;if(t.SecretBinary)e.SecretBinary=t.SecretBinary;if(t.SecretString)e.SecretString=t.SecretString;if(t.Tags&&t.Tags.length>0)e.Tags=t.Tags;if(t.AddReplicaRegions&&t.AddReplicaRegions.length>0)e.AddReplicaRegions=t.AddReplicaRegions;if(t.ForceOverwriteReplicaSecret!==void 0)e.ForceOverwriteReplicaSecret=t.ForceOverwriteReplicaSecret;e.ClientRequestToken=t.ClientRequestToken||crypto.randomUUID();let r=await this.client.request({service:"secretsmanager",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"secretsmanager.CreateSecret","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(e)});return{ARN:r.ARN,Name:r.Name,VersionId:r.VersionId,ReplicationStatus:r.ReplicationStatus}}async updateSecret(t){let e={SecretId:t.SecretId};if(t.Description)e.Description=t.Description;if(t.KmsKeyId)e.KmsKeyId=t.KmsKeyId;if(t.SecretBinary)e.SecretBinary=t.SecretBinary;if(t.SecretString)e.SecretString=t.SecretString;let r=await this.client.request({service:"secretsmanager",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"secretsmanager.UpdateSecret","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(e)});return{ARN:r.ARN,Name:r.Name,VersionId:r.VersionId}}async putSecretValue(t){let e={SecretId:t.SecretId};if(t.SecretBinary)e.SecretBinary=t.SecretBinary;if(t.SecretString)e.SecretString=t.SecretString;if(t.VersionStages&&t.VersionStages.length>0)e.VersionStages=t.VersionStages;if(t.ClientRequestToken)e.ClientRequestToken=t.ClientRequestToken;let r=await this.client.request({service:"secretsmanager",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"secretsmanager.PutSecretValue","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(e)});return{ARN:r.ARN,Name:r.Name,VersionId:r.VersionId,VersionStages:r.VersionStages}}async getSecretValue(t){let e={SecretId:t.SecretId};if(t.VersionId)e.VersionId=t.VersionId;if(t.VersionStage)e.VersionStage=t.VersionStage;let r=await this.client.request({service:"secretsmanager",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"secretsmanager.GetSecretValue","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(e)});return{ARN:r.ARN,Name:r.Name,VersionId:r.VersionId,SecretBinary:r.SecretBinary,SecretString:r.SecretString,VersionStages:r.VersionStages,CreatedDate:r.CreatedDate}}async describeSecret(t){let e={SecretId:t},r=await this.client.request({service:"secretsmanager",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"secretsmanager.DescribeSecret","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(e)});return this.parseSecret(r)}async listSecrets(t){let e={};if(t?.MaxResults)e.MaxResults=t.MaxResults;if(t?.NextToken)e.NextToken=t.NextToken;if(t?.Filters&&t.Filters.length>0)e.Filters=t.Filters;if(t?.SortOrder)e.SortOrder=t.SortOrder;let r=await this.client.request({service:"secretsmanager",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"secretsmanager.ListSecrets","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(e)});return{SecretList:r.SecretList?.map((d)=>this.parseSecret(d)),NextToken:r.NextToken}}async deleteSecret(t){let e={SecretId:t.SecretId};if(t.RecoveryWindowInDays!==void 0)e.RecoveryWindowInDays=t.RecoveryWindowInDays;if(t.ForceDeleteWithoutRecovery!==void 0)e.ForceDeleteWithoutRecovery=t.ForceDeleteWithoutRecovery;let r=await this.client.request({service:"secretsmanager",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"secretsmanager.DeleteSecret","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(e)});return{ARN:r.ARN,Name:r.Name,DeletionDate:r.DeletionDate}}async restoreSecret(t){let e={SecretId:t},r=await this.client.request({service:"secretsmanager",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"secretsmanager.RestoreSecret","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(e)});return{ARN:r.ARN,Name:r.Name}}async rotateSecret(t){let e={SecretId:t.SecretId};if(t.ClientRequestToken)e.ClientRequestToken=t.ClientRequestToken;if(t.RotationLambdaARN)e.RotationLambdaARN=t.RotationLambdaARN;if(t.RotationRules)e.RotationRules=t.RotationRules;if(t.RotateImmediately!==void 0)e.RotateImmediately=t.RotateImmediately;let r=await this.client.request({service:"secretsmanager",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"secretsmanager.RotateSecret","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(e)});return{ARN:r.ARN,Name:r.Name,VersionId:r.VersionId}}async cancelRotateSecret(t){let e={SecretId:t},r=await this.client.request({service:"secretsmanager",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"secretsmanager.CancelRotateSecret","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(e)});return{ARN:r.ARN,Name:r.Name}}async getResourcePolicy(t){let e={SecretId:t},r=await this.client.request({service:"secretsmanager",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"secretsmanager.GetResourcePolicy","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(e)});return{ARN:r.ARN,Name:r.Name,ResourcePolicy:r.ResourcePolicy}}async putResourcePolicy(t){let e={SecretId:t.SecretId,ResourcePolicy:t.ResourcePolicy};if(t.BlockPublicPolicy!==void 0)e.BlockPublicPolicy=t.BlockPublicPolicy;let r=await this.client.request({service:"secretsmanager",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"secretsmanager.PutResourcePolicy","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(e)});return{ARN:r.ARN,Name:r.Name}}async deleteResourcePolicy(t){let e={SecretId:t},r=await this.client.request({service:"secretsmanager",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"secretsmanager.DeleteResourcePolicy","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(e)});return{ARN:r.ARN,Name:r.Name}}async tagResource(t){let e={SecretId:t.SecretId,Tags:t.Tags};await this.client.request({service:"secretsmanager",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"secretsmanager.TagResource","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(e)})}async untagResource(t){let e={SecretId:t.SecretId,TagKeys:t.TagKeys};await this.client.request({service:"secretsmanager",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"secretsmanager.UntagResource","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(e)})}async setString(t,e,r){try{let d=await this.putSecretValue({SecretId:t,SecretString:e});return{ARN:d.ARN,VersionId:d.VersionId}}catch(d){if(d.code==="ResourceNotFoundException"){let E=await this.createSecret({Name:t,SecretString:e,Description:r?.description,KmsKeyId:r?.kmsKeyId,Tags:r?.tags});return{ARN:E.ARN,VersionId:E.VersionId}}throw d}}async setJson(t,e,r){return this.setString(t,JSON.stringify(e),r)}async getString(t){return(await this.getSecretValue({SecretId:t})).SecretString}async getJson(t){let e=await this.getString(t);if(e)return JSON.parse(e);return}async listAll(){let t=[],e;do{let r=await this.listSecrets({NextToken:e});if(r.SecretList)t.push(...r.SecretList);e=r.NextToken}while(e);return t}parseSecret(t){return{ARN:t.ARN,Name:t.Name,Description:t.Description,KmsKeyId:t.KmsKeyId,RotationEnabled:t.RotationEnabled,RotationLambdaARN:t.RotationLambdaARN,RotationRules:t.RotationRules,LastRotatedDate:t.LastRotatedDate,LastChangedDate:t.LastChangedDate,LastAccessedDate:t.LastAccessedDate,DeletedDate:t.DeletedDate,NextRotationDate:t.NextRotationDate,Tags:t.Tags,SecretVersionsToStages:t.SecretVersionsToStages,CreatedDate:t.CreatedDate,PrimaryRegion:t.PrimaryRegion}}}Lt();class jn{client;region;constructor(t="us-east-1",e){this.region=t,this.client=new dt}async putParameter(t){let e={Name:t.Name,Value:t.Value};if(t.Type)e.Type=t.Type;if(t.Description)e.Description=t.Description;if(t.KeyId)e.KeyId=t.KeyId;if(t.Overwrite!==void 0)e.Overwrite=t.Overwrite;if(t.AllowedPattern)e.AllowedPattern=t.AllowedPattern;if(t.Tags&&t.Tags.length>0)e.Tags=t.Tags;if(t.Tier)e.Tier=t.Tier;if(t.DataType)e.DataType=t.DataType;let r=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(e)});return{Version:r.Version,Tier:r.Tier}}async getParameter(t){let e={Name:t.Name};if(t.WithDecryption!==void 0)e.WithDecryption=t.WithDecryption;let r=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(e)});return{Parameter:r.Parameter?this.parseParameter(r.Parameter):void 0}}async getParameters(t){let e={Names:t.Names};if(t.WithDecryption!==void 0)e.WithDecryption=t.WithDecryption;let r=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(e)});return{Parameters:r.Parameters?.map((d)=>this.parseParameter(d)),InvalidParameters:r.InvalidParameters}}async getParametersByPath(t){let e={Path:t.Path};if(t.Recursive!==void 0)e.Recursive=t.Recursive;if(t.WithDecryption!==void 0)e.WithDecryption=t.WithDecryption;if(t.MaxResults)e.MaxResults=t.MaxResults;if(t.NextToken)e.NextToken=t.NextToken;if(t.ParameterFilters&&t.ParameterFilters.length>0)e.ParameterFilters=t.ParameterFilters;let r=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(e)});return{Parameters:r.Parameters?.map((d)=>this.parseParameter(d)),NextToken:r.NextToken}}async deleteParameter(t){let e={Name:t.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(e)})}async deleteParameters(t){let e={Names:t},r=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(e)});return{DeletedParameters:r.DeletedParameters,InvalidParameters:r.InvalidParameters}}async describeParameters(t){let e={};if(t?.Filters&&t.Filters.length>0)e.Filters=t.Filters;if(t?.ParameterFilters&&t.ParameterFilters.length>0)e.ParameterFilters=t.ParameterFilters;if(t?.MaxResults)e.MaxResults=t.MaxResults;if(t?.NextToken)e.NextToken=t.NextToken;let r=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(e)});return{Parameters:r.Parameters?.map((d)=>this.parseParameter(d)),NextToken:r.NextToken}}async getParameterHistory(t){let e={Name:t.Name};if(t.WithDecryption!==void 0)e.WithDecryption=t.WithDecryption;if(t.MaxResults)e.MaxResults=t.MaxResults;if(t.NextToken)e.NextToken=t.NextToken;let r=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(e)});return{Parameters:r.Parameters?.map((d)=>({Name:d.Name,Type:d.Type,KeyId:d.KeyId,LastModifiedDate:d.LastModifiedDate,LastModifiedUser:d.LastModifiedUser,Description:d.Description,Value:d.Value,Version:d.Version,Labels:d.Labels,Tier:d.Tier})),NextToken:r.NextToken}}async labelParameterVersion(t){let e={Name:t.Name,Labels:t.Labels};if(t.ParameterVersion!==void 0)e.ParameterVersion=t.ParameterVersion;let r=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(e)});return{InvalidLabels:r.InvalidLabels,ParameterVersion:r.ParameterVersion}}async addTagsToResource(t){let e={ResourceType:t.ResourceType,ResourceId:t.ResourceId,Tags:t.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(e)})}async removeTagsFromResource(t){let e={ResourceType:t.ResourceType,ResourceId:t.ResourceId,TagKeys:t.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(e)})}async listTagsForResource(t){let e={ResourceType:t.ResourceType,ResourceId:t.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(e)})).TagList}}async setString(t,e,r){return this.putParameter({Name:t,Value:e,Type:"String",Description:r?.description,Overwrite:r?.overwrite??!0,Tags:r?.tags})}async setSecureString(t,e,r){return this.putParameter({Name:t,Value:e,Type:"SecureString",Description:r?.description,Overwrite:r?.overwrite??!0,KeyId:r?.kmsKeyId,Tags:r?.tags})}async getValue(t){return(await this.getParameter({Name:t,WithDecryption:!0})).Parameter?.Value}async getAllByPath(t,e=!0){let r=[],d;do{let E=await this.getParametersByPath({Path:t,Recursive:e,WithDecryption:!0,NextToken:d});if(E.Parameters)r.push(...E.Parameters);d=E.NextToken}while(d);return r}parseParameter(t){return{Name:t.Name,Type:t.Type,Value:t.Value,Version:t.Version,LastModifiedDate:t.LastModifiedDate,ARN:t.ARN,DataType:t.DataType,Description:t.Description,AllowedPattern:t.AllowedPattern,KeyId:t.KeyId,Tier:t.Tier}}async sendCommand(t){if(!t.InstanceIds&&!t.Targets)throw Error("SendCommand requires either InstanceIds or Targets");let e={DocumentName:t.DocumentName};if(t.InstanceIds)e.InstanceIds=t.InstanceIds;if(t.Targets)e.Targets=t.Targets;if(t.Parameters)e.Parameters=t.Parameters;if(t.TimeoutSeconds)e.TimeoutSeconds=t.TimeoutSeconds;if(t.Comment)e.Comment=t.Comment;if(t.OutputS3BucketName)e.OutputS3BucketName=t.OutputS3BucketName;if(t.OutputS3KeyPrefix)e.OutputS3KeyPrefix=t.OutputS3KeyPrefix;let r=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(e)});return{CommandId:r.Command?.CommandId,Status:r.Command?.Status,StatusDetails:r.Command?.StatusDetails}}async getCommandInvocation(t){let e={CommandId:t.CommandId,InstanceId:t.InstanceId},r=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(e)});return{Status:r.Status,StatusDetails:r.StatusDetails,StandardOutputContent:r.StandardOutputContent,StandardErrorContent:r.StandardErrorContent,ResponseCode:r.ResponseCode}}async runShellCommand(t,e,r){let d=await this.sendCommand({InstanceIds:[t],DocumentName:"AWS-RunShellScript",Parameters:{commands:e},TimeoutSeconds:r?.timeoutSeconds||600});if(!d.CommandId)return{success:!1,error:"Failed to send command"};if(r?.waitForCompletion===!1)return{success:!0,status:"Pending"};let E=r?.pollIntervalMs||2000,n=r?.maxWaitMs||300000,c=Date.now();while(Date.now()-c<n){await new Promise((_)=>setTimeout(_,E));try{let _=await this.getCommandInvocation({CommandId:d.CommandId,InstanceId:t});if(_.Status==="Success")return{success:!0,output:_.StandardOutputContent,error:_.StandardErrorContent,status:_.Status};if(_.Status==="Failed"||_.Status==="Cancelled"||_.Status==="TimedOut")return{success:!1,output:_.StandardOutputContent,error:_.StandardErrorContent||_.StatusDetails,status:_.Status}}catch(_){if(!_.message?.includes("InvocationDoesNotExist"))return{success:!1,error:_.message}}}return{success:!1,error:"Command timed out waiting for completion"}}async listCommandInvocations(t){let e={CommandId:t.CommandId};if(t.Details)e.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(e)})).CommandInvocations||[]).map((E)=>({InstanceId:E.InstanceId,Status:E.Status,StatusDetails:E.StatusDetails,StandardOutputContent:E.CommandPlugins?.[0]?.Output,StandardErrorContent:E.CommandPlugins?.[0]?.StandardErrorUrl}))}async sendCommandByTags(t){let e=Object.entries(t.tags).map(([T,i])=>({Key:`tag:${T}`,Values:[i]})),r=await this.sendCommand({Targets:e,DocumentName:"AWS-RunShellScript",Parameters:{commands:t.commands},TimeoutSeconds:t.timeoutSeconds||600,Comment:t.comment});if(!r.CommandId)return{success:!1,instanceCount:0,perInstance:[],error:"Failed to send command"};let d=t.pollIntervalMs||3000,E=t.maxWaitMs||600000,n=Date.now(),c=new Set(["Success","Failed","Cancelled","TimedOut"]),_=[];while(Date.now()-n<E){await new Promise((T)=>setTimeout(T,d));try{if(_=await this.listCommandInvocations({CommandId:r.CommandId,Details:!0}),_.length===0)continue;if(_.every((i)=>c.has(i.Status||""))){let i=_.map((R)=>({instanceId:R.InstanceId,status:R.Status||"Unknown",output:R.StandardOutputContent,error:R.StandardErrorContent||R.StatusDetails})),h=_.every((R)=>R.Status==="Success");return{success:h,instanceCount:_.length,perInstance:i,error:h?void 0:"One or more instances reported a non-success status"}}}catch(T){if(!T.message?.includes("InvocationDoesNotExist"))return{success:!1,instanceCount:0,perInstance:[],error:T.message}}}return{success:!1,instanceCount:_.length,perInstance:_.map((T)=>({instanceId:T.InstanceId,status:T.Status||"Unknown"})),error:"Command timed out waiting for all instances to complete"}}}import{isIP as cl}from"node:net";var eX={every_minute:"* * * * *",every_five_minutes:"*/5 * * * *",hourly:"0 * * * *",daily:"0 0 * * *",weekly:"0 0 * * 0"},rX={JAN:1,FEB:2,MAR:3,APR:4,MAY:5,JUN:6,JUL:7,AUG:8,SEP:9,OCT:10,NOV:11,DEC:12},tl={SUN:0,MON:1,TUE:2,WED:3,THU:4,FRI:5,SAT:6};function el(t){try{return new Intl.DateTimeFormat("en",{timeZone:t}).format(new Date),t}catch{throw Error(`Unknown schedule timezone: ${t}`)}}function mT(t,e,r,d){let E=e[t.toUpperCase()]??Number(t);if(!Number.isInteger(E)||E<r||E>d)throw Error(`Schedule field value ${t} is outside ${r}-${d}.`);return E}function zn(t,e,r,d={},E){if(t==="*"||t==="?")return;let n=new Set;for(let c of t.split(",")){let[_,T]=c.split("/"),i=T?mT(T,{},1,r-e+1):1,h,R;if(_==="*")h=e,R=r;else if(_.includes("-")){let N=_.split("-");h=mT(N[0],d,e,r),R=mT(N[1],d,e,r)}else h=mT(_,d,e,r),R=h;if(R<h)throw Error("Schedule ranges must be ascending.");for(let N=h;N<=R;N+=i)n.add(E?E(N):N===7&&r===7?0:N)}return n}function dX(t,e){let r=Object.fromEntries(new Intl.DateTimeFormat("en-US",{timeZone:e,year:"numeric",month:"numeric",day:"numeric",weekday:"short",hour:"numeric",minute:"numeric",hourCycle:"h23"}).formatToParts(t).map((d)=>[d.type,d.value]));return{minute:Number(r.minute),hour:Number(r.hour),day:Number(r.day),month:Number(r.month),weekday:tl[r.weekday.toUpperCase()],year:Number(r.year),key:`${r.year}-${r.month}-${r.day} ${r.hour}:${r.minute}`}}function rl(t){let r=(t.startsWith("cron(")?t.slice(5,-1).trim():t.trim()).split(/\s+/);if(r.length!==5&&r.length!==6)throw Error("Cron schedules require five standard fields or six EventBridge fields.");let[d,E,n,c,_,T]=r,i=r.length===6;return{minute:zn(d,0,59),hour:zn(E,0,23),day:zn(n,1,31),month:zn(c,1,12,rX),weekday:zn(_,i?1:0,7,tl,i?(h)=>h===7?6:h-1:void 0),year:T?zn(T,1970,2199):void 0,dayWildcard:n==="*"||n==="?",weekdayWildcard:_==="*"||_==="?"}}function EX(t,e){if(!((!e.minute||e.minute.has(t.minute))&&(!e.hour||e.hour.has(t.hour))&&(!e.month||e.month.has(t.month))&&(!e.year||e.year.has(t.year))))return!1;let d=!e.day||e.day.has(t.day),E=!e.weekday||e.weekday.has(t.weekday);return e.dayWildcard?E:e.weekdayWildcard?d:d||E}function dl(t){let e=/^rate\(\s*(\d+)\s+(minute|minutes|hour|hours|day|days)\s*\)$/i.exec(t);if(!e)return;let r=Number(e[1]);if(r<1)throw Error("Rate amount must be positive.");return r*(e[2].toLowerCase().startsWith("minute")?60000:e[2].toLowerCase().startsWith("hour")?3600000:86400000)}function Fn(t){let e=t.trim(),r=eX[e.toLowerCase()]??e;if(!r)throw Error("Schedule expression is required.");let d=dl(r);if(d){let E=d/60000;return{original:e,normalized:`rate(${E} minutes)`,kind:"rate",description:E%1440===0?`Every ${E/1440} day(s)`:E%60===0?`Every ${E/60} hour(s)`:`Every ${E} minute(s)`}}return rl(r),{original:e,normalized:r.startsWith("cron(")?r:`cron(${r})`,kind:"cron",description:`Cron ${r.replace(/^cron\(|\)$/g,"")}`}}function PE(t,e,r=new Date,d=5){let E=Fn(t),n=el(e),c=Math.min(20,Math.max(1,d)),_=dl(E.normalized);if(_)return Array.from({length:c},(A,u)=>new Date(r.getTime()+_*(u+1)).toISOString());let T=rl(E.normalized),i=[],h=new Set,R=new Date(Math.floor(r.getTime()/60000)*60000+60000),N=0;while(i.length<c&&N<1100000){let A=dX(R,n);if(EX(A,T)&&!h.has(A.key))i.push(R.toISOString()),h.add(A.key);R=new Date(R.getTime()+60000),N++}if(i.length<c)throw Error("Schedule produced no runs within the bounded preview horizon.");return i}function jE(t,e="UTC",r=new Date,d=5){let E=Fn(t),n=PE(E.normalized,e,r,d),c=E.kind==="cron"?["Server cron and EventBridge use the same wall-clock preview; provider-specific extensions are retained only when supported."]:["Rate schedules use elapsed-time intervals and are not shifted by DST."];return{...E,timezone:el(e),nextRuns:n,capabilities:{server:E.kind==="cron",eventbridge:!0,notes:c}}}function ZS(t){let e=Fn(t.expression),r=e.normalized.slice(5,-1).trim().split(/\s+/),d=e.kind==="cron"&&r.length===5;if(t.provider==="server")return{provider:"server",supported:d,features:{timezone:!0,flexibleWindow:!1,catchUp:!1,replaceOverlap:!1},notes:[e.kind==="rate"?"Server cron requires a cron expression; use an equivalent cron schedule.":r.length!==5?"EventBridge six-field cron extensions cannot be installed as server cron.":"Cron is reconciled through a root-owned ts-cloud entry.",t.missedRunPolicy==="catch_up"?"Catch-up is handled by the control plane, not cron.":"Missed runs are skipped by cron."]};if(t.provider==="eventbridge")return{provider:"eventbridge",supported:!0,features:{timezone:!0,flexibleWindow:!0,catchUp:!1,replaceOverlap:!1},notes:["Five-field cron is translated explicitly to EventBridge six-field syntax. Flexible windows are provider-native; overlap and catch-up remain control-plane policies."]};if(t.provider==="lambda")return{provider:"lambda",supported:!0,features:{timezone:!0,flexibleWindow:!0,catchUp:!1,replaceOverlap:!1},notes:["The schedule invokes one immutable Lambda target."]};return{provider:"platform",supported:!0,features:{timezone:!0,flexibleWindow:!0,catchUp:!0,replaceOverlap:!0},notes:["The durable control-plane worker enforces all configured policies."]}}function nX(t){if(t.queues===!0)return[{queue:"default",processes:t.queueConcurrency??1}];if(!Array.isArray(t.queues))return[];return t.queues.map((e)=>{if(typeof e==="string")return{queue:e,processes:t.queueConcurrency??1};let[r,d]=Object.entries(e)[0]??["default",t.queueConcurrency??1];return{queue:r,processes:d}})}function kS(t,e,r){let d=new Set,E=new Set,n=new Map(r.resources.map((R)=>[R.slug,R])),c=0,_=0;for(let[R,N]of Object.entries(e.sites??{})){let A=n.get(R);if(N.scheduler){let w=`config:site:${R}:scheduler`;d.add(w),t.upsertConfigJob({organizationId:r.organization.id,projectId:r.project.id,environmentId:r.environment.id,resourceId:A?.id,name:`${R} scheduler`,provider:"server",expression:"* * * * *",timezone:"UTC",flexibleMinutes:0,target:{kind:"dashboard_operation",operationId:`scheduler:run:${R}`},payloadRefs:{},missedRunPolicy:"skip",overlapPolicy:"forbid",retryPolicy:{maxAttempts:3,backoffSeconds:30},timeoutSeconds:300,enabled:!0,origin:"config",sourceKey:w,observedState:{source:"cloud.config.ts"},reconciliationStatus:"pending"}),c++}let u=N,f=Array.isArray(u.queues??u.workers)?u.queues??u.workers:[];for(let[w,I]of f.entries()){let a=typeof I==="string"?{queue:I}:I,P=String(a.queue??a.name??"default"),j=`config:site:${R}:worker:${w}:${P}`;E.add(j),t.upsertWorker({organizationId:r.organization.id,projectId:r.project.id,environmentId:r.environment.id,resourceId:A?.id,name:`${R}:${P}`,provider:"systemd",queue:P,processes:Number(a.processes)||1,timeoutSeconds:Number(a.timeout)||60,restartPolicy:"always",target:{operationId:`worker:restart:${R}`,site:R},enabled:!0,origin:"config",sourceKey:j,observedState:{source:"cloud.config.ts",currentJob:null,failures:0},reconciliationStatus:"pending"}),_++}}let T=e.infrastructure?.compute?.backups;if(T?.enabled)d.add("config:platform:backup"),t.upsertConfigJob({organizationId:r.organization.id,projectId:r.project.id,environmentId:r.environment.id,name:"Scheduled backup",provider:"server",expression:String(T.schedule??"0 2 * * *"),timezone:String(T.timezone??"UTC"),flexibleMinutes:0,target:{kind:"dashboard_operation",operationId:"backup:run"},payloadRefs:{},missedRunPolicy:"skip",overlapPolicy:"forbid",retryPolicy:{maxAttempts:3,backoffSeconds:60},timeoutSeconds:3600,enabled:!0,origin:"config",sourceKey:"config:platform:backup",observedState:{source:"cloud.config.ts"},reconciliationStatus:"pending"}),c++;let i=e.environments?.[r.environment.slug]?.app;if(i){if(i.scheduler!=="off"){let R=`config:serverless:${r.environment.slug}:scheduler`;d.add(R),t.upsertConfigJob({organizationId:r.organization.id,projectId:r.project.id,environmentId:r.environment.id,name:`${r.environment.name} serverless scheduler`,provider:"eventbridge",expression:"rate(1 minute)",timezone:"UTC",flexibleMinutes:0,target:{kind:"serverless_scheduler",action:"schedule:run"},payloadRefs:{},missedRunPolicy:i.scheduler==="sub-minute"?"catch_up":"skip",overlapPolicy:"forbid",retryPolicy:{maxAttempts:3,backoffSeconds:30},timeoutSeconds:i.cliTimeout??900,enabled:!0,origin:"config",sourceKey:R,observedState:{source:"cloud.config.ts",mode:i.scheduler??"on"},reconciliationStatus:"pending"}),c++}for(let{queue:R,processes:N}of nX(i)){let A=`config:serverless:${r.environment.slug}:worker:${R}`;E.add(A),t.upsertWorker({organizationId:r.organization.id,projectId:r.project.id,environmentId:r.environment.id,name:`${r.environment.name}:${R}`,provider:"lambda",queue:R,processes:N,timeoutSeconds:i.queueTimeout??120,restartPolicy:"on_failure",target:{function:"queue",queue:R},enabled:!0,origin:"config",sourceKey:A,observedState:{source:"cloud.config.ts",currentJob:null,failures:0},reconciliationStatus:"pending"}),_++}}let h=0;for(let R of t.list(r.project.id,{environmentId:r.environment.id}).filter((N)=>N.origin==="config"&&N.sourceKey&&!d.has(N.sourceKey)))t.reconcile(R.id,"drifted",{...R.observedState,reason:"Definition is no longer present in configuration; retained for non-destructive review."}),h++;for(let R of t.listWorkers(r.project.id,r.environment.id).filter((N)=>N.origin==="config"&&N.sourceKey&&!E.has(N.sourceKey)))t.reconcileWorker(R.id,"drifted",{...R.observedState,reason:"Definition is no longer present in configuration; retained for non-destructive review."}),h++;return{jobs:c,workers:_,drifted:h}}class bS{store;queue;constructor(t,e={}){this.store=t;this.queue=e.queue??new gt(t.controlPlane)}enqueue(t,e){let r=new Date(e.scheduledFor??this.store.now()).toISOString(),d=`${t.id}:${e.trigger==="manual"?crypto.randomUUID():r}`,E=this.store.activeExecution(t.id);if(E&&t.overlapPolicy==="forbid")return this.store.createExecution({jobId:t.id,trigger:e.trigger,scheduledFor:r,idempotencyKey:d,status:"skipped",output:{reason:"overlap_forbidden",activeExecutionId:E.id}});if(E&&t.overlapPolicy==="replace"&&E.operationId)try{this.queue.requestCancellation(E.operationId,e.actorId)}catch{}let n=this.store.createExecution({jobId:t.id,trigger:e.trigger,scheduledFor:r,idempotencyKey:d,status:"queued",output:{semantics:"at_least_once"}});if(n.operationId)return n;let c=this.queue.enqueue({projectId:t.projectId,environmentId:t.environmentId,resourceId:t.resourceId,actorId:e.actorId,kind:"job.execute",input:{jobId:t.id,executionId:n.id},idempotencyKey:`job-execution:${n.id}`,lockKey:t.overlapPolicy==="allow"?`job-execution:${n.id}`:`job:${t.id}`,maxAttempts:t.retryPolicy.maxAttempts,timeoutSeconds:t.timeoutSeconds,retryClasses:["job_transient"],resumePolicy:"requeue"}).operation;return this.store.attachOperation(n.id,c.id)}tick(t=this.store.now()){let e=[];for(let r of this.store.due(t.toISOString())){let d=r.nextRunAt,E=PE(r.normalizedExpression,r.timezone,t,1)[0];if(r.missedRunPolicy==="catch_up"){let n=d,c=0;while(n<=t.toISOString()&&c<10)e.push(this.enqueue(r,{trigger:n===d?"scheduled":"catch_up",scheduledFor:n})),n=PE(r.normalizedExpression,r.timezone,new Date(n),1)[0],c++}else e.push(this.enqueue(r,{trigger:"scheduled",scheduledFor:d}));this.store.markScheduled(r.id,d,E)}return e}}function El(t){return{"job.execute":async(r)=>{let d=r.operation.input&&typeof r.operation.input==="object"&&!Array.isArray(r.operation.input)?r.operation.input:{},E=t.store.get(String(d.jobId??"")),n=t.store.getExecution(String(d.executionId??""));if(!E||!n)throw Error("Scheduled job execution is no longer available.");t.store.transitionExecution(n.id,"running",{attempt:r.operation.attempt}),r.checkpoint("execute",`Running ${E.name} on ${E.provider}.`),r.log(`Trigger ${n.trigger}; scheduled for ${n.scheduledFor}; semantics at-least-once.`,{stream:"system"});let c=await t.executor(E,E.target,r);if(c.stdout)r.log(c.stdout,{stream:"stdout"});if(c.stderr)r.log(c.stderr,{stream:"stderr"});if(!c.ok){if(t.store.transitionExecution(n.id,r.operation.attempt>=E.retryPolicy.maxAttempts?"dead":"failed",{attempt:r.operation.attempt,error:c.stderr??"Job execution failed."}),c.retryable)throw new $r(c.stderr??"Scheduled job failed transiently.","job_transient");throw Error(c.stderr??"Scheduled job failed.")}return t.store.transitionExecution(n.id,"succeeded",{attempt:r.operation.attempt,output:c.output??{}}),{jobId:E.id,executionId:n.id,provider:E.provider}}}}var ae=(t)=>typeof t==="string"&&t?t:void 0,nl=(t)=>Number(t)===1,zE=(t)=>{try{return JSON.parse(String(t))}catch{return{}}},Vd=(t,e,r,d)=>{let E=Number(t);return Number.isFinite(E)?Math.min(d,Math.max(r,Math.floor(E))):e};function pT(t){return{id:String(t.id),organizationId:String(t.organization_id),projectId:String(t.project_id),environmentId:ae(t.environment_id),resourceId:ae(t.resource_id),name:String(t.name),provider:String(t.provider),expression:String(t.expression),normalizedExpression:String(t.normalized_expression),timezone:String(t.timezone),startsAt:ae(t.starts_at),endsAt:ae(t.ends_at),flexibleMinutes:Number(t.flexible_minutes),target:zE(t.target),payloadRefs:zE(t.payload_refs),missedRunPolicy:String(t.missed_run_policy),overlapPolicy:String(t.overlap_policy),retryPolicy:zE(t.retry_policy),timeoutSeconds:Number(t.timeout_seconds),enabled:nl(t.enabled),origin:String(t.origin),sourceKey:ae(t.source_key),ownerActorId:ae(t.owner_actor_id),observedState:zE(t.observed_state),reconciliationStatus:String(t.reconciliation_status),nextRunAt:ae(t.next_run_at),lastScheduledFor:ae(t.last_scheduled_for),version:Number(t.version),createdAt:String(t.created_at),updatedAt:String(t.updated_at)}}function ti(t){return{id:String(t.id),jobId:String(t.job_id),operationId:ae(t.operation_id),trigger:String(t.trigger),scheduledFor:String(t.scheduled_for),idempotencyKey:String(t.idempotency_key),status:String(t.status),attempt:Number(t.attempt),startedAt:ae(t.started_at),finishedAt:ae(t.finished_at),output:zE(t.output),error:ae(t.error),createdAt:String(t.created_at),updatedAt:String(t.updated_at)}}function xS(t){return{id:String(t.id),organizationId:String(t.organization_id),projectId:String(t.project_id),environmentId:ae(t.environment_id),resourceId:ae(t.resource_id),name:String(t.name),provider:String(t.provider),queue:String(t.queue),processes:Number(t.processes),timeoutSeconds:Number(t.timeout_seconds),restartPolicy:String(t.restart_policy),target:zE(t.target),enabled:nl(t.enabled),origin:String(t.origin),sourceKey:ae(t.source_key),ownerActorId:ae(t.owner_actor_id),observedState:zE(t.observed_state),reconciliationStatus:String(t.reconciliation_status),version:Number(t.version),createdAt:String(t.created_at),updatedAt:String(t.updated_at)}}class qS{controlPlane;options;constructor(t,e={}){this.controlPlane=t;this.options=e}now(){return this.options.now?.()??new Date}create(t){if(!t.name.trim())throw Error("Scheduled jobs require a name.");let e=jE(t.expression,t.timezone,this.now(),1),r=crypto.randomUUID(),d=this.now().toISOString(),E=t.startsAt?new Date(t.startsAt).toISOString():void 0,n=t.endsAt?new Date(t.endsAt).toISOString():void 0;if(E&&n&&E>=n)throw Error("Schedule start must be before end.");let c=e.nextRuns.find((_)=>(!E||_>=E)&&(!n||_<=n));return this.controlPlane.database.run("INSERT INTO scheduled_jobs (id,organization_id,project_id,environment_id,resource_id,name,provider,expression,normalized_expression,timezone,starts_at,ends_at,flexible_minutes,target,payload_refs,missed_run_policy,overlap_policy,retry_policy,timeout_seconds,enabled,origin,source_key,owner_actor_id,observed_state,reconciliation_status,next_run_at,version,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",[r,t.organizationId,t.projectId,t.environmentId??null,t.resourceId??null,t.name.trim().slice(0,120),t.provider,t.expression,e.normalized,t.timezone,E??null,n??null,Vd(t.flexibleMinutes,0,0,1440),JSON.stringify(t.target),JSON.stringify(t.payloadRefs),t.missedRunPolicy,t.overlapPolicy,JSON.stringify({maxAttempts:Vd(t.retryPolicy.maxAttempts,3,1,20),backoffSeconds:Vd(t.retryPolicy.backoffSeconds,30,0,86400),deadLetterRef:t.retryPolicy.deadLetterRef}),Vd(t.timeoutSeconds,900,1,86400),t.enabled?1:0,t.origin,t.sourceKey??null,t.ownerActorId??null,JSON.stringify(t.observedState),t.reconciliationStatus,c??null,1,d,d]),this.get(r)}get(t){let e=this.controlPlane.database.query("SELECT * FROM scheduled_jobs WHERE id=?").get(t);return e?pT(e):void 0}getBySource(t,e,r){let d=this.controlPlane.database.query("SELECT * FROM scheduled_jobs WHERE project_id=? AND environment_id IS ? AND source_key=?").get(t,e??null,r);return d?pT(d):void 0}list(t,e={}){let r=["project_id=?"],d=[t];if(e.environmentId)r.push("environment_id=?"),d.push(e.environmentId);if(e.resourceIds?.length)r.push(`resource_id IN (${e.resourceIds.map(()=>"?").join(",")})`),d.push(...e.resourceIds);if(e.enabled!=null)r.push("enabled=?"),d.push(e.enabled?1:0);return this.controlPlane.database.query(`SELECT * FROM scheduled_jobs WHERE ${r.join(" AND ")} ORDER BY next_run_at IS NULL,next_run_at,name`).all(...d).map(pT)}setEnabled(t,e){this.controlPlane.database.run("UPDATE scheduled_jobs SET enabled=?,version=version+1,updated_at=? WHERE id=?",[e?1:0,this.now().toISOString(),t]);let r=this.get(t);if(!r)throw Error("Scheduled job was not found.");return r}updateSchedule(t,e){let r=this.get(t);if(!r)throw Error("Scheduled job was not found.");let d=e.expression??r.expression,E=e.timezone??r.timezone,n=jE(d,E,this.now(),1),c=this.now().toISOString();return this.controlPlane.database.run("UPDATE scheduled_jobs SET expression=?,normalized_expression=?,timezone=?,missed_run_policy=?,overlap_policy=?,timeout_seconds=?,next_run_at=?,reconciliation_status=?,version=version+1,updated_at=? WHERE id=?",[d,n.normalized,E,e.missedRunPolicy??r.missedRunPolicy,e.overlapPolicy??r.overlapPolicy,Vd(e.timeoutSeconds,r.timeoutSeconds,1,86400),n.nextRuns[0],"pending",c,t]),this.get(t)}remove(t){let e=this.get(t);if(!e)throw Error("Scheduled job was not found.");if(e.origin==="config")throw Error("Config-defined jobs must be removed from configuration, not destructively deleted.");this.controlPlane.database.run("DELETE FROM scheduled_jobs WHERE id=?",[t])}markScheduled(t,e,r){this.controlPlane.database.run("UPDATE scheduled_jobs SET last_scheduled_for=?,next_run_at=?,updated_at=? WHERE id=?",[e,r??null,this.now().toISOString(),t])}reconcile(t,e,r){return this.controlPlane.database.run("UPDATE scheduled_jobs SET reconciliation_status=?,observed_state=?,updated_at=? WHERE id=?",[e,JSON.stringify(r),this.now().toISOString(),t]),this.get(t)}upsertConfigJob(t){let e=this.getBySource(t.projectId,t.environmentId,t.sourceKey);if(!e)return this.create(t);let r=jE(t.expression,t.timezone,this.now(),1),d=this.now().toISOString();if(e.resourceId===t.resourceId&&e.name===t.name&&e.provider===t.provider&&e.expression===t.expression&&e.normalizedExpression===r.normalized&&e.timezone===t.timezone&&JSON.stringify(e.target)===JSON.stringify(t.target)&&JSON.stringify(e.payloadRefs)===JSON.stringify(t.payloadRefs)&&e.missedRunPolicy===t.missedRunPolicy&&e.overlapPolicy===t.overlapPolicy&&JSON.stringify(e.retryPolicy)===JSON.stringify(t.retryPolicy)&&e.timeoutSeconds===t.timeoutSeconds&&e.enabled===t.enabled)return e;return this.controlPlane.database.run("UPDATE scheduled_jobs SET resource_id=?,name=?,provider=?,expression=?,normalized_expression=?,timezone=?,target=?,payload_refs=?,missed_run_policy=?,overlap_policy=?,retry_policy=?,timeout_seconds=?,enabled=?,observed_state=?,reconciliation_status=?,next_run_at=COALESCE(next_run_at,?),version=version+1,updated_at=? WHERE id=?",[t.resourceId??null,t.name,t.provider,t.expression,r.normalized,t.timezone,JSON.stringify(t.target),JSON.stringify(t.payloadRefs),t.missedRunPolicy,t.overlapPolicy,JSON.stringify(t.retryPolicy),t.timeoutSeconds,t.enabled?1:0,JSON.stringify(t.observedState),t.reconciliationStatus,r.nextRuns[0],d,e.id]),this.get(e.id)}due(t=this.now().toISOString()){return this.controlPlane.database.query("SELECT * FROM scheduled_jobs WHERE enabled=1 AND next_run_at IS NOT NULL AND next_run_at<=? AND (starts_at IS NULL OR starts_at<=?) AND (ends_at IS NULL OR ends_at>=?) ORDER BY next_run_at LIMIT 200").all(t,t,t).map(pT)}createExecution(t){let e=this.controlPlane.database.query("SELECT * FROM job_executions WHERE idempotency_key=?").get(t.idempotencyKey);if(e)return ti(e);let r=crypto.randomUUID(),d=this.now().toISOString();return this.controlPlane.database.run("INSERT INTO job_executions (id,job_id,operation_id,trigger,scheduled_for,idempotency_key,status,attempt,output,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?)",[r,t.jobId,t.operationId??null,t.trigger,t.scheduledFor,t.idempotencyKey,t.status,0,JSON.stringify(t.output),d,d]),this.getExecution(r)}getExecution(t){let e=this.controlPlane.database.query("SELECT * FROM job_executions WHERE id=?").get(t);return e?ti(e):void 0}listExecutions(t,e=100){return this.controlPlane.database.query("SELECT * FROM job_executions WHERE job_id=? ORDER BY scheduled_for DESC,created_at DESC LIMIT ?").all(t,Math.min(1000,Math.max(1,e))).map(ti)}activeExecution(t){let e=this.controlPlane.database.query("SELECT * FROM job_executions WHERE job_id=? AND status IN ('queued','running') ORDER BY created_at DESC LIMIT 1").get(t);return e?ti(e):void 0}attachOperation(t,e){return this.controlPlane.database.run("UPDATE job_executions SET operation_id=?,updated_at=? WHERE id=?",[e,this.now().toISOString(),t]),this.getExecution(t)}transitionExecution(t,e,r={}){let d=this.now().toISOString(),E=e==="running"?d:null,n=["succeeded","failed","skipped","dead"].includes(e)?d:null;return this.controlPlane.database.run("UPDATE job_executions SET status=?,attempt=COALESCE(?,attempt),started_at=COALESCE(started_at,?),finished_at=?,output=COALESCE(?,output),error=?,updated_at=? WHERE id=?",[e,r.attempt??null,E,n,r.output?JSON.stringify(r.output):null,r.error?.slice(0,2000)??null,d,t]),this.getExecution(t)}upsertWorker(t){let e=t.sourceKey?this.controlPlane.database.query("SELECT * FROM worker_definitions WHERE project_id=? AND source_key=? AND environment_id IS ?").get(t.projectId,t.sourceKey,t.environmentId??null):void 0,r=e?xS(e):void 0,d=r?.id??crypto.randomUUID(),E=this.now().toISOString(),n=Vd(t.processes,1,0,1000),c=Vd(t.timeoutSeconds,60,1,86400);if(r&&r.resourceId===t.resourceId&&r.name===t.name.slice(0,120)&&r.provider===t.provider&&r.queue===t.queue.slice(0,200)&&r.processes===n&&r.timeoutSeconds===c&&r.restartPolicy===t.restartPolicy&&JSON.stringify(r.target)===JSON.stringify(t.target)&&r.enabled===t.enabled)return r;return this.controlPlane.database.run("INSERT INTO worker_definitions (id,organization_id,project_id,environment_id,resource_id,name,provider,queue,processes,timeout_seconds,restart_policy,target,enabled,origin,source_key,owner_actor_id,observed_state,reconciliation_status,version,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) ON CONFLICT(id) DO UPDATE SET name=excluded.name,resource_id=excluded.resource_id,provider=excluded.provider,queue=excluded.queue,processes=excluded.processes,timeout_seconds=excluded.timeout_seconds,restart_policy=excluded.restart_policy,target=excluded.target,enabled=excluded.enabled,observed_state=excluded.observed_state,reconciliation_status=excluded.reconciliation_status,version=worker_definitions.version+1,updated_at=excluded.updated_at",[d,t.organizationId,t.projectId,t.environmentId??null,t.resourceId??null,t.name.slice(0,120),t.provider,t.queue.slice(0,200),n,c,t.restartPolicy,JSON.stringify(t.target),t.enabled?1:0,t.origin,t.sourceKey??null,t.ownerActorId??null,JSON.stringify(t.observedState),t.reconciliationStatus,1,r?.createdAt??E,E]),this.getWorker(d)}getWorker(t){let e=this.controlPlane.database.query("SELECT * FROM worker_definitions WHERE id=?").get(t);return e?xS(e):void 0}listWorkers(t,e){return this.controlPlane.database.query(`SELECT * FROM worker_definitions WHERE project_id=?${e?" AND environment_id=?":""} ORDER BY name`).all(t,...e?[e]:[]).map(xS)}setWorkerProcesses(t,e){this.controlPlane.database.run("UPDATE worker_definitions SET processes=?,reconciliation_status='pending',version=version+1,updated_at=? WHERE id=?",[Vd(e,1,0,1000),this.now().toISOString(),t]);let r=this.getWorker(t);if(!r)throw Error("Worker was not found.");return r}reconcileWorker(t,e,r){this.controlPlane.database.run("UPDATE worker_definitions SET reconciliation_status=?,observed_state=?,updated_at=? WHERE id=?",[e,JSON.stringify(r),this.now().toISOString(),t]);let d=this.getWorker(t);if(!d)throw Error("Worker was not found.");return d}}var yt=(t)=>t==null?void 0:String(t),ei=(t)=>Number(t)===1,Kd=(t,e)=>{try{return JSON.parse(String(t))}catch{return e}};function _l(t){return{id:String(t.id),organizationId:String(t.organization_id),projectId:String(t.project_id),name:String(t.name),provider:String(t.provider),endpoint:yt(t.endpoint),endpointPolicy:String(t.endpoint_policy),bucket:yt(t.bucket),prefix:String(t.prefix),region:yt(t.region),forcePathStyle:ei(t.force_path_style),credentialRef:yt(t.credential_ref),encryption:String(t.encryption),encryptionKeyRef:yt(t.encryption_key_ref),immutability:Kd(t.immutability,{}),status:String(t.status),lastTestedAt:yt(t.last_tested_at),lastSuccessAt:yt(t.last_success_at),lastFailureAt:yt(t.last_failure_at),lastError:yt(t.last_error),version:Number(t.version),createdAt:String(t.created_at),updatedAt:String(t.updated_at)}}function sS(t){return{id:String(t.id),organizationId:String(t.organization_id),projectId:String(t.project_id),environmentId:yt(t.environment_id),resourceId:yt(t.resource_id),dataServiceId:yt(t.data_service_id),destinationId:String(t.destination_id),name:String(t.name),resourceKind:String(t.resource_kind),schedule:String(t.schedule),timezone:String(t.timezone),retention:Kd(t.retention,{}),compression:String(t.compression),encryption:String(t.encryption),includePatterns:Kd(t.include_patterns,[]),excludePatterns:Kd(t.exclude_patterns,[]),expectedRpoMinutes:Number(t.expected_rpo_minutes),expectedRtoMinutes:Number(t.expected_rto_minutes),healthCheckId:yt(t.health_check_id),enabled:ei(t.enabled),nextRunAt:yt(t.next_run_at),lastRunAt:yt(t.last_run_at),version:Number(t.version),createdAt:String(t.created_at),updatedAt:String(t.updated_at)}}function oS(t){return{id:String(t.id),projectId:String(t.project_id),policyId:yt(t.policy_id),destinationId:String(t.destination_id),resourceId:yt(t.resource_id),dataServiceId:yt(t.data_service_id),backupJobId:yt(t.backup_job_id),kind:String(t.kind),pointInTime:String(t.point_in_time),uri:String(t.uri),sizeBytes:Number(t.size_bytes),checksum:String(t.checksum),manifest:Kd(t.manifest,{}),toolVersion:yt(t.tool_version),engineVersion:yt(t.engine_version),expiresAt:yt(t.expires_at),lockedUntil:yt(t.locked_until),held:ei(t.held),pinned:ei(t.pinned),status:String(t.status),verificationState:String(t.verification_state),verifiedAt:yt(t.verified_at),durationMs:t.duration_ms==null?void 0:Number(t.duration_ms),createdAt:String(t.created_at),updatedAt:String(t.updated_at)}}function mS(t){return{id:String(t.id),projectId:String(t.project_id),policyId:yt(t.policy_id),recoveryPointId:yt(t.recovery_point_id),operationId:yt(t.operation_id),kind:String(t.kind),status:String(t.status),idempotencyKey:String(t.idempotency_key),target:Kd(t.target,{}),restoreMode:yt(t.restore_mode),cancellability:String(t.cancellability),safetyBackupId:yt(t.safety_backup_id),healthResult:t.health_result?Kd(t.health_result,{}):void 0,progress:Kd(t.progress,{}),error:yt(t.error),startedAt:yt(t.started_at),finishedAt:yt(t.finished_at),createdAt:String(t.created_at),updatedAt:String(t.updated_at)}}function cX(t){let e=t.toLowerCase();if(e==="localhost"||e.endsWith(".localhost")||e.endsWith(".local")||e.endsWith(".internal"))return!0;if(cl(e)===6)return e==="::1"||e.startsWith("fe80:");if(cl(e)!==4)return!1;let[r,d]=e.split(".").map(Number);return r===10||r===127||r===0||r===169&&d===254||r===172&&d>=16&&d<=31||r===192&&d===168}function _X(t){if(!/^[a-z0-9][a-z0-9-]{1,62}$/.test(t.name))throw Error("Backup destination names must be 2-63 lowercase letters, numbers, or dashes.");if(t.provider!=="aws_backup"&&!t.bucket)throw Error("S3 backup destinations require a bucket.");if(t.provider==="s3_compatible"&&!t.endpoint)throw Error("S3-compatible destinations require an explicit endpoint.");if(t.provider==="s3_compatible"&&!t.credentialRef)throw Error("S3-compatible destinations require a credential reference.");if(t.encryption!=="provider"&&!t.encryptionKeyRef)throw Error("Client-side encryption requires an encryption key reference.");if(t.endpoint){let e=new URL(t.endpoint);if(e.protocol!=="https:"||e.username||e.password||e.search||e.hash||e.pathname!=="/")throw Error("Backup endpoints must be origin-only HTTPS URLs without credentials, paths, queries, or fragments.");if(cX(e.hostname)&&t.endpointPolicy!=="allow_private")throw Error("Private backup endpoints require endpointPolicy allow_private.")}}class pS{controlPlane;now;constructor(t,e=()=>new Date){this.controlPlane=t;this.now=e}createDestination(t){_X(t);let e=crypto.randomUUID(),r=this.now().toISOString();return this.controlPlane.database.run("INSERT INTO backup_destinations (id,organization_id,project_id,name,provider,endpoint,endpoint_policy,bucket,prefix,region,force_path_style,credential_ref,encryption,encryption_key_ref,immutability,status,last_tested_at,last_success_at,last_failure_at,last_error,version,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",[e,t.organizationId,t.projectId,t.name,t.provider,t.endpoint??null,t.endpointPolicy,t.bucket??null,t.prefix,t.region??null,t.forcePathStyle?1:0,t.credentialRef??null,t.encryption,t.encryptionKeyRef??null,JSON.stringify(t.immutability),t.status,t.lastTestedAt??null,t.lastSuccessAt??null,t.lastFailureAt??null,t.lastError??null,1,r,r]),this.getDestination(e)}getDestination(t){let e=this.controlPlane.database.query("SELECT * FROM backup_destinations WHERE id=?").get(t);return e?_l(e):void 0}listDestinations(t){return this.controlPlane.database.query("SELECT * FROM backup_destinations WHERE project_id=? ORDER BY name").all(t).map(_l)}recordDestinationTest(t,e){let r=this.now().toISOString();return this.controlPlane.database.run("UPDATE backup_destinations SET status=?,last_tested_at=?,last_success_at=CASE WHEN ? THEN ? ELSE last_success_at END,last_failure_at=CASE WHEN ? THEN last_failure_at ELSE ? END,last_error=?,version=version+1,updated_at=? WHERE id=?",[e.ok?"healthy":"failing",r,e.ok?1:0,r,e.ok?1:0,r,e.ok?null:String(e.error??"Destination test failed.").slice(0,1000),r,t]),this.getDestination(t)}createPolicy(t){if(!/^[a-z0-9][a-z0-9-]{1,62}$/.test(t.name))throw Error("Backup policy names must be lowercase slugs.");if(!t.resourceId&&!t.dataServiceId&&!["control_plane","infrastructure"].includes(t.resourceKind))throw Error("A backup policy requires a resource or data service target.");let e=this.getDestination(t.destinationId);if(!e||e.projectId!==t.projectId)throw Error("Backup destination was not found.");if(t.resourceKind==="control_plane"&&e.encryption==="provider")throw Error("Control-plane backups require client-side destination encryption.");if(["logical_database","volume","files","control_plane"].includes(t.resourceKind)&&e.provider==="aws_backup")throw Error(`${t.resourceKind} backups require an object-storage destination.`);if(t.resourceKind==="infrastructure"&&e.provider!=="aws_backup")throw Error("Infrastructure backups require an AWS Backup destination.");let r=Fn(t.schedule),d=PE(r.normalized,t.timezone,this.now(),1)[0],E=crypto.randomUUID(),n=this.now().toISOString();return this.controlPlane.database.run("INSERT INTO backup_policies (id,organization_id,project_id,environment_id,resource_id,data_service_id,destination_id,name,resource_kind,schedule,timezone,retention,compression,encryption,include_patterns,exclude_patterns,expected_rpo_minutes,expected_rto_minutes,health_check_id,enabled,next_run_at,last_run_at,version,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",[E,t.organizationId,t.projectId,t.environmentId??null,t.resourceId??null,t.dataServiceId??null,t.destinationId,t.name,t.resourceKind,r.normalized,t.timezone,JSON.stringify(t.retention),t.compression,t.encryption,JSON.stringify(t.includePatterns),JSON.stringify(t.excludePatterns),t.expectedRpoMinutes,t.expectedRtoMinutes,t.healthCheckId??null,t.enabled?1:0,d,t.lastRunAt??null,1,n,n]),this.getPolicy(E)}getPolicy(t){let e=this.controlPlane.database.query("SELECT * FROM backup_policies WHERE id=?").get(t);return e?sS(e):void 0}listPolicies(t,e){return this.controlPlane.database.query(`SELECT * FROM backup_policies WHERE project_id=?${e?" AND environment_id=?":""} ORDER BY name`).all(t,...e?[e]:[]).map(sS)}duePolicies(t=this.now()){return this.controlPlane.database.query("SELECT * FROM backup_policies WHERE enabled=1 AND next_run_at<=? ORDER BY next_run_at,id").all(t.toISOString()).map(sS)}advancePolicy(t,e){let r=this.getPolicy(t);if(!r)throw Error("Backup policy was not found.");let d=PE(r.schedule,r.timezone,new Date(e),1)[0];return this.controlPlane.database.run("UPDATE backup_policies SET last_run_at=?,next_run_at=?,version=version+1,updated_at=? WHERE id=?",[e,d,this.now().toISOString(),t]),this.getPolicy(t)}createJob(t){let e=this.controlPlane.database.query("SELECT * FROM backup_jobs WHERE idempotency_key=?").get(t.idempotencyKey);if(e)return mS(e);let r=crypto.randomUUID(),d=this.now().toISOString();return this.controlPlane.database.run("INSERT INTO backup_jobs (id,project_id,policy_id,recovery_point_id,operation_id,kind,status,idempotency_key,target,restore_mode,cancellability,safety_backup_id,health_result,progress,error,started_at,finished_at,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",[r,t.projectId,t.policyId??null,t.recoveryPointId??null,t.operationId??null,t.kind,t.status,t.idempotencyKey,JSON.stringify(t.target),t.restoreMode??null,t.cancellability,t.safetyBackupId??null,t.healthResult?JSON.stringify(t.healthResult):null,JSON.stringify(t.progress),t.error??null,t.startedAt??null,t.finishedAt??null,d,d]),this.getJob(r)}getJob(t){let e=this.controlPlane.database.query("SELECT * FROM backup_jobs WHERE id=?").get(t);return e?mS(e):void 0}listJobs(t){return this.controlPlane.database.query("SELECT * FROM backup_jobs WHERE project_id=? ORDER BY created_at DESC").all(t).map(mS)}updateJob(t,e){let r=this.getJob(t);if(!r)throw Error("Backup job was not found.");let d={...r,...e};return this.controlPlane.database.run("UPDATE backup_jobs SET status=?,operation_id=?,recovery_point_id=?,progress=?,health_result=?,error=?,started_at=?,finished_at=?,safety_backup_id=?,updated_at=? WHERE id=?",[d.status,d.operationId??null,d.recoveryPointId??null,JSON.stringify(d.progress),d.healthResult?JSON.stringify(d.healthResult):null,d.error??null,d.startedAt??null,d.finishedAt??null,d.safetyBackupId??null,this.now().toISOString(),t]),this.getJob(t)}createRecoveryPoint(t){if(!/^sha256:[a-f0-9]{64}$/i.test(t.checksum))throw Error("Recovery points require a SHA-256 checksum.");if(typeof t.uri!=="string"||!["s3:","aws-backup:","file:"].some((d)=>t.uri.startsWith(d)))throw Error("Recovery point URI uses an unsupported destination scheme.");let e=crypto.randomUUID(),r=this.now().toISOString();return this.controlPlane.database.run("INSERT INTO recovery_points (id,project_id,policy_id,destination_id,resource_id,data_service_id,backup_job_id,kind,point_in_time,uri,size_bytes,checksum,manifest,tool_version,engine_version,expires_at,locked_until,held,pinned,status,verification_state,verified_at,duration_ms,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",[e,t.projectId,t.policyId??null,t.destinationId,t.resourceId??null,t.dataServiceId??null,t.backupJobId??null,t.kind,t.pointInTime,t.uri,t.sizeBytes,t.checksum,JSON.stringify(t.manifest),t.toolVersion??null,t.engineVersion??null,t.expiresAt??null,t.lockedUntil??null,t.held?1:0,t.pinned?1:0,t.status,t.verificationState,t.verifiedAt??null,t.durationMs??null,r,r]),this.getRecoveryPoint(e)}getRecoveryPoint(t){let e=this.controlPlane.database.query("SELECT * FROM recovery_points WHERE id=?").get(t);return e?oS(e):void 0}listRecoveryPoints(t,e){return this.controlPlane.database.query(`SELECT * FROM recovery_points WHERE project_id=?${e?" AND policy_id=?":""} ORDER BY point_in_time DESC`).all(t,...e?[e]:[]).map(oS)}updateRecoveryPoint(t,e){let r=this.getRecoveryPoint(t);if(!r)throw Error("Recovery point was not found.");let d={...r,...e};return this.controlPlane.database.run("UPDATE recovery_points SET status=?,verification_state=?,verified_at=?,held=?,pinned=?,manifest=?,duration_ms=?,updated_at=? WHERE id=?",[d.status,d.verificationState,d.verifiedAt??null,d.held?1:0,d.pinned?1:0,JSON.stringify(d.manifest),d.durationMs??null,this.now().toISOString(),t]),this.getRecoveryPoint(t)}retentionCandidates(t=this.now()){let e=this.controlPlane.database.query(`SELECT rp.* FROM recovery_points rp
|
|
5533
5533
|
WHERE rp.status='available' AND rp.held=0 AND rp.pinned=0
|
|
5534
5534
|
AND rp.expires_at IS NOT NULL AND rp.expires_at<=?
|
|
5535
5535
|
AND (rp.locked_until IS NULL OR rp.locked_until<=?)
|
|
@@ -5537,7 +5537,7 @@ data: ${JSON.stringify(m)}
|
|
|
5537
5537
|
SELECT 1 FROM backup_jobs bj WHERE bj.recovery_point_id=rp.id
|
|
5538
5538
|
AND bj.kind IN ('restore','drill') AND bj.status IN ('queued','running','cleanup_required')
|
|
5539
5539
|
)
|
|
5540
|
-
ORDER BY rp.expires_at,rp.id`).all(t.toISOString(),t.toISOString()).map(oS),r=new Set;for(let d of new Set(e.map((E)=>E.projectId)))for(let E of this.listPolicies(d)){let n=this.listRecoveryPoints(E.projectId,E.id).filter((_)=>_.status==="available").sort((_,T)=>T.pointInTime.localeCompare(_.pointInTime));for(let _ of n.slice(0,Math.max(0,E.retention.keepLast??0)))r.add(_.id);let c=[[E.retention.hourly,(_)=>_.toISOString().slice(0,13)],[E.retention.daily,(_)=>_.toISOString().slice(0,10)],[E.retention.weekly,(_)=>{return new Date(Date.UTC(_.getUTCFullYear(),_.getUTCMonth(),_.getUTCDate()-(_.getUTCDay()+6)%7)).toISOString().slice(0,10)}],[E.retention.monthly,(_)=>_.toISOString().slice(0,7)]];for(let[_,T]of c){let i=new Set;for(let h of n){let R=T(new Date(h.pointInTime));if(i.has(R))continue;if(i.add(R),i.size<=Math.max(0,_??0))r.add(h.id)}}}return e.filter((d)=>!r.has(d.id))}coverage(t,e=this.now()){let r=new Map(this.listDestinations(t).map((d)=>[d.id,d]));return this.listPolicies(t).map((d)=>{let E=this.listRecoveryPoints(t,d.id).filter((_)=>_.status==="available"),n=E[0],c=n?(e.getTime()-new Date(n.pointInTime).getTime())/60000:Number.POSITIVE_INFINITY;return{policy:d,lastRecoveryPoint:n,missedRpo:d.enabled&&c>d.expectedRpoMinutes,unverified:E.filter((_)=>_.verificationState!=="verified").length,destinationHealthy:r.get(d.destinationId)?.status==="healthy"}})}}tr();import{createCipheriv as TX,createDecipheriv as iX,createHash as Tl,randomBytes as il}from"node:crypto";var tN=Buffer.from("TSCB1"),ri=(t)=>`sha256:${Tl("sha256").update(t).digest("hex")}`;function hl(t){return Tl("sha256").update(t).digest()}function hX(t,e,r){let d=r?Buffer.from(r):il(12);if(d.length!==12)throw Error("Backup encryption IV must contain 12 bytes.");let E=TX("aes-256-gcm",hl(e),d),n=Buffer.concat([E.update(t),E.final()]),c=E.getAuthTag();return Buffer.concat([tN,d,c,n])}function RX(t,e){let r=Buffer.from(t);if(!r.subarray(0,tN.length).equals(tN))throw Error("Backup does not contain a valid encrypted envelope.");let d=r.subarray(5,17),E=r.subarray(17,33),n=r.subarray(33),c=iX("aes-256-gcm",hl(e),d);return c.setAuthTag(E),Buffer.concat([c.update(n),c.final()])}function SX(t){let e;try{e=JSON.parse(t)}catch{throw Error("Backup destination credential must be a JSON object with accessKeyId and secretAccessKey.")}if(!e.accessKeyId||!e.secretAccessKey)throw Error("Backup destination credential requires accessKeyId and secretAccessKey.");if(e.expiresAt){let r=new Date(String(e.expiresAt));if(!Number.isFinite(r.getTime()))throw Error("Backup destination credential expiresAt must be an ISO timestamp.");if(r.getTime()<=Date.now())throw Error("Backup destination credential has expired.")}return{accessKeyId:String(e.accessKeyId),secretAccessKey:String(e.secretAccessKey),sessionToken:e.sessionToken?String(e.sessionToken):void 0}}async function Rl(t,e,r=new Date){if(!t.credentialRef)return{status:"default"};try{let d=JSON.parse(await e.resolve(t.credentialRef));if(!d.accessKeyId||!d.secretAccessKey)return{status:"invalid"};if(!d.expiresAt)return{status:"static"};let E=new Date(String(d.expiresAt));if(!Number.isFinite(E.getTime()))return{status:"invalid"};let n=E.getTime()-r.getTime();return{status:n<=0?"expired":n<=604800000?"expiring":"valid",expiresAt:E.toISOString()}}catch{return{status:"invalid"}}}class eN{secrets;clientFactory;multipartThreshold;partSize;constructor(t,e=(E,n)=>new pt(E.region??"us-east-1",void 0,{endpoint:E.endpoint?new URL(E.endpoint).host:void 0,forcePathStyle:E.forcePathStyle,credentials:n}),r=8388608,d=8388608){this.secrets=t;this.clientFactory=e;this.multipartThreshold=r;this.partSize=d}async client(t){let e=t.credentialRef?SX(await this.secrets.resolve(t.credentialRef)):void 0;return this.clientFactory(t,e)}async test(t){if(!t.bucket)throw Error("S3 destination has no configured bucket.");let e=await this.client(t),r=`${t.prefix?`${t.prefix.replace(/\/$/,"")}/`:""}.ts-cloud-health/${crypto.randomUUID()}`;await e.putObject({bucket:t.bucket,key:r,body:"ts-cloud backup destination health check",contentType:"text/plain"});try{let d=await e.getObjectBytes(t.bucket,r);if(Buffer.from(d.body).toString()!=="ts-cloud backup destination health check")throw Error("Backup destination health object was corrupted.")}finally{await e.deleteObject(t.bucket,r)}}async upload(t,e){if(!t.bucket)throw Error("S3 destination has no configured bucket.");let r=await this.client(t),d=ri(e.body),E=t.encryption!=="provider"?await this.secrets.resolve(t.encryptionKeyRef):void 0,n=E?e.resume?.encryptionIv?Buffer.from(e.resume.encryptionIv,"base64url"):il(12):void 0,c=E?hX(e.body,E,n):Buffer.from(e.body),_=ri(c),T=`${t.prefix?`${t.prefix.replace(/\/$/,"")}/`:""}${e.key.replace(/^\/+/,"")}`,i=e.contentType??"application/octet-stream",h={"ts-cloud-format":"v1","ts-cloud-sha256":_.slice(7),"ts-cloud-encrypted":E?"true":"false"};if(e.resume&&e.resume.key!==T)throw Error("Multipart checkpoint does not match the requested backup key.");if(e.resume&&E&&!e.resume.encryptionIv)throw Error("Encrypted multipart checkpoint has no resumable envelope state.");if(e.resume&&E&&e.resume.plaintextChecksum!==d)throw Error("Encrypted multipart checkpoint does not match the backup payload.");if(c.length<this.multipartThreshold)await r.putObject({bucket:t.bucket,key:T,body:c,contentType:i,metadata:h});else{let R=e.resume?void 0:await r.createMultipartUpload(t.bucket,T,{contentType:i,metadata:h}),N=e.resume??{uploadId:R.UploadId,key:T,parts:[],bytesUploaded:0,encryptionIv:n?.toString("base64url"),plaintextChecksum:d},A=new Map(N.parts.map((f)=>[f.PartNumber,f])),u=Math.ceil(c.length/this.partSize);for(let f=0;f<u;f++){let w=f+1;if(!A.has(w)){let I=f*this.partSize,a=await r.uploadPart(t.bucket,T,N.uploadId,w,c.subarray(I,Math.min(c.length,I+this.partSize)));A.set(w,{PartNumber:w,ETag:a.ETag})}N.parts=[...A.values()].sort((I,a)=>I.PartNumber-a.PartNumber),N.bytesUploaded=Math.min(c.length,w*this.partSize),e.checkpoint?.(N)}await r.completeMultipartUpload(t.bucket,T,N.uploadId,N.parts)}return{uri:`s3://${t.bucket}/${T}`,key:T,sizeBytes:c.length,checksum:_,manifest:{format:"ts-cloud-backup-v1",encrypted:!!E,plaintextChecksum:d,storageChecksum:_,contentType:i}}}async download(t,e){if(!t.bucket)throw Error("S3 destination has no configured bucket.");let r=await this.client(t),d=await r.getObjectBytes(t.bucket,e.key),E=Buffer.from(d.body);if(ri(E)!==e.checksum)throw Error("Backup checksum verification failed; object is corrupt.");let n=e.manifest.encrypted?RX(E,await this.secrets.resolve(t.encryptionKeyRef)):E;if(ri(n)!==e.manifest.plaintextChecksum)throw Error("Backup plaintext checksum verification failed.");return n}async abortPartial(t,e){if(!t.bucket)throw Error("S3 destination has no configured bucket.");await(await this.client(t)).abortMultipartUpload(t.bucket,e.key,e.uploadId)}async delete(t,e){if(!t.bucket)throw Error("S3 destination has no configured bucket.");await(await this.client(t)).deleteObject(t.bucket,e)}}import{createHash as NX}from"node:crypto";var AX=(t)=>`sha256:${NX("sha256").update(t).digest("hex")}`;class di{store;queue;now;constructor(t,e,r=()=>new Date){this.store=t;this.queue=e;this.now=r}enqueueBackup(t,e=this.now().toISOString(),r){if(!t.enabled)throw Error("Backup policy is disabled.");let d=this.store.createJob({projectId:t.projectId,policyId:t.id,kind:"backup",status:"queued",idempotencyKey:`backup:${t.id}:${e}`,target:{scheduledFor:e},cancellability:"checkpoint_only",progress:{phase:"queued"}});if(!d.operationId){let E=this.queue.enqueue({projectId:t.projectId,environmentId:t.environmentId,resourceId:t.resourceId,actorId:r,kind:"backup.run",input:{backupJobId:d.id},lockKey:t.dataServiceId?`data-service:${t.dataServiceId}`:t.resourceId?`resource:${t.resourceId}`:`backup-policy:${t.id}`,providerKey:"backup",maxAttempts:3,timeoutSeconds:14400,retryClasses:["provider_transient"],resumePolicy:"requeue"});return this.store.updateJob(d.id,{operationId:E.operation.id})}return d}enqueueDue(t=this.now()){return this.store.duePolicies(t).map((e)=>{let r=e.nextRunAt;return this.store.advancePolicy(e.id,r),this.enqueueBackup(e,r)})}enqueueVerification(t){let e=this.store.createJob({projectId:t.projectId,policyId:t.policyId,recoveryPointId:t.id,kind:"verify",status:"queued",idempotencyKey:`verify:${t.id}:${t.checksum}`,target:{},cancellability:"safe",progress:{phase:"queued"}});if(!e.operationId){let r=this.queue.enqueue({projectId:t.projectId,resourceId:t.resourceId,kind:"backup.verify",input:{backupJobId:e.id},lockKey:`recovery-point:${t.id}`,providerKey:"backup",maxAttempts:2,timeoutSeconds:7200,retryClasses:["provider_transient"],resumePolicy:"requeue"});return this.store.updateJob(e.id,{operationId:r.operation.id})}return e}planRestore(t,e){if(t.status!=="available")throw Error("Only available recovery points can be restored.");if(t.verificationState!=="verified")throw Error("Restore requires a verified recovery point.");if(e.mode==="in_place"){if(!e.recentAuth)throw Error("In-place restore requires recent authentication.");if(e.confirm!==e.targetName)throw Error(`Type ${e.targetName} to confirm in-place restore.`);if(!e.downtimeAcknowledged)throw Error("In-place restore requires downtime acknowledgement.");let r=e.safetyBackupId?this.store.getRecoveryPoint(e.safetyBackupId):void 0;if(!r||r.id===t.id||r.status!=="available"||r.verificationState!=="verified"||r.resourceId!==t.resourceId||r.dataServiceId!==t.dataServiceId)throw Error("In-place restore requires a distinct verified safety backup for the same target.")}return{point:t,mode:e.mode,target:{...e.target,inPlace:e.mode==="in_place",restoreMode:e.mode},warnings:e.mode==="in_place"?["The target is locked against deployments and backup work.","Downtime and data replacement are expected.","Provider cancellation may stop only at a checkpoint."]:["An isolated target is created and health-validated before cleanup."]}}enqueueRestore(t,e){let r=this.planRestore(t,e),d=e.drill?"drill":"restore",E=AX(JSON.stringify({point:t.id,mode:e.mode,target:e.target,safety:e.safetyBackupId,drill:!!e.drill})),n=this.store.createJob({projectId:t.projectId,policyId:t.policyId,recoveryPointId:t.id,kind:d,status:"queued",idempotencyKey:`${d}:${E}`,target:r.target,restoreMode:r.mode,cancellability:"checkpoint_only",safetyBackupId:e.safetyBackupId,progress:{phase:"queued",warnings:r.warnings}});if(!n.operationId){let c=this.queue.enqueue({projectId:t.projectId,resourceId:t.resourceId,actorId:e.actorId,kind:e.drill?"backup.drill":"backup.restore",input:{backupJobId:n.id},lockKey:t.dataServiceId?`data-service:${t.dataServiceId}`:t.resourceId?`resource:${t.resourceId}`:`recovery-point:${t.id}`,providerKey:"backup",maxAttempts:1,timeoutSeconds:14400,retryClasses:[],resumePolicy:"fail"});return this.store.updateJob(n.id,{operationId:c.operation.id})}return n}enqueueRetention(t=this.now()){return this.store.retentionCandidates(t).map((e)=>{let r=this.store.createJob({projectId:e.projectId,policyId:e.policyId,recoveryPointId:e.id,kind:"cleanup",status:"queued",idempotencyKey:`cleanup:${e.id}:${e.expiresAt}`,target:{},cancellability:"safe",progress:{phase:"queued"}});if(!r.operationId){let d=this.queue.enqueue({projectId:e.projectId,resourceId:e.resourceId,kind:"backup.cleanup",input:{backupJobId:r.id},lockKey:`recovery-point:${e.id}`,providerKey:"backup",maxAttempts:3,timeoutSeconds:7200,retryClasses:["provider_transient"],resumePolicy:"requeue"});return this.store.updateJob(r.id,{operationId:d.operation.id})}return r})}}function Sl(t){let e=t.now??(()=>new Date),r=new di(t.store,t.queue,e),d=(_)=>{let T=_.recoveryPointId?t.store.getRecoveryPoint(_.recoveryPointId):void 0,i=_.policyId?t.store.getPolicy(_.policyId):T?.policyId?t.store.getPolicy(T.policyId):void 0;if(!i)throw Error("Backup policy was not found.");let h=t.store.getDestination(T?.destinationId??i.destinationId),R=t.resolveSource(i);if(!h)throw Error("Backup destination was not found.");if(!R)throw Error(`No ${i.resourceKind} backup adapter is configured.`);return{point:T,policy:i,destination:h,source:R}},E=(_)=>{let T=_.operation.input,i=t.store.getJob(String(T.backupJobId??""));if(!i)throw Error("Backup job was not found.");return t.store.updateJob(i.id,{status:"running",startedAt:i.startedAt??e().toISOString(),progress:{...i.progress,phase:"running"}}),i},n=(_,T)=>{let i=t.store.getJob(_.id)??_;t.store.updateJob(_.id,{status:"failed",finishedAt:e().toISOString(),error:T instanceof Error?T.message:String(T),progress:{...i.progress,phase:"failed"}})};return{"backup.run":async(_)=>{let T=E(_);try{let{policy:i,destination:h,source:R}=d(T),N=await R.create(i,_),A=t.resolveDestination(h),u=N.mode==="object"?await(async()=>{if(!A)throw Error("Backup destination adapter is not configured.");let a=t.store.getJob(T.id)?.progress,P=a?.multipart,j=P&&typeof P==="object"&&!Array.isArray(P)&&typeof P.uploadId==="string"&&typeof P.key==="string"&&Array.isArray(P.parts)?P:void 0;return A.upload(h,{key:N.key,body:N.body,contentType:N.contentType,resume:j,checkpoint:(H)=>{_.checkpoint("uploading",`Uploaded ${Number(H.bytesUploaded??0)} backup bytes.`),t.store.updateJob(T.id,{progress:{phase:"uploading",multipart:{...H}}})}})})():{uri:N.uri,key:N.uri,sizeBytes:N.sizeBytes,checksum:N.checksum,manifest:{format:"ts-cloud-backup-v1",encrypted:!1,plaintextChecksum:N.checksum,storageChecksum:N.checksum,contentType:"application/provider-snapshot"}},f=i.retention.expireAfterDays?new Date(e().getTime()+i.retention.expireAfterDays*86400000).toISOString():void 0,w=t.store.getJob(T.id)?.startedAt,I=t.store.createRecoveryPoint({projectId:i.projectId,policyId:i.id,destinationId:h.id,resourceId:i.resourceId,dataServiceId:i.dataServiceId,backupJobId:T.id,kind:i.resourceKind,pointInTime:e().toISOString(),uri:u.uri,sizeBytes:u.sizeBytes,checksum:u.checksum,manifest:{...N.manifest,...u.manifest,storageKey:u.key},toolVersion:N.toolVersion,engineVersion:N.engineVersion,expiresAt:f,lockedUntil:h.immutability.defaultRetentionDays?new Date(e().getTime()+h.immutability.defaultRetentionDays*86400000).toISOString():void 0,held:!1,pinned:!1,status:"available",verificationState:"unverified",durationMs:Math.max(0,e().getTime()-new Date(w??e().toISOString()).getTime())});if(N.mode==="external"&&h.provider==="aws_backup")t.store.recordDestinationTest(h.id,{ok:!0});return t.store.updateJob(T.id,{status:"succeeded",recoveryPointId:I.id,finishedAt:e().toISOString(),progress:{phase:"stored",recoveryPointId:I.id}}),r.enqueueVerification(I),{backupJobId:T.id,recoveryPointId:I.id}}catch(i){let h=t.store.getJob(T.id),R=h?.progress.multipart,N=(()=>{try{return d(T)}catch{return}})();if(N?.destination.provider==="aws_backup")t.store.recordDestinationTest(N.destination.id,{ok:!1,error:i instanceof Error?i.message:String(i)});let A=!1;if(R&&typeof R==="object"&&!Array.isArray(R)&&N){let u=t.resolveDestination(N.destination);if(A=!0,u?.abortPartial)try{await u.abortPartial(N.destination,R),A=!1,t.store.updateJob(T.id,{progress:{...h.progress,partialCleanup:"aborted"}})}catch{t.store.updateJob(T.id,{progress:{...h.progress,partialCleanup:"required"}})}}if(A)t.store.updateJob(T.id,{status:"cleanup_required",finishedAt:e().toISOString(),error:i instanceof Error?i.message:String(i),progress:{...t.store.getJob(T.id)?.progress??{},phase:"cleanup_required"}});else n(T,i);throw i}},"backup.verify":async(_)=>{let T=E(_);try{let{point:i,destination:h,source:R}=d(T);if(!i)throw Error("Recovery point was not found.");t.store.updateRecoveryPoint(i.id,{verificationState:"verifying"});let N;if(i.uri.startsWith("s3:")){let A=t.resolveDestination(h);if(!A)throw Error("Backup destination adapter is not configured.");let u=await A.download(h,{key:String(i.manifest.storageKey??""),checksum:i.checksum,manifest:i.manifest}),f=R.verify?await R.verify(i,u,_):{};N={bytes:u.length,checksum:i.checksum,...f}}else if(R.verifyExternal)N=await R.verifyExternal(i,_);else throw Error("External recovery point verification is not supported.");return t.store.updateRecoveryPoint(i.id,{verificationState:"verified",verifiedAt:e().toISOString(),manifest:{...i.manifest,verification:N}}),t.store.updateJob(T.id,{status:"succeeded",finishedAt:e().toISOString(),progress:{phase:"verified",evidence:N}}),{backupJobId:T.id,recoveryPointId:i.id,evidence:N}}catch(i){if(T.recoveryPointId)t.store.updateRecoveryPoint(T.recoveryPointId,{verificationState:/checksum|corrupt|authentic/i.test(i instanceof Error?i.message:String(i))?"corrupt":"failed"});throw n(T,i),i}},"backup.restore":async(_)=>c(_,!1),"backup.drill":async(_)=>c(_,!0),"backup.cleanup":async(_)=>{let T=E(_);try{let{point:i,destination:h,source:R}=d(T);if(!i)throw Error("Recovery point was not found.");if(!t.store.retentionCandidates(e()).some((N)=>N.id===i.id))throw Error("Recovery point is held, pinned, locked, or in active use.");if(t.store.updateRecoveryPoint(i.id,{status:"deleting"}),i.uri.startsWith("s3:")){let N=t.resolveDestination(h);if(!N)throw Error("Destination cleanup is unavailable.");await N.delete(h,String(i.manifest.storageKey??""))}else if(R.deleteExternal)await R.deleteExternal(i,_);else throw Error("External recovery point cleanup is unavailable.");return t.store.updateRecoveryPoint(i.id,{status:"deleted"}),t.store.updateJob(T.id,{status:"succeeded",finishedAt:e().toISOString(),progress:{phase:"deleted"}}),{backupJobId:T.id,recoveryPointId:i.id,deleted:!0}}catch(i){throw n(T,i),i}}};async function c(_,T){let i=E(_);try{let{point:h,policy:R,destination:N,source:A}=d(i);if(!h)throw Error("Recovery point was not found.");if(T&&!A.cleanup)throw Error("This backup source cannot safely clean a recovery drill target.");let u=h.uri.startsWith("s3:")?t.resolveDestination(N):void 0,f=u?await u.download(N,{key:String(h.manifest.storageKey??""),checksum:h.checksum,manifest:h.manifest}):void 0,w=await A.restore(h,f,i.target,_),I=A.validateHealth?await A.validateHealth({...i.target,...w},_):{healthy:!0,mode:"adapter"},a=t.validateHealth?await t.validateHealth(R,i.target):{healthy:!0,mode:"not_configured"},P={...I,healthy:I.healthy===!0&&a.healthy===!0,configured:a};if(P.healthy!==!0)throw Error("Restored target did not pass its configured health check.");if(T&&A.cleanup)await A.cleanup({...i.target,provider:h.manifest.provider??null},_);return t.store.updateJob(i.id,{status:"succeeded",finishedAt:e().toISOString(),healthResult:P,progress:{phase:T?"drill_cleaned":"restored",restored:w}}),{backupJobId:i.id,recoveryPointId:h.id,restored:w,health:P,cleaned:T}}catch(h){let R=(()=>{try{return d(i)}catch{return}})(),N=h instanceof Error?h.message:String(h),A=!1;if(T&&R?.source.cleanup)try{await R.source.cleanup({...i.target,provider:R.point?.manifest.provider??null},_)}catch{A=!0}if(A)t.store.updateJob(i.id,{status:"cleanup_required",finishedAt:e().toISOString(),error:N,progress:{...i.progress,phase:"cleanup_required"}});else n(i,h);throw h}}}Pn();import{createHash as LX}from"node:crypto";var uX=(t)=>`sha256:${LX("sha256").update(t).digest("hex")}`;class rN{dataServices;client;constructor(t,e=new nd){this.dataServices=t;this.client=e}service(t){let e=t.dataServiceId?this.dataServices.get(t.dataServiceId):void 0;if(!e||!["aws_rds","aws_aurora"].includes(e.provider))throw Error("Managed database backup policy requires an RDS or Aurora data service.");return e}async waitForSnapshot(t,e,r){for(;;){r.throwIfCancellationRequested?.(),r.heartbeat?.();let d=t==="aws_aurora"?(await this.client.describeDBClusterSnapshots({DBClusterSnapshotIdentifier:e})).DBClusterSnapshots[0]:(await this.client.describeDBSnapshots({DBSnapshotIdentifier:e})).DBSnapshots?.[0];if(!d)throw Error("Provider snapshot was not found.");let E=d,n=String(E.Status??E.DBSnapshotStatus??"unknown");if(r.checkpoint?.("provider_snapshot",`Database snapshot ${e} is ${n}.`),n==="available")return E;if(["deleted","deleting","failed"].includes(n))throw Error(`Provider snapshot ${e} failed with state ${n}.`);await Bun.sleep(5000)}}async create(t,e){let r=this.service(t),d=String(e.operation?.id??new Date().toISOString()).replace(/[^A-Za-z0-9]/g,"").slice(0,20),E=`${r.placement.slice(0,42).replace(/-+$/,"")}-${d}`;if(r.provider==="aws_aurora")await this.client.createDBClusterSnapshot(r.placement,E);else await this.client.createDBSnapshot({DBInstanceIdentifier:r.placement,DBSnapshotIdentifier:E});await this.waitForSnapshot(r.provider,E,e);let n=`${r.provider}:${r.placement}:${E}`;return{mode:"external",uri:`aws-backup:${n}`,checksum:uX(n),sizeBytes:0,manifest:{provider:r.provider,sourceId:r.placement,snapshotId:E,plan:r.plan,engine:r.engine},engineVersion:r.engineVersion,toolVersion:"aws-rds-api-2014-10-31"}}async verifyExternal(t,e){let r=String(t.manifest.snapshotId??""),d=String(t.manifest.provider??"");if(!r)throw Error("Snapshot recovery point has no snapshot ID.");let E=await this.waitForSnapshot(d,r,e),n=String(E.Status??E.DBSnapshotStatus??"unknown");return{snapshotId:r,status:n,encrypted:E.Encrypted??E.StorageEncrypted??!0}}async restore(t,e,r,d){let E=String(r.targetId??""),n=String(t.manifest.snapshotId??""),c=String(t.manifest.provider??"");if(!/^[a-z0-9][a-z0-9-]{1,62}$/.test(E))throw Error("Managed restore requires a valid distinct targetId.");if(E===t.manifest.sourceId)throw Error("Managed restore target must differ from its source.");if(c==="aws_aurora"){let _=t.manifest.engine==="postgres"?"aurora-postgresql":"aurora-mysql";await this.client.restoreDBClusterFromSnapshot({DBClusterIdentifier:E,SnapshotIdentifier:n,Engine:_,EngineVersion:t.engineVersion,DeletionProtection:!0,ServerlessV2ScalingConfiguration:{MinCapacity:Number(r.minCapacity)||0.5,MaxCapacity:Number(r.maxCapacity)||4}}),await this.client.createDBInstance({DBInstanceIdentifier:`${E}-writer-1`,DBClusterIdentifier:E,DBInstanceClass:String(r.plan??t.manifest.plan??"db.serverless"),Engine:_,PubliclyAccessible:!1})}else await this.client.restoreDBInstanceFromDBSnapshot({DBInstanceIdentifier:E,DBSnapshotIdentifier:n,DBInstanceClass:String(r.plan??t.manifest.plan??""),PubliclyAccessible:!1,DeletionProtection:!0,Tags:[{Key:"managed-by",Value:"ts-cloud-restore"}]});return{targetId:E,provider:c,status:"creating",isolated:!0}}async validateHealth(t,e){let r=String(t.targetId??""),d=String(t.provider??"");for(;;){e.throwIfCancellationRequested?.(),e.heartbeat?.();let E=d==="aws_aurora"?(await this.client.describeDBClusters({DBClusterIdentifier:r})).DBClusters?.[0]:(await this.client.describeDBInstances({DBInstanceIdentifier:r})).DBInstances?.[0];if(!E)throw Error("Restored managed database was not found.");let n=String(E.Status??E.DBInstanceStatus??"unknown");if(e.checkpoint?.("provider_restore",`Restored database ${r} is ${n}.`),n==="available")return{healthy:!0,targetId:r,provider:d,status:n};if(["deleted","deleting","failed","incompatible-restore"].includes(n))throw Error(`Restored managed database ${r} failed with state ${n}.`);await Bun.sleep(5000)}}async cleanup(t,e){let r=String(t.targetId??""),d=String(t.provider??"");if(!r)throw Error("Restore cleanup target is required.");if(d==="aws_aurora")await this.client.deleteDBInstance({DBInstanceIdentifier:`${r}-writer-1`,SkipFinalSnapshot:!0}),await this.client.modifyDBCluster({DBClusterIdentifier:r,DeletionProtection:!1,ApplyImmediately:!0}),await this.client.deleteDBCluster(r);else await this.client.modifyDBInstance({DBInstanceIdentifier:r,DeletionProtection:!1,ApplyImmediately:!0}),await this.client.deleteDBInstance({DBInstanceIdentifier:r,SkipFinalSnapshot:!0,DeleteAutomatedBackups:!0})}async deleteExternal(t,e){let r=String(t.manifest.snapshotId??"");if(t.manifest.provider==="aws_aurora")await this.client.deleteDBClusterSnapshot(r);else await this.client.deleteDBSnapshot(r)}}var Pe=(t,e="none",r=!1)=>({supported:!0,downtime:e,destructive:r,explanation:t}),Ce=(t)=>({supported:!1,downtime:"none",destructive:!1,explanation:t});function i_(t,e){let r=["aws_rds","aws_aurora","aws_elasticache"].includes(e),d=["server","container"].includes(e),E=["postgres","mysql","mariadb"].includes(t),n=t==="redis",c={};return c.create=e==="external"?Ce("External services can be adopted as read-only inventory."):Pe(r?"Provision through the provider API.":"Provision through the owning runtime driver.","possible"),c.observe=e==="external"?Ce("External observation requires a configured provider adapter."):Pe("Provider/runtime health and endpoint metadata are observable."),c.connect=Pe("Connection guidance uses secret references and never returns a password by default."),c.backup=E&&(r||d)?Pe(r?"Create a provider snapshot.":"Create a consistent engine-native dump.","possible"):Ce("This cache path is not a durable backup source."),c.restore=r&&E?Pe("Restore creates a reviewed provider target.","required",!0):Ce("Restore requires a configured provider restore runner."),c.restart=e==="external"?Ce("External restart requires a configured provider adapter."):Pe(r?"Provider restart/failover semantics apply.":"Restart the owning service unit.","required"),c.resize=e==="aws_elasticache"?Ce("ElastiCache resizing requires a replication-group migration runner."):r?Pe("Provider plan/storage modification may enter a maintenance window.","possible"):d?Pe("Edit host/container resources and reconcile.","required"):Ce("External resize requires a configured provider adapter."),c.version=d?Ce("Runtime version upgrades require an explicit image migration runner."):r&&e!=="aws_elasticache"?Pe(E?"Major versions require compatibility preflight and backup.":"Engine upgrades require a maintenance window.","required"):Ce("External upgrades require a configured provider adapter."),c.rotate=e==="aws_elasticache"||e==="external"||d&&!E&&!n?Ce("Credential rotation is not available for this provider/engine path."):Pe("Rotate through the secret backend, update the engine, then flag dependent releases."),c.expose=d?Ce("Direct container publishing is refused; use a reviewed firewall and proxy policy."):e==="aws_rds"?Pe("Exposure is reconciled through security groups; public access defaults off."):Ce("Exposure changes require a provider-specific network runner."),c.delete=e==="external"?Ce("External deletion requires a configured provider adapter."):Pe(r?"Final snapshot is supported where the provider allows it.":"A final engine backup is required unless explicitly retained.","required",!0),c.logs=d?Pe("Read bounded service logs from the runtime."):Ce("Provider log export is not configured for this adapter."),c.slow_queries=d&&E?Pe("Read bounded runtime logs after engine slow-query logging is enabled."):Ce("A slow-query log runner is not configured for this provider."),c.users=d&&E?Pe("Logical users can be listed; creation requires a referenced secondary credential."):Ce("User management requires an engine connection runner."),c.databases=d&&E?Pe("Logical databases can be listed, created, and confirmation-gated for deletion."):Ce("Logical database management requires an engine connection runner."),{actions:c,endpointTypes:r?["internal","external","tunnel"]:["internal","tunnel"],metrics:n?["connections","memory","evictions","hit_rate","latency"]:["connections","cpu","storage","read_latency","write_latency","iops"]}}var Bn=(t)=>t==null?void 0:String(t),ni=(t)=>Number(t)===1,Ei=(t)=>{try{return JSON.parse(String(t))}catch{return{}}};function Nl(t){return{id:String(t.id),organizationId:String(t.organization_id),projectId:String(t.project_id),environmentId:Bn(t.environment_id),resourceId:Bn(t.resource_id),name:String(t.name),engine:String(t.engine),provider:String(t.provider),placement:String(t.placement),engineVersion:Bn(t.engine_version),plan:String(t.plan),storageGb:t.storage_gb==null?void 0:Number(t.storage_gb),highAvailability:ni(t.high_availability),publicExposure:ni(t.public_exposure),allowedCidrs:Ei(t.allowed_cidrs),desiredState:Ei(t.desired_state),observedState:Ei(t.observed_state),capabilities:Ei(t.capabilities),credentialRef:Bn(t.credential_ref),status:String(t.status),origin:String(t.origin),managementEnabled:ni(t.management_enabled),ownerActorId:Bn(t.owner_actor_id),version:Number(t.version),createdAt:String(t.created_at),updatedAt:String(t.updated_at)}}class dN{controlPlane;now;constructor(t,e=()=>new Date){this.controlPlane=t;this.now=e}create(t){if(!/^[a-z0-9][a-z0-9-]{1,62}$/.test(t.name))throw Error("Data service names must be 2-63 lowercase letters, numbers, or dashes.");if(t.publicExposure&&(!t.allowedCidrs.length||t.allowedCidrs.includes("0.0.0.0/0")))throw Error("Public exposure requires explicit narrow CIDRs; 0.0.0.0/0 is refused.");let e=crypto.randomUUID(),r=this.now().toISOString(),d=i_(t.engine,t.provider);return this.controlPlane.database.run("INSERT INTO data_services (id,organization_id,project_id,environment_id,resource_id,name,engine,provider,placement,engine_version,plan,storage_gb,high_availability,public_exposure,allowed_cidrs,desired_state,observed_state,capabilities,credential_ref,status,origin,management_enabled,owner_actor_id,version,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",[e,t.organizationId,t.projectId,t.environmentId??null,t.resourceId??null,t.name,t.engine,t.provider,t.placement,t.engineVersion??null,t.plan,t.storageGb??null,t.highAvailability?1:0,t.publicExposure?1:0,JSON.stringify(t.allowedCidrs),JSON.stringify(t.desiredState),JSON.stringify(t.observedState),JSON.stringify(d),t.credentialRef??null,t.status,t.origin,t.managementEnabled?1:0,t.ownerActorId??null,1,r,r]),this.get(e)}get(t){let e=this.controlPlane.database.query("SELECT * FROM data_services WHERE id=?").get(t);return e?Nl(e):void 0}list(t,e){return this.controlPlane.database.query(`SELECT * FROM data_services WHERE project_id=?${e?" AND environment_id=?":""} ORDER BY name`).all(t,...e?[e]:[]).map(Nl)}update(t,e,r){let d=this.get(t);if(!d)throw Error("Data service was not found.");if(d.version!==e)throw Error("Data service changed; refresh before retrying.");let E={...d,...r};if(E.publicExposure&&(!E.allowedCidrs.length||E.allowedCidrs.includes("0.0.0.0/0")))throw Error("Public exposure requires explicit narrow CIDRs; 0.0.0.0/0 is refused.");if(this.controlPlane.database.run("UPDATE data_services SET plan=?,storage_gb=?,engine_version=?,high_availability=?,public_exposure=?,allowed_cidrs=?,desired_state=?,observed_state=?,status=?,management_enabled=?,credential_ref=?,version=version+1,updated_at=? WHERE id=? AND version=?",[E.plan,E.storageGb??null,E.engineVersion??null,E.highAvailability?1:0,E.publicExposure?1:0,JSON.stringify(E.allowedCidrs),JSON.stringify(E.desiredState),JSON.stringify(E.observedState),E.status,E.managementEnabled?1:0,E.credentialRef??null,this.now().toISOString(),t,e]).changes!==1)throw Error("Data service changed; refresh before retrying.");return this.get(t)}credential(t){let e=this.controlPlane.database.query("SELECT * FROM data_service_credentials WHERE service_id=? ORDER BY version DESC LIMIT 1").get(t);return e?{id:String(e.id),serviceId:String(e.service_id),username:String(e.username),secretRef:String(e.secret_ref),version:Number(e.version),createdAt:String(e.created_at),rotatedAt:Bn(e.rotated_at)}:void 0}saveCredential(t,e,r){let d=this.credential(t),E=d?.id??crypto.randomUUID(),n=this.now().toISOString();return this.controlPlane.database.run("INSERT INTO data_service_credentials (id,service_id,username,secret_ref,version,created_at,rotated_at) VALUES (?,?,?,?,?,?,?) ON CONFLICT(service_id,username) DO UPDATE SET secret_ref=excluded.secret_ref,version=data_service_credentials.version+1,rotated_at=excluded.rotated_at",[E,t,e,r,d?.version??1,d?.createdAt??n,d?n:null]),this.credential(t)}addDependency(t){let e=this.now().toISOString();return this.controlPlane.database.run("INSERT INTO data_service_dependencies (service_id,resource_id,secret_ref,requires_redeploy,created_at) VALUES (?,?,?,?,?) ON CONFLICT(service_id,resource_id) DO UPDATE SET secret_ref=excluded.secret_ref,requires_redeploy=excluded.requires_redeploy",[t.serviceId,t.resourceId,t.secretRef,t.requiresRedeploy?1:0,e]),{...t,createdAt:e}}dependencies(t){return this.controlPlane.database.query("SELECT * FROM data_service_dependencies WHERE service_id=? ORDER BY resource_id").all(t).map((e)=>({serviceId:String(e.service_id),resourceId:String(e.resource_id),secretRef:String(e.secret_ref),requiresRedeploy:ni(e.requires_redeploy),createdAt:String(e.created_at)}))}removeDependency(t,e){return this.controlPlane.database.run("DELETE FROM data_service_dependencies WHERE service_id=? AND resource_id=?",[t,e]).changes===1}remove(t){this.controlPlane.database.run("DELETE FROM data_services WHERE id=?",[t])}}function Al(){let e=crypto.getRandomValues(new Uint8Array(40));return Array.from(e,(r)=>"ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz23456789!@#$%^&*_-+="[r%69]).join("")}function Ll(t,e){return e.map((r)=>{let d=r.type==="tunnel"?"127.0.0.1":r.host,E=t.engine==="redis"?`redis-cli -h ${d} -p ${r.port}${r.tls?" --tls":""}`:t.engine==="postgres"?`psql "host=${d} port=${r.port} dbname=${r.database??"postgres"} sslmode=${r.tls?"require":"disable"}"`:t.engine==="mongodb"?`mongosh "mongodb://${d}:${r.port}/${r.database??"admin"}${r.tls?"?tls=true":""}"`:t.engine==="libsql"?`turso db shell ${r.tls?"https":"http"}://${d}:${r.port}`:`mysql --host=${d} --port=${r.port} --database=${r.database??"mysql"} --ssl-mode=${r.tls?"REQUIRED":"DISABLED"}`;return{type:r.type,command:E,secretRef:t.credentialRef}})}class ci{store;queue;secrets;constructor(t,e,r){this.store=t;this.queue=e;this.secrets=r}async create(t){let e,r;if(t.provider!=="aws_elasticache"){let d=t.username??"app",E=Al();r=`secret://data-services/${t.projectId}/${t.name}/${d}`,await this.secrets.put(r,E),e={username:d,password:E,secretRef:r}}try{let d=this.store.create({...t,credentialRef:r,status:"planning"});if(e)this.store.saveCredential(d.id,e.username,e.secretRef);let E=this.enqueue(d,"create",{});return{service:d,credential:e,operationId:E}}catch(d){if(r)await this.secrets.remove(r);throw d}}plan(t,e,r={}){let d=t.capabilities.actions[e],E=e==="version"&&String(r.engineVersion??"").split(".")[0]!==String(t.engineVersion??"").split(".")[0];return{service:t,action:e,capability:d,changes:r,preflight:{backupRequired:["delete","restore"].includes(e)||E,compatibilityRequired:E,typedConfirmation:d.destructive?t.name:void 0,retentionChoiceRequired:e==="delete"},warnings:[...d.downtime!=="none"?[`Downtime is ${d.downtime}.`]:[],...t.origin==="adopted"&&!t.managementEnabled?["Adopted resource is read-only until management is explicitly enabled."]:[]]}}enqueue(t,e,r,d){let E=this.plan(t,e,r);if(!E.capability.supported)throw Error(E.capability.explanation);if(t.origin==="adopted"&&!t.managementEnabled&&e!=="observe")throw Error("Adopted resources remain read-only until management is explicitly enabled.");if(E.preflight.typedConfirmation&&r.confirm!==E.preflight.typedConfirmation)throw Error(`Type ${E.preflight.typedConfirmation} to confirm ${e}.`);if(E.preflight.retentionChoiceRequired&&!["final_backup","retain"].includes(String(r.retention??"")))throw Error("Deletion requires retention final_backup or retain.");if(E.preflight.compatibilityRequired&&(r.compatibilityReviewed!==!0||!r.backupId))throw Error("Major version changes require compatibilityReviewed=true and a backupId.");if(e==="restore"){let n=String(r.backupId??""),c=String(r.targetId??"");if(!n||!c)throw Error("Restore requires both backupId and targetId.");if(c===t.placement)throw Error("Restore targetId must differ from the source placement.");if(!/^[a-z0-9][a-z0-9-]{1,62}$/.test(c))throw Error("Restore targetId must be 2-63 lowercase letters, numbers, or dashes.")}return this.queue.enqueue({projectId:t.projectId,environmentId:t.environmentId,resourceId:t.resourceId,actorId:d,kind:"data_service.action",input:{serviceId:t.id,action:e,...r},lockKey:`data-service:${t.id}`,providerKey:t.provider,maxAttempts:3,timeoutSeconds:7200,retryClasses:["provider_transient"],resumePolicy:"requeue"}).operation.id}async rotate(t,e,r){let d=this.store.credential(t.id);if(!d)throw Error("Data service credential metadata was not found.");let E=Al(),n=`${d.secretRef}/v${d.version+1}`;await this.secrets.put(n,E);try{return await e.action(t,"rotate",{username:d.username,secretRef:n},E,r),this.store.saveCredential(t.id,d.username,n),this.store.update(t.id,t.version,{credentialRef:n}),{credential:{username:d.username,password:E,secretRef:n},dependencies:this.store.dependencies(t.id).filter((c)=>c.requiresRedeploy).map((c)=>c.resourceId)}}catch(c){throw await this.secrets.remove(n),c}}}function ul(t){return{"data_service.action":async(e)=>{let r=e.operation.input,d=t.store.get(String(r.serviceId??"")),E=String(r.action??"");if(!d)throw Error("Data service was not found.");let n=t.resolveAdapter(d);if(!n||n.provider!==d.provider||!n.engines.includes(d.engine))throw Error(`No ${d.provider}/${d.engine} adapter is configured.`);if(E==="rotate"){let _=await new ci(t.store,new gt(t.store.controlPlane),t.secrets).rotate(d,n,e);return{serviceId:d.id,action:E,username:_.credential.username,secretRef:_.credential.secretRef,dependencies:_.dependencies}}let c=d.credentialRef?await t.secrets.resolve(d.credentialRef):void 0;try{let _=E==="observe"?await n.observe(d):E==="create"?await n.apply(d,c,e):await n.action(d,E,r,c,e),T=t.store.get(d.id);return t.store.update(d.id,T.version,{observedState:_,status:E==="delete"?r.retention==="retain"?"retained":"deleting":"available"}),{serviceId:d.id,action:E,observed:_}}catch(_){let T=t.store.get(d.id);if(t.store.update(d.id,T.version,{status:"failed",observedState:{...T.observedState,error:_ instanceof Error?_.message:String(_)}}),/temporar|timeout|unavailable|throttl/i.test(_ instanceof Error?_.message:String(_)))throw new gr(_ instanceof Error?_.message:String(_),"provider_transient");throw _}}}}class Jn{transport;constructor(t){this.transport=t}observe(t){return this.transport.observe(t.placement)}apply(t,e){return this.transport.apply({id:t.placement,name:t.name,engine:t.engine,engineVersion:t.engineVersion??null,plan:t.plan,storageGb:t.storageGb??null,highAvailability:t.highAvailability,publicExposure:t.publicExposure,allowedCidrs:t.allowedCidrs,username:t.desiredState.username??"app",desiredState:t.desiredState},e)}action(t,e,r,d,E){return this.transport.execute(t.placement,e,{engine:t.engine,engineVersion:t.engineVersion??null,plan:t.plan,desiredState:t.desiredState,...r},d,E)}}class EN extends Jn{provider="aws_rds";engines=["postgres","mysql","mariadb"]}class nN extends Jn{provider="aws_aurora";engines=["postgres","mysql"]}class cN extends Jn{provider="aws_elasticache";engines=["redis"]}class _N extends Jn{provider="server";engines=["postgres","mysql","mariadb","redis","mongodb","libsql"]}class TN extends Jn{provider="container";engines=["postgres","mysql","mariadb","redis","mongodb","libsql"]}Pn();var ii=(t,e)=>{let r=t.desiredState;return t[e]??(r&&typeof r==="object"&&!Array.isArray(r)?r[e]:void 0)},bt=(t,e,r)=>{let d=ii(t,e);return d==null?r:String(d)},Ze=(t,e)=>{let r=ii(t,e);return r==null?void 0:Number(r)},Zd=(t,e)=>{let r=ii(t,e);return r==null?void 0:r===!0||r==="true"},Hn=(t,e)=>{let r=ii(t,e);return Array.isArray(r)?r.map(String):[]},Ti=(t,e)=>bt(e,"snapshotId")??`${t}-final-${new Date().toISOString().replace(/[^0-9]/g,"").slice(0,14)}`;function _i(t){if(!t)throw Error("RDS instance was not found.");return{providerId:t.DBInstanceIdentifier??null,status:t.DBInstanceStatus??"unknown",engine:t.Engine??null,engineVersion:t.EngineVersion??null,plan:t.DBInstanceClass??null,storageGb:t.AllocatedStorage??null,highAvailability:t.MultiAZ??!1,publicExposure:t.PubliclyAccessible??!1,endpoint:t.Endpoint?.Address??null,port:t.Endpoint?.Port??null,username:t.MasterUsername??null,database:t.DBName??null,encrypted:t.StorageEncrypted??!1}}class hN{client;constructor(t=new nd){this.client=t}async observe(t){return _i(await this.client.describeDBInstance(t))}async apply(t,e){let r=String(t.id),d=await this.client.createDBInstance({DBInstanceIdentifier:r,DBInstanceClass:String(t.plan),Engine:String(t.engine),MasterUsername:bt(t,"username","app"),MasterUserPassword:e,DBName:bt(t,"database"),AllocatedStorage:Ze(t,"storageGb"),VpcSecurityGroupIds:Hn(t,"securityGroupIds"),DBSubnetGroupName:bt(t,"subnetGroup"),BackupRetentionPeriod:Ze(t,"backupRetentionDays")??7,MultiAZ:Zd(t,"highAvailability"),EngineVersion:bt(t,"engineVersion"),PubliclyAccessible:Zd(t,"publicExposure")??!1,StorageType:bt(t,"storageType","gp3"),StorageEncrypted:!0,KmsKeyId:bt(t,"kmsKeyId"),DeletionProtection:!0,Tags:[{Key:"managed-by",Value:"ts-cloud"}]});return _i(d.DBInstance)}async execute(t,e,r,d,E){if(e==="observe")return this.observe(t);if(e==="restart")return await this.client.rebootDBInstance({DBInstanceIdentifier:t}),{status:"rebooting"};if(e==="backup"){let n=Ti(t,r);return await this.client.createDBSnapshot({DBInstanceIdentifier:t,DBSnapshotIdentifier:n}),{status:"snapshotting",snapshotId:n}}if(e==="restore"){let n=String(r.targetId),c=await this.client.restoreDBInstanceFromDBSnapshot({DBInstanceIdentifier:n,DBSnapshotIdentifier:String(r.backupId),DBInstanceClass:bt(r,"plan"),DBSubnetGroupName:bt(r,"subnetGroup"),MultiAZ:Zd(r,"highAvailability"),PubliclyAccessible:!1,StorageType:bt(r,"storageType"),VpcSecurityGroupIds:Hn(r,"securityGroupIds"),DeletionProtection:!0,Tags:[{Key:"managed-by",Value:"ts-cloud"}]});return{..._i(c.DBInstance),sourceId:t,restoreTargetId:n}}if(e==="delete"){if(r.retention==="retain")return{status:"retained"};let n=Ti(t,r);return await this.client.modifyDBInstance({DBInstanceIdentifier:t,DeletionProtection:!1,ApplyImmediately:!0}),await this.client.deleteDBInstance({DBInstanceIdentifier:t,SkipFinalSnapshot:!1,FinalDBSnapshotIdentifier:n,DeleteAutomatedBackups:!1}),{status:"deleting",finalSnapshotId:n}}if(["resize","version","rotate","expose"].includes(e)){let n=await this.client.modifyDBInstance({DBInstanceIdentifier:t,DBInstanceClass:bt(r,"plan"),AllocatedStorage:Ze(r,"storageGb"),MasterUserPassword:e==="rotate"?d:void 0,EngineVersion:bt(r,"engineVersion"),MultiAZ:Zd(r,"highAvailability"),PubliclyAccessible:Zd(r,"publicExposure"),VpcSecurityGroupIds:Hn(r,"securityGroupIds"),ApplyImmediately:Zd(r,"applyImmediately")??!0});return _i(n.DBInstance)}throw Error(`RDS action ${e} requires an engine connection runner.`)}}function iN(t){if(!t)throw Error("Aurora cluster was not found.");return{providerId:t.DBClusterIdentifier??null,status:t.Status??"unknown",engine:t.Engine??null,engineVersion:t.EngineVersion??null,endpoint:t.Endpoint??null,readerEndpoint:t.ReaderEndpoint??null,port:t.Port??null,username:t.MasterUsername??null,database:t.DatabaseName??null,encrypted:t.StorageEncrypted??!1,highAvailability:t.MultiAZ??!0}}class RN{client;constructor(t=new nd){this.client=t}async observe(t){let e=await this.client.describeDBClusters({DBClusterIdentifier:t});return iN(e.DBClusters?.[0])}async apply(t,e){let r=String(t.id),d=String(t.engine)==="postgres"?"aurora-postgresql":"aurora-mysql";return await this.client.createDBCluster({DBClusterIdentifier:r,Engine:d,EngineVersion:bt(t,"engineVersion"),MasterUsername:bt(t,"username","app"),MasterUserPassword:e,DatabaseName:bt(t,"database"),DBSubnetGroupName:bt(t,"subnetGroup"),VpcSecurityGroupIds:Hn(t,"securityGroupIds"),BackupRetentionPeriod:Ze(t,"backupRetentionDays")??7,StorageEncrypted:!0,KmsKeyId:bt(t,"kmsKeyId"),DeletionProtection:!0,ServerlessV2ScalingConfiguration:{MinCapacity:Ze(t,"minCapacity")??0.5,MaxCapacity:Ze(t,"maxCapacity")??4}}),await this.client.createDBInstance({DBInstanceIdentifier:`${r}-writer-1`,DBClusterIdentifier:r,DBInstanceClass:String(t.plan||"db.serverless"),Engine:d,PubliclyAccessible:Zd(t,"publicExposure")??!1}),{status:"creating",providerId:r}}async execute(t,e,r,d){if(e==="observe")return this.observe(t);if(e==="restart")return await this.client.rebootDBCluster(t),{status:"rebooting"};if(e==="backup"){let E=Ti(t,r);return await this.client.createDBClusterSnapshot(t,E),{status:"snapshotting",snapshotId:E}}if(e==="restore"){let E=String(r.targetId),n=String(r.engine)==="postgres"?"aurora-postgresql":"aurora-mysql",c=await this.client.restoreDBClusterFromSnapshot({DBClusterIdentifier:E,SnapshotIdentifier:String(r.backupId),Engine:n,EngineVersion:bt(r,"engineVersion"),DBSubnetGroupName:bt(r,"subnetGroup"),VpcSecurityGroupIds:Hn(r,"securityGroupIds"),DeletionProtection:!0,ServerlessV2ScalingConfiguration:{MinCapacity:Ze(r,"minCapacity")??0.5,MaxCapacity:Ze(r,"maxCapacity")??4}});return await this.client.createDBInstance({DBInstanceIdentifier:`${E}-writer-1`,DBClusterIdentifier:E,DBInstanceClass:bt(r,"plan","db.serverless"),Engine:n,PubliclyAccessible:!1}),{...iN(c.DBCluster),sourceId:t,restoreTargetId:E}}if(e==="delete"){if(r.retention==="retain")return{status:"retained"};let E=Ti(t,r);return await this.client.modifyDBCluster({DBClusterIdentifier:t,DeletionProtection:!1,ApplyImmediately:!0}),await this.client.deleteDBCluster(t,E),{status:"deleting",finalSnapshotId:E}}if(["resize","version","rotate"].includes(e)){let E=await this.client.modifyDBCluster({DBClusterIdentifier:t,ServerlessV2ScalingConfiguration:Ze(r,"minCapacity")==null&&Ze(r,"maxCapacity")==null?void 0:{MinCapacity:Ze(r,"minCapacity")??0.5,MaxCapacity:Ze(r,"maxCapacity")??4},EngineVersion:bt(r,"engineVersion"),MasterUserPassword:e==="rotate"?d:void 0,ApplyImmediately:Zd(r,"applyImmediately")??!0});return iN(E.DBCluster)}throw Error(`Aurora action ${e} requires an engine connection runner.`)}}class SN{client;constructor(t=new T_){this.client=t}async observe(t){let e=(await this.client.describeCacheClusters(t)).CacheClusters[0];if(!e)throw Error("ElastiCache cluster was not found.");let r=e.CacheNodes?.[0]?.Endpoint;return{providerId:e.CacheClusterId,status:e.CacheClusterStatus,engine:e.Engine,engineVersion:e.EngineVersion,plan:e.CacheNodeType,nodes:e.NumCacheNodes,endpoint:r?.Address??null,port:r?.Port??null}}async apply(t){let e=await this.client.createCacheCluster({cacheClusterId:String(t.id),engine:"redis",cacheNodeType:String(t.plan),numCacheNodes:Ze(t,"nodes")??1,engineVersion:bt(t,"engineVersion"),port:Ze(t,"port"),securityGroupIds:Hn(t,"securityGroupIds"),subnetGroupName:bt(t,"subnetGroup"),tags:[{Key:"managed-by",Value:"ts-cloud"}]});return{providerId:e.CacheCluster.CacheClusterId,status:e.CacheCluster.CacheClusterStatus}}async execute(t,e,r){if(e==="observe")return this.observe(t);if(e==="restart"){let d=(await this.client.describeCacheClusters(t)).CacheClusters[0];return await this.client.rebootCacheCluster(t,d?.CacheNodes?.map((E)=>E.CacheNodeId)??["0001"]),{status:"rebooting"}}if(e==="delete"){if(r.retention==="retain")return{status:"retained"};return await this.client.deleteCacheCluster(t),{status:"deleting"}}throw Error(`ElastiCache action ${e} is not supported by this cluster mode.`)}}await Ht();import{mkdir as OX,writeFile as CX}from"node:fs/promises";import{join as lX}from"node:path";async function er(t,e,r=!1){let d=Bun.spawn(["docker",...t],{stdin:e==null?"ignore":"pipe",stdout:"pipe",stderr:"pipe"}),E=new Response(d.stdout).text(),n=new Response(d.stderr).text();if(e!=null)d.stdin.write(e),d.stdin.end();let[c,_,T]=await Promise.all([d.exited,E,n]);if(c!==0&&!r)throw Error(`Docker command failed (${c}): ${T.trim()||_.trim()}`);return{code:c,stdout:_,stderr:T}}class Ol{async ensureNetwork(t){if((await er(["network","inspect",t],void 0,!0)).code!==0)await er(["network","create","--internal",t])}async seedSecret(t,e){await er(["volume","create",t]),await er(["run","--rm","-i","-v",`${t}:/run/target`,"alpine:3.21","sh","-c","umask 077; cat > /run/target/credential"],e)}async removeVolume(t){await er(["volume","rm",t],void 0,!0)}async inspect(t){let e=await er(["inspect",t],void 0,!0);if(e.code!==0)return;return JSON.parse(e.stdout)[0]}async run(t){await er(["run",...t])}async exec(t,e,r){return(await er(["exec","-i",t,...e],r)).stdout}async update(t,e){await er(["update",...e,t])}async restart(t){await er(["restart",t])}async remove(t){await er(["rm","--force",t],void 0,!0)}async logs(t,e){let r=await er(["logs","--tail",String(Math.min(2000,Math.max(1,e))),t],void 0,!0);return`${r.stdout}${r.stderr}`.slice(-262144)}async stats(t){let e=await er(["stats","--no-stream","--format","{{json .}}",t],void 0,!0);if(e.code!==0||!e.stdout.trim())return{};let r=JSON.parse(e.stdout.trim());return{cpuPercent:String(r.CPUPerc??""),memoryUsage:String(r.MemUsage??""),memoryPercent:String(r.MemPerc??""),networkIo:String(r.NetIO??""),blockIo:String(r.BlockIO??""),pids:Number(r.PIDs??0)}}}var IX={postgres:{image:"postgres:17-alpine",port:5432,dataPath:"/var/lib/postgresql/data"},mysql:{image:"mysql:8.4",port:3306,dataPath:"/var/lib/mysql"},mariadb:{image:"mariadb:11.7",port:3306,dataPath:"/var/lib/mysql"},redis:{image:"redis:7.4-alpine",port:6379,dataPath:"/data"},mongodb:{image:"mongo:8.0",port:27017,dataPath:"/data/db"}};function cd(t,e="app"){let r=String(t??e);if(!/^[A-Za-z_][A-Za-z0-9_]{0,62}$/.test(r))throw Error("Database identifiers must be letters, numbers, or underscores.");return r}function FE(t){if(!/^[a-z0-9][a-z0-9_.-]{1,62}$/i.test(t))throw Error("Runtime placement must be a valid container identifier.");return`tscloud-data-${t.toLowerCase()}`}function DX(t,e){let r=t.desiredState;return t[e]??(r&&typeof r==="object"&&!Array.isArray(r)?r[e]:void 0)}function h_(t){return t.Config?.Labels??{}}class Wn{runtime;backupRoot;constructor(t=new Ol,e=ne(process.cwd(),"backups","data")){this.runtime=t;this.backupRoot=e}async observe(t){let e=FE(t),r=await this.runtime.inspect(e);if(!r)throw Error(`Data container ${e} was not found.`);let d=h_(r),E=await this.runtime.stats(e),n=r.NetworkSettings?.Ports??{},c=Object.values(n).flat().find(Boolean);return{providerId:e,status:r.State?.Status??"unknown",healthy:r.State?.Health?.Status??null,engine:d["ts-cloud.engine"]??null,engineVersion:d["ts-cloud.engine-version"]??null,username:d["ts-cloud.username"]??null,database:d["ts-cloud.database"]??null,endpoint:c?.HostIp||"127.0.0.1",port:c?.HostPort?Number(c.HostPort):null,image:r.Config?.Image??null,startedAt:r.State?.StartedAt??null,metrics:E}}async apply(t,e){let r=String(t.id),d=FE(r),E=String(t.engine);if(E==="libsql")throw Error("libSQL requires an explicitly configured runtime image.");let n=IX[E];if(!n)throw Error(`Unsupported runtime data engine ${E}.`);if(!e)throw Error(`${E} requires a managed credential.`);if(t.publicExposure===!0)throw Error("Container public exposure requires an external reviewed firewall policy; direct publishing is refused.");let c=cd(t.username),_=cd(DX(t,"database")),T=`${d}-secret`,i=`${d}-data`,h=E==="redis"?`appendonly yes
|
|
5540
|
+
ORDER BY rp.expires_at,rp.id`).all(t.toISOString(),t.toISOString()).map(oS),r=new Set;for(let d of new Set(e.map((E)=>E.projectId)))for(let E of this.listPolicies(d)){let n=this.listRecoveryPoints(E.projectId,E.id).filter((_)=>_.status==="available").sort((_,T)=>T.pointInTime.localeCompare(_.pointInTime));for(let _ of n.slice(0,Math.max(0,E.retention.keepLast??0)))r.add(_.id);let c=[[E.retention.hourly,(_)=>_.toISOString().slice(0,13)],[E.retention.daily,(_)=>_.toISOString().slice(0,10)],[E.retention.weekly,(_)=>{return new Date(Date.UTC(_.getUTCFullYear(),_.getUTCMonth(),_.getUTCDate()-(_.getUTCDay()+6)%7)).toISOString().slice(0,10)}],[E.retention.monthly,(_)=>_.toISOString().slice(0,7)]];for(let[_,T]of c){let i=new Set;for(let h of n){let R=T(new Date(h.pointInTime));if(i.has(R))continue;if(i.add(R),i.size<=Math.max(0,_??0))r.add(h.id)}}}return e.filter((d)=>!r.has(d.id))}coverage(t,e=this.now()){let r=new Map(this.listDestinations(t).map((d)=>[d.id,d]));return this.listPolicies(t).map((d)=>{let E=this.listRecoveryPoints(t,d.id).filter((_)=>_.status==="available"),n=E[0],c=n?(e.getTime()-new Date(n.pointInTime).getTime())/60000:Number.POSITIVE_INFINITY;return{policy:d,lastRecoveryPoint:n,missedRpo:d.enabled&&c>d.expectedRpoMinutes,unverified:E.filter((_)=>_.verificationState!=="verified").length,destinationHealthy:r.get(d.destinationId)?.status==="healthy"}})}}tr();import{createCipheriv as TX,createDecipheriv as iX,createHash as Tl,randomBytes as il}from"node:crypto";var tN=Buffer.from("TSCB1"),ri=(t)=>`sha256:${Tl("sha256").update(t).digest("hex")}`;function hl(t){return Tl("sha256").update(t).digest()}function hX(t,e,r){let d=r?Buffer.from(r):il(12);if(d.length!==12)throw Error("Backup encryption IV must contain 12 bytes.");let E=TX("aes-256-gcm",hl(e),d),n=Buffer.concat([E.update(t),E.final()]),c=E.getAuthTag();return Buffer.concat([tN,d,c,n])}function RX(t,e){let r=Buffer.from(t);if(!r.subarray(0,tN.length).equals(tN))throw Error("Backup does not contain a valid encrypted envelope.");let d=r.subarray(5,17),E=r.subarray(17,33),n=r.subarray(33),c=iX("aes-256-gcm",hl(e),d);return c.setAuthTag(E),Buffer.concat([c.update(n),c.final()])}function SX(t){let e;try{e=JSON.parse(t)}catch{throw Error("Backup destination credential must be a JSON object with accessKeyId and secretAccessKey.")}if(!e.accessKeyId||!e.secretAccessKey)throw Error("Backup destination credential requires accessKeyId and secretAccessKey.");if(e.expiresAt){let r=new Date(String(e.expiresAt));if(!Number.isFinite(r.getTime()))throw Error("Backup destination credential expiresAt must be an ISO timestamp.");if(r.getTime()<=Date.now())throw Error("Backup destination credential has expired.")}return{accessKeyId:String(e.accessKeyId),secretAccessKey:String(e.secretAccessKey),sessionToken:e.sessionToken?String(e.sessionToken):void 0}}async function Rl(t,e,r=new Date){if(!t.credentialRef)return{status:"default"};try{let d=JSON.parse(await e.resolve(t.credentialRef));if(!d.accessKeyId||!d.secretAccessKey)return{status:"invalid"};if(!d.expiresAt)return{status:"static"};let E=new Date(String(d.expiresAt));if(!Number.isFinite(E.getTime()))return{status:"invalid"};let n=E.getTime()-r.getTime();return{status:n<=0?"expired":n<=604800000?"expiring":"valid",expiresAt:E.toISOString()}}catch{return{status:"invalid"}}}class eN{secrets;clientFactory;multipartThreshold;partSize;constructor(t,e=(E,n)=>new pt(E.region??"us-east-1",void 0,{endpoint:E.endpoint?new URL(E.endpoint).host:void 0,forcePathStyle:E.forcePathStyle,credentials:n}),r=8388608,d=8388608){this.secrets=t;this.clientFactory=e;this.multipartThreshold=r;this.partSize=d}async client(t){let e=t.credentialRef?SX(await this.secrets.resolve(t.credentialRef)):void 0;return this.clientFactory(t,e)}async test(t){if(!t.bucket)throw Error("S3 destination has no configured bucket.");let e=await this.client(t),r=`${t.prefix?`${t.prefix.replace(/\/$/,"")}/`:""}.ts-cloud-health/${crypto.randomUUID()}`;await e.putObject({bucket:t.bucket,key:r,body:"ts-cloud backup destination health check",contentType:"text/plain"});try{let d=await e.getObjectBytes(t.bucket,r);if(Buffer.from(d.body).toString()!=="ts-cloud backup destination health check")throw Error("Backup destination health object was corrupted.")}finally{await e.deleteObject(t.bucket,r)}}async upload(t,e){if(!t.bucket)throw Error("S3 destination has no configured bucket.");let r=await this.client(t),d=ri(e.body),E=t.encryption!=="provider"?await this.secrets.resolve(t.encryptionKeyRef):void 0,n=E?e.resume?.encryptionIv?Buffer.from(e.resume.encryptionIv,"base64url"):il(12):void 0,c=E?hX(e.body,E,n):Buffer.from(e.body),_=ri(c),T=`${t.prefix?`${t.prefix.replace(/\/$/,"")}/`:""}${e.key.replace(/^\/+/,"")}`,i=e.contentType??"application/octet-stream",h={"ts-cloud-format":"v1","ts-cloud-sha256":_.slice(7),"ts-cloud-encrypted":E?"true":"false"};if(e.resume&&e.resume.key!==T)throw Error("Multipart checkpoint does not match the requested backup key.");if(e.resume&&E&&!e.resume.encryptionIv)throw Error("Encrypted multipart checkpoint has no resumable envelope state.");if(e.resume&&E&&e.resume.plaintextChecksum!==d)throw Error("Encrypted multipart checkpoint does not match the backup payload.");if(c.length<this.multipartThreshold)await r.putObject({bucket:t.bucket,key:T,body:c,contentType:i,metadata:h});else{let R=e.resume?void 0:await r.createMultipartUpload(t.bucket,T,{contentType:i,metadata:h}),N=e.resume??{uploadId:R.UploadId,key:T,parts:[],bytesUploaded:0,encryptionIv:n?.toString("base64url"),plaintextChecksum:d},A=new Map(N.parts.map((f)=>[f.PartNumber,f])),u=Math.ceil(c.length/this.partSize);for(let f=0;f<u;f++){let w=f+1;if(!A.has(w)){let I=f*this.partSize,a=await r.uploadPart(t.bucket,T,N.uploadId,w,c.subarray(I,Math.min(c.length,I+this.partSize)));A.set(w,{PartNumber:w,ETag:a.ETag})}N.parts=[...A.values()].sort((I,a)=>I.PartNumber-a.PartNumber),N.bytesUploaded=Math.min(c.length,w*this.partSize),e.checkpoint?.(N)}await r.completeMultipartUpload(t.bucket,T,N.uploadId,N.parts)}return{uri:`s3://${t.bucket}/${T}`,key:T,sizeBytes:c.length,checksum:_,manifest:{format:"ts-cloud-backup-v1",encrypted:!!E,plaintextChecksum:d,storageChecksum:_,contentType:i}}}async download(t,e){if(!t.bucket)throw Error("S3 destination has no configured bucket.");let r=await this.client(t),d=await r.getObjectBytes(t.bucket,e.key),E=Buffer.from(d.body);if(ri(E)!==e.checksum)throw Error("Backup checksum verification failed; object is corrupt.");let n=e.manifest.encrypted?RX(E,await this.secrets.resolve(t.encryptionKeyRef)):E;if(ri(n)!==e.manifest.plaintextChecksum)throw Error("Backup plaintext checksum verification failed.");return n}async abortPartial(t,e){if(!t.bucket)throw Error("S3 destination has no configured bucket.");await(await this.client(t)).abortMultipartUpload(t.bucket,e.key,e.uploadId)}async delete(t,e){if(!t.bucket)throw Error("S3 destination has no configured bucket.");await(await this.client(t)).deleteObject(t.bucket,e)}}import{createHash as NX}from"node:crypto";var AX=(t)=>`sha256:${NX("sha256").update(t).digest("hex")}`;class di{store;queue;now;constructor(t,e,r=()=>new Date){this.store=t;this.queue=e;this.now=r}enqueueBackup(t,e=this.now().toISOString(),r){if(!t.enabled)throw Error("Backup policy is disabled.");let d=this.store.createJob({projectId:t.projectId,policyId:t.id,kind:"backup",status:"queued",idempotencyKey:`backup:${t.id}:${e}`,target:{scheduledFor:e},cancellability:"checkpoint_only",progress:{phase:"queued"}});if(!d.operationId){let E=this.queue.enqueue({projectId:t.projectId,environmentId:t.environmentId,resourceId:t.resourceId,actorId:r,kind:"backup.run",input:{backupJobId:d.id},lockKey:t.dataServiceId?`data-service:${t.dataServiceId}`:t.resourceId?`resource:${t.resourceId}`:`backup-policy:${t.id}`,providerKey:"backup",maxAttempts:3,timeoutSeconds:14400,retryClasses:["provider_transient"],resumePolicy:"requeue"});return this.store.updateJob(d.id,{operationId:E.operation.id})}return d}enqueueDue(t=this.now()){return this.store.duePolicies(t).map((e)=>{let r=e.nextRunAt;return this.store.advancePolicy(e.id,r),this.enqueueBackup(e,r)})}enqueueVerification(t){let e=this.store.createJob({projectId:t.projectId,policyId:t.policyId,recoveryPointId:t.id,kind:"verify",status:"queued",idempotencyKey:`verify:${t.id}:${t.checksum}`,target:{},cancellability:"safe",progress:{phase:"queued"}});if(!e.operationId){let r=this.queue.enqueue({projectId:t.projectId,resourceId:t.resourceId,kind:"backup.verify",input:{backupJobId:e.id},lockKey:`recovery-point:${t.id}`,providerKey:"backup",maxAttempts:2,timeoutSeconds:7200,retryClasses:["provider_transient"],resumePolicy:"requeue"});return this.store.updateJob(e.id,{operationId:r.operation.id})}return e}planRestore(t,e){if(t.status!=="available")throw Error("Only available recovery points can be restored.");if(t.verificationState!=="verified")throw Error("Restore requires a verified recovery point.");if(e.mode==="in_place"){if(!e.recentAuth)throw Error("In-place restore requires recent authentication.");if(e.confirm!==e.targetName)throw Error(`Type ${e.targetName} to confirm in-place restore.`);if(!e.downtimeAcknowledged)throw Error("In-place restore requires downtime acknowledgement.");let r=e.safetyBackupId?this.store.getRecoveryPoint(e.safetyBackupId):void 0;if(!r||r.id===t.id||r.status!=="available"||r.verificationState!=="verified"||r.resourceId!==t.resourceId||r.dataServiceId!==t.dataServiceId)throw Error("In-place restore requires a distinct verified safety backup for the same target.")}return{point:t,mode:e.mode,target:{...e.target,inPlace:e.mode==="in_place",restoreMode:e.mode},warnings:e.mode==="in_place"?["The target is locked against deployments and backup work.","Downtime and data replacement are expected.","Provider cancellation may stop only at a checkpoint."]:["An isolated target is created and health-validated before cleanup."]}}enqueueRestore(t,e){let r=this.planRestore(t,e),d=e.drill?"drill":"restore",E=AX(JSON.stringify({point:t.id,mode:e.mode,target:e.target,safety:e.safetyBackupId,drill:!!e.drill})),n=this.store.createJob({projectId:t.projectId,policyId:t.policyId,recoveryPointId:t.id,kind:d,status:"queued",idempotencyKey:`${d}:${E}`,target:r.target,restoreMode:r.mode,cancellability:"checkpoint_only",safetyBackupId:e.safetyBackupId,progress:{phase:"queued",warnings:r.warnings}});if(!n.operationId){let c=this.queue.enqueue({projectId:t.projectId,resourceId:t.resourceId,actorId:e.actorId,kind:e.drill?"backup.drill":"backup.restore",input:{backupJobId:n.id},lockKey:t.dataServiceId?`data-service:${t.dataServiceId}`:t.resourceId?`resource:${t.resourceId}`:`recovery-point:${t.id}`,providerKey:"backup",maxAttempts:1,timeoutSeconds:14400,retryClasses:[],resumePolicy:"fail"});return this.store.updateJob(n.id,{operationId:c.operation.id})}return n}enqueueRetention(t=this.now()){return this.store.retentionCandidates(t).map((e)=>{let r=this.store.createJob({projectId:e.projectId,policyId:e.policyId,recoveryPointId:e.id,kind:"cleanup",status:"queued",idempotencyKey:`cleanup:${e.id}:${e.expiresAt}`,target:{},cancellability:"safe",progress:{phase:"queued"}});if(!r.operationId){let d=this.queue.enqueue({projectId:e.projectId,resourceId:e.resourceId,kind:"backup.cleanup",input:{backupJobId:r.id},lockKey:`recovery-point:${e.id}`,providerKey:"backup",maxAttempts:3,timeoutSeconds:7200,retryClasses:["provider_transient"],resumePolicy:"requeue"});return this.store.updateJob(r.id,{operationId:d.operation.id})}return r})}}function Sl(t){let e=t.now??(()=>new Date),r=new di(t.store,t.queue,e),d=(_)=>{let T=_.recoveryPointId?t.store.getRecoveryPoint(_.recoveryPointId):void 0,i=_.policyId?t.store.getPolicy(_.policyId):T?.policyId?t.store.getPolicy(T.policyId):void 0;if(!i)throw Error("Backup policy was not found.");let h=t.store.getDestination(T?.destinationId??i.destinationId),R=t.resolveSource(i);if(!h)throw Error("Backup destination was not found.");if(!R)throw Error(`No ${i.resourceKind} backup adapter is configured.`);return{point:T,policy:i,destination:h,source:R}},E=(_)=>{let T=_.operation.input,i=t.store.getJob(String(T.backupJobId??""));if(!i)throw Error("Backup job was not found.");return t.store.updateJob(i.id,{status:"running",startedAt:i.startedAt??e().toISOString(),progress:{...i.progress,phase:"running"}}),i},n=(_,T)=>{let i=t.store.getJob(_.id)??_;t.store.updateJob(_.id,{status:"failed",finishedAt:e().toISOString(),error:T instanceof Error?T.message:String(T),progress:{...i.progress,phase:"failed"}})};return{"backup.run":async(_)=>{let T=E(_);try{let{policy:i,destination:h,source:R}=d(T),N=await R.create(i,_),A=t.resolveDestination(h),u=N.mode==="object"?await(async()=>{if(!A)throw Error("Backup destination adapter is not configured.");let a=t.store.getJob(T.id)?.progress,P=a?.multipart,j=P&&typeof P==="object"&&!Array.isArray(P)&&typeof P.uploadId==="string"&&typeof P.key==="string"&&Array.isArray(P.parts)?P:void 0;return A.upload(h,{key:N.key,body:N.body,contentType:N.contentType,resume:j,checkpoint:(H)=>{_.checkpoint("uploading",`Uploaded ${Number(H.bytesUploaded??0)} backup bytes.`),t.store.updateJob(T.id,{progress:{phase:"uploading",multipart:{...H}}})}})})():{uri:N.uri,key:N.uri,sizeBytes:N.sizeBytes,checksum:N.checksum,manifest:{format:"ts-cloud-backup-v1",encrypted:!1,plaintextChecksum:N.checksum,storageChecksum:N.checksum,contentType:"application/provider-snapshot"}},f=i.retention.expireAfterDays?new Date(e().getTime()+i.retention.expireAfterDays*86400000).toISOString():void 0,w=t.store.getJob(T.id)?.startedAt,I=t.store.createRecoveryPoint({projectId:i.projectId,policyId:i.id,destinationId:h.id,resourceId:i.resourceId,dataServiceId:i.dataServiceId,backupJobId:T.id,kind:i.resourceKind,pointInTime:e().toISOString(),uri:u.uri,sizeBytes:u.sizeBytes,checksum:u.checksum,manifest:{...N.manifest,...u.manifest,storageKey:u.key},toolVersion:N.toolVersion,engineVersion:N.engineVersion,expiresAt:f,lockedUntil:h.immutability.defaultRetentionDays?new Date(e().getTime()+h.immutability.defaultRetentionDays*86400000).toISOString():void 0,held:!1,pinned:!1,status:"available",verificationState:"unverified",durationMs:Math.max(0,e().getTime()-new Date(w??e().toISOString()).getTime())});if(N.mode==="external"&&h.provider==="aws_backup")t.store.recordDestinationTest(h.id,{ok:!0});return t.store.updateJob(T.id,{status:"succeeded",recoveryPointId:I.id,finishedAt:e().toISOString(),progress:{phase:"stored",recoveryPointId:I.id}}),r.enqueueVerification(I),{backupJobId:T.id,recoveryPointId:I.id}}catch(i){let h=t.store.getJob(T.id),R=h?.progress.multipart,N=(()=>{try{return d(T)}catch{return}})();if(N?.destination.provider==="aws_backup")t.store.recordDestinationTest(N.destination.id,{ok:!1,error:i instanceof Error?i.message:String(i)});let A=!1;if(R&&typeof R==="object"&&!Array.isArray(R)&&N){let u=t.resolveDestination(N.destination);if(A=!0,u?.abortPartial)try{await u.abortPartial(N.destination,R),A=!1,t.store.updateJob(T.id,{progress:{...h.progress,partialCleanup:"aborted"}})}catch{t.store.updateJob(T.id,{progress:{...h.progress,partialCleanup:"required"}})}}if(A)t.store.updateJob(T.id,{status:"cleanup_required",finishedAt:e().toISOString(),error:i instanceof Error?i.message:String(i),progress:{...t.store.getJob(T.id)?.progress??{},phase:"cleanup_required"}});else n(T,i);throw i}},"backup.verify":async(_)=>{let T=E(_);try{let{point:i,destination:h,source:R}=d(T);if(!i)throw Error("Recovery point was not found.");t.store.updateRecoveryPoint(i.id,{verificationState:"verifying"});let N;if(i.uri.startsWith("s3:")){let A=t.resolveDestination(h);if(!A)throw Error("Backup destination adapter is not configured.");let u=await A.download(h,{key:String(i.manifest.storageKey??""),checksum:i.checksum,manifest:i.manifest}),f=R.verify?await R.verify(i,u,_):{};N={bytes:u.length,checksum:i.checksum,...f}}else if(R.verifyExternal)N=await R.verifyExternal(i,_);else throw Error("External recovery point verification is not supported.");return t.store.updateRecoveryPoint(i.id,{verificationState:"verified",verifiedAt:e().toISOString(),manifest:{...i.manifest,verification:N}}),t.store.updateJob(T.id,{status:"succeeded",finishedAt:e().toISOString(),progress:{phase:"verified",evidence:N}}),{backupJobId:T.id,recoveryPointId:i.id,evidence:N}}catch(i){if(T.recoveryPointId)t.store.updateRecoveryPoint(T.recoveryPointId,{verificationState:/checksum|corrupt|authentic/i.test(i instanceof Error?i.message:String(i))?"corrupt":"failed"});throw n(T,i),i}},"backup.restore":async(_)=>c(_,!1),"backup.drill":async(_)=>c(_,!0),"backup.cleanup":async(_)=>{let T=E(_);try{let{point:i,destination:h,source:R}=d(T);if(!i)throw Error("Recovery point was not found.");if(!t.store.retentionCandidates(e()).some((N)=>N.id===i.id))throw Error("Recovery point is held, pinned, locked, or in active use.");if(t.store.updateRecoveryPoint(i.id,{status:"deleting"}),i.uri.startsWith("s3:")){let N=t.resolveDestination(h);if(!N)throw Error("Destination cleanup is unavailable.");await N.delete(h,String(i.manifest.storageKey??""))}else if(R.deleteExternal)await R.deleteExternal(i,_);else throw Error("External recovery point cleanup is unavailable.");return t.store.updateRecoveryPoint(i.id,{status:"deleted"}),t.store.updateJob(T.id,{status:"succeeded",finishedAt:e().toISOString(),progress:{phase:"deleted"}}),{backupJobId:T.id,recoveryPointId:i.id,deleted:!0}}catch(i){throw n(T,i),i}}};async function c(_,T){let i=E(_);try{let{point:h,policy:R,destination:N,source:A}=d(i);if(!h)throw Error("Recovery point was not found.");if(T&&!A.cleanup)throw Error("This backup source cannot safely clean a recovery drill target.");let u=h.uri.startsWith("s3:")?t.resolveDestination(N):void 0,f=u?await u.download(N,{key:String(h.manifest.storageKey??""),checksum:h.checksum,manifest:h.manifest}):void 0,w=await A.restore(h,f,i.target,_),I=A.validateHealth?await A.validateHealth({...i.target,...w},_):{healthy:!0,mode:"adapter"},a=t.validateHealth?await t.validateHealth(R,i.target):{healthy:!0,mode:"not_configured"},P={...I,healthy:I.healthy===!0&&a.healthy===!0,configured:a};if(P.healthy!==!0)throw Error("Restored target did not pass its configured health check.");if(T&&A.cleanup)await A.cleanup({...i.target,provider:h.manifest.provider??null},_);return t.store.updateJob(i.id,{status:"succeeded",finishedAt:e().toISOString(),healthResult:P,progress:{phase:T?"drill_cleaned":"restored",restored:w}}),{backupJobId:i.id,recoveryPointId:h.id,restored:w,health:P,cleaned:T}}catch(h){let R=(()=>{try{return d(i)}catch{return}})(),N=h instanceof Error?h.message:String(h),A=!1;if(T&&R?.source.cleanup)try{await R.source.cleanup({...i.target,provider:R.point?.manifest.provider??null},_)}catch{A=!0}if(A)t.store.updateJob(i.id,{status:"cleanup_required",finishedAt:e().toISOString(),error:N,progress:{...i.progress,phase:"cleanup_required"}});else n(i,h);throw h}}}Pn();import{createHash as LX}from"node:crypto";var uX=(t)=>`sha256:${LX("sha256").update(t).digest("hex")}`;class rN{dataServices;client;constructor(t,e=new nd){this.dataServices=t;this.client=e}service(t){let e=t.dataServiceId?this.dataServices.get(t.dataServiceId):void 0;if(!e||!["aws_rds","aws_aurora"].includes(e.provider))throw Error("Managed database backup policy requires an RDS or Aurora data service.");return e}async waitForSnapshot(t,e,r){for(;;){r.throwIfCancellationRequested?.(),r.heartbeat?.();let d=t==="aws_aurora"?(await this.client.describeDBClusterSnapshots({DBClusterSnapshotIdentifier:e})).DBClusterSnapshots[0]:(await this.client.describeDBSnapshots({DBSnapshotIdentifier:e})).DBSnapshots?.[0];if(!d)throw Error("Provider snapshot was not found.");let E=d,n=String(E.Status??E.DBSnapshotStatus??"unknown");if(r.checkpoint?.("provider_snapshot",`Database snapshot ${e} is ${n}.`),n==="available")return E;if(["deleted","deleting","failed"].includes(n))throw Error(`Provider snapshot ${e} failed with state ${n}.`);await Bun.sleep(5000)}}async create(t,e){let r=this.service(t),d=String(e.operation?.id??new Date().toISOString()).replace(/[^A-Za-z0-9]/g,"").slice(0,20),E=`${r.placement.slice(0,42).replace(/-+$/,"")}-${d}`;if(r.provider==="aws_aurora")await this.client.createDBClusterSnapshot(r.placement,E);else await this.client.createDBSnapshot({DBInstanceIdentifier:r.placement,DBSnapshotIdentifier:E});await this.waitForSnapshot(r.provider,E,e);let n=`${r.provider}:${r.placement}:${E}`;return{mode:"external",uri:`aws-backup:${n}`,checksum:uX(n),sizeBytes:0,manifest:{provider:r.provider,sourceId:r.placement,snapshotId:E,plan:r.plan,engine:r.engine},engineVersion:r.engineVersion,toolVersion:"aws-rds-api-2014-10-31"}}async verifyExternal(t,e){let r=String(t.manifest.snapshotId??""),d=String(t.manifest.provider??"");if(!r)throw Error("Snapshot recovery point has no snapshot ID.");let E=await this.waitForSnapshot(d,r,e),n=String(E.Status??E.DBSnapshotStatus??"unknown");return{snapshotId:r,status:n,encrypted:E.Encrypted??E.StorageEncrypted??!0}}async restore(t,e,r,d){let E=String(r.targetId??""),n=String(t.manifest.snapshotId??""),c=String(t.manifest.provider??"");if(!/^[a-z0-9][a-z0-9-]{1,62}$/.test(E))throw Error("Managed restore requires a valid distinct targetId.");if(E===t.manifest.sourceId)throw Error("Managed restore target must differ from its source.");if(c==="aws_aurora"){let _=t.manifest.engine==="postgres"?"aurora-postgresql":"aurora-mysql";await this.client.restoreDBClusterFromSnapshot({DBClusterIdentifier:E,SnapshotIdentifier:n,Engine:_,EngineVersion:t.engineVersion,DeletionProtection:!0,ServerlessV2ScalingConfiguration:{MinCapacity:Number(r.minCapacity)||0.5,MaxCapacity:Number(r.maxCapacity)||4}}),await this.client.createDBInstance({DBInstanceIdentifier:`${E}-writer-1`,DBClusterIdentifier:E,DBInstanceClass:String(r.plan??t.manifest.plan??"db.serverless"),Engine:_,PubliclyAccessible:!1})}else await this.client.restoreDBInstanceFromDBSnapshot({DBInstanceIdentifier:E,DBSnapshotIdentifier:n,DBInstanceClass:String(r.plan??t.manifest.plan??""),PubliclyAccessible:!1,DeletionProtection:!0,Tags:[{Key:"managed-by",Value:"ts-cloud-restore"}]});return{targetId:E,provider:c,status:"creating",isolated:!0}}async validateHealth(t,e){let r=String(t.targetId??""),d=String(t.provider??"");for(;;){e.throwIfCancellationRequested?.(),e.heartbeat?.();let E=d==="aws_aurora"?(await this.client.describeDBClusters({DBClusterIdentifier:r})).DBClusters?.[0]:(await this.client.describeDBInstances({DBInstanceIdentifier:r})).DBInstances?.[0];if(!E)throw Error("Restored managed database was not found.");let n=String(E.Status??E.DBInstanceStatus??"unknown");if(e.checkpoint?.("provider_restore",`Restored database ${r} is ${n}.`),n==="available")return{healthy:!0,targetId:r,provider:d,status:n};if(["deleted","deleting","failed","incompatible-restore"].includes(n))throw Error(`Restored managed database ${r} failed with state ${n}.`);await Bun.sleep(5000)}}async cleanup(t,e){let r=String(t.targetId??""),d=String(t.provider??"");if(!r)throw Error("Restore cleanup target is required.");if(d==="aws_aurora")await this.client.deleteDBInstance({DBInstanceIdentifier:`${r}-writer-1`,SkipFinalSnapshot:!0}),await this.client.modifyDBCluster({DBClusterIdentifier:r,DeletionProtection:!1,ApplyImmediately:!0}),await this.client.deleteDBCluster(r);else await this.client.modifyDBInstance({DBInstanceIdentifier:r,DeletionProtection:!1,ApplyImmediately:!0}),await this.client.deleteDBInstance({DBInstanceIdentifier:r,SkipFinalSnapshot:!0,DeleteAutomatedBackups:!0})}async deleteExternal(t,e){let r=String(t.manifest.snapshotId??"");if(t.manifest.provider==="aws_aurora")await this.client.deleteDBClusterSnapshot(r);else await this.client.deleteDBSnapshot(r)}}var Pe=(t,e="none",r=!1)=>({supported:!0,downtime:e,destructive:r,explanation:t}),Ce=(t)=>({supported:!1,downtime:"none",destructive:!1,explanation:t});function i_(t,e){let r=["aws_rds","aws_aurora","aws_elasticache"].includes(e),d=["server","container"].includes(e),E=["postgres","mysql","mariadb"].includes(t),n=t==="redis",c={};return c.create=e==="external"?Ce("External services can be adopted as read-only inventory."):Pe(r?"Provision through the provider API.":"Provision through the owning runtime driver.","possible"),c.observe=e==="external"?Ce("External observation requires a configured provider adapter."):Pe("Provider/runtime health and endpoint metadata are observable."),c.connect=Pe("Connection guidance uses secret references and never returns a password by default."),c.backup=E&&(r||d)?Pe(r?"Create a provider snapshot.":"Create a consistent engine-native dump.","possible"):Ce("This cache path is not a durable backup source."),c.restore=r&&E?Pe("Restore creates a reviewed provider target.","required",!0):Ce("Restore requires a configured provider restore runner."),c.restart=e==="external"?Ce("External restart requires a configured provider adapter."):Pe(r?"Provider restart/failover semantics apply.":"Restart the owning service unit.","required"),c.resize=e==="aws_elasticache"?Ce("ElastiCache resizing requires a replication-group migration runner."):r?Pe("Provider plan/storage modification may enter a maintenance window.","possible"):d?Pe("Edit host/container resources and reconcile.","required"):Ce("External resize requires a configured provider adapter."),c.version=d?Ce("Runtime version upgrades require an explicit image migration runner."):r&&e!=="aws_elasticache"?Pe(E?"Major versions require compatibility preflight and backup.":"Engine upgrades require a maintenance window.","required"):Ce("External upgrades require a configured provider adapter."),c.rotate=e==="aws_elasticache"||e==="external"||d&&!E&&!n?Ce("Credential rotation is not available for this provider/engine path."):Pe("Rotate through the secret backend, update the engine, then flag dependent releases."),c.expose=d?Ce("Direct container publishing is refused; use a reviewed firewall and proxy policy."):e==="aws_rds"?Pe("Exposure is reconciled through security groups; public access defaults off."):Ce("Exposure changes require a provider-specific network runner."),c.delete=e==="external"?Ce("External deletion requires a configured provider adapter."):Pe(r?"Final snapshot is supported where the provider allows it.":"A final engine backup is required unless explicitly retained.","required",!0),c.logs=d?Pe("Read bounded service logs from the runtime."):Ce("Provider log export is not configured for this adapter."),c.slow_queries=d&&E?Pe("Read bounded runtime logs after engine slow-query logging is enabled."):Ce("A slow-query log runner is not configured for this provider."),c.users=d&&E?Pe("Logical users can be listed; creation requires a referenced secondary credential."):Ce("User management requires an engine connection runner."),c.databases=d&&E?Pe("Logical databases can be listed, created, and confirmation-gated for deletion."):Ce("Logical database management requires an engine connection runner."),{actions:c,endpointTypes:r?["internal","external","tunnel"]:["internal","tunnel"],metrics:n?["connections","memory","evictions","hit_rate","latency"]:["connections","cpu","storage","read_latency","write_latency","iops"]}}var Bn=(t)=>t==null?void 0:String(t),ni=(t)=>Number(t)===1,Ei=(t)=>{try{return JSON.parse(String(t))}catch{return{}}};function Nl(t){return{id:String(t.id),organizationId:String(t.organization_id),projectId:String(t.project_id),environmentId:Bn(t.environment_id),resourceId:Bn(t.resource_id),name:String(t.name),engine:String(t.engine),provider:String(t.provider),placement:String(t.placement),engineVersion:Bn(t.engine_version),plan:String(t.plan),storageGb:t.storage_gb==null?void 0:Number(t.storage_gb),highAvailability:ni(t.high_availability),publicExposure:ni(t.public_exposure),allowedCidrs:Ei(t.allowed_cidrs),desiredState:Ei(t.desired_state),observedState:Ei(t.observed_state),capabilities:Ei(t.capabilities),credentialRef:Bn(t.credential_ref),status:String(t.status),origin:String(t.origin),managementEnabled:ni(t.management_enabled),ownerActorId:Bn(t.owner_actor_id),version:Number(t.version),createdAt:String(t.created_at),updatedAt:String(t.updated_at)}}class dN{controlPlane;now;constructor(t,e=()=>new Date){this.controlPlane=t;this.now=e}create(t){if(!/^[a-z0-9][a-z0-9-]{1,62}$/.test(t.name))throw Error("Data service names must be 2-63 lowercase letters, numbers, or dashes.");if(t.publicExposure&&(!t.allowedCidrs.length||t.allowedCidrs.includes("0.0.0.0/0")))throw Error("Public exposure requires explicit narrow CIDRs; 0.0.0.0/0 is refused.");let e=crypto.randomUUID(),r=this.now().toISOString(),d=i_(t.engine,t.provider);return this.controlPlane.database.run("INSERT INTO data_services (id,organization_id,project_id,environment_id,resource_id,name,engine,provider,placement,engine_version,plan,storage_gb,high_availability,public_exposure,allowed_cidrs,desired_state,observed_state,capabilities,credential_ref,status,origin,management_enabled,owner_actor_id,version,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",[e,t.organizationId,t.projectId,t.environmentId??null,t.resourceId??null,t.name,t.engine,t.provider,t.placement,t.engineVersion??null,t.plan,t.storageGb??null,t.highAvailability?1:0,t.publicExposure?1:0,JSON.stringify(t.allowedCidrs),JSON.stringify(t.desiredState),JSON.stringify(t.observedState),JSON.stringify(d),t.credentialRef??null,t.status,t.origin,t.managementEnabled?1:0,t.ownerActorId??null,1,r,r]),this.get(e)}get(t){let e=this.controlPlane.database.query("SELECT * FROM data_services WHERE id=?").get(t);return e?Nl(e):void 0}list(t,e){return this.controlPlane.database.query(`SELECT * FROM data_services WHERE project_id=?${e?" AND environment_id=?":""} ORDER BY name`).all(t,...e?[e]:[]).map(Nl)}update(t,e,r){let d=this.get(t);if(!d)throw Error("Data service was not found.");if(d.version!==e)throw Error("Data service changed; refresh before retrying.");let E={...d,...r};if(E.publicExposure&&(!E.allowedCidrs.length||E.allowedCidrs.includes("0.0.0.0/0")))throw Error("Public exposure requires explicit narrow CIDRs; 0.0.0.0/0 is refused.");if(this.controlPlane.database.run("UPDATE data_services SET plan=?,storage_gb=?,engine_version=?,high_availability=?,public_exposure=?,allowed_cidrs=?,desired_state=?,observed_state=?,status=?,management_enabled=?,credential_ref=?,version=version+1,updated_at=? WHERE id=? AND version=?",[E.plan,E.storageGb??null,E.engineVersion??null,E.highAvailability?1:0,E.publicExposure?1:0,JSON.stringify(E.allowedCidrs),JSON.stringify(E.desiredState),JSON.stringify(E.observedState),E.status,E.managementEnabled?1:0,E.credentialRef??null,this.now().toISOString(),t,e]).changes!==1)throw Error("Data service changed; refresh before retrying.");return this.get(t)}credential(t){let e=this.controlPlane.database.query("SELECT * FROM data_service_credentials WHERE service_id=? ORDER BY version DESC LIMIT 1").get(t);return e?{id:String(e.id),serviceId:String(e.service_id),username:String(e.username),secretRef:String(e.secret_ref),version:Number(e.version),createdAt:String(e.created_at),rotatedAt:Bn(e.rotated_at)}:void 0}saveCredential(t,e,r){let d=this.credential(t),E=d?.id??crypto.randomUUID(),n=this.now().toISOString();return this.controlPlane.database.run("INSERT INTO data_service_credentials (id,service_id,username,secret_ref,version,created_at,rotated_at) VALUES (?,?,?,?,?,?,?) ON CONFLICT(service_id,username) DO UPDATE SET secret_ref=excluded.secret_ref,version=data_service_credentials.version+1,rotated_at=excluded.rotated_at",[E,t,e,r,d?.version??1,d?.createdAt??n,d?n:null]),this.credential(t)}addDependency(t){let e=this.now().toISOString();return this.controlPlane.database.run("INSERT INTO data_service_dependencies (service_id,resource_id,secret_ref,requires_redeploy,created_at) VALUES (?,?,?,?,?) ON CONFLICT(service_id,resource_id) DO UPDATE SET secret_ref=excluded.secret_ref,requires_redeploy=excluded.requires_redeploy",[t.serviceId,t.resourceId,t.secretRef,t.requiresRedeploy?1:0,e]),{...t,createdAt:e}}dependencies(t){return this.controlPlane.database.query("SELECT * FROM data_service_dependencies WHERE service_id=? ORDER BY resource_id").all(t).map((e)=>({serviceId:String(e.service_id),resourceId:String(e.resource_id),secretRef:String(e.secret_ref),requiresRedeploy:ni(e.requires_redeploy),createdAt:String(e.created_at)}))}removeDependency(t,e){return this.controlPlane.database.run("DELETE FROM data_service_dependencies WHERE service_id=? AND resource_id=?",[t,e]).changes===1}remove(t){this.controlPlane.database.run("DELETE FROM data_services WHERE id=?",[t])}}function Al(){let e=crypto.getRandomValues(new Uint8Array(40));return Array.from(e,(r)=>"ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz23456789!@#$%^&*_-+="[r%69]).join("")}function Ll(t,e){return e.map((r)=>{let d=r.type==="tunnel"?"127.0.0.1":r.host,E=t.engine==="redis"?`redis-cli -h ${d} -p ${r.port}${r.tls?" --tls":""}`:t.engine==="postgres"?`psql "host=${d} port=${r.port} dbname=${r.database??"postgres"} sslmode=${r.tls?"require":"disable"}"`:t.engine==="mongodb"?`mongosh "mongodb://${d}:${r.port}/${r.database??"admin"}${r.tls?"?tls=true":""}"`:t.engine==="libsql"?`turso db shell ${r.tls?"https":"http"}://${d}:${r.port}`:`mysql --host=${d} --port=${r.port} --database=${r.database??"mysql"} --ssl-mode=${r.tls?"REQUIRED":"DISABLED"}`;return{type:r.type,command:E,secretRef:t.credentialRef}})}class ci{store;queue;secrets;constructor(t,e,r){this.store=t;this.queue=e;this.secrets=r}async create(t){let e,r;if(t.provider!=="aws_elasticache"){let d=t.username??"app",E=Al();r=`secret://data-services/${t.projectId}/${t.name}/${d}`,await this.secrets.put(r,E),e={username:d,password:E,secretRef:r}}try{let d=this.store.create({...t,credentialRef:r,status:"planning"});if(e)this.store.saveCredential(d.id,e.username,e.secretRef);let E=this.enqueue(d,"create",{});return{service:d,credential:e,operationId:E}}catch(d){if(r)await this.secrets.remove(r);throw d}}plan(t,e,r={}){let d=t.capabilities.actions[e],E=e==="version"&&String(r.engineVersion??"").split(".")[0]!==String(t.engineVersion??"").split(".")[0];return{service:t,action:e,capability:d,changes:r,preflight:{backupRequired:["delete","restore"].includes(e)||E,compatibilityRequired:E,typedConfirmation:d.destructive?t.name:void 0,retentionChoiceRequired:e==="delete"},warnings:[...d.downtime!=="none"?[`Downtime is ${d.downtime}.`]:[],...t.origin==="adopted"&&!t.managementEnabled?["Adopted resource is read-only until management is explicitly enabled."]:[]]}}enqueue(t,e,r,d){let E=this.plan(t,e,r);if(!E.capability.supported)throw Error(E.capability.explanation);if(t.origin==="adopted"&&!t.managementEnabled&&e!=="observe")throw Error("Adopted resources remain read-only until management is explicitly enabled.");if(E.preflight.typedConfirmation&&r.confirm!==E.preflight.typedConfirmation)throw Error(`Type ${E.preflight.typedConfirmation} to confirm ${e}.`);if(E.preflight.retentionChoiceRequired&&!["final_backup","retain"].includes(String(r.retention??"")))throw Error("Deletion requires retention final_backup or retain.");if(E.preflight.compatibilityRequired&&(r.compatibilityReviewed!==!0||!r.backupId))throw Error("Major version changes require compatibilityReviewed=true and a backupId.");if(e==="restore"){let n=String(r.backupId??""),c=String(r.targetId??"");if(!n||!c)throw Error("Restore requires both backupId and targetId.");if(c===t.placement)throw Error("Restore targetId must differ from the source placement.");if(!/^[a-z0-9][a-z0-9-]{1,62}$/.test(c))throw Error("Restore targetId must be 2-63 lowercase letters, numbers, or dashes.")}return this.queue.enqueue({projectId:t.projectId,environmentId:t.environmentId,resourceId:t.resourceId,actorId:d,kind:"data_service.action",input:{serviceId:t.id,action:e,...r},lockKey:`data-service:${t.id}`,providerKey:t.provider,maxAttempts:3,timeoutSeconds:7200,retryClasses:["provider_transient"],resumePolicy:"requeue"}).operation.id}async rotate(t,e,r){let d=this.store.credential(t.id);if(!d)throw Error("Data service credential metadata was not found.");let E=Al(),n=`${d.secretRef}/v${d.version+1}`;await this.secrets.put(n,E);try{return await e.action(t,"rotate",{username:d.username,secretRef:n},E,r),this.store.saveCredential(t.id,d.username,n),this.store.update(t.id,t.version,{credentialRef:n}),{credential:{username:d.username,password:E,secretRef:n},dependencies:this.store.dependencies(t.id).filter((c)=>c.requiresRedeploy).map((c)=>c.resourceId)}}catch(c){throw await this.secrets.remove(n),c}}}function ul(t){return{"data_service.action":async(e)=>{let r=e.operation.input,d=t.store.get(String(r.serviceId??"")),E=String(r.action??"");if(!d)throw Error("Data service was not found.");let n=t.resolveAdapter(d);if(!n||n.provider!==d.provider||!n.engines.includes(d.engine))throw Error(`No ${d.provider}/${d.engine} adapter is configured.`);if(E==="rotate"){let _=await new ci(t.store,new gt(t.store.controlPlane),t.secrets).rotate(d,n,e);return{serviceId:d.id,action:E,username:_.credential.username,secretRef:_.credential.secretRef,dependencies:_.dependencies}}let c=d.credentialRef?await t.secrets.resolve(d.credentialRef):void 0;try{let _=E==="observe"?await n.observe(d):E==="create"?await n.apply(d,c,e):await n.action(d,E,r,c,e),T=t.store.get(d.id);return t.store.update(d.id,T.version,{observedState:_,status:E==="delete"?r.retention==="retain"?"retained":"deleting":"available"}),{serviceId:d.id,action:E,observed:_}}catch(_){let T=t.store.get(d.id);if(t.store.update(d.id,T.version,{status:"failed",observedState:{...T.observedState,error:_ instanceof Error?_.message:String(_)}}),/temporar|timeout|unavailable|throttl/i.test(_ instanceof Error?_.message:String(_)))throw new $r(_ instanceof Error?_.message:String(_),"provider_transient");throw _}}}}class Jn{transport;constructor(t){this.transport=t}observe(t){return this.transport.observe(t.placement)}apply(t,e){return this.transport.apply({id:t.placement,name:t.name,engine:t.engine,engineVersion:t.engineVersion??null,plan:t.plan,storageGb:t.storageGb??null,highAvailability:t.highAvailability,publicExposure:t.publicExposure,allowedCidrs:t.allowedCidrs,username:t.desiredState.username??"app",desiredState:t.desiredState},e)}action(t,e,r,d,E){return this.transport.execute(t.placement,e,{engine:t.engine,engineVersion:t.engineVersion??null,plan:t.plan,desiredState:t.desiredState,...r},d,E)}}class EN extends Jn{provider="aws_rds";engines=["postgres","mysql","mariadb"]}class nN extends Jn{provider="aws_aurora";engines=["postgres","mysql"]}class cN extends Jn{provider="aws_elasticache";engines=["redis"]}class _N extends Jn{provider="server";engines=["postgres","mysql","mariadb","redis","mongodb","libsql"]}class TN extends Jn{provider="container";engines=["postgres","mysql","mariadb","redis","mongodb","libsql"]}Pn();var ii=(t,e)=>{let r=t.desiredState;return t[e]??(r&&typeof r==="object"&&!Array.isArray(r)?r[e]:void 0)},bt=(t,e,r)=>{let d=ii(t,e);return d==null?r:String(d)},Ze=(t,e)=>{let r=ii(t,e);return r==null?void 0:Number(r)},Zd=(t,e)=>{let r=ii(t,e);return r==null?void 0:r===!0||r==="true"},Hn=(t,e)=>{let r=ii(t,e);return Array.isArray(r)?r.map(String):[]},Ti=(t,e)=>bt(e,"snapshotId")??`${t}-final-${new Date().toISOString().replace(/[^0-9]/g,"").slice(0,14)}`;function _i(t){if(!t)throw Error("RDS instance was not found.");return{providerId:t.DBInstanceIdentifier??null,status:t.DBInstanceStatus??"unknown",engine:t.Engine??null,engineVersion:t.EngineVersion??null,plan:t.DBInstanceClass??null,storageGb:t.AllocatedStorage??null,highAvailability:t.MultiAZ??!1,publicExposure:t.PubliclyAccessible??!1,endpoint:t.Endpoint?.Address??null,port:t.Endpoint?.Port??null,username:t.MasterUsername??null,database:t.DBName??null,encrypted:t.StorageEncrypted??!1}}class hN{client;constructor(t=new nd){this.client=t}async observe(t){return _i(await this.client.describeDBInstance(t))}async apply(t,e){let r=String(t.id),d=await this.client.createDBInstance({DBInstanceIdentifier:r,DBInstanceClass:String(t.plan),Engine:String(t.engine),MasterUsername:bt(t,"username","app"),MasterUserPassword:e,DBName:bt(t,"database"),AllocatedStorage:Ze(t,"storageGb"),VpcSecurityGroupIds:Hn(t,"securityGroupIds"),DBSubnetGroupName:bt(t,"subnetGroup"),BackupRetentionPeriod:Ze(t,"backupRetentionDays")??7,MultiAZ:Zd(t,"highAvailability"),EngineVersion:bt(t,"engineVersion"),PubliclyAccessible:Zd(t,"publicExposure")??!1,StorageType:bt(t,"storageType","gp3"),StorageEncrypted:!0,KmsKeyId:bt(t,"kmsKeyId"),DeletionProtection:!0,Tags:[{Key:"managed-by",Value:"ts-cloud"}]});return _i(d.DBInstance)}async execute(t,e,r,d,E){if(e==="observe")return this.observe(t);if(e==="restart")return await this.client.rebootDBInstance({DBInstanceIdentifier:t}),{status:"rebooting"};if(e==="backup"){let n=Ti(t,r);return await this.client.createDBSnapshot({DBInstanceIdentifier:t,DBSnapshotIdentifier:n}),{status:"snapshotting",snapshotId:n}}if(e==="restore"){let n=String(r.targetId),c=await this.client.restoreDBInstanceFromDBSnapshot({DBInstanceIdentifier:n,DBSnapshotIdentifier:String(r.backupId),DBInstanceClass:bt(r,"plan"),DBSubnetGroupName:bt(r,"subnetGroup"),MultiAZ:Zd(r,"highAvailability"),PubliclyAccessible:!1,StorageType:bt(r,"storageType"),VpcSecurityGroupIds:Hn(r,"securityGroupIds"),DeletionProtection:!0,Tags:[{Key:"managed-by",Value:"ts-cloud"}]});return{..._i(c.DBInstance),sourceId:t,restoreTargetId:n}}if(e==="delete"){if(r.retention==="retain")return{status:"retained"};let n=Ti(t,r);return await this.client.modifyDBInstance({DBInstanceIdentifier:t,DeletionProtection:!1,ApplyImmediately:!0}),await this.client.deleteDBInstance({DBInstanceIdentifier:t,SkipFinalSnapshot:!1,FinalDBSnapshotIdentifier:n,DeleteAutomatedBackups:!1}),{status:"deleting",finalSnapshotId:n}}if(["resize","version","rotate","expose"].includes(e)){let n=await this.client.modifyDBInstance({DBInstanceIdentifier:t,DBInstanceClass:bt(r,"plan"),AllocatedStorage:Ze(r,"storageGb"),MasterUserPassword:e==="rotate"?d:void 0,EngineVersion:bt(r,"engineVersion"),MultiAZ:Zd(r,"highAvailability"),PubliclyAccessible:Zd(r,"publicExposure"),VpcSecurityGroupIds:Hn(r,"securityGroupIds"),ApplyImmediately:Zd(r,"applyImmediately")??!0});return _i(n.DBInstance)}throw Error(`RDS action ${e} requires an engine connection runner.`)}}function iN(t){if(!t)throw Error("Aurora cluster was not found.");return{providerId:t.DBClusterIdentifier??null,status:t.Status??"unknown",engine:t.Engine??null,engineVersion:t.EngineVersion??null,endpoint:t.Endpoint??null,readerEndpoint:t.ReaderEndpoint??null,port:t.Port??null,username:t.MasterUsername??null,database:t.DatabaseName??null,encrypted:t.StorageEncrypted??!1,highAvailability:t.MultiAZ??!0}}class RN{client;constructor(t=new nd){this.client=t}async observe(t){let e=await this.client.describeDBClusters({DBClusterIdentifier:t});return iN(e.DBClusters?.[0])}async apply(t,e){let r=String(t.id),d=String(t.engine)==="postgres"?"aurora-postgresql":"aurora-mysql";return await this.client.createDBCluster({DBClusterIdentifier:r,Engine:d,EngineVersion:bt(t,"engineVersion"),MasterUsername:bt(t,"username","app"),MasterUserPassword:e,DatabaseName:bt(t,"database"),DBSubnetGroupName:bt(t,"subnetGroup"),VpcSecurityGroupIds:Hn(t,"securityGroupIds"),BackupRetentionPeriod:Ze(t,"backupRetentionDays")??7,StorageEncrypted:!0,KmsKeyId:bt(t,"kmsKeyId"),DeletionProtection:!0,ServerlessV2ScalingConfiguration:{MinCapacity:Ze(t,"minCapacity")??0.5,MaxCapacity:Ze(t,"maxCapacity")??4}}),await this.client.createDBInstance({DBInstanceIdentifier:`${r}-writer-1`,DBClusterIdentifier:r,DBInstanceClass:String(t.plan||"db.serverless"),Engine:d,PubliclyAccessible:Zd(t,"publicExposure")??!1}),{status:"creating",providerId:r}}async execute(t,e,r,d){if(e==="observe")return this.observe(t);if(e==="restart")return await this.client.rebootDBCluster(t),{status:"rebooting"};if(e==="backup"){let E=Ti(t,r);return await this.client.createDBClusterSnapshot(t,E),{status:"snapshotting",snapshotId:E}}if(e==="restore"){let E=String(r.targetId),n=String(r.engine)==="postgres"?"aurora-postgresql":"aurora-mysql",c=await this.client.restoreDBClusterFromSnapshot({DBClusterIdentifier:E,SnapshotIdentifier:String(r.backupId),Engine:n,EngineVersion:bt(r,"engineVersion"),DBSubnetGroupName:bt(r,"subnetGroup"),VpcSecurityGroupIds:Hn(r,"securityGroupIds"),DeletionProtection:!0,ServerlessV2ScalingConfiguration:{MinCapacity:Ze(r,"minCapacity")??0.5,MaxCapacity:Ze(r,"maxCapacity")??4}});return await this.client.createDBInstance({DBInstanceIdentifier:`${E}-writer-1`,DBClusterIdentifier:E,DBInstanceClass:bt(r,"plan","db.serverless"),Engine:n,PubliclyAccessible:!1}),{...iN(c.DBCluster),sourceId:t,restoreTargetId:E}}if(e==="delete"){if(r.retention==="retain")return{status:"retained"};let E=Ti(t,r);return await this.client.modifyDBCluster({DBClusterIdentifier:t,DeletionProtection:!1,ApplyImmediately:!0}),await this.client.deleteDBCluster(t,E),{status:"deleting",finalSnapshotId:E}}if(["resize","version","rotate"].includes(e)){let E=await this.client.modifyDBCluster({DBClusterIdentifier:t,ServerlessV2ScalingConfiguration:Ze(r,"minCapacity")==null&&Ze(r,"maxCapacity")==null?void 0:{MinCapacity:Ze(r,"minCapacity")??0.5,MaxCapacity:Ze(r,"maxCapacity")??4},EngineVersion:bt(r,"engineVersion"),MasterUserPassword:e==="rotate"?d:void 0,ApplyImmediately:Zd(r,"applyImmediately")??!0});return iN(E.DBCluster)}throw Error(`Aurora action ${e} requires an engine connection runner.`)}}class SN{client;constructor(t=new T_){this.client=t}async observe(t){let e=(await this.client.describeCacheClusters(t)).CacheClusters[0];if(!e)throw Error("ElastiCache cluster was not found.");let r=e.CacheNodes?.[0]?.Endpoint;return{providerId:e.CacheClusterId,status:e.CacheClusterStatus,engine:e.Engine,engineVersion:e.EngineVersion,plan:e.CacheNodeType,nodes:e.NumCacheNodes,endpoint:r?.Address??null,port:r?.Port??null}}async apply(t){let e=await this.client.createCacheCluster({cacheClusterId:String(t.id),engine:"redis",cacheNodeType:String(t.plan),numCacheNodes:Ze(t,"nodes")??1,engineVersion:bt(t,"engineVersion"),port:Ze(t,"port"),securityGroupIds:Hn(t,"securityGroupIds"),subnetGroupName:bt(t,"subnetGroup"),tags:[{Key:"managed-by",Value:"ts-cloud"}]});return{providerId:e.CacheCluster.CacheClusterId,status:e.CacheCluster.CacheClusterStatus}}async execute(t,e,r){if(e==="observe")return this.observe(t);if(e==="restart"){let d=(await this.client.describeCacheClusters(t)).CacheClusters[0];return await this.client.rebootCacheCluster(t,d?.CacheNodes?.map((E)=>E.CacheNodeId)??["0001"]),{status:"rebooting"}}if(e==="delete"){if(r.retention==="retain")return{status:"retained"};return await this.client.deleteCacheCluster(t),{status:"deleting"}}throw Error(`ElastiCache action ${e} is not supported by this cluster mode.`)}}await Ht();import{mkdir as OX,writeFile as CX}from"node:fs/promises";import{join as lX}from"node:path";async function er(t,e,r=!1){let d=Bun.spawn(["docker",...t],{stdin:e==null?"ignore":"pipe",stdout:"pipe",stderr:"pipe"}),E=new Response(d.stdout).text(),n=new Response(d.stderr).text();if(e!=null)d.stdin.write(e),d.stdin.end();let[c,_,T]=await Promise.all([d.exited,E,n]);if(c!==0&&!r)throw Error(`Docker command failed (${c}): ${T.trim()||_.trim()}`);return{code:c,stdout:_,stderr:T}}class Ol{async ensureNetwork(t){if((await er(["network","inspect",t],void 0,!0)).code!==0)await er(["network","create","--internal",t])}async seedSecret(t,e){await er(["volume","create",t]),await er(["run","--rm","-i","-v",`${t}:/run/target`,"alpine:3.21","sh","-c","umask 077; cat > /run/target/credential"],e)}async removeVolume(t){await er(["volume","rm",t],void 0,!0)}async inspect(t){let e=await er(["inspect",t],void 0,!0);if(e.code!==0)return;return JSON.parse(e.stdout)[0]}async run(t){await er(["run",...t])}async exec(t,e,r){return(await er(["exec","-i",t,...e],r)).stdout}async update(t,e){await er(["update",...e,t])}async restart(t){await er(["restart",t])}async remove(t){await er(["rm","--force",t],void 0,!0)}async logs(t,e){let r=await er(["logs","--tail",String(Math.min(2000,Math.max(1,e))),t],void 0,!0);return`${r.stdout}${r.stderr}`.slice(-262144)}async stats(t){let e=await er(["stats","--no-stream","--format","{{json .}}",t],void 0,!0);if(e.code!==0||!e.stdout.trim())return{};let r=JSON.parse(e.stdout.trim());return{cpuPercent:String(r.CPUPerc??""),memoryUsage:String(r.MemUsage??""),memoryPercent:String(r.MemPerc??""),networkIo:String(r.NetIO??""),blockIo:String(r.BlockIO??""),pids:Number(r.PIDs??0)}}}var IX={postgres:{image:"postgres:17-alpine",port:5432,dataPath:"/var/lib/postgresql/data"},mysql:{image:"mysql:8.4",port:3306,dataPath:"/var/lib/mysql"},mariadb:{image:"mariadb:11.7",port:3306,dataPath:"/var/lib/mysql"},redis:{image:"redis:7.4-alpine",port:6379,dataPath:"/data"},mongodb:{image:"mongo:8.0",port:27017,dataPath:"/data/db"}};function cd(t,e="app"){let r=String(t??e);if(!/^[A-Za-z_][A-Za-z0-9_]{0,62}$/.test(r))throw Error("Database identifiers must be letters, numbers, or underscores.");return r}function FE(t){if(!/^[a-z0-9][a-z0-9_.-]{1,62}$/i.test(t))throw Error("Runtime placement must be a valid container identifier.");return`tscloud-data-${t.toLowerCase()}`}function DX(t,e){let r=t.desiredState;return t[e]??(r&&typeof r==="object"&&!Array.isArray(r)?r[e]:void 0)}function h_(t){return t.Config?.Labels??{}}class Wn{runtime;backupRoot;constructor(t=new Ol,e=ne(process.cwd(),"backups","data")){this.runtime=t;this.backupRoot=e}async observe(t){let e=FE(t),r=await this.runtime.inspect(e);if(!r)throw Error(`Data container ${e} was not found.`);let d=h_(r),E=await this.runtime.stats(e),n=r.NetworkSettings?.Ports??{},c=Object.values(n).flat().find(Boolean);return{providerId:e,status:r.State?.Status??"unknown",healthy:r.State?.Health?.Status??null,engine:d["ts-cloud.engine"]??null,engineVersion:d["ts-cloud.engine-version"]??null,username:d["ts-cloud.username"]??null,database:d["ts-cloud.database"]??null,endpoint:c?.HostIp||"127.0.0.1",port:c?.HostPort?Number(c.HostPort):null,image:r.Config?.Image??null,startedAt:r.State?.StartedAt??null,metrics:E}}async apply(t,e){let r=String(t.id),d=FE(r),E=String(t.engine);if(E==="libsql")throw Error("libSQL requires an explicitly configured runtime image.");let n=IX[E];if(!n)throw Error(`Unsupported runtime data engine ${E}.`);if(!e)throw Error(`${E} requires a managed credential.`);if(t.publicExposure===!0)throw Error("Container public exposure requires an external reviewed firewall policy; direct publishing is refused.");let c=cd(t.username),_=cd(DX(t,"database")),T=`${d}-secret`,i=`${d}-data`,h=E==="redis"?`appendonly yes
|
|
5541
5541
|
protected-mode yes
|
|
5542
5542
|
requirepass ${e.replaceAll("\\","\\\\").replaceAll(`
|
|
5543
5543
|
`,"")}
|
|
@@ -5581,16 +5581,16 @@ requirepass ${d.replaceAll("\\","\\\\").replaceAll(`
|
|
|
5581
5581
|
`;r+=`| Variable | Type | Description | Example |
|
|
5582
5582
|
`,r+=`|----------|------|-------------|----------|
|
|
5583
5583
|
`;for(let d of t)r+=`| \`${d.key}\` | ${d.type} | ${d.description} | \`${d.example}\` |
|
|
5584
|
-
`;return r}}function Ma(t,e){let r=XI("process");if(typeof r>"u"||!r.env)return e;let d=r.env[t];return d!==void 0?d:e}function wI(t,e,r={}){return gI(t,e,r,new WeakMap)}function gI(t,e,r,d){let{arrayMergeMode:E="replace",skipNullish:n=!1,customMerger:c}=r;if(e===null||e===void 0)return n?t:e;if(c){let _=c(t,e);if(_!==void 0)return _}if(Array.isArray(e)||Array.isArray(t))return $I(t,e,E,d);if(!ur(e)||!ur(t))return e;return Za(t,e,r,d)}function $I(t,e,r,d){if(Array.isArray(e)&&!Array.isArray(t))return e;if(Array.isArray(t)&&!Array.isArray(e))return e;if(Array.isArray(e)&&Array.isArray(t))switch(r){case"replace":return e;case"concat":return Ga(t,e);case"smart":return Va(t,e,d);default:return e}return e}function Ga(t,e){let r=[...e];for(let d of t)if(!r.some((E)=>kN(E,d)))r.push(d);return r}function Va(t,e,r){if(e.length===0)return t;if(t.length===0)return e;if(ur(e[0])&&ur(t[0]))return Ka(t,e,r);if(e.every((d)=>typeof d==="string")&&t.every((d)=>typeof d==="string")){let d=[...e];for(let E of t)if(!d.includes(E))d.push(E);return d}return e}function Ka(t,e,r){let d=[...e];for(let E of t){if(!ur(E)){d.push(E);continue}let n=["id","name","key","path","type"],c=!1;for(let _ of n)if(_ in E){if(d.find((i)=>ur(i)&&(_ in i)&&i[_]===E[_])){c=!0;break}}if(!c)d.push(E)}return d}function Za(t,e,r,d){let E=e;if(ur(E)&&d.has(E))return d.get(E);let n={...t};if(ur(E))d.set(E,n);for(let c in E){if(!Object.prototype.hasOwnProperty.call(E,c))continue;let _=E[c],T=n[c];if(r.skipNullish&&(_===null||_===void 0))continue;if(_===null||_===void 0){n[c]=_;continue}if(ur(_)&&ur(T))n[c]=gI(T,_,r,d);else if(Array.isArray(_)||Array.isArray(T))n[c]=$I(T,_,r.arrayMergeMode||"smart",d);else n[c]=_}return n}function _A(t,e,r="replace"){return wI(t,e,{arrayMergeMode:r==="replace"?"replace":"smart",skipNullish:!0})}function kN(t,e){if(t===e)return!0;if(Array.isArray(t)&&Array.isArray(e)){if(t.length!==e.length)return!1;for(let r=0;r<t.length;r++)if(!kN(t[r],e[r]))return!1;return!0}if(ur(t)&&ur(e)){let r=Object.keys(t),d=Object.keys(e);if(r.length!==d.length)return!1;for(let E of r){if(!Object.prototype.hasOwnProperty.call(e,E))return!1;if(!kN(t[E],e[E]))return!1}return!0}return!1}function ur(t){return Boolean(t&&typeof t==="object"&&!Array.isArray(t))}class xi{extensions=[".ts",".js",".mjs",".cjs",".json",".mts",".cts"];async loadFromPath(t,e,r={}){let{arrayStrategy:d="replace",useCache:E=!0,cacheTtl:n,trackPerformance:c=!0,verbose:_=!1}=r;if(E){let i=sn.getWithFileCheck("file",t);if(i){if(_)console.log(`Configuration loaded from cache: ${t}`);return i}}let T=async()=>{if(!li(t))return null;try{let i=`?t=${Date.now()}`,h=await import(t+i),R=h.default||h,N="default"in h,A=Object.keys(h).length>0;if(!N&&!A)throw new A_(t,Error("Configuration file is empty and exports nothing"),"unknown");if(typeof R!=="object"||R===null||Array.isArray(R))throw new A_(t,Error("Configuration must export a valid object"),"unknown");let w={config:_A(e,R,d),source:{type:"file",path:t,priority:100,timestamp:new Date}};if(E)sn.setWithFileCheck("file",w,t,n);return w}catch(i){throw i instanceof Error?xd.configLoad(t,i):xd.configLoad(t,Error(String(i)))}};if(c)return u_.track("loadFromPath",T,{path:t});return T()}async tryLoadFromPaths(t,e,r={}){for(let d of t)try{let E=await this.loadFromPath(d,e,r);if(E)return E}catch(E){if(E instanceof Error&&E.name==="ConfigLoadError")throw E;if(r.verbose)console.warn(`Failed to load config from ${d}:`,E)}return null}generateConfigPaths(t,e,r){let d=this.generateNamePatterns(t,r),E=[];for(let n of d)for(let c of this.extensions)E.push(zN(e,`${n}${c}`));return E}generateNamePatterns(t,e){let r=[];if(r.push("config",".config"),t)r.push(t,`.${t}.config`,`${t}.config`,`.${t}`);if(e){if(r.push(e,`.${e}.config`,`${e}.config`,`.${e}`),t)r.push(`${t}.${e}.config`,`.${t}.${e}.config`)}return r.filter(Boolean)}checkFileAccess(t){return fI(async()=>{return li(t)},{maxRetries:2,retryDelay:100,fallback:!1})}async discoverConfigFiles(t,e,r){let d=[];if(!li(t))return d;if(e||r){let E=this.generateNamePatterns(e||"",r);for(let n of E)for(let c of this.extensions){let _=zN(t,`${n}${c}`);if(await this.checkFileAccess(_))d.push(_)}}else try{let{readdirSync:E}=await import("fs"),n=E(t);for(let c of n)if(this.looksLikeConfigFile(c)){let _=zN(t,c);if(await this.checkFileAccess(_))d.push(_)}}catch{return[]}return d}looksLikeConfigFile(t){return[/\.config\.(ts|js|mjs|cjs|json|mts|cts)$/,/^\..*\.(ts|js|mjs|cjs|json|mts|cts)$/,/config\.(ts|js|mjs|cjs|json|mts|cts)$/].some((r)=>r.test(t))}async validateConfigFile(t){let e=[];try{if(!li(t))return e.push("Configuration file does not exist"),e;let r=await import(t),d=r.default||r;if(d===void 0)e.push("Configuration file must export a default value or named exports");else if(typeof d!=="object"||d===null)e.push("Configuration must be an object");else if(Array.isArray(d))e.push("Configuration cannot be an array at the root level");if(t.endsWith(".json"))try{let{readFileSync:E}=await import("fs"),n=E(t,"utf8");JSON.parse(n)}catch(E){e.push(`Invalid JSON syntax: ${E}`)}}catch(r){e.push(`Failed to load configuration file: ${r}`)}return e}async getFileModificationTime(t){try{let{statSync:e}=await import("fs");return e(t).mtime}catch{return null}}async preloadConfigurations(t,e={}){let r=new Map;return await Promise.allSettled(t.map(async(d)=>{try{let E=await this.loadFromPath(d,{},e);if(E)r.set(d,E.config)}catch(E){if(e.verbose)console.warn(`Failed to preload ${d}:`,E)}})),r}}class TA{async validateConfiguration(t,e,r={}){let{stopOnFirstError:d=!1,validateRequired:E=!0,validateTypes:n=!0,customRules:c=[],trackPerformance:_=!0,verbose:T=!1}=r,i=async()=>{let h=[],R=[],N={stopOnFirstError:d,validateRequired:E,validateTypes:n,customRules:c,trackPerformance:_,verbose:T};try{if(typeof e==="string")return await this.validateWithSchemaFile(t,e,N);else if(Array.isArray(e))return this.validateWithRules(t,[...e,...c],N);else return this.validateWithJSONSchema(t,e,N)}catch(A){return h.push({path:"",message:`Validation failed: ${A}`,rule:"system"}),{isValid:!1,errors:h,warnings:R}}};if(_)return await u_.track("validateConfiguration",i);return i()}async validateWithSchemaFile(t,e,r){try{if(!ca(e))throw new L_(e,[{path:"",message:"Schema file does not exist"}]);let d=await import(e),E=d.default||d;if(Array.isArray(E))return this.validateWithRules(t,E,r);else return this.validateWithJSONSchema(t,E,r)}catch(d){throw new L_(e,[{path:"",message:`Failed to load schema: ${d}`}])}}validateWithJSONSchema(t,e,r){let d=[],E=[];return this.validateObjectAgainstSchema(t,e,"",d,E,r),{isValid:d.length===0,errors:d,warnings:E}}validateObjectAgainstSchema(t,e,r,d,E,n){if(n.validateTypes&&e.type){let c=Array.isArray(t)?"array":typeof t,_=Array.isArray(e.type)?e.type:[e.type];if(!_.includes(c)){if(d.push({path:r,message:`Expected type ${_.join(" or ")}, got ${c}`,expected:_.join(" or "),actual:c,rule:"type"}),n.stopOnFirstError)return}}if(e.enum&&!e.enum.includes(t)){if(d.push({path:r,message:`Value must be one of: ${e.enum.join(", ")}`,expected:e.enum.join(", "),actual:t,rule:"enum"}),n.stopOnFirstError)return}if(typeof t==="string"){if(e.minLength!==void 0&&t.length<e.minLength)d.push({path:r,message:`String length must be at least ${e.minLength}`,expected:`>= ${e.minLength}`,actual:t.length,rule:"minLength"});if(e.maxLength!==void 0&&t.length>e.maxLength)d.push({path:r,message:`String length must not exceed ${e.maxLength}`,expected:`<= ${e.maxLength}`,actual:t.length,rule:"maxLength"});if(e.pattern){if(!new RegExp(e.pattern).test(t))d.push({path:r,message:`String does not match pattern ${e.pattern}`,expected:e.pattern,actual:t,rule:"pattern"})}}if(typeof t==="number"){if(e.minimum!==void 0&&t<e.minimum)d.push({path:r,message:`Value must be at least ${e.minimum}`,expected:`>= ${e.minimum}`,actual:t,rule:"minimum"});if(e.maximum!==void 0&&t>e.maximum)d.push({path:r,message:`Value must not exceed ${e.maximum}`,expected:`<= ${e.maximum}`,actual:t,rule:"maximum"})}if(Array.isArray(t)&&e.items)for(let c=0;c<t.length;c++){let _=r?`${r}[${c}]`:`[${c}]`;if(this.validateObjectAgainstSchema(t[c],e.items,_,d,E,n),n.stopOnFirstError&&d.length>0)return}if(t&&typeof t==="object"&&!Array.isArray(t)){let c=t;if(n.validateRequired&&e.required){for(let _ of e.required)if(!(_ in c)){if(d.push({path:r?`${r}.${_}`:_,message:`Missing required property '${_}'`,expected:"required",rule:"required"}),n.stopOnFirstError)return}}if(e.properties){for(let[_,T]of Object.entries(e.properties))if(_ in c){let i=r?`${r}.${_}`:_;if(this.validateObjectAgainstSchema(c[_],T,i,d,E,n),n.stopOnFirstError&&d.length>0)return}}if(e.additionalProperties===!1){let _=new Set(Object.keys(e.properties||{}));for(let T of Object.keys(c))if(!_.has(T))E.push({path:r?`${r}.${T}`:T,message:`Additional property '${T}' is not allowed`,rule:"additionalProperties"})}}}validateWithRules(t,e,r){let d=[],E=[];for(let n of e)try{let c=this.getValueByPath(t,n.path),_=this.validateWithRule(c,n,n.path);if(d.push(..._),r.stopOnFirstError&&d.length>0)break}catch(c){d.push({path:n.path,message:`Rule validation failed: ${c}`,rule:"system"})}return{isValid:d.length===0,errors:d,warnings:E}}validateWithRule(t,e,r){let d=[];if(e.required&&(t===void 0||t===null))return d.push({path:r,message:e.message||`Property '${r}' is required`,expected:"required",rule:"required"}),d;if(t===void 0||t===null)return d;if(e.type){let E=Array.isArray(t)?"array":typeof t;if(E!==e.type)d.push({path:r,message:e.message||`Expected type ${e.type}, got ${E}`,expected:e.type,actual:E,rule:"type"})}if(e.min!==void 0){let E=Array.isArray(t)?t.length:typeof t==="string"?t.length:typeof t==="number"?t:0;if(E<e.min)d.push({path:r,message:e.message||`Value must be at least ${e.min}`,expected:`>= ${e.min}`,actual:E,rule:"min"})}if(e.max!==void 0){let E=Array.isArray(t)?t.length:typeof t==="string"?t.length:typeof t==="number"?t:0;if(E>e.max)d.push({path:r,message:e.message||`Value must not exceed ${e.max}`,expected:`<= ${e.max}`,actual:E,rule:"max"})}if(e.pattern&&typeof t==="string"){if(!e.pattern.test(t))d.push({path:r,message:e.message||`Value does not match pattern ${e.pattern}`,expected:e.pattern.toString(),actual:t,rule:"pattern"})}if(e.enum&&!e.enum.includes(t))d.push({path:r,message:e.message||`Value must be one of: ${e.enum.join(", ")}`,expected:e.enum.join(", "),actual:t,rule:"enum"});if(e.validator){let E=e.validator(t);if(E)d.push({path:r,message:e.message||E,rule:"custom"})}return d}getValueByPath(t,e){if(!e)return t;let r=e.split("."),d=t;for(let E of r)if(d&&typeof d==="object"&&E in d)d=d[E];else return;return d}generateRulesFromInterface(t){let e=[],r=t.matchAll(/(\w+)(\?)?:\s*(\w+)/g);for(let d of r){let[,E,n,c]=d;e.push({path:E,required:!n,type:this.mapTypeScriptType(c)})}return e}mapTypeScriptType(t){switch(t.toLowerCase()){case"string":return"string";case"number":return"number";case"boolean":return"boolean";case"array":return"array";case"object":return"object";default:return"object"}}static createCommonRules(){return{server:[{path:"port",required:!0,type:"number",min:1,max:65535},{path:"host",required:!0,type:"string",min:1},{path:"ssl",type:"boolean"}],database:[{path:"url",required:!0,type:"string",min:1},{path:"pool",type:"number",min:1,max:100},{path:"timeout",type:"number",min:0}],api:[{path:"baseUrl",required:!0,type:"string",pattern:FI},{path:"timeout",type:"number",min:0},{path:"retries",type:"number",min:0,max:10}]}}}class iA{fileLoader=new xi;envProcessor=new bi;validator=new TA;async loadConfig(t){let e=Date.now(),{cache:r,performance:d,schema:E,validate:n,...c}=t;try{if(r?.enabled){let T=this.checkCache(c.name||"",c);if(T)return T}let _;try{_=await this.loadConfigurationStrategies(c,!0,r)}catch(T){let i=c.__strictErrorHandling;if(T instanceof Error&&T.name==="ConfigNotFoundError"){if(i)throw T;_={...await this.applyEnvironmentVariables(c.name||"",c.defaultConfig,c.checkEnv!==!1,c.verbose||!1),warnings:[`No configuration file found for "${c.name||"config"}", using defaults with environment variables`]}}else if(T instanceof Error&&T.name==="ConfigLoadError"){let h=T.message.includes("EACCES")||T.message.includes("EPERM")||T.message.includes("permission denied"),R=!h&&(T.message.includes("syntax")||T.message.includes("Expected")||T.message.includes("Unexpected")||T.message.includes("BuildMessage")||T.message.includes("errors building")),N=T.message.includes("Configuration must export a valid object")||T.message.includes("Configuration file is empty and exports nothing");if(i&&(N||h))throw T;if(R&&(!i||!N))_={...await this.applyEnvironmentVariables(c.name||"",c.defaultConfig,c.checkEnv!==!1,c.verbose||!1),warnings:["Configuration file has syntax errors, using defaults with environment variables"]};else if(!i)_={...await this.applyEnvironmentVariables(c.name||"",c.defaultConfig,c.checkEnv!==!1,c.verbose||!1),warnings:[`Configuration loading error, using defaults: ${T.message}`]};else throw T}else _={...await this.applyEnvironmentVariables(c.name||"",c.defaultConfig,c.checkEnv!==!1,c.verbose||!1),warnings:[`Configuration loading failed, using defaults: ${T instanceof Error?T.message:String(T)}`]}}if(E||n)await this.validateConfiguration(_.config,E,n,c.name);if(r?.enabled&&_)this.cacheResult(c.name||"",_,r,c);if(d?.enabled){let T={operation:"loadConfig",duration:Date.now()-e,configName:c.name,timestamp:new Date};if(d.onMetrics)d.onMetrics(T);if(d.slowThreshold&&T.duration>d.slowThreshold)Xr.warn(`Slow configuration loading detected: ${T.duration}ms for ${c.name}`);_.metrics=T}return _}catch(_){let T=Date.now()-e;throw Xr.error(`Configuration loading failed after ${T}ms:`,[_ instanceof Error?_:Error(String(_))]),_}}async loadConfigurationStrategies(t,e=!1,r){let{name:d="",alias:E,cwd:n,configDir:c,defaultConfig:_,checkEnv:T=!0,arrayStrategy:i="replace",verbose:h=!1}=t,R=n||HE.cwd(),N=[],A=await this.loadLocalConfiguration(d,E,R,c,_,i,h,T,r);if(A)return N.push(...this.getLocalSearchPaths(d,E,R,c)),this.finalizeResult(A,N,T,d,h);let u=await this.loadHomeConfiguration(d,E,_,i,h,T);if(u)return N.push(...this.getHomeSearchPaths(d,E)),this.finalizeResult(u,N,T,d,h);let f=await this.loadPackageJsonConfiguration(d,E,R,_,i,h,T);if(f)return N.push(He(R,"package.json")),this.finalizeResult(f,N,T,d,h);if(N.push(...this.getAllSearchPaths(d,E,R,c)),e)throw xd.configNotFound(d,N,E);return{...await this.applyEnvironmentVariables(d,_,T,h),warnings:[`No configuration file found for "${d}"${E?` or alias "${E}"`:""}, using defaults with environment variables`]}}async loadLocalConfiguration(t,e,r,d,E,n,c,_,T){let i=_?S_(t,E,c):E,h=this.getLocalDirectories(r,d);for(let R of h){if(c)Xr.info(`Searching for configuration in: ${R}`);let N=this.fileLoader.generateConfigPaths(t,R,e),A=await this.fileLoader.tryLoadFromPaths(N,i,{arrayStrategy:n,verbose:c,cacheTtl:T?.ttl,useCache:!T?.ttl||T.ttl>100});if(A){if(c)Xr.success(`Configuration loaded from: ${A.source.path}`);return A}}return null}async loadHomeConfiguration(t,e,r,d,E,n){if(!t)return null;let c=n?S_(t,r,E):r,_=[He(Yn(),".config",t),He(Yn(),".config"),Yn()];for(let T of _){if(E)Xr.info(`Checking home directory: ${T}`);let i=this.fileLoader.generateConfigPaths(t,T,e),h=await this.fileLoader.tryLoadFromPaths(i,c,{arrayStrategy:d,verbose:E});if(h){if(E)Xr.success(`Configuration loaded from home directory: ${h.source.path}`);return h}}return null}async loadPackageJsonConfiguration(t,e,r,d,E,n,c){let _=c?S_(t,d,n):d;try{let T=He(r,"package.json");if(!KN(T))return null;let i=await import(T),h=i[t],R=t;if(!h&&e)h=i[e],R=e;if(h&&typeof h==="object"&&!Array.isArray(h)){if(n)Xr.success(`Configuration loaded from package.json: ${R}`);return{config:_A(_,h,E),source:{type:"package.json",path:T,priority:30,timestamp:new Date}}}}catch(T){if(n)Xr.warn("Failed to load package.json:",[T instanceof Error?T:Error(String(T))])}return null}async applyEnvironmentVariables(t,e,r,d){if(!r||!t||typeof e!=="object"||e===null||Array.isArray(e))return{config:e,source:{type:"default",priority:10,timestamp:new Date}};return{config:S_(t,e,d),source:{type:"environment",priority:20,timestamp:new Date}}}async finalizeResult(t,e,r,d,E){return{config:t.config,source:t.source,path:t.source.path}}async validateConfiguration(t,e,r,d){let E=[];if(r){let n=r(t);if(n)E.push(...n)}if(e){let n=await this.validator.validateConfiguration(t,e);if(!n.isValid)E.push(...n.errors.map((c)=>c.path?`${c.path}: ${c.message}`:c.message))}if(E.length>0)throw xd.configValidation(d||"unknown",E,d)}checkCache(t,e){let r=this.generateCacheKey(t,e);return sn.get(r)||null}cacheResult(t,e,r,d){let E=this.generateCacheKey(t,d);sn.set(E,e,void 0,r.ttl)}generateCacheKey(t,e){let r=[t];if(e.alias)r.push(`alias:${e.alias}`);if(e.cwd)r.push(`cwd:${e.cwd}`);if(e.configDir)r.push(`configDir:${e.configDir}`);if("checkEnv"in e)r.push(`checkEnv:${e.checkEnv}`);return r.join("|")}getLocalDirectories(t,e){return Array.from(new Set([t,He(t,"config"),He(t,".config"),e?He(t,e):void 0].filter(Boolean)))}getAllSearchPaths(t,e,r,d){let E=[];return E.push(...this.getLocalSearchPaths(t,e,r,d)),E.push(...this.getHomeSearchPaths(t,e)),E.push(He(r,"package.json")),E}getLocalSearchPaths(t,e,r,d){let E=this.getLocalDirectories(r,d),n=[];for(let c of E)n.push(...this.fileLoader.generateConfigPaths(t,c,e));return n}getHomeSearchPaths(t,e){if(!t)return[];let r=[He(Yn(),".config",t),He(Yn(),".config"),Yn()],d=[];for(let E of r)d.push(...this.fileLoader.generateConfigPaths(t,E,e));return d}async loadConfigWithResult(t){return this.loadConfig(t)}}function rI(t){let r=!(t.message.includes("EACCES")||t.message.includes("EPERM")||t.message.includes("permission denied"))&&(t.message.includes("syntax")||t.message.includes("Expected")||t.message.includes("Unexpected")||t.message.includes("BuildMessage")),d=t.message.includes("Configuration must export a valid object")||t.message.includes("Configuration file is empty and exports nothing");return r||d}async function ka(t){return Nd.loadConfig({...t,__strictErrorHandling:!0})}async function yI(t){let e="defaultConfig"in t&&t.defaultConfig!==void 0?t.defaultConfig:{},r="cache"in t||"performance"in t||"schema"in t||"validate"in t;try{let d;if(r)d=await Nd.loadConfig(t);else d=await Nd.loadConfig({...t,defaultConfig:e,cache:{enabled:!0},performance:{enabled:!1}});return d?.config??e}catch(d){let E=d instanceof Error?d.name:"UnknownError",n=d instanceof Error?d.message:String(d);if(!(E==="ConfigNotFoundError"||E==="ConfigLoadError"||E==="ConfigValidationError"||n.includes("config"))&&t.verbose)Xr.warn("Unexpected error loading config, using defaults:",[d instanceof Error?d:Error(String(d))]);let _=r?{...t,defaultConfig:e}:{...t,defaultConfig:e,cache:{enabled:!0},performance:{enabled:!1}};if("checkEnv"in t?t.checkEnv!==!1:!0)return(await Nd.applyEnvironmentVariables(_.name||"",e,!0,_.verbose||!1))?.config??e;return e}}async function ba(t={defaultConfig:{}}){if(typeof t==="string"){let{cwd:e}=await import("process");try{return(await Nd.loadConfig({name:t,cwd:e(),generatedDir:"./generated",configDir:"./config",defaultConfig:{},checkEnv:!0,arrayStrategy:"replace"})).config}catch(r){if(r instanceof Error&&(r.name==="ConfigNotFoundError"||r.name==="ConfigLoadError"&&rI(r)))return(await Nd.applyEnvironmentVariables(t,{},!0,!1)).config;throw r}}try{return(await Nd.loadConfig({...t,cwd:t.cwd||HE.cwd(),cache:{enabled:!0},performance:{enabled:!1}})).config}catch(e){if(e instanceof Error&&(e.name==="ConfigNotFoundError"||e.name==="ConfigLoadError"&&rI(e)))return(await Nd.applyEnvironmentVariables(t.name||"",t.defaultConfig||{},t.checkEnv!==!1,t.verbose||!1)).config;throw e}}async function xa(t,e,r="replace"){let d=new xi;try{let E=await d.loadFromPath(t,e,{arrayStrategy:r,useCache:!1,trackPerformance:!1});return E?E.config:null}catch{return null}}function S_(t,e,r=!1){let d=new bi,E=t.toUpperCase().replace(/[^A-Z0-9]/g,"_");function n(c,_=[]){let T={...c};for(let[i,h]of Object.entries(c)){let R=[..._,i],N=[`${E}_${R.join("_").toUpperCase()}`,`${E}_${R.map((f)=>f.toUpperCase()).join("")}`,`${E}_${R.map((f)=>f.replace(/([A-Z])/g,"_$1").toUpperCase()).join("")}`],A,u;for(let f of N)if(A=HE.env[f],A!==void 0){u=f;break}if(A!==void 0&&u)if(typeof h==="boolean")T[i]=["true","1","yes"].includes(A.toLowerCase());else if(typeof h==="number"){let f=Number(A);if(!Number.isNaN(f))T[i]=f}else if(Array.isArray(h))try{T[i]=JSON.parse(A)}catch{T[i]=A.split(",").map((f)=>f.trim())}else T[i]=A;else if(h&&typeof h==="object"&&!Array.isArray(h))T[i]=n(h,R)}return T}return n(e)}function qa(t){let e=He(HE.cwd(),t.configDir),r=He(HE.cwd(),t.generatedDir),d=He(r,"config-types.ts");if(!KN(Fl(d)))WX(Fl(d),{recursive:!0,mode:511});let E=KN(e)?vX(e).map((c)=>c.replace(/\.(ts|js|mjs|cjs|mts|cts|json)$/,"")).sort():[],n=`// Generated by bunfig v${w2}
|
|
5584
|
+
`;return r}}function Ma(t,e){let r=XI("process");if(typeof r>"u"||!r.env)return e;let d=r.env[t];return d!==void 0?d:e}function wI(t,e,r={}){return gI(t,e,r,new WeakMap)}function gI(t,e,r,d){let{arrayMergeMode:E="replace",skipNullish:n=!1,customMerger:c}=r;if(e===null||e===void 0)return n?t:e;if(c){let _=c(t,e);if(_!==void 0)return _}if(Array.isArray(e)||Array.isArray(t))return $I(t,e,E,d);if(!ur(e)||!ur(t))return e;return Za(t,e,r,d)}function $I(t,e,r,d){if(Array.isArray(e)&&!Array.isArray(t))return e;if(Array.isArray(t)&&!Array.isArray(e))return e;if(Array.isArray(e)&&Array.isArray(t))switch(r){case"replace":return e;case"concat":return Ga(t,e);case"smart":return Va(t,e,d);default:return e}return e}function Ga(t,e){let r=[...e];for(let d of t)if(!r.some((E)=>kN(E,d)))r.push(d);return r}function Va(t,e,r){if(e.length===0)return t;if(t.length===0)return e;if(ur(e[0])&&ur(t[0]))return Ka(t,e,r);if(e.every((d)=>typeof d==="string")&&t.every((d)=>typeof d==="string")){let d=[...e];for(let E of t)if(!d.includes(E))d.push(E);return d}return e}function Ka(t,e,r){let d=[...e];for(let E of t){if(!ur(E)){d.push(E);continue}let n=["id","name","key","path","type"],c=!1;for(let _ of n)if(_ in E){if(d.find((i)=>ur(i)&&(_ in i)&&i[_]===E[_])){c=!0;break}}if(!c)d.push(E)}return d}function Za(t,e,r,d){let E=e;if(ur(E)&&d.has(E))return d.get(E);let n={...t};if(ur(E))d.set(E,n);for(let c in E){if(!Object.prototype.hasOwnProperty.call(E,c))continue;let _=E[c],T=n[c];if(r.skipNullish&&(_===null||_===void 0))continue;if(_===null||_===void 0){n[c]=_;continue}if(ur(_)&&ur(T))n[c]=gI(T,_,r,d);else if(Array.isArray(_)||Array.isArray(T))n[c]=$I(T,_,r.arrayMergeMode||"smart",d);else n[c]=_}return n}function _A(t,e,r="replace"){return wI(t,e,{arrayMergeMode:r==="replace"?"replace":"smart",skipNullish:!0})}function kN(t,e){if(t===e)return!0;if(Array.isArray(t)&&Array.isArray(e)){if(t.length!==e.length)return!1;for(let r=0;r<t.length;r++)if(!kN(t[r],e[r]))return!1;return!0}if(ur(t)&&ur(e)){let r=Object.keys(t),d=Object.keys(e);if(r.length!==d.length)return!1;for(let E of r){if(!Object.prototype.hasOwnProperty.call(e,E))return!1;if(!kN(t[E],e[E]))return!1}return!0}return!1}function ur(t){return Boolean(t&&typeof t==="object"&&!Array.isArray(t))}class xi{extensions=[".ts",".js",".mjs",".cjs",".json",".mts",".cts"];async loadFromPath(t,e,r={}){let{arrayStrategy:d="replace",useCache:E=!0,cacheTtl:n,trackPerformance:c=!0,verbose:_=!1}=r;if(E){let i=sn.getWithFileCheck("file",t);if(i){if(_)console.log(`Configuration loaded from cache: ${t}`);return i}}let T=async()=>{if(!li(t))return null;try{let i=`?t=${Date.now()}`,h=await import(t+i),R=h.default||h,N="default"in h,A=Object.keys(h).length>0;if(!N&&!A)throw new A_(t,Error("Configuration file is empty and exports nothing"),"unknown");if(typeof R!=="object"||R===null||Array.isArray(R))throw new A_(t,Error("Configuration must export a valid object"),"unknown");let w={config:_A(e,R,d),source:{type:"file",path:t,priority:100,timestamp:new Date}};if(E)sn.setWithFileCheck("file",w,t,n);return w}catch(i){throw i instanceof Error?xd.configLoad(t,i):xd.configLoad(t,Error(String(i)))}};if(c)return u_.track("loadFromPath",T,{path:t});return T()}async tryLoadFromPaths(t,e,r={}){for(let d of t)try{let E=await this.loadFromPath(d,e,r);if(E)return E}catch(E){if(E instanceof Error&&E.name==="ConfigLoadError")throw E;if(r.verbose)console.warn(`Failed to load config from ${d}:`,E)}return null}generateConfigPaths(t,e,r){let d=this.generateNamePatterns(t,r),E=[];for(let n of d)for(let c of this.extensions)E.push(zN(e,`${n}${c}`));return E}generateNamePatterns(t,e){let r=[];if(r.push("config",".config"),t)r.push(t,`.${t}.config`,`${t}.config`,`.${t}`);if(e){if(r.push(e,`.${e}.config`,`${e}.config`,`.${e}`),t)r.push(`${t}.${e}.config`,`.${t}.${e}.config`)}return r.filter(Boolean)}checkFileAccess(t){return fI(async()=>{return li(t)},{maxRetries:2,retryDelay:100,fallback:!1})}async discoverConfigFiles(t,e,r){let d=[];if(!li(t))return d;if(e||r){let E=this.generateNamePatterns(e||"",r);for(let n of E)for(let c of this.extensions){let _=zN(t,`${n}${c}`);if(await this.checkFileAccess(_))d.push(_)}}else try{let{readdirSync:E}=await import("fs"),n=E(t);for(let c of n)if(this.looksLikeConfigFile(c)){let _=zN(t,c);if(await this.checkFileAccess(_))d.push(_)}}catch{return[]}return d}looksLikeConfigFile(t){return[/\.config\.(ts|js|mjs|cjs|json|mts|cts)$/,/^\..*\.(ts|js|mjs|cjs|json|mts|cts)$/,/config\.(ts|js|mjs|cjs|json|mts|cts)$/].some((r)=>r.test(t))}async validateConfigFile(t){let e=[];try{if(!li(t))return e.push("Configuration file does not exist"),e;let r=await import(t),d=r.default||r;if(d===void 0)e.push("Configuration file must export a default value or named exports");else if(typeof d!=="object"||d===null)e.push("Configuration must be an object");else if(Array.isArray(d))e.push("Configuration cannot be an array at the root level");if(t.endsWith(".json"))try{let{readFileSync:E}=await import("fs"),n=E(t,"utf8");JSON.parse(n)}catch(E){e.push(`Invalid JSON syntax: ${E}`)}}catch(r){e.push(`Failed to load configuration file: ${r}`)}return e}async getFileModificationTime(t){try{let{statSync:e}=await import("fs");return e(t).mtime}catch{return null}}async preloadConfigurations(t,e={}){let r=new Map;return await Promise.allSettled(t.map(async(d)=>{try{let E=await this.loadFromPath(d,{},e);if(E)r.set(d,E.config)}catch(E){if(e.verbose)console.warn(`Failed to preload ${d}:`,E)}})),r}}class TA{async validateConfiguration(t,e,r={}){let{stopOnFirstError:d=!1,validateRequired:E=!0,validateTypes:n=!0,customRules:c=[],trackPerformance:_=!0,verbose:T=!1}=r,i=async()=>{let h=[],R=[],N={stopOnFirstError:d,validateRequired:E,validateTypes:n,customRules:c,trackPerformance:_,verbose:T};try{if(typeof e==="string")return await this.validateWithSchemaFile(t,e,N);else if(Array.isArray(e))return this.validateWithRules(t,[...e,...c],N);else return this.validateWithJSONSchema(t,e,N)}catch(A){return h.push({path:"",message:`Validation failed: ${A}`,rule:"system"}),{isValid:!1,errors:h,warnings:R}}};if(_)return await u_.track("validateConfiguration",i);return i()}async validateWithSchemaFile(t,e,r){try{if(!ca(e))throw new L_(e,[{path:"",message:"Schema file does not exist"}]);let d=await import(e),E=d.default||d;if(Array.isArray(E))return this.validateWithRules(t,E,r);else return this.validateWithJSONSchema(t,E,r)}catch(d){throw new L_(e,[{path:"",message:`Failed to load schema: ${d}`}])}}validateWithJSONSchema(t,e,r){let d=[],E=[];return this.validateObjectAgainstSchema(t,e,"",d,E,r),{isValid:d.length===0,errors:d,warnings:E}}validateObjectAgainstSchema(t,e,r,d,E,n){if(n.validateTypes&&e.type){let c=Array.isArray(t)?"array":typeof t,_=Array.isArray(e.type)?e.type:[e.type];if(!_.includes(c)){if(d.push({path:r,message:`Expected type ${_.join(" or ")}, got ${c}`,expected:_.join(" or "),actual:c,rule:"type"}),n.stopOnFirstError)return}}if(e.enum&&!e.enum.includes(t)){if(d.push({path:r,message:`Value must be one of: ${e.enum.join(", ")}`,expected:e.enum.join(", "),actual:t,rule:"enum"}),n.stopOnFirstError)return}if(typeof t==="string"){if(e.minLength!==void 0&&t.length<e.minLength)d.push({path:r,message:`String length must be at least ${e.minLength}`,expected:`>= ${e.minLength}`,actual:t.length,rule:"minLength"});if(e.maxLength!==void 0&&t.length>e.maxLength)d.push({path:r,message:`String length must not exceed ${e.maxLength}`,expected:`<= ${e.maxLength}`,actual:t.length,rule:"maxLength"});if(e.pattern){if(!new RegExp(e.pattern).test(t))d.push({path:r,message:`String does not match pattern ${e.pattern}`,expected:e.pattern,actual:t,rule:"pattern"})}}if(typeof t==="number"){if(e.minimum!==void 0&&t<e.minimum)d.push({path:r,message:`Value must be at least ${e.minimum}`,expected:`>= ${e.minimum}`,actual:t,rule:"minimum"});if(e.maximum!==void 0&&t>e.maximum)d.push({path:r,message:`Value must not exceed ${e.maximum}`,expected:`<= ${e.maximum}`,actual:t,rule:"maximum"})}if(Array.isArray(t)&&e.items)for(let c=0;c<t.length;c++){let _=r?`${r}[${c}]`:`[${c}]`;if(this.validateObjectAgainstSchema(t[c],e.items,_,d,E,n),n.stopOnFirstError&&d.length>0)return}if(t&&typeof t==="object"&&!Array.isArray(t)){let c=t;if(n.validateRequired&&e.required){for(let _ of e.required)if(!(_ in c)){if(d.push({path:r?`${r}.${_}`:_,message:`Missing required property '${_}'`,expected:"required",rule:"required"}),n.stopOnFirstError)return}}if(e.properties){for(let[_,T]of Object.entries(e.properties))if(_ in c){let i=r?`${r}.${_}`:_;if(this.validateObjectAgainstSchema(c[_],T,i,d,E,n),n.stopOnFirstError&&d.length>0)return}}if(e.additionalProperties===!1){let _=new Set(Object.keys(e.properties||{}));for(let T of Object.keys(c))if(!_.has(T))E.push({path:r?`${r}.${T}`:T,message:`Additional property '${T}' is not allowed`,rule:"additionalProperties"})}}}validateWithRules(t,e,r){let d=[],E=[];for(let n of e)try{let c=this.getValueByPath(t,n.path),_=this.validateWithRule(c,n,n.path);if(d.push(..._),r.stopOnFirstError&&d.length>0)break}catch(c){d.push({path:n.path,message:`Rule validation failed: ${c}`,rule:"system"})}return{isValid:d.length===0,errors:d,warnings:E}}validateWithRule(t,e,r){let d=[];if(e.required&&(t===void 0||t===null))return d.push({path:r,message:e.message||`Property '${r}' is required`,expected:"required",rule:"required"}),d;if(t===void 0||t===null)return d;if(e.type){let E=Array.isArray(t)?"array":typeof t;if(E!==e.type)d.push({path:r,message:e.message||`Expected type ${e.type}, got ${E}`,expected:e.type,actual:E,rule:"type"})}if(e.min!==void 0){let E=Array.isArray(t)?t.length:typeof t==="string"?t.length:typeof t==="number"?t:0;if(E<e.min)d.push({path:r,message:e.message||`Value must be at least ${e.min}`,expected:`>= ${e.min}`,actual:E,rule:"min"})}if(e.max!==void 0){let E=Array.isArray(t)?t.length:typeof t==="string"?t.length:typeof t==="number"?t:0;if(E>e.max)d.push({path:r,message:e.message||`Value must not exceed ${e.max}`,expected:`<= ${e.max}`,actual:E,rule:"max"})}if(e.pattern&&typeof t==="string"){if(!e.pattern.test(t))d.push({path:r,message:e.message||`Value does not match pattern ${e.pattern}`,expected:e.pattern.toString(),actual:t,rule:"pattern"})}if(e.enum&&!e.enum.includes(t))d.push({path:r,message:e.message||`Value must be one of: ${e.enum.join(", ")}`,expected:e.enum.join(", "),actual:t,rule:"enum"});if(e.validator){let E=e.validator(t);if(E)d.push({path:r,message:e.message||E,rule:"custom"})}return d}getValueByPath(t,e){if(!e)return t;let r=e.split("."),d=t;for(let E of r)if(d&&typeof d==="object"&&E in d)d=d[E];else return;return d}generateRulesFromInterface(t){let e=[],r=t.matchAll(/(\w+)(\?)?:\s*(\w+)/g);for(let d of r){let[,E,n,c]=d;e.push({path:E,required:!n,type:this.mapTypeScriptType(c)})}return e}mapTypeScriptType(t){switch(t.toLowerCase()){case"string":return"string";case"number":return"number";case"boolean":return"boolean";case"array":return"array";case"object":return"object";default:return"object"}}static createCommonRules(){return{server:[{path:"port",required:!0,type:"number",min:1,max:65535},{path:"host",required:!0,type:"string",min:1},{path:"ssl",type:"boolean"}],database:[{path:"url",required:!0,type:"string",min:1},{path:"pool",type:"number",min:1,max:100},{path:"timeout",type:"number",min:0}],api:[{path:"baseUrl",required:!0,type:"string",pattern:FI},{path:"timeout",type:"number",min:0},{path:"retries",type:"number",min:0,max:10}]}}}class iA{fileLoader=new xi;envProcessor=new bi;validator=new TA;async loadConfig(t){let e=Date.now(),{cache:r,performance:d,schema:E,validate:n,...c}=t;try{if(r?.enabled){let T=this.checkCache(c.name||"",c);if(T)return T}let _;try{_=await this.loadConfigurationStrategies(c,!0,r)}catch(T){let i=c.__strictErrorHandling;if(T instanceof Error&&T.name==="ConfigNotFoundError"){if(i)throw T;_={...await this.applyEnvironmentVariables(c.name||"",c.defaultConfig,c.checkEnv!==!1,c.verbose||!1),warnings:[`No configuration file found for "${c.name||"config"}", using defaults with environment variables`]}}else if(T instanceof Error&&T.name==="ConfigLoadError"){let h=T.message.includes("EACCES")||T.message.includes("EPERM")||T.message.includes("permission denied"),R=!h&&(T.message.includes("syntax")||T.message.includes("Expected")||T.message.includes("Unexpected")||T.message.includes("BuildMessage")||T.message.includes("errors building")),N=T.message.includes("Configuration must export a valid object")||T.message.includes("Configuration file is empty and exports nothing");if(i&&(N||h))throw T;if(R&&(!i||!N))_={...await this.applyEnvironmentVariables(c.name||"",c.defaultConfig,c.checkEnv!==!1,c.verbose||!1),warnings:["Configuration file has syntax errors, using defaults with environment variables"]};else if(!i)_={...await this.applyEnvironmentVariables(c.name||"",c.defaultConfig,c.checkEnv!==!1,c.verbose||!1),warnings:[`Configuration loading error, using defaults: ${T.message}`]};else throw T}else _={...await this.applyEnvironmentVariables(c.name||"",c.defaultConfig,c.checkEnv!==!1,c.verbose||!1),warnings:[`Configuration loading failed, using defaults: ${T instanceof Error?T.message:String(T)}`]}}if(E||n)await this.validateConfiguration(_.config,E,n,c.name);if(r?.enabled&&_)this.cacheResult(c.name||"",_,r,c);if(d?.enabled){let T={operation:"loadConfig",duration:Date.now()-e,configName:c.name,timestamp:new Date};if(d.onMetrics)d.onMetrics(T);if(d.slowThreshold&&T.duration>d.slowThreshold)ar.warn(`Slow configuration loading detected: ${T.duration}ms for ${c.name}`);_.metrics=T}return _}catch(_){let T=Date.now()-e;throw ar.error(`Configuration loading failed after ${T}ms:`,[_ instanceof Error?_:Error(String(_))]),_}}async loadConfigurationStrategies(t,e=!1,r){let{name:d="",alias:E,cwd:n,configDir:c,defaultConfig:_,checkEnv:T=!0,arrayStrategy:i="replace",verbose:h=!1}=t,R=n||HE.cwd(),N=[],A=await this.loadLocalConfiguration(d,E,R,c,_,i,h,T,r);if(A)return N.push(...this.getLocalSearchPaths(d,E,R,c)),this.finalizeResult(A,N,T,d,h);let u=await this.loadHomeConfiguration(d,E,_,i,h,T);if(u)return N.push(...this.getHomeSearchPaths(d,E)),this.finalizeResult(u,N,T,d,h);let f=await this.loadPackageJsonConfiguration(d,E,R,_,i,h,T);if(f)return N.push(He(R,"package.json")),this.finalizeResult(f,N,T,d,h);if(N.push(...this.getAllSearchPaths(d,E,R,c)),e)throw xd.configNotFound(d,N,E);return{...await this.applyEnvironmentVariables(d,_,T,h),warnings:[`No configuration file found for "${d}"${E?` or alias "${E}"`:""}, using defaults with environment variables`]}}async loadLocalConfiguration(t,e,r,d,E,n,c,_,T){let i=_?S_(t,E,c):E,h=this.getLocalDirectories(r,d);for(let R of h){if(c)ar.info(`Searching for configuration in: ${R}`);let N=this.fileLoader.generateConfigPaths(t,R,e),A=await this.fileLoader.tryLoadFromPaths(N,i,{arrayStrategy:n,verbose:c,cacheTtl:T?.ttl,useCache:!T?.ttl||T.ttl>100});if(A){if(c)ar.success(`Configuration loaded from: ${A.source.path}`);return A}}return null}async loadHomeConfiguration(t,e,r,d,E,n){if(!t)return null;let c=n?S_(t,r,E):r,_=[He(Yn(),".config",t),He(Yn(),".config"),Yn()];for(let T of _){if(E)ar.info(`Checking home directory: ${T}`);let i=this.fileLoader.generateConfigPaths(t,T,e),h=await this.fileLoader.tryLoadFromPaths(i,c,{arrayStrategy:d,verbose:E});if(h){if(E)ar.success(`Configuration loaded from home directory: ${h.source.path}`);return h}}return null}async loadPackageJsonConfiguration(t,e,r,d,E,n,c){let _=c?S_(t,d,n):d;try{let T=He(r,"package.json");if(!KN(T))return null;let i=await import(T),h=i[t],R=t;if(!h&&e)h=i[e],R=e;if(h&&typeof h==="object"&&!Array.isArray(h)){if(n)ar.success(`Configuration loaded from package.json: ${R}`);return{config:_A(_,h,E),source:{type:"package.json",path:T,priority:30,timestamp:new Date}}}}catch(T){if(n)ar.warn("Failed to load package.json:",[T instanceof Error?T:Error(String(T))])}return null}async applyEnvironmentVariables(t,e,r,d){if(!r||!t||typeof e!=="object"||e===null||Array.isArray(e))return{config:e,source:{type:"default",priority:10,timestamp:new Date}};return{config:S_(t,e,d),source:{type:"environment",priority:20,timestamp:new Date}}}async finalizeResult(t,e,r,d,E){return{config:t.config,source:t.source,path:t.source.path}}async validateConfiguration(t,e,r,d){let E=[];if(r){let n=r(t);if(n)E.push(...n)}if(e){let n=await this.validator.validateConfiguration(t,e);if(!n.isValid)E.push(...n.errors.map((c)=>c.path?`${c.path}: ${c.message}`:c.message))}if(E.length>0)throw xd.configValidation(d||"unknown",E,d)}checkCache(t,e){let r=this.generateCacheKey(t,e);return sn.get(r)||null}cacheResult(t,e,r,d){let E=this.generateCacheKey(t,d);sn.set(E,e,void 0,r.ttl)}generateCacheKey(t,e){let r=[t];if(e.alias)r.push(`alias:${e.alias}`);if(e.cwd)r.push(`cwd:${e.cwd}`);if(e.configDir)r.push(`configDir:${e.configDir}`);if("checkEnv"in e)r.push(`checkEnv:${e.checkEnv}`);return r.join("|")}getLocalDirectories(t,e){return Array.from(new Set([t,He(t,"config"),He(t,".config"),e?He(t,e):void 0].filter(Boolean)))}getAllSearchPaths(t,e,r,d){let E=[];return E.push(...this.getLocalSearchPaths(t,e,r,d)),E.push(...this.getHomeSearchPaths(t,e)),E.push(He(r,"package.json")),E}getLocalSearchPaths(t,e,r,d){let E=this.getLocalDirectories(r,d),n=[];for(let c of E)n.push(...this.fileLoader.generateConfigPaths(t,c,e));return n}getHomeSearchPaths(t,e){if(!t)return[];let r=[He(Yn(),".config",t),He(Yn(),".config"),Yn()],d=[];for(let E of r)d.push(...this.fileLoader.generateConfigPaths(t,E,e));return d}async loadConfigWithResult(t){return this.loadConfig(t)}}function rI(t){let r=!(t.message.includes("EACCES")||t.message.includes("EPERM")||t.message.includes("permission denied"))&&(t.message.includes("syntax")||t.message.includes("Expected")||t.message.includes("Unexpected")||t.message.includes("BuildMessage")),d=t.message.includes("Configuration must export a valid object")||t.message.includes("Configuration file is empty and exports nothing");return r||d}async function ka(t){return Nd.loadConfig({...t,__strictErrorHandling:!0})}async function yI(t){let e="defaultConfig"in t&&t.defaultConfig!==void 0?t.defaultConfig:{},r="cache"in t||"performance"in t||"schema"in t||"validate"in t;try{let d;if(r)d=await Nd.loadConfig(t);else d=await Nd.loadConfig({...t,defaultConfig:e,cache:{enabled:!0},performance:{enabled:!1}});return d?.config??e}catch(d){let E=d instanceof Error?d.name:"UnknownError",n=d instanceof Error?d.message:String(d);if(!(E==="ConfigNotFoundError"||E==="ConfigLoadError"||E==="ConfigValidationError"||n.includes("config"))&&t.verbose)ar.warn("Unexpected error loading config, using defaults:",[d instanceof Error?d:Error(String(d))]);let _=r?{...t,defaultConfig:e}:{...t,defaultConfig:e,cache:{enabled:!0},performance:{enabled:!1}};if("checkEnv"in t?t.checkEnv!==!1:!0)return(await Nd.applyEnvironmentVariables(_.name||"",e,!0,_.verbose||!1))?.config??e;return e}}async function ba(t={defaultConfig:{}}){if(typeof t==="string"){let{cwd:e}=await import("process");try{return(await Nd.loadConfig({name:t,cwd:e(),generatedDir:"./generated",configDir:"./config",defaultConfig:{},checkEnv:!0,arrayStrategy:"replace"})).config}catch(r){if(r instanceof Error&&(r.name==="ConfigNotFoundError"||r.name==="ConfigLoadError"&&rI(r)))return(await Nd.applyEnvironmentVariables(t,{},!0,!1)).config;throw r}}try{return(await Nd.loadConfig({...t,cwd:t.cwd||HE.cwd(),cache:{enabled:!0},performance:{enabled:!1}})).config}catch(e){if(e instanceof Error&&(e.name==="ConfigNotFoundError"||e.name==="ConfigLoadError"&&rI(e)))return(await Nd.applyEnvironmentVariables(t.name||"",t.defaultConfig||{},t.checkEnv!==!1,t.verbose||!1)).config;throw e}}async function xa(t,e,r="replace"){let d=new xi;try{let E=await d.loadFromPath(t,e,{arrayStrategy:r,useCache:!1,trackPerformance:!1});return E?E.config:null}catch{return null}}function S_(t,e,r=!1){let d=new bi,E=t.toUpperCase().replace(/[^A-Z0-9]/g,"_");function n(c,_=[]){let T={...c};for(let[i,h]of Object.entries(c)){let R=[..._,i],N=[`${E}_${R.join("_").toUpperCase()}`,`${E}_${R.map((f)=>f.toUpperCase()).join("")}`,`${E}_${R.map((f)=>f.replace(/([A-Z])/g,"_$1").toUpperCase()).join("")}`],A,u;for(let f of N)if(A=HE.env[f],A!==void 0){u=f;break}if(A!==void 0&&u)if(typeof h==="boolean")T[i]=["true","1","yes"].includes(A.toLowerCase());else if(typeof h==="number"){let f=Number(A);if(!Number.isNaN(f))T[i]=f}else if(Array.isArray(h))try{T[i]=JSON.parse(A)}catch{T[i]=A.split(",").map((f)=>f.trim())}else T[i]=A;else if(h&&typeof h==="object"&&!Array.isArray(h))T[i]=n(h,R)}return T}return n(e)}function qa(t){let e=He(HE.cwd(),t.configDir),r=He(HE.cwd(),t.generatedDir),d=He(r,"config-types.ts");if(!KN(Fl(d)))WX(Fl(d),{recursive:!0,mode:511});let E=KN(e)?vX(e).map((c)=>c.replace(/\.(ts|js|mjs|cjs|mts|cts|json)$/,"")).sort():[],n=`// Generated by bunfig v${w2}
|
|
5585
5585
|
export type ConfigNames = ${E.length?`'${E.join("' | '")}'`:"string"}
|
|
5586
|
-
`;QX(d,n,{mode:438})}function sa(t){let e=null,r=null,d=()=>{if(!r)r=yI(t).then((n)=>{return e=n,n},(n)=>{let c="defaultConfig"in t?t.defaultConfig:{};if(e=c,"verbose"in t&&t.verbose)
|
|
5586
|
+
`;QX(d,n,{mode:438})}function sa(t){let e=null,r=null,d=()=>{if(!r)r=yI(t).then((n)=>{return e=n,n},(n)=>{let c="defaultConfig"in t?t.defaultConfig:{};if(e=c,"verbose"in t&&t.verbose)ar.warn("Config loading failed, using defaults:",[n instanceof Error?n:Error(String(n))]);return c});return r},E="defaultConfig"in t?t.defaultConfig:{};return e=E,d(),new Proxy({},{get(n,c){if(e)return e[c];let _=E[c];return d(),_},has(n,c){return c in(e||E)},ownKeys(){return Object.keys(e||E)},getOwnPropertyDescriptor(n,c){return Object.getOwnPropertyDescriptor(e||E,c)},set(n,c,_){if(!e)e={...E};return e[c]=_,!0}})}function oa(t){let e=xl(ia.cwd(),t?.configDir||"./config");function r(){if(!_a(e))return[];let E=new Set([".ts",".js",".mjs",".cjs",".mts",".cts",".json"]),n=[".ts",".mts",".cts",".js",".mjs",".cjs",".json"],c=Ta(e).filter((T)=>E.has(FN(T))).map((T)=>({base:T.replace(/\.(?:ts|js|mjs|cjs|mts|cts|json)$/i,""),file:T})),_=new Map;for(let{base:T,file:i}of c){let h=FN(i).toLowerCase(),R=_.get(T);if(!R){_.set(T,i);continue}let N=FN(R).toLowerCase();if(n.indexOf(h)<n.indexOf(N))_.set(T,i)}return Array.from(_.entries()).map(([T,i])=>({base:T,file:i})).sort((T,i)=>T.base.localeCompare(i.base))}function d(){let E=r(),n=E.map((i)=>i.base),c=n.length?n.map((i)=>`'${i}'`).join(" | "):"string",_=E.length?`{
|
|
5587
5587
|
${E.map((i)=>{let h=xl(e,i.file).replace(/\\/g,"/");return` '${i.base}': typeof import('${h}').default`}).join(`,
|
|
5588
5588
|
`)}
|
|
5589
5589
|
}`:"Record<string, any>";return`export type ConfigNames = ${c}
|
|
5590
5590
|
export type ConfigByName = ${_}
|
|
5591
5591
|
export type Config<N extends ConfigNames> = N extends keyof ConfigByName ? ConfigByName[N] : unknown
|
|
5592
5592
|
export type ConfigOf = Config
|
|
5593
|
-
`}return{name:"bunfig-plugin",setup(E){E.onResolve({filter:/^virtual:bunfig-types$/},(n)=>{return{path:n.path,namespace:"bunfig-virtual"}}),E.onLoad({filter:/^virtual:bunfig-types$/,namespace:"bunfig-virtual"},()=>{return{contents:d(),loader:"ts"}})}}}var XI,sn,u_,aI,ma,pa,dI,Xi,bN,Ie,Mt,t2,EI,e2,nI,r2,d2,WN,E2,cI,_I,vN,n2,c2,_2,T2,ai,PI,i2,De,h2,R2,TI,Pi,xN,_e,Pt,S2,iI,N2,hI,A2,L2,QN,u2,RI,SI,O2,YN,C2,l2,I2,D2,f2,ji,jI,U2,w2="0.15.6",rr,Mi,A_,qN,sN,Gi,oN,mN,L_,pN,tA,xd,zI,FI,Xr,Nd,BI,JI,g2=ga(async()=>{XI=import.meta.require,sn=new dA,u_=new EA,aI={createKey:$a,isEquivalent:ya,estimateMemoryUsage:Xa},ma=Ji(ZN.cwd(),"config"),pa=Ji(ZN.cwd(),"src/generated"),dI=Bi.env.CLARITY_LOG_DIR||GX(ja(),"logs"),Xi={level:"info",defaultName:"clarity",timestamp:!0,colors:!0,format:"text",maxLogSize:10485760,logDatePattern:"YYYY-MM-DD",logDirectory:dI,rotation:{frequency:"daily",maxSize:10485760,maxFiles:5,compress:!1,rotateHour:0,rotateMinute:0,rotateDayOfWeek:0,rotateDayOfMonth:1,encrypt:!1},verbose:!1},bN=await za(),Ie={red:(t)=>`\x1B[31m${t}\x1B[0m`,green:(t)=>`\x1B[32m${t}\x1B[0m`,yellow:(t)=>`\x1B[33m${t}\x1B[0m`,blue:(t)=>`\x1B[34m${t}\x1B[0m`,magenta:(t)=>`\x1B[35m${t}\x1B[0m`,cyan:(t)=>`\x1B[36m${t}\x1B[0m`,white:(t)=>`\x1B[37m${t}\x1B[0m`,gray:(t)=>`\x1B[90m${t}\x1B[0m`,bgRed:(t)=>`\x1B[41m${t}\x1B[0m`,bgYellow:(t)=>`\x1B[43m${t}\x1B[0m`,bold:(t)=>`\x1B[1m${t}\x1B[0m`,dim:(t)=>`\x1B[2m${t}\x1B[0m`,italic:(t)=>`\x1B[3m${t}\x1B[0m`,underline:(t)=>`\x1B[4m${t}\x1B[0m`,reset:"\x1B[0m"},Mt=Ie,t2=Ie.red,EI=Ie.green,e2=Ie.yellow,nI=Ie.blue,r2=Ie.magenta,d2=Ie.cyan,WN=Ie.white,E2=Ie.gray,cI=Ie.bgRed,_I=Ie.bgYellow,vN=Ie.bold,n2=Ie.dim,c2=Ie.italic,_2=Ie.underline,T2=Ie.reset,ai={activationLevel:"error",bufferSize:50,flushOnDeactivation:!0,stopBuffering:!1},PI={debug:"\uD83D\uDD0D",info:nI("ℹ"),success:EI("✓"),warning:_I(WN(vN(" WARN "))),error:cI(WN(vN(" ERROR ")))},i2=new vi("stacks"),De=new vi("bunfig",{showTags:!0}),h2=Je(N_.cwd(),"config"),R2=Je(N_.cwd(),"src/generated"),TI=Fi.env.CLARITY_LOG_DIR||YX(Ha(),"logs"),Pi={level:"info",defaultName:"clarity",timestamp:!0,colors:!0,format:"text",maxLogSize:10485760,logDatePattern:"YYYY-MM-DD",logDirectory:TI,rotation:{frequency:"daily",maxSize:10485760,maxFiles:5,compress:!1,rotateHour:0,rotateMinute:0,rotateDayOfWeek:0,rotateDayOfMonth:1,encrypt:!1},verbose:!1,writeToFile:!1},xN=await Wa(),_e={red:(t)=>`\x1B[31m${t}\x1B[0m`,green:(t)=>`\x1B[32m${t}\x1B[0m`,yellow:(t)=>`\x1B[33m${t}\x1B[0m`,blue:(t)=>`\x1B[34m${t}\x1B[0m`,magenta:(t)=>`\x1B[35m${t}\x1B[0m`,cyan:(t)=>`\x1B[36m${t}\x1B[0m`,white:(t)=>`\x1B[37m${t}\x1B[0m`,gray:(t)=>`\x1B[90m${t}\x1B[0m`,bgRed:(t)=>`\x1B[41m${t}\x1B[0m`,bgYellow:(t)=>`\x1B[43m${t}\x1B[0m`,bgGray:(t)=>`\x1B[100m${t}\x1B[0m`,bold:(t)=>`\x1B[1m${t}\x1B[0m`,dim:(t)=>`\x1B[2m${t}\x1B[0m`,italic:(t)=>`\x1B[3m${t}\x1B[0m`,underline:(t)=>`\x1B[4m${t}\x1B[0m`,strikethrough:(t)=>`\x1B[9m${t}\x1B[0m`,reset:"\x1B[0m"},Pt=_e,S2=_e.red,iI=_e.green,N2=_e.yellow,hI=_e.blue,A2=_e.magenta,L2=_e.cyan,QN=_e.white,u2=_e.gray,RI=_e.bgRed,SI=_e.bgYellow,O2=_e.bgGray,YN=_e.bold,C2=_e.dim,l2=_e.italic,I2=_e.underline,D2=_e.strikethrough,f2=_e.reset,ji={activationLevel:"error",bufferSize:50,flushOnDeactivation:!0,stopBuffering:!1},jI={debug:"\uD83D\uDD0D",info:hI("ℹ"),success:iI("✓"),warning:SI(QN(YN(" WARN "))),error:RI(QN(YN(" ERROR ")))},U2=new Yi("stacks"),rr=class extends Error{timestamp;context;constructor(e,r={}){super(e);if(this.name=this.constructor.name,this.timestamp=new Date,this.context=r,Error.captureStackTrace)Error.captureStackTrace(this,this.constructor)}toJSON(){return{name:this.name,code:this.code,message:this.message,timestamp:this.timestamp.toISOString(),context:this.context,stack:this.stack}}toString(){let e=Object.keys(this.context).length>0?` (${Object.entries(this.context).map(([r,d])=>`${r}: ${d}`).join(", ")})`:"";return`${this.name} [${this.code}]: ${this.message}${e}`}},Mi=class extends rr{code="CONFIG_NOT_FOUND";constructor(e,r,d){let E=d?` or alias "${d}"`:"";super(`Configuration "${e}"${E} not found`,{configName:e,alias:d,searchPaths:r,searchPathCount:r.length})}},A_=class extends rr{code="CONFIG_LOAD_ERROR";constructor(e,r,d){super(`Failed to load configuration from "${e}": ${r.message}`,{configPath:e,configName:d,originalError:r.name,originalMessage:r.message});this.cause=r}},qN=class extends rr{code="CONFIG_VALIDATION_ERROR";constructor(e,r,d){super(`Configuration validation failed for "${e}"`,{configPath:e,configName:d,validationErrors:r,errorCount:r.length})}},sN=class extends rr{code="CONFIG_MERGE_ERROR";constructor(e,r,d,E){super(`Failed to merge configuration from "${e}" with "${r}": ${d.message}`,{sourcePath:e,targetPath:r,configName:E,originalError:d.name,originalMessage:d.message});this.cause=d}},Gi=class extends rr{code="ENV_VAR_ERROR";constructor(e,r,d,E){super(`Failed to parse environment variable "${e}" with value "${r}" as ${d}`,{envKey:e,envValue:r,expectedType:d,configName:E})}},oN=class extends rr{code="FILE_SYSTEM_ERROR";constructor(e,r,d){super(`File system ${e} failed for "${r}": ${d.message}`,{operation:e,path:r,originalError:d.name,originalMessage:d.message});this.cause=d}},mN=class extends rr{code="TYPE_GENERATION_ERROR";constructor(e,r,d){super(`Failed to generate types from "${e}" to "${r}": ${d.message}`,{configDir:e,outputPath:r,originalError:d.name,originalMessage:d.message});this.cause=d}},L_=class extends rr{code="SCHEMA_VALIDATION_ERROR";constructor(e,r,d){super(`Schema validation failed${d?` for config "${d}"`:""}`,{schemaPath:e,configName:d,validationErrors:r,errorCount:r.length})}},pN=class extends rr{code="BROWSER_CONFIG_ERROR";constructor(e,r,d,E){super(`Failed to fetch configuration from "${e}": ${r} ${d}`,{endpoint:e,status:r,statusText:d,configName:E})}},tA=class extends rr{code="PLUGIN_ERROR";constructor(e,r,d){super(`Plugin "${e}" failed during ${r}: ${d.message}`,{pluginName:e,operation:r,originalError:d.name,originalMessage:d.message});this.cause=d}},xd={configNotFound(t,e,r){return new Mi(t,e,r)},configLoad(t,e,r){return new A_(t,e,r)},configValidation(t,e,r){return new qN(t,e,r)},configMerge(t,e,r,d){return new sN(t,e,r,d)},envVar(t,e,r,d){return new Gi(t,e,r,d)},fileSystem(t,e,r){return new oN(t,e,r)},typeGeneration(t,e,r){return new mN(t,e,r)},schemaValidation(t,e,r){return new L_(t,e,r)},browserConfig(t,e,r,d){return new pN(t,e,r,d)},plugin(t,e,r){return new tA(t,e,r)}},zI={replace:"replace",concat:"concat",smart:"smart"},FI=/^https?:\/\//,Xr=new Yi("bunfig",{showTags:!0}),Nd=new iA,BI=He(HE.cwd(),"config"),JI=He(HE.cwd(),"src/generated")});function $2(t,e={}){let r=Hi.cwd();while(r.includes("storage"))r=ql(r,"..");let d=ql(r,t||"");if(e?.relative)return Ra(Hi.cwd(),d);return d}var y2=Hi.env.CLARITY_LOG_DIR||ha($2(),"logs"),HI={level:"info",defaultName:"clarity",timestamp:!0,colors:!0,format:"text",maxLogSize:10485760,logDatePattern:"YYYY-MM-DD",logDirectory:y2,rotation:{frequency:"daily",maxSize:10485760,maxFiles:5,compress:!1,rotateHour:0,rotateMinute:0,rotateDayOfWeek:0,rotateDayOfMonth:1,encrypt:!1},verbose:!1,writeToFile:!1},Vi={...HI},FM=(async()=>{try{let{loadConfig:t}=await g2().then(()=>lI),e=await t({name:"clarity",alias:"logging",defaultConfig:HI,cwd:Hi.cwd()});if(e)Object.assign(Vi,e)}catch{}return Vi})();function Te(){if(Sd.env.NODE_ENV==="test"||Sd.env.BUN_ENV==="test")return!1;return typeof window<"u"}async function X2(){if(Sd.env.NODE_ENV==="test"||Sd.env.BUN_ENV==="test")return!0;if(typeof navigator<"u"&&navigator.product==="ReactNative")return!0;if(typeof Sd<"u"){let t=Sd.type;if(t==="renderer"||t==="worker")return!1;return!!(Sd.versions&&(Sd.versions.node||Sd.versions.bun))}return!1}class WI{async format(t){let e=await X2(),r=await this.getMetadata(e);return JSON.stringify({timestamp:t.timestamp.toISOString(),level:t.level,name:t.name,message:t.message,metadata:r})}async getMetadata(t){if(t){let{hostname:e}=await import("os");return{pid:qn.pid,hostname:e(),environment:qn.env.NODE_ENV||"development",platform:qn.platform,version:qn.version}}return{userAgent:navigator.userAgent,hostname:window.location.hostname||"browser",environment:qn.env.NODE_ENV||qn.env.BUN_ENV||"development",viewport:{width:window.innerWidth,height:window.innerHeight},language:navigator.language}}}var Se={red:(t)=>`\x1B[31m${t}\x1B[0m`,green:(t)=>`\x1B[32m${t}\x1B[0m`,yellow:(t)=>`\x1B[33m${t}\x1B[0m`,blue:(t)=>`\x1B[34m${t}\x1B[0m`,magenta:(t)=>`\x1B[35m${t}\x1B[0m`,cyan:(t)=>`\x1B[36m${t}\x1B[0m`,white:(t)=>`\x1B[37m${t}\x1B[0m`,gray:(t)=>`\x1B[90m${t}\x1B[0m`,bgRed:(t)=>`\x1B[41m${t}\x1B[0m`,bgYellow:(t)=>`\x1B[43m${t}\x1B[0m`,bgGray:(t)=>`\x1B[100m${t}\x1B[0m`,bold:(t)=>`\x1B[1m${t}\x1B[0m`,dim:(t)=>`\x1B[2m${t}\x1B[0m`,italic:(t)=>`\x1B[3m${t}\x1B[0m`,underline:(t)=>`\x1B[4m${t}\x1B[0m`,strikethrough:(t)=>`\x1B[9m${t}\x1B[0m`,reset:"\x1B[0m"},jt=Se,BM=Se.red,a2=Se.green,JM=Se.yellow,P2=Se.blue,HM=Se.magenta,WM=Se.cyan,NI=Se.white,vM=Se.gray,j2=Se.bgRed,z2=Se.bgYellow,QM=Se.bgGray,AI=Se.bold,YM=Se.dim,MM=Se.italic,GM=Se.underline,VM=Se.strikethrough,KM=Se.reset,MN={activationLevel:"error",bufferSize:50,flushOnDeactivation:!0,stopBuffering:!1},F2={debug:"\uD83D\uDD0D",info:P2("ℹ"),success:a2("✓"),warning:z2(NI(AI(" WARN "))),error:j2(NI(AI(" ERROR ")))};class qi{name;fileLocks=new Map;currentKeyId=null;keys=new Map;fingersCrossedConfig;fingersCrossedActive=!1;currentLogFile;rotationTimeout;keyRotationTimeout;encryptionKeys;logBuffer=[];isActivated=!1;pendingOperations=[];enabled;fancy;tagFormat;timestampPosition;environment;config;options;formatter;timers=new Set;subLoggers=new Set;fingersCrossedBuffer=[];ANSI_PATTERN=/\u001B\[.*?m/g;activeProgressBar=null;constructor(t,e={}){this.name=t,this.config={...Vi},this.options=this.normalizeOptions(e),this.formatter=this.options.formatter||new WI,this.enabled=e.enabled??!0,this.fancy=e.fancy??!0,this.tagFormat=e.tagFormat??{prefix:"[",suffix:"]"},this.timestampPosition=e.timestampPosition??"right",this.environment=e.environment??at.env.APP_ENV??"local",this.fingersCrossedConfig=this.initializeFingersCrossedConfig(e);let r={...e},d=e.timestamp!==void 0;if(d)delete r.timestamp;if(this.config={...this.config,...r,timestamp:d||this.config.timestamp,level:this.options.level??"info"},this.currentLogFile=this.generateLogFilename(),this.encryptionKeys=new Map,this.validateEncryptionConfig()){this.setupRotation();let E=this.generateKeyId(),n=this.generateKey();this.currentKeyId=E,this.keys.set(E,n),this.encryptionKeys.set(E,{key:n,createdAt:new Date}),this.setupKeyRotation()}}shouldActivateFingersCrossed(t){if(!this.fingersCrossedConfig)return!1;let e={debug:0,info:1,success:2,warning:3,error:4},r=this.fingersCrossedConfig.activationLevel??"error";return e[t]>=e[r]}initializeFingersCrossedConfig(t){if(!t.fingersCrossedEnabled&&t.fingersCrossed)return{...MN,...t.fingersCrossed};if(!t.fingersCrossedEnabled)return null;if(!t.fingersCrossed)return{...MN};return{...MN,...t.fingersCrossed}}normalizeOptions(t){let e={format:"json",level:"info",logDirectory:Vi.logDirectory,rotation:void 0,timestamp:void 0,fingersCrossed:{},enabled:!0,showTags:!1,showIcons:!0,formatter:void 0},r={...e,...Object.fromEntries(Object.entries(t).filter(([,d])=>d!==void 0))};if(!r.level||!["debug","info","success","warning","error"].includes(r.level))r.level=e.level;return r}shouldWriteToFile(){return!Te()&&this.config.writeToFile===!0}async writeToFile(t){let r=(async()=>{let E,n=0,c=3,_=1000;while(n<c)try{try{try{await ua(this.config.logDirectory,pl.F_OK|pl.W_OK)}catch(i){if(i instanceof Error&&"code"in i)if(i.code==="ENOENT")await Oa(this.config.logDirectory,{recursive:!0,mode:493});else if(i.code==="EACCES")throw Error(`No write permission for log directory: ${this.config.logDirectory}`);else throw i;else throw i}}catch(i){throw console.error("Debug: [writeToFile] Failed to create log directory:",i),i}let T=this.validateEncryptionConfig()?(await this.encrypt(t)).encrypted:id.from(t);try{if(!Ii(this.currentLogFile))await HN(this.currentLogFile,"",{mode:420});if(E=ml(this.currentLogFile,"a",420),La(E,T,{flag:"a"}),ol(E),E!==void 0)JN(E),E=void 0;if((await bn(this.currentLogFile)).size===0){if(await HN(this.currentLogFile,T,{flag:"w",mode:420}),(await bn(this.currentLogFile)).size===0)throw Error("File exists but is empty after retry write")}return}catch(i){let h=i;if(h.code&&["ENETDOWN","ENETUNREACH","ENOTFOUND","ETIMEDOUT"].includes(h.code)){if(n<c-1){let R=typeof h.message==="string"?h.message:"Unknown error";console.error(`Network error during write attempt ${n+1}/${c}:`,R);let N=_*2**n;await new Promise((A)=>setTimeout(A,N)),n++;continue}}if(h?.code&&["ENOSPC","EDQUOT"].includes(h.code))throw Error(`Disk quota exceeded or no space left on device: ${h.message}`);throw console.error("Debug: [writeToFile] Error writing to file:",h),h}finally{if(E!==void 0)try{JN(E)}catch(i){console.error("Debug: [writeToFile] Error closing file descriptor:",i)}}}catch(T){if(n===c-1){let h=T,R=typeof h.message==="string"?h.message:"Unknown error";throw console.error("Debug: [writeToFile] Max retries reached. Final error:",R),T}n++;let i=_*2**(n-1);await new Promise((h)=>setTimeout(h,i))}})();this.pendingOperations.push(r);let d=this.pendingOperations.length-1;try{await r}catch(E){throw console.error("Debug: [writeToFile] Error in operation:",E),E}finally{this.pendingOperations.splice(d,1)}}generateLogFilename(){if(this.name.includes("stream-throughput")||this.name.includes("decompress-perf-test")||this.name.includes("decompression-latency")||this.name.includes("concurrent-read-test")||this.name.includes("clock-change-test"))return xn(this.config.logDirectory,`${this.name}.log`);if(this.name.includes("pending-test")||this.name.includes("temp-file-test")||this.name==="crash-test"||this.name==="corrupt-test"||this.name.includes("rotation-load-test")||this.name==="sigterm-test"||this.name==="sigint-test"||this.name==="failed-rotation-test"||this.name==="integration-test")return xn(this.config.logDirectory,`${this.name}.log`);let t=new Date().toISOString().split("T")[0];return xn(this.config.logDirectory,`${this.name}-${t}.log`)}setupRotation(){if(Te())return;if(!this.shouldWriteToFile())return;if(typeof this.config.rotation==="boolean")return;let t=this.config.rotation,e;switch(t.frequency){case"daily":e=86400000;break;case"weekly":e=604800000;break;case"monthly":e=2592000000;break;default:return}this.rotationTimeout=setInterval(()=>{this.rotateLog()},e)}setupKeyRotation(){if(!this.validateEncryptionConfig()){console.error("Invalid encryption configuration detected during key rotation setup");return}let e=this.config.rotation.keyRotation;if(!e?.enabled)return;let r=typeof e.interval==="number"?e.interval:60,d=Math.max(r,60)*1000;this.keyRotationTimeout=setInterval(()=>{this.rotateKeys().catch((E)=>{console.error("Error rotating keys:",E)})},d)}async rotateKeys(){if(!this.validateEncryptionConfig()){console.error("Invalid encryption configuration detected during key rotation");return}let e=this.config.rotation.keyRotation,r=this.generateKeyId(),d=this.generateKey();this.currentKeyId=r,this.keys.set(r,d),this.encryptionKeys.set(r,{key:d,createdAt:new Date});let E=Array.from(this.encryptionKeys.entries()).sort(([,_],[,T])=>T.createdAt.getTime()-_.createdAt.getTime()),n=typeof e.maxKeys==="number"?e.maxKeys:1,c=Math.max(1,n);if(E.length>c)for(let[_]of E.slice(c))this.encryptionKeys.delete(_),this.keys.delete(_)}generateKeyId(){return BN(16).toString("hex")}generateKey(){return BN(32)}getCurrentKey(){if(!this.currentKeyId)throw Error("Encryption is not properly initialized. Make sure encryption is enabled in the configuration.");let t=this.keys.get(this.currentKeyId);if(!t)throw Error(`No key found for ID ${this.currentKeyId}. The encryption key may have been rotated or removed.`);return{key:t,id:this.currentKeyId}}encrypt(t){let{key:e}=this.getCurrentKey(),r=BN(16),d=Sa("aes-256-gcm",e,r),E=id.isBuffer(t)?t:id.from(t,"utf8"),n=d.update(E),c=d.final(),_=n.length+c.length,T=d.getAuthTag(),i=id.allocUnsafe(16+_+16);return r.copy(i,0),n.copy(i,16),c.copy(i,16+n.length),T.copy(i,16+_),{encrypted:i,iv:r}}async compressData(t){return new Promise((e,r)=>{let d=eI(),E=[];d.on("data",(n)=>E.push(n)),d.on("end",()=>e(id.from(id.concat(E)))),d.on("error",r),d.write(t),d.end()})}getEncryptionOptions(){if(!this.config.rotation||typeof this.config.rotation==="boolean"||!this.config.rotation.encrypt)return{};let t={algorithm:"aes-256-cbc",compress:!1};if(typeof this.config.rotation.encrypt==="object"){let e=this.config.rotation.encrypt;return{...t,...e}}return t}async rotateLog(){if(Te())return;if(!this.shouldWriteToFile())return;let t=await bn(this.currentLogFile).catch(()=>null);if(!t)return;let e=this.config.rotation;if(typeof e==="boolean")return;if(e.maxSize&&t.size>=e.maxSize){let r=this.currentLogFile,d=this.generateLogFilename();if(this.name.includes("rotation-load-test")||this.name==="failed-rotation-test"){let E=await Di(this.config.logDirectory),n=E.filter((T)=>T.startsWith(this.name)&&/\.log\.\d+$/.test(T)).sort((T,i)=>{let h=Number.parseInt(T.match(/\.log\.(\d+)$/)?.[1]||"0");return Number.parseInt(i.match(/\.log\.(\d+)$/)?.[1]||"0")-h}),c=n.length>0?Number.parseInt(n[0].match(/\.log\.(\d+)$/)?.[1]||"0")+1:1,_=`${r}.${c}`;if(await bn(r).catch(()=>null))try{if(await tI(r,_),e.compress)try{let T=`${_}.gz`;await this.compressLogFile(_,T),await fi(_)}catch(T){console.error("Error compressing rotated file:",T)}if(n.length===0&&!E.some((T)=>T.endsWith(".log.1")))try{let T=`${r}.1`;await HN(T,"")}catch(T){console.error("Error creating backup file:",T)}}catch(T){console.error(`Error during rotation: ${T instanceof Error?T.message:String(T)}`)}}else{let E=new Date().toISOString().replace(/[:.]/g,"-"),n=r.replace(/\.log$/,`-${E}.log`);if(await bn(r).catch(()=>null))await tI(r,n)}if(this.currentLogFile=d,e.maxFiles){let n=(await Di(this.config.logDirectory)).filter((c)=>c.startsWith(this.name)).sort((c,_)=>_.localeCompare(c));for(let c of n.slice(e.maxFiles))await fi(xn(this.config.logDirectory,c))}}}async compressLogFile(t,e){let r=sl(t),d=Aa(e),E=eI();await Ia(r,E,d)}async handleFingersCrossedBuffer(t,e){if(!this.fingersCrossedConfig)return;if(this.shouldActivateFingersCrossed(t)&&!this.isActivated){this.isActivated=!0;for(let r of this.logBuffer){let d=await this.formatter.format(r);if(this.shouldWriteToFile())await this.writeToFile(d);console.log(d)}if(this.fingersCrossedConfig.stopBuffering)this.logBuffer=[]}if(this.isActivated){if(this.shouldWriteToFile())await this.writeToFile(e);console.log(e)}}shouldLog(t){if(!this.enabled)return!1;let e={debug:0,info:1,success:2,warning:3,error:4};return e[t]>=e[this.config.level]}async flushPendingWrites(){if(await Promise.all(this.pendingOperations.map((t)=>{if(t instanceof Promise)return t.catch((e)=>{console.error("Error in pending write operation:",e)});return Promise.resolve()})),Ii(this.currentLogFile))try{let t=ml(this.currentLogFile,"r+");ol(t),JN(t)}catch(t){console.error(`Error flushing file: ${t}`)}}async destroy(){if(this.rotationTimeout)clearInterval(this.rotationTimeout);if(this.keyRotationTimeout)clearInterval(this.keyRotationTimeout);this.timers.clear();for(let t of this.pendingOperations)if(typeof t.cancel==="function")t.cancel();return(async()=>{if(this.pendingOperations.length>0)try{await Promise.allSettled(this.pendingOperations)}catch(t){console.error("Error waiting for pending operations:",t)}if(!Te()&&this.config.rotation&&typeof this.config.rotation!=="boolean"&&this.config.rotation.compress)try{let e=(await Di(this.config.logDirectory)).filter((r)=>(r.includes("temp")||r.includes(".tmp"))&&r.includes(this.name));for(let r of e)try{await fi(xn(this.config.logDirectory,r))}catch(d){console.error(`Failed to delete temp file ${r}:`,d)}}catch(t){console.error("Error cleaning up temporary files:",t)}})()}getCurrentLogFilePath(){return this.currentLogFile}formatTag(t){if(!t)return"";return`${this.tagFormat.prefix}${t}${this.tagFormat.suffix}`}formatFileTimestamp(t){return`[${t.toISOString()}]`}formatConsoleTimestamp(t){return this.shouldStyleConsole()?jt.gray(t.toLocaleTimeString()):t.toLocaleTimeString()}shouldStyleConsole(){if(!this.fancy||Te())return!1;let t=typeof at.env.NO_COLOR<"u",e=at.env.FORCE_COLOR==="0";if(t||e)return!1;return!!(typeof at.stderr<"u"&&at.stderr.isTTY||typeof at.stdout<"u"&&at.stdout.isTTY)}formatConsoleMessage(t){let{timestamp:e,icon:r="",tag:d="",message:E,level:n,showTimestamp:c=!0}=t,_=(A)=>A.replace(this.ANSI_PATTERN,"");if(!this.fancy){let A=[];if(c)A.push(e);if(n==="warning")A.push("WARN");else if(n==="error")A.push("ERROR");else if(r)A.push(r.replace(/[^\p{L}\p{N}\p{P}\p{Z}]/gu,""));if(d)A.push(d.replace(/[[\]]/g,""));return A.push(E),A.join(" ")}let T=at.stdout.columns||120,i="";if(n==="warning"||n==="error")i=`${r} ${E}`;else if(n==="info"||n==="success")i=`${r} ${d} ${E}`;else i=`${r} ${d} ${jt.cyan(E)}`;if(!c)return i.trim();let h=_(i).trim().length,R=_(e).length,N=Math.max(1,T-2-h-R);return`${i.trim()}${" ".repeat(N)}${e}`}formatMessage(t,e){if(e.length===1&&Array.isArray(e[0]))return t.replace(/\{(\d+)\}/g,(n,c)=>{let _=Number.parseInt(c,10);return _<e[0].length?String(e[0][_]):n});let r=/%([sdijfo%])/g,d=0,E=t.replace(r,(n,c)=>{if(c==="%")return"%";if(d>=e.length)return n;let _=e[d++];switch(c){case"s":return String(_);case"d":case"i":return Number(_).toString();case"j":case"o":return JSON.stringify(_,null,2);default:return n}});if(d<e.length)E+=` ${e.slice(d).map((n)=>typeof n==="object"?JSON.stringify(n,null,2):String(n)).join(" ")}`;return E}formatMarkdown(t){if(!t)return t;let e=t;return e=e.replace(/\[([^\]]+)\]\(([^)]+)\)/g,(r,d,E)=>{let n=jt.underline(jt.blue(d)),c=this.toAbsoluteFilePath(E);if(c&&this.shouldStyleConsole()&&this.supportsHyperlinks()){let _=`file://${encodeURI(c)}`,T="\x1B]8;;",i="\x1B\\";return`\x1B]8;;${_}\x1B\\${n}\x1B]8;;\x1B\\`}if(this.shouldStyleConsole()&&this.supportsHyperlinks())return`\x1B]8;;${E}\x1B\\${n}\x1B]8;;\x1B\\`;return n}),e=e.replace(/`([^`]+)`/g,(r,d)=>jt.bgGray(d)),e=e.replace(/\*\*([^*]+)\*\*/g,(r,d)=>jt.bold(d)),e=e.replace(/(?<!\*)\*([^*]+)\*(?!\*)/g,(r,d)=>jt.italic(d)),e=e.replace(/(?<!_)_([^_]+)_(?!_)/g,(r,d)=>jt.italic(d)),e=e.replace(/~([^~]+)~/g,(r,d)=>jt.strikethrough(d)),e}supportsHyperlinks(){if(Te())return!1;let t=at.env;if(!t)return!1;if(t.TERM_PROGRAM==="iTerm.app"||t.TERM_PROGRAM==="vscode"||t.TERM_PROGRAM==="WezTerm")return!0;if(t.WT_SESSION)return!0;if(t.TERM==="xterm-kitty")return!0;let e=t.VTE_VERSION?Number.parseInt(t.VTE_VERSION,10):0;if(!Number.isNaN(e)&&e>=5000)return!0;return!1}toAbsoluteFilePath(t){try{let e=t;if(e.startsWith("file://"))e=e.replace(/^file:\/\//,"");if(e.startsWith("~")){let r=at.env.HOME||"";if(r)e=e.replace(/^~(?=$|\/)/,r)}if(Ca(e)||e.startsWith("./")||e.startsWith("../"))e=la(e);else return null;return Ii(e)?e:null}catch{return null}}buildOutputTexts(t){let e=this.shouldStyleConsole()?this.formatMarkdown(t):t,r=t.replace(this.ANSI_PATTERN,"");return{consoleText:e,fileText:r}}async log(t,e,...r){if(!this.shouldLog(t))return;let d=new Date,E=this.formatConsoleTimestamp(d),n=this.formatFileTimestamp(d),c,_;if(e instanceof Error)c=e.message,_=e.stack;else c=this.formatMessage(e,r);let{consoleText:T,fileText:i}=this.buildOutputTexts(c);if(this.shouldStyleConsole()){let R=this.options.showIcons===!1?"":F2[t],N=this.options.showTags!==!1&&this.name?jt.gray(this.formatTag(this.name)):"",A;switch(t){case"debug":A=this.formatConsoleMessage({timestamp:E,icon:R,tag:N,message:jt.gray(T),level:t}),console.error(A);break;case"info":A=this.formatConsoleMessage({timestamp:E,icon:R,tag:N,message:T,level:t}),console.warn(A);break;case"success":A=this.formatConsoleMessage({timestamp:E,icon:R,tag:N,message:jt.green(T),level:t}),console.error(A);break;case"warning":A=this.formatConsoleMessage({timestamp:E,icon:R,tag:N,message:T,level:t}),console.warn(A);break;case"error":if(A=this.formatConsoleMessage({timestamp:E,icon:R,tag:N,message:T,level:t}),console.error(A),_){let u=_.split(`
|
|
5593
|
+
`}return{name:"bunfig-plugin",setup(E){E.onResolve({filter:/^virtual:bunfig-types$/},(n)=>{return{path:n.path,namespace:"bunfig-virtual"}}),E.onLoad({filter:/^virtual:bunfig-types$/,namespace:"bunfig-virtual"},()=>{return{contents:d(),loader:"ts"}})}}}var XI,sn,u_,aI,ma,pa,dI,Xi,bN,Ie,Mt,t2,EI,e2,nI,r2,d2,WN,E2,cI,_I,vN,n2,c2,_2,T2,ai,PI,i2,De,h2,R2,TI,Pi,xN,_e,Pt,S2,iI,N2,hI,A2,L2,QN,u2,RI,SI,O2,YN,C2,l2,I2,D2,f2,ji,jI,U2,w2="0.15.6",rr,Mi,A_,qN,sN,Gi,oN,mN,L_,pN,tA,xd,zI,FI,ar,Nd,BI,JI,g2=ga(async()=>{XI=import.meta.require,sn=new dA,u_=new EA,aI={createKey:$a,isEquivalent:ya,estimateMemoryUsage:Xa},ma=Ji(ZN.cwd(),"config"),pa=Ji(ZN.cwd(),"src/generated"),dI=Bi.env.CLARITY_LOG_DIR||GX(ja(),"logs"),Xi={level:"info",defaultName:"clarity",timestamp:!0,colors:!0,format:"text",maxLogSize:10485760,logDatePattern:"YYYY-MM-DD",logDirectory:dI,rotation:{frequency:"daily",maxSize:10485760,maxFiles:5,compress:!1,rotateHour:0,rotateMinute:0,rotateDayOfWeek:0,rotateDayOfMonth:1,encrypt:!1},verbose:!1},bN=await za(),Ie={red:(t)=>`\x1B[31m${t}\x1B[0m`,green:(t)=>`\x1B[32m${t}\x1B[0m`,yellow:(t)=>`\x1B[33m${t}\x1B[0m`,blue:(t)=>`\x1B[34m${t}\x1B[0m`,magenta:(t)=>`\x1B[35m${t}\x1B[0m`,cyan:(t)=>`\x1B[36m${t}\x1B[0m`,white:(t)=>`\x1B[37m${t}\x1B[0m`,gray:(t)=>`\x1B[90m${t}\x1B[0m`,bgRed:(t)=>`\x1B[41m${t}\x1B[0m`,bgYellow:(t)=>`\x1B[43m${t}\x1B[0m`,bold:(t)=>`\x1B[1m${t}\x1B[0m`,dim:(t)=>`\x1B[2m${t}\x1B[0m`,italic:(t)=>`\x1B[3m${t}\x1B[0m`,underline:(t)=>`\x1B[4m${t}\x1B[0m`,reset:"\x1B[0m"},Mt=Ie,t2=Ie.red,EI=Ie.green,e2=Ie.yellow,nI=Ie.blue,r2=Ie.magenta,d2=Ie.cyan,WN=Ie.white,E2=Ie.gray,cI=Ie.bgRed,_I=Ie.bgYellow,vN=Ie.bold,n2=Ie.dim,c2=Ie.italic,_2=Ie.underline,T2=Ie.reset,ai={activationLevel:"error",bufferSize:50,flushOnDeactivation:!0,stopBuffering:!1},PI={debug:"\uD83D\uDD0D",info:nI("ℹ"),success:EI("✓"),warning:_I(WN(vN(" WARN "))),error:cI(WN(vN(" ERROR ")))},i2=new vi("stacks"),De=new vi("bunfig",{showTags:!0}),h2=Je(N_.cwd(),"config"),R2=Je(N_.cwd(),"src/generated"),TI=Fi.env.CLARITY_LOG_DIR||YX(Ha(),"logs"),Pi={level:"info",defaultName:"clarity",timestamp:!0,colors:!0,format:"text",maxLogSize:10485760,logDatePattern:"YYYY-MM-DD",logDirectory:TI,rotation:{frequency:"daily",maxSize:10485760,maxFiles:5,compress:!1,rotateHour:0,rotateMinute:0,rotateDayOfWeek:0,rotateDayOfMonth:1,encrypt:!1},verbose:!1,writeToFile:!1},xN=await Wa(),_e={red:(t)=>`\x1B[31m${t}\x1B[0m`,green:(t)=>`\x1B[32m${t}\x1B[0m`,yellow:(t)=>`\x1B[33m${t}\x1B[0m`,blue:(t)=>`\x1B[34m${t}\x1B[0m`,magenta:(t)=>`\x1B[35m${t}\x1B[0m`,cyan:(t)=>`\x1B[36m${t}\x1B[0m`,white:(t)=>`\x1B[37m${t}\x1B[0m`,gray:(t)=>`\x1B[90m${t}\x1B[0m`,bgRed:(t)=>`\x1B[41m${t}\x1B[0m`,bgYellow:(t)=>`\x1B[43m${t}\x1B[0m`,bgGray:(t)=>`\x1B[100m${t}\x1B[0m`,bold:(t)=>`\x1B[1m${t}\x1B[0m`,dim:(t)=>`\x1B[2m${t}\x1B[0m`,italic:(t)=>`\x1B[3m${t}\x1B[0m`,underline:(t)=>`\x1B[4m${t}\x1B[0m`,strikethrough:(t)=>`\x1B[9m${t}\x1B[0m`,reset:"\x1B[0m"},Pt=_e,S2=_e.red,iI=_e.green,N2=_e.yellow,hI=_e.blue,A2=_e.magenta,L2=_e.cyan,QN=_e.white,u2=_e.gray,RI=_e.bgRed,SI=_e.bgYellow,O2=_e.bgGray,YN=_e.bold,C2=_e.dim,l2=_e.italic,I2=_e.underline,D2=_e.strikethrough,f2=_e.reset,ji={activationLevel:"error",bufferSize:50,flushOnDeactivation:!0,stopBuffering:!1},jI={debug:"\uD83D\uDD0D",info:hI("ℹ"),success:iI("✓"),warning:SI(QN(YN(" WARN "))),error:RI(QN(YN(" ERROR ")))},U2=new Yi("stacks"),rr=class extends Error{timestamp;context;constructor(e,r={}){super(e);if(this.name=this.constructor.name,this.timestamp=new Date,this.context=r,Error.captureStackTrace)Error.captureStackTrace(this,this.constructor)}toJSON(){return{name:this.name,code:this.code,message:this.message,timestamp:this.timestamp.toISOString(),context:this.context,stack:this.stack}}toString(){let e=Object.keys(this.context).length>0?` (${Object.entries(this.context).map(([r,d])=>`${r}: ${d}`).join(", ")})`:"";return`${this.name} [${this.code}]: ${this.message}${e}`}},Mi=class extends rr{code="CONFIG_NOT_FOUND";constructor(e,r,d){let E=d?` or alias "${d}"`:"";super(`Configuration "${e}"${E} not found`,{configName:e,alias:d,searchPaths:r,searchPathCount:r.length})}},A_=class extends rr{code="CONFIG_LOAD_ERROR";constructor(e,r,d){super(`Failed to load configuration from "${e}": ${r.message}`,{configPath:e,configName:d,originalError:r.name,originalMessage:r.message});this.cause=r}},qN=class extends rr{code="CONFIG_VALIDATION_ERROR";constructor(e,r,d){super(`Configuration validation failed for "${e}"`,{configPath:e,configName:d,validationErrors:r,errorCount:r.length})}},sN=class extends rr{code="CONFIG_MERGE_ERROR";constructor(e,r,d,E){super(`Failed to merge configuration from "${e}" with "${r}": ${d.message}`,{sourcePath:e,targetPath:r,configName:E,originalError:d.name,originalMessage:d.message});this.cause=d}},Gi=class extends rr{code="ENV_VAR_ERROR";constructor(e,r,d,E){super(`Failed to parse environment variable "${e}" with value "${r}" as ${d}`,{envKey:e,envValue:r,expectedType:d,configName:E})}},oN=class extends rr{code="FILE_SYSTEM_ERROR";constructor(e,r,d){super(`File system ${e} failed for "${r}": ${d.message}`,{operation:e,path:r,originalError:d.name,originalMessage:d.message});this.cause=d}},mN=class extends rr{code="TYPE_GENERATION_ERROR";constructor(e,r,d){super(`Failed to generate types from "${e}" to "${r}": ${d.message}`,{configDir:e,outputPath:r,originalError:d.name,originalMessage:d.message});this.cause=d}},L_=class extends rr{code="SCHEMA_VALIDATION_ERROR";constructor(e,r,d){super(`Schema validation failed${d?` for config "${d}"`:""}`,{schemaPath:e,configName:d,validationErrors:r,errorCount:r.length})}},pN=class extends rr{code="BROWSER_CONFIG_ERROR";constructor(e,r,d,E){super(`Failed to fetch configuration from "${e}": ${r} ${d}`,{endpoint:e,status:r,statusText:d,configName:E})}},tA=class extends rr{code="PLUGIN_ERROR";constructor(e,r,d){super(`Plugin "${e}" failed during ${r}: ${d.message}`,{pluginName:e,operation:r,originalError:d.name,originalMessage:d.message});this.cause=d}},xd={configNotFound(t,e,r){return new Mi(t,e,r)},configLoad(t,e,r){return new A_(t,e,r)},configValidation(t,e,r){return new qN(t,e,r)},configMerge(t,e,r,d){return new sN(t,e,r,d)},envVar(t,e,r,d){return new Gi(t,e,r,d)},fileSystem(t,e,r){return new oN(t,e,r)},typeGeneration(t,e,r){return new mN(t,e,r)},schemaValidation(t,e,r){return new L_(t,e,r)},browserConfig(t,e,r,d){return new pN(t,e,r,d)},plugin(t,e,r){return new tA(t,e,r)}},zI={replace:"replace",concat:"concat",smart:"smart"},FI=/^https?:\/\//,ar=new Yi("bunfig",{showTags:!0}),Nd=new iA,BI=He(HE.cwd(),"config"),JI=He(HE.cwd(),"src/generated")});function $2(t,e={}){let r=Hi.cwd();while(r.includes("storage"))r=ql(r,"..");let d=ql(r,t||"");if(e?.relative)return Ra(Hi.cwd(),d);return d}var y2=Hi.env.CLARITY_LOG_DIR||ha($2(),"logs"),HI={level:"info",defaultName:"clarity",timestamp:!0,colors:!0,format:"text",maxLogSize:10485760,logDatePattern:"YYYY-MM-DD",logDirectory:y2,rotation:{frequency:"daily",maxSize:10485760,maxFiles:5,compress:!1,rotateHour:0,rotateMinute:0,rotateDayOfWeek:0,rotateDayOfMonth:1,encrypt:!1},verbose:!1,writeToFile:!1},Vi={...HI},FM=(async()=>{try{let{loadConfig:t}=await g2().then(()=>lI),e=await t({name:"clarity",alias:"logging",defaultConfig:HI,cwd:Hi.cwd()});if(e)Object.assign(Vi,e)}catch{}return Vi})();function Te(){if(Sd.env.NODE_ENV==="test"||Sd.env.BUN_ENV==="test")return!1;return typeof window<"u"}async function X2(){if(Sd.env.NODE_ENV==="test"||Sd.env.BUN_ENV==="test")return!0;if(typeof navigator<"u"&&navigator.product==="ReactNative")return!0;if(typeof Sd<"u"){let t=Sd.type;if(t==="renderer"||t==="worker")return!1;return!!(Sd.versions&&(Sd.versions.node||Sd.versions.bun))}return!1}class WI{async format(t){let e=await X2(),r=await this.getMetadata(e);return JSON.stringify({timestamp:t.timestamp.toISOString(),level:t.level,name:t.name,message:t.message,metadata:r})}async getMetadata(t){if(t){let{hostname:e}=await import("os");return{pid:qn.pid,hostname:e(),environment:qn.env.NODE_ENV||"development",platform:qn.platform,version:qn.version}}return{userAgent:navigator.userAgent,hostname:window.location.hostname||"browser",environment:qn.env.NODE_ENV||qn.env.BUN_ENV||"development",viewport:{width:window.innerWidth,height:window.innerHeight},language:navigator.language}}}var Se={red:(t)=>`\x1B[31m${t}\x1B[0m`,green:(t)=>`\x1B[32m${t}\x1B[0m`,yellow:(t)=>`\x1B[33m${t}\x1B[0m`,blue:(t)=>`\x1B[34m${t}\x1B[0m`,magenta:(t)=>`\x1B[35m${t}\x1B[0m`,cyan:(t)=>`\x1B[36m${t}\x1B[0m`,white:(t)=>`\x1B[37m${t}\x1B[0m`,gray:(t)=>`\x1B[90m${t}\x1B[0m`,bgRed:(t)=>`\x1B[41m${t}\x1B[0m`,bgYellow:(t)=>`\x1B[43m${t}\x1B[0m`,bgGray:(t)=>`\x1B[100m${t}\x1B[0m`,bold:(t)=>`\x1B[1m${t}\x1B[0m`,dim:(t)=>`\x1B[2m${t}\x1B[0m`,italic:(t)=>`\x1B[3m${t}\x1B[0m`,underline:(t)=>`\x1B[4m${t}\x1B[0m`,strikethrough:(t)=>`\x1B[9m${t}\x1B[0m`,reset:"\x1B[0m"},jt=Se,BM=Se.red,a2=Se.green,JM=Se.yellow,P2=Se.blue,HM=Se.magenta,WM=Se.cyan,NI=Se.white,vM=Se.gray,j2=Se.bgRed,z2=Se.bgYellow,QM=Se.bgGray,AI=Se.bold,YM=Se.dim,MM=Se.italic,GM=Se.underline,VM=Se.strikethrough,KM=Se.reset,MN={activationLevel:"error",bufferSize:50,flushOnDeactivation:!0,stopBuffering:!1},F2={debug:"\uD83D\uDD0D",info:P2("ℹ"),success:a2("✓"),warning:z2(NI(AI(" WARN "))),error:j2(NI(AI(" ERROR ")))};class qi{name;fileLocks=new Map;currentKeyId=null;keys=new Map;fingersCrossedConfig;fingersCrossedActive=!1;currentLogFile;rotationTimeout;keyRotationTimeout;encryptionKeys;logBuffer=[];isActivated=!1;pendingOperations=[];enabled;fancy;tagFormat;timestampPosition;environment;config;options;formatter;timers=new Set;subLoggers=new Set;fingersCrossedBuffer=[];ANSI_PATTERN=/\u001B\[.*?m/g;activeProgressBar=null;constructor(t,e={}){this.name=t,this.config={...Vi},this.options=this.normalizeOptions(e),this.formatter=this.options.formatter||new WI,this.enabled=e.enabled??!0,this.fancy=e.fancy??!0,this.tagFormat=e.tagFormat??{prefix:"[",suffix:"]"},this.timestampPosition=e.timestampPosition??"right",this.environment=e.environment??at.env.APP_ENV??"local",this.fingersCrossedConfig=this.initializeFingersCrossedConfig(e);let r={...e},d=e.timestamp!==void 0;if(d)delete r.timestamp;if(this.config={...this.config,...r,timestamp:d||this.config.timestamp,level:this.options.level??"info"},this.currentLogFile=this.generateLogFilename(),this.encryptionKeys=new Map,this.validateEncryptionConfig()){this.setupRotation();let E=this.generateKeyId(),n=this.generateKey();this.currentKeyId=E,this.keys.set(E,n),this.encryptionKeys.set(E,{key:n,createdAt:new Date}),this.setupKeyRotation()}}shouldActivateFingersCrossed(t){if(!this.fingersCrossedConfig)return!1;let e={debug:0,info:1,success:2,warning:3,error:4},r=this.fingersCrossedConfig.activationLevel??"error";return e[t]>=e[r]}initializeFingersCrossedConfig(t){if(!t.fingersCrossedEnabled&&t.fingersCrossed)return{...MN,...t.fingersCrossed};if(!t.fingersCrossedEnabled)return null;if(!t.fingersCrossed)return{...MN};return{...MN,...t.fingersCrossed}}normalizeOptions(t){let e={format:"json",level:"info",logDirectory:Vi.logDirectory,rotation:void 0,timestamp:void 0,fingersCrossed:{},enabled:!0,showTags:!1,showIcons:!0,formatter:void 0},r={...e,...Object.fromEntries(Object.entries(t).filter(([,d])=>d!==void 0))};if(!r.level||!["debug","info","success","warning","error"].includes(r.level))r.level=e.level;return r}shouldWriteToFile(){return!Te()&&this.config.writeToFile===!0}async writeToFile(t){let r=(async()=>{let E,n=0,c=3,_=1000;while(n<c)try{try{try{await ua(this.config.logDirectory,pl.F_OK|pl.W_OK)}catch(i){if(i instanceof Error&&"code"in i)if(i.code==="ENOENT")await Oa(this.config.logDirectory,{recursive:!0,mode:493});else if(i.code==="EACCES")throw Error(`No write permission for log directory: ${this.config.logDirectory}`);else throw i;else throw i}}catch(i){throw console.error("Debug: [writeToFile] Failed to create log directory:",i),i}let T=this.validateEncryptionConfig()?(await this.encrypt(t)).encrypted:id.from(t);try{if(!Ii(this.currentLogFile))await HN(this.currentLogFile,"",{mode:420});if(E=ml(this.currentLogFile,"a",420),La(E,T,{flag:"a"}),ol(E),E!==void 0)JN(E),E=void 0;if((await bn(this.currentLogFile)).size===0){if(await HN(this.currentLogFile,T,{flag:"w",mode:420}),(await bn(this.currentLogFile)).size===0)throw Error("File exists but is empty after retry write")}return}catch(i){let h=i;if(h.code&&["ENETDOWN","ENETUNREACH","ENOTFOUND","ETIMEDOUT"].includes(h.code)){if(n<c-1){let R=typeof h.message==="string"?h.message:"Unknown error";console.error(`Network error during write attempt ${n+1}/${c}:`,R);let N=_*2**n;await new Promise((A)=>setTimeout(A,N)),n++;continue}}if(h?.code&&["ENOSPC","EDQUOT"].includes(h.code))throw Error(`Disk quota exceeded or no space left on device: ${h.message}`);throw console.error("Debug: [writeToFile] Error writing to file:",h),h}finally{if(E!==void 0)try{JN(E)}catch(i){console.error("Debug: [writeToFile] Error closing file descriptor:",i)}}}catch(T){if(n===c-1){let h=T,R=typeof h.message==="string"?h.message:"Unknown error";throw console.error("Debug: [writeToFile] Max retries reached. Final error:",R),T}n++;let i=_*2**(n-1);await new Promise((h)=>setTimeout(h,i))}})();this.pendingOperations.push(r);let d=this.pendingOperations.length-1;try{await r}catch(E){throw console.error("Debug: [writeToFile] Error in operation:",E),E}finally{this.pendingOperations.splice(d,1)}}generateLogFilename(){if(this.name.includes("stream-throughput")||this.name.includes("decompress-perf-test")||this.name.includes("decompression-latency")||this.name.includes("concurrent-read-test")||this.name.includes("clock-change-test"))return xn(this.config.logDirectory,`${this.name}.log`);if(this.name.includes("pending-test")||this.name.includes("temp-file-test")||this.name==="crash-test"||this.name==="corrupt-test"||this.name.includes("rotation-load-test")||this.name==="sigterm-test"||this.name==="sigint-test"||this.name==="failed-rotation-test"||this.name==="integration-test")return xn(this.config.logDirectory,`${this.name}.log`);let t=new Date().toISOString().split("T")[0];return xn(this.config.logDirectory,`${this.name}-${t}.log`)}setupRotation(){if(Te())return;if(!this.shouldWriteToFile())return;if(typeof this.config.rotation==="boolean")return;let t=this.config.rotation,e;switch(t.frequency){case"daily":e=86400000;break;case"weekly":e=604800000;break;case"monthly":e=2592000000;break;default:return}this.rotationTimeout=setInterval(()=>{this.rotateLog()},e)}setupKeyRotation(){if(!this.validateEncryptionConfig()){console.error("Invalid encryption configuration detected during key rotation setup");return}let e=this.config.rotation.keyRotation;if(!e?.enabled)return;let r=typeof e.interval==="number"?e.interval:60,d=Math.max(r,60)*1000;this.keyRotationTimeout=setInterval(()=>{this.rotateKeys().catch((E)=>{console.error("Error rotating keys:",E)})},d)}async rotateKeys(){if(!this.validateEncryptionConfig()){console.error("Invalid encryption configuration detected during key rotation");return}let e=this.config.rotation.keyRotation,r=this.generateKeyId(),d=this.generateKey();this.currentKeyId=r,this.keys.set(r,d),this.encryptionKeys.set(r,{key:d,createdAt:new Date});let E=Array.from(this.encryptionKeys.entries()).sort(([,_],[,T])=>T.createdAt.getTime()-_.createdAt.getTime()),n=typeof e.maxKeys==="number"?e.maxKeys:1,c=Math.max(1,n);if(E.length>c)for(let[_]of E.slice(c))this.encryptionKeys.delete(_),this.keys.delete(_)}generateKeyId(){return BN(16).toString("hex")}generateKey(){return BN(32)}getCurrentKey(){if(!this.currentKeyId)throw Error("Encryption is not properly initialized. Make sure encryption is enabled in the configuration.");let t=this.keys.get(this.currentKeyId);if(!t)throw Error(`No key found for ID ${this.currentKeyId}. The encryption key may have been rotated or removed.`);return{key:t,id:this.currentKeyId}}encrypt(t){let{key:e}=this.getCurrentKey(),r=BN(16),d=Sa("aes-256-gcm",e,r),E=id.isBuffer(t)?t:id.from(t,"utf8"),n=d.update(E),c=d.final(),_=n.length+c.length,T=d.getAuthTag(),i=id.allocUnsafe(16+_+16);return r.copy(i,0),n.copy(i,16),c.copy(i,16+n.length),T.copy(i,16+_),{encrypted:i,iv:r}}async compressData(t){return new Promise((e,r)=>{let d=eI(),E=[];d.on("data",(n)=>E.push(n)),d.on("end",()=>e(id.from(id.concat(E)))),d.on("error",r),d.write(t),d.end()})}getEncryptionOptions(){if(!this.config.rotation||typeof this.config.rotation==="boolean"||!this.config.rotation.encrypt)return{};let t={algorithm:"aes-256-cbc",compress:!1};if(typeof this.config.rotation.encrypt==="object"){let e=this.config.rotation.encrypt;return{...t,...e}}return t}async rotateLog(){if(Te())return;if(!this.shouldWriteToFile())return;let t=await bn(this.currentLogFile).catch(()=>null);if(!t)return;let e=this.config.rotation;if(typeof e==="boolean")return;if(e.maxSize&&t.size>=e.maxSize){let r=this.currentLogFile,d=this.generateLogFilename();if(this.name.includes("rotation-load-test")||this.name==="failed-rotation-test"){let E=await Di(this.config.logDirectory),n=E.filter((T)=>T.startsWith(this.name)&&/\.log\.\d+$/.test(T)).sort((T,i)=>{let h=Number.parseInt(T.match(/\.log\.(\d+)$/)?.[1]||"0");return Number.parseInt(i.match(/\.log\.(\d+)$/)?.[1]||"0")-h}),c=n.length>0?Number.parseInt(n[0].match(/\.log\.(\d+)$/)?.[1]||"0")+1:1,_=`${r}.${c}`;if(await bn(r).catch(()=>null))try{if(await tI(r,_),e.compress)try{let T=`${_}.gz`;await this.compressLogFile(_,T),await fi(_)}catch(T){console.error("Error compressing rotated file:",T)}if(n.length===0&&!E.some((T)=>T.endsWith(".log.1")))try{let T=`${r}.1`;await HN(T,"")}catch(T){console.error("Error creating backup file:",T)}}catch(T){console.error(`Error during rotation: ${T instanceof Error?T.message:String(T)}`)}}else{let E=new Date().toISOString().replace(/[:.]/g,"-"),n=r.replace(/\.log$/,`-${E}.log`);if(await bn(r).catch(()=>null))await tI(r,n)}if(this.currentLogFile=d,e.maxFiles){let n=(await Di(this.config.logDirectory)).filter((c)=>c.startsWith(this.name)).sort((c,_)=>_.localeCompare(c));for(let c of n.slice(e.maxFiles))await fi(xn(this.config.logDirectory,c))}}}async compressLogFile(t,e){let r=sl(t),d=Aa(e),E=eI();await Ia(r,E,d)}async handleFingersCrossedBuffer(t,e){if(!this.fingersCrossedConfig)return;if(this.shouldActivateFingersCrossed(t)&&!this.isActivated){this.isActivated=!0;for(let r of this.logBuffer){let d=await this.formatter.format(r);if(this.shouldWriteToFile())await this.writeToFile(d);console.log(d)}if(this.fingersCrossedConfig.stopBuffering)this.logBuffer=[]}if(this.isActivated){if(this.shouldWriteToFile())await this.writeToFile(e);console.log(e)}}shouldLog(t){if(!this.enabled)return!1;let e={debug:0,info:1,success:2,warning:3,error:4};return e[t]>=e[this.config.level]}async flushPendingWrites(){if(await Promise.all(this.pendingOperations.map((t)=>{if(t instanceof Promise)return t.catch((e)=>{console.error("Error in pending write operation:",e)});return Promise.resolve()})),Ii(this.currentLogFile))try{let t=ml(this.currentLogFile,"r+");ol(t),JN(t)}catch(t){console.error(`Error flushing file: ${t}`)}}async destroy(){if(this.rotationTimeout)clearInterval(this.rotationTimeout);if(this.keyRotationTimeout)clearInterval(this.keyRotationTimeout);this.timers.clear();for(let t of this.pendingOperations)if(typeof t.cancel==="function")t.cancel();return(async()=>{if(this.pendingOperations.length>0)try{await Promise.allSettled(this.pendingOperations)}catch(t){console.error("Error waiting for pending operations:",t)}if(!Te()&&this.config.rotation&&typeof this.config.rotation!=="boolean"&&this.config.rotation.compress)try{let e=(await Di(this.config.logDirectory)).filter((r)=>(r.includes("temp")||r.includes(".tmp"))&&r.includes(this.name));for(let r of e)try{await fi(xn(this.config.logDirectory,r))}catch(d){console.error(`Failed to delete temp file ${r}:`,d)}}catch(t){console.error("Error cleaning up temporary files:",t)}})()}getCurrentLogFilePath(){return this.currentLogFile}formatTag(t){if(!t)return"";return`${this.tagFormat.prefix}${t}${this.tagFormat.suffix}`}formatFileTimestamp(t){return`[${t.toISOString()}]`}formatConsoleTimestamp(t){return this.shouldStyleConsole()?jt.gray(t.toLocaleTimeString()):t.toLocaleTimeString()}shouldStyleConsole(){if(!this.fancy||Te())return!1;let t=typeof at.env.NO_COLOR<"u",e=at.env.FORCE_COLOR==="0";if(t||e)return!1;return!!(typeof at.stderr<"u"&&at.stderr.isTTY||typeof at.stdout<"u"&&at.stdout.isTTY)}formatConsoleMessage(t){let{timestamp:e,icon:r="",tag:d="",message:E,level:n,showTimestamp:c=!0}=t,_=(A)=>A.replace(this.ANSI_PATTERN,"");if(!this.fancy){let A=[];if(c)A.push(e);if(n==="warning")A.push("WARN");else if(n==="error")A.push("ERROR");else if(r)A.push(r.replace(/[^\p{L}\p{N}\p{P}\p{Z}]/gu,""));if(d)A.push(d.replace(/[[\]]/g,""));return A.push(E),A.join(" ")}let T=at.stdout.columns||120,i="";if(n==="warning"||n==="error")i=`${r} ${E}`;else if(n==="info"||n==="success")i=`${r} ${d} ${E}`;else i=`${r} ${d} ${jt.cyan(E)}`;if(!c)return i.trim();let h=_(i).trim().length,R=_(e).length,N=Math.max(1,T-2-h-R);return`${i.trim()}${" ".repeat(N)}${e}`}formatMessage(t,e){if(e.length===1&&Array.isArray(e[0]))return t.replace(/\{(\d+)\}/g,(n,c)=>{let _=Number.parseInt(c,10);return _<e[0].length?String(e[0][_]):n});let r=/%([sdijfo%])/g,d=0,E=t.replace(r,(n,c)=>{if(c==="%")return"%";if(d>=e.length)return n;let _=e[d++];switch(c){case"s":return String(_);case"d":case"i":return Number(_).toString();case"j":case"o":return JSON.stringify(_,null,2);default:return n}});if(d<e.length)E+=` ${e.slice(d).map((n)=>typeof n==="object"?JSON.stringify(n,null,2):String(n)).join(" ")}`;return E}formatMarkdown(t){if(!t)return t;let e=t;return e=e.replace(/\[([^\]]+)\]\(([^)]+)\)/g,(r,d,E)=>{let n=jt.underline(jt.blue(d)),c=this.toAbsoluteFilePath(E);if(c&&this.shouldStyleConsole()&&this.supportsHyperlinks()){let _=`file://${encodeURI(c)}`,T="\x1B]8;;",i="\x1B\\";return`\x1B]8;;${_}\x1B\\${n}\x1B]8;;\x1B\\`}if(this.shouldStyleConsole()&&this.supportsHyperlinks())return`\x1B]8;;${E}\x1B\\${n}\x1B]8;;\x1B\\`;return n}),e=e.replace(/`([^`]+)`/g,(r,d)=>jt.bgGray(d)),e=e.replace(/\*\*([^*]+)\*\*/g,(r,d)=>jt.bold(d)),e=e.replace(/(?<!\*)\*([^*]+)\*(?!\*)/g,(r,d)=>jt.italic(d)),e=e.replace(/(?<!_)_([^_]+)_(?!_)/g,(r,d)=>jt.italic(d)),e=e.replace(/~([^~]+)~/g,(r,d)=>jt.strikethrough(d)),e}supportsHyperlinks(){if(Te())return!1;let t=at.env;if(!t)return!1;if(t.TERM_PROGRAM==="iTerm.app"||t.TERM_PROGRAM==="vscode"||t.TERM_PROGRAM==="WezTerm")return!0;if(t.WT_SESSION)return!0;if(t.TERM==="xterm-kitty")return!0;let e=t.VTE_VERSION?Number.parseInt(t.VTE_VERSION,10):0;if(!Number.isNaN(e)&&e>=5000)return!0;return!1}toAbsoluteFilePath(t){try{let e=t;if(e.startsWith("file://"))e=e.replace(/^file:\/\//,"");if(e.startsWith("~")){let r=at.env.HOME||"";if(r)e=e.replace(/^~(?=$|\/)/,r)}if(Ca(e)||e.startsWith("./")||e.startsWith("../"))e=la(e);else return null;return Ii(e)?e:null}catch{return null}}buildOutputTexts(t){let e=this.shouldStyleConsole()?this.formatMarkdown(t):t,r=t.replace(this.ANSI_PATTERN,"");return{consoleText:e,fileText:r}}async log(t,e,...r){if(!this.shouldLog(t))return;let d=new Date,E=this.formatConsoleTimestamp(d),n=this.formatFileTimestamp(d),c,_;if(e instanceof Error)c=e.message,_=e.stack;else c=this.formatMessage(e,r);let{consoleText:T,fileText:i}=this.buildOutputTexts(c);if(this.shouldStyleConsole()){let R=this.options.showIcons===!1?"":F2[t],N=this.options.showTags!==!1&&this.name?jt.gray(this.formatTag(this.name)):"",A;switch(t){case"debug":A=this.formatConsoleMessage({timestamp:E,icon:R,tag:N,message:jt.gray(T),level:t}),console.error(A);break;case"info":A=this.formatConsoleMessage({timestamp:E,icon:R,tag:N,message:T,level:t}),console.warn(A);break;case"success":A=this.formatConsoleMessage({timestamp:E,icon:R,tag:N,message:jt.green(T),level:t}),console.error(A);break;case"warning":A=this.formatConsoleMessage({timestamp:E,icon:R,tag:N,message:T,level:t}),console.warn(A);break;case"error":if(A=this.formatConsoleMessage({timestamp:E,icon:R,tag:N,message:T,level:t}),console.error(A),_){let u=_.split(`
|
|
5594
5594
|
`);for(let f of u)if(f.trim()&&!f.includes(c))console.error(this.formatConsoleMessage({timestamp:E,message:jt.gray(` ${f}`),level:t,showTimestamp:!1}))}break}}else if(!Te()){if(console.error(`${n} ${this.environment}.${t.toUpperCase()}: ${c}`),_)console.error(_)}let h=`${n} ${this.environment}.${t.toUpperCase()}: ${i}
|
|
5595
5595
|
`;if(_)h+=`${_}
|
|
5596
5596
|
`;if(h=h.replace(this.ANSI_PATTERN,""),this.shouldWriteToFile())await this.writeToFile(h)}progress(t,e=""){let r={update:(_,T)=>{},finish:(_)=>{},interrupt:(_,T)=>{}};if(!this.enabled)return r;let d=30;if(this.activeProgressBar={total:Math.max(1,t||1),current:0,message:e||"",barLength:d,lastRenderedLine:""},this.shouldStyleConsole()&&!Te()&&at.stdout.isTTY)this.renderProgressBar(this.activeProgressBar);return{update:(_,T)=>{if(!this.enabled||!this.activeProgressBar)return;if(this.activeProgressBar.current=Math.min(Math.max(0,_),this.activeProgressBar.total),T!==void 0)this.activeProgressBar.message=T;if(this.shouldStyleConsole()&&!Te()&&at.stdout.isTTY)this.renderProgressBar(this.activeProgressBar)},finish:(_)=>{if(!this.activeProgressBar)return;this.finishProgressBar(this.activeProgressBar,_)},interrupt:(_,T="info")=>{if(!Te()&&at.stdout.isTTY)at.stdout.write(`
|
|
@@ -5599,7 +5599,7 @@ export type ConfigOf = Config
|
|
|
5599
5599
|
`),T=Math.max(..._.map((N)=>N.length))+2,i=`┌${"─".repeat(T)}┐`,h=`└${"─".repeat(T)}┘`,R=_.map((N)=>{return this.formatConsoleMessage({timestamp:r,message:jt.cyan(N),showTimestamp:!1})});console.error(this.formatConsoleMessage({timestamp:r,message:jt.cyan(i),showTimestamp:!1})),R.forEach((N)=>console.error(N)),console.error(this.formatConsoleMessage({timestamp:r,message:jt.cyan(h),showTimestamp:!1}))}else if(!Te())console.error(`${d} ${this.environment}.INFO: [BOX] ${n}`);let c=`${d} ${this.environment}.INFO: [BOX] ${n}
|
|
5600
5600
|
`.replace(this.ANSI_PATTERN,"");if(this.shouldWriteToFile())await this.writeToFile(c)}async prompt(t){if(Te())return Promise.resolve(!0);return new Promise((e)=>{console.error(`${jt.cyan("?")} ${t} (y/n) `);let r=(d)=>{let E=d.toString().trim().toLowerCase();at.stdin.removeListener("data",r);try{if(typeof at.stdin.setRawMode==="function")at.stdin.setRawMode(!1)}catch{}at.stdin.pause(),console.error(""),e(E==="y"||E==="yes")};try{if(typeof at.stdin.setRawMode==="function")at.stdin.setRawMode(!0)}catch{}at.stdin.resume(),at.stdin.once("data",r)})}setFancy(t){this.fancy=t}isFancy(){return this.fancy}pause(){this.enabled=!1}resume(){this.enabled=!0}async start(t,...e){if(!this.enabled)return;let r=t;if(e&&e.length>0){let T=/%([sdijfo%])/g,i=0;if(r=t.replace(T,(h,R)=>{if(R==="%")return"%";if(i>=e.length)return h;let N=e[i++];switch(R){case"s":return String(N);case"d":case"i":return Number(N).toString();case"j":case"o":return JSON.stringify(N,null,2);default:return h}}),i<e.length)r+=` ${e.slice(i).map((h)=>typeof h==="object"?JSON.stringify(h,null,2):String(h)).join(" ")}`}let{consoleText:d,fileText:E}=this.buildOutputTexts(r);if(this.shouldStyleConsole()){let T=this.options.showTags!==!1&&this.name?jt.gray(this.formatTag(this.name)):"",i=this.options.showIcons===!1?"":`${jt.blue("◐")} `;console.error(`${i}${T} ${jt.cyan(d)}`)}let _=`[${new Date().toISOString()}] ${this.environment}.INFO: [START] ${E}
|
|
5601
5601
|
`.replace(this.ANSI_PATTERN,"");if(this.shouldWriteToFile())await this.writeToFile(_)}renderProgressBar(t,e=!1){if(!this.enabled||!this.shouldStyleConsole()||!at.stdout.isTTY)return;let r=Math.min(100,Math.max(0,Math.round(t.current/t.total*100))),d=Math.round(t.barLength*r/100),E=t.barLength-d,n=jt.green("━".repeat(d)),c=jt.gray("━".repeat(E)),_=`[${n}${c}]`,T=`${r}%`.padStart(4),i=t.message?` ${t.message}`:"",h=this.options.showIcons===!1?"":e||r===100?jt.green("✓"):jt.blue("▶"),R=this.options.showTags!==!1&&this.name?` ${jt.gray(this.formatTag(this.name))}`:"",N=`\r${h}${R} ${_} ${T}${i}`,A=at.stdout.columns||80,u=" ".repeat(Math.max(0,A-N.replace(this.ANSI_PATTERN,"").length));if(t.lastRenderedLine=`${N}${u}`,at.stdout.write(t.lastRenderedLine),e)at.stdout.write(`
|
|
5602
|
-
`)}finishProgressBar(t,e){if(!this.enabled||!this.fancy||Te()||!at.stdout.isTTY){this.activeProgressBar=null;return}if(t.current<t.total)t.current=t.total;if(e)t.message=e;this.renderProgressBar(t,!0),this.activeProgressBar=null}async clear(t={}){if(Te()){console.warn("Log clearing is not supported in browser environments.");return}try{console.warn("Clearing logs...",this.config.logDirectory);let e=await Di(this.config.logDirectory),r=[];for(let d of e){if(!(t.name?new RegExp(t.name.replace("*",".*")).test(d):d.startsWith(this.name))||!d.endsWith(".log"))continue;let n=xn(this.config.logDirectory,d);if(t.before)try{if((await bn(n)).mtime>=t.before)continue}catch(c){console.error(`Failed to get stats for file ${n}:`,c);continue}r.push(n)}if(r.length===0){console.warn("No log files matched the criteria for clearing.");return}console.warn(`Preparing to delete ${r.length} log file(s)...`);for(let d of r)try{await fi(d),console.warn(`Deleted log file: ${d}`)}catch(E){console.error(`Failed to delete log file ${d}:`,E)}console.warn("Log clearing process finished.")}catch(e){console.error("Error during log clearing process:",e)}}}var ZM=new qi("stacks");class
|
|
5602
|
+
`)}finishProgressBar(t,e){if(!this.enabled||!this.fancy||Te()||!at.stdout.isTTY){this.activeProgressBar=null;return}if(t.current<t.total)t.current=t.total;if(e)t.message=e;this.renderProgressBar(t,!0),this.activeProgressBar=null}async clear(t={}){if(Te()){console.warn("Log clearing is not supported in browser environments.");return}try{console.warn("Clearing logs...",this.config.logDirectory);let e=await Di(this.config.logDirectory),r=[];for(let d of e){if(!(t.name?new RegExp(t.name.replace("*",".*")).test(d):d.startsWith(this.name))||!d.endsWith(".log"))continue;let n=xn(this.config.logDirectory,d);if(t.before)try{if((await bn(n)).mtime>=t.before)continue}catch(c){console.error(`Failed to get stats for file ${n}:`,c);continue}r.push(n)}if(r.length===0){console.warn("No log files matched the criteria for clearing.");return}console.warn(`Preparing to delete ${r.length} log file(s)...`);for(let d of r)try{await fi(d),console.warn(`Deleted log file: ${d}`)}catch(E){console.error(`Failed to delete log file ${d}:`,E)}console.warn("Log clearing process finished.")}catch(e){console.error("Error during log clearing process:",e)}}}var ZM=new qi("stacks");class Pr extends Error{timestamp;context;constructor(t,e={}){super(t);if(this.name=this.constructor.name,this.timestamp=new Date,this.context=e,Error.captureStackTrace)Error.captureStackTrace(this,this.constructor)}toJSON(){return{name:this.name,code:this.code,message:this.message,timestamp:this.timestamp.toISOString(),context:this.context,stack:this.stack}}toString(){let t=Object.keys(this.context).length>0?` (${Object.entries(this.context).map(([e,r])=>`${e}: ${r}`).join(", ")})`:"";return`${this.name} [${this.code}]: ${this.message}${t}`}}class vI extends Pr{code="CONFIG_NOT_FOUND";constructor(t,e,r){let d=r===void 0?[]:Array.isArray(r)?r.filter(Boolean):[r],E="";if(d.length===1)E=` or alias "${d[0]}"`;else if(d.length>1)E=` or aliases ${d.map((n)=>`"${n}"`).join(", ")}`;super(`Configuration "${t}"${E} not found`,{configName:t,alias:r,searchPaths:e,searchPathCount:e.length})}}class Ki extends Pr{code="CONFIG_LOAD_ERROR";constructor(t,e,r){super(`Failed to load configuration from "${t}": ${e.message}`,{configPath:t,configName:r,originalError:e.name,originalMessage:e.message});this.cause=e}}class QI extends Pr{code="CONFIG_VALIDATION_ERROR";constructor(t,e,r){super(`Configuration validation failed for "${t}"`,{configPath:t,configName:r,validationErrors:e,errorCount:e.length})}}class YI extends Pr{code="CONFIG_MERGE_ERROR";constructor(t,e,r,d){super(`Failed to merge configuration from "${t}" with "${e}": ${r.message}`,{sourcePath:t,targetPath:e,configName:d,originalError:r.name,originalMessage:r.message});this.cause=r}}class hA extends Pr{code="ENV_VAR_ERROR";constructor(t,e,r,d){super(`Failed to parse environment variable "${t}" with value "${e}" as ${r}`,{envKey:t,envValue:e,expectedType:r,configName:d})}}class MI extends Pr{code="FILE_SYSTEM_ERROR";constructor(t,e,r){super(`File system ${t} failed for "${e}": ${r.message}`,{operation:t,path:e,originalError:r.name,originalMessage:r.message});this.cause=r}}class GI extends Pr{code="TYPE_GENERATION_ERROR";constructor(t,e,r){super(`Failed to generate types from "${t}" to "${e}": ${r.message}`,{configDir:t,outputPath:e,originalError:r.name,originalMessage:r.message});this.cause=r}}class Zi extends Pr{code="SCHEMA_VALIDATION_ERROR";constructor(t,e,r){super(`Schema validation failed${r?` for config "${r}"`:""}`,{schemaPath:t,configName:r,validationErrors:e,errorCount:e.length})}}class VI extends Pr{code="BROWSER_CONFIG_ERROR";constructor(t,e,r,d){super(`Failed to fetch configuration from "${t}": ${e} ${r}`,{endpoint:t,status:e,statusText:r,configName:d})}}class KI extends Pr{code="PLUGIN_ERROR";constructor(t,e,r){super(`Plugin "${t}" failed during ${e}: ${r.message}`,{pluginName:t,operation:e,originalError:r.name,originalMessage:r.message});this.cause=r}}var on={configNotFound(t,e,r){return new vI(t,e,r)},configLoad(t,e,r){return new Ki(t,e,r)},configValidation(t,e,r){return new QI(t,e,r)},configMerge(t,e,r,d){return new YI(t,e,r,d)},envVar(t,e,r,d){return new hA(t,e,r,d)},fileSystem(t,e,r){return new MI(t,e,r)},typeGeneration(t,e,r){return new GI(t,e,r)},schemaValidation(t,e,r){return new Zi(t,e,r)},browserConfig(t,e,r,d){return new VI(t,e,r,d)},plugin(t,e,r){return new KI(t,e,r)}};async function B2(t,e={}){let{maxRetries:r=3,retryDelay:d=1000,isRetryable:E=()=>!0,fallback:n}=e,c=Error("Unknown error occurred");for(let _=0;_<=r;_++)try{return await t()}catch(T){if(c=T instanceof Error?T:Error(String(T)),_===r||!E(c))break;if(d>0)await new Promise((i)=>setTimeout(i,d))}if(n!==void 0)return n;throw c instanceof Error?c:Error(`Unknown error: ${String(c)}`)}class RA{defaultParsers;constructor(){this.defaultParsers=[{name:"boolean",canParse:(t,e)=>e==="boolean"||["true","false","1","0","yes","no"].includes(t.toLowerCase()),parse:(t)=>{let e=t.toLowerCase();return["true","1","yes"].includes(e)}},{name:"number",canParse:(t,e)=>e==="number"||!Number.isNaN(Number(t))&&!Number.isNaN(Number.parseFloat(t)),parse:(t)=>{let e=Number(t);if(Number.isNaN(e))throw TypeError(`Cannot parse "${t}" as number`);return e}},{name:"array",canParse:(t,e)=>e==="array"||t.startsWith("[")||t.includes(","),parse:(t)=>{try{let e=JSON.parse(t);if(Array.isArray(e))return e}catch{}return t.split(",").map((e)=>e.trim())}},{name:"json",canParse:(t,e)=>e==="object"||(t.startsWith("{")&&t.endsWith("}")||t.startsWith("[")&&t.endsWith("]")),parse:(t)=>{try{return JSON.parse(t)}catch(e){throw Error(`Cannot parse "${t}" as JSON: ${e}`)}}}]}async applyEnvironmentVariables(t,e,r={}){let{prefix:d,useCamelCase:E=!0,useBackwardCompatibility:n=!0,customParsers:c={},verbose:_=!1,trackPerformance:T=!0}=r,i=async()=>{if(!t)return{config:e,source:{type:"environment",priority:50,timestamp:new Date}};let h=d||this.generateEnvPrefix(t),R={...e};return this.processObject(R,[],h,{useCamelCase:E,useBackwardCompatibility:n,customParsers:c,verbose:_,configName:t}),{config:R,source:{type:"environment",priority:50,timestamp:new Date}}};if(T)return rA.track("applyEnvironmentVariables",i,{configName:t});return i()}generateEnvPrefix(t){return t.toUpperCase().replace(/-/g,"_")}formatEnvKey(t,e){if(!e)return t.toUpperCase();return t.replace(/([A-Z])/g,"_$1").toUpperCase()}processObject(t,e,r,d){for(let[E,n]of Object.entries(t)){let c=[...e,E],_=c.map((h)=>this.formatEnvKey(h,d.useCamelCase)),T=`${r}_${_.join("_")}`,i=d.useBackwardCompatibility?`${r}_${c.map((h)=>h.toUpperCase()).join("_")}`:null;if(d.verbose);if(typeof n==="object"&&n!==null&&!Array.isArray(n))this.processObject(n,c,r,d);else{let h=wi.env[T]||(i?wi.env[i]:void 0);if(h!==void 0){if(d.verbose){let R=wi.env[T]?T:i}try{t[E]=this.parseEnvironmentValue(h,typeof n,T,d.customParsers,d.configName)}catch(R){if(R instanceof hA)throw R;throw on.envVar(T,h,typeof n,d.configName)}}}}}parseEnvironmentValue(t,e,r,d,E){for(let[n,c]of Object.entries(d))try{return c(t)}catch{continue}for(let n of this.defaultParsers)if(n.canParse(t,e))try{return n.parse(t)}catch{throw on.envVar(r,t,`${e} (via ${n.name} parser)`,E)}return t}getEnvironmentVariables(t){let e={},r=t.toUpperCase();for(let[d,E]of Object.entries(wi.env))if(d.startsWith(r)&&E!==void 0)e[d]=E;return e}validateEnvironmentVariable(t,e,r){let d=[];if(!/^[A-Z_][A-Z0-9_]*$/.test(t))d.push(`Environment variable key "${t}" should only contain uppercase letters, numbers, and underscores`);if(r)try{this.parseEnvironmentValue(t,e,r,{})}catch(E){d.push(`Cannot parse value "${e}" as ${r}: ${E}`)}return{isValid:d.length===0,errors:d}}generateEnvVarDocs(t,e,r={}){let{prefix:d,format:E="text"}=r,n=d||this.generateEnvPrefix(t),c=[];switch(this.extractEnvVarInfo(e,[],n,c),E){case"markdown":return this.formatAsMarkdown(c,t);case"json":return JSON.stringify(c,null,2);default:return this.formatAsText(c,t)}}extractEnvVarInfo(t,e,r,d){for(let[E,n]of Object.entries(t)){let c=[...e,E],_=`${r}_${c.map((T)=>this.formatEnvKey(T,!0)).join("_")}`;if(typeof n==="object"&&n!==null&&!Array.isArray(n))this.extractEnvVarInfo(n,c,r,d);else d.push({key:_,type:Array.isArray(n)?"array":typeof n,description:`Configuration for ${c.join(".")}`,example:this.generateExample(n)})}}generateExample(t){if(Array.isArray(t))return JSON.stringify(t);if(typeof t==="object"&&t!==null)return JSON.stringify(t);return String(t)}formatAsText(t,e){let r=`Environment Variables for ${e}:
|
|
5603
5603
|
|
|
5604
5604
|
`;for(let d of t)r+=`${d.key}
|
|
5605
5605
|
`,r+=` Type: ${d.type}
|
|
@@ -5619,7 +5619,7 @@ export type ConfigOf = Config
|
|
|
5619
5619
|
`)+(Object.keys(t).length?`
|
|
5620
5620
|
`:"")}import{createCipheriv as q2,createDecipheriv as s2,createHash as cD,randomBytes as o2}from"node:crypto";class O_{controlPlane;now;kind="local_encrypted";key;constructor(t,e,r=()=>new Date){this.controlPlane=t;this.now=r;if(!e)throw Error("Configuration encryption key is required.");this.key=cD("sha256").update(`ts-cloud:configuration:${e}`).digest()}encrypt(t){let e=o2(12),r=q2("aes-256-gcm",this.key,e),d=Buffer.concat([r.update(t,"utf8"),r.final()]);return`v1.${e.toString("base64url")}.${r.getAuthTag().toString("base64url")}.${d.toString("base64url")}`}decrypt(t){let[e,r,d,E]=t.split(".");if(e!=="v1"||!r||!d||!E)throw Error("Encrypted configuration secret is unavailable.");try{let n=s2("aes-256-gcm",this.key,Buffer.from(r,"base64url"));return n.setAuthTag(Buffer.from(d,"base64url")),Buffer.concat([n.update(Buffer.from(E,"base64url")),n.final()]).toString("utf8")}catch{throw Error("Encrypted configuration secret could not be decrypted.")}}async put(t){if(!t.value)throw Error("Configuration secrets cannot be empty.");let e=t.reference??`secret://configuration/${t.name}/${crypto.randomUUID()}`;if(!/^secret:\/\/configuration\/[A-Za-z0-9._/-]+$/.test(e))throw Error("Invalid local configuration secret reference.");let d=(this.controlPlane.database.query("SELECT version FROM configuration_secret_values WHERE reference=?").get(e)?.version??0)+1,E=this.now().toISOString();return this.controlPlane.database.run("INSERT INTO configuration_secret_values (reference,ciphertext,fingerprint,version,created_at,updated_at) VALUES (?,?,?,?,?,?) ON CONFLICT(reference) DO UPDATE SET ciphertext=excluded.ciphertext,fingerprint=excluded.fingerprint,version=excluded.version,updated_at=excluded.updated_at",[e,this.encrypt(t.value),cD("sha256").update(t.value).digest("hex"),d,E,E]),{reference:e,version:String(d)}}async resolve(t){let e=this.controlPlane.database.query("SELECT ciphertext FROM configuration_secret_values WHERE reference=?").get(t);if(!e)throw Error("Configuration secret was not found.");return this.decrypt(e.ciphertext)}async remove(t){this.controlPlane.database.run("DELETE FROM configuration_secret_values WHERE reference=?",[t])}async validate(t){return!!this.controlPlane.database.query("SELECT 1 AS found FROM configuration_secret_values WHERE reference=?").get(t)}}class LA{client;region;kind="aws_secrets_manager";constructor(t,e){this.client=t;this.region=e}async put(t){if(t.reference){let r=this.id(t.reference),d=await this.client.putSecretValue({SecretId:r,SecretString:t.value,ClientRequestToken:t.idempotencyKey});return{reference:t.reference,version:d.VersionId??t.idempotencyKey}}let e=await this.client.createSecret({Name:t.name,SecretString:t.value,ClientRequestToken:t.idempotencyKey,Tags:[{Key:"managed-by",Value:"ts-cloud"}]});return{reference:`aws-sm://${this.region}/${encodeURIComponent(e.ARN??e.Name??t.name)}`,version:e.VersionId??t.idempotencyKey}}async resolve(t){let e=await this.client.getSecretValue({SecretId:this.id(t)});if(e.SecretString==null)throw Error("AWS Secrets Manager value is unavailable.");return e.SecretString}async remove(t){await this.client.deleteSecret({SecretId:this.id(t),RecoveryWindowInDays:7})}async validate(t){try{return await this.client.describeSecret(this.id(t)),!0}catch{return!1}}id(t){let e=new URL(t);if(e.protocol!=="aws-sm:"||e.hostname!==this.region)throw Error("Invalid AWS Secrets Manager reference.");return decodeURIComponent(e.pathname.slice(1))}}class uA{client;region;kind="aws_ssm";constructor(t,e){this.client=t;this.region=e}async put(t){let e=t.reference?this.name(t.reference):`/${t.name.replace(/^\/+/,"")}`,r=await this.client.putParameter({Name:e,Value:t.value,Type:"SecureString",Overwrite:!!t.reference,Description:"Managed by ts-cloud"});return{reference:`aws-ssm://${this.region}${e}`,version:String(r.Version??1)}}async resolve(t){let e=await this.client.getParameter({Name:this.name(t),WithDecryption:!0});if(e.Parameter?.Value==null)throw Error("AWS SSM parameter value is unavailable.");return e.Parameter.Value}async remove(t){await this.client.deleteParameter({Name:this.name(t)})}async validate(t){try{return!!(await this.client.getParameter({Name:this.name(t),WithDecryption:!1})).Parameter}catch{return!1}}name(t){let e=new URL(t);if(e.protocol!=="aws-ssm:"||e.hostname!==this.region||!e.pathname.startsWith("/"))throw Error("Invalid AWS SSM reference.");return e.pathname}}class OA{kind="external";async put(){throw Error("External secret references cannot be written by ts-cloud.")}async resolve(){throw Error("External secrets must be resolved by the deployment provider.")}async remove(){}async validate(t){return/^(?:vault|doppler|op|external):\/\//.test(t)}}import{createHmac as m2}from"node:crypto";var p2=/^(?:secret|aws-sm|aws-ssm|vault|doppler|op|external):\/\//,tP=/^(?:AWS_|TS_CLOUD_|PORT$|HOST$)/;function ke(t){return[...new Set(t)].sort()}function _D(t,e={}){let r=t.kind==="secret";return{id:t.id,key:t.key,kind:t.kind,scope:t.scope,inherited:!!e.inherited,overridden:!!e.overridden,required:t.required,backend:!r||e.canReadSecretMetadata?t.backend:void 0,backendVersion:!r||e.canReadSecretMetadata?t.backendVersion:void 0,reference:r&&e.canReadSecretMetadata?t.secretRef:void 0,value:!r?t.value:void 0,lastUsedAt:t.lastUsedAt,rotatedAt:t.rotatedAt,version:t.version,updatedAt:t.updatedAt}}class CA{store;backends=new Map;fingerprintKey;now;constructor(t,e){if(this.store=t,this.fingerprintKey=e.fingerprintKey??e.encryptionKey,this.now=e.now??(()=>new Date),!this.fingerprintKey)throw Error("Configuration fingerprint key is required.");let r=e.backends??[new O_(t.controlPlane,e.encryptionKey,this.now)];for(let d of r)this.backends.set(d.kind,d)}list(t){let e=t.search?.toLowerCase();return this.store.list(t).filter((r)=>!e||r.key.toLowerCase().includes(e)).map((r)=>_D(r,{canReadSecretMetadata:t.canReadSecretMetadata}))}plan(t){let e=this.store.list({projectId:t.projectId,scope:t.scope}),r=new Map(e.map((T)=>[T.key,T])),d=[],E=[],n=[],c=[];for(let[T,i]of Object.entries(t.values)){d.push(...this.warnings(T,i));let h=r.get(T);if(!h)E.push(T);else if(h.valueFingerprint!==this.fingerprint(i))n.push(T);else c.push(T)}let _=t.removeMissing?e.filter((T)=>!Object.hasOwn(t.values,T.key)).map((T)=>T.key):[];return{added:ke(E),changed:ke(n),removed:ke(_),unchanged:ke(c),affectedResourceIds:this.affectedResources(t.projectId,t.scope,[...E,...n,..._]),warnings:d}}async set(t){let e=this.requestHash(t),r=t.idempotencyKey;if(r){let u=this.store.mutation(r);if(u){if(u.requestHash!==e)throw Error("Idempotency key was already used for a different configuration mutation.");let f=this.store.get(String(u.result.entryId??""));if(!f)throw Error("Idempotent configuration result is no longer available.");return{entry:f,mutation:u.result.mutation,warnings:[]}}}if(t.value!=null&&p2.test(t.value))throw Error("Secret references must use the reference field, not a plaintext value field.");let d=this.store.find(t.projectId,t.scope,t.key),E=this.fingerprint(t.value??t.reference??"");if(d&&t.expectedVersion!=null&&d.version!==t.expectedVersion)throw Error("Configuration entry changed; refresh and retry.");if(d&&d.kind!==t.kind)throw Error("Delete the existing entry before changing between variable and secret kinds.");let n=t.kind==="variable"?"plaintext":t.backend??(t.reference?"external":"local_encrypted");if(!!d&&(d.valueFingerprint!==E||d.backend!==n||d.required!==!!t.required)&&(this.isProduction(d)||this.store.dependencies(d.id).length>0)&&!t.confirmed)throw Error("Confirmation is required because this replacement affects production or dependent services.");let _=t.reference,T;if(t.kind==="secret"){let u=this.backend(n);if(t.reference&&t.value==null){if(!await u.validate(t.reference))throw Error("Secret backend reference is unavailable or invalid.");T=d?.backendVersion??"external"}else{if(t.value==null)throw Error("A secret value or external reference is required.");let f=await u.put({reference:d?.backend===n?d.secretRef:void 0,name:this.backendName(t),value:t.value,idempotencyKey:r??crypto.randomUUID()});_=f.reference,T=f.version}}let i=t.kind==="variable"?t.value:void 0;if(t.kind==="variable"&&i==null)throw Error("A variable value is required.");let h=!d||d.valueFingerprint!==E||d.backend!==n||d.secretRef!==_||d.backendVersion!==T||d.required!==!!t.required,R=d?h?this.store.update(d.id,d.version,{value:i,valueFingerprint:E,secretRef:_,backend:n,backendVersion:T,required:!!t.required,metadata:ut(t.metadata??d.metadata),rotatedAt:t.kind==="secret"?this.now().toISOString():d.rotatedAt}):d:this.store.create({organizationId:t.organizationId,projectId:t.projectId,scope:t.scope,key:t.key,kind:t.kind,value:i,valueFingerprint:E,secretRef:_,backend:n,backendVersion:T,origin:t.origin??"managed",required:!!t.required,metadata:ut(t.metadata??{}),rotatedAt:t.kind==="secret"?this.now().toISOString():void 0}),N=this.affectedResources(t.projectId,t.scope,[t.key]),A={added:d?[]:[t.key],changed:d&&h?[t.key]:[],removed:[],unchanged:d&&!h?[t.key]:[],affectedResourceIds:N,versions:{[t.key]:R.version}};if(r)this.store.recordMutation({projectId:t.projectId,idempotencyKey:r,requestHash:e,actorId:t.actorId,result:{entryId:R.id,mutation:A}});return this.audit(t.projectId,t.actorId,d&&h?"configuration.updated":d?"configuration.unchanged":"configuration.created",R,N),{entry:R,mutation:A,warnings:this.warnings(t.key,t.value??"")}}async importDotenv(t){let e=ED(t.source);if(!e.valid)return{document:e,warnings:[]};let r=new Set(t.secretKeys??[]),d={added:[],changed:[],removed:[],unchanged:[],affectedResourceIds:[],versions:{}},E=[];for(let[n,c]of Object.entries(e.values)){let _=await this.set({...t,source:void 0,key:n,value:c,kind:r.has(n)?"secret":"variable",idempotencyKey:t.idempotencyKey?`${t.idempotencyKey}:${n}`:void 0});d.added.push(..._.mutation.added),d.changed.push(..._.mutation.changed),d.unchanged.push(..._.mutation.unchanged),d.affectedResourceIds.push(..._.mutation.affectedResourceIds),Object.assign(d.versions,_.mutation.versions),E.push(..._.warnings)}return d.added=ke(d.added),d.changed=ke(d.changed),d.unchanged=ke(d.unchanged),d.affectedResourceIds=ke(d.affectedResourceIds),{document:e,mutation:d,warnings:E}}exportVariables(t){return nD(Object.fromEntries(this.store.list({projectId:t.projectId,scope:t.scope,kind:"variable"}).map((e)=>[e.key,e.value??""])))}async transfer(t){let e=this.store.get(t.entryId);if(!e)throw Error("Configuration entry was not found.");if(e.scope.type===t.targetScope.type&&e.scope.id===t.targetScope.id)throw Error("Choose a different destination scope.");let r=e.kind==="variable"?e.value:e.backend==="external"?void 0:await this.backend(e.backend).resolve(e.secretRef),d=e.kind==="secret"?e.backend:void 0,E=await this.set({organizationId:e.organizationId,projectId:e.projectId,scope:t.targetScope,key:e.key,kind:e.kind,value:r,reference:e.backend==="external"?e.secretRef:void 0,backend:d,required:e.required,metadata:e.metadata,confirmed:t.confirmed,actorId:t.actorId,idempotencyKey:t.idempotencyKey?`${t.idempotencyKey}:copy`:void 0,origin:e.origin});if(t.mode==="move")await this.remove({entryId:e.id,expectedVersion:e.version,confirmed:t.confirmed,actorId:t.actorId});let n={added:E.mutation.added,changed:E.mutation.changed,removed:t.mode==="move"?[e.key]:[],unchanged:E.mutation.unchanged,affectedResourceIds:ke([...E.mutation.affectedResourceIds,...this.affectedResources(e.projectId,e.scope,[e.key])]),versions:E.mutation.versions};return{entry:E.entry,mutation:n}}async resolve(t){let e=this.store.list({projectId:t.projectId}),r=e.filter((i)=>this.applies(i,t)).sort((i,h)=>this.rank(i.scope.type)-this.rank(h.scope.type)),d=new Map,E=new Set;for(let i of r){if(d.has(i.key))E.add(i.key);d.set(i.key,i)}let n={},c={},_=[],T=new Set(t.allowedPreviewSecrets??[]);for(let[i,h]of d){if(t.previewId&&h.kind==="secret"&&h.scope.type!=="preview"&&(!t.trustedPreview||!T.has(i)))continue;if(h.kind==="variable")n[i]=h.value??"";else if(t.nativeReferences)n[i]=h.secretRef;else{let R=this.backend(h.backend);if(!await R.validate(h.secretRef)){if(_.push({key:i,code:"stale_reference",message:`${i} points to an unavailable secret.`}),h.required)_.push({key:i,code:"missing_required",message:`${i} is required but unavailable.`});continue}n[i]=await R.resolve(h.secretRef)}c[i]=_D(h,{inherited:h.scope.type!==(t.previewId?"preview":t.functionId?"function":t.resourceId?"service":t.environmentId?"environment":"project"),overridden:E.has(i),canReadSecretMetadata:t.canReadSecretMetadata}),this.store.controlPlane.database.run("UPDATE configuration_entries SET last_used_at=? WHERE id=?",[this.now().toISOString(),h.id])}return{values:n,entries:c,warnings:_,configurationHash:this.fingerprint([...d.values()].map((i)=>`${i.key}:${i.valueFingerprint}:${i.version}`).sort().join(`
|
|
5621
5621
|
`))}}async reveal(t){let e=this.store.get(t.entryId);if(!e||e.kind!=="secret")throw Error("Configuration secret was not found.");if(!t.canRevealSecrets)throw Error("Secret reveal permission is required.");if(!t.recentlyAuthenticated)throw Error("Recent authentication is required to reveal a secret.");let r=await this.backend(e.backend).resolve(e.secretRef);return this.audit(e.projectId,t.actorId,"configuration.secret.revealed",e,[]),r}async remove(t){let e=this.store.get(t.entryId);if(!e)throw Error("Configuration entry was not found.");let r=this.store.dependencies(e.id);if(((e.scope.environmentId?this.store.controlPlane.listEnvironments(e.projectId).some((c)=>c.id===e.scope.environmentId&&c.kind==="production"):e.scope.type==="project")||r.length)&&!t.confirmed)throw Error("Confirmation is required because this configuration affects production or dependent services.");if(e.kind==="secret"&&e.backend!=="external")await this.backend(e.backend).remove(e.secretRef);this.store.remove(e.id,t.expectedVersion);let E=ke(r.map((c)=>c.resourceId)),n={added:[],changed:[],removed:[e.key],unchanged:[],affectedResourceIds:E,versions:{}};return this.audit(e.projectId,t.actorId,"configuration.deleted",e,E),n}applies(t,e){if(t.scope.type==="project")return!0;if(t.scope.type==="environment")return t.scope.id===e.environmentId;if(t.scope.type==="service")return t.scope.id===e.resourceId;if(t.scope.type==="function")return t.scope.id===e.functionId;return t.scope.id===e.previewId}rank(t){return{project:0,environment:1,service:2,function:3,preview:4}[t]}fingerprint(t){return`hmac-sha256:${m2("sha256",this.fingerprintKey).update(t).digest("hex")}`}requestHash(t){return this.fingerprint(JSON.stringify({...t,idempotencyKey:void 0,actorId:void 0}))}backend(t){let e=this.backends.get(t);if(!e)throw Error(`Configuration secret backend is not configured: ${t}`);return e}backendName(t){return`ts-cloud/${t.projectId}/${t.scope.type}/${t.scope.id}/${t.key}`.replace(/[^A-Za-z0-9/_+=.@-]/g,"-")}isProduction(t){return t.scope.type==="project"||!!t.scope.environmentId&&this.store.controlPlane.listEnvironments(t.projectId).some((e)=>e.id===t.scope.environmentId&&e.kind==="production")}warnings(t,e){let r=[];if(tP.test(t))r.push({key:t,code:"reserved",message:`${t} may be reserved by the runtime or provider.`});if(Buffer.byteLength(e)>65536)r.push({key:t,code:"limit",message:`${t} exceeds the portable 64 KiB value limit.`});return r}affectedResources(t,e,r){let d=this.store.list({projectId:t,scope:e}).filter((E)=>r.includes(E.key)).flatMap((E)=>this.store.dependencies(E.id).map((n)=>n.resourceId));if(e.type==="service"||e.type==="function")return ke([...d,e.id]);if(e.type==="environment")return ke([...d,...this.store.controlPlane.listResources(t,e.id).map((E)=>E.id)]);if(e.type==="preview"){let E=this.store.controlPlane.database.query("SELECT resource_id FROM preview_instances WHERE id=?").get(e.id);return ke([...d,...E?[E.resource_id]:[]])}return ke([...d,...this.store.controlPlane.listResources(t).map((E)=>E.id)])}audit(t,e,r,d,E){this.store.controlPlane.appendEvent({projectId:t,actorId:e,type:r,payload:{entryId:d.id,key:d.key,kind:d.kind,scopeType:d.scope.type,scopeId:d.scope.id,backend:d.backend,version:d.version,affectedResourceIds:E}})}}async function TD(t,e,r,d){let E={added:0,changed:0,removed:0,overridden:0},n=async(c,_)=>{let T=t.store.list({projectId:e.project.id,scope:c,kind:"variable"}),i=new Set(Object.keys(_));for(let h of T.filter((R)=>R.origin==="config"&&!i.has(R.key)))await t.remove({entryId:h.id,expectedVersion:h.version,confirmed:!0,actorId:d}),E.removed++;for(let[h,R]of Object.entries(_)){let N=t.store.find(e.project.id,c,h);if(N?.origin!=="config"){if(N)E.overridden++;else await t.set({organizationId:e.organization.id,projectId:e.project.id,scope:c,key:h,kind:"variable",value:String(R),origin:"config",confirmed:!0,actorId:d}),E.added++;continue}if(N.value===String(R))continue;await t.set({organizationId:e.organization.id,projectId:e.project.id,scope:c,key:h,kind:"variable",value:String(R),origin:"config",confirmed:!0,actorId:d,expectedVersion:N.version}),E.changed++}};for(let[c,_]of Object.entries(r.environments??{})){let T=e.environments.get(c);if(!T)continue;let i=_,h={...i.variables??{},...i.app?.env??{}};await n({type:"environment",id:T.id,environmentId:T.id},h);for(let[R,N]of Object.entries(r.sites??{})){let A=e.store.listResources(e.project.id,T.id).find((u)=>u.kind==="application"&&u.slug===R);if(A)await n({type:"service",id:A.id,environmentId:T.id,resourceId:A.id},{...N.env??{}})}for(let[R,N]of Object.entries(r.infrastructure?.functions??{})){let A=e.store.listResources(e.project.id,T.id).find((u)=>u.kind==="function"&&u.slug===R);if(A)await n({type:"function",id:A.id,environmentId:T.id,resourceId:A.id},{...N.environment??{}})}}return E}import{createHash as eP}from"node:crypto";var iD=async(t)=>{let e=Bun.spawn(t,{stdout:"pipe",stderr:"pipe"}),[r,d,E]=await Promise.all([e.exited,new Response(e.stdout).text(),new Response(e.stderr).text()]);return{code:r,stdout:d,stderr:E}};class hD{async scan(t,e){let r=await iD(["ssh-keyscan","-T","10","-p",String(e),"-t","ed25519",t]),d=r.stdout.split(`
|
|
5622
|
-
`).find((E)=>E&&!E.startsWith("#"))?.trim().split(/\s+/);if(r.code!==0||!d?.[1]||!d[2])throw Error(`SSH host-key scan failed: ${r.stderr.trim()||"no key returned"}`);return{algorithm:d[1],key:d[2]}}async exec(t,e){if(t.trustState!=="pinned")throw Error("SSH host key must be pinned before remote execution.");return iD(["ssh","-p",String(t.sshPort),"-o","BatchMode=yes","-o","StrictHostKeyChecking=yes","-o","ConnectTimeout=10",`${t.sshUser}@${t.endpoint}`,e])}}var rP=(t)=>`SHA256:${eP("sha256").update(Buffer.from(t,"base64")).digest("base64").replace(/=+$/,"")}`,dP=`set -eu; printf '{'; printf '"os":"%s",' "$(. /etc/os-release 2>/dev/null; printf %s "\${PRETTY_NAME:-Linux}")"; printf '"arch":"%s",' "$(uname -m)"; printf '"cpuCores":%s,' "$(getconf _NPROCESSORS_ONLN)"; printf '"memoryBytes":%s,' "$(awk '/MemTotal/{print $2*1024}' /proc/meminfo)"; printf '"diskBytes":%s,' "$(df -B1 / | awk 'NR==2{print $2}')"; printf '"diskFreeBytes":%s,' "$(df -B1 / | awk 'NR==2{print $4}')"; printf '"dnsOk":'; getent hosts example.com >/dev/null && printf true || printf false; printf ',"timeSkewSeconds":0,"tools":{"curl":"'; command -v curl >/dev/null && printf installed; printf '","tar":"'; command -v tar >/dev/null && printf installed; printf '"},"privilege":"'; sudo -n true >/dev/null 2>&1 && printf sudo || printf user; printf '"}'`;class C_{provider;transport;discoverer;constructor(t,e=new hD,r){this.provider=t;this.transport=e;this.discoverer=r}discover(t){return this.discoverer?.(t)??Promise.resolve([])}async test(t){try{let e=await this.transport.scan(t.endpoint,t.sshPort);return{reachable:!0,hostKeyAlgorithm:e.algorithm,hostKeyFingerprint:rP(e.key),latencyMs:0}}catch{return{reachable:!1,hostKeyAlgorithm:"unknown",hostKeyFingerprint:"",latencyMs:0}}}async validate(t){let e=await this.transport.exec(t,dP);if(e.code!==0)throw Error(`Fleet validation failed: ${e.stderr.trim()||e.code}`);try{return JSON.parse(e.stdout)}catch{throw Error("Fleet validation returned malformed facts.")}}async bootstrap(t,e){let r=await this.transport.exec(t,`sudo -n ts-cloud-agent bootstrap --version 1 --steps ${e.length}`);if(r.code!==0)throw Error(`Fleet bootstrap failed: ${r.stderr.trim()||r.code}`);return{version:"1"}}capabilities(){return{document:{supported:!0,reason:"fleet-capabilities/v1; sha256:driver-contract"},validate:{supported:!0},bootstrap:{supported:!0},heartbeat:{supported:!0},drain:{supported:!0},archive:{supported:!0},terminate:{supported:!1,reason:"Inventory removal never terminates provider infrastructure."}}}}function RD(t,e){return{"fleet.bootstrap":async(r)=>{let d=r.operation.input&&typeof r.operation.input==="object"&&!Array.isArray(r.operation.input)?r.operation.input:{},E=t.get(String(d.serverId??""));if(!E)throw Error("Queued fleet server was not found.");let n=e.find((T)=>T.provider===E.provider);if(!n)throw Error(`No ${E.provider} fleet driver is configured.`);let c=Array.isArray(d.steps)?d.steps.map(String):[];if(r.checkpoint("preflight","Rechecking pinned trust and healthy validation."),E.trustState!=="pinned"||!E.validation?.valid)throw Error("Fleet bootstrap requires pinned trust and a healthy validation report.");r.checkpoint("bootstrap","Applying the reviewed idempotent bootstrap plan.");let _=await n.bootstrap(E,c);return t.update(E.id,{bootstrapVersion:_.version,status:"ready"}),r.checkpoint("verify","Bootstrap completed; heartbeat can now establish freshness."),{serverId:E.id,bootstrapVersion:_.version,steps:c.length}}}}var br=(t)=>t==null?void 0:String(t),vE=(t,e)=>{try{return JSON.parse(String(t))}catch{return e}},lA=(t)=>({id:String(t.id),organizationId:String(t.organization_id),projectId:String(t.project_id),resourceId:String(t.resource_id),name:String(t.name),provider:String(t.provider),providerId:br(t.provider_id),region:br(t.region),zone:br(t.zone),endpoint:String(t.endpoint),sshUser:String(t.ssh_user),sshPort:Number(t.ssh_port),credentialRef:String(t.credential_ref),hostKeyAlgorithm:br(t.host_key_algorithm),hostKeyFingerprint:br(t.host_key_fingerprint),pendingHostKey:br(t.pending_host_key),roles:vE(t.roles,[]),labels:vE(t.labels,{}),taints:vE(t.taints,[]),capacity:vE(t.capacity,{}),usage:vE(t.usage,{}),capabilities:vE(t.capabilities,{}),status:String(t.status),trustState:String(t.trust_state),validation:vE(t.validation,void 0),bootstrapVersion:br(t.bootstrap_version),heartbeatAt:br(t.heartbeat_at),lastSeenAt:br(t.last_seen_at),archivedAt:br(t.archived_at),version:Number(t.version),createdAt:String(t.created_at),updatedAt:String(t.updated_at)});class IA{control;now;id;constructor(t,e=()=>new Date,r=()=>crypto.randomUUID()){this.control=t;this.now=e;this.id=r}get(t){let e=this.control.database.query("SELECT * FROM fleet_servers WHERE id=?").get(t);return e?lA(e):void 0}list(t,e=!1){return this.control.database.query("SELECT * FROM fleet_servers WHERE project_id=? ORDER BY name").all(t).map(lA).filter((r)=>e||r.status!=="archived")}findProvider(t,e,r){let d=this.control.database.query("SELECT * FROM fleet_servers WHERE organization_id=? AND provider=? AND provider_id=? AND archived_at IS NULL").get(t,e,r);return d?lA(d):void 0}create(t){let e=this.id(),r=this.now().toISOString();return this.control.database.run("INSERT INTO fleet_servers (id,organization_id,project_id,resource_id,name,provider,provider_id,region,zone,endpoint,ssh_user,ssh_port,credential_ref,host_key_algorithm,host_key_fingerprint,pending_host_key,roles,labels,taints,capacity,usage,capabilities,status,trust_state,validation,bootstrap_version,heartbeat_at,last_seen_at,archived_at,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",[e,t.organizationId,t.projectId,t.resourceId,t.name,t.provider,t.providerId??null,t.region??null,t.zone??null,t.endpoint,t.sshUser,t.sshPort,t.credentialRef,t.hostKeyAlgorithm??null,t.hostKeyFingerprint??null,t.pendingHostKey??null,JSON.stringify(t.roles),JSON.stringify(t.labels),JSON.stringify(t.taints),JSON.stringify(t.capacity),JSON.stringify(t.usage),JSON.stringify(t.capabilities),t.status,t.trustState,JSON.stringify(t.validation??{}),t.bootstrapVersion??null,t.heartbeatAt??null,t.lastSeenAt??null,t.archivedAt??null,r,r]),this.get(e)}update(t,e){let r=this.get(t);if(!r)throw Error("Server was not found.");let d={...r,...e},E=this.now().toISOString();return this.control.database.run("UPDATE fleet_servers SET name=?,provider_id=?,region=?,zone=?,endpoint=?,ssh_user=?,ssh_port=?,credential_ref=?,host_key_algorithm=?,host_key_fingerprint=?,pending_host_key=?,roles=?,labels=?,taints=?,capacity=?,usage=?,capabilities=?,status=?,trust_state=?,validation=?,bootstrap_version=?,heartbeat_at=?,last_seen_at=?,archived_at=?,version=version+1,updated_at=? WHERE id=?",[d.name,d.providerId??null,d.region??null,d.zone??null,d.endpoint,d.sshUser,d.sshPort,d.credentialRef,d.hostKeyAlgorithm??null,d.hostKeyFingerprint??null,d.pendingHostKey??null,JSON.stringify(d.roles),JSON.stringify(d.labels),JSON.stringify(d.taints),JSON.stringify(d.capacity),JSON.stringify(d.usage),JSON.stringify(d.capabilities),d.status,d.trustState,JSON.stringify(d.validation??{}),d.bootstrapVersion??null,d.heartbeatAt??null,d.lastSeenAt??null,d.archivedAt??null,E,t]),this.get(t)}}var EP=/^(?:[A-Za-z0-9](?:[A-Za-z0-9.-]{0,251}[A-Za-z0-9])?|\[[0-9a-fA-F:]+\])$/;class DA{store;drivers;now;queue;constructor(t,e,r,d=()=>new Date){this.store=t;this.drivers=e;this.now=d;this.queue=r??new gt(t.control)}driver(t){let e=this.drivers.find((r)=>r.provider===t);if(!e)throw Error(`No ${t} fleet driver is configured.`);return e}enroll(t){if(!/^[a-z0-9][a-z0-9-]{1,62}$/.test(t.name))throw Error("Server name is invalid.");if(!EP.test(t.endpoint)||t.sshUser==="root"||!t.credentialRef.startsWith("secret://"))throw Error("Enrollment requires a valid endpoint, non-root SSH user, and secret credential reference.");let e=t.providerId?this.store.findProvider(t.organizationId,t.provider,t.providerId):void 0;if(e)return this.store.update(e.id,{endpoint:t.endpoint,region:t.region,zone:t.zone});let r=this.store.control.createResource({projectId:t.projectId,kind:"server",slug:t.name,name:t.name,provider:t.provider,providerId:t.providerId}),d=this.driver(t.provider);return this.store.create({...t,resourceId:r.id,sshPort:t.sshPort??22,labels:t.labels??{},taints:[],capacity:{},usage:{},capabilities:d.capabilities(),status:"pending",trustState:"unverified"})}async test(t){let e=this.store.get(t);if(!e)throw Error("Server was not found.");let r=await this.driver(e.provider).test(e);if(!r.reachable)return this.store.update(t,{status:"unreachable"});if(e.hostKeyFingerprint&&e.hostKeyFingerprint!==r.hostKeyFingerprint)return this.store.update(t,{status:"degraded",trustState:"rotation_pending",pendingHostKey:r.hostKeyFingerprint});return this.store.update(t,{hostKeyAlgorithm:r.hostKeyAlgorithm,hostKeyFingerprint:r.hostKeyFingerprint,pendingHostKey:void 0,trustState:"pinned",status:"validating",lastSeenAt:this.now().toISOString()})}reviewHostKey(t,e){let r=this.store.get(t);if(!r||r.pendingHostKey!==e)throw Error("Pending host key does not match.");return this.store.update(t,{hostKeyFingerprint:e,pendingHostKey:void 0,trustState:"pinned",status:"validating"})}async validate(t){let e=this.store.get(t);if(!e||e.trustState!=="pinned")throw Error("Pin the SSH host key before validation.");let r=await this.driver(e.provider).validate(e),d=[];if(!["x64","arm64","x86_64","aarch64"].includes(r.arch??""))d.push({code:"arch.unsupported",severity:"error",message:"Unsupported architecture.",remediation:"Use x86_64 or arm64 Linux."});for(let c of["curl","tar"])if(!r.tools?.[c])d.push({code:`tool.${c}`,severity:"error",message:`${c} is missing.`,remediation:`Install ${c} before bootstrap.`});if(Math.abs(r.timeSkewSeconds??0)>60)d.push({code:"time.skew",severity:"error",message:"Clock skew exceeds 60 seconds.",remediation:"Enable NTP synchronization."});if(!r.dnsOk)d.push({code:"dns.failed",severity:"error",message:"DNS validation failed.",remediation:"Repair resolver configuration."});let E={valid:!d.some((c)=>c.severity==="error"),facts:r,findings:d,validatedAt:this.now().toISOString(),validatorVersion:"1"},n={cpu:r.cpuCores??0,memoryBytes:r.memoryBytes??0,diskBytes:r.diskBytes??0};return this.store.update(t,{validation:E,capacity:n,status:E.valid?"ready":"degraded"})}bootstrap(t,e=!1){let r=this.store.get(t);if(!r?.validation?.valid)throw Error("A healthy validation report is required.");let d=["install runtime dependencies","install ts-cloud agent","configure heartbeat","verify least-privilege access"];if(!e)return{preview:!0,steps:d};let E=this.queue.enqueue({projectId:r.projectId,resourceId:r.resourceId,kind:"fleet.bootstrap",input:{serverId:t,steps:d},lockKey:`server:${t}`,providerKey:r.provider}).operation;return{preview:!1,steps:d,operation:E}}heartbeat(t,e){let r=this.store.get(t);if(!r)throw Error("Server was not found.");let d=this.now().toISOString();return this.store.update(t,{usage:e.usage,capabilities:e.capabilities??r.capabilities,heartbeatAt:d,lastSeenAt:d,status:r.status==="draining"||r.status==="drained"?r.status:"ready"})}drain(t,e=!1){return this.store.update(t,{status:e?"drained":"draining"})}uncordon(t){return this.store.update(t,{status:"ready"})}archive(t,e){let r=this.store.get(t);if(!r||e!==r.name)throw Error("Exact server name confirmation is required.");return this.store.update(t,{status:"archived",archivedAt:this.now().toISOString()})}}import{createHash as fA,createPublicKey as AD,verify as nP}from"node:crypto";function l_(t){if(t===null||typeof t!=="object")return JSON.stringify(t);if(Array.isArray(t))return`[${t.map(l_).join(",")}]`;return`{${Object.keys(t).sort().map((e)=>`${JSON.stringify(e)}:${l_(t[e])}`).join(",")}}`}var LD=(t)=>fA("sha256").update(l_(t)).digest("hex"),si=(t)=>fA("sha256").update(l_(t)).digest("hex"),uD=(t)=>fA("sha256").update(AD(t).export({type:"spki",format:"der"})).digest("hex");function OD(t,e,r){try{return nP(null,Buffer.from(l_(t)),AD(r),Buffer.from(e,"base64"))}catch{return!1}}var SD=(t)=>t.replace(/^v/,"").split(/[.-]/).slice(0,3).map((e)=>Number(e)||0),ND=(t,e)=>{let r=SD(t),d=SD(e);for(let E=0;E<3;E++){let n=(r[E]??0)-(d[E]??0);if(n)return n}return 0};function CD(t,e){let r=[];if(e.schemaVersion<t.minimumSchema)r.push(`schema ${e.schemaVersion} is below ${t.minimumSchema}`);if(e.schemaVersion>t.maximumSchema)r.push(`schema ${e.schemaVersion} is above ${t.maximumSchema}`);if(t.minimumVersion&&ND(e.currentVersion,t.minimumVersion)<0)r.push(`platform ${e.currentVersion} is below ${t.minimumVersion}`);if(ND(t.version,e.currentVersion)<=0)r.push(`version ${t.version} is not newer than ${e.currentVersion}`);if(!t.artifacts.some((d)=>d.platform===e.platform&&d.architecture===e.architecture))r.push(`no artifact for ${e.platform}/${e.architecture}`);return{compatible:r.length===0,reasons:r}}var Ad=(t,e)=>{try{return JSON.parse(String(t))}catch{return e}},fe=(t)=>t==null?void 0:String(t),cP=(t)=>({id:String(t.id),organizationId:String(t.organization_id),name:String(t.name),algorithm:"ed25519",publicKeyPem:String(t.public_key_pem),fingerprint:String(t.fingerprint),revokedAt:fe(t.revoked_at),createdAt:String(t.created_at)}),lD=(t)=>({id:String(t.id),organizationId:String(t.organization_id),version:String(t.version),channel:String(t.channel),publishedAt:String(t.published_at),keyId:String(t.key_id),digest:String(t.digest),document:Ad(t.document,{}),signature:String(t.signature),verificationStatus:String(t.verification_status),compatibility:Ad(t.compatibility,{compatible:!1,reasons:[]}),createdAt:String(t.created_at)}),ID=(t)=>({id:String(t.id),projectId:String(t.project_id),name:String(t.name),schedule:String(t.schedule),timezone:String(t.timezone),durationMinutes:Number(t.duration_minutes),allowedOperations:Ad(t.allowed_operations,[]),requireApproval:Number(t.require_approval)===1,enabled:Number(t.enabled)===1,createdAt:String(t.created_at),updatedAt:String(t.updated_at)}),DD=(t)=>({id:String(t.id),projectId:String(t.project_id),manifestId:String(t.manifest_id),windowId:fe(t.window_id),fromVersion:String(t.from_version),strategy:String(t.strategy),batchSize:Number(t.batch_size),healthGate:Ad(t.health_gate,{}),status:String(t.status),currentStage:fe(t.current_stage),backupId:fe(t.backup_id),approvedBy:fe(t.approved_by),createdAt:String(t.created_at),updatedAt:String(t.updated_at)}),UA=(t)=>({id:String(t.id),campaignId:String(t.campaign_id),serverId:fe(t.server_id),target:String(t.target),cohort:Number(t.cohort),previousVersion:String(t.previous_version),status:String(t.status),evidence:Ad(t.evidence,{}),error:fe(t.error),startedAt:fe(t.started_at),finishedAt:fe(t.finished_at),createdAt:String(t.created_at),updatedAt:String(t.updated_at)}),fD=(t)=>({id:String(t.id),projectId:String(t.project_id),kind:String(t.kind),criteria:Ad(t.criteria,{}),candidates:Ad(t.candidates,[]),candidateDigest:String(t.candidate_digest),estimatedBytes:Number(t.estimated_bytes),status:String(t.status),confirmation:fe(t.confirmation),expiresAt:String(t.expires_at),result:Ad(t.result,{}),createdAt:String(t.created_at),updatedAt:String(t.updated_at)}),UD=(t)=>({id:String(t.id),projectId:String(t.project_id),backupPolicyId:fe(t.backup_policy_id),recoveryPointId:fe(t.recovery_point_id),topologyId:fe(t.topology_id),scenario:String(t.scenario),isolatedTarget:String(t.isolated_target),expectedRpoMinutes:Number(t.expected_rpo_minutes),expectedRtoMinutes:Number(t.expected_rto_minutes),status:String(t.status),operationId:fe(t.operation_id),evidence:Ad(t.evidence,{}),measuredRpoMinutes:t.measured_rpo_minutes==null?void 0:Number(t.measured_rpo_minutes),measuredRtoMinutes:t.measured_rto_minutes==null?void 0:Number(t.measured_rto_minutes),cleanupVerified:Number(t.cleanup_verified)===1,error:fe(t.error),startedAt:fe(t.started_at),finishedAt:fe(t.finished_at),createdAt:String(t.created_at),updatedAt:String(t.updated_at)});class wA{control;now;id;constructor(t,e=()=>new Date,r=()=>crypto.randomUUID()){this.control=t;this.now=e;this.id=r}addTrustedKey(t){let e=this.id(),r=this.now().toISOString(),d=uD(t.publicKeyPem);return this.control.database.run("INSERT INTO platform_trusted_keys (id,organization_id,name,algorithm,public_key_pem,fingerprint,created_at) VALUES (?,?,?,'ed25519',?,?,?)",[e,t.organizationId,t.name,t.publicKeyPem,d,r]),this.key(e)}key(t){let e=this.control.database.query("SELECT * FROM platform_trusted_keys WHERE id=?").get(t);return e?cP(e):void 0}revokeKey(t){return this.control.database.run("UPDATE platform_trusted_keys SET revoked_at=? WHERE id=?",[this.now().toISOString(),t]),this.key(t)}importManifest(t){let e=this.key(t.keyId);if(!e||e.organizationId!==t.organizationId)throw Error("Trusted update key was not found.");if(e.revokedAt)throw Error("Update signing key is revoked.");if(!OD(t.document,t.signature,e.publicKeyPem))throw Error("Update manifest signature is invalid.");let r=CD(t.document,t.current),d=LD(t.document),E=this.id(),n=this.now().toISOString();return this.control.database.run("INSERT INTO platform_update_manifests (id,organization_id,version,channel,published_at,key_id,digest,document,signature,verification_status,compatibility,created_at) VALUES (?,?,?,?,?,?,?,?,?,'verified',?,?)",[E,t.organizationId,t.document.version,t.document.channel,new Date(t.document.publishedAt).toISOString(),t.keyId,d,JSON.stringify(t.document),t.signature,JSON.stringify(r),n]),this.manifest(E)}manifest(t){let e=this.control.database.query("SELECT * FROM platform_update_manifests WHERE id=?").get(t);return e?lD(e):void 0}manifests(t){return this.control.database.query("SELECT * FROM platform_update_manifests WHERE organization_id=? ORDER BY published_at DESC").all(t).map(lD)}createWindow(t){let e=this.id(),r=this.now().toISOString();return this.control.database.run("INSERT INTO maintenance_windows (id,project_id,name,schedule,timezone,duration_minutes,allowed_operations,require_approval,enabled,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,1,?,?)",[e,t.projectId,t.name,t.schedule,t.timezone,t.durationMinutes,JSON.stringify(t.allowedOperations),t.requireApproval===!1?0:1,r,r]),this.window(e)}window(t){let e=this.control.database.query("SELECT * FROM maintenance_windows WHERE id=?").get(t);return e?ID(e):void 0}windows(t){return this.control.database.query("SELECT * FROM maintenance_windows WHERE project_id=? ORDER BY name").all(t).map(ID)}createCampaign(t){return this.control.transaction(()=>{let e=this.manifest(t.manifestId);if(!e?.compatibility.compatible||e.verificationStatus!=="verified")throw Error("A verified compatible update manifest is required.");if(!t.backupId)throw Error("A verified pre-upgrade backup is required.");let r=this.id(),d=this.now().toISOString();return this.control.database.run("INSERT INTO platform_upgrade_campaigns (id,project_id,manifest_id,window_id,from_version,strategy,batch_size,health_gate,status,backup_id,approved_by,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?, 'planned',?,?,?,?)",[r,t.projectId,t.manifestId,t.windowId??null,t.fromVersion,t.strategy,t.batchSize,JSON.stringify(t.healthGate),t.backupId,t.approvedBy??null,d,d]),t.targets.forEach((E,n)=>this.control.database.run("INSERT INTO platform_upgrade_targets (id,campaign_id,server_id,target,cohort,previous_version,status,created_at,updated_at) VALUES (?,?,?,?,?,?,'pending',?,?)",[this.id(),r,E.serverId??null,E.target,t.strategy==="canary"?n===0?0:1+Math.floor((n-1)/t.batchSize):Math.floor(n/t.batchSize),E.previousVersion,d,d])),this.campaign(r)})}campaign(t){let e=this.control.database.query("SELECT * FROM platform_upgrade_campaigns WHERE id=?").get(t);return e?DD(e):void 0}campaigns(t){return this.control.database.query("SELECT * FROM platform_upgrade_campaigns WHERE project_id=? ORDER BY created_at DESC").all(t).map(DD)}targets(t){return this.control.database.query("SELECT * FROM platform_upgrade_targets WHERE campaign_id=? ORDER BY cohort,target").all(t).map(UA)}updateCampaign(t,e){let r=this.campaign(t);if(!r)throw Error("Upgrade campaign was not found.");let d={...r,...e};return this.control.database.run("UPDATE platform_upgrade_campaigns SET status=?,current_stage=?,updated_at=? WHERE id=?",[d.status,d.currentStage??null,this.now().toISOString(),t]),this.campaign(t)}updateTarget(t,e){let r=this.control.database.query("SELECT * FROM platform_upgrade_targets WHERE id=?").get(t);if(!r)throw Error("Upgrade target was not found.");let d={...UA(r),...e};return this.control.database.run("UPDATE platform_upgrade_targets SET status=?,evidence=?,error=?,started_at=?,finished_at=?,updated_at=? WHERE id=?",[d.status,JSON.stringify(d.evidence),d.error??null,d.startedAt??null,d.finishedAt??null,this.now().toISOString(),t]),UA(this.control.database.query("SELECT * FROM platform_upgrade_targets WHERE id=?").get(t))}createCleanup(t){let e=[...t.candidates].sort((c,_)=>c.id.localeCompare(_.id)),r=si(e),d=this.id(),E=this.now().toISOString(),n=new Date(this.now().getTime()+(t.ttlMinutes??60)*60000).toISOString();return this.control.database.run("INSERT INTO cleanup_plans (id,project_id,kind,criteria,candidates,candidate_digest,estimated_bytes,status,expires_at,created_at,updated_at) VALUES (?,?,?,?,?,?,?,'preview',?,?,?)",[d,t.projectId,t.kind,JSON.stringify(t.criteria),JSON.stringify(e),r,e.reduce((c,_)=>c+_.bytes,0),n,E,E]),this.cleanup(d)}cleanup(t){let e=this.control.database.query("SELECT * FROM cleanup_plans WHERE id=?").get(t);return e?fD(e):void 0}cleanups(t){return this.control.database.query("SELECT * FROM cleanup_plans WHERE project_id=? ORDER BY created_at DESC").all(t).map(fD)}updateCleanup(t,e){let r=this.cleanup(t);if(!r)throw Error("Cleanup plan was not found.");let d={...r,...e};return this.control.database.run("UPDATE cleanup_plans SET status=?,confirmation=?,result=?,updated_at=? WHERE id=?",[d.status,d.confirmation??null,JSON.stringify(d.result),this.now().toISOString(),t]),this.cleanup(t)}createDrill(t){if(!/^isolated:\/\//.test(t.isolatedTarget))throw Error("DR drills require an isolated target.");let e=this.id(),r=this.now().toISOString();return this.control.database.run("INSERT INTO disaster_recovery_drills (id,project_id,backup_policy_id,recovery_point_id,topology_id,scenario,isolated_target,expected_rpo_minutes,expected_rto_minutes,status,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,'planned',?,?)",[e,t.projectId,t.backupPolicyId??null,t.recoveryPointId??null,t.topologyId??null,t.scenario,t.isolatedTarget,t.expectedRpoMinutes,t.expectedRtoMinutes,r,r]),this.drill(e)}drill(t){let e=this.control.database.query("SELECT * FROM disaster_recovery_drills WHERE id=?").get(t);return e?UD(e):void 0}drills(t){return this.control.database.query("SELECT * FROM disaster_recovery_drills WHERE project_id=? ORDER BY created_at DESC").all(t).map(UD)}updateDrill(t,e){let r=this.drill(t);if(!r)throw Error("DR drill was not found.");let d={...r,...e};return this.control.database.run("UPDATE disaster_recovery_drills SET status=?,operation_id=?,evidence=?,measured_rpo_minutes=?,measured_rto_minutes=?,cleanup_verified=?,error=?,started_at=?,finished_at=?,updated_at=? WHERE id=?",[d.status,d.operationId??null,JSON.stringify(d.evidence),d.measuredRpoMinutes??null,d.measuredRtoMinutes??null,d.cleanupVerified?1:0,d.error??null,d.startedAt??null,d.finishedAt??null,this.now().toISOString(),t]),this.drill(t)}}function _P(t,e=new Date){if(!t.enabled)return!1;let r=new Date(t.schedule);if(!Number.isNaN(r.getTime()))return e>=r&&e.getTime()<=r.getTime()+t.durationMinutes*60000;let d=/^(\d{2}):(\d{2})$/.exec(t.schedule);if(!d)return!1;let E=new Intl.DateTimeFormat("en-US",{timeZone:t.timezone,hour:"2-digit",minute:"2-digit",hourCycle:"h23"}).formatToParts(e),n=Number(E.find((_)=>_.type==="hour")?.value)*60+Number(E.find((_)=>_.type==="minute")?.value),c=Number(d[1])*60+Number(d[2]);return n>=c&&n<c+t.durationMinutes}class gA{store;now;queue;constructor(t,e,r=()=>new Date){this.store=t;this.now=r;this.queue=e??new gt(t.control)}enqueueCampaign(t,e={}){let r=this.store.campaign(t);if(!r)throw Error("Upgrade campaign was not found.");let d=r.windowId?this.store.window(r.windowId):void 0;if(d&&!d.allowedOperations.includes("platform.upgrade"))throw Error("Maintenance window does not permit platform upgrades.");if(d&&!e.overrideWindow&&!_P(d,this.now()))throw Error("Upgrade is outside its maintenance window.");if(d?.requireApproval&&!e.approvedBy&&!r.approvedBy)throw Error("Maintenance approval is required.");let E=this.queue.enqueue({projectId:r.projectId,actorId:e.approvedBy,kind:"maintenance.upgrade",input:{campaignId:t},lockKey:"platform-upgrade",providerKey:"platform",timeoutSeconds:7200,cancellationMode:"cooperative",resumePolicy:"fail"}).operation;return{campaign:this.store.updateCampaign(t,{status:"queued"}),operation:E}}async previewCleanup(t,e){let r=e.find((d)=>d.kind===t.kind);if(!r)throw Error(`No ${t.kind} cleanup driver is configured.`);return this.store.createCleanup({...t,candidates:await r.discover(t.criteria)})}enqueueCleanup(t,e){let r=this.store.cleanup(t);if(!r||r.status!=="preview")throw Error("A current cleanup preview is required.");if(new Date(r.expiresAt)<=this.now())throw Error("Cleanup preview expired; generate it again.");let d=`DELETE ${r.candidates.length} ${r.kind}`;if(e!==d)throw Error(`Exact confirmation ${d} is required.`);let E=this.queue.enqueue({projectId:r.projectId,kind:"maintenance.cleanup",input:{planId:t},lockKey:`cleanup:${r.kind}`,providerKey:"cleanup",timeoutSeconds:3600,cancellationMode:"cooperative"}).operation;return{plan:this.store.updateCleanup(t,{status:"approved",confirmation:e}),operation:E}}enqueueDrill(t){let e=this.store.drill(t);if(!e||e.status!=="planned")throw Error("A planned DR drill is required.");let r=this.queue.enqueue({projectId:e.projectId,kind:"maintenance.drill",input:{drillId:t},lockKey:`drill:${e.scenario}:${e.id}`,providerKey:"recovery",timeoutSeconds:7200,cancellationMode:"cooperative"}).operation;return{drill:this.store.updateDrill(t,{status:"queued",operationId:r.id}),operation:r}}}var $A=(t)=>t&&typeof t==="object"&&!Array.isArray(t)?t:{};function wD(t){return{"maintenance.upgrade":async(E)=>{let n=t.store.campaign(String($A(E.operation.input).campaignId??""));if(!n||!t.platform)throw Error("Upgrade campaign or platform maintenance driver is unavailable.");let c=t.store.manifest(n.manifestId);if(!c?.compatibility.compatible||c.verificationStatus!=="verified")throw Error("Update manifest is no longer verified and compatible.");let _=c.document.artifacts.find((i)=>i.platform===process.platform&&i.architecture===process.arch)??c.document.artifacts[0];if(!_)throw Error("No update artifact matches this platform.");t.store.updateCampaign(n.id,{status:"running",currentStage:"preflight"});let T=[];try{for(let i of[...new Set(t.store.targets(n.id).map((h)=>h.cohort))].sort((h,R)=>h-R)){t.store.updateCampaign(n.id,{currentStage:`cohort:${i}`});for(let h of t.store.targets(n.id).filter((R)=>R.cohort===i)){E.throwIfCancellationRequested(),E.checkpoint(`download:${h.target}`,"Downloading signed platform artifact."),t.store.updateTarget(h.id,{status:"downloading",startedAt:new Date().toISOString()});let R=await t.platform.download({target:h,artifact:_,signal:E.signal});if(R.sha256!==_.sha256)throw Error(`Artifact checksum mismatch for ${h.target}.`);E.checkpoint(`install:${h.target}`,"Installing verified artifact."),t.store.updateTarget(h.id,{status:"installing"}),await t.platform.install({target:h,path:R.path,version:c.version,signal:E.signal}),T.push(h);let N=await t.platform.health({target:h,gate:n.healthGate});if(!N.healthy)throw Error(`Upgrade health gate failed for ${h.target}.`);t.store.updateTarget(h.id,{status:"healthy",evidence:N.evidence,finishedAt:new Date().toISOString()})}}return t.store.updateCampaign(n.id,{status:"succeeded",currentStage:void 0}),{campaignId:n.id,version:c.version,targets:T.length}}catch(i){t.store.updateCampaign(n.id,{status:"rolling_back",currentStage:"rollback"});for(let h of T.reverse())t.store.updateTarget(h.id,{status:"rolling_back"}),await t.platform.rollback({target:h,version:h.previousVersion,signal:E.signal}),t.store.updateTarget(h.id,{status:"rolled_back",finishedAt:new Date().toISOString()});throw t.store.updateCampaign(n.id,{status:"rolled_back",currentStage:void 0}),i}},"maintenance.cleanup":async(E)=>{let n=t.store.cleanup(String($A(E.operation.input).planId??""));if(!n||n.status!=="approved")throw Error("Approved cleanup plan was not found.");if(si([...n.candidates].sort((h,R)=>h.id.localeCompare(R.id)))!==n.candidateDigest)throw Error("Cleanup candidate set changed after preview.");let c=t.cleanup?.find((h)=>h.kind===n.kind);if(!c)throw Error(`No ${n.kind} cleanup driver is configured.`);t.store.updateCleanup(n.id,{status:"running"});let _=[],T=[];for(let h of n.candidates){E.throwIfCancellationRequested();try{await c.remove(h),_.push(h.id)}catch(R){T.push({id:h.id,error:R instanceof Error?R.message:String(R)})}}let i=T.length?_.length?"partial":"failed":"succeeded";if(t.store.updateCleanup(n.id,{status:i,result:{removed:_,failed:T,reclaimedBytes:n.candidates.filter((h)=>_.includes(h.id)).reduce((h,R)=>h+R.bytes,0)}}),T.length)throw Error(`Cleanup failed for ${T.length} candidate(s).`);return{planId:n.id,removed:_.length,reclaimedBytes:n.estimatedBytes}},"maintenance.drill":async(E)=>{let n=t.store.drill(String($A(E.operation.input).drillId??""));if(!n)throw Error("DR drill was not found.");let c=t.recovery?.find((R)=>R.scenario===n.scenario);if(!c)throw Error(`No ${n.scenario} recovery driver is configured.`);let _=new Date;t.store.updateDrill(n.id,{status:"restoring",startedAt:_.toISOString()});let T=n.isolatedTarget,i={},h={};try{E.checkpoint("restore","Restoring into isolated drill target.");let R=await c.restore({drill:n,signal:E.signal});if(!R.target.startsWith("isolated://"))throw Error("Recovery driver attempted a non-isolated target.");T=R.target,i=R.evidence;let N=(_.getTime()-new Date(R.recoveryPointAt).getTime())/60000;t.store.updateDrill(n.id,{status:"verifying",measuredRpoMinutes:N,evidence:{restore:i}}),E.checkpoint("verify","Running recovery health checks without production traffic.");let A=await c.verify({drill:n,target:T});h=A.evidence;let u=(Date.now()-_.getTime())/60000;if(!A.healthy||N>n.expectedRpoMinutes||u>n.expectedRtoMinutes)throw Error("DR drill failed its health, RPO, or RTO objective.");t.store.updateDrill(n.id,{measuredRpoMinutes:N,measuredRtoMinutes:u,evidence:{restore:i,verify:h}})}catch(R){throw t.store.updateDrill(n.id,{status:"failed",error:R instanceof Error?R.message:String(R),evidence:{restore:i,verify:h}}),R}finally{t.store.updateDrill(n.id,{status:"cleaning"});try{await c.cleanup({drill:n,target:T});let R=t.store.drill(n.id);t.store.updateDrill(n.id,{status:R.error?"failed":"passed",cleanupVerified:!0,finishedAt:new Date().toISOString()})}catch(R){t.store.updateDrill(n.id,{status:"cleanup_required",cleanupVerified:!1,error:R instanceof Error?R.message:String(R),finishedAt:new Date().toISOString()})}}return{drillId:n.id,status:t.store.drill(n.id).status}}}}var gD={releases:{select:"SELECT id,created_at,0 bytes FROM releases WHERE project_id=? AND pinned=0 AND status IN ('failed','rolled_back','superseded') AND created_at<?",remove:"DELETE FROM releases WHERE id=?"},artifacts:{select:"SELECT a.id,a.created_at,a.size bytes FROM release_artifacts a WHERE a.organization_id=? AND NOT EXISTS(SELECT 1 FROM releases r WHERE r.artifact_id=a.id) AND a.created_at<?",remove:"DELETE FROM release_artifacts WHERE id=?"},operations:{select:"SELECT id,created_at,0 bytes FROM operations WHERE project_id=? AND state IN ('succeeded','failed','cancelled','timed_out') AND updated_at<?",remove:"DELETE FROM operations WHERE id=?"},logs:{select:"SELECT l.id,l.created_at,length(l.message) bytes FROM operation_logs l JOIN operations o ON o.id=l.operation_id WHERE o.project_id=? AND o.state IN ('succeeded','failed','cancelled','timed_out') AND l.created_at<?",remove:"DELETE FROM operation_logs WHERE id=?"},previews:{select:"SELECT id,created_at,0 bytes FROM preview_instances WHERE project_id=? AND status IN ('destroyed','failed') AND updated_at<?",remove:"DELETE FROM preview_instances WHERE id=?"},snapshots:{select:"SELECT id,created_at,size_bytes bytes FROM recovery_points WHERE project_id=? AND pinned=0 AND held=0 AND status IN ('failed','deleted') AND created_at<?",remove:"DELETE FROM recovery_points WHERE id=?"},orphaned_resources:{select:"SELECT id,created_at,COALESCE(capacity_bytes,0) bytes FROM persistent_volumes WHERE project_id=? AND status='orphaned' AND orphaned_at<?",remove:"UPDATE persistent_volumes SET status='deleted',deleted_at=datetime('now'),updated_at=datetime('now') WHERE id=? AND status='orphaned'"}};class yA{kind;control;projectId;organizationId;constructor(t,e,r,d){this.kind=t;this.control=e;this.projectId=r;this.organizationId=d}async discover(t){let e=Math.max(1,Math.min(3650,Number(t.olderThanDays??30))),r=new Date(Date.now()-e*86400000).toISOString(),d=gD[this.kind],E=this.kind==="artifacts"?this.organizationId:this.projectId;return this.control.database.query(d.select).all(E,r).map((c)=>({id:String(c.id),kind:this.kind,label:`${this.kind}:${String(c.id)}`,bytes:Number(c.bytes??0),metadata:{createdAt:String(c.created_at)}}))}async remove(t){if(this.control.database.run(gD[this.kind].remove,[t.id]).changes!==1)throw Error(`${t.label} changed or is no longer removable.`)}}var Pr=(t,e)=>{try{return JSON.parse(String(t))}catch{return e}},be=(t)=>t==null?void 0:String(t),XD=()=>({cpu:0,memoryBytes:0,diskBytes:0,gpu:0}),mn=(t={})=>({...XD(),...t});function $D(t){return{id:String(t.id),organizationId:String(t.organization_id),projectId:String(t.project_id),name:String(t.name),purpose:String(t.purpose),backend:String(t.backend),region:be(t.region),architecture:be(t.architecture),labels:Pr(t.labels,{}),requiredServerLabels:Pr(t.required_server_labels,{}),toleratedTaints:Pr(t.tolerated_taints,[]),capacity:mn(Pr(t.capacity,{})),reserved:Pr(t.reserved,{}),maxWorkloads:Number(t.max_workloads),costWeight:Number(t.cost_weight),spreadKey:be(t.spread_key),concurrency:Number(t.concurrency),ephemeralWorkspaces:Number(t.ephemeral_workspaces)===1,allowProductionSecrets:Number(t.allow_production_secrets)===1,status:String(t.status),version:Number(t.version),createdAt:String(t.created_at),updatedAt:String(t.updated_at)}}function yD(t){return{id:String(t.id),projectId:String(t.project_id),environmentId:be(t.environment_id),resourceId:String(t.resource_id),releaseId:be(t.release_id),poolId:String(t.pool_id),serverId:be(t.server_id),purpose:String(t.purpose),requirements:Pr(t.requirements,{}),decision:Pr(t.decision,{}),stateful:Number(t.stateful)===1,autoReschedule:Number(t.auto_reschedule)===1,status:String(t.status),version:Number(t.version),createdAt:String(t.created_at),updatedAt:String(t.updated_at)}}function TP(t){return{id:String(t.id),projectId:String(t.project_id),resourceId:be(t.resource_id),poolId:String(t.pool_id),placementId:be(t.placement_id),operationId:be(t.operation_id),sourceSha:String(t.source_sha),buildSpec:Pr(t.build_spec,{}),credentialPolicy:Pr(t.credential_policy,{productionSecrets:!1,shortLivedTokenExpiresAt:""}),workspace:be(t.workspace),cacheKey:be(t.cache_key),artifactUri:be(t.artifact_uri),artifactDigest:be(t.artifact_digest),status:String(t.status),cleanupAt:be(t.cleanup_at),createdAt:String(t.created_at),updatedAt:String(t.updated_at)}}class XA{control;now;id;constructor(t,e=()=>new Date,r=()=>crypto.randomUUID()){this.control=t;this.now=e;this.id=r}createPool(t){let e=this.id(),r=this.now().toISOString();return this.control.database.run("INSERT INTO capacity_pools (id,organization_id,project_id,name,purpose,backend,region,architecture,labels,required_server_labels,tolerated_taints,capacity,reserved,max_workloads,cost_weight,spread_key,concurrency,ephemeral_workspaces,allow_production_secrets,status,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",[e,t.organizationId,t.projectId,t.name,t.purpose,t.backend,t.region??null,t.architecture??null,JSON.stringify(t.labels),JSON.stringify(t.requiredServerLabels),JSON.stringify(t.toleratedTaints),JSON.stringify(mn(t.capacity)),"{}",t.maxWorkloads,t.costWeight,t.spreadKey??null,t.concurrency,t.ephemeralWorkspaces?1:0,t.allowProductionSecrets?1:0,t.status,r,r]),this.getPool(e)}getPool(t){let e=this.control.database.query("SELECT * FROM capacity_pools WHERE id=?").get(t);return e?$D(e):void 0}listPools(t){return this.control.database.query("SELECT * FROM capacity_pools WHERE project_id=? ORDER BY name").all(t).map($D)}updatePool(t,e){let r=this.getPool(t);if(!r)throw Error("Capacity pool was not found.");let d={...r,...e},E=this.now().toISOString();return this.control.database.run("UPDATE capacity_pools SET status=?,reserved=?,capacity=?,concurrency=?,version=version+1,updated_at=? WHERE id=?",[d.status,JSON.stringify(d.reserved),JSON.stringify(d.capacity),d.concurrency,E,t]),this.getPool(t)}addMember(t,e,r={}){let d=this.now().toISOString();this.control.database.run("INSERT INTO capacity_pool_members (pool_id,server_id,capacity_override,status,created_at,updated_at) VALUES (?,?,?,'active',?,?) ON CONFLICT(pool_id,server_id) DO UPDATE SET capacity_override=excluded.capacity_override,status='active',updated_at=excluded.updated_at",[t,e,JSON.stringify(r),d,d])}members(t){return this.control.database.query("SELECT * FROM capacity_pool_members WHERE pool_id=? ORDER BY server_id").all(t).map((e)=>({serverId:String(e.server_id),status:String(e.status),capacityOverride:Pr(e.capacity_override,{})}))}memberStatus(t,e,r){this.control.database.run("UPDATE capacity_pool_members SET status=?,updated_at=? WHERE pool_id=? AND server_id=?",[r,this.now().toISOString(),t,e])}listPlacements(t,e){let r=this.control.database.query("SELECT * FROM workload_placements WHERE project_id=? ORDER BY created_at,id").all(t).map(yD);return e?.length?r.filter((d)=>e.includes(d.status)):r}getPlacement(t){let e=this.control.database.query("SELECT * FROM workload_placements WHERE id=?").get(t);return e?yD(e):void 0}activeUsage(t,e){let r=this.control.database.query("SELECT l.resources,l.server_id FROM capacity_leases l WHERE l.pool_id=? AND l.state='active' AND l.expires_at>?").all(t,this.now().toISOString()),d=e?r.filter((E)=>String(E.server_id)===e):r;return{resources:d.reduce((E,n)=>{let c=mn(Pr(n.resources,{}));for(let _ of Object.keys(E))E[_]+=c[_];return E},XD()),count:d.length}}expireLeases(){return this.control.database.run("UPDATE capacity_leases SET state='expired',updated_at=? WHERE state='active' AND expires_at<=?",[this.now().toISOString(),this.now().toISOString()]).changes}reserve(t){return this.control.transaction(()=>{this.expireLeases();let e=this.id(),r=this.id(),d=this.now().toISOString(),E=new Date(this.now().getTime()+(t.requirements.leaseSeconds??300)*1000).toISOString();return this.control.database.run("INSERT INTO workload_placements (id,project_id,environment_id,resource_id,release_id,pool_id,server_id,purpose,requirements,decision,stateful,auto_reschedule,status,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,'reserved',?,?)",[e,t.projectId,t.environmentId??null,t.resourceId,t.releaseId??null,t.decision.poolId,t.decision.serverId??null,t.requirements.purpose,JSON.stringify(t.requirements),JSON.stringify(t.decision),t.requirements.stateful?1:0,t.requirements.autoReschedule&&!t.requirements.stateful?1:0,d,d]),this.control.database.run("INSERT INTO capacity_leases (id,placement_id,pool_id,server_id,resources,state,expires_at,created_at,updated_at) VALUES (?,?,?,?,?,'active',?,?,?)",[r,e,t.decision.poolId,t.decision.serverId??null,JSON.stringify(mn(t.requirements.resources)),E,d,d]),this.getPlacement(e)})}transitionPlacement(t,e){if(!this.getPlacement(t))throw Error("Placement was not found.");let d=this.now().toISOString();if(this.control.database.run("UPDATE workload_placements SET status=?,version=version+1,updated_at=? WHERE id=?",[e,d,t]),["released","failed","blocked"].includes(e))this.control.database.run("UPDATE capacity_leases SET state='released',updated_at=? WHERE placement_id=? AND state='active'",[d,t]);return this.getPlacement(t)}createBuild(t){let e=this.id(),r=this.now().toISOString();return this.control.database.run("INSERT INTO remote_builds (id,project_id,resource_id,pool_id,placement_id,operation_id,source_sha,build_spec,credential_policy,status,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,'queued',?,?)",[e,t.projectId,t.resourceId??null,t.poolId,t.placementId??null,t.operationId??null,t.sourceSha,JSON.stringify(t.buildSpec),JSON.stringify({productionSecrets:!1,shortLivedTokenExpiresAt:t.tokenExpiresAt}),r,r]),this.getBuild(e)}getBuild(t){let e=this.control.database.query("SELECT * FROM remote_builds WHERE id=?").get(t);return e?TP(e):void 0}updateBuild(t,e){let r=this.getBuild(t);if(!r)throw Error("Remote build was not found.");let d={...r,...e},E=this.now().toISOString();return this.control.database.run("UPDATE remote_builds SET operation_id=?,workspace=?,cache_key=?,artifact_uri=?,artifact_digest=?,status=?,cleanup_at=?,updated_at=? WHERE id=?",[d.operationId??null,d.workspace??null,d.cacheKey??null,d.artifactUri??null,d.artifactDigest??null,d.status,d.cleanupAt??null,E,t]),this.getBuild(t)}}var oi=["cpu","memoryBytes","diskBytes","gpu"],aD=(t,e={})=>Object.entries(e).every(([r,d])=>t[r]===d),iP=(t,e,r)=>Object.fromEntries(oi.map((d)=>[d,Math.max(0,t[d]-e[d]-(r[d]??0))])),hP=(t,e)=>oi.every((r)=>t[r]>=(e[r]??0)),RP=(t,e)=>oi.reduce((r,d)=>r+(e[d]??0)/(t[d]||1),0);class aA{store;fleet;constructor(t,e){this.store=t;this.fleet=e}poolCandidates(t,e,r){let d=[];for(let E of this.store.listPools(t)){if(E.id===r)continue;let n=[];if(E.status!=="active")n.push(`pool is ${E.status}`);if(E.purpose!==e.purpose)n.push(`purpose is ${E.purpose}`);if(e.region&&E.region!==e.region)n.push(`region is ${E.region??"unset"}`);if(e.architecture&&E.architecture!==e.architecture)n.push(`architecture is ${E.architecture??"unset"}`);if(!aD(E.labels,e.labels))n.push("pool labels do not match");if(E.backend==="server"){let c=this.store.members(E.id);if(!c.length)d.push(this.decision(E,void 0,e,[...n,"pool has no servers"]));for(let _ of c){let T=this.fleet.get(_.serverId),i=[...n];if(!T)i.push("server is missing");else this.serverReasons(E,T,_.status,e,i);d.push(this.decision(E,T,e,i,_.capacityOverride))}}else d.push(this.decision(E,void 0,e,n))}return d.sort((E,n)=>Number(n.eligible)-Number(E.eligible)||E.score.cost-n.score.cost||E.score.spread-n.score.spread||E.score.fit-n.score.fit||E.poolName.localeCompare(n.poolName)||(E.serverId??"").localeCompare(n.serverId??""))}serverReasons(t,e,r,d,E){if(r!=="active")E.push(`member is ${r}`);if(e.status!=="ready")E.push(`server is ${e.status}`);if(!e.roles.includes(d.purpose==="build"?"build":d.purpose))E.push(`server lacks ${d.purpose} role`);if(!aD(e.labels,t.requiredServerLabels))E.push("server labels do not match pool selector");for(let n of e.taints)if(!t.toleratedTaints.includes(n))E.push(`taint ${n} is not tolerated`)}decision(t,e,r,d,E={}){let n=mn({...e?.capacity,...E}),c=e?Object.fromEntries(oi.map((i)=>[i,Math.min(t.capacity[i],n[i])])):t.capacity,_=this.store.activeUsage(t.id,e?.id),T=iP(c,_.resources,t.reserved);if(_.count>=t.maxWorkloads)d.push("workload limit reached");if(r.purpose==="build"&&_.count>=t.concurrency)d.push("build concurrency reached");if(!hP(T,r.resources))d.push("insufficient capacity");return{poolId:t.id,poolName:t.name,serverId:e?.id,eligible:d.length===0,reasons:d,available:T,score:{fit:RP(T,r.resources),spread:_.count,cost:t.costWeight}}}explain(t,e){return this.poolCandidates(t,e)}place(t){return this.store.control.transaction(()=>{let e=this.poolCandidates(t.projectId,t.requirements).find((r)=>r.eligible);if(!e)throw Error(`No eligible capacity: ${this.explain(t.projectId,t.requirements).flatMap((r)=>r.reasons).join("; ")}`);return this.store.reserve({...t,decision:e})})}activate(t){return this.store.transitionPlacement(t,"active")}release(t){return this.store.transitionPlacement(t,"released")}drainPool(t){let e=this.store.updatePool(t,{status:"draining"}),r=[],d=[];for(let E of this.store.listPlacements(e.projectId,["reserved","active"]).filter((n)=>n.poolId===t)){if(E.stateful){d.push(this.store.transitionPlacement(E.id,"blocked"));continue}this.store.transitionPlacement(E.id,"moving");let n=this.place({projectId:E.projectId,environmentId:E.environmentId,resourceId:E.resourceId,releaseId:E.releaseId,requirements:E.requirements});r.push(this.activate(n.id)),this.store.transitionPlacement(E.id,"released")}return{pool:e,moved:r,blocked:d}}drainServer(t,e){this.store.memberStatus(t,e,"draining");let r=this.store.getPool(t);if(!r)throw Error("Capacity pool was not found.");let d=[],E=[];for(let n of this.store.listPlacements(r.projectId,["reserved","active"]).filter((c)=>c.poolId===t&&c.serverId===e)){if(n.stateful){E.push(this.store.transitionPlacement(n.id,"blocked"));continue}this.store.transitionPlacement(n.id,"moving");let c=this.poolCandidates(n.projectId,n.requirements).find((T)=>T.eligible);if(!c){E.push(this.store.transitionPlacement(n.id,"blocked"));continue}let _=this.store.reserve({projectId:n.projectId,environmentId:n.environmentId,resourceId:n.resourceId,releaseId:n.releaseId,requirements:n.requirements,decision:c});d.push(this.activate(_.id)),this.store.transitionPlacement(n.id,"released")}return{moved:d,blocked:E}}reconcileFailure(t){let e=this.fleet.get(t);if(!e)throw Error("Server was not found.");let r=[],d=[];for(let E of this.store.listPlacements(e.projectId,["active"]).filter((n)=>n.serverId===t)){if(E.stateful||!E.autoReschedule){d.push(this.store.transitionPlacement(E.id,"blocked"));continue}this.store.transitionPlacement(E.id,"failed");let n=this.place({projectId:E.projectId,environmentId:E.environmentId,resourceId:E.resourceId,releaseId:E.releaseId,requirements:E.requirements});r.push(this.activate(n.id))}return{rescheduled:r,blocked:d}}}var Ld=(t,e)=>{try{return JSON.parse(String(t))}catch{return e}},Cr=(t)=>t==null?void 0:String(t),PD=(t)=>({id:String(t.id),organizationId:String(t.organization_id),projectId:String(t.project_id),environmentId:Cr(t.environment_id),name:String(t.name),hostname:String(t.hostname),homeRegion:String(t.home_region),regions:Ld(t.regions,[]),trafficPolicy:String(t.traffic_policy),dataPolicy:Ld(t.data_policy,{replicate:[],maxLagSeconds:60,retainOnDestroy:!0}),status:String(t.status),activeRegion:String(t.active_region),revision:Cr(t.revision),version:Number(t.version),createdAt:String(t.created_at),updatedAt:String(t.updated_at)}),PA=(t)=>({id:String(t.id),topologyId:String(t.topology_id),region:String(t.region),role:String(t.role),provider:String(t.provider),stackId:Cr(t.stack_id),stackRevision:Cr(t.stack_revision),status:String(t.status),health:Ld(t.health,{}),lastHealthyAt:Cr(t.last_healthy_at),version:Number(t.version),createdAt:String(t.created_at),updatedAt:String(t.updated_at)}),jA=(t)=>({id:String(t.id),topologyId:String(t.topology_id),kind:String(t.kind),sourceRegion:String(t.source_region),targetRegion:String(t.target_region),config:Ld(t.config,{}),status:String(t.status),checkpoint:Cr(t.checkpoint),lagSeconds:t.lag_seconds==null?void 0:Number(t.lag_seconds),lastVerifiedAt:Cr(t.last_verified_at),version:Number(t.version),createdAt:String(t.created_at),updatedAt:String(t.updated_at)}),zA=(t)=>({id:String(t.id),topologyId:String(t.topology_id),hostname:String(t.hostname),dnsProvider:String(t.dns_provider),cdnEnabled:Number(t.cdn_enabled)===1,wafEnabled:Number(t.waf_enabled)===1,weights:Ld(t.weights,{}),desiredWeights:Ld(t.desired_weights,{}),status:String(t.status),providerState:Ld(t.provider_state,{}),version:Number(t.version),createdAt:String(t.created_at),updatedAt:String(t.updated_at)}),jD=(t)=>({id:String(t.id),topologyId:String(t.topology_id),operationId:Cr(t.operation_id),kind:String(t.kind),requestedRegion:Cr(t.requested_region),revision:Cr(t.revision),plan:Ld(t.plan,[]),currentStep:Cr(t.current_step),completedSteps:Ld(t.completed_steps,[]),status:String(t.status),error:Cr(t.error),createdAt:String(t.created_at),updatedAt:String(t.updated_at)});class FA{control;now;id;constructor(t,e=()=>new Date,r=()=>crypto.randomUUID()){this.control=t;this.now=e;this.id=r}create(t){return this.control.transaction(()=>{if(t.regions.length<2||new Set(t.regions.map((n)=>n.region)).size!==t.regions.length||t.regions.filter((n)=>n.role==="primary").length!==1)throw Error("A topology requires unique regions and exactly one primary.");let e=t.regions.find((n)=>n.role==="primary"),r=this.id(),d=this.now().toISOString();this.control.database.run("INSERT INTO regional_topologies (id,organization_id,project_id,environment_id,name,hostname,home_region,regions,traffic_policy,data_policy,status,active_region,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,'draft',?,?,?)",[r,t.organizationId,t.projectId,t.environmentId??null,t.name,t.hostname,e.region,JSON.stringify(t.regions),t.trafficPolicy,JSON.stringify(t.dataPolicy),e.region,d,d]);for(let n of t.regions)this.control.database.run("INSERT INTO regional_targets (id,topology_id,region,role,provider,status,created_at,updated_at) VALUES (?,?,?,?,?,'pending',?,?)",[this.id(),r,n.region,n.role,n.provider,d,d]);for(let n of t.dataPolicy.replicate)for(let c of t.regions)for(let _ of t.regions.filter((T)=>T.region!==c.region))this.control.database.run("INSERT INTO regional_replication_channels (id,topology_id,kind,source_region,target_region,config,status,created_at,updated_at) VALUES (?,?,?,?,?,?,'pending',?,?)",[this.id(),r,n,c.region,_.region,"{}",d,d]);let E=Object.fromEntries(t.regions.map((n)=>[n.region,n.region===e.region?100:0]));return this.control.database.run("INSERT INTO regional_traffic_routes (id,topology_id,hostname,dns_provider,cdn_enabled,waf_enabled,weights,desired_weights,status,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?, 'pending',?,?)",[this.id(),r,t.hostname,t.dnsProvider??"route53",t.cdnEnabled?1:0,t.wafEnabled?1:0,JSON.stringify(E),JSON.stringify(E),d,d]),this.get(r)})}get(t){let e=this.control.database.query("SELECT * FROM regional_topologies WHERE id=?").get(t);return e?PD(e):void 0}list(t){return this.control.database.query("SELECT * FROM regional_topologies WHERE project_id=? ORDER BY name").all(t).map(PD)}targets(t){return this.control.database.query("SELECT * FROM regional_targets WHERE topology_id=? ORDER BY role,region").all(t).map(PA)}channels(t){return this.control.database.query("SELECT * FROM regional_replication_channels WHERE topology_id=? ORDER BY kind,target_region").all(t).map(jA)}route(t){let e=this.control.database.query("SELECT * FROM regional_traffic_routes WHERE topology_id=?").get(t);return e?zA(e):void 0}updateTopology(t,e){let r=this.get(t);if(!r)throw Error("Regional topology was not found.");let d={...r,...e},E=this.now().toISOString();return this.control.database.run("UPDATE regional_topologies SET status=?,active_region=?,revision=?,regions=?,version=version+1,updated_at=? WHERE id=?",[d.status,d.activeRegion,d.revision??null,JSON.stringify(d.regions),E,t]),this.get(t)}updateTarget(t,e){let r=this.control.database.query("SELECT * FROM regional_targets WHERE id=?").get(t);if(!r)throw Error("Regional target was not found.");let d=PA(r),E={...d,...e},n=this.now().toISOString();return this.control.database.run("UPDATE regional_targets SET role=?,stack_id=?,stack_revision=?,status=?,health=?,last_healthy_at=?,version=version+1,updated_at=? WHERE id=?",[E.role,E.stackId??null,E.stackRevision??null,E.status,JSON.stringify(E.health),E.lastHealthyAt??null,n,t]),PA(this.control.database.query("SELECT * FROM regional_targets WHERE id=?").get(t))}updateChannel(t,e){let r=this.control.database.query("SELECT * FROM regional_replication_channels WHERE id=?").get(t);if(!r)throw Error("Replication channel was not found.");let d=jA(r),E={...d,...e},n=this.now().toISOString();return this.control.database.run("UPDATE regional_replication_channels SET status=?,checkpoint=?,lag_seconds=?,last_verified_at=?,version=version+1,updated_at=? WHERE id=?",[E.status,E.checkpoint??null,E.lagSeconds??null,E.lastVerifiedAt??null,n,t]),jA(this.control.database.query("SELECT * FROM regional_replication_channels WHERE id=?").get(t))}updateRoute(t,e){let r=this.control.database.query("SELECT * FROM regional_traffic_routes WHERE id=?").get(t);if(!r)throw Error("Traffic route was not found.");let d=zA(r),E={...d,...e},n=this.now().toISOString();return this.control.database.run("UPDATE regional_traffic_routes SET weights=?,desired_weights=?,status=?,provider_state=?,version=version+1,updated_at=? WHERE id=?",[JSON.stringify(E.weights),JSON.stringify(E.desiredWeights),E.status,JSON.stringify(E.providerState),n,t]),zA(this.control.database.query("SELECT * FROM regional_traffic_routes WHERE id=?").get(t))}createExecution(t){let e=this.id(),r=this.now().toISOString();return this.control.database.run("INSERT INTO regional_executions (id,topology_id,operation_id,kind,requested_region,revision,plan,status,created_at,updated_at) VALUES (?,?,?,?,?,?,?,'queued',?,?)",[e,t.topologyId,t.operationId??null,t.kind,t.requestedRegion??null,t.revision??null,JSON.stringify(t.plan),r,r]),this.execution(e)}execution(t){let e=this.control.database.query("SELECT * FROM regional_executions WHERE id=?").get(t);return e?jD(e):void 0}executions(t){return this.control.database.query("SELECT * FROM regional_executions WHERE topology_id=? ORDER BY created_at DESC").all(t).map(jD)}updateExecution(t,e){let r=this.execution(t);if(!r)throw Error("Regional execution was not found.");let d={...r,...e},E=this.now().toISOString();return this.control.database.run("UPDATE regional_executions SET operation_id=?,current_step=?,completed_steps=?,status=?,error=?,updated_at=? WHERE id=?",[d.operationId??null,d.currentStep??null,JSON.stringify(d.completedSteps),d.status,d.error??null,E,t]),this.execution(t)}}class BA{store;queue;constructor(t,e){this.store=t;this.queue=e??new gt(t.control)}create(t){return this.store.create(t)}plan(t,e,r){if(!this.store.get(t))throw Error("Regional topology was not found.");let E=this.store.targets(t),n=this.store.channels(t);if(e==="rollout")return[...E.filter((c)=>c.role==="secondary").map((c)=>`apply:${c.region}`),...E.filter((c)=>c.role==="primary").map((c)=>`apply:${c.region}`),...n.map((c)=>`replicate:${c.kind}:${c.targetRegion}`),"traffic:activate"];if(e==="failover"||e==="failback")return[`health:${r}`,`replication:${r}`,`traffic:${r}`,`roles:${r}`];if(e==="destroy")return["traffic:drain",...E.filter((c)=>c.role==="secondary").map((c)=>`delete:${c.region}`),...E.filter((c)=>c.role==="primary").map((c)=>`delete:${c.region}`),"complete"];return["observe","repair"]}enqueue(t){let e=this.store.get(t.topologyId);if(!e)throw Error("Regional topology was not found.");if(["failover","failback"].includes(t.kind)&&(!t.targetRegion||!e.regions.some((n)=>n.region===t.targetRegion)))throw Error("A topology target region is required.");if(t.kind==="failover"&&t.targetRegion===e.activeRegion)throw Error("Target region is already active.");if((t.kind==="destroy"||t.deleteData)&&t.confirmation!==e.name)throw Error("Exact topology name confirmation is required.");if(t.deleteData&&e.dataPolicy.retainOnDestroy)throw Error("Topology policy requires regional data retention.");if(t.kind==="rollout"&&!/^[A-Za-z0-9._:@/-]{7,200}$/.test(t.revision??""))throw Error("An immutable revision is required.");let r=this.plan(e.id,t.kind,t.targetRegion),d=this.store.createExecution({topologyId:e.id,kind:t.kind,requestedRegion:t.targetRegion,revision:t.revision,plan:r}),E=this.queue.enqueue({projectId:e.projectId,environmentId:e.environmentId,kind:`region.${t.kind}`,input:{executionId:d.id,manifest:t.manifest??{},deleteData:t.deleteData===!0},lockKey:`regional-topology:${e.id}`,providerKey:"multi-region",timeoutSeconds:7200,cancellationMode:"provider_non_cancellable",resumePolicy:"requeue",maxAttempts:3}).operation;return this.store.updateExecution(d.id,{operationId:E.id}),{execution:this.store.execution(d.id),operation:E}}}var SP=(t)=>t&&typeof t==="object"&&!Array.isArray(t)?t:{};function zD(t,e){let r=(i)=>{let h=e.find((R)=>R.provider===i.provider);if(!h)throw Error(`No ${i.provider} regional driver is configured.`);return h},d=(i,h,R)=>{i.throwIfCancellationRequested(),i.checkpoint(R,R),t.updateExecution(h.id,{status:"running",currentStep:R,completedSteps:[...t.execution(h.id).completedSteps,R]})},E=async(i,h)=>{let R=t.route(i.id);if(!R)throw Error("Regional traffic route was not found.");let N=t.targets(i.id).find((u)=>u.region===i.activeRegion)??t.targets(i.id)[0];if(!N)throw Error("Regional traffic target was not found.");t.updateRoute(R.id,{status:"applying",desiredWeights:h});let A=await r(N).applyTraffic({route:t.route(i.id),topology:i,weights:h});t.updateRoute(R.id,{status:Object.values(h).every((u)=>u===0)?"drained":"in_sync",weights:h,providerState:A.providerState})},n=async(i,h,R,N)=>{t.updateTopology(R.id,{status:"provisioning"});let A=h.revision,u=N.manifest??{},f=t.targets(R.id).sort((I,a)=>Number(I.role==="primary")-Number(a.role==="primary"));for(let I of f){d(i,h,`apply:${I.region}`),t.updateTarget(I.id,{status:"provisioning"});let a=await r(I).applyStack({target:I,revision:A,manifest:u,signal:i.signal}),P=await r(I).health({target:t.updateTarget(I.id,{stackId:a.stackId,stackRevision:A})});if(!P.healthy)throw Error(`Regional health gate failed in ${I.region}.`);t.updateTarget(I.id,{status:"ready",health:P.evidence,lastHealthyAt:new Date().toISOString()})}for(let I of t.channels(R.id)){d(i,h,`replicate:${I.kind}:${I.targetRegion}`),t.updateChannel(I.id,{status:"configuring"});let a=f.find((H)=>H.region===I.sourceRegion),P=await r(a).configureReplication({channel:I,topology:R}),j=await r(a).verifyReplication({channel:t.updateChannel(I.id,{checkpoint:P.checkpoint,lagSeconds:P.lagSeconds}),topology:R});if(!j.healthy||j.lagSeconds>R.dataPolicy.maxLagSeconds)throw Error(`${I.kind} replication to ${I.targetRegion} exceeds the RPO.`);t.updateChannel(I.id,{status:"in_sync",checkpoint:j.checkpoint,lagSeconds:j.lagSeconds,lastVerifiedAt:new Date().toISOString()})}d(i,h,"traffic:activate");let w=Object.fromEntries(R.regions.map((I)=>[I.region,I.region===R.activeRegion?100:0]));return await E(R,w),t.updateTopology(R.id,{status:"ready",revision:A}),{revision:A,activeRegion:R.activeRegion}},c=async(i,h,R)=>{let N=h.requestedRegion,A=t.targets(R.id).find((w)=>w.region===N);if(!A)throw Error("Requested regional target was not found.");t.updateTopology(R.id,{status:h.kind==="failover"?"failing_over":"failing_back"}),d(i,h,`health:${N}`);let u=await r(A).health({target:A});if(!u.healthy)throw Error(`Target region ${N} is unhealthy.`);t.updateTarget(A.id,{status:"ready",health:u.evidence,lastHealthyAt:new Date().toISOString()}),d(i,h,`replication:${N}`);for(let w of t.channels(R.id).filter((I)=>I.targetRegion===N)){let I=await r(A).verifyReplication({channel:w,topology:R});if(!I.healthy||I.lagSeconds>R.dataPolicy.maxLagSeconds)throw Error(`${w.kind} replication is outside the failover RPO.`);t.updateChannel(w.id,{status:"in_sync",checkpoint:I.checkpoint,lagSeconds:I.lagSeconds,lastVerifiedAt:new Date().toISOString()})}d(i,h,`traffic:${N}`),await E(R,Object.fromEntries(R.regions.map((w)=>[w.region,w.region===N?100:0]))),d(i,h,`roles:${N}`);let f=R.regions.map((w)=>({...w,role:w.region===N?"primary":"secondary"}));for(let w of t.targets(R.id))t.updateTarget(w.id,{role:w.region===N?"primary":"secondary"});return t.updateTopology(R.id,{status:h.kind==="failover"?"failed_over":"ready",activeRegion:N,regions:f}),{activeRegion:N}},_=async(i,h,R,N)=>{t.updateTopology(R.id,{status:"destroying"}),d(i,h,"traffic:drain"),await E(R,Object.fromEntries(R.regions.map((u)=>[u.region,0])));let A=N.deleteData!==!0;for(let u of t.targets(R.id).sort((f,w)=>Number(f.role==="primary")-Number(w.role==="primary")))d(i,h,`delete:${u.region}`),t.updateTarget(u.id,{status:"deleting"}),await r(u).deleteStack({target:u,retainData:A,signal:i.signal}),t.updateTarget(u.id,{status:"deleted"});return d(i,h,"complete"),t.updateTopology(R.id,{status:"destroyed"}),{destroyed:!0,dataRetained:A}},T=async(i)=>{let h=SP(i.operation.input),R=t.execution(String(h.executionId??""));if(!R)throw Error("Regional execution was not found.");let N=t.get(R.topologyId);if(!N)throw Error("Regional topology was not found.");try{let A;if(R.kind==="rollout")A=await n(i,R,N,h);else if(R.kind==="failover"||R.kind==="failback")A=await c(i,R,N);else if(R.kind==="destroy")A=await _(i,R,N,h);else throw Error("Regional reconciliation is not configured.");return t.updateExecution(R.id,{status:"succeeded",currentStep:void 0}),{executionId:R.id,...A}}catch(A){if(t.updateExecution(R.id,{status:i.cancellationRequested()?"cancelled":"failed",error:A instanceof Error?A.message:String(A)}),t.get(N.id)?.status!=="destroyed")t.updateTopology(N.id,{status:"failed"});throw A}};return{"region.rollout":T,"region.failover":T,"region.failback":T,"region.destroy":T,"region.reconcile":T}}class JA{provider;reason;constructor(t,e="Configure a regional provider transport before executing this operation."){this.provider=t;this.reason=e}fail(){throw Error(this.reason)}async applyStack(){return this.fail()}async deleteStack(){this.fail()}async health(){return this.fail()}async configureReplication(){return this.fail()}async verifyReplication(){return this.fail()}async applyTraffic(){return this.fail()}}function xr(t,e,r){return[t,e,r].map((d)=>encodeURIComponent(d)).join(":")}function NP(t){return Object.fromEntries(["start","stop","restart","redeploy","scale","logs","exec","inspect","files"].map((e)=>[e,{supported:!1,reason:t}]))}function QE(t,e,r=["exec","files"]){let d=NP(e);for(let E of t)d[E]={supported:!0,requiresConfirmation:!["logs","inspect"].includes(E),requiresRecentAuth:r.includes(E)};return d}var AP=/(?:secret|password|passwd|token|api[_-]?key|private[_-]?key|credential|authorization|cookie)/i;function Od(t){let e=String(t??"").trim().toLowerCase();if(["active","running","ready","healthy","available","steady","active:running"].includes(e))return"running";if(["activating","pending","provisioning","starting","created","initializing"].includes(e))return"starting";if(["deactivating","stopping","draining","terminating"].includes(e))return"stopping";if(["inactive","stopped","complete","completed","exited","disabled"].includes(e))return"stopped";if(["degraded","unhealthy","warning"].includes(e))return"degraded";if(["failed","dead","error","crashed","oomkilled"].includes(e))return"failed";return"unknown"}function ud(t){if(Array.isArray(t))return t.map((r)=>ud(r));if(!t||typeof t!=="object")return t;let e={};for(let[r,d]of Object.entries(t))e[r]=AP.test(r)?"[REDACTED]":ud(d);return e}function YE(t,e=new Date){if(!t)return;let r=new Date(t).getTime();return Number.isFinite(r)?Math.max(0,Math.floor((e.getTime()-r)/1000)):void 0}function FD(t){let e=Number(t);return Number.isFinite(e)&&e>=0?e:void 0}function LP(t){let e=String(t?.message??t);if(/(?:unauthorized|accessdenied|forbidden|credentials)/i.test(e))return"unauthorized";if(/(?:timeout|unreachable|econnrefused|enotfound|network)/i.test(e))return"unreachable";return"error"}async function BD(t,e={},r={}){let d=e.now??new Date,E=Math.max(100,r.timeoutMs??1e4),n=Math.max(1,r.staleAfterSeconds??60),c=await Promise.all(t.map(async(T)=>{try{let i=await Promise.race([T.discover({...e,now:d}),new Promise((h,R)=>setTimeout(()=>R(Error(`Runtime source ${T.id} timed out after ${E}ms`)),E))]);return{workloads:i,source:{id:T.id,provider:T.provider,status:"fresh",discoveredAt:d.toISOString(),staleAfterSeconds:n,itemCount:i.length}}}catch(i){return{workloads:[],source:{id:T.id,provider:T.provider,status:LP(i),discoveredAt:d.toISOString(),staleAfterSeconds:n,itemCount:0,message:String(i?.message??i).slice(0,500)}}}})),_=c.map((T)=>T.source);return{generatedAt:d.toISOString(),workloads:c.flatMap((T)=>T.workloads).sort((T,i)=>T.name.localeCompare(i.name)||T.id.localeCompare(i.id)),sources:_,degraded:_.some((T)=>T.status!=="fresh")}}await Ht();Lt();tr();Lt();class qr{client;region;constructor(t="us-east-1",e){this.region=t,this.client=new dt(void 0,{profile:e})}async createStack(t){let e={Action:"CreateStack",StackName:t.stackName,Version:"2010-05-15"};if(t.templateBody)e.TemplateBody=t.templateBody;else if(t.templateUrl)e.TemplateURL=t.templateUrl;else throw Error("Either templateBody or templateUrl must be provided");if(t.parameters)t.parameters.forEach((d,E)=>{e[`Parameters.member.${E+1}.ParameterKey`]=d.ParameterKey,e[`Parameters.member.${E+1}.ParameterValue`]=d.ParameterValue});if(t.capabilities)t.capabilities.forEach((d,E)=>{e[`Capabilities.member.${E+1}`]=d});if(t.roleArn)e.RoleARN=t.roleArn;if(t.tags)t.tags.forEach((d,E)=>{e[`Tags.member.${E+1}.Key`]=d.Key,e[`Tags.member.${E+1}.Value`]=d.Value});if(t.timeoutInMinutes)e.TimeoutInMinutes=t.timeoutInMinutes;if(t.onFailure)e.OnFailure=t.onFailure;let r=await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(e).toString()});return{StackId:r.StackId||r.CreateStackResult?.StackId}}async updateStack(t){let e={Action:"UpdateStack",StackName:t.stackName,Version:"2010-05-15"};if(t.templateBody)e.TemplateBody=t.templateBody;else if(t.templateUrl)e.TemplateURL=t.templateUrl;if(t.parameters)t.parameters.forEach((d,E)=>{if(e[`Parameters.member.${E+1}.ParameterKey`]=d.ParameterKey,d.UsePreviousValue)e[`Parameters.member.${E+1}.UsePreviousValue`]="true";else e[`Parameters.member.${E+1}.ParameterValue`]=d.ParameterValue});if(t.capabilities)t.capabilities.forEach((d,E)=>{e[`Capabilities.member.${E+1}`]=d});if(t.roleArn)e.RoleARN=t.roleArn;if(t.tags)t.tags.forEach((d,E)=>{e[`Tags.member.${E+1}.Key`]=d.Key,e[`Tags.member.${E+1}.Value`]=d.Value});let r=await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(e).toString()});return{StackId:r.StackId||r.UpdateStackResult?.StackId}}async deleteStack(t,e,r){let d={Action:"DeleteStack",StackName:t,Version:"2010-05-15"};if(e)d.RoleARN=e;if(r&&r.length>0)r.forEach((E,n)=>{d[`RetainResources.member.${n+1}`]=E});await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(d).toString()})}async describeStacks(t={}){let e={Action:"DescribeStacks",Version:"2010-05-15"};if(t.stackName)e.StackName=t.stackName;let r=await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(e).toString()});return{Stacks:this.parseStacksResponse(r)}}async describeStackEvents(t){let e={Action:"DescribeStackEvents",StackName:t,Version:"2010-05-15"},r=await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(e).toString()});return{StackEvents:this.parseStackEvents(r)}}async listStackResources(t){let e={Action:"ListStackResources",StackName:t,Version:"2010-05-15"},d=(await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(e).toString()}))?.ListStackResourcesResult?.StackResourceSummaries?.member,E=[];if(d)E=Array.isArray(d)?d:[d];return{StackResourceSummaries:E}}async waitForStack(t,e){let r={"stack-create-complete":["CREATE_COMPLETE"],"stack-update-complete":["UPDATE_COMPLETE"],"stack-delete-complete":["DELETE_COMPLETE"]},d=["CREATE_FAILED","ROLLBACK_FAILED","ROLLBACK_COMPLETE","UPDATE_ROLLBACK_FAILED","UPDATE_ROLLBACK_COMPLETE"],E=r[e],n=360,c=0;while(c<360)try{let _=await this.describeStacks({stackName:t});if(_.Stacks.length===0){if(e==="stack-delete-complete")return;if(c%10===0)console.log(`[waitForStack] Attempt ${c}: Stack not visible yet`);await new Promise((i)=>setTimeout(i,2000)),c++;continue}let T=_.Stacks[0];if(c%10===0)console.log(`[waitForStack] Attempt ${c}: Status = ${T.StackStatus}${T.StackStatusReason?` (${T.StackStatusReason})`:""}`);if(E.includes(T.StackStatus))return;if((e==="stack-create-complete"||e==="stack-update-complete")&&(T.StackStatus==="DELETE_IN_PROGRESS"||T.StackStatus==="DELETE_COMPLETE")){console.log("[waitForStack] Stack is being deleted (creation/update failed)");let i="";try{let R=await this.describeStackEvents(t);console.log("[waitForStack] Stack events (most recent first):");for(let N of R.StackEvents.slice(0,15))if(N.ResourceStatus.includes("FAILED")||N.ResourceStatusReason){if(console.log(` ${N.LogicalResourceId}: ${N.ResourceStatus} - ${N.ResourceStatusReason||"No reason provided"}`),N.ResourceStatus.includes("FAILED")&&N.ResourceStatusReason&&!i)i=N.ResourceStatusReason}}catch{}let h=i||T.StackStatusReason||"Check CloudFormation console for details.";throw Error(`Stack creation/update failed - stack is being deleted. Reason: ${h}`)}if(T.StackStatus==="DELETE_FAILED"&&e==="stack-delete-complete"){let i=Error("Stack deletion failed - may have resources that need to be retained");throw i.code="DELETE_FAILED",i.stackStatus=T.StackStatus,i.statusReason=T.StackStatusReason,i}if(d.includes(T.StackStatus))throw Error(`Stack reached failure status: ${T.StackStatus}`);await new Promise((i)=>setTimeout(i,5000)),c++}catch(_){if(e==="stack-delete-complete"&&_.message?.includes("does not exist"))return;if(e==="stack-create-complete"&&_.message?.includes("does not exist")){if(c%10===0)console.log(`[waitForStack] Attempt ${c}: Stack does not exist (error), retrying...`);await new Promise((T)=>setTimeout(T,2000)),c++;continue}throw console.log(`[waitForStack] Unexpected error: ${_.message}`),_}throw console.log(`[waitForStack] Timeout after ${c} attempts`),Error(`Timeout waiting for stack to reach ${e}`)}async validateTemplate(t){let e={Action:"ValidateTemplate",TemplateBody:t,Version:"2010-05-15"};return await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(e).toString()})}async listStacks(t){let e={Action:"ListStacks",Version:"2010-05-15"};if(t)t.forEach((_,T)=>{e[`StackStatusFilter.member.${T+1}`]=_});let r=await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(e).toString()}),d=r.ListStacksResponse||r,E=d.ListStacksResult||d,n=E.StackSummaries?.member||E.StackSummaries||[];return{StackSummaries:(Array.isArray(n)?n:n?[n]:[]).map((_)=>({StackId:_.StackId||"",StackName:_.StackName||"",TemplateDescription:_.TemplateDescription,CreationTime:_.CreationTime||"",LastUpdatedTime:_.LastUpdatedTime,DeletionTime:_.DeletionTime,StackStatus:_.StackStatus||""}))}}async createChangeSet(t){let e={Action:"CreateChangeSet",StackName:t.stackName,ChangeSetName:t.changeSetName,Version:"2010-05-15"};if(t.templateBody)e.TemplateBody=t.templateBody;else if(t.templateUrl)e.TemplateURL=t.templateUrl;if(t.parameters)t.parameters.forEach((d,E)=>{e[`Parameters.member.${E+1}.ParameterKey`]=d.ParameterKey,e[`Parameters.member.${E+1}.ParameterValue`]=d.ParameterValue});if(t.capabilities)t.capabilities.forEach((d,E)=>{e[`Capabilities.member.${E+1}`]=d});if(t.changeSetType)e.ChangeSetType=t.changeSetType;let r=await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(e).toString()});return{Id:r.Id,StackId:r.StackId}}async describeChangeSet(t,e){let r={Action:"DescribeChangeSet",StackName:t,ChangeSetName:e,Version:"2010-05-15"};return await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(r).toString()})}async executeChangeSet(t,e){let r={Action:"ExecuteChangeSet",StackName:t,ChangeSetName:e,Version:"2010-05-15"};await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(r).toString()})}async deleteChangeSet(t,e){let r={Action:"DeleteChangeSet",StackName:t,ChangeSetName:e,Version:"2010-05-15"};await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(r).toString()})}async getStackOutputs(t){let e=await this.describeStacks({stackName:t});if(!e.Stacks||e.Stacks.length===0)throw Error(`Stack ${t} not found`);let r=e.Stacks[0],d={};if(r.Outputs)for(let E of r.Outputs)d[E.OutputKey]=E.OutputValue;return d}async getTemplate(t){let e={Action:"GetTemplate",StackName:t,Version:"2010-05-15"},r=await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(e).toString()});return{TemplateBody:r?.GetTemplateResult?.TemplateBody||r?.TemplateBody||""}}parseStacksResponse(t){let e=[],r=t?.DescribeStacksResult?.Stacks?.member||t?.Stacks?.member||t?.Stacks||t;if(r&&!Array.isArray(r))r=[r];if(Array.isArray(r)){for(let d of r)if(d.StackId||d.StackName){let E;if(d.Outputs?.member)E=(Array.isArray(d.Outputs.member)?d.Outputs.member:[d.Outputs.member]).map((c)=>({OutputKey:c.OutputKey,OutputValue:c.OutputValue,Description:c.Description,ExportName:c.ExportName}));e.push({StackId:d.StackId,StackName:d.StackName,StackStatus:d.StackStatus,CreationTime:d.CreationTime,LastUpdatedTime:d.LastUpdatedTime,StackStatusReason:d.StackStatusReason,Outputs:E})}}else if(t.StackId)e.push({StackId:t.StackId,StackName:t.StackName,StackStatus:t.StackStatus,CreationTime:t.CreationTime,LastUpdatedTime:t.LastUpdatedTime});return e}parseStackEvents(t){let e=[],r=t?.DescribeStackEventsResult?.StackEvents?.member||t?.StackEvents?.member||t?.StackEvents||[];if(r&&!Array.isArray(r))r=[r];for(let d of r)if(d.LogicalResourceId)e.push({Timestamp:d.Timestamp,ResourceType:d.ResourceType,LogicalResourceId:d.LogicalResourceId,ResourceStatus:d.ResourceStatus,ResourceStatusReason:d.ResourceStatusReason});return e}async waitForStackWithProgress(t,e,r){let d={"stack-create-complete":["CREATE_COMPLETE"],"stack-update-complete":["UPDATE_COMPLETE"],"stack-delete-complete":["DELETE_COMPLETE"]},E=["CREATE_FAILED","ROLLBACK_FAILED","ROLLBACK_COMPLETE","UPDATE_ROLLBACK_FAILED","UPDATE_ROLLBACK_COMPLETE"],n=d[e],c=360,_=0,T=new Set;while(_<360)try{if(r)try{let N=[...(await this.describeStackEvents(t)).StackEvents||[]].reverse();for(let A of N){let u=`${A.LogicalResourceId}-${A.ResourceStatus}-${A.Timestamp}`;if(!T.has(u))T.add(u),r({resourceId:A.LogicalResourceId,resourceType:A.ResourceType,status:A.ResourceStatus,reason:A.ResourceStatusReason,timestamp:A.Timestamp})}}catch{}let i=await this.describeStacks({stackName:t});if(i.Stacks.length===0){if(e==="stack-delete-complete")return;await new Promise((R)=>setTimeout(R,2000)),_++;continue}let h=i.Stacks[0];if(n.includes(h.StackStatus))return;if(h.StackStatus==="DELETE_FAILED"&&e==="stack-delete-complete"){let R=Error("Stack deletion failed - may have resources that need to be retained");throw R.code="DELETE_FAILED",R.stackStatus=h.StackStatus,R.statusReason=h.StackStatusReason,R}if(E.includes(h.StackStatus))throw Error(`Stack reached failure status: ${h.StackStatus}`);await new Promise((R)=>setTimeout(R,3000)),_++}catch(i){if(e==="stack-delete-complete"&&i.message?.includes("does not exist"))return;if(e==="stack-create-complete"&&i.message?.includes("does not exist")){await new Promise((h)=>setTimeout(h,2000)),_++;continue}throw i}throw Error(`Timeout waiting for stack to reach ${e}`)}async waitForStackComplete(t,e=120,r=5000){let d=["CREATE_COMPLETE","UPDATE_COMPLETE","DELETE_COMPLETE"],E=["CREATE_FAILED","UPDATE_FAILED","DELETE_FAILED","ROLLBACK_COMPLETE","ROLLBACK_FAILED","UPDATE_ROLLBACK_COMPLETE","UPDATE_ROLLBACK_FAILED"];for(let n=0;n<e;n++)try{let c=await this.describeStacks({stackName:t});if(c.Stacks.length===0)return{success:!0,status:"DELETE_COMPLETE"};let _=c.Stacks[0],T=_.StackStatus;if(d.includes(T))return{success:!0,status:T};if(E.includes(T))return{success:!1,status:T,reason:_.StackStatusReason};await new Promise((i)=>setTimeout(i,r))}catch(c){if(c.message?.includes("does not exist"))return{success:!0,status:"DELETE_COMPLETE"};throw c}return{success:!1,status:"TIMEOUT",reason:"Timeout waiting for stack operation"}}}Lt();import{createHash as uP}from"node:crypto";import{existsSync as OP,mkdirSync as CP,readdirSync as PG,readFileSync as lP,rmSync as jG,writeFileSync as IP}from"node:fs";import{homedir as DP}from"node:os";import{join as I_}from"node:path";var JD=1,HD=3600000,fP=24*HD,UP=HD,wP=30*fP;function gP(){let t=process.env.XDG_CACHE_HOME;return I_(t&&t.trim()?t:I_(DP(),".cache"),"ts-cloud","cost-explorer")}function WD(t){return I_(gP(),t??"__default__")}function vD(t){let e={s:t.start,e:t.end,g:t.granularity,m:[...t.metrics].sort(),gb:[...t.groupBy].map((r)=>`${r.Type}:${r.Key}`).sort(),f:t.filter??null};return uP("sha256").update(JSON.stringify(e)).digest("hex").slice(0,24)}function $P(t,e){let r=Date.parse(`${e}T00:00:00Z`);if(Number.isNaN(r))return!1;let d=new Date,E=Date.UTC(d.getUTCFullYear(),d.getUTCMonth(),1);return r<=E}function yP(t){return $P(t.start,t.end)?wP:UP}function QD(t,e){let r=I_(WD(t),`${vD(e)}.json`);if(!OP(r))return null;let d;try{d=JSON.parse(lP(r,"utf-8"))}catch{return null}if(d.schema!==JD)return null;let E=Date.now()-d.savedAt;if(E<0||E>yP(e))return null;return{response:d.response,ageSeconds:Math.floor(E/1000)}}function YD(t,e,r){let d=WD(t);CP(d,{recursive:!0});let E={schema:JD,savedAt:Date.now(),key:e,response:r};IP(I_(d,`${vD(e)}.json`),JSON.stringify(E))}class HA{client;profile;useCache;lastCacheAgeSeconds=null;constructor(t,e){this.profile=t,this.useCache=e?.useCache??!0,this.client=new dt(an(t))}async getCostByService(t){return(await this.getCostByDimension({...t,dimension:"SERVICE"})).map((r)=>({service:r.key,amount:r.amount,unit:r.unit}))}async getCostByDimension(t){let{start:e,end:r,dimension:d,granularity:E="MONTHLY",filter:n}=t,c=["UnblendedCost"],_=[{Type:"DIMENSION",Key:d}],T={start:e,end:r,granularity:E,metrics:c,groupBy:_,filter:n};if(this.useCache){let N=QD(this.profile,T);if(N)return this.lastCacheAgeSeconds=N.ageSeconds,N.response}this.lastCacheAgeSeconds=null;let i=new Map,h;do{let N={TimePeriod:{Start:e,End:r},Granularity:E,Metrics:c,GroupBy:_};if(n)N.Filter=n;if(h)N.NextPageToken=h;let A=await this.client.request({service:"ce",region:"us-east-1",method:"POST",path:"/",headers:{"content-type":"application/x-amz-json-1.1","x-amz-target":"AWSInsightsIndexService.GetCostAndUsage"},body:JSON.stringify(N)});for(let u of A?.ResultsByTime??[])for(let f of u?.Groups??[]){let w=f.Keys?.[0]??"Unknown",I=Number.parseFloat(f.Metrics?.UnblendedCost?.Amount??"0"),a=f.Metrics?.UnblendedCost?.Unit??"USD",P=i.get(w);i.set(w,{key:w,amount:(P?.amount??0)+I,unit:a})}h=A?.NextPageToken||void 0}while(h);let R=[...i.values()].filter((N)=>N.amount>0).sort((N,A)=>A.amount-N.amount);if(this.useCache)YD(this.profile,T,R);return R}async getDailyTotals(t){return((await this.client.request({service:"ce",region:"us-east-1",method:"POST",path:"/",headers:{"content-type":"application/x-amz-json-1.1","x-amz-target":"AWSInsightsIndexService.GetCostAndUsage"},body:JSON.stringify({TimePeriod:{Start:t.start,End:t.end},Granularity:"DAILY",Metrics:["UnblendedCost"]})}))?.ResultsByTime??[]).map((d)=>Number.parseFloat(d.Total?.UnblendedCost?.Amount??"0"))}}Lt();class D_{client;region;constructor(t="us-east-1"){this.region=t,this.client=new dt}async describeInstances(t){let e={Action:"DescribeInstances",Version:"2016-11-15"};if(t?.InstanceIds)t.InstanceIds.forEach((E,n)=>{e[`InstanceId.${n+1}`]=E});if(t?.Filters)t.Filters.forEach((E,n)=>{e[`Filter.${n+1}.Name`]=E.Name,E.Values.forEach((c,_)=>{e[`Filter.${n+1}.Value.${_+1}`]=c})});if(t?.MaxResults)e.MaxResults=String(t.MaxResults);if(t?.NextToken)e.NextToken=t.NextToken;let r=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(e).toString()}),d=r.DescribeInstancesResponse||r;return{Reservations:this.parseReservations(d.reservationSet?.item),NextToken:d.nextToken}}async getInstance(t){return(await this.describeInstances({InstanceIds:[t]})).Reservations?.[0]?.Instances?.[0]}async getConsoleOutput(t,e){let r={Action:"GetConsoleOutput",Version:"2016-11-15",InstanceId:t};if(e)r.Latest="true";let d=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(r).toString()}),E=d.GetConsoleOutputResponse||d;return{InstanceId:E.instanceId,Output:E.output,Timestamp:E.timestamp}}async getConsoleOutputDecoded(t,e){let r=await this.getConsoleOutput(t,e?.latest);if(!r.Output)return"No console output available yet";let d=Buffer.from(r.Output,"base64").toString("utf-8");if(e?.tailLines)return d.split(`
|
|
5622
|
+
`).find((E)=>E&&!E.startsWith("#"))?.trim().split(/\s+/);if(r.code!==0||!d?.[1]||!d[2])throw Error(`SSH host-key scan failed: ${r.stderr.trim()||"no key returned"}`);return{algorithm:d[1],key:d[2]}}async exec(t,e){if(t.trustState!=="pinned")throw Error("SSH host key must be pinned before remote execution.");return iD(["ssh","-p",String(t.sshPort),"-o","BatchMode=yes","-o","StrictHostKeyChecking=yes","-o","ConnectTimeout=10",`${t.sshUser}@${t.endpoint}`,e])}}var rP=(t)=>`SHA256:${eP("sha256").update(Buffer.from(t,"base64")).digest("base64").replace(/=+$/,"")}`,dP=`set -eu; printf '{'; printf '"os":"%s",' "$(. /etc/os-release 2>/dev/null; printf %s "\${PRETTY_NAME:-Linux}")"; printf '"arch":"%s",' "$(uname -m)"; printf '"cpuCores":%s,' "$(getconf _NPROCESSORS_ONLN)"; printf '"memoryBytes":%s,' "$(awk '/MemTotal/{print $2*1024}' /proc/meminfo)"; printf '"diskBytes":%s,' "$(df -B1 / | awk 'NR==2{print $2}')"; printf '"diskFreeBytes":%s,' "$(df -B1 / | awk 'NR==2{print $4}')"; printf '"dnsOk":'; getent hosts example.com >/dev/null && printf true || printf false; printf ',"timeSkewSeconds":0,"tools":{"curl":"'; command -v curl >/dev/null && printf installed; printf '","tar":"'; command -v tar >/dev/null && printf installed; printf '"},"privilege":"'; sudo -n true >/dev/null 2>&1 && printf sudo || printf user; printf '"}'`;class C_{provider;transport;discoverer;constructor(t,e=new hD,r){this.provider=t;this.transport=e;this.discoverer=r}discover(t){return this.discoverer?.(t)??Promise.resolve([])}async test(t){try{let e=await this.transport.scan(t.endpoint,t.sshPort);return{reachable:!0,hostKeyAlgorithm:e.algorithm,hostKeyFingerprint:rP(e.key),latencyMs:0}}catch{return{reachable:!1,hostKeyAlgorithm:"unknown",hostKeyFingerprint:"",latencyMs:0}}}async validate(t){let e=await this.transport.exec(t,dP);if(e.code!==0)throw Error(`Fleet validation failed: ${e.stderr.trim()||e.code}`);try{return JSON.parse(e.stdout)}catch{throw Error("Fleet validation returned malformed facts.")}}async bootstrap(t,e){let r=await this.transport.exec(t,`sudo -n ts-cloud-agent bootstrap --version 1 --steps ${e.length}`);if(r.code!==0)throw Error(`Fleet bootstrap failed: ${r.stderr.trim()||r.code}`);return{version:"1"}}capabilities(){return{document:{supported:!0,reason:"fleet-capabilities/v1; sha256:driver-contract"},validate:{supported:!0},bootstrap:{supported:!0},heartbeat:{supported:!0},drain:{supported:!0},archive:{supported:!0},terminate:{supported:!1,reason:"Inventory removal never terminates provider infrastructure."}}}}function RD(t,e){return{"fleet.bootstrap":async(r)=>{let d=r.operation.input&&typeof r.operation.input==="object"&&!Array.isArray(r.operation.input)?r.operation.input:{},E=t.get(String(d.serverId??""));if(!E)throw Error("Queued fleet server was not found.");let n=e.find((T)=>T.provider===E.provider);if(!n)throw Error(`No ${E.provider} fleet driver is configured.`);let c=Array.isArray(d.steps)?d.steps.map(String):[];if(r.checkpoint("preflight","Rechecking pinned trust and healthy validation."),E.trustState!=="pinned"||!E.validation?.valid)throw Error("Fleet bootstrap requires pinned trust and a healthy validation report.");r.checkpoint("bootstrap","Applying the reviewed idempotent bootstrap plan.");let _=await n.bootstrap(E,c);return t.update(E.id,{bootstrapVersion:_.version,status:"ready"}),r.checkpoint("verify","Bootstrap completed; heartbeat can now establish freshness."),{serverId:E.id,bootstrapVersion:_.version,steps:c.length}}}}var br=(t)=>t==null?void 0:String(t),vE=(t,e)=>{try{return JSON.parse(String(t))}catch{return e}},lA=(t)=>({id:String(t.id),organizationId:String(t.organization_id),projectId:String(t.project_id),resourceId:String(t.resource_id),name:String(t.name),provider:String(t.provider),providerId:br(t.provider_id),region:br(t.region),zone:br(t.zone),endpoint:String(t.endpoint),sshUser:String(t.ssh_user),sshPort:Number(t.ssh_port),credentialRef:String(t.credential_ref),hostKeyAlgorithm:br(t.host_key_algorithm),hostKeyFingerprint:br(t.host_key_fingerprint),pendingHostKey:br(t.pending_host_key),roles:vE(t.roles,[]),labels:vE(t.labels,{}),taints:vE(t.taints,[]),capacity:vE(t.capacity,{}),usage:vE(t.usage,{}),capabilities:vE(t.capabilities,{}),status:String(t.status),trustState:String(t.trust_state),validation:vE(t.validation,void 0),bootstrapVersion:br(t.bootstrap_version),heartbeatAt:br(t.heartbeat_at),lastSeenAt:br(t.last_seen_at),archivedAt:br(t.archived_at),version:Number(t.version),createdAt:String(t.created_at),updatedAt:String(t.updated_at)});class IA{control;now;id;constructor(t,e=()=>new Date,r=()=>crypto.randomUUID()){this.control=t;this.now=e;this.id=r}get(t){let e=this.control.database.query("SELECT * FROM fleet_servers WHERE id=?").get(t);return e?lA(e):void 0}list(t,e=!1){return this.control.database.query("SELECT * FROM fleet_servers WHERE project_id=? ORDER BY name").all(t).map(lA).filter((r)=>e||r.status!=="archived")}findProvider(t,e,r){let d=this.control.database.query("SELECT * FROM fleet_servers WHERE organization_id=? AND provider=? AND provider_id=? AND archived_at IS NULL").get(t,e,r);return d?lA(d):void 0}create(t){let e=this.id(),r=this.now().toISOString();return this.control.database.run("INSERT INTO fleet_servers (id,organization_id,project_id,resource_id,name,provider,provider_id,region,zone,endpoint,ssh_user,ssh_port,credential_ref,host_key_algorithm,host_key_fingerprint,pending_host_key,roles,labels,taints,capacity,usage,capabilities,status,trust_state,validation,bootstrap_version,heartbeat_at,last_seen_at,archived_at,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",[e,t.organizationId,t.projectId,t.resourceId,t.name,t.provider,t.providerId??null,t.region??null,t.zone??null,t.endpoint,t.sshUser,t.sshPort,t.credentialRef,t.hostKeyAlgorithm??null,t.hostKeyFingerprint??null,t.pendingHostKey??null,JSON.stringify(t.roles),JSON.stringify(t.labels),JSON.stringify(t.taints),JSON.stringify(t.capacity),JSON.stringify(t.usage),JSON.stringify(t.capabilities),t.status,t.trustState,JSON.stringify(t.validation??{}),t.bootstrapVersion??null,t.heartbeatAt??null,t.lastSeenAt??null,t.archivedAt??null,r,r]),this.get(e)}update(t,e){let r=this.get(t);if(!r)throw Error("Server was not found.");let d={...r,...e},E=this.now().toISOString();return this.control.database.run("UPDATE fleet_servers SET name=?,provider_id=?,region=?,zone=?,endpoint=?,ssh_user=?,ssh_port=?,credential_ref=?,host_key_algorithm=?,host_key_fingerprint=?,pending_host_key=?,roles=?,labels=?,taints=?,capacity=?,usage=?,capabilities=?,status=?,trust_state=?,validation=?,bootstrap_version=?,heartbeat_at=?,last_seen_at=?,archived_at=?,version=version+1,updated_at=? WHERE id=?",[d.name,d.providerId??null,d.region??null,d.zone??null,d.endpoint,d.sshUser,d.sshPort,d.credentialRef,d.hostKeyAlgorithm??null,d.hostKeyFingerprint??null,d.pendingHostKey??null,JSON.stringify(d.roles),JSON.stringify(d.labels),JSON.stringify(d.taints),JSON.stringify(d.capacity),JSON.stringify(d.usage),JSON.stringify(d.capabilities),d.status,d.trustState,JSON.stringify(d.validation??{}),d.bootstrapVersion??null,d.heartbeatAt??null,d.lastSeenAt??null,d.archivedAt??null,E,t]),this.get(t)}}var EP=/^(?:[A-Za-z0-9](?:[A-Za-z0-9.-]{0,251}[A-Za-z0-9])?|\[[0-9a-fA-F:]+\])$/;class DA{store;drivers;now;queue;constructor(t,e,r,d=()=>new Date){this.store=t;this.drivers=e;this.now=d;this.queue=r??new gt(t.control)}driver(t){let e=this.drivers.find((r)=>r.provider===t);if(!e)throw Error(`No ${t} fleet driver is configured.`);return e}enroll(t){if(!/^[a-z0-9][a-z0-9-]{1,62}$/.test(t.name))throw Error("Server name is invalid.");if(!EP.test(t.endpoint)||t.sshUser==="root"||!t.credentialRef.startsWith("secret://"))throw Error("Enrollment requires a valid endpoint, non-root SSH user, and secret credential reference.");let e=t.providerId?this.store.findProvider(t.organizationId,t.provider,t.providerId):void 0;if(e)return this.store.update(e.id,{endpoint:t.endpoint,region:t.region,zone:t.zone});let r=this.store.control.createResource({projectId:t.projectId,kind:"server",slug:t.name,name:t.name,provider:t.provider,providerId:t.providerId}),d=this.driver(t.provider);return this.store.create({...t,resourceId:r.id,sshPort:t.sshPort??22,labels:t.labels??{},taints:[],capacity:{},usage:{},capabilities:d.capabilities(),status:"pending",trustState:"unverified"})}async test(t){let e=this.store.get(t);if(!e)throw Error("Server was not found.");let r=await this.driver(e.provider).test(e);if(!r.reachable)return this.store.update(t,{status:"unreachable"});if(e.hostKeyFingerprint&&e.hostKeyFingerprint!==r.hostKeyFingerprint)return this.store.update(t,{status:"degraded",trustState:"rotation_pending",pendingHostKey:r.hostKeyFingerprint});return this.store.update(t,{hostKeyAlgorithm:r.hostKeyAlgorithm,hostKeyFingerprint:r.hostKeyFingerprint,pendingHostKey:void 0,trustState:"pinned",status:"validating",lastSeenAt:this.now().toISOString()})}reviewHostKey(t,e){let r=this.store.get(t);if(!r||r.pendingHostKey!==e)throw Error("Pending host key does not match.");return this.store.update(t,{hostKeyFingerprint:e,pendingHostKey:void 0,trustState:"pinned",status:"validating"})}async validate(t){let e=this.store.get(t);if(!e||e.trustState!=="pinned")throw Error("Pin the SSH host key before validation.");let r=await this.driver(e.provider).validate(e),d=[];if(!["x64","arm64","x86_64","aarch64"].includes(r.arch??""))d.push({code:"arch.unsupported",severity:"error",message:"Unsupported architecture.",remediation:"Use x86_64 or arm64 Linux."});for(let c of["curl","tar"])if(!r.tools?.[c])d.push({code:`tool.${c}`,severity:"error",message:`${c} is missing.`,remediation:`Install ${c} before bootstrap.`});if(Math.abs(r.timeSkewSeconds??0)>60)d.push({code:"time.skew",severity:"error",message:"Clock skew exceeds 60 seconds.",remediation:"Enable NTP synchronization."});if(!r.dnsOk)d.push({code:"dns.failed",severity:"error",message:"DNS validation failed.",remediation:"Repair resolver configuration."});let E={valid:!d.some((c)=>c.severity==="error"),facts:r,findings:d,validatedAt:this.now().toISOString(),validatorVersion:"1"},n={cpu:r.cpuCores??0,memoryBytes:r.memoryBytes??0,diskBytes:r.diskBytes??0};return this.store.update(t,{validation:E,capacity:n,status:E.valid?"ready":"degraded"})}bootstrap(t,e=!1){let r=this.store.get(t);if(!r?.validation?.valid)throw Error("A healthy validation report is required.");let d=["install runtime dependencies","install ts-cloud agent","configure heartbeat","verify least-privilege access"];if(!e)return{preview:!0,steps:d};let E=this.queue.enqueue({projectId:r.projectId,resourceId:r.resourceId,kind:"fleet.bootstrap",input:{serverId:t,steps:d},lockKey:`server:${t}`,providerKey:r.provider}).operation;return{preview:!1,steps:d,operation:E}}heartbeat(t,e){let r=this.store.get(t);if(!r)throw Error("Server was not found.");let d=this.now().toISOString();return this.store.update(t,{usage:e.usage,capabilities:e.capabilities??r.capabilities,heartbeatAt:d,lastSeenAt:d,status:r.status==="draining"||r.status==="drained"?r.status:"ready"})}drain(t,e=!1){return this.store.update(t,{status:e?"drained":"draining"})}uncordon(t){return this.store.update(t,{status:"ready"})}archive(t,e){let r=this.store.get(t);if(!r||e!==r.name)throw Error("Exact server name confirmation is required.");return this.store.update(t,{status:"archived",archivedAt:this.now().toISOString()})}}import{createHash as fA,createPublicKey as AD,verify as nP}from"node:crypto";function l_(t){if(t===null||typeof t!=="object")return JSON.stringify(t);if(Array.isArray(t))return`[${t.map(l_).join(",")}]`;return`{${Object.keys(t).sort().map((e)=>`${JSON.stringify(e)}:${l_(t[e])}`).join(",")}}`}var LD=(t)=>fA("sha256").update(l_(t)).digest("hex"),si=(t)=>fA("sha256").update(l_(t)).digest("hex"),uD=(t)=>fA("sha256").update(AD(t).export({type:"spki",format:"der"})).digest("hex");function OD(t,e,r){try{return nP(null,Buffer.from(l_(t)),AD(r),Buffer.from(e,"base64"))}catch{return!1}}var SD=(t)=>t.replace(/^v/,"").split(/[.-]/).slice(0,3).map((e)=>Number(e)||0),ND=(t,e)=>{let r=SD(t),d=SD(e);for(let E=0;E<3;E++){let n=(r[E]??0)-(d[E]??0);if(n)return n}return 0};function CD(t,e){let r=[];if(e.schemaVersion<t.minimumSchema)r.push(`schema ${e.schemaVersion} is below ${t.minimumSchema}`);if(e.schemaVersion>t.maximumSchema)r.push(`schema ${e.schemaVersion} is above ${t.maximumSchema}`);if(t.minimumVersion&&ND(e.currentVersion,t.minimumVersion)<0)r.push(`platform ${e.currentVersion} is below ${t.minimumVersion}`);if(ND(t.version,e.currentVersion)<=0)r.push(`version ${t.version} is not newer than ${e.currentVersion}`);if(!t.artifacts.some((d)=>d.platform===e.platform&&d.architecture===e.architecture))r.push(`no artifact for ${e.platform}/${e.architecture}`);return{compatible:r.length===0,reasons:r}}var Ad=(t,e)=>{try{return JSON.parse(String(t))}catch{return e}},fe=(t)=>t==null?void 0:String(t),cP=(t)=>({id:String(t.id),organizationId:String(t.organization_id),name:String(t.name),algorithm:"ed25519",publicKeyPem:String(t.public_key_pem),fingerprint:String(t.fingerprint),revokedAt:fe(t.revoked_at),createdAt:String(t.created_at)}),lD=(t)=>({id:String(t.id),organizationId:String(t.organization_id),version:String(t.version),channel:String(t.channel),publishedAt:String(t.published_at),keyId:String(t.key_id),digest:String(t.digest),document:Ad(t.document,{}),signature:String(t.signature),verificationStatus:String(t.verification_status),compatibility:Ad(t.compatibility,{compatible:!1,reasons:[]}),createdAt:String(t.created_at)}),ID=(t)=>({id:String(t.id),projectId:String(t.project_id),name:String(t.name),schedule:String(t.schedule),timezone:String(t.timezone),durationMinutes:Number(t.duration_minutes),allowedOperations:Ad(t.allowed_operations,[]),requireApproval:Number(t.require_approval)===1,enabled:Number(t.enabled)===1,createdAt:String(t.created_at),updatedAt:String(t.updated_at)}),DD=(t)=>({id:String(t.id),projectId:String(t.project_id),manifestId:String(t.manifest_id),windowId:fe(t.window_id),fromVersion:String(t.from_version),strategy:String(t.strategy),batchSize:Number(t.batch_size),healthGate:Ad(t.health_gate,{}),status:String(t.status),currentStage:fe(t.current_stage),backupId:fe(t.backup_id),approvedBy:fe(t.approved_by),createdAt:String(t.created_at),updatedAt:String(t.updated_at)}),UA=(t)=>({id:String(t.id),campaignId:String(t.campaign_id),serverId:fe(t.server_id),target:String(t.target),cohort:Number(t.cohort),previousVersion:String(t.previous_version),status:String(t.status),evidence:Ad(t.evidence,{}),error:fe(t.error),startedAt:fe(t.started_at),finishedAt:fe(t.finished_at),createdAt:String(t.created_at),updatedAt:String(t.updated_at)}),fD=(t)=>({id:String(t.id),projectId:String(t.project_id),kind:String(t.kind),criteria:Ad(t.criteria,{}),candidates:Ad(t.candidates,[]),candidateDigest:String(t.candidate_digest),estimatedBytes:Number(t.estimated_bytes),status:String(t.status),confirmation:fe(t.confirmation),expiresAt:String(t.expires_at),result:Ad(t.result,{}),createdAt:String(t.created_at),updatedAt:String(t.updated_at)}),UD=(t)=>({id:String(t.id),projectId:String(t.project_id),backupPolicyId:fe(t.backup_policy_id),recoveryPointId:fe(t.recovery_point_id),topologyId:fe(t.topology_id),scenario:String(t.scenario),isolatedTarget:String(t.isolated_target),expectedRpoMinutes:Number(t.expected_rpo_minutes),expectedRtoMinutes:Number(t.expected_rto_minutes),status:String(t.status),operationId:fe(t.operation_id),evidence:Ad(t.evidence,{}),measuredRpoMinutes:t.measured_rpo_minutes==null?void 0:Number(t.measured_rpo_minutes),measuredRtoMinutes:t.measured_rto_minutes==null?void 0:Number(t.measured_rto_minutes),cleanupVerified:Number(t.cleanup_verified)===1,error:fe(t.error),startedAt:fe(t.started_at),finishedAt:fe(t.finished_at),createdAt:String(t.created_at),updatedAt:String(t.updated_at)});class wA{control;now;id;constructor(t,e=()=>new Date,r=()=>crypto.randomUUID()){this.control=t;this.now=e;this.id=r}addTrustedKey(t){let e=this.id(),r=this.now().toISOString(),d=uD(t.publicKeyPem);return this.control.database.run("INSERT INTO platform_trusted_keys (id,organization_id,name,algorithm,public_key_pem,fingerprint,created_at) VALUES (?,?,?,'ed25519',?,?,?)",[e,t.organizationId,t.name,t.publicKeyPem,d,r]),this.key(e)}key(t){let e=this.control.database.query("SELECT * FROM platform_trusted_keys WHERE id=?").get(t);return e?cP(e):void 0}revokeKey(t){return this.control.database.run("UPDATE platform_trusted_keys SET revoked_at=? WHERE id=?",[this.now().toISOString(),t]),this.key(t)}importManifest(t){let e=this.key(t.keyId);if(!e||e.organizationId!==t.organizationId)throw Error("Trusted update key was not found.");if(e.revokedAt)throw Error("Update signing key is revoked.");if(!OD(t.document,t.signature,e.publicKeyPem))throw Error("Update manifest signature is invalid.");let r=CD(t.document,t.current),d=LD(t.document),E=this.id(),n=this.now().toISOString();return this.control.database.run("INSERT INTO platform_update_manifests (id,organization_id,version,channel,published_at,key_id,digest,document,signature,verification_status,compatibility,created_at) VALUES (?,?,?,?,?,?,?,?,?,'verified',?,?)",[E,t.organizationId,t.document.version,t.document.channel,new Date(t.document.publishedAt).toISOString(),t.keyId,d,JSON.stringify(t.document),t.signature,JSON.stringify(r),n]),this.manifest(E)}manifest(t){let e=this.control.database.query("SELECT * FROM platform_update_manifests WHERE id=?").get(t);return e?lD(e):void 0}manifests(t){return this.control.database.query("SELECT * FROM platform_update_manifests WHERE organization_id=? ORDER BY published_at DESC").all(t).map(lD)}createWindow(t){let e=this.id(),r=this.now().toISOString();return this.control.database.run("INSERT INTO maintenance_windows (id,project_id,name,schedule,timezone,duration_minutes,allowed_operations,require_approval,enabled,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,1,?,?)",[e,t.projectId,t.name,t.schedule,t.timezone,t.durationMinutes,JSON.stringify(t.allowedOperations),t.requireApproval===!1?0:1,r,r]),this.window(e)}window(t){let e=this.control.database.query("SELECT * FROM maintenance_windows WHERE id=?").get(t);return e?ID(e):void 0}windows(t){return this.control.database.query("SELECT * FROM maintenance_windows WHERE project_id=? ORDER BY name").all(t).map(ID)}createCampaign(t){return this.control.transaction(()=>{let e=this.manifest(t.manifestId);if(!e?.compatibility.compatible||e.verificationStatus!=="verified")throw Error("A verified compatible update manifest is required.");if(!t.backupId)throw Error("A verified pre-upgrade backup is required.");let r=this.id(),d=this.now().toISOString();return this.control.database.run("INSERT INTO platform_upgrade_campaigns (id,project_id,manifest_id,window_id,from_version,strategy,batch_size,health_gate,status,backup_id,approved_by,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?, 'planned',?,?,?,?)",[r,t.projectId,t.manifestId,t.windowId??null,t.fromVersion,t.strategy,t.batchSize,JSON.stringify(t.healthGate),t.backupId,t.approvedBy??null,d,d]),t.targets.forEach((E,n)=>this.control.database.run("INSERT INTO platform_upgrade_targets (id,campaign_id,server_id,target,cohort,previous_version,status,created_at,updated_at) VALUES (?,?,?,?,?,?,'pending',?,?)",[this.id(),r,E.serverId??null,E.target,t.strategy==="canary"?n===0?0:1+Math.floor((n-1)/t.batchSize):Math.floor(n/t.batchSize),E.previousVersion,d,d])),this.campaign(r)})}campaign(t){let e=this.control.database.query("SELECT * FROM platform_upgrade_campaigns WHERE id=?").get(t);return e?DD(e):void 0}campaigns(t){return this.control.database.query("SELECT * FROM platform_upgrade_campaigns WHERE project_id=? ORDER BY created_at DESC").all(t).map(DD)}targets(t){return this.control.database.query("SELECT * FROM platform_upgrade_targets WHERE campaign_id=? ORDER BY cohort,target").all(t).map(UA)}updateCampaign(t,e){let r=this.campaign(t);if(!r)throw Error("Upgrade campaign was not found.");let d={...r,...e};return this.control.database.run("UPDATE platform_upgrade_campaigns SET status=?,current_stage=?,updated_at=? WHERE id=?",[d.status,d.currentStage??null,this.now().toISOString(),t]),this.campaign(t)}updateTarget(t,e){let r=this.control.database.query("SELECT * FROM platform_upgrade_targets WHERE id=?").get(t);if(!r)throw Error("Upgrade target was not found.");let d={...UA(r),...e};return this.control.database.run("UPDATE platform_upgrade_targets SET status=?,evidence=?,error=?,started_at=?,finished_at=?,updated_at=? WHERE id=?",[d.status,JSON.stringify(d.evidence),d.error??null,d.startedAt??null,d.finishedAt??null,this.now().toISOString(),t]),UA(this.control.database.query("SELECT * FROM platform_upgrade_targets WHERE id=?").get(t))}createCleanup(t){let e=[...t.candidates].sort((c,_)=>c.id.localeCompare(_.id)),r=si(e),d=this.id(),E=this.now().toISOString(),n=new Date(this.now().getTime()+(t.ttlMinutes??60)*60000).toISOString();return this.control.database.run("INSERT INTO cleanup_plans (id,project_id,kind,criteria,candidates,candidate_digest,estimated_bytes,status,expires_at,created_at,updated_at) VALUES (?,?,?,?,?,?,?,'preview',?,?,?)",[d,t.projectId,t.kind,JSON.stringify(t.criteria),JSON.stringify(e),r,e.reduce((c,_)=>c+_.bytes,0),n,E,E]),this.cleanup(d)}cleanup(t){let e=this.control.database.query("SELECT * FROM cleanup_plans WHERE id=?").get(t);return e?fD(e):void 0}cleanups(t){return this.control.database.query("SELECT * FROM cleanup_plans WHERE project_id=? ORDER BY created_at DESC").all(t).map(fD)}updateCleanup(t,e){let r=this.cleanup(t);if(!r)throw Error("Cleanup plan was not found.");let d={...r,...e};return this.control.database.run("UPDATE cleanup_plans SET status=?,confirmation=?,result=?,updated_at=? WHERE id=?",[d.status,d.confirmation??null,JSON.stringify(d.result),this.now().toISOString(),t]),this.cleanup(t)}createDrill(t){if(!/^isolated:\/\//.test(t.isolatedTarget))throw Error("DR drills require an isolated target.");let e=this.id(),r=this.now().toISOString();return this.control.database.run("INSERT INTO disaster_recovery_drills (id,project_id,backup_policy_id,recovery_point_id,topology_id,scenario,isolated_target,expected_rpo_minutes,expected_rto_minutes,status,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,'planned',?,?)",[e,t.projectId,t.backupPolicyId??null,t.recoveryPointId??null,t.topologyId??null,t.scenario,t.isolatedTarget,t.expectedRpoMinutes,t.expectedRtoMinutes,r,r]),this.drill(e)}drill(t){let e=this.control.database.query("SELECT * FROM disaster_recovery_drills WHERE id=?").get(t);return e?UD(e):void 0}drills(t){return this.control.database.query("SELECT * FROM disaster_recovery_drills WHERE project_id=? ORDER BY created_at DESC").all(t).map(UD)}updateDrill(t,e){let r=this.drill(t);if(!r)throw Error("DR drill was not found.");let d={...r,...e};return this.control.database.run("UPDATE disaster_recovery_drills SET status=?,operation_id=?,evidence=?,measured_rpo_minutes=?,measured_rto_minutes=?,cleanup_verified=?,error=?,started_at=?,finished_at=?,updated_at=? WHERE id=?",[d.status,d.operationId??null,JSON.stringify(d.evidence),d.measuredRpoMinutes??null,d.measuredRtoMinutes??null,d.cleanupVerified?1:0,d.error??null,d.startedAt??null,d.finishedAt??null,this.now().toISOString(),t]),this.drill(t)}}function _P(t,e=new Date){if(!t.enabled)return!1;let r=new Date(t.schedule);if(!Number.isNaN(r.getTime()))return e>=r&&e.getTime()<=r.getTime()+t.durationMinutes*60000;let d=/^(\d{2}):(\d{2})$/.exec(t.schedule);if(!d)return!1;let E=new Intl.DateTimeFormat("en-US",{timeZone:t.timezone,hour:"2-digit",minute:"2-digit",hourCycle:"h23"}).formatToParts(e),n=Number(E.find((_)=>_.type==="hour")?.value)*60+Number(E.find((_)=>_.type==="minute")?.value),c=Number(d[1])*60+Number(d[2]);return n>=c&&n<c+t.durationMinutes}class gA{store;now;queue;constructor(t,e,r=()=>new Date){this.store=t;this.now=r;this.queue=e??new gt(t.control)}enqueueCampaign(t,e={}){let r=this.store.campaign(t);if(!r)throw Error("Upgrade campaign was not found.");let d=r.windowId?this.store.window(r.windowId):void 0;if(d&&!d.allowedOperations.includes("platform.upgrade"))throw Error("Maintenance window does not permit platform upgrades.");if(d&&!e.overrideWindow&&!_P(d,this.now()))throw Error("Upgrade is outside its maintenance window.");if(d?.requireApproval&&!e.approvedBy&&!r.approvedBy)throw Error("Maintenance approval is required.");let E=this.queue.enqueue({projectId:r.projectId,actorId:e.approvedBy,kind:"maintenance.upgrade",input:{campaignId:t},lockKey:"platform-upgrade",providerKey:"platform",timeoutSeconds:7200,cancellationMode:"cooperative",resumePolicy:"fail"}).operation;return{campaign:this.store.updateCampaign(t,{status:"queued"}),operation:E}}async previewCleanup(t,e){let r=e.find((d)=>d.kind===t.kind);if(!r)throw Error(`No ${t.kind} cleanup driver is configured.`);return this.store.createCleanup({...t,candidates:await r.discover(t.criteria)})}enqueueCleanup(t,e){let r=this.store.cleanup(t);if(!r||r.status!=="preview")throw Error("A current cleanup preview is required.");if(new Date(r.expiresAt)<=this.now())throw Error("Cleanup preview expired; generate it again.");let d=`DELETE ${r.candidates.length} ${r.kind}`;if(e!==d)throw Error(`Exact confirmation ${d} is required.`);let E=this.queue.enqueue({projectId:r.projectId,kind:"maintenance.cleanup",input:{planId:t},lockKey:`cleanup:${r.kind}`,providerKey:"cleanup",timeoutSeconds:3600,cancellationMode:"cooperative"}).operation;return{plan:this.store.updateCleanup(t,{status:"approved",confirmation:e}),operation:E}}enqueueDrill(t){let e=this.store.drill(t);if(!e||e.status!=="planned")throw Error("A planned DR drill is required.");let r=this.queue.enqueue({projectId:e.projectId,kind:"maintenance.drill",input:{drillId:t},lockKey:`drill:${e.scenario}:${e.id}`,providerKey:"recovery",timeoutSeconds:7200,cancellationMode:"cooperative"}).operation;return{drill:this.store.updateDrill(t,{status:"queued",operationId:r.id}),operation:r}}}var $A=(t)=>t&&typeof t==="object"&&!Array.isArray(t)?t:{};function wD(t){return{"maintenance.upgrade":async(E)=>{let n=t.store.campaign(String($A(E.operation.input).campaignId??""));if(!n||!t.platform)throw Error("Upgrade campaign or platform maintenance driver is unavailable.");let c=t.store.manifest(n.manifestId);if(!c?.compatibility.compatible||c.verificationStatus!=="verified")throw Error("Update manifest is no longer verified and compatible.");let _=c.document.artifacts.find((i)=>i.platform===process.platform&&i.architecture===process.arch)??c.document.artifacts[0];if(!_)throw Error("No update artifact matches this platform.");t.store.updateCampaign(n.id,{status:"running",currentStage:"preflight"});let T=[];try{for(let i of[...new Set(t.store.targets(n.id).map((h)=>h.cohort))].sort((h,R)=>h-R)){t.store.updateCampaign(n.id,{currentStage:`cohort:${i}`});for(let h of t.store.targets(n.id).filter((R)=>R.cohort===i)){E.throwIfCancellationRequested(),E.checkpoint(`download:${h.target}`,"Downloading signed platform artifact."),t.store.updateTarget(h.id,{status:"downloading",startedAt:new Date().toISOString()});let R=await t.platform.download({target:h,artifact:_,signal:E.signal});if(R.sha256!==_.sha256)throw Error(`Artifact checksum mismatch for ${h.target}.`);E.checkpoint(`install:${h.target}`,"Installing verified artifact."),t.store.updateTarget(h.id,{status:"installing"}),await t.platform.install({target:h,path:R.path,version:c.version,signal:E.signal}),T.push(h);let N=await t.platform.health({target:h,gate:n.healthGate});if(!N.healthy)throw Error(`Upgrade health gate failed for ${h.target}.`);t.store.updateTarget(h.id,{status:"healthy",evidence:N.evidence,finishedAt:new Date().toISOString()})}}return t.store.updateCampaign(n.id,{status:"succeeded",currentStage:void 0}),{campaignId:n.id,version:c.version,targets:T.length}}catch(i){t.store.updateCampaign(n.id,{status:"rolling_back",currentStage:"rollback"});for(let h of T.reverse())t.store.updateTarget(h.id,{status:"rolling_back"}),await t.platform.rollback({target:h,version:h.previousVersion,signal:E.signal}),t.store.updateTarget(h.id,{status:"rolled_back",finishedAt:new Date().toISOString()});throw t.store.updateCampaign(n.id,{status:"rolled_back",currentStage:void 0}),i}},"maintenance.cleanup":async(E)=>{let n=t.store.cleanup(String($A(E.operation.input).planId??""));if(!n||n.status!=="approved")throw Error("Approved cleanup plan was not found.");if(si([...n.candidates].sort((h,R)=>h.id.localeCompare(R.id)))!==n.candidateDigest)throw Error("Cleanup candidate set changed after preview.");let c=t.cleanup?.find((h)=>h.kind===n.kind);if(!c)throw Error(`No ${n.kind} cleanup driver is configured.`);t.store.updateCleanup(n.id,{status:"running"});let _=[],T=[];for(let h of n.candidates){E.throwIfCancellationRequested();try{await c.remove(h),_.push(h.id)}catch(R){T.push({id:h.id,error:R instanceof Error?R.message:String(R)})}}let i=T.length?_.length?"partial":"failed":"succeeded";if(t.store.updateCleanup(n.id,{status:i,result:{removed:_,failed:T,reclaimedBytes:n.candidates.filter((h)=>_.includes(h.id)).reduce((h,R)=>h+R.bytes,0)}}),T.length)throw Error(`Cleanup failed for ${T.length} candidate(s).`);return{planId:n.id,removed:_.length,reclaimedBytes:n.estimatedBytes}},"maintenance.drill":async(E)=>{let n=t.store.drill(String($A(E.operation.input).drillId??""));if(!n)throw Error("DR drill was not found.");let c=t.recovery?.find((R)=>R.scenario===n.scenario);if(!c)throw Error(`No ${n.scenario} recovery driver is configured.`);let _=new Date;t.store.updateDrill(n.id,{status:"restoring",startedAt:_.toISOString()});let T=n.isolatedTarget,i={},h={};try{E.checkpoint("restore","Restoring into isolated drill target.");let R=await c.restore({drill:n,signal:E.signal});if(!R.target.startsWith("isolated://"))throw Error("Recovery driver attempted a non-isolated target.");T=R.target,i=R.evidence;let N=(_.getTime()-new Date(R.recoveryPointAt).getTime())/60000;t.store.updateDrill(n.id,{status:"verifying",measuredRpoMinutes:N,evidence:{restore:i}}),E.checkpoint("verify","Running recovery health checks without production traffic.");let A=await c.verify({drill:n,target:T});h=A.evidence;let u=(Date.now()-_.getTime())/60000;if(!A.healthy||N>n.expectedRpoMinutes||u>n.expectedRtoMinutes)throw Error("DR drill failed its health, RPO, or RTO objective.");t.store.updateDrill(n.id,{measuredRpoMinutes:N,measuredRtoMinutes:u,evidence:{restore:i,verify:h}})}catch(R){throw t.store.updateDrill(n.id,{status:"failed",error:R instanceof Error?R.message:String(R),evidence:{restore:i,verify:h}}),R}finally{t.store.updateDrill(n.id,{status:"cleaning"});try{await c.cleanup({drill:n,target:T});let R=t.store.drill(n.id);t.store.updateDrill(n.id,{status:R.error?"failed":"passed",cleanupVerified:!0,finishedAt:new Date().toISOString()})}catch(R){t.store.updateDrill(n.id,{status:"cleanup_required",cleanupVerified:!1,error:R instanceof Error?R.message:String(R),finishedAt:new Date().toISOString()})}}return{drillId:n.id,status:t.store.drill(n.id).status}}}}var gD={releases:{select:"SELECT id,created_at,0 bytes FROM releases WHERE project_id=? AND pinned=0 AND status IN ('failed','rolled_back','superseded') AND created_at<?",remove:"DELETE FROM releases WHERE id=?"},artifacts:{select:"SELECT a.id,a.created_at,a.size bytes FROM release_artifacts a WHERE a.organization_id=? AND NOT EXISTS(SELECT 1 FROM releases r WHERE r.artifact_id=a.id) AND a.created_at<?",remove:"DELETE FROM release_artifacts WHERE id=?"},operations:{select:"SELECT id,created_at,0 bytes FROM operations WHERE project_id=? AND state IN ('succeeded','failed','cancelled','timed_out') AND updated_at<?",remove:"DELETE FROM operations WHERE id=?"},logs:{select:"SELECT l.id,l.created_at,length(l.message) bytes FROM operation_logs l JOIN operations o ON o.id=l.operation_id WHERE o.project_id=? AND o.state IN ('succeeded','failed','cancelled','timed_out') AND l.created_at<?",remove:"DELETE FROM operation_logs WHERE id=?"},previews:{select:"SELECT id,created_at,0 bytes FROM preview_instances WHERE project_id=? AND status IN ('destroyed','failed') AND updated_at<?",remove:"DELETE FROM preview_instances WHERE id=?"},snapshots:{select:"SELECT id,created_at,size_bytes bytes FROM recovery_points WHERE project_id=? AND pinned=0 AND held=0 AND status IN ('failed','deleted') AND created_at<?",remove:"DELETE FROM recovery_points WHERE id=?"},orphaned_resources:{select:"SELECT id,created_at,COALESCE(capacity_bytes,0) bytes FROM persistent_volumes WHERE project_id=? AND status='orphaned' AND orphaned_at<?",remove:"UPDATE persistent_volumes SET status='deleted',deleted_at=datetime('now'),updated_at=datetime('now') WHERE id=? AND status='orphaned'"}};class yA{kind;control;projectId;organizationId;constructor(t,e,r,d){this.kind=t;this.control=e;this.projectId=r;this.organizationId=d}async discover(t){let e=Math.max(1,Math.min(3650,Number(t.olderThanDays??30))),r=new Date(Date.now()-e*86400000).toISOString(),d=gD[this.kind],E=this.kind==="artifacts"?this.organizationId:this.projectId;return this.control.database.query(d.select).all(E,r).map((c)=>({id:String(c.id),kind:this.kind,label:`${this.kind}:${String(c.id)}`,bytes:Number(c.bytes??0),metadata:{createdAt:String(c.created_at)}}))}async remove(t){if(this.control.database.run(gD[this.kind].remove,[t.id]).changes!==1)throw Error(`${t.label} changed or is no longer removable.`)}}var jr=(t,e)=>{try{return JSON.parse(String(t))}catch{return e}},be=(t)=>t==null?void 0:String(t),XD=()=>({cpu:0,memoryBytes:0,diskBytes:0,gpu:0}),mn=(t={})=>({...XD(),...t});function $D(t){return{id:String(t.id),organizationId:String(t.organization_id),projectId:String(t.project_id),name:String(t.name),purpose:String(t.purpose),backend:String(t.backend),region:be(t.region),architecture:be(t.architecture),labels:jr(t.labels,{}),requiredServerLabels:jr(t.required_server_labels,{}),toleratedTaints:jr(t.tolerated_taints,[]),capacity:mn(jr(t.capacity,{})),reserved:jr(t.reserved,{}),maxWorkloads:Number(t.max_workloads),costWeight:Number(t.cost_weight),spreadKey:be(t.spread_key),concurrency:Number(t.concurrency),ephemeralWorkspaces:Number(t.ephemeral_workspaces)===1,allowProductionSecrets:Number(t.allow_production_secrets)===1,status:String(t.status),version:Number(t.version),createdAt:String(t.created_at),updatedAt:String(t.updated_at)}}function yD(t){return{id:String(t.id),projectId:String(t.project_id),environmentId:be(t.environment_id),resourceId:String(t.resource_id),releaseId:be(t.release_id),poolId:String(t.pool_id),serverId:be(t.server_id),purpose:String(t.purpose),requirements:jr(t.requirements,{}),decision:jr(t.decision,{}),stateful:Number(t.stateful)===1,autoReschedule:Number(t.auto_reschedule)===1,status:String(t.status),version:Number(t.version),createdAt:String(t.created_at),updatedAt:String(t.updated_at)}}function TP(t){return{id:String(t.id),projectId:String(t.project_id),resourceId:be(t.resource_id),poolId:String(t.pool_id),placementId:be(t.placement_id),operationId:be(t.operation_id),sourceSha:String(t.source_sha),buildSpec:jr(t.build_spec,{}),credentialPolicy:jr(t.credential_policy,{productionSecrets:!1,shortLivedTokenExpiresAt:""}),workspace:be(t.workspace),cacheKey:be(t.cache_key),artifactUri:be(t.artifact_uri),artifactDigest:be(t.artifact_digest),status:String(t.status),cleanupAt:be(t.cleanup_at),createdAt:String(t.created_at),updatedAt:String(t.updated_at)}}class XA{control;now;id;constructor(t,e=()=>new Date,r=()=>crypto.randomUUID()){this.control=t;this.now=e;this.id=r}createPool(t){let e=this.id(),r=this.now().toISOString();return this.control.database.run("INSERT INTO capacity_pools (id,organization_id,project_id,name,purpose,backend,region,architecture,labels,required_server_labels,tolerated_taints,capacity,reserved,max_workloads,cost_weight,spread_key,concurrency,ephemeral_workspaces,allow_production_secrets,status,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",[e,t.organizationId,t.projectId,t.name,t.purpose,t.backend,t.region??null,t.architecture??null,JSON.stringify(t.labels),JSON.stringify(t.requiredServerLabels),JSON.stringify(t.toleratedTaints),JSON.stringify(mn(t.capacity)),"{}",t.maxWorkloads,t.costWeight,t.spreadKey??null,t.concurrency,t.ephemeralWorkspaces?1:0,t.allowProductionSecrets?1:0,t.status,r,r]),this.getPool(e)}getPool(t){let e=this.control.database.query("SELECT * FROM capacity_pools WHERE id=?").get(t);return e?$D(e):void 0}listPools(t){return this.control.database.query("SELECT * FROM capacity_pools WHERE project_id=? ORDER BY name").all(t).map($D)}updatePool(t,e){let r=this.getPool(t);if(!r)throw Error("Capacity pool was not found.");let d={...r,...e},E=this.now().toISOString();return this.control.database.run("UPDATE capacity_pools SET status=?,reserved=?,capacity=?,concurrency=?,version=version+1,updated_at=? WHERE id=?",[d.status,JSON.stringify(d.reserved),JSON.stringify(d.capacity),d.concurrency,E,t]),this.getPool(t)}addMember(t,e,r={}){let d=this.now().toISOString();this.control.database.run("INSERT INTO capacity_pool_members (pool_id,server_id,capacity_override,status,created_at,updated_at) VALUES (?,?,?,'active',?,?) ON CONFLICT(pool_id,server_id) DO UPDATE SET capacity_override=excluded.capacity_override,status='active',updated_at=excluded.updated_at",[t,e,JSON.stringify(r),d,d])}members(t){return this.control.database.query("SELECT * FROM capacity_pool_members WHERE pool_id=? ORDER BY server_id").all(t).map((e)=>({serverId:String(e.server_id),status:String(e.status),capacityOverride:jr(e.capacity_override,{})}))}memberStatus(t,e,r){this.control.database.run("UPDATE capacity_pool_members SET status=?,updated_at=? WHERE pool_id=? AND server_id=?",[r,this.now().toISOString(),t,e])}listPlacements(t,e){let r=this.control.database.query("SELECT * FROM workload_placements WHERE project_id=? ORDER BY created_at,id").all(t).map(yD);return e?.length?r.filter((d)=>e.includes(d.status)):r}getPlacement(t){let e=this.control.database.query("SELECT * FROM workload_placements WHERE id=?").get(t);return e?yD(e):void 0}activeUsage(t,e){let r=this.control.database.query("SELECT l.resources,l.server_id FROM capacity_leases l WHERE l.pool_id=? AND l.state='active' AND l.expires_at>?").all(t,this.now().toISOString()),d=e?r.filter((E)=>String(E.server_id)===e):r;return{resources:d.reduce((E,n)=>{let c=mn(jr(n.resources,{}));for(let _ of Object.keys(E))E[_]+=c[_];return E},XD()),count:d.length}}expireLeases(){return this.control.database.run("UPDATE capacity_leases SET state='expired',updated_at=? WHERE state='active' AND expires_at<=?",[this.now().toISOString(),this.now().toISOString()]).changes}reserve(t){return this.control.transaction(()=>{this.expireLeases();let e=this.id(),r=this.id(),d=this.now().toISOString(),E=new Date(this.now().getTime()+(t.requirements.leaseSeconds??300)*1000).toISOString();return this.control.database.run("INSERT INTO workload_placements (id,project_id,environment_id,resource_id,release_id,pool_id,server_id,purpose,requirements,decision,stateful,auto_reschedule,status,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,'reserved',?,?)",[e,t.projectId,t.environmentId??null,t.resourceId,t.releaseId??null,t.decision.poolId,t.decision.serverId??null,t.requirements.purpose,JSON.stringify(t.requirements),JSON.stringify(t.decision),t.requirements.stateful?1:0,t.requirements.autoReschedule&&!t.requirements.stateful?1:0,d,d]),this.control.database.run("INSERT INTO capacity_leases (id,placement_id,pool_id,server_id,resources,state,expires_at,created_at,updated_at) VALUES (?,?,?,?,?,'active',?,?,?)",[r,e,t.decision.poolId,t.decision.serverId??null,JSON.stringify(mn(t.requirements.resources)),E,d,d]),this.getPlacement(e)})}transitionPlacement(t,e){if(!this.getPlacement(t))throw Error("Placement was not found.");let d=this.now().toISOString();if(this.control.database.run("UPDATE workload_placements SET status=?,version=version+1,updated_at=? WHERE id=?",[e,d,t]),["released","failed","blocked"].includes(e))this.control.database.run("UPDATE capacity_leases SET state='released',updated_at=? WHERE placement_id=? AND state='active'",[d,t]);return this.getPlacement(t)}createBuild(t){let e=this.id(),r=this.now().toISOString();return this.control.database.run("INSERT INTO remote_builds (id,project_id,resource_id,pool_id,placement_id,operation_id,source_sha,build_spec,credential_policy,status,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,'queued',?,?)",[e,t.projectId,t.resourceId??null,t.poolId,t.placementId??null,t.operationId??null,t.sourceSha,JSON.stringify(t.buildSpec),JSON.stringify({productionSecrets:!1,shortLivedTokenExpiresAt:t.tokenExpiresAt}),r,r]),this.getBuild(e)}getBuild(t){let e=this.control.database.query("SELECT * FROM remote_builds WHERE id=?").get(t);return e?TP(e):void 0}updateBuild(t,e){let r=this.getBuild(t);if(!r)throw Error("Remote build was not found.");let d={...r,...e},E=this.now().toISOString();return this.control.database.run("UPDATE remote_builds SET operation_id=?,workspace=?,cache_key=?,artifact_uri=?,artifact_digest=?,status=?,cleanup_at=?,updated_at=? WHERE id=?",[d.operationId??null,d.workspace??null,d.cacheKey??null,d.artifactUri??null,d.artifactDigest??null,d.status,d.cleanupAt??null,E,t]),this.getBuild(t)}}var oi=["cpu","memoryBytes","diskBytes","gpu"],aD=(t,e={})=>Object.entries(e).every(([r,d])=>t[r]===d),iP=(t,e,r)=>Object.fromEntries(oi.map((d)=>[d,Math.max(0,t[d]-e[d]-(r[d]??0))])),hP=(t,e)=>oi.every((r)=>t[r]>=(e[r]??0)),RP=(t,e)=>oi.reduce((r,d)=>r+(e[d]??0)/(t[d]||1),0);class aA{store;fleet;constructor(t,e){this.store=t;this.fleet=e}poolCandidates(t,e,r){let d=[];for(let E of this.store.listPools(t)){if(E.id===r)continue;let n=[];if(E.status!=="active")n.push(`pool is ${E.status}`);if(E.purpose!==e.purpose)n.push(`purpose is ${E.purpose}`);if(e.region&&E.region!==e.region)n.push(`region is ${E.region??"unset"}`);if(e.architecture&&E.architecture!==e.architecture)n.push(`architecture is ${E.architecture??"unset"}`);if(!aD(E.labels,e.labels))n.push("pool labels do not match");if(E.backend==="server"){let c=this.store.members(E.id);if(!c.length)d.push(this.decision(E,void 0,e,[...n,"pool has no servers"]));for(let _ of c){let T=this.fleet.get(_.serverId),i=[...n];if(!T)i.push("server is missing");else this.serverReasons(E,T,_.status,e,i);d.push(this.decision(E,T,e,i,_.capacityOverride))}}else d.push(this.decision(E,void 0,e,n))}return d.sort((E,n)=>Number(n.eligible)-Number(E.eligible)||E.score.cost-n.score.cost||E.score.spread-n.score.spread||E.score.fit-n.score.fit||E.poolName.localeCompare(n.poolName)||(E.serverId??"").localeCompare(n.serverId??""))}serverReasons(t,e,r,d,E){if(r!=="active")E.push(`member is ${r}`);if(e.status!=="ready")E.push(`server is ${e.status}`);if(!e.roles.includes(d.purpose==="build"?"build":d.purpose))E.push(`server lacks ${d.purpose} role`);if(!aD(e.labels,t.requiredServerLabels))E.push("server labels do not match pool selector");for(let n of e.taints)if(!t.toleratedTaints.includes(n))E.push(`taint ${n} is not tolerated`)}decision(t,e,r,d,E={}){let n=mn({...e?.capacity,...E}),c=e?Object.fromEntries(oi.map((i)=>[i,Math.min(t.capacity[i],n[i])])):t.capacity,_=this.store.activeUsage(t.id,e?.id),T=iP(c,_.resources,t.reserved);if(_.count>=t.maxWorkloads)d.push("workload limit reached");if(r.purpose==="build"&&_.count>=t.concurrency)d.push("build concurrency reached");if(!hP(T,r.resources))d.push("insufficient capacity");return{poolId:t.id,poolName:t.name,serverId:e?.id,eligible:d.length===0,reasons:d,available:T,score:{fit:RP(T,r.resources),spread:_.count,cost:t.costWeight}}}explain(t,e){return this.poolCandidates(t,e)}place(t){return this.store.control.transaction(()=>{let e=this.poolCandidates(t.projectId,t.requirements).find((r)=>r.eligible);if(!e)throw Error(`No eligible capacity: ${this.explain(t.projectId,t.requirements).flatMap((r)=>r.reasons).join("; ")}`);return this.store.reserve({...t,decision:e})})}activate(t){return this.store.transitionPlacement(t,"active")}release(t){return this.store.transitionPlacement(t,"released")}drainPool(t){let e=this.store.updatePool(t,{status:"draining"}),r=[],d=[];for(let E of this.store.listPlacements(e.projectId,["reserved","active"]).filter((n)=>n.poolId===t)){if(E.stateful){d.push(this.store.transitionPlacement(E.id,"blocked"));continue}this.store.transitionPlacement(E.id,"moving");let n=this.place({projectId:E.projectId,environmentId:E.environmentId,resourceId:E.resourceId,releaseId:E.releaseId,requirements:E.requirements});r.push(this.activate(n.id)),this.store.transitionPlacement(E.id,"released")}return{pool:e,moved:r,blocked:d}}drainServer(t,e){this.store.memberStatus(t,e,"draining");let r=this.store.getPool(t);if(!r)throw Error("Capacity pool was not found.");let d=[],E=[];for(let n of this.store.listPlacements(r.projectId,["reserved","active"]).filter((c)=>c.poolId===t&&c.serverId===e)){if(n.stateful){E.push(this.store.transitionPlacement(n.id,"blocked"));continue}this.store.transitionPlacement(n.id,"moving");let c=this.poolCandidates(n.projectId,n.requirements).find((T)=>T.eligible);if(!c){E.push(this.store.transitionPlacement(n.id,"blocked"));continue}let _=this.store.reserve({projectId:n.projectId,environmentId:n.environmentId,resourceId:n.resourceId,releaseId:n.releaseId,requirements:n.requirements,decision:c});d.push(this.activate(_.id)),this.store.transitionPlacement(n.id,"released")}return{moved:d,blocked:E}}reconcileFailure(t){let e=this.fleet.get(t);if(!e)throw Error("Server was not found.");let r=[],d=[];for(let E of this.store.listPlacements(e.projectId,["active"]).filter((n)=>n.serverId===t)){if(E.stateful||!E.autoReschedule){d.push(this.store.transitionPlacement(E.id,"blocked"));continue}this.store.transitionPlacement(E.id,"failed");let n=this.place({projectId:E.projectId,environmentId:E.environmentId,resourceId:E.resourceId,releaseId:E.releaseId,requirements:E.requirements});r.push(this.activate(n.id))}return{rescheduled:r,blocked:d}}}var Ld=(t,e)=>{try{return JSON.parse(String(t))}catch{return e}},Cr=(t)=>t==null?void 0:String(t),PD=(t)=>({id:String(t.id),organizationId:String(t.organization_id),projectId:String(t.project_id),environmentId:Cr(t.environment_id),name:String(t.name),hostname:String(t.hostname),homeRegion:String(t.home_region),regions:Ld(t.regions,[]),trafficPolicy:String(t.traffic_policy),dataPolicy:Ld(t.data_policy,{replicate:[],maxLagSeconds:60,retainOnDestroy:!0}),status:String(t.status),activeRegion:String(t.active_region),revision:Cr(t.revision),version:Number(t.version),createdAt:String(t.created_at),updatedAt:String(t.updated_at)}),PA=(t)=>({id:String(t.id),topologyId:String(t.topology_id),region:String(t.region),role:String(t.role),provider:String(t.provider),stackId:Cr(t.stack_id),stackRevision:Cr(t.stack_revision),status:String(t.status),health:Ld(t.health,{}),lastHealthyAt:Cr(t.last_healthy_at),version:Number(t.version),createdAt:String(t.created_at),updatedAt:String(t.updated_at)}),jA=(t)=>({id:String(t.id),topologyId:String(t.topology_id),kind:String(t.kind),sourceRegion:String(t.source_region),targetRegion:String(t.target_region),config:Ld(t.config,{}),status:String(t.status),checkpoint:Cr(t.checkpoint),lagSeconds:t.lag_seconds==null?void 0:Number(t.lag_seconds),lastVerifiedAt:Cr(t.last_verified_at),version:Number(t.version),createdAt:String(t.created_at),updatedAt:String(t.updated_at)}),zA=(t)=>({id:String(t.id),topologyId:String(t.topology_id),hostname:String(t.hostname),dnsProvider:String(t.dns_provider),cdnEnabled:Number(t.cdn_enabled)===1,wafEnabled:Number(t.waf_enabled)===1,weights:Ld(t.weights,{}),desiredWeights:Ld(t.desired_weights,{}),status:String(t.status),providerState:Ld(t.provider_state,{}),version:Number(t.version),createdAt:String(t.created_at),updatedAt:String(t.updated_at)}),jD=(t)=>({id:String(t.id),topologyId:String(t.topology_id),operationId:Cr(t.operation_id),kind:String(t.kind),requestedRegion:Cr(t.requested_region),revision:Cr(t.revision),plan:Ld(t.plan,[]),currentStep:Cr(t.current_step),completedSteps:Ld(t.completed_steps,[]),status:String(t.status),error:Cr(t.error),createdAt:String(t.created_at),updatedAt:String(t.updated_at)});class FA{control;now;id;constructor(t,e=()=>new Date,r=()=>crypto.randomUUID()){this.control=t;this.now=e;this.id=r}create(t){return this.control.transaction(()=>{if(t.regions.length<2||new Set(t.regions.map((n)=>n.region)).size!==t.regions.length||t.regions.filter((n)=>n.role==="primary").length!==1)throw Error("A topology requires unique regions and exactly one primary.");let e=t.regions.find((n)=>n.role==="primary"),r=this.id(),d=this.now().toISOString();this.control.database.run("INSERT INTO regional_topologies (id,organization_id,project_id,environment_id,name,hostname,home_region,regions,traffic_policy,data_policy,status,active_region,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,'draft',?,?,?)",[r,t.organizationId,t.projectId,t.environmentId??null,t.name,t.hostname,e.region,JSON.stringify(t.regions),t.trafficPolicy,JSON.stringify(t.dataPolicy),e.region,d,d]);for(let n of t.regions)this.control.database.run("INSERT INTO regional_targets (id,topology_id,region,role,provider,status,created_at,updated_at) VALUES (?,?,?,?,?,'pending',?,?)",[this.id(),r,n.region,n.role,n.provider,d,d]);for(let n of t.dataPolicy.replicate)for(let c of t.regions)for(let _ of t.regions.filter((T)=>T.region!==c.region))this.control.database.run("INSERT INTO regional_replication_channels (id,topology_id,kind,source_region,target_region,config,status,created_at,updated_at) VALUES (?,?,?,?,?,?,'pending',?,?)",[this.id(),r,n,c.region,_.region,"{}",d,d]);let E=Object.fromEntries(t.regions.map((n)=>[n.region,n.region===e.region?100:0]));return this.control.database.run("INSERT INTO regional_traffic_routes (id,topology_id,hostname,dns_provider,cdn_enabled,waf_enabled,weights,desired_weights,status,created_at,updated_at) VALUES (?,?,?,?,?,?,?,?, 'pending',?,?)",[this.id(),r,t.hostname,t.dnsProvider??"route53",t.cdnEnabled?1:0,t.wafEnabled?1:0,JSON.stringify(E),JSON.stringify(E),d,d]),this.get(r)})}get(t){let e=this.control.database.query("SELECT * FROM regional_topologies WHERE id=?").get(t);return e?PD(e):void 0}list(t){return this.control.database.query("SELECT * FROM regional_topologies WHERE project_id=? ORDER BY name").all(t).map(PD)}targets(t){return this.control.database.query("SELECT * FROM regional_targets WHERE topology_id=? ORDER BY role,region").all(t).map(PA)}channels(t){return this.control.database.query("SELECT * FROM regional_replication_channels WHERE topology_id=? ORDER BY kind,target_region").all(t).map(jA)}route(t){let e=this.control.database.query("SELECT * FROM regional_traffic_routes WHERE topology_id=?").get(t);return e?zA(e):void 0}updateTopology(t,e){let r=this.get(t);if(!r)throw Error("Regional topology was not found.");let d={...r,...e},E=this.now().toISOString();return this.control.database.run("UPDATE regional_topologies SET status=?,active_region=?,revision=?,regions=?,version=version+1,updated_at=? WHERE id=?",[d.status,d.activeRegion,d.revision??null,JSON.stringify(d.regions),E,t]),this.get(t)}updateTarget(t,e){let r=this.control.database.query("SELECT * FROM regional_targets WHERE id=?").get(t);if(!r)throw Error("Regional target was not found.");let d=PA(r),E={...d,...e},n=this.now().toISOString();return this.control.database.run("UPDATE regional_targets SET role=?,stack_id=?,stack_revision=?,status=?,health=?,last_healthy_at=?,version=version+1,updated_at=? WHERE id=?",[E.role,E.stackId??null,E.stackRevision??null,E.status,JSON.stringify(E.health),E.lastHealthyAt??null,n,t]),PA(this.control.database.query("SELECT * FROM regional_targets WHERE id=?").get(t))}updateChannel(t,e){let r=this.control.database.query("SELECT * FROM regional_replication_channels WHERE id=?").get(t);if(!r)throw Error("Replication channel was not found.");let d=jA(r),E={...d,...e},n=this.now().toISOString();return this.control.database.run("UPDATE regional_replication_channels SET status=?,checkpoint=?,lag_seconds=?,last_verified_at=?,version=version+1,updated_at=? WHERE id=?",[E.status,E.checkpoint??null,E.lagSeconds??null,E.lastVerifiedAt??null,n,t]),jA(this.control.database.query("SELECT * FROM regional_replication_channels WHERE id=?").get(t))}updateRoute(t,e){let r=this.control.database.query("SELECT * FROM regional_traffic_routes WHERE id=?").get(t);if(!r)throw Error("Traffic route was not found.");let d=zA(r),E={...d,...e},n=this.now().toISOString();return this.control.database.run("UPDATE regional_traffic_routes SET weights=?,desired_weights=?,status=?,provider_state=?,version=version+1,updated_at=? WHERE id=?",[JSON.stringify(E.weights),JSON.stringify(E.desiredWeights),E.status,JSON.stringify(E.providerState),n,t]),zA(this.control.database.query("SELECT * FROM regional_traffic_routes WHERE id=?").get(t))}createExecution(t){let e=this.id(),r=this.now().toISOString();return this.control.database.run("INSERT INTO regional_executions (id,topology_id,operation_id,kind,requested_region,revision,plan,status,created_at,updated_at) VALUES (?,?,?,?,?,?,?,'queued',?,?)",[e,t.topologyId,t.operationId??null,t.kind,t.requestedRegion??null,t.revision??null,JSON.stringify(t.plan),r,r]),this.execution(e)}execution(t){let e=this.control.database.query("SELECT * FROM regional_executions WHERE id=?").get(t);return e?jD(e):void 0}executions(t){return this.control.database.query("SELECT * FROM regional_executions WHERE topology_id=? ORDER BY created_at DESC").all(t).map(jD)}updateExecution(t,e){let r=this.execution(t);if(!r)throw Error("Regional execution was not found.");let d={...r,...e},E=this.now().toISOString();return this.control.database.run("UPDATE regional_executions SET operation_id=?,current_step=?,completed_steps=?,status=?,error=?,updated_at=? WHERE id=?",[d.operationId??null,d.currentStep??null,JSON.stringify(d.completedSteps),d.status,d.error??null,E,t]),this.execution(t)}}class BA{store;queue;constructor(t,e){this.store=t;this.queue=e??new gt(t.control)}create(t){return this.store.create(t)}plan(t,e,r){if(!this.store.get(t))throw Error("Regional topology was not found.");let E=this.store.targets(t),n=this.store.channels(t);if(e==="rollout")return[...E.filter((c)=>c.role==="secondary").map((c)=>`apply:${c.region}`),...E.filter((c)=>c.role==="primary").map((c)=>`apply:${c.region}`),...n.map((c)=>`replicate:${c.kind}:${c.targetRegion}`),"traffic:activate"];if(e==="failover"||e==="failback")return[`health:${r}`,`replication:${r}`,`traffic:${r}`,`roles:${r}`];if(e==="destroy")return["traffic:drain",...E.filter((c)=>c.role==="secondary").map((c)=>`delete:${c.region}`),...E.filter((c)=>c.role==="primary").map((c)=>`delete:${c.region}`),"complete"];return["observe","repair"]}enqueue(t){let e=this.store.get(t.topologyId);if(!e)throw Error("Regional topology was not found.");if(["failover","failback"].includes(t.kind)&&(!t.targetRegion||!e.regions.some((n)=>n.region===t.targetRegion)))throw Error("A topology target region is required.");if(t.kind==="failover"&&t.targetRegion===e.activeRegion)throw Error("Target region is already active.");if((t.kind==="destroy"||t.deleteData)&&t.confirmation!==e.name)throw Error("Exact topology name confirmation is required.");if(t.deleteData&&e.dataPolicy.retainOnDestroy)throw Error("Topology policy requires regional data retention.");if(t.kind==="rollout"&&!/^[A-Za-z0-9._:@/-]{7,200}$/.test(t.revision??""))throw Error("An immutable revision is required.");let r=this.plan(e.id,t.kind,t.targetRegion),d=this.store.createExecution({topologyId:e.id,kind:t.kind,requestedRegion:t.targetRegion,revision:t.revision,plan:r}),E=this.queue.enqueue({projectId:e.projectId,environmentId:e.environmentId,kind:`region.${t.kind}`,input:{executionId:d.id,manifest:t.manifest??{},deleteData:t.deleteData===!0},lockKey:`regional-topology:${e.id}`,providerKey:"multi-region",timeoutSeconds:7200,cancellationMode:"provider_non_cancellable",resumePolicy:"requeue",maxAttempts:3}).operation;return this.store.updateExecution(d.id,{operationId:E.id}),{execution:this.store.execution(d.id),operation:E}}}var SP=(t)=>t&&typeof t==="object"&&!Array.isArray(t)?t:{};function zD(t,e){let r=(i)=>{let h=e.find((R)=>R.provider===i.provider);if(!h)throw Error(`No ${i.provider} regional driver is configured.`);return h},d=(i,h,R)=>{i.throwIfCancellationRequested(),i.checkpoint(R,R),t.updateExecution(h.id,{status:"running",currentStep:R,completedSteps:[...t.execution(h.id).completedSteps,R]})},E=async(i,h)=>{let R=t.route(i.id);if(!R)throw Error("Regional traffic route was not found.");let N=t.targets(i.id).find((u)=>u.region===i.activeRegion)??t.targets(i.id)[0];if(!N)throw Error("Regional traffic target was not found.");t.updateRoute(R.id,{status:"applying",desiredWeights:h});let A=await r(N).applyTraffic({route:t.route(i.id),topology:i,weights:h});t.updateRoute(R.id,{status:Object.values(h).every((u)=>u===0)?"drained":"in_sync",weights:h,providerState:A.providerState})},n=async(i,h,R,N)=>{t.updateTopology(R.id,{status:"provisioning"});let A=h.revision,u=N.manifest??{},f=t.targets(R.id).sort((I,a)=>Number(I.role==="primary")-Number(a.role==="primary"));for(let I of f){d(i,h,`apply:${I.region}`),t.updateTarget(I.id,{status:"provisioning"});let a=await r(I).applyStack({target:I,revision:A,manifest:u,signal:i.signal}),P=await r(I).health({target:t.updateTarget(I.id,{stackId:a.stackId,stackRevision:A})});if(!P.healthy)throw Error(`Regional health gate failed in ${I.region}.`);t.updateTarget(I.id,{status:"ready",health:P.evidence,lastHealthyAt:new Date().toISOString()})}for(let I of t.channels(R.id)){d(i,h,`replicate:${I.kind}:${I.targetRegion}`),t.updateChannel(I.id,{status:"configuring"});let a=f.find((H)=>H.region===I.sourceRegion),P=await r(a).configureReplication({channel:I,topology:R}),j=await r(a).verifyReplication({channel:t.updateChannel(I.id,{checkpoint:P.checkpoint,lagSeconds:P.lagSeconds}),topology:R});if(!j.healthy||j.lagSeconds>R.dataPolicy.maxLagSeconds)throw Error(`${I.kind} replication to ${I.targetRegion} exceeds the RPO.`);t.updateChannel(I.id,{status:"in_sync",checkpoint:j.checkpoint,lagSeconds:j.lagSeconds,lastVerifiedAt:new Date().toISOString()})}d(i,h,"traffic:activate");let w=Object.fromEntries(R.regions.map((I)=>[I.region,I.region===R.activeRegion?100:0]));return await E(R,w),t.updateTopology(R.id,{status:"ready",revision:A}),{revision:A,activeRegion:R.activeRegion}},c=async(i,h,R)=>{let N=h.requestedRegion,A=t.targets(R.id).find((w)=>w.region===N);if(!A)throw Error("Requested regional target was not found.");t.updateTopology(R.id,{status:h.kind==="failover"?"failing_over":"failing_back"}),d(i,h,`health:${N}`);let u=await r(A).health({target:A});if(!u.healthy)throw Error(`Target region ${N} is unhealthy.`);t.updateTarget(A.id,{status:"ready",health:u.evidence,lastHealthyAt:new Date().toISOString()}),d(i,h,`replication:${N}`);for(let w of t.channels(R.id).filter((I)=>I.targetRegion===N)){let I=await r(A).verifyReplication({channel:w,topology:R});if(!I.healthy||I.lagSeconds>R.dataPolicy.maxLagSeconds)throw Error(`${w.kind} replication is outside the failover RPO.`);t.updateChannel(w.id,{status:"in_sync",checkpoint:I.checkpoint,lagSeconds:I.lagSeconds,lastVerifiedAt:new Date().toISOString()})}d(i,h,`traffic:${N}`),await E(R,Object.fromEntries(R.regions.map((w)=>[w.region,w.region===N?100:0]))),d(i,h,`roles:${N}`);let f=R.regions.map((w)=>({...w,role:w.region===N?"primary":"secondary"}));for(let w of t.targets(R.id))t.updateTarget(w.id,{role:w.region===N?"primary":"secondary"});return t.updateTopology(R.id,{status:h.kind==="failover"?"failed_over":"ready",activeRegion:N,regions:f}),{activeRegion:N}},_=async(i,h,R,N)=>{t.updateTopology(R.id,{status:"destroying"}),d(i,h,"traffic:drain"),await E(R,Object.fromEntries(R.regions.map((u)=>[u.region,0])));let A=N.deleteData!==!0;for(let u of t.targets(R.id).sort((f,w)=>Number(f.role==="primary")-Number(w.role==="primary")))d(i,h,`delete:${u.region}`),t.updateTarget(u.id,{status:"deleting"}),await r(u).deleteStack({target:u,retainData:A,signal:i.signal}),t.updateTarget(u.id,{status:"deleted"});return d(i,h,"complete"),t.updateTopology(R.id,{status:"destroyed"}),{destroyed:!0,dataRetained:A}},T=async(i)=>{let h=SP(i.operation.input),R=t.execution(String(h.executionId??""));if(!R)throw Error("Regional execution was not found.");let N=t.get(R.topologyId);if(!N)throw Error("Regional topology was not found.");try{let A;if(R.kind==="rollout")A=await n(i,R,N,h);else if(R.kind==="failover"||R.kind==="failback")A=await c(i,R,N);else if(R.kind==="destroy")A=await _(i,R,N,h);else throw Error("Regional reconciliation is not configured.");return t.updateExecution(R.id,{status:"succeeded",currentStep:void 0}),{executionId:R.id,...A}}catch(A){if(t.updateExecution(R.id,{status:i.cancellationRequested()?"cancelled":"failed",error:A instanceof Error?A.message:String(A)}),t.get(N.id)?.status!=="destroyed")t.updateTopology(N.id,{status:"failed"});throw A}};return{"region.rollout":T,"region.failover":T,"region.failback":T,"region.destroy":T,"region.reconcile":T}}class JA{provider;reason;constructor(t,e="Configure a regional provider transport before executing this operation."){this.provider=t;this.reason=e}fail(){throw Error(this.reason)}async applyStack(){return this.fail()}async deleteStack(){this.fail()}async health(){return this.fail()}async configureReplication(){return this.fail()}async verifyReplication(){return this.fail()}async applyTraffic(){return this.fail()}}function xr(t,e,r){return[t,e,r].map((d)=>encodeURIComponent(d)).join(":")}function NP(t){return Object.fromEntries(["start","stop","restart","redeploy","scale","logs","exec","inspect","files"].map((e)=>[e,{supported:!1,reason:t}]))}function QE(t,e,r=["exec","files"]){let d=NP(e);for(let E of t)d[E]={supported:!0,requiresConfirmation:!["logs","inspect"].includes(E),requiresRecentAuth:r.includes(E)};return d}var AP=/(?:secret|password|passwd|token|api[_-]?key|private[_-]?key|credential|authorization|cookie)/i;function Od(t){let e=String(t??"").trim().toLowerCase();if(["active","running","ready","healthy","available","steady","active:running"].includes(e))return"running";if(["activating","pending","provisioning","starting","created","initializing"].includes(e))return"starting";if(["deactivating","stopping","draining","terminating"].includes(e))return"stopping";if(["inactive","stopped","complete","completed","exited","disabled"].includes(e))return"stopped";if(["degraded","unhealthy","warning"].includes(e))return"degraded";if(["failed","dead","error","crashed","oomkilled"].includes(e))return"failed";return"unknown"}function ud(t){if(Array.isArray(t))return t.map((r)=>ud(r));if(!t||typeof t!=="object")return t;let e={};for(let[r,d]of Object.entries(t))e[r]=AP.test(r)?"[REDACTED]":ud(d);return e}function YE(t,e=new Date){if(!t)return;let r=new Date(t).getTime();return Number.isFinite(r)?Math.max(0,Math.floor((e.getTime()-r)/1000)):void 0}function FD(t){let e=Number(t);return Number.isFinite(e)&&e>=0?e:void 0}function LP(t){let e=String(t?.message??t);if(/(?:unauthorized|accessdenied|forbidden|credentials)/i.test(e))return"unauthorized";if(/(?:timeout|unreachable|econnrefused|enotfound|network)/i.test(e))return"unreachable";return"error"}async function BD(t,e={},r={}){let d=e.now??new Date,E=Math.max(100,r.timeoutMs??1e4),n=Math.max(1,r.staleAfterSeconds??60),c=await Promise.all(t.map(async(T)=>{try{let i=await Promise.race([T.discover({...e,now:d}),new Promise((h,R)=>setTimeout(()=>R(Error(`Runtime source ${T.id} timed out after ${E}ms`)),E))]);return{workloads:i,source:{id:T.id,provider:T.provider,status:"fresh",discoveredAt:d.toISOString(),staleAfterSeconds:n,itemCount:i.length}}}catch(i){return{workloads:[],source:{id:T.id,provider:T.provider,status:LP(i),discoveredAt:d.toISOString(),staleAfterSeconds:n,itemCount:0,message:String(i?.message??i).slice(0,500)}}}})),_=c.map((T)=>T.source);return{generatedAt:d.toISOString(),workloads:c.flatMap((T)=>T.workloads).sort((T,i)=>T.name.localeCompare(i.name)||T.id.localeCompare(i.id)),sources:_,degraded:_.some((T)=>T.status!=="fresh")}}await Ht();Lt();tr();Lt();class qr{client;region;constructor(t="us-east-1",e){this.region=t,this.client=new dt(void 0,{profile:e})}async createStack(t){let e={Action:"CreateStack",StackName:t.stackName,Version:"2010-05-15"};if(t.templateBody)e.TemplateBody=t.templateBody;else if(t.templateUrl)e.TemplateURL=t.templateUrl;else throw Error("Either templateBody or templateUrl must be provided");if(t.parameters)t.parameters.forEach((d,E)=>{e[`Parameters.member.${E+1}.ParameterKey`]=d.ParameterKey,e[`Parameters.member.${E+1}.ParameterValue`]=d.ParameterValue});if(t.capabilities)t.capabilities.forEach((d,E)=>{e[`Capabilities.member.${E+1}`]=d});if(t.roleArn)e.RoleARN=t.roleArn;if(t.tags)t.tags.forEach((d,E)=>{e[`Tags.member.${E+1}.Key`]=d.Key,e[`Tags.member.${E+1}.Value`]=d.Value});if(t.timeoutInMinutes)e.TimeoutInMinutes=t.timeoutInMinutes;if(t.onFailure)e.OnFailure=t.onFailure;let r=await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(e).toString()});return{StackId:r.StackId||r.CreateStackResult?.StackId}}async updateStack(t){let e={Action:"UpdateStack",StackName:t.stackName,Version:"2010-05-15"};if(t.templateBody)e.TemplateBody=t.templateBody;else if(t.templateUrl)e.TemplateURL=t.templateUrl;if(t.parameters)t.parameters.forEach((d,E)=>{if(e[`Parameters.member.${E+1}.ParameterKey`]=d.ParameterKey,d.UsePreviousValue)e[`Parameters.member.${E+1}.UsePreviousValue`]="true";else e[`Parameters.member.${E+1}.ParameterValue`]=d.ParameterValue});if(t.capabilities)t.capabilities.forEach((d,E)=>{e[`Capabilities.member.${E+1}`]=d});if(t.roleArn)e.RoleARN=t.roleArn;if(t.tags)t.tags.forEach((d,E)=>{e[`Tags.member.${E+1}.Key`]=d.Key,e[`Tags.member.${E+1}.Value`]=d.Value});let r=await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(e).toString()});return{StackId:r.StackId||r.UpdateStackResult?.StackId}}async deleteStack(t,e,r){let d={Action:"DeleteStack",StackName:t,Version:"2010-05-15"};if(e)d.RoleARN=e;if(r&&r.length>0)r.forEach((E,n)=>{d[`RetainResources.member.${n+1}`]=E});await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(d).toString()})}async describeStacks(t={}){let e={Action:"DescribeStacks",Version:"2010-05-15"};if(t.stackName)e.StackName=t.stackName;let r=await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(e).toString()});return{Stacks:this.parseStacksResponse(r)}}async describeStackEvents(t){let e={Action:"DescribeStackEvents",StackName:t,Version:"2010-05-15"},r=await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(e).toString()});return{StackEvents:this.parseStackEvents(r)}}async listStackResources(t){let e={Action:"ListStackResources",StackName:t,Version:"2010-05-15"},d=(await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(e).toString()}))?.ListStackResourcesResult?.StackResourceSummaries?.member,E=[];if(d)E=Array.isArray(d)?d:[d];return{StackResourceSummaries:E}}async waitForStack(t,e){let r={"stack-create-complete":["CREATE_COMPLETE"],"stack-update-complete":["UPDATE_COMPLETE"],"stack-delete-complete":["DELETE_COMPLETE"]},d=["CREATE_FAILED","ROLLBACK_FAILED","ROLLBACK_COMPLETE","UPDATE_ROLLBACK_FAILED","UPDATE_ROLLBACK_COMPLETE"],E=r[e],n=360,c=0;while(c<360)try{let _=await this.describeStacks({stackName:t});if(_.Stacks.length===0){if(e==="stack-delete-complete")return;if(c%10===0)console.log(`[waitForStack] Attempt ${c}: Stack not visible yet`);await new Promise((i)=>setTimeout(i,2000)),c++;continue}let T=_.Stacks[0];if(c%10===0)console.log(`[waitForStack] Attempt ${c}: Status = ${T.StackStatus}${T.StackStatusReason?` (${T.StackStatusReason})`:""}`);if(E.includes(T.StackStatus))return;if((e==="stack-create-complete"||e==="stack-update-complete")&&(T.StackStatus==="DELETE_IN_PROGRESS"||T.StackStatus==="DELETE_COMPLETE")){console.log("[waitForStack] Stack is being deleted (creation/update failed)");let i="";try{let R=await this.describeStackEvents(t);console.log("[waitForStack] Stack events (most recent first):");for(let N of R.StackEvents.slice(0,15))if(N.ResourceStatus.includes("FAILED")||N.ResourceStatusReason){if(console.log(` ${N.LogicalResourceId}: ${N.ResourceStatus} - ${N.ResourceStatusReason||"No reason provided"}`),N.ResourceStatus.includes("FAILED")&&N.ResourceStatusReason&&!i)i=N.ResourceStatusReason}}catch{}let h=i||T.StackStatusReason||"Check CloudFormation console for details.";throw Error(`Stack creation/update failed - stack is being deleted. Reason: ${h}`)}if(T.StackStatus==="DELETE_FAILED"&&e==="stack-delete-complete"){let i=Error("Stack deletion failed - may have resources that need to be retained");throw i.code="DELETE_FAILED",i.stackStatus=T.StackStatus,i.statusReason=T.StackStatusReason,i}if(d.includes(T.StackStatus))throw Error(`Stack reached failure status: ${T.StackStatus}`);await new Promise((i)=>setTimeout(i,5000)),c++}catch(_){if(e==="stack-delete-complete"&&_.message?.includes("does not exist"))return;if(e==="stack-create-complete"&&_.message?.includes("does not exist")){if(c%10===0)console.log(`[waitForStack] Attempt ${c}: Stack does not exist (error), retrying...`);await new Promise((T)=>setTimeout(T,2000)),c++;continue}throw console.log(`[waitForStack] Unexpected error: ${_.message}`),_}throw console.log(`[waitForStack] Timeout after ${c} attempts`),Error(`Timeout waiting for stack to reach ${e}`)}async validateTemplate(t){let e={Action:"ValidateTemplate",TemplateBody:t,Version:"2010-05-15"};return await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(e).toString()})}async listStacks(t){let e={Action:"ListStacks",Version:"2010-05-15"};if(t)t.forEach((_,T)=>{e[`StackStatusFilter.member.${T+1}`]=_});let r=await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(e).toString()}),d=r.ListStacksResponse||r,E=d.ListStacksResult||d,n=E.StackSummaries?.member||E.StackSummaries||[];return{StackSummaries:(Array.isArray(n)?n:n?[n]:[]).map((_)=>({StackId:_.StackId||"",StackName:_.StackName||"",TemplateDescription:_.TemplateDescription,CreationTime:_.CreationTime||"",LastUpdatedTime:_.LastUpdatedTime,DeletionTime:_.DeletionTime,StackStatus:_.StackStatus||""}))}}async createChangeSet(t){let e={Action:"CreateChangeSet",StackName:t.stackName,ChangeSetName:t.changeSetName,Version:"2010-05-15"};if(t.templateBody)e.TemplateBody=t.templateBody;else if(t.templateUrl)e.TemplateURL=t.templateUrl;if(t.parameters)t.parameters.forEach((d,E)=>{e[`Parameters.member.${E+1}.ParameterKey`]=d.ParameterKey,e[`Parameters.member.${E+1}.ParameterValue`]=d.ParameterValue});if(t.capabilities)t.capabilities.forEach((d,E)=>{e[`Capabilities.member.${E+1}`]=d});if(t.changeSetType)e.ChangeSetType=t.changeSetType;let r=await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(e).toString()});return{Id:r.Id,StackId:r.StackId}}async describeChangeSet(t,e){let r={Action:"DescribeChangeSet",StackName:t,ChangeSetName:e,Version:"2010-05-15"};return await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(r).toString()})}async executeChangeSet(t,e){let r={Action:"ExecuteChangeSet",StackName:t,ChangeSetName:e,Version:"2010-05-15"};await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(r).toString()})}async deleteChangeSet(t,e){let r={Action:"DeleteChangeSet",StackName:t,ChangeSetName:e,Version:"2010-05-15"};await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(r).toString()})}async getStackOutputs(t){let e=await this.describeStacks({stackName:t});if(!e.Stacks||e.Stacks.length===0)throw Error(`Stack ${t} not found`);let r=e.Stacks[0],d={};if(r.Outputs)for(let E of r.Outputs)d[E.OutputKey]=E.OutputValue;return d}async getTemplate(t){let e={Action:"GetTemplate",StackName:t,Version:"2010-05-15"},r=await this.client.request({service:"cloudformation",region:this.region,method:"POST",path:"/",body:new URLSearchParams(e).toString()});return{TemplateBody:r?.GetTemplateResult?.TemplateBody||r?.TemplateBody||""}}parseStacksResponse(t){let e=[],r=t?.DescribeStacksResult?.Stacks?.member||t?.Stacks?.member||t?.Stacks||t;if(r&&!Array.isArray(r))r=[r];if(Array.isArray(r)){for(let d of r)if(d.StackId||d.StackName){let E;if(d.Outputs?.member)E=(Array.isArray(d.Outputs.member)?d.Outputs.member:[d.Outputs.member]).map((c)=>({OutputKey:c.OutputKey,OutputValue:c.OutputValue,Description:c.Description,ExportName:c.ExportName}));e.push({StackId:d.StackId,StackName:d.StackName,StackStatus:d.StackStatus,CreationTime:d.CreationTime,LastUpdatedTime:d.LastUpdatedTime,StackStatusReason:d.StackStatusReason,Outputs:E})}}else if(t.StackId)e.push({StackId:t.StackId,StackName:t.StackName,StackStatus:t.StackStatus,CreationTime:t.CreationTime,LastUpdatedTime:t.LastUpdatedTime});return e}parseStackEvents(t){let e=[],r=t?.DescribeStackEventsResult?.StackEvents?.member||t?.StackEvents?.member||t?.StackEvents||[];if(r&&!Array.isArray(r))r=[r];for(let d of r)if(d.LogicalResourceId)e.push({Timestamp:d.Timestamp,ResourceType:d.ResourceType,LogicalResourceId:d.LogicalResourceId,ResourceStatus:d.ResourceStatus,ResourceStatusReason:d.ResourceStatusReason});return e}async waitForStackWithProgress(t,e,r){let d={"stack-create-complete":["CREATE_COMPLETE"],"stack-update-complete":["UPDATE_COMPLETE"],"stack-delete-complete":["DELETE_COMPLETE"]},E=["CREATE_FAILED","ROLLBACK_FAILED","ROLLBACK_COMPLETE","UPDATE_ROLLBACK_FAILED","UPDATE_ROLLBACK_COMPLETE"],n=d[e],c=360,_=0,T=new Set;while(_<360)try{if(r)try{let N=[...(await this.describeStackEvents(t)).StackEvents||[]].reverse();for(let A of N){let u=`${A.LogicalResourceId}-${A.ResourceStatus}-${A.Timestamp}`;if(!T.has(u))T.add(u),r({resourceId:A.LogicalResourceId,resourceType:A.ResourceType,status:A.ResourceStatus,reason:A.ResourceStatusReason,timestamp:A.Timestamp})}}catch{}let i=await this.describeStacks({stackName:t});if(i.Stacks.length===0){if(e==="stack-delete-complete")return;await new Promise((R)=>setTimeout(R,2000)),_++;continue}let h=i.Stacks[0];if(n.includes(h.StackStatus))return;if(h.StackStatus==="DELETE_FAILED"&&e==="stack-delete-complete"){let R=Error("Stack deletion failed - may have resources that need to be retained");throw R.code="DELETE_FAILED",R.stackStatus=h.StackStatus,R.statusReason=h.StackStatusReason,R}if(E.includes(h.StackStatus))throw Error(`Stack reached failure status: ${h.StackStatus}`);await new Promise((R)=>setTimeout(R,3000)),_++}catch(i){if(e==="stack-delete-complete"&&i.message?.includes("does not exist"))return;if(e==="stack-create-complete"&&i.message?.includes("does not exist")){await new Promise((h)=>setTimeout(h,2000)),_++;continue}throw i}throw Error(`Timeout waiting for stack to reach ${e}`)}async waitForStackComplete(t,e=120,r=5000){let d=["CREATE_COMPLETE","UPDATE_COMPLETE","DELETE_COMPLETE"],E=["CREATE_FAILED","UPDATE_FAILED","DELETE_FAILED","ROLLBACK_COMPLETE","ROLLBACK_FAILED","UPDATE_ROLLBACK_COMPLETE","UPDATE_ROLLBACK_FAILED"];for(let n=0;n<e;n++)try{let c=await this.describeStacks({stackName:t});if(c.Stacks.length===0)return{success:!0,status:"DELETE_COMPLETE"};let _=c.Stacks[0],T=_.StackStatus;if(d.includes(T))return{success:!0,status:T};if(E.includes(T))return{success:!1,status:T,reason:_.StackStatusReason};await new Promise((i)=>setTimeout(i,r))}catch(c){if(c.message?.includes("does not exist"))return{success:!0,status:"DELETE_COMPLETE"};throw c}return{success:!1,status:"TIMEOUT",reason:"Timeout waiting for stack operation"}}}Lt();import{createHash as uP}from"node:crypto";import{existsSync as OP,mkdirSync as CP,readdirSync as PG,readFileSync as lP,rmSync as jG,writeFileSync as IP}from"node:fs";import{homedir as DP}from"node:os";import{join as I_}from"node:path";var JD=1,HD=3600000,fP=24*HD,UP=HD,wP=30*fP;function gP(){let t=process.env.XDG_CACHE_HOME;return I_(t&&t.trim()?t:I_(DP(),".cache"),"ts-cloud","cost-explorer")}function WD(t){return I_(gP(),t??"__default__")}function vD(t){let e={s:t.start,e:t.end,g:t.granularity,m:[...t.metrics].sort(),gb:[...t.groupBy].map((r)=>`${r.Type}:${r.Key}`).sort(),f:t.filter??null};return uP("sha256").update(JSON.stringify(e)).digest("hex").slice(0,24)}function $P(t,e){let r=Date.parse(`${e}T00:00:00Z`);if(Number.isNaN(r))return!1;let d=new Date,E=Date.UTC(d.getUTCFullYear(),d.getUTCMonth(),1);return r<=E}function yP(t){return $P(t.start,t.end)?wP:UP}function QD(t,e){let r=I_(WD(t),`${vD(e)}.json`);if(!OP(r))return null;let d;try{d=JSON.parse(lP(r,"utf-8"))}catch{return null}if(d.schema!==JD)return null;let E=Date.now()-d.savedAt;if(E<0||E>yP(e))return null;return{response:d.response,ageSeconds:Math.floor(E/1000)}}function YD(t,e,r){let d=WD(t);CP(d,{recursive:!0});let E={schema:JD,savedAt:Date.now(),key:e,response:r};IP(I_(d,`${vD(e)}.json`),JSON.stringify(E))}class HA{client;profile;useCache;lastCacheAgeSeconds=null;constructor(t,e){this.profile=t,this.useCache=e?.useCache??!0,this.client=new dt(an(t))}async getCostByService(t){return(await this.getCostByDimension({...t,dimension:"SERVICE"})).map((r)=>({service:r.key,amount:r.amount,unit:r.unit}))}async getCostByDimension(t){let{start:e,end:r,dimension:d,granularity:E="MONTHLY",filter:n}=t,c=["UnblendedCost"],_=[{Type:"DIMENSION",Key:d}],T={start:e,end:r,granularity:E,metrics:c,groupBy:_,filter:n};if(this.useCache){let N=QD(this.profile,T);if(N)return this.lastCacheAgeSeconds=N.ageSeconds,N.response}this.lastCacheAgeSeconds=null;let i=new Map,h;do{let N={TimePeriod:{Start:e,End:r},Granularity:E,Metrics:c,GroupBy:_};if(n)N.Filter=n;if(h)N.NextPageToken=h;let A=await this.client.request({service:"ce",region:"us-east-1",method:"POST",path:"/",headers:{"content-type":"application/x-amz-json-1.1","x-amz-target":"AWSInsightsIndexService.GetCostAndUsage"},body:JSON.stringify(N)});for(let u of A?.ResultsByTime??[])for(let f of u?.Groups??[]){let w=f.Keys?.[0]??"Unknown",I=Number.parseFloat(f.Metrics?.UnblendedCost?.Amount??"0"),a=f.Metrics?.UnblendedCost?.Unit??"USD",P=i.get(w);i.set(w,{key:w,amount:(P?.amount??0)+I,unit:a})}h=A?.NextPageToken||void 0}while(h);let R=[...i.values()].filter((N)=>N.amount>0).sort((N,A)=>A.amount-N.amount);if(this.useCache)YD(this.profile,T,R);return R}async getDailyTotals(t){return((await this.client.request({service:"ce",region:"us-east-1",method:"POST",path:"/",headers:{"content-type":"application/x-amz-json-1.1","x-amz-target":"AWSInsightsIndexService.GetCostAndUsage"},body:JSON.stringify({TimePeriod:{Start:t.start,End:t.end},Granularity:"DAILY",Metrics:["UnblendedCost"]})}))?.ResultsByTime??[]).map((d)=>Number.parseFloat(d.Total?.UnblendedCost?.Amount??"0"))}}Lt();class D_{client;region;constructor(t="us-east-1"){this.region=t,this.client=new dt}async describeInstances(t){let e={Action:"DescribeInstances",Version:"2016-11-15"};if(t?.InstanceIds)t.InstanceIds.forEach((E,n)=>{e[`InstanceId.${n+1}`]=E});if(t?.Filters)t.Filters.forEach((E,n)=>{e[`Filter.${n+1}.Name`]=E.Name,E.Values.forEach((c,_)=>{e[`Filter.${n+1}.Value.${_+1}`]=c})});if(t?.MaxResults)e.MaxResults=String(t.MaxResults);if(t?.NextToken)e.NextToken=t.NextToken;let r=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(e).toString()}),d=r.DescribeInstancesResponse||r;return{Reservations:this.parseReservations(d.reservationSet?.item),NextToken:d.nextToken}}async getInstance(t){return(await this.describeInstances({InstanceIds:[t]})).Reservations?.[0]?.Instances?.[0]}async getConsoleOutput(t,e){let r={Action:"GetConsoleOutput",Version:"2016-11-15",InstanceId:t};if(e)r.Latest="true";let d=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(r).toString()}),E=d.GetConsoleOutputResponse||d;return{InstanceId:E.instanceId,Output:E.output,Timestamp:E.timestamp}}async getConsoleOutputDecoded(t,e){let r=await this.getConsoleOutput(t,e?.latest);if(!r.Output)return"No console output available yet";let d=Buffer.from(r.Output,"base64").toString("utf-8");if(e?.tailLines)return d.split(`
|
|
5623
5623
|
`).slice(-e.tailLines).join(`
|
|
5624
5624
|
`);return d}async describeInstanceStatus(t){let e={Action:"DescribeInstanceStatus",Version:"2016-11-15"};if(t?.InstanceIds)t.InstanceIds.forEach((d,E)=>{e[`InstanceId.${E+1}`]=d});if(t?.IncludeAllInstances)e.IncludeAllInstances="true";if(t?.Filters)t.Filters.forEach((d,E)=>{e[`Filter.${E+1}.Name`]=d.Name,d.Values.forEach((n,c)=>{e[`Filter.${E+1}.Value.${c+1}`]=n})});let r=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(e).toString()});return{InstanceStatuses:this.parseArray(r.instanceStatusSet?.item).map((d)=>({InstanceId:d.instanceId,InstanceState:d.instanceState?{Code:Number.parseInt(d.instanceState.code),Name:d.instanceState.name}:void 0,InstanceStatus:d.instanceStatus?{Status:d.instanceStatus.status,Details:this.parseArray(d.instanceStatus.details?.item).map((E)=>({Name:E.name,Status:E.status}))}:void 0,SystemStatus:d.systemStatus?{Status:d.systemStatus.status,Details:this.parseArray(d.systemStatus.details?.item).map((E)=>({Name:E.name,Status:E.status}))}:void 0}))}}async startInstances(t){let e={Action:"StartInstances",Version:"2016-11-15"};t.forEach((d,E)=>{e[`InstanceId.${E+1}`]=d});let r=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(e).toString()});return{StartingInstances:this.parseArray(r.instancesSet?.item).map((d)=>({InstanceId:d.instanceId,CurrentState:d.currentState?{Name:d.currentState.name}:void 0,PreviousState:d.previousState?{Name:d.previousState.name}:void 0}))}}async stopInstances(t,e){let r={Action:"StopInstances",Version:"2016-11-15"};if(t.forEach((E,n)=>{r[`InstanceId.${n+1}`]=E}),e)r.Force="true";let d=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(r).toString()});return{StoppingInstances:this.parseArray(d.instancesSet?.item).map((E)=>({InstanceId:E.instanceId,CurrentState:E.currentState?{Name:E.currentState.name}:void 0,PreviousState:E.previousState?{Name:E.previousState.name}:void 0}))}}async rebootInstances(t){let e={Action:"RebootInstances",Version:"2016-11-15"};t.forEach((r,d)=>{e[`InstanceId.${d+1}`]=r}),await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(e).toString()})}async terminateInstances(t){let e={Action:"TerminateInstances",Version:"2016-11-15"};t.forEach((d,E)=>{e[`InstanceId.${E+1}`]=d});let r=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(e).toString()});return{TerminatingInstances:this.parseArray(r.instancesSet?.item).map((d)=>({InstanceId:d.instanceId,CurrentState:d.currentState?{Name:d.currentState.name}:void 0,PreviousState:d.previousState?{Name:d.previousState.name}:void 0}))}}async createImage(t){let e={Action:"CreateImage",Version:"2016-11-15",InstanceId:t.InstanceId,Name:t.Name};if(t.Description)e.Description=t.Description;if(t.NoReboot!==void 0)e.NoReboot=String(t.NoReboot);if(t.TagSpecifications)t.TagSpecifications.forEach((E,n)=>{e[`TagSpecification.${n+1}.ResourceType`]=E.ResourceType,E.Tags.forEach((c,_)=>{e[`TagSpecification.${n+1}.Tag.${_+1}.Key`]=c.Key,e[`TagSpecification.${n+1}.Tag.${_+1}.Value`]=c.Value})});let r=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(e).toString()});return{ImageId:(r.CreateImageResponse||r).imageId}}async deregisterImage(t){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:t}).toString()})}async describeVpcs(t){let e={Action:"DescribeVpcs",Version:"2016-11-15"};if(t?.VpcIds)t.VpcIds.forEach((d,E)=>{e[`VpcId.${E+1}`]=d});if(t?.Filters)t.Filters.forEach((d,E)=>{e[`Filter.${E+1}.Name`]=d.Name,d.Values.forEach((n,c)=>{e[`Filter.${E+1}.Value.${c+1}`]=n})});let r=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(e).toString()});return{Vpcs:this.parseArray(r.vpcSet?.item).map((d)=>({VpcId:d.vpcId,CidrBlock:d.cidrBlock,State:d.state,DhcpOptionsId:d.dhcpOptionsId,InstanceTenancy:d.instanceTenancy,IsDefault:d.isDefault==="true",Tags:this.parseTags(d.tagSet?.item)}))}}async describeSubnets(t){let e={Action:"DescribeSubnets",Version:"2016-11-15"};if(t?.SubnetIds)t.SubnetIds.forEach((d,E)=>{e[`SubnetId.${E+1}`]=d});if(t?.Filters)t.Filters.forEach((d,E)=>{e[`Filter.${E+1}.Name`]=d.Name,d.Values.forEach((n,c)=>{e[`Filter.${E+1}.Value.${c+1}`]=n})});let r=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(e).toString()});return{Subnets:this.parseArray(r.subnetSet?.item).map((d)=>({SubnetId:d.subnetId,VpcId:d.vpcId,CidrBlock:d.cidrBlock,AvailabilityZone:d.availabilityZone,AvailableIpAddressCount:Number.parseInt(d.availableIpAddressCount),State:d.state,MapPublicIpOnLaunch:d.mapPublicIpOnLaunch==="true",Tags:this.parseTags(d.tagSet?.item)}))}}async describeSecurityGroups(t){let e={Action:"DescribeSecurityGroups",Version:"2016-11-15"};if(t?.GroupIds)t.GroupIds.forEach((d,E)=>{e[`GroupId.${E+1}`]=d});if(t?.GroupNames)t.GroupNames.forEach((d,E)=>{e[`GroupName.${E+1}`]=d});if(t?.Filters)t.Filters.forEach((d,E)=>{e[`Filter.${E+1}.Name`]=d.Name,d.Values.forEach((n,c)=>{e[`Filter.${E+1}.Value.${c+1}`]=n})});let r=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(e).toString()});return{SecurityGroups:this.parseArray(r.securityGroupInfo?.item).map((d)=>({GroupId:d.groupId,GroupName:d.groupName,Description:d.groupDescription,VpcId:d.vpcId,IpPermissions:this.parseIpPermissions(d.ipPermissions?.item),IpPermissionsEgress:this.parseIpPermissions(d.ipPermissionsEgress?.item),Tags:this.parseTags(d.tagSet?.item)}))}}async describeInternetGateways(t){let e={Action:"DescribeInternetGateways",Version:"2016-11-15"};if(t?.InternetGatewayIds)t.InternetGatewayIds.forEach((d,E)=>{e[`InternetGatewayId.${E+1}`]=d});if(t?.Filters)t.Filters.forEach((d,E)=>{e[`Filter.${E+1}.Name`]=d.Name,d.Values.forEach((n,c)=>{e[`Filter.${E+1}.Value.${c+1}`]=n})});let r=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(e).toString()});return{InternetGateways:this.parseArray(r.internetGatewaySet?.item).map((d)=>({InternetGatewayId:d.internetGatewayId,Attachments:this.parseArray(d.attachmentSet?.item).map((E)=>({VpcId:E.vpcId,State:E.state})),Tags:this.parseTags(d.tagSet?.item)}))}}async describeAddresses(t){let e={Action:"DescribeAddresses",Version:"2016-11-15"};if(t?.AllocationIds)t.AllocationIds.forEach((d,E)=>{e[`AllocationId.${E+1}`]=d});if(t?.PublicIps)t.PublicIps.forEach((d,E)=>{e[`PublicIp.${E+1}`]=d});if(t?.Filters)t.Filters.forEach((d,E)=>{e[`Filter.${E+1}.Name`]=d.Name,d.Values.forEach((n,c)=>{e[`Filter.${E+1}.Value.${c+1}`]=n})});let r=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(e).toString()});return{Addresses:this.parseArray(r.addressesSet?.item).map((d)=>({PublicIp:d.publicIp,AllocationId:d.allocationId,AssociationId:d.associationId,InstanceId:d.instanceId,NetworkInterfaceId:d.networkInterfaceId,PrivateIpAddress:d.privateIpAddress,Domain:d.domain,Tags:this.parseTags(d.tagSet?.item)}))}}async allocateAddress(t){let e={Action:"AllocateAddress",Version:"2016-11-15"};if(t?.Domain)e.Domain=t.Domain;if(t?.TagSpecifications)t.TagSpecifications.forEach((d,E)=>{e[`TagSpecification.${E+1}.ResourceType`]=d.ResourceType,d.Tags.forEach((n,c)=>{e[`TagSpecification.${E+1}.Tag.${c+1}.Key`]=n.Key,e[`TagSpecification.${E+1}.Tag.${c+1}.Value`]=n.Value})});let r=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(e).toString()});return{AllocationId:r.allocationId,PublicIp:r.publicIp,Domain:r.domain}}async associateAddress(t){let e={Action:"AssociateAddress",Version:"2016-11-15"};if(t.AllocationId)e.AllocationId=t.AllocationId;if(t.PublicIp)e.PublicIp=t.PublicIp;if(t.InstanceId)e.InstanceId=t.InstanceId;if(t.NetworkInterfaceId)e.NetworkInterfaceId=t.NetworkInterfaceId;if(t.PrivateIpAddress)e.PrivateIpAddress=t.PrivateIpAddress;if(t.AllowReassociation)e.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(e).toString()})).associationId}}async createTags(t){let e={Action:"CreateTags",Version:"2016-11-15"};t.Resources.forEach((r,d)=>{e[`ResourceId.${d+1}`]=r}),t.Tags.forEach((r,d)=>{e[`Tag.${d+1}.Key`]=r.Key,e[`Tag.${d+1}.Value`]=r.Value}),await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(e).toString()})}async waitForInstanceState(t,e,r){let d=r?.maxWaitMs||300000,E=r?.pollIntervalMs||5000,n=Date.now();while(Date.now()-n<d){let c;try{c=await this.getInstance(t)}catch{c=void 0}if(c?.State?.Name===e)return c;await new Promise((_)=>setTimeout(_,E))}return}async createVpc(t){let e={Action:"CreateVpc",Version:"2016-11-15",CidrBlock:t.CidrBlock};if(t.InstanceTenancy)e.InstanceTenancy=t.InstanceTenancy;if(t.TagSpecifications)t.TagSpecifications.forEach((n,c)=>{e[`TagSpecification.${c+1}.ResourceType`]=n.ResourceType,n.Tags.forEach((_,T)=>{e[`TagSpecification.${c+1}.Tag.${T+1}.Key`]=_.Key,e[`TagSpecification.${c+1}.Tag.${T+1}.Value`]=_.Value})});let r=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(e).toString()}),E=(r.CreateVpcResponse||r).vpc;return{Vpc:E?{VpcId:E.vpcId,CidrBlock:E.cidrBlock,State:E.state,DhcpOptionsId:E.dhcpOptionsId,InstanceTenancy:E.instanceTenancy,IsDefault:E.isDefault==="true",Tags:this.parseTags(E.tagSet?.item)}:void 0}}async createSubnet(t){let e={Action:"CreateSubnet",Version:"2016-11-15",VpcId:t.VpcId,CidrBlock:t.CidrBlock};if(t.AvailabilityZone)e.AvailabilityZone=t.AvailabilityZone;if(t.TagSpecifications)t.TagSpecifications.forEach((n,c)=>{e[`TagSpecification.${c+1}.ResourceType`]=n.ResourceType,n.Tags.forEach((_,T)=>{e[`TagSpecification.${c+1}.Tag.${T+1}.Key`]=_.Key,e[`TagSpecification.${c+1}.Tag.${T+1}.Value`]=_.Value})});let r=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(e).toString()}),E=(r.CreateSubnetResponse||r).subnet;return{Subnet:E?{SubnetId:E.subnetId,VpcId:E.vpcId,CidrBlock:E.cidrBlock,AvailabilityZone:E.availabilityZone,AvailableIpAddressCount:E.availableIpAddressCount?Number.parseInt(E.availableIpAddressCount):void 0,State:E.state,MapPublicIpOnLaunch:E.mapPublicIpOnLaunch==="true",Tags:this.parseTags(E.tagSet?.item)}:void 0}}async modifySubnetAttribute(t){let e={Action:"ModifySubnetAttribute",Version:"2016-11-15",SubnetId:t.SubnetId};if(t.MapPublicIpOnLaunch!==void 0)e["MapPublicIpOnLaunch.Value"]=String(t.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(e).toString()})}async createSecurityGroup(t){let e={Action:"CreateSecurityGroup",Version:"2016-11-15",GroupName:t.GroupName,GroupDescription:t.Description};if(t.VpcId)e.VpcId=t.VpcId;if(t.TagSpecifications)t.TagSpecifications.forEach((E,n)=>{e[`TagSpecification.${n+1}.ResourceType`]=E.ResourceType,E.Tags.forEach((c,_)=>{e[`TagSpecification.${n+1}.Tag.${_+1}.Key`]=c.Key,e[`TagSpecification.${n+1}.Tag.${_+1}.Value`]=c.Value})});let r=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(e).toString()});return{GroupId:(r.CreateSecurityGroupResponse||r).groupId}}async authorizeSecurityGroupIngress(t){let e={Action:"AuthorizeSecurityGroupIngress",Version:"2016-11-15",GroupId:t.GroupId};this.encodeIpPermissions(e,t.IpPermissions),await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(e).toString()})}async authorizeSecurityGroupEgress(t){let e={Action:"AuthorizeSecurityGroupEgress",Version:"2016-11-15",GroupId:t.GroupId};this.encodeIpPermissions(e,t.IpPermissions),await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(e).toString()})}async describeRouteTables(t){let e={Action:"DescribeRouteTables",Version:"2016-11-15"};if(t?.RouteTableIds)t.RouteTableIds.forEach((E,n)=>{e[`RouteTableId.${n+1}`]=E});if(t?.Filters)t.Filters.forEach((E,n)=>{e[`Filter.${n+1}.Name`]=E.Name,E.Values.forEach((c,_)=>{e[`Filter.${n+1}.Value.${_+1}`]=c})});let r=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(e).toString()}),d=r.DescribeRouteTablesResponse||r;return{RouteTables:this.parseArray(d.routeTableSet?.item).map((E)=>({RouteTableId:E.routeTableId,VpcId:E.vpcId,Routes:this.parseArray(E.routeSet?.item).map((n)=>({DestinationCidrBlock:n.destinationCidrBlock,GatewayId:n.gatewayId,NatGatewayId:n.natGatewayId,State:n.state})),Associations:this.parseArray(E.associationSet?.item).map((n)=>({RouteTableAssociationId:n.routeTableAssociationId,SubnetId:n.subnetId,Main:n.main==="true"||n.main===!0})),Tags:this.parseTags(E.tagSet?.item)}))}}async deleteVpc(t){let e={Action:"DeleteVpc",Version:"2016-11-15",VpcId:t};await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(e).toString()})}async deleteSubnet(t){let e={Action:"DeleteSubnet",Version:"2016-11-15",SubnetId:t};await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(e).toString()})}async deleteSecurityGroup(t){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:t}).toString()})}async describeNetworkInterfaces(t){let e={Action:"DescribeNetworkInterfaces",Version:"2016-11-15"};if(t?.NetworkInterfaceIds)t.NetworkInterfaceIds.forEach((E,n)=>{e[`NetworkInterfaceId.${n+1}`]=E});if(t?.Filters)t.Filters.forEach((E,n)=>{e[`Filter.${n+1}.Name`]=E.Name,E.Values.forEach((c,_)=>{e[`Filter.${n+1}.Value.${_+1}`]=c})});let r=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(e).toString()}),d=r.DescribeNetworkInterfacesResponse||r;return{NetworkInterfaces:this.parseArray(d.networkInterfaceSet?.item).map((E)=>({NetworkInterfaceId:E.networkInterfaceId,SubnetId:E.subnetId,VpcId:E.vpcId,Status:E.status,Attachment:E.attachment?{AttachmentId:E.attachment.attachmentId,InstanceId:E.attachment.instanceId,Status:E.attachment.status}:void 0}))}}async detachNetworkInterface(t,e){let r={Action:"DetachNetworkInterface",Version:"2016-11-15",AttachmentId:t};if(e)r.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(r).toString()})}async deleteNetworkInterface(t){let e={Action:"DeleteNetworkInterface",Version:"2016-11-15",NetworkInterfaceId:t};await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(e).toString()})}async describeRegions(){let t={Action:"DescribeRegions",Version:"2016-11-15"},e=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(t).toString()}),r=e.DescribeRegionsResponse||e;return{Regions:this.parseArray(r.regionInfo?.item).map((d)=>({RegionName:d.regionName,Endpoint:d.regionEndpoint}))}}async runInstances(t){let e={Action:"RunInstances",Version:"2016-11-15",ImageId:t.ImageId,InstanceType:t.InstanceType,MinCount:String(t.MinCount),MaxCount:String(t.MaxCount)};if(t.SecurityGroupIds)t.SecurityGroupIds.forEach((E,n)=>{e[`SecurityGroupId.${n+1}`]=E});if(t.SubnetId)e.SubnetId=t.SubnetId;if(t.UserData)e.UserData=t.UserData;if(t.IamInstanceProfile){if(t.IamInstanceProfile.Name)e["IamInstanceProfile.Name"]=t.IamInstanceProfile.Name;if(t.IamInstanceProfile.Arn)e["IamInstanceProfile.Arn"]=t.IamInstanceProfile.Arn}if(t.TagSpecifications)t.TagSpecifications.forEach((E,n)=>{e[`TagSpecification.${n+1}.ResourceType`]=E.ResourceType,E.Tags.forEach((c,_)=>{e[`TagSpecification.${n+1}.Tag.${_+1}.Key`]=c.Key,e[`TagSpecification.${n+1}.Tag.${_+1}.Value`]=c.Value})});let r=await this.client.request({service:"ec2",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(e).toString()}),d=r.RunInstancesResponse||r;return{Instances:this.parseInstances(d.instancesSet?.item||d.instancesSet)}}encodeIpPermissions(t,e){e.forEach((r,d)=>{let E=`IpPermissions.${d+1}`;if(r.IpProtocol!==void 0)t[`${E}.IpProtocol`]=r.IpProtocol;if(r.FromPort!==void 0)t[`${E}.FromPort`]=String(r.FromPort);if(r.ToPort!==void 0)t[`${E}.ToPort`]=String(r.ToPort);if(r.IpRanges)r.IpRanges.forEach((n,c)=>{if(n.CidrIp)t[`${E}.IpRanges.${c+1}.CidrIp`]=n.CidrIp;if(n.Description)t[`${E}.IpRanges.${c+1}.Description`]=n.Description});if(r.Ipv6Ranges)r.Ipv6Ranges.forEach((n,c)=>{if(n.CidrIpv6)t[`${E}.Ipv6Ranges.${c+1}.CidrIpv6`]=n.CidrIpv6;if(n.Description)t[`${E}.Ipv6Ranges.${c+1}.Description`]=n.Description});if(r.UserIdGroupPairs)r.UserIdGroupPairs.forEach((n,c)=>{if(n.GroupId)t[`${E}.Groups.${c+1}.GroupId`]=n.GroupId;if(n.UserId)t[`${E}.Groups.${c+1}.UserId`]=n.UserId;if(n.Description)t[`${E}.Groups.${c+1}.Description`]=n.Description})})}parseArray(t){if(!t)return[];return Array.isArray(t)?t:[t]}parseFirstIpv6Address(t){for(let e of this.parseArray(t))for(let r of this.parseArray(e?.ipv6AddressesSet?.item))if(r?.ipv6Address)return r.ipv6Address;return}parseTags(t){return this.parseArray(t).map((e)=>({Key:e.key,Value:e.value}))}parseReservations(t){return this.parseArray(t).map((e)=>({ReservationId:e.reservationId,Instances:this.parseInstances(e.instancesSet?.item||e.instancesSet)}))}parseInstances(t){return this.parseArray(t).map((e)=>({InstanceId:e.instanceId,ImageId:e.imageId,InstanceType:e.instanceType,State:e.instanceState?{Code:Number.parseInt(e.instanceState.code),Name:e.instanceState.name}:void 0,PrivateIpAddress:e.privateIpAddress,PublicIpAddress:e.ipAddress,Ipv6Address:this.parseFirstIpv6Address(e.networkInterfaceSet?.item),SubnetId:e.subnetId,VpcId:e.vpcId,SecurityGroups:this.parseArray(e.groupSet?.item).map((r)=>({GroupId:r.groupId,GroupName:r.groupName})),Tags:this.parseTags(e.tagSet?.item),LaunchTime:e.launchTime,Placement:e.placement?{AvailabilityZone:e.placement.availabilityZone,Tenancy:e.placement.tenancy}:void 0,Architecture:e.architecture,RootDeviceType:e.rootDeviceType,RootDeviceName:e.rootDeviceName,BlockDeviceMappings:this.parseArray(e.blockDeviceMapping?.item).map((r)=>({DeviceName:r.deviceName,Ebs:r.ebs?{VolumeId:r.ebs.volumeId,Status:r.ebs.status,AttachTime:r.ebs.attachTime,DeleteOnTermination:r.ebs.deleteOnTermination==="true"}:void 0})),IamInstanceProfile:e.iamInstanceProfile?{Arn:e.iamInstanceProfile.arn,Id:e.iamInstanceProfile.id}:void 0}))}parseIpPermissions(t){return this.parseArray(t).map((e)=>({IpProtocol:e.ipProtocol,FromPort:e.fromPort?Number.parseInt(e.fromPort):void 0,ToPort:e.toPort?Number.parseInt(e.toPort):void 0,IpRanges:this.parseArray(e.ipRanges?.item).map((r)=>({CidrIp:r.cidrIp,Description:r.description})),Ipv6Ranges:this.parseArray(e.ipv6Ranges?.item).map((r)=>({CidrIpv6:r.cidrIpv6,Description:r.description})),UserIdGroupPairs:this.parseArray(e.groups?.item).map((r)=>({GroupId:r.groupId,UserId:r.userId,Description:r.description}))}))}}tr();Lt();class mi{client;constructor(t,e){this.client=e??new dt(void 0,{profile:t})}collectionItems(t,e){let r=t?.Items??t?.[e];if(!r)return[];if(Array.isArray(r))return r;let d=r[e]??r.Item;if(d===void 0)return typeof r==="object"&&(r.Id||r.PathPattern)?[r]:[];return Array.isArray(d)?d:[d]}validateExistingOriginInput(t,e){if(!/^[A-Z0-9]{8,32}$/.test(t))throw Error("CloudFront distribution ID is invalid");if(!/^[A-Za-z0-9][A-Za-z0-9_.-]{0,127}$/.test(e.id))throw Error("CloudFront origin ID is invalid");if(!/^(?=.{1,253}$)(?:[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?\.)+[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?$/.test(e.domainName))throw Error("CloudFront origin must be a hostname without a scheme or path");let r=e.pathPattern.startsWith("/")?e.pathPattern:`/${e.pathPattern}`;if(r==="/"||r==="/*"||!/^\/[A-Za-z0-9_.*?~!$&'()+,;=:@%/-]{1,255}$/.test(r))throw Error("CloudFront path pattern must be a non-default absolute pattern");if(e.originPath&&(!e.originPath.startsWith("/")||e.originPath.includes("..")))throw Error("CloudFront origin path must be absolute and traversal-free");if(Object.entries(e.customHeaders??{}).some(([d,E])=>!/^[A-Za-z0-9-]{1,64}$/.test(d)||!E||E.length>1024))throw Error("CloudFront custom origin headers are invalid");return{...e,pathPattern:r}}async upsertExistingDistributionOrigin(t,e){let r=this.validateExistingOriginInput(t,e),d=await this.client.request({service:"cloudfront",region:"us-east-1",method:"GET",path:`/2020-05-31/distribution/${t}/config`,returnHeaders:!0}),E=d.headers?.etag||d.headers?.ETag||d.ETag||"",n=d.body?.DistributionConfig||d.DistributionConfig||d.body;if(!n||n.Enabled===void 0||!E)throw Error("Failed to read an ETag-protected CloudFront distribution config");let c=this.collectionItems(n.Origins,"Origin"),_=this.collectionItems(n.CacheBehaviors,"CacheBehavior"),T=c.find((I)=>String(I.Id)===r.id),i=_.find((I)=>String(I.PathPattern)===r.pathPattern);if(T&&String(T.DomainName)!==r.domainName&&!r.replaceExisting)throw Error(`Origin ${r.id} already targets ${T.DomainName}; pass replaceExisting only after reviewing the live config`);if(i&&String(i.TargetOriginId)!==r.id&&!r.replaceExisting)throw Error(`Path ${r.pathPattern} already targets ${i.TargetOriginId}; pass replaceExisting only after reviewing the live config`);let h={Id:r.id,DomainName:r.domainName,OriginPath:r.originPath??"",CustomHeaders:{Quantity:Object.keys(r.customHeaders??{}).length,...Object.keys(r.customHeaders??{}).length?{Items:{OriginCustomHeader:Object.entries(r.customHeaders).map(([I,a])=>({HeaderName:I,HeaderValue:a}))}}:{}},CustomOriginConfig:{HTTPPort:80,HTTPSPort:443,OriginProtocolPolicy:r.protocolPolicy??"https-only",OriginSslProtocols:{Quantity:1,Items:{SslProtocol:["TLSv1.2"]}},OriginReadTimeout:30,OriginKeepaliveTimeout:5},ConnectionAttempts:3,ConnectionTimeout:10,...r.originAccessControlId?{OriginAccessControlId:r.originAccessControlId}:{}},R=["GET","HEAD","OPTIONS","PUT","POST","PATCH","DELETE"],N={PathPattern:r.pathPattern,TargetOriginId:r.id,ViewerProtocolPolicy:"redirect-to-https",Compress:!0,CachePolicyId:"4135ea2d-6df8-44a3-9df3-4b5a84be39ad",OriginRequestPolicyId:"b689b0a8-53d0-40ab-baf2-68738e2966ac",AllowedMethods:{Quantity:R.length,Items:{Method:R},CachedMethods:{Quantity:2,Items:{Method:["GET","HEAD"]}}},SmoothStreaming:!1,FieldLevelEncryptionId:"",TrustedSigners:{Enabled:!1,Quantity:0},TrustedKeyGroups:{Enabled:!1,Quantity:0},LambdaFunctionAssociations:{Quantity:0},FunctionAssociations:{Quantity:0}},A=T?c.map((I)=>String(I.Id)===r.id?h:I):[...c,h],u=i?_.map((I)=>String(I.PathPattern)===r.pathPattern?N:I):[..._,N],f=JSON.stringify(c)!==JSON.stringify(A)||JSON.stringify(_)!==JSON.stringify(u);if(!f||r.dryRun)return{distributionId:t,originId:r.id,domainName:r.domainName,pathPattern:r.pathPattern,changed:f,applied:!1,etag:E};n.Origins={Quantity:A.length,Items:{Origin:A}},n.CacheBehaviors={Quantity:u.length,...u.length?{Items:{CacheBehavior:u}}:{}};let w=await this.client.request({service:"cloudfront",region:"us-east-1",method:"PUT",path:`/2020-05-31/distribution/${t}/config`,body:this.buildDistributionConfigXml(n),headers:{"Content-Type":"application/xml","If-Match":E}});return{distributionId:t,originId:r.id,domainName:r.domainName,pathPattern:r.pathPattern,changed:!0,applied:!0,etag:w.ETag||w.headers?.etag||""}}async removeExistingDistributionOrigin(t,e){let r=this.validateExistingOriginInput(t,e),d=await this.client.request({service:"cloudfront",region:"us-east-1",method:"GET",path:`/2020-05-31/distribution/${t}/config`,returnHeaders:!0}),E=d.headers?.etag||d.headers?.ETag||d.ETag||"",n=d.body?.DistributionConfig||d.DistributionConfig||d.body;if(!n||n.Enabled===void 0||!E)throw Error("Failed to read an ETag-protected CloudFront distribution config");let c=this.collectionItems(n.Origins,"Origin"),_=this.collectionItems(n.CacheBehaviors,"CacheBehavior"),T=c.find((u)=>String(u.Id)===r.id),i=_.find((u)=>String(u.PathPattern)===r.pathPattern);if(T&&String(T.DomainName)!==r.domainName)throw Error(`Origin ${r.id} no longer targets ${r.domainName}; refusing ambiguous removal`);if(i&&String(i.TargetOriginId)!==r.id)throw Error(`Path ${r.pathPattern} no longer targets ${r.id}; refusing ambiguous removal`);if(!i)return{distributionId:t,originId:r.id,domainName:r.domainName,pathPattern:r.pathPattern,changed:!1,applied:!1,originRemoved:!1,etag:E};let h=_.filter((u)=>String(u.PathPattern)!==r.pathPattern),R=String(n.DefaultCacheBehavior?.TargetOriginId)===r.id||h.some((u)=>String(u.TargetOriginId)===r.id),N=R?c:c.filter((u)=>String(u.Id)!==r.id);if(r.dryRun)return{distributionId:t,originId:r.id,domainName:r.domainName,pathPattern:r.pathPattern,changed:!0,applied:!1,originRemoved:!R&&!!T,etag:E};n.Origins={Quantity:N.length,Items:{Origin:N}},n.CacheBehaviors={Quantity:h.length,...h.length?{Items:{CacheBehavior:h}}:{}};let A=await this.client.request({service:"cloudfront",region:"us-east-1",method:"PUT",path:`/2020-05-31/distribution/${t}/config`,body:this.buildDistributionConfigXml(n),headers:{"Content-Type":"application/xml","If-Match":E}});return{distributionId:t,originId:r.id,domainName:r.domainName,pathPattern:r.pathPattern,changed:!0,applied:!0,originRemoved:!R&&!!T,etag:A.ETag||A.headers?.etag||""}}async createInvalidation(t){let e=t.callerReference||Date.now().toString(),r=`<?xml version="1.0" encoding="UTF-8"?>
|
|
5625
5625
|
<InvalidationBatch>
|
|
@@ -5760,13 +5760,13 @@ ${Object.entries(t).filter(([n])=>!n.startsWith("@_")).map(([n,c])=>E(n,c," ","
|
|
|
5760
5760
|
</CustomErrorResponse>
|
|
5761
5761
|
</Items>
|
|
5762
5762
|
</CustomErrorResponses>`}
|
|
5763
|
-
</DistributionConfig>`,P=await this.client.request({service:"cloudfront",region:"us-east-1",method:"POST",path:"/2020-05-31/distribution",body:a,headers:{"Content-Type":"application/xml"},returnHeaders:!0}),j=P.body?.Distribution||P.Distribution||P.body||P;return{Id:j.Id,ARN:j.ARN,DomainName:j.DomainName,Status:j.Status,ETag:P.headers?.etag||P.ETag||""}}async createMediaDistributionForS3(t){return this.createDistributionForS3({...t,defaultRootObject:"",mediaDelivery:!0,comment:t.comment??`Media distribution for ${t.bucketName}`})}async listPublicKeys(){let t=await this.client.request({service:"cloudfront",region:"us-east-1",method:"GET",path:"/2020-05-31/public-key"});return this.collectionItems(t.PublicKeyList??t,"PublicKeySummary").map((r)=>({Id:String(r.Id),Name:String(r.Name),Comment:r.Comment?String(r.Comment):void 0}))}async createPublicKey(t){if(!/^[A-Za-z0-9_-]{1,128}$/.test(t.name))throw TypeError("CloudFront public key name is invalid");if(!t.encodedKey.includes("BEGIN PUBLIC KEY"))throw TypeError("CloudFront public key must be PEM encoded");let e=(E)=>E.replaceAll("&","&").replaceAll("<","<").replaceAll(">",">"),r=await this.client.request({service:"cloudfront",region:"us-east-1",method:"POST",path:"/2020-05-31/public-key",headers:{"Content-Type":"application/xml"},body:`<PublicKeyConfig xmlns="http://cloudfront.amazonaws.com/doc/2020-05-31/"><CallerReference>${e(t.callerReference??`${Date.now()}-${t.name}`)}</CallerReference><Name>${e(t.name)}</Name><EncodedKey>${e(t.encodedKey)}</EncodedKey><Comment>${e(t.comment??"")}</Comment></PublicKeyConfig>`}),d=r.PublicKey??r;return{Id:String(d.Id),Name:String(d.PublicKeyConfig?.Name??t.name),EncodedKey:String(d.PublicKeyConfig?.EncodedKey??t.encodedKey),Comment:String(d.PublicKeyConfig?.Comment??t.comment??"")}}async listKeyGroups(){let t=await this.client.request({service:"cloudfront",region:"us-east-1",method:"GET",path:"/2020-05-31/key-group"});return this.collectionItems(t.KeyGroupList??t,"KeyGroupSummary").map((r)=>({Id:String(r.KeyGroup?.Id??r.Id),Name:String(r.KeyGroup?.KeyGroupConfig?.Name??r.KeyGroupConfig?.Name??r.Name),Items:this.collectionItems(r.KeyGroup?.KeyGroupConfig?.Items??r.KeyGroupConfig?.Items??r.Items,"Item").map(String),Comment:r.KeyGroup?.KeyGroupConfig?.Comment??r.KeyGroupConfig?.Comment??r.Comment}))}async createKeyGroup(t){if(!/^[A-Za-z0-9_-]{1,128}$/.test(t.name))throw TypeError("CloudFront key group name is invalid");let e=[...new Set(t.publicKeyIds)];if(e.length===0)throw TypeError("CloudFront key group requires at least one public key");let r=(c)=>c.replaceAll("&","&").replaceAll("<","<").replaceAll(">",">"),d=e.map((c)=>`<Item>${r(c)}</Item>`).join(""),E=await this.client.request({service:"cloudfront",region:"us-east-1",method:"POST",path:"/2020-05-31/key-group",headers:{"Content-Type":"application/xml"},body:`<KeyGroupConfig xmlns="http://cloudfront.amazonaws.com/doc/2020-05-31/"><Name>${r(t.name)}</Name><Items>${d}</Items><Comment>${r(t.comment??"")}</Comment></KeyGroupConfig>`}),n=E.KeyGroup??E;return{Id:String(n.Id),Name:String(n.KeyGroupConfig?.Name??t.name),Items:e,Comment:String(n.KeyGroupConfig?.Comment??t.comment??"")}}static getS3BucketPolicyForCloudFront(t,e){return{Version:"2012-10-17",Statement:[{Sid:"AllowCloudFrontServicePrincipal",Effect:"Allow",Principal:{Service:"cloudfront.amazonaws.com"},Action:"s3:GetObject",Resource:`arn:aws:s3:::${t}/*`,Condition:{StringEquals:{"AWS:SourceArn":e}}}]}}async waitForDistributionDeployed(t,e=60){for(let r=0;r<e;r++){if((await this.getDistribution(t)).Status==="Deployed")return!0;await new Promise((E)=>setTimeout(E,30000))}return!1}async disableDistribution(t){let e=await this.client.request({service:"cloudfront",region:"us-east-1",method:"GET",path:`/2020-05-31/distribution/${t}/config`,returnHeaders:!0}),r=e.headers?.etag||e.headers?.ETag||"",d=e.body?.DistributionConfig||(e.body?.Enabled!==void 0?e.body:void 0)||e.DistributionConfig;if(!d||d.Enabled===void 0)throw Error("Failed to get current distribution config");d.Enabled=!1;let E=this.buildDistributionConfigXml(d),n=await this.client.request({service:"cloudfront",region:"us-east-1",method:"PUT",path:`/2020-05-31/distribution/${t}/config`,body:E,headers:{"Content-Type":"application/xml","If-Match":r},returnHeaders:!0});return{ETag:n.headers?.etag||n.headers?.ETag||n.ETag||""}}async deleteDistribution(t,e){let r=e||"";if(!r){let d=await this.client.request({service:"cloudfront",region:"us-east-1",method:"GET",path:`/2020-05-31/distribution/${t}`,returnHeaders:!0});r=d.headers?.etag||d.headers?.ETag||""}await this.client.request({service:"cloudfront",region:"us-east-1",method:"DELETE",path:`/2020-05-31/distribution/${t}`,headers:{"If-Match":r}})}async waitForDistributionDisabled(t,e=60){for(let r=0;r<e;r++){let d=await this.getDistribution(t);if(d.Status==="Deployed"&&!d.Enabled)return!0;await new Promise((E)=>setTimeout(E,30000))}return!1}async removeAlias(t,e){let r=await this.client.request({service:"cloudfront",region:"us-east-1",method:"GET",path:`/2020-05-31/distribution/${t}/config`,returnHeaders:!0}),d=r.headers?.etag||r.headers?.ETag||"",E=r.body?.DistributionConfig||(r.body?.Enabled!==void 0?r.body:void 0)||r.DistributionConfig;if(!E||E.Enabled===void 0)throw Error("Failed to get current distribution config");let n=[];if(E.Aliases?.Items){if(Array.isArray(E.Aliases.Items))n=E.Aliases.Items;else if(typeof E.Aliases.Items==="object"){let i=E.Aliases.Items.CNAME;if(typeof i==="string")n=[i];else if(Array.isArray(i))n=i}}if(n.length===0)throw Error("Distribution has no aliases to remove");let c=n.filter((i)=>i!==e);if(c.length===n.length)throw Error(`Alias ${e} not found in distribution`);if(E.Aliases.Quantity=c.length,E.Aliases.Items=c.length>0?c:void 0,c.length===0)E.ViewerCertificate={CloudFrontDefaultCertificate:!0,MinimumProtocolVersion:"TLSv1.2_2021"};let _=this.buildDistributionConfigXml(E),T=await this.client.request({service:"cloudfront",region:"us-east-1",method:"PUT",path:`/2020-05-31/distribution/${t}/config`,body:_,headers:{"Content-Type":"application/xml","If-Match":d},returnHeaders:!0});return{ETag:T.headers?.etag||T.headers?.ETag||T.ETag||""}}}n_();Lt();Lt();n_();function MD(t,e=""){return t===408||t===409||t===425||t===429||t>=500||/rate limit|temporar|timed? ?out|try again/i.test(e)}async function WA(t,e){let r=e?.headers.get("retry-after"),d=r===null||r===void 0?void 0:Number(r)*1000,E=Number.isFinite(d)?Math.max(0,d):Math.min(1000*2**(t-1),30000);await new Promise((n)=>setTimeout(n,E))}class pn{name="porkbun";apiKey;secretKey;requestTimeoutMs;constructor(t,e,r=15000){this.apiKey=t,this.secretKey=e,this.requestTimeoutMs=r}async request(t,e={}){let r;for(let d=1;d<=8;d+=1){let E,n=new AbortController,c=setTimeout(()=>{n.abort(Error(`Porkbun API request timed out after ${this.requestTimeoutMs}ms`))},this.requestTimeoutMs);try{E=await fetch(`https://api.porkbun.com/api/json/v3${t}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({apikey:this.apiKey,secretapikey:this.secretKey,...e}),signal:n.signal})}catch(T){if(r=T,d===8)throw T;await WA(d);continue}finally{clearTimeout(c)}if(!E.ok){if(r=Error(`Porkbun API error: ${E.status} ${E.statusText}`),!MD(E.status)||d===8)throw r;await WA(d,E);continue}let _=await E.json();if(_.status==="ERROR"){if(r=Error(`Porkbun API error: ${_.message||"Unknown error"}`),!MD(0,_.message)||d===8)throw r;await WA(d,E);continue}return _}throw r}getSubdomain(t,e){let r=t.replace(/\.$/,""),d=e.replace(/\.$/,"");if(r===d)return"";if(r.endsWith(`.${d}`))return r.slice(0,-(d.length+1));return r}getRootDomain(t){let e=t.replace(/\.$/,"").split(".");if(e.length>=2)return e.slice(-2).join(".");return t}static ADDRESS_TYPES=new Set(["A","AAAA"]);async clearConflictingAliases(t,e){if(!pn.ADDRESS_TYPES.has(e.type))return[];let r=this.getRootDomain(t),d=this.getSubdomain(e.name,r),E=await this.listRecords(t);if(!E.success)return[`could not list records to clear ALIAS/CNAME conflicts: ${E.message??"unknown provider error"}`];let n=[];for(let c of E.records){if(c.type!=="ALIAS"&&c.type!=="CNAME")continue;if(this.getSubdomain(c.name,r)!==d)continue;let _=await this.deleteRecord(t,c);if(!_.success)n.push(`could not remove conflicting ${c.type} on ${c.name}: ${_.message??"unknown provider error"}`)}return n}async addressRecordExists(t,e){let r=this.getRootDomain(t),d=this.getSubdomain(e.name,r),E=await this.listRecords(t);if(!E.success)return!0;return E.records.some((n)=>n.type===e.type&&this.getSubdomain(n.name,r)===d&&n.content===e.content)}async createRecord(t,e){try{let r=this.getRootDomain(t),d=this.getSubdomain(e.name,r),E={type:e.type,content:e.content,ttl:String(e.ttl||600)};if(d)E.name=d;if((e.type==="MX"||e.type==="SRV")&&e.priority!==void 0)E.prio=String(e.priority);if(e.type==="SRV"&&e.weight!==void 0&&e.port!==void 0)E.content=`${e.weight} ${e.port} ${e.content}`;let n=await this.clearConflictingAliases(t,e),c=await this.request(`/dns/create/${r}`,E);if(pn.ADDRESS_TYPES.has(e.type)&&!await this.addressRecordExists(t,e))return{success:!1,message:`Porkbun reported success but no ${e.type} record for ${e.name} exists${n.length>0?` (${n.join("; ")})`:""}. A conflicting ALIAS/CNAME on the same name silently voids the write.`};return{success:!0,id:c.id?.toString(),message:"Record created successfully"}}catch(r){return{success:!1,message:r instanceof Error?r.message:"Unknown error"}}}async upsertRecord(t,e){try{let r=this.getRootDomain(t),d=this.getSubdomain(e.name,r),E=await this.listRecords(t,e.type);if(E.success){let n=E.records.find((c)=>{return this.getSubdomain(c.name,r)===d&&c.type===e.type});if(n?.id){let c={type:e.type,content:e.content,ttl:String(e.ttl||600)};if(d)c.name=d;if((e.type==="MX"||e.type==="SRV")&&e.priority!==void 0)c.prio=String(e.priority);if(e.type==="SRV"&&e.weight!==void 0&&e.port!==void 0)c.content=`${e.weight} ${e.port} ${e.content}`;return await this.request(`/dns/edit/${r}/${n.id}`,c),{success:!0,id:n.id,message:"Record updated successfully"}}}return this.createRecord(t,e)}catch(r){return this.createRecord(t,e)}}async deleteRecord(t,e){try{let r=this.getRootDomain(t);if("id"in e&&e.id)return await this.request(`/dns/delete/${r}/${e.id}`),{success:!0,message:"Record deleted successfully"};let d=this.getSubdomain(e.name,r),E=await this.listRecords(t);if(!E.success)return{success:!1,message:"Failed to list records"};let n=E.records.find((c)=>{return this.getSubdomain(c.name,r)===d&&c.type===e.type&&c.content===e.content});if(!n?.id)return{success:!1,message:"Record not found"};return await this.request(`/dns/delete/${r}/${n.id}`),{success:!0,message:"Record deleted successfully"}}catch(r){return{success:!1,message:r instanceof Error?r.message:"Unknown error"}}}async listRecords(t,e){try{let r=this.getRootDomain(t),d=`/dns/retrieve/${r}`;if(e)d=`/dns/retrieveByNameType/${r}/${e}`;return{success:!0,records:((await this.request(d)).records||[]).map((c)=>({id:c.id,name:c.name||r,type:c.type,content:c.content,ttl:Number.parseInt(c.ttl,10),priority:c.prio?Number.parseInt(c.prio,10):void 0}))}}catch(r){return{success:!1,records:[],message:r instanceof Error?r.message:"Unknown error"}}}async canManageDomain(t){try{let e=this.getRootDomain(t);return await this.request(`/dns/retrieve/${e}`),!0}catch{return!1}}async listDomains(){try{return((await this.request("/domain/listAll")).domains||[]).map((e)=>e.domain)}catch{return[]}}async getNameServers(t){try{let e=this.getRootDomain(t);return(await this.request(`/dns/getNS/${e}`)).ns||[]}catch{return[]}}async updateNameServers(t,e){try{let r=this.getRootDomain(t);return await this.request(`/dns/updateNS/${r}`,{ns:e}),!0}catch{return!1}}}class pi{name="godaddy";apiKey;apiSecret;baseUrl;constructor(t,e,r="production"){this.apiKey=t,this.apiSecret=e,this.baseUrl=r==="ote"?"https://api.ote-godaddy.com":"https://api.godaddy.com"}async request(t,e,r){let d=`${this.baseUrl}${e}`,E={Authorization:`sso-key ${this.apiKey}:${this.apiSecret}`,"Content-Type":"application/json",Accept:"application/json"},n={method:t,headers:E};if(r)n.body=JSON.stringify(r);let c=await fetch(d,n);if(c.status===204)return{};if(c.ok){let T=await c.text();if(T)return JSON.parse(T);return{}}let _=`GoDaddy API error: ${c.status} ${c.statusText}`;try{let T=await c.json();if(T.message)_=`GoDaddy API error: ${T.message}`;if(T.fields)_+=` - Fields: ${JSON.stringify(T.fields)}`}catch{}throw Error(_)}getSubdomain(t,e){let r=t.replace(/\.$/,""),d=e.replace(/\.$/,"");if(r===d)return"@";if(r.endsWith(`.${d}`))return r.slice(0,-(d.length+1));return r}getRootDomain(t){let e=t.replace(/\.$/,"").split(".");if(e.length>=2)return e.slice(-2).join(".");return t}toGoDaddyRecord(t,e){let r=this.getRootDomain(e),d=this.getSubdomain(t.name,r),E={type:t.type,name:d,data:t.content,ttl:t.ttl||600};if(t.type==="MX"&&t.priority!==void 0)E.priority=t.priority;return E}fromGoDaddyRecord(t,e){let r=this.getRootDomain(e),d=t.name;if(d==="@")d=r;else if(!d.endsWith(r))d=`${d}.${r}`;return{name:d,type:t.type,content:t.data,ttl:t.ttl,priority:t.priority}}async createRecord(t,e){try{let r=this.getRootDomain(t),d=this.toGoDaddyRecord(e,t);return await this.request("PATCH",`/v1/domains/${r}/records`,[d]),{success:!0,message:"Record created successfully"}}catch(r){return{success:!1,message:r instanceof Error?r.message:"Unknown error"}}}async upsertRecord(t,e){try{let r=this.getRootDomain(t),d=this.toGoDaddyRecord(e,t);return await this.request("PUT",`/v1/domains/${r}/records/${e.type}/${d.name}`,[d]),{success:!0,message:"Record upserted successfully"}}catch(r){return this.createRecord(t,e)}}async deleteRecord(t,e){try{let r=this.getRootDomain(t),d=this.getSubdomain(e.name,r),E=await this.request("GET",`/v1/domains/${r}/records/${e.type}/${d}`),n=E.filter((c)=>c.data!==e.content);if(n.length===E.length)return{success:!1,message:"Record not found"};if(n.length===0)try{await this.request("DELETE",`/v1/domains/${r}/records/${e.type}/${d}`)}catch{}else await this.request("PUT",`/v1/domains/${r}/records/${e.type}/${d}`,n);return{success:!0,message:"Record deleted successfully"}}catch(r){return{success:!1,message:r instanceof Error?r.message:"Unknown error"}}}async listRecords(t,e){try{let r=this.getRootDomain(t),d=`/v1/domains/${r}/records`;if(e)d=`/v1/domains/${r}/records/${e}`;return{success:!0,records:(await this.request("GET",d)).map((n)=>this.fromGoDaddyRecord(n,t))}}catch(r){return{success:!1,records:[],message:r instanceof Error?r.message:"Unknown error"}}}async canManageDomain(t){try{let e=this.getRootDomain(t);return await this.request("GET",`/v1/domains/${e}`),!0}catch{return!1}}async listDomains(){try{return(await this.request("GET","/v1/domains")).map((e)=>e.domain)}catch{return[]}}async getDomainDetails(t){try{let e=this.getRootDomain(t),r=await this.request("GET",`/v1/domains/${e}`);return{domain:r.domain,status:r.status,nameServers:r.nameServers,expires:r.expires}}catch{return null}}async updateNameServers(t,e){try{let r=this.getRootDomain(t);return await this.request("PUT",`/v1/domains/${r}/records/NS`,e.map((d)=>({type:"NS",name:"@",data:d,ttl:3600}))),!0}catch{return!1}}async checkDomainAvailability(t){try{let e=await this.request("GET",`/v1/domains/available?domain=${encodeURIComponent(t)}`);return{available:e.available,price:e.price,currency:e.currency}}catch{return{available:!1}}}}class th{name="cloudflare";apiToken;zoneCache=new Map;constructor(t){this.apiToken=t}async request(t,e,r){let d=`https://api.cloudflare.com/client/v4${e}`,E={Authorization:`Bearer ${this.apiToken}`,"Content-Type":"application/json"},n={method:t,headers:E};if(r)n.body=JSON.stringify(r);let _=await(await fetch(d,n)).json();if(!_.success){let T=_.errors.map((i)=>i.message).join(", ");throw Error(`Cloudflare API error: ${T}`)}return _}getRootDomain(t){let e=t.replace(/\.$/,"").split(".");if(e.length>=2)return e.slice(-2).join(".");return t}async getZoneId(t){let e=this.getRootDomain(t),r=this.zoneCache.get(e);if(r)return r;let d=await this.request("GET",`/zones?name=${encodeURIComponent(e)}`);if(!d.result||d.result.length===0)throw Error(`Zone not found for domain: ${e}`);let E=d.result[0].id;return this.zoneCache.set(e,E),E}getFullRecordName(t,e){let r=this.getRootDomain(e),d=t.replace(/\.$/,"");if(!d||d===r||d==="@")return r;if(d.endsWith(`.${r}`))return d;return`${d}.${r}`}toCloudflareRecord(t,e){let r={type:t.type,name:this.getFullRecordName(t.name,e),content:t.content||t.value||"",ttl:t.ttl||1};if(t.type==="MX"&&t.priority!==void 0)r.priority=t.priority;if(t.type==="SRV"){if(t.priority!==void 0)r.priority=t.priority}return r}fromCloudflareRecord(t){return{id:t.id,name:t.name,type:t.type,content:t.content,ttl:t.ttl,priority:t.priority}}async createRecord(t,e){try{let r=await this.getZoneId(t),d=this.toCloudflareRecord(e,t);return{success:!0,id:(await this.request("POST",`/zones/${r}/dns_records`,d)).result.id,message:"Record created successfully"}}catch(r){return{success:!1,message:r instanceof Error?r.message:"Unknown error"}}}async upsertRecord(t,e){try{let r=await this.getZoneId(t),d=this.getFullRecordName(e.name,t),E=await this.request("GET",`/zones/${r}/dns_records?type=${e.type}&name=${encodeURIComponent(d)}`),n=this.toCloudflareRecord(e,t);if(E.result&&E.result.length>0){let _=E.result[0].id;return{success:!0,id:(await this.request("PUT",`/zones/${r}/dns_records/${_}`,n)).result.id,message:"Record updated successfully"}}return{success:!0,id:(await this.request("POST",`/zones/${r}/dns_records`,n)).result.id,message:"Record created successfully"}}catch(r){return this.createRecord(t,e)}}async deleteRecord(t,e){try{let r=await this.getZoneId(t),d=this.getFullRecordName(e.name,t),E=await this.request("GET",`/zones/${r}/dns_records?type=${e.type}&name=${encodeURIComponent(d)}`);if(!E.result||E.result.length===0)return{success:!1,message:"Record not found"};let n=E.result.find((c)=>c.content===e.content);if(!n)return{success:!1,message:"Record with matching content not found"};return await this.request("DELETE",`/zones/${r}/dns_records/${n.id}`),{success:!0,message:"Record deleted successfully"}}catch(r){return{success:!1,message:r instanceof Error?r.message:"Unknown error"}}}async listRecords(t,e){try{let d=`/zones/${await this.getZoneId(t)}/dns_records?per_page=100`;if(e)d+=`&type=${e}`;let E=[],n=1,c=!0;while(c){let _=await this.request("GET",`${d}&page=${n}`);if(E.push(..._.result||[]),_.result_info)c=n<_.result_info.total_pages,n++;else c=!1}return{success:!0,records:E.map((_)=>this.fromCloudflareRecord(_))}}catch(r){return{success:!1,records:[],message:r instanceof Error?r.message:"Unknown error"}}}async canManageDomain(t){try{return await this.getZoneId(t),!0}catch{return!1}}async listDomains(){try{let t=[],e=1,r=!0;while(r){let d=await this.request("GET",`/zones?per_page=50&page=${e}`);if(t.push(...d.result||[]),d.result_info)r=e<d.result_info.total_pages,e++;else r=!1}return t.map((d)=>d.name)}catch{return[]}}async getZoneDetails(t){try{let e=await this.getZoneId(t),r=await this.request("GET",`/zones/${e}`);return{id:r.result.id,name:r.result.name,status:r.result.status,nameServers:r.result.name_servers,paused:r.result.paused}}catch{return null}}async purgeCache(t,e){try{let r=await this.getZoneId(t),d={};if(e?.purgeEverything)d.purge_everything=!0;else{if(e?.files)d.files=e.files;if(e?.tags)d.tags=e.tags;if(e?.hosts)d.hosts=e.hosts}if(Object.keys(d).length===0)d.purge_everything=!0;return await this.request("POST",`/zones/${r}/purge_cache`,d),!0}catch{return!1}}async getRecordProxyStatus(t,e){try{let r=await this.getZoneId(t),d=this.getFullRecordName(e.name,t),E=await this.request("GET",`/zones/${r}/dns_records?type=${e.type}&name=${encodeURIComponent(d)}`);if(E.result&&E.result.length>0)return E.result.find((c)=>c.content===e.content)?.proxied??null;return null}catch{return null}}async setRecordProxyStatus(t,e,r){try{let d=await this.getZoneId(t),E=this.getFullRecordName(e.name,t),n=await this.request("GET",`/zones/${d}/dns_records?type=${e.type}&name=${encodeURIComponent(E)}`);if(!n.result||n.result.length===0)return!1;let c=n.result.find((_)=>_.content===e.content);if(!c)return!1;return await this.request("PATCH",`/zones/${d}/dns_records/${c.id}`,{proxied:r}),!0}catch{return!1}}}n_();class eh{name="route53";client;hostedZoneCache=new Map;providedHostedZoneId;constructor(t="us-east-1",e){this.client=new Md(t),this.providedHostedZoneId=e}getRootDomain(t){let e=t.replace(/\.$/,"").split(".");if(e.length>=2)return e.slice(-2).join(".");return t}async getHostedZoneId(t){if(this.providedHostedZoneId)return this.providedHostedZoneId;let e=this.getRootDomain(t),r=this.hostedZoneCache.get(e);if(r)return r;let d=await this.client.findHostedZoneForDomain(t);if(d){let E=d.Id.replace("/hostedzone/","");return this.hostedZoneCache.set(e,E),E}return null}normalizeName(t,e){let r=t.replace(/\.$/,""),d=e.replace(/\.$/,"");if(!d||d==="@")return`${r}.`;if(d===r||d.endsWith(`.${r}`))return`${d}.`;return`${d}.${r}.`}async createRecord(t,e){try{let r=await this.getHostedZoneId(t);if(!r)return{success:!1,message:`No hosted zone found for domain: ${t}`};let d=this.normalizeName(t,e.name),E=e.content;if(e.type==="TXT"&&!E.startsWith('"'))E=`"${E}"`;if(e.type==="MX"&&e.priority!==void 0)E=`${e.priority} ${E}`;return{success:!0,id:(await this.client.changeResourceRecordSets({HostedZoneId:r,ChangeBatch:{Comment:"Created by ts-cloud DNS provider",Changes:[{Action:"CREATE",ResourceRecordSet:{Name:d,Type:e.type,TTL:e.ttl||300,ResourceRecords:[{Value:E}]}}]}})).ChangeInfo?.Id,message:"Record created successfully"}}catch(r){return{success:!1,message:r instanceof Error?r.message:"Unknown error"}}}async upsertRecord(t,e){try{let r=await this.getHostedZoneId(t);if(!r)return{success:!1,message:`No hosted zone found for domain: ${t}`};let d=this.normalizeName(t,e.name),E=e.content;if(e.type==="TXT"&&!E.startsWith('"'))E=`"${E}"`;if(e.type==="MX"&&e.priority!==void 0)E=`${e.priority} ${E}`;return{success:!0,id:(await this.client.changeResourceRecordSets({HostedZoneId:r,ChangeBatch:{Comment:"Upserted by ts-cloud DNS provider",Changes:[{Action:"UPSERT",ResourceRecordSet:{Name:d,Type:e.type,TTL:e.ttl||300,ResourceRecords:[{Value:E}]}}]}})).ChangeInfo?.Id,message:"Record upserted successfully"}}catch(r){return{success:!1,message:r instanceof Error?r.message:"Unknown error"}}}async deleteRecord(t,e){try{let r=await this.getHostedZoneId(t);if(!r)return{success:!1,message:`No hosted zone found for domain: ${t}`};let d=this.normalizeName(t,e.name),E=e.content;if(e.type==="TXT"&&!E.startsWith('"'))E=`"${E}"`;if(e.type==="MX"&&e.priority!==void 0)E=`${e.priority} ${E}`;return await this.client.changeResourceRecordSets({HostedZoneId:r,ChangeBatch:{Comment:"Deleted by ts-cloud DNS provider",Changes:[{Action:"DELETE",ResourceRecordSet:{Name:d,Type:e.type,TTL:e.ttl||300,ResourceRecords:[{Value:E}]}}]}}),{success:!0,message:"Record deleted successfully"}}catch(r){return{success:!1,message:r instanceof Error?r.message:"Unknown error"}}}async listRecords(t,e){try{let r=await this.getHostedZoneId(t);if(!r)return{success:!1,records:[],message:`No hosted zone found for domain: ${t}`};let d=await this.client.listResourceRecordSets({HostedZoneId:r,StartRecordType:e}),E=[];for(let n of d.ResourceRecordSets){if(e&&n.Type!==e)continue;if(n.AliasTarget)continue;for(let c of n.ResourceRecords||[]){let _=c.Value,T;if(n.Type==="MX"){let i=_.split(" ");if(i.length>=2)T=Number.parseInt(i[0],10),_=i.slice(1).join(" ")}if(n.Type==="TXT"&&_.startsWith('"')&&_.endsWith('"'))_=_.slice(1,-1);E.push({name:n.Name.replace(/\.$/,""),type:n.Type,content:_,ttl:n.TTL,priority:T})}}return{success:!0,records:E}}catch(r){return{success:!1,records:[],message:r instanceof Error?r.message:"Unknown error"}}}async canManageDomain(t){return await this.getHostedZoneId(t)!==null}async listDomains(){try{return(await this.client.listHostedZones()).HostedZones.map((e)=>e.Name.replace(/\.$/,""))}catch{return[]}}getRoute53Client(){return this.client}async createAliasRecord(t){try{let e=await this.getHostedZoneId(t.domain);if(!e)return{success:!1,message:`No hosted zone found for domain: ${t.domain}`};return{success:!0,id:(await this.client.createAliasRecord({HostedZoneId:e,Name:this.normalizeName(t.domain,t.name),TargetHostedZoneId:t.targetHostedZoneId,TargetDNSName:t.targetDnsName,EvaluateTargetHealth:t.evaluateTargetHealth,Type:t.type})).ChangeInfo?.Id,message:"Alias record created successfully"}}catch(e){return{success:!1,message:e instanceof Error?e.message:"Unknown error"}}}async createCloudFrontAlias(t){return this.createAliasRecord({domain:t.domain,name:t.name,targetHostedZoneId:Md.CloudFrontHostedZoneId,targetDnsName:t.cloudFrontDomainName,evaluateTargetHealth:!1})}async createAlbAlias(t){let e=Md.ALBHostedZoneIds[t.region];if(!e)return{success:!1,message:`Unknown region for ALB: ${t.region}`};return this.createAliasRecord({domain:t.domain,name:t.name,targetHostedZoneId:e,targetDnsName:t.albDnsName,evaluateTargetHealth:!0})}}function f_(t){switch(t.provider){case"route53":return new eh(t.region,t.hostedZoneId);case"porkbun":return new pn(t.apiKey,t.secretKey);case"godaddy":return new pi(t.apiKey,t.apiSecret,t.environment);case"cloudflare":return new th(t.apiToken);default:throw Error(`Unknown DNS provider: ${t.provider}`)}}class GD{providers=new Map;configs=[];addConfig(t){return this.configs.push(t),this}addRoute53(t,e){return this.configs.push({provider:"route53",region:t,hostedZoneId:e}),this}addPorkbun(t,e){return this.configs.push({provider:"porkbun",apiKey:t,secretKey:e}),this}addGoDaddy(t,e,r){return this.configs.push({provider:"godaddy",apiKey:t,apiSecret:e,environment:r}),this}addCloudflare(t){return this.configs.push({provider:"cloudflare",apiToken:t}),this}loadFromEnv(){if(process.env.AWS_ACCESS_KEY_ID||process.env.AWS_REGION)this.addRoute53(process.env.AWS_REGION);let t=process.env.PORKBUN_API_KEY,e=process.env.PORKBUN_SECRET_KEY;if(t&&e)this.addPorkbun(t,e);let r=process.env.GODADDY_API_KEY,d=process.env.GODADDY_API_SECRET;if(r&&d){let n=process.env.GODADDY_ENVIRONMENT;this.addGoDaddy(r,d,n)}let E=process.env.CLOUDFLARE_API_TOKEN;if(E)this.addCloudflare(E);return this}getProvider(t){let e=this.providers.get(t);if(e)return e;let r=this.configs.find((E)=>E.provider===t);if(!r)return null;let d=f_(r);return this.providers.set(t,d),d}async getProviderForDomain(t){for(let e of this.configs){let r=f_(e);if(await r.canManageDomain(t))return r}return null}getAllProviders(){return this.configs.map((t)=>f_(t))}}var T4=new GD;VD();Lt();class U_{client;region;constructor(t="us-east-1",e){this.region=t,this.client=new dt(void 0,{profile:e})}async describeServices(t){let e={cluster:t.cluster,services:t.services};return await this.client.request({service:"ecs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonEC2ContainerServiceV20141113.DescribeServices","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(e)})}async listServices(t,e={}){let r={cluster:t,...e};return await this.client.request({service:"ecs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonEC2ContainerServiceV20141113.ListServices","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(r)})}async listTasks(t,e,r={}){let d={cluster:t,...r};if(e)d.serviceName=e;return await this.client.request({service:"ecs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonEC2ContainerServiceV20141113.ListTasks","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(d)})}async describeTasks(t,e){let r={cluster:t,tasks:e};return await this.client.request({service:"ecs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonEC2ContainerServiceV20141113.DescribeTasks","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(r)})}async updateService(t){let e={cluster:t.cluster,service:t.service};if(t.forceNewDeployment!==void 0)e.forceNewDeployment=t.forceNewDeployment;if(t.desiredCount!==void 0)e.desiredCount=t.desiredCount;if(t.taskDefinition)e.taskDefinition=t.taskDefinition;return await this.client.request({service:"ecs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonEC2ContainerServiceV20141113.UpdateService","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(e)})}async createService(t){let e={cluster:t.cluster,serviceName:t.serviceName,taskDefinition:t.taskDefinition,desiredCount:t.desiredCount};if(t.launchType)e.launchType=t.launchType;if(t.networkConfiguration)e.networkConfiguration=t.networkConfiguration;if(t.loadBalancers)e.loadBalancers=t.loadBalancers;if(t.healthCheckGracePeriodSeconds!==void 0)e.healthCheckGracePeriodSeconds=t.healthCheckGracePeriodSeconds;if(t.deploymentConfiguration)e.deploymentConfiguration=t.deploymentConfiguration;return await this.client.request({service:"ecs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonEC2ContainerServiceV20141113.CreateService","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(e)})}async deleteService(t){let e={cluster:t.cluster,service:t.service};if(t.force!==void 0)e.force=t.force;return await this.client.request({service:"ecs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonEC2ContainerServiceV20141113.DeleteService","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(e)})}async listClusters(t={}){return await this.client.request({service:"ecs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonEC2ContainerServiceV20141113.ListClusters","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(t)})}async describeClusters(t){let e={clusters:t,include:["ATTACHMENTS","CONFIGURATIONS","SETTINGS","STATISTICS","TAGS"]};return await this.client.request({service:"ecs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonEC2ContainerServiceV20141113.DescribeClusters","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(e)})}async stopTask(t){let e={cluster:t.cluster,task:t.task};if(t.reason)e.reason=t.reason;return await this.client.request({service:"ecs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonEC2ContainerServiceV20141113.StopTask","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(e)})}async runTask(t){let e={cluster:t.cluster,taskDefinition:t.taskDefinition};if(t.count!==void 0)e.count=t.count;if(t.launchType)e.launchType=t.launchType;if(t.networkConfiguration)e.networkConfiguration=t.networkConfiguration;if(t.overrides)e.overrides=t.overrides;return await this.client.request({service:"ecs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonEC2ContainerServiceV20141113.RunTask","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(e)})}async registerTaskDefinition(t){return await this.client.request({service:"ecs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonEC2ContainerServiceV20141113.RegisterTaskDefinition","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(t)})}async deregisterTaskDefinition(t){return await this.client.request({service:"ecs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonEC2ContainerServiceV20141113.DeregisterTaskDefinition","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify({taskDefinition:t})})}async describeTaskDefinition(t){return await this.client.request({service:"ecs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonEC2ContainerServiceV20141113.DescribeTaskDefinition","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify({taskDefinition:t,include:["TAGS"]})})}async listTaskDefinitionFamilies(t){let e={};if(t?.familyPrefix)e.familyPrefix=t.familyPrefix;if(t?.status)e.status=t.status;return await this.client.request({service:"ecs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonEC2ContainerServiceV20141113.ListTaskDefinitionFamilies","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(e)})}async waitForServiceStable(t,e,r=40,d=15000){for(let E=0;E<r;E++){let c=(await this.describeServices({cluster:t,services:[e]})).services?.[0];if(c){let _=c.deployments?.find((T)=>T.status==="PRIMARY");if(_&&_.runningCount===_.desiredCount&&c.deployments?.length===1)return!0}await new Promise((_)=>setTimeout(_,d))}return!1}async forceNewDeployment(t,e){return this.updateService({cluster:t,service:e,forceNewDeployment:!0})}async scaleService(t,e,r){return this.updateService({cluster:t,service:e,desiredCount:r})}}Lt();xT();qT();Lt();Lt();class sd{client;region;constructor(t="us-east-1",e){this.region=t,this.client=new dt}async createQueue(t){let r={Action:"CreateQueue",QueueName:t.fifo&&!t.queueName.endsWith(".fifo")?`${t.queueName}.fifo`:t.queueName,Version:"2012-11-05"},d=1;if(t.visibilityTimeout!==void 0)r[`Attribute.${d}.Name`]="VisibilityTimeout",r[`Attribute.${d}.Value`]=t.visibilityTimeout.toString(),d++;if(t.messageRetentionPeriod!==void 0)r[`Attribute.${d}.Name`]="MessageRetentionPeriod",r[`Attribute.${d}.Value`]=t.messageRetentionPeriod.toString(),d++;if(t.delaySeconds!==void 0)r[`Attribute.${d}.Name`]="DelaySeconds",r[`Attribute.${d}.Value`]=t.delaySeconds.toString(),d++;if(t.maxMessageSize!==void 0)r[`Attribute.${d}.Name`]="MaximumMessageSize",r[`Attribute.${d}.Value`]=t.maxMessageSize.toString(),d++;if(t.receiveMessageWaitTime!==void 0)r[`Attribute.${d}.Name`]="ReceiveMessageWaitTimeSeconds",r[`Attribute.${d}.Value`]=t.receiveMessageWaitTime.toString(),d++;if(t.fifo){if(r[`Attribute.${d}.Name`]="FifoQueue",r[`Attribute.${d}.Value`]="true",d++,t.contentBasedDeduplication)r[`Attribute.${d}.Name`]="ContentBasedDeduplication",r[`Attribute.${d}.Value`]="true",d++}if(t.deadLetterTargetArn&&t.maxReceiveCount)r[`Attribute.${d}.Name`]="RedrivePolicy",r[`Attribute.${d}.Value`]=JSON.stringify({deadLetterTargetArn:t.deadLetterTargetArn,maxReceiveCount:t.maxReceiveCount}),d++;if(t.tags&&Object.keys(t.tags).length>0){let n=1;for(let[c,_]of Object.entries(t.tags))r[`Tag.${n}.Key`]=c,r[`Tag.${n}.Value`]=_,n++}let E=await this.client.request({service:"sqs",region:this.region,method:"POST",path:"/",body:new URLSearchParams(r).toString()});return{QueueUrl:E.QueueUrl||E.CreateQueueResult?.QueueUrl}}async listQueues(t){let e={Action:"ListQueues",Version:"2012-11-05"};if(t)e.QueueNamePrefix=t;let r=await this.client.request({service:"sqs",region:this.region,method:"POST",path:"/",body:new URLSearchParams(e).toString()}),d=[];if(r.QueueUrl)d.push(r.QueueUrl);else if(r.ListQueuesResult?.QueueUrl)if(Array.isArray(r.ListQueuesResult.QueueUrl))d.push(...r.ListQueuesResult.QueueUrl);else d.push(r.ListQueuesResult.QueueUrl);return{QueueUrls:d}}async getQueueAttributes(t){let e={Action:"GetQueueAttributes",QueueUrl:t,Version:"2012-11-05","AttributeName.1":"All"},r=await this.client.request({service:"sqs",region:this.region,method:"POST",path:"/",body:new URLSearchParams(e).toString()});return{Attributes:r.Attributes||r.GetQueueAttributesResult?.Attributes||{}}}async getQueueUrl(t){let e={Action:"GetQueueUrl",QueueName:t,Version:"2012-11-05"},r=await this.client.request({service:"sqs",region:this.region,method:"POST",path:"/",body:new URLSearchParams(e).toString()});return{QueueUrl:r.QueueUrl||r.GetQueueUrlResult?.QueueUrl}}async deleteQueue(t){let e={Action:"DeleteQueue",QueueUrl:t,Version:"2012-11-05"};await this.client.request({service:"sqs",region:this.region,method:"POST",path:"/",body:new URLSearchParams(e).toString()})}async purgeQueue(t){let e={Action:"PurgeQueue",QueueUrl:t,Version:"2012-11-05"};await this.client.request({service:"sqs",region:this.region,method:"POST",path:"/",body:new URLSearchParams(e).toString()})}async sendMessage(t){let e={Action:"SendMessage",QueueUrl:t.queueUrl,MessageBody:t.messageBody,Version:"2012-11-05"};if(t.delaySeconds!==void 0)e.DelaySeconds=t.delaySeconds;if(t.messageGroupId)e.MessageGroupId=t.messageGroupId;if(t.messageDeduplicationId)e.MessageDeduplicationId=t.messageDeduplicationId;let r=await this.client.request({service:"sqs",region:this.region,method:"POST",path:"/",body:new URLSearchParams(e).toString()});return{MessageId:r.MessageId||r.SendMessageResult?.MessageId}}async receiveMessages(t){let e={Action:"ReceiveMessage",QueueUrl:t.queueUrl,Version:"2012-11-05"};if(t.maxMessages!==void 0)e.MaxNumberOfMessages=t.maxMessages;if(t.visibilityTimeout!==void 0)e.VisibilityTimeout=t.visibilityTimeout;if(t.waitTimeSeconds!==void 0)e.WaitTimeSeconds=t.waitTimeSeconds;let r=await this.client.request({service:"sqs",region:this.region,method:"POST",path:"/",body:new URLSearchParams(e).toString()}),d=[],E=r.Message||r.ReceiveMessageResult?.Message;if(E)if(Array.isArray(E))d.push(...E.map((n)=>({MessageId:n.MessageId,ReceiptHandle:n.ReceiptHandle,Body:n.Body})));else d.push({MessageId:E.MessageId,ReceiptHandle:E.ReceiptHandle,Body:E.Body});return{Messages:d}}async deleteMessage(t,e){let r={Action:"DeleteMessage",QueueUrl:t,ReceiptHandle:e,Version:"2012-11-05"};await this.client.request({service:"sqs",region:this.region,method:"POST",path:"/",body:new URLSearchParams(r).toString()})}}Lt();import{deflateRawSync as XP}from"zlib";function KD(t,e){let r=typeof e==="string"?Buffer.from(e,"utf-8"):e,d=XP(r),E=aP(r),n=new Date,c=(n.getHours()<<11|n.getMinutes()<<5|n.getSeconds()>>1)&65535,_=(n.getFullYear()-1980<<9|n.getMonth()+1<<5|n.getDate())&65535,T=Buffer.from(t,"utf-8"),i=Buffer.alloc(30+T.length);i.writeUInt32LE(67324752,0),i.writeUInt16LE(20,4),i.writeUInt16LE(0,6),i.writeUInt16LE(8,8),i.writeUInt16LE(c,10),i.writeUInt16LE(_,12),i.writeUInt32LE(E,14),i.writeUInt32LE(d.length,18),i.writeUInt32LE(r.length,22),i.writeUInt16LE(T.length,26),i.writeUInt16LE(0,28),T.copy(i,30);let h=Buffer.alloc(46+T.length);h.writeUInt32LE(33639248,0),h.writeUInt16LE(20,4),h.writeUInt16LE(20,6),h.writeUInt16LE(0,8),h.writeUInt16LE(8,10),h.writeUInt16LE(c,12),h.writeUInt16LE(_,14),h.writeUInt32LE(E,16),h.writeUInt32LE(d.length,20),h.writeUInt32LE(r.length,24),h.writeUInt16LE(T.length,28),h.writeUInt16LE(0,30),h.writeUInt16LE(0,32),h.writeUInt16LE(0,34),h.writeUInt16LE(0,36),h.writeUInt32LE(0,38),h.writeUInt32LE(0,42),T.copy(h,46);let R=i.length+d.length,N=h.length,A=Buffer.alloc(22);return A.writeUInt32LE(101010256,0),A.writeUInt16LE(0,4),A.writeUInt16LE(0,6),A.writeUInt16LE(1,8),A.writeUInt16LE(1,10),A.writeUInt32LE(N,12),A.writeUInt32LE(R,16),A.writeUInt16LE(0,20),Buffer.concat([i,d,h,A])}function aP(t){let e=[];for(let d=0;d<256;d++){let E=d;for(let n=0;n<8;n++)E=E&1?3988292384^E>>>1:E>>>1;e[d]=E}let r=4294967295;for(let d=0;d<t.length;d++)r=e[(r^t[d])&255]^r>>>8;return(r^4294967295)>>>0}class dr{client;region;constructor(t="us-east-1",e){this.region=t,this.client=new dt(void 0,{profile:e})}async createFunction(t){return await this.client.request({service:"lambda",region:this.region,method:"POST",path:"/2015-03-31/functions",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)})}async getFunction(t){return await this.client.request({service:"lambda",region:this.region,method:"GET",path:`/2015-03-31/functions/${encodeURIComponent(t)}`,headers:{"Content-Type":"application/json"}})}async updateFunctionCode(t){let{FunctionName:e,...r}=t;return await this.client.request({service:"lambda",region:this.region,method:"PUT",path:`/2015-03-31/functions/${encodeURIComponent(e)}/code`,headers:{"Content-Type":"application/json"},body:JSON.stringify(r)})}async updateFunctionCodeInline(t,e,r="index.js"){let d=KD(r,e);return this.updateFunctionCode({FunctionName:t,ZipFile:d.toString("base64")})}async updateFunctionConfiguration(t){let{FunctionName:e,...r}=t;return await this.client.request({service:"lambda",region:this.region,method:"PUT",path:`/2015-03-31/functions/${encodeURIComponent(e)}/configuration`,headers:{"Content-Type":"application/json"},body:JSON.stringify(r)})}async deleteFunction(t){await this.client.request({service:"lambda",region:this.region,method:"DELETE",path:`/2015-03-31/functions/${encodeURIComponent(t)}`,headers:{"Content-Type":"application/json"}})}async invoke(t){let{FunctionName:e,InvocationType:r="RequestResponse",Payload:d,LogType:E}=t,n={"Content-Type":"application/json","X-Amz-Invocation-Type":r};if(E)n["X-Amz-Log-Type"]=E;let c=d?typeof d==="string"?d:JSON.stringify(d):void 0,_=await this.client.request({service:"lambda",region:this.region,method:"POST",path:`/2015-03-31/functions/${encodeURIComponent(e)}/invocations`,headers:n,body:c,returnHeaders:!0});return{StatusCode:_.statusCode||200,FunctionError:_.headers?.["x-amz-function-error"],LogResult:_.headers?.["x-amz-log-result"],Payload:typeof _.body==="string"?_.body:JSON.stringify(_.body),ExecutedVersion:_.headers?.["x-amz-executed-version"]}}async listFunctions(t){let e={};if(t?.MaxItems)e.MaxItems=String(t.MaxItems);if(t?.Marker)e.Marker=t.Marker;if(t?.FunctionVersion)e.FunctionVersion=t.FunctionVersion;return await this.client.request({service:"lambda",region:this.region,method:"GET",path:"/2015-03-31/functions",queryParams:Object.keys(e).length>0?e:void 0,headers:{"Content-Type":"application/json"}})}async addPermission(t){let{FunctionName:e,...r}=t;return await this.client.request({service:"lambda",region:this.region,method:"POST",path:`/2015-03-31/functions/${encodeURIComponent(e)}/policy`,headers:{"Content-Type":"application/json"},body:JSON.stringify(r)})}async removePermission(t,e){await this.client.request({service:"lambda",region:this.region,method:"DELETE",path:`/2015-03-31/functions/${encodeURIComponent(t)}/policy/${encodeURIComponent(e)}`,headers:{"Content-Type":"application/json"}})}async publishVersion(t){let{FunctionName:e,...r}=t;return await this.client.request({service:"lambda",region:this.region,method:"POST",path:`/2015-03-31/functions/${encodeURIComponent(e)}/versions`,headers:{"Content-Type":"application/json"},body:JSON.stringify(r)})}async createAlias(t){let{FunctionName:e,...r}=t;return await this.client.request({service:"lambda",region:this.region,method:"POST",path:`/2015-03-31/functions/${encodeURIComponent(e)}/aliases`,headers:{"Content-Type":"application/json"},body:JSON.stringify(r)})}async updateAlias(t){let{FunctionName:e,Name:r,...d}=t;return this.client.request({service:"lambda",region:this.region,method:"PUT",path:`/2015-03-31/functions/${encodeURIComponent(e)}/aliases/${encodeURIComponent(r)}`,headers:{"Content-Type":"application/json"},body:JSON.stringify(d)})}async getAlias(t,e){try{return await this.client.request({service:"lambda",region:this.region,method:"GET",path:`/2015-03-31/functions/${encodeURIComponent(t)}/aliases/${encodeURIComponent(e)}`})}catch(r){if(/ResourceNotFound/i.test(String(r?.message)))return null;throw r}}async getProvisionedConcurrencyConfig(t,e){try{return await this.client.request({service:"lambda",region:this.region,method:"GET",path:`/2019-09-30/functions/${encodeURIComponent(t)}/provisioned-concurrency`,queryParams:{Qualifier:e}})}catch(r){if(/ProvisionedConcurrencyConfigNotFound|ResourceNotFound/i.test(String(r?.message)))return null;throw r}}async putProvisionedConcurrencyConfig(t){let{FunctionName:e,Qualifier:r,ProvisionedConcurrentExecutions:d}=t;return this.client.request({service:"lambda",region:this.region,method:"PUT",path:`/2019-09-30/functions/${encodeURIComponent(e)}/provisioned-concurrency`,queryParams:{Qualifier:r},headers:{"Content-Type":"application/json"},body:JSON.stringify({ProvisionedConcurrentExecutions:d})})}async deleteProvisionedConcurrencyConfig(t,e){await this.client.request({service:"lambda",region:this.region,method:"DELETE",path:`/2019-09-30/functions/${encodeURIComponent(t)}/provisioned-concurrency`,queryParams:{Qualifier:e}})}async waitForFunctionActive(t,e=60){let r=Date.now(),d=e*1000;while(Date.now()-r<d)try{let E=await this.getFunction(t),n=E.Configuration?.State;if(n==="Active")return E.Configuration;if(n==="Failed")throw Error(`Function ${t} failed: ${E.Configuration?.StateReason}`);await new Promise((c)=>setTimeout(c,2000))}catch(E){if(E.code==="ResourceNotFoundException"){await new Promise((n)=>setTimeout(n,2000));continue}throw E}throw Error(`Timeout waiting for function ${t} to become active`)}async functionExists(t){try{return await this.getFunction(t),!0}catch(e){if(e.code==="ResourceNotFoundException"||e.statusCode===404)return!1;throw e}}async createFunctionUrl(t){let{FunctionName:e,...r}=t;return await this.client.request({service:"lambda",region:this.region,method:"POST",path:`/2021-10-31/functions/${encodeURIComponent(e)}/url`,headers:{"Content-Type":"application/json"},body:JSON.stringify(r)})}async getFunctionUrl(t){try{return await this.client.request({service:"lambda",region:this.region,method:"GET",path:`/2021-10-31/functions/${encodeURIComponent(t)}/url`,headers:{"Content-Type":"application/json"}})}catch(e){if(e.statusCode===404)return null;throw e}}async deleteFunctionUrl(t){await this.client.request({service:"lambda",region:this.region,method:"DELETE",path:`/2021-10-31/functions/${encodeURIComponent(t)}/url`,headers:{"Content-Type":"application/json"}})}async createFunctionWithCode(t){let{Code:e,Filename:r="index.js",...d}=t,E=KD(r,e);return this.createFunction({...d,Code:{ZipFile:E.toString("base64")}})}async addFunctionUrlPermission(t){return this.addPermission({FunctionName:t,StatementId:"FunctionURLAllowPublicAccess",Action:"lambda:InvokeFunctionUrl",Principal:"*",FunctionUrlAuthType:"NONE"})}async publishLayerVersion(t){let{LayerName:e,...r}=t;return await this.client.request({service:"lambda",region:this.region,method:"POST",path:`/2018-10-31/layers/${encodeURIComponent(e)}/versions`,headers:{"Content-Type":"application/json"},body:JSON.stringify(r)})}async listLayerVersions(t,e){let r={};if(e?.CompatibleRuntime)r.CompatibleRuntime=e.CompatibleRuntime;if(e?.CompatibleArchitecture)r.CompatibleArchitecture=e.CompatibleArchitecture;if(e?.MaxItems)r.MaxItems=String(e.MaxItems);if(e?.Marker)r.Marker=e.Marker;return await this.client.request({service:"lambda",region:this.region,method:"GET",path:`/2018-10-31/layers/${encodeURIComponent(t)}/versions`,queryParams:Object.keys(r).length>0?r:void 0,headers:{"Content-Type":"application/json"}})}async getLayerVersion(t,e){return await this.client.request({service:"lambda",region:this.region,method:"GET",path:`/2018-10-31/layers/${encodeURIComponent(t)}/versions/${e}`,headers:{"Content-Type":"application/json"}})}async addLayerVersionPermission(t){let{LayerName:e,VersionNumber:r,...d}=t;return await this.client.request({service:"lambda",region:this.region,method:"POST",path:`/2018-10-31/layers/${encodeURIComponent(e)}/versions/${r}/policy`,headers:{"Content-Type":"application/json"},body:JSON.stringify(d)})}async deleteLayerVersion(t,e){await this.client.request({service:"lambda",region:this.region,method:"DELETE",path:`/2018-10-31/layers/${encodeURIComponent(t)}/versions/${e}`,headers:{"Content-Type":"application/json"}})}}Lt();class w_{client;region;constructor(t="us-east-1",e){this.region=t,this.client=new dt(void 0,{profile:e})}async createLogGroup(t,e){await this.client.request({service:"logs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"Logs_20140328.CreateLogGroup","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify({logGroupName:t,...e?{tags:e}:{}})})}async putRetentionPolicy(t,e){if(![1,3,5,7,14,30,60,90,120,150,180,365,400,545,731,1096,1827,2192,2557,2922,3288,3653].includes(e))throw Error("Unsupported CloudWatch Logs retention period");await this.client.request({service:"logs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"Logs_20140328.PutRetentionPolicy","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify({logGroupName:t,retentionInDays:e})})}async describeLogStreams(t){let e={logGroupName:t.logGroupName};if(t.logStreamNamePrefix)e.logStreamNamePrefix=t.logStreamNamePrefix;if(t.orderBy)e.orderBy=t.orderBy;if(t.descending!==void 0)e.descending=t.descending;if(t.limit)e.limit=t.limit;return await this.client.request({service:"logs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"Logs_20140328.DescribeLogStreams","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(e)})}async getLogEvents(t){let e={logGroupName:t.logGroupName,logStreamName:t.logStreamName};if(t.startTime)e.startTime=t.startTime;if(t.endTime)e.endTime=t.endTime;if(t.limit)e.limit=t.limit;if(t.startFromHead!==void 0)e.startFromHead=t.startFromHead;return await this.client.request({service:"logs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"Logs_20140328.GetLogEvents","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(e)})}async describeLogGroups(t){let e={};if(t?.logGroupNamePrefix)e.logGroupNamePrefix=t.logGroupNamePrefix;if(t?.limit)e.limit=t.limit;return await this.client.request({service:"logs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"Logs_20140328.DescribeLogGroups","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(e)})}async deleteLogGroup(t){await this.client.request({service:"logs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"Logs_20140328.DeleteLogGroup","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify({logGroupName:t})})}async filterLogEvents(t){let e={logGroupName:t.logGroupName};if(t.logStreamNames)e.logStreamNames=t.logStreamNames;if(t.startTime)e.startTime=t.startTime;if(t.endTime)e.endTime=t.endTime;if(t.filterPattern)e.filterPattern=t.filterPattern;if(t.limit)e.limit=t.limit;return await this.client.request({service:"logs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"Logs_20140328.FilterLogEvents","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(e)})}}Lt();Lt();Pn();Lt();Lt();Lt();Lt();Lt();Lt();Lt();Lt();Lt();Lt();Lt();Lt();class vA{client;region;constructor(t="us-east-1"){this.region=t,this.client=new dt}async request(t,e){return this.client.request({service:"events",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-amz-json-1.1","X-Amz-Target":`AWSEvents.${t}`},body:JSON.stringify(e)})}async putRule(t){return this.request("PutRule",t)}async deleteRule(t){return this.request("DeleteRule",t)}async describeRule(t){return this.request("DescribeRule",t)}async listRules(t){return this.request("ListRules",t||{})}async listEventBuses(t){return this.request("ListEventBuses",t||{})}async enableRule(t){return this.request("EnableRule",t)}async disableRule(t){return this.request("DisableRule",t)}async putTargets(t){return this.request("PutTargets",t)}async removeTargets(t){return this.request("RemoveTargets",t)}async listTargetsByRule(t){return this.request("ListTargetsByRule",t)}async putEvents(t){return this.request("PutEvents",t)}async createSchedule(t){return this.client.request({service:"scheduler",region:this.region,method:"POST",path:`/schedules/${t.Name}`,headers:{"Content-Type":"application/json"},body:JSON.stringify(t)})}}Lt();kT();Lt();tr();tr();xT();tr();tr();Lt();Lt();tr();Lt();class QA{client;region;constructor(t="us-east-1"){this.region=t,this.client=new dt}async describeFileSystems(t){let e=[];if(t?.FileSystemId)e.push(`FileSystemId=${encodeURIComponent(t.FileSystemId)}`);if(t?.CreationToken)e.push(`CreationToken=${encodeURIComponent(t.CreationToken)}`);let r=`/2015-02-01/file-systems${e.length>0?`?${e.join("&")}`:""}`;return{FileSystems:((await this.client.request({service:"elasticfilesystem",region:this.region,method:"GET",path:r,headers:{"Content-Type":"application/json"}})).FileSystems||[]).map((E)=>({FileSystemId:E.FileSystemId,Name:E.Name,CreationTime:E.CreationTime,LifeCycleState:E.LifeCycleState,NumberOfMountTargets:E.NumberOfMountTargets,SizeInBytes:E.SizeInBytes?{Value:E.SizeInBytes.Value,Timestamp:E.SizeInBytes.Timestamp}:void 0,PerformanceMode:E.PerformanceMode,Encrypted:E.Encrypted,ThroughputMode:E.ThroughputMode,Tags:E.Tags}))}}}await Ht();await Ht();import{readFileSync as Af}from"node:fs";import{join as Sj}from"node:path";function od(t){if(!t)return;let e=t.trim();if(!e)return;if(!e.includes("/"))return e;let[r]=e.split("/");if(!r.endsWith("::"))return r||void 0;return`${r}1`}tr();await Ht();var ZD={php:"php.net",nginx:"nginx.org",composer:"getcomposer.org",mysql:"mysql.com",mariadb:"mariadb.com/server",postgres:"postgresql.org",vitess:"vitess.io",etcd:"etcd.io",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"};var We="/opt/pantry";function rh(t){return`'${t.split("'").join("'\\''")}'`}function dh(t={}){return["export DEBIAN_FRONTEND=noninteractive","export PANTRY_SERVICE_SCOPE=system","export PANTRY_INSTALL_DIR=/usr/local/bin",t.version?`export PANTRY_VERSION=${rh(t.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 tc(){return'eval "$(cd /opt/pantry && pantry env 2>/dev/null)" || true'}function md(t){if(t.length===0)return[];return[`(cd /opt/pantry && pantry install ${[...new Set(t)].map(rh).join(" ")})`]}function Eh(t){return[...new Set(t)].flatMap((e)=>[`(cd /opt/pantry && pantry start ${rh(e)})`,`(cd /opt/pantry && pantry enable ${rh(e)})`])}var jr=`${We}/pantry/.bin`,GA=15306,YA=15991,ch=15999,kD=16101,_h=2379,Cd="/var/lib/vitess",VA=100;function jP(t){return t===!0||typeof t==="object"&&t!==null}function zP(t){return typeof t==="object"&&t!==null?t:{}}function Ue(t){return`'${String(t).split("'").join("'\\''")}'`}function FP(t){let r=[t.version?`vitess.io@${t.version}`:"vitess.io"];if(t.mode!=="combo"&&!t.etcdEndpoint)r.push("etcd.io");return r.push("mysql.com@8.0.43"),r}var lr="vitess",BP=`${jr}:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin`,sD="/usr/local/lib/vitess",KA=new Map;function MA(t){return`${sD}/${t}.sh`}function ec(t,e){return KA.set(t,JP(e)),`/bin/sh ${MA(t)}`}function bD(){let t=[`mkdir -p ${sD}`];for(let[e,r]of KA)t.push(`cat > ${MA(e)} <<'TS_CLOUD_VITESS_LAUNCHER_EOF'`,r,"TS_CLOUD_VITESS_LAUNCHER_EOF",`chmod 0755 ${MA(e)}`);return t}function JP(t){return["#!/bin/sh","set -e",`cd ${We}`,'eval "$(pantry env 2>/dev/null)" || true',`VT_MYSQL_ROOT="$(dirname "$(dirname "$(readlink -f ${jr}/mysqld 2>/dev/null)")")"`,`VTROOT="$(dirname "$(dirname "$(readlink -f ${jr}/mysqlctld 2>/dev/null)")")"`,"export VT_MYSQL_ROOT VTROOT",`exec ${t.join(" ")}`].join(`
|
|
5763
|
+
</DistributionConfig>`,P=await this.client.request({service:"cloudfront",region:"us-east-1",method:"POST",path:"/2020-05-31/distribution",body:a,headers:{"Content-Type":"application/xml"},returnHeaders:!0}),j=P.body?.Distribution||P.Distribution||P.body||P;return{Id:j.Id,ARN:j.ARN,DomainName:j.DomainName,Status:j.Status,ETag:P.headers?.etag||P.ETag||""}}async createMediaDistributionForS3(t){return this.createDistributionForS3({...t,defaultRootObject:"",mediaDelivery:!0,comment:t.comment??`Media distribution for ${t.bucketName}`})}async listPublicKeys(){let t=await this.client.request({service:"cloudfront",region:"us-east-1",method:"GET",path:"/2020-05-31/public-key"});return this.collectionItems(t.PublicKeyList??t,"PublicKeySummary").map((r)=>({Id:String(r.Id),Name:String(r.Name),Comment:r.Comment?String(r.Comment):void 0}))}async createPublicKey(t){if(!/^[A-Za-z0-9_-]{1,128}$/.test(t.name))throw TypeError("CloudFront public key name is invalid");if(!t.encodedKey.includes("BEGIN PUBLIC KEY"))throw TypeError("CloudFront public key must be PEM encoded");let e=(E)=>E.replaceAll("&","&").replaceAll("<","<").replaceAll(">",">"),r=await this.client.request({service:"cloudfront",region:"us-east-1",method:"POST",path:"/2020-05-31/public-key",headers:{"Content-Type":"application/xml"},body:`<PublicKeyConfig xmlns="http://cloudfront.amazonaws.com/doc/2020-05-31/"><CallerReference>${e(t.callerReference??`${Date.now()}-${t.name}`)}</CallerReference><Name>${e(t.name)}</Name><EncodedKey>${e(t.encodedKey)}</EncodedKey><Comment>${e(t.comment??"")}</Comment></PublicKeyConfig>`}),d=r.PublicKey??r;return{Id:String(d.Id),Name:String(d.PublicKeyConfig?.Name??t.name),EncodedKey:String(d.PublicKeyConfig?.EncodedKey??t.encodedKey),Comment:String(d.PublicKeyConfig?.Comment??t.comment??"")}}async listKeyGroups(){let t=await this.client.request({service:"cloudfront",region:"us-east-1",method:"GET",path:"/2020-05-31/key-group"});return this.collectionItems(t.KeyGroupList??t,"KeyGroupSummary").map((r)=>({Id:String(r.KeyGroup?.Id??r.Id),Name:String(r.KeyGroup?.KeyGroupConfig?.Name??r.KeyGroupConfig?.Name??r.Name),Items:this.collectionItems(r.KeyGroup?.KeyGroupConfig?.Items??r.KeyGroupConfig?.Items??r.Items,"Item").map(String),Comment:r.KeyGroup?.KeyGroupConfig?.Comment??r.KeyGroupConfig?.Comment??r.Comment}))}async createKeyGroup(t){if(!/^[A-Za-z0-9_-]{1,128}$/.test(t.name))throw TypeError("CloudFront key group name is invalid");let e=[...new Set(t.publicKeyIds)];if(e.length===0)throw TypeError("CloudFront key group requires at least one public key");let r=(c)=>c.replaceAll("&","&").replaceAll("<","<").replaceAll(">",">"),d=e.map((c)=>`<Item>${r(c)}</Item>`).join(""),E=await this.client.request({service:"cloudfront",region:"us-east-1",method:"POST",path:"/2020-05-31/key-group",headers:{"Content-Type":"application/xml"},body:`<KeyGroupConfig xmlns="http://cloudfront.amazonaws.com/doc/2020-05-31/"><Name>${r(t.name)}</Name><Items>${d}</Items><Comment>${r(t.comment??"")}</Comment></KeyGroupConfig>`}),n=E.KeyGroup??E;return{Id:String(n.Id),Name:String(n.KeyGroupConfig?.Name??t.name),Items:e,Comment:String(n.KeyGroupConfig?.Comment??t.comment??"")}}static getS3BucketPolicyForCloudFront(t,e){return{Version:"2012-10-17",Statement:[{Sid:"AllowCloudFrontServicePrincipal",Effect:"Allow",Principal:{Service:"cloudfront.amazonaws.com"},Action:"s3:GetObject",Resource:`arn:aws:s3:::${t}/*`,Condition:{StringEquals:{"AWS:SourceArn":e}}}]}}async waitForDistributionDeployed(t,e=60){for(let r=0;r<e;r++){if((await this.getDistribution(t)).Status==="Deployed")return!0;await new Promise((E)=>setTimeout(E,30000))}return!1}async disableDistribution(t){let e=await this.client.request({service:"cloudfront",region:"us-east-1",method:"GET",path:`/2020-05-31/distribution/${t}/config`,returnHeaders:!0}),r=e.headers?.etag||e.headers?.ETag||"",d=e.body?.DistributionConfig||(e.body?.Enabled!==void 0?e.body:void 0)||e.DistributionConfig;if(!d||d.Enabled===void 0)throw Error("Failed to get current distribution config");d.Enabled=!1;let E=this.buildDistributionConfigXml(d),n=await this.client.request({service:"cloudfront",region:"us-east-1",method:"PUT",path:`/2020-05-31/distribution/${t}/config`,body:E,headers:{"Content-Type":"application/xml","If-Match":r},returnHeaders:!0});return{ETag:n.headers?.etag||n.headers?.ETag||n.ETag||""}}async deleteDistribution(t,e){let r=e||"";if(!r){let d=await this.client.request({service:"cloudfront",region:"us-east-1",method:"GET",path:`/2020-05-31/distribution/${t}`,returnHeaders:!0});r=d.headers?.etag||d.headers?.ETag||""}await this.client.request({service:"cloudfront",region:"us-east-1",method:"DELETE",path:`/2020-05-31/distribution/${t}`,headers:{"If-Match":r}})}async waitForDistributionDisabled(t,e=60){for(let r=0;r<e;r++){let d=await this.getDistribution(t);if(d.Status==="Deployed"&&!d.Enabled)return!0;await new Promise((E)=>setTimeout(E,30000))}return!1}async removeAlias(t,e){let r=await this.client.request({service:"cloudfront",region:"us-east-1",method:"GET",path:`/2020-05-31/distribution/${t}/config`,returnHeaders:!0}),d=r.headers?.etag||r.headers?.ETag||"",E=r.body?.DistributionConfig||(r.body?.Enabled!==void 0?r.body:void 0)||r.DistributionConfig;if(!E||E.Enabled===void 0)throw Error("Failed to get current distribution config");let n=[];if(E.Aliases?.Items){if(Array.isArray(E.Aliases.Items))n=E.Aliases.Items;else if(typeof E.Aliases.Items==="object"){let i=E.Aliases.Items.CNAME;if(typeof i==="string")n=[i];else if(Array.isArray(i))n=i}}if(n.length===0)throw Error("Distribution has no aliases to remove");let c=n.filter((i)=>i!==e);if(c.length===n.length)throw Error(`Alias ${e} not found in distribution`);if(E.Aliases.Quantity=c.length,E.Aliases.Items=c.length>0?c:void 0,c.length===0)E.ViewerCertificate={CloudFrontDefaultCertificate:!0,MinimumProtocolVersion:"TLSv1.2_2021"};let _=this.buildDistributionConfigXml(E),T=await this.client.request({service:"cloudfront",region:"us-east-1",method:"PUT",path:`/2020-05-31/distribution/${t}/config`,body:_,headers:{"Content-Type":"application/xml","If-Match":d},returnHeaders:!0});return{ETag:T.headers?.etag||T.headers?.ETag||T.ETag||""}}}n_();Lt();Lt();n_();function MD(t,e=""){return t===408||t===409||t===425||t===429||t>=500||/rate limit|temporar|timed? ?out|try again/i.test(e)}async function WA(t,e){let r=e?.headers.get("retry-after"),d=r===null||r===void 0?void 0:Number(r)*1000,E=Number.isFinite(d)?Math.max(0,d):Math.min(1000*2**(t-1),30000);await new Promise((n)=>setTimeout(n,E))}class pn{name="porkbun";apiKey;secretKey;requestTimeoutMs;constructor(t,e,r=15000){this.apiKey=t,this.secretKey=e,this.requestTimeoutMs=r}async request(t,e={}){let r;for(let d=1;d<=8;d+=1){let E,n=new AbortController,c=setTimeout(()=>{n.abort(Error(`Porkbun API request timed out after ${this.requestTimeoutMs}ms`))},this.requestTimeoutMs);try{E=await fetch(`https://api.porkbun.com/api/json/v3${t}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({apikey:this.apiKey,secretapikey:this.secretKey,...e}),signal:n.signal})}catch(T){if(r=T,d===8)throw T;await WA(d);continue}finally{clearTimeout(c)}if(!E.ok){if(r=Error(`Porkbun API error: ${E.status} ${E.statusText}`),!MD(E.status)||d===8)throw r;await WA(d,E);continue}let _=await E.json();if(_.status==="ERROR"){if(r=Error(`Porkbun API error: ${_.message||"Unknown error"}`),!MD(0,_.message)||d===8)throw r;await WA(d,E);continue}return _}throw r}getSubdomain(t,e){let r=t.replace(/\.$/,""),d=e.replace(/\.$/,"");if(r===d)return"";if(r.endsWith(`.${d}`))return r.slice(0,-(d.length+1));return r}getRootDomain(t){let e=t.replace(/\.$/,"").split(".");if(e.length>=2)return e.slice(-2).join(".");return t}static ADDRESS_TYPES=new Set(["A","AAAA"]);async clearConflictingAliases(t,e){if(!pn.ADDRESS_TYPES.has(e.type))return[];let r=this.getRootDomain(t),d=this.getSubdomain(e.name,r),E=await this.listRecords(t);if(!E.success)return[`could not list records to clear ALIAS/CNAME conflicts: ${E.message??"unknown provider error"}`];let n=[];for(let c of E.records){if(c.type!=="ALIAS"&&c.type!=="CNAME")continue;if(this.getSubdomain(c.name,r)!==d)continue;let _=await this.deleteRecord(t,c);if(!_.success)n.push(`could not remove conflicting ${c.type} on ${c.name}: ${_.message??"unknown provider error"}`)}return n}async addressRecordExists(t,e){let r=this.getRootDomain(t),d=this.getSubdomain(e.name,r),E=await this.listRecords(t);if(!E.success)return!0;return E.records.some((n)=>n.type===e.type&&this.getSubdomain(n.name,r)===d&&n.content===e.content)}async createRecord(t,e){try{let r=this.getRootDomain(t),d=this.getSubdomain(e.name,r),E={type:e.type,content:e.content,ttl:String(e.ttl||600)};if(d)E.name=d;if((e.type==="MX"||e.type==="SRV")&&e.priority!==void 0)E.prio=String(e.priority);if(e.type==="SRV"&&e.weight!==void 0&&e.port!==void 0)E.content=`${e.weight} ${e.port} ${e.content}`;let n=await this.clearConflictingAliases(t,e),c=await this.request(`/dns/create/${r}`,E);if(pn.ADDRESS_TYPES.has(e.type)&&!await this.addressRecordExists(t,e))return{success:!1,message:`Porkbun reported success but no ${e.type} record for ${e.name} exists${n.length>0?` (${n.join("; ")})`:""}. A conflicting ALIAS/CNAME on the same name silently voids the write.`};return{success:!0,id:c.id?.toString(),message:"Record created successfully"}}catch(r){return{success:!1,message:r instanceof Error?r.message:"Unknown error"}}}async upsertRecord(t,e){try{let r=this.getRootDomain(t),d=this.getSubdomain(e.name,r),E=await this.listRecords(t,e.type);if(E.success){let n=E.records.find((c)=>{return this.getSubdomain(c.name,r)===d&&c.type===e.type});if(n?.id){let c={type:e.type,content:e.content,ttl:String(e.ttl||600)};if(d)c.name=d;if((e.type==="MX"||e.type==="SRV")&&e.priority!==void 0)c.prio=String(e.priority);if(e.type==="SRV"&&e.weight!==void 0&&e.port!==void 0)c.content=`${e.weight} ${e.port} ${e.content}`;return await this.request(`/dns/edit/${r}/${n.id}`,c),{success:!0,id:n.id,message:"Record updated successfully"}}}return this.createRecord(t,e)}catch(r){return this.createRecord(t,e)}}async deleteRecord(t,e){try{let r=this.getRootDomain(t);if("id"in e&&e.id)return await this.request(`/dns/delete/${r}/${e.id}`),{success:!0,message:"Record deleted successfully"};let d=this.getSubdomain(e.name,r),E=await this.listRecords(t);if(!E.success)return{success:!1,message:"Failed to list records"};let n=E.records.find((c)=>{return this.getSubdomain(c.name,r)===d&&c.type===e.type&&c.content===e.content});if(!n?.id)return{success:!1,message:"Record not found"};return await this.request(`/dns/delete/${r}/${n.id}`),{success:!0,message:"Record deleted successfully"}}catch(r){return{success:!1,message:r instanceof Error?r.message:"Unknown error"}}}async listRecords(t,e){try{let r=this.getRootDomain(t),d=`/dns/retrieve/${r}`;if(e)d=`/dns/retrieveByNameType/${r}/${e}`;return{success:!0,records:((await this.request(d)).records||[]).map((c)=>({id:c.id,name:c.name||r,type:c.type,content:c.content,ttl:Number.parseInt(c.ttl,10),priority:c.prio?Number.parseInt(c.prio,10):void 0}))}}catch(r){return{success:!1,records:[],message:r instanceof Error?r.message:"Unknown error"}}}async canManageDomain(t){try{let e=this.getRootDomain(t);return await this.request(`/dns/retrieve/${e}`),!0}catch{return!1}}async listDomains(){try{return((await this.request("/domain/listAll")).domains||[]).map((e)=>e.domain)}catch{return[]}}async getNameServers(t){try{let e=this.getRootDomain(t);return(await this.request(`/dns/getNS/${e}`)).ns||[]}catch{return[]}}async updateNameServers(t,e){try{let r=this.getRootDomain(t);return await this.request(`/dns/updateNS/${r}`,{ns:e}),!0}catch{return!1}}}class pi{name="godaddy";apiKey;apiSecret;baseUrl;constructor(t,e,r="production"){this.apiKey=t,this.apiSecret=e,this.baseUrl=r==="ote"?"https://api.ote-godaddy.com":"https://api.godaddy.com"}async request(t,e,r){let d=`${this.baseUrl}${e}`,E={Authorization:`sso-key ${this.apiKey}:${this.apiSecret}`,"Content-Type":"application/json",Accept:"application/json"},n={method:t,headers:E};if(r)n.body=JSON.stringify(r);let c=await fetch(d,n);if(c.status===204)return{};if(c.ok){let T=await c.text();if(T)return JSON.parse(T);return{}}let _=`GoDaddy API error: ${c.status} ${c.statusText}`;try{let T=await c.json();if(T.message)_=`GoDaddy API error: ${T.message}`;if(T.fields)_+=` - Fields: ${JSON.stringify(T.fields)}`}catch{}throw Error(_)}getSubdomain(t,e){let r=t.replace(/\.$/,""),d=e.replace(/\.$/,"");if(r===d)return"@";if(r.endsWith(`.${d}`))return r.slice(0,-(d.length+1));return r}getRootDomain(t){let e=t.replace(/\.$/,"").split(".");if(e.length>=2)return e.slice(-2).join(".");return t}toGoDaddyRecord(t,e){let r=this.getRootDomain(e),d=this.getSubdomain(t.name,r),E={type:t.type,name:d,data:t.content,ttl:t.ttl||600};if(t.type==="MX"&&t.priority!==void 0)E.priority=t.priority;return E}fromGoDaddyRecord(t,e){let r=this.getRootDomain(e),d=t.name;if(d==="@")d=r;else if(!d.endsWith(r))d=`${d}.${r}`;return{name:d,type:t.type,content:t.data,ttl:t.ttl,priority:t.priority}}async createRecord(t,e){try{let r=this.getRootDomain(t),d=this.toGoDaddyRecord(e,t);return await this.request("PATCH",`/v1/domains/${r}/records`,[d]),{success:!0,message:"Record created successfully"}}catch(r){return{success:!1,message:r instanceof Error?r.message:"Unknown error"}}}async upsertRecord(t,e){try{let r=this.getRootDomain(t),d=this.toGoDaddyRecord(e,t);return await this.request("PUT",`/v1/domains/${r}/records/${e.type}/${d.name}`,[d]),{success:!0,message:"Record upserted successfully"}}catch(r){return this.createRecord(t,e)}}async deleteRecord(t,e){try{let r=this.getRootDomain(t),d=this.getSubdomain(e.name,r),E=await this.request("GET",`/v1/domains/${r}/records/${e.type}/${d}`),n=E.filter((c)=>c.data!==e.content);if(n.length===E.length)return{success:!1,message:"Record not found"};if(n.length===0)try{await this.request("DELETE",`/v1/domains/${r}/records/${e.type}/${d}`)}catch{}else await this.request("PUT",`/v1/domains/${r}/records/${e.type}/${d}`,n);return{success:!0,message:"Record deleted successfully"}}catch(r){return{success:!1,message:r instanceof Error?r.message:"Unknown error"}}}async listRecords(t,e){try{let r=this.getRootDomain(t),d=`/v1/domains/${r}/records`;if(e)d=`/v1/domains/${r}/records/${e}`;return{success:!0,records:(await this.request("GET",d)).map((n)=>this.fromGoDaddyRecord(n,t))}}catch(r){return{success:!1,records:[],message:r instanceof Error?r.message:"Unknown error"}}}async canManageDomain(t){try{let e=this.getRootDomain(t);return await this.request("GET",`/v1/domains/${e}`),!0}catch{return!1}}async listDomains(){try{return(await this.request("GET","/v1/domains")).map((e)=>e.domain)}catch{return[]}}async getDomainDetails(t){try{let e=this.getRootDomain(t),r=await this.request("GET",`/v1/domains/${e}`);return{domain:r.domain,status:r.status,nameServers:r.nameServers,expires:r.expires}}catch{return null}}async updateNameServers(t,e){try{let r=this.getRootDomain(t);return await this.request("PUT",`/v1/domains/${r}/records/NS`,e.map((d)=>({type:"NS",name:"@",data:d,ttl:3600}))),!0}catch{return!1}}async checkDomainAvailability(t){try{let e=await this.request("GET",`/v1/domains/available?domain=${encodeURIComponent(t)}`);return{available:e.available,price:e.price,currency:e.currency}}catch{return{available:!1}}}}class th{name="cloudflare";apiToken;zoneCache=new Map;constructor(t){this.apiToken=t}async request(t,e,r){let d=`https://api.cloudflare.com/client/v4${e}`,E={Authorization:`Bearer ${this.apiToken}`,"Content-Type":"application/json"},n={method:t,headers:E};if(r)n.body=JSON.stringify(r);let _=await(await fetch(d,n)).json();if(!_.success){let T=_.errors.map((i)=>i.message).join(", ");throw Error(`Cloudflare API error: ${T}`)}return _}getRootDomain(t){let e=t.replace(/\.$/,"").split(".");if(e.length>=2)return e.slice(-2).join(".");return t}async getZoneId(t){let e=this.getRootDomain(t),r=this.zoneCache.get(e);if(r)return r;let d=await this.request("GET",`/zones?name=${encodeURIComponent(e)}`);if(!d.result||d.result.length===0)throw Error(`Zone not found for domain: ${e}`);let E=d.result[0].id;return this.zoneCache.set(e,E),E}getFullRecordName(t,e){let r=this.getRootDomain(e),d=t.replace(/\.$/,"");if(!d||d===r||d==="@")return r;if(d.endsWith(`.${r}`))return d;return`${d}.${r}`}toCloudflareRecord(t,e){let r={type:t.type,name:this.getFullRecordName(t.name,e),content:t.content||t.value||"",ttl:t.ttl||1};if(t.type==="MX"&&t.priority!==void 0)r.priority=t.priority;if(t.type==="SRV"){if(t.priority!==void 0)r.priority=t.priority}return r}fromCloudflareRecord(t){return{id:t.id,name:t.name,type:t.type,content:t.content,ttl:t.ttl,priority:t.priority}}async createRecord(t,e){try{let r=await this.getZoneId(t),d=this.toCloudflareRecord(e,t);return{success:!0,id:(await this.request("POST",`/zones/${r}/dns_records`,d)).result.id,message:"Record created successfully"}}catch(r){return{success:!1,message:r instanceof Error?r.message:"Unknown error"}}}async upsertRecord(t,e){try{let r=await this.getZoneId(t),d=this.getFullRecordName(e.name,t),E=await this.request("GET",`/zones/${r}/dns_records?type=${e.type}&name=${encodeURIComponent(d)}`),n=this.toCloudflareRecord(e,t);if(E.result&&E.result.length>0){let _=E.result[0].id;return{success:!0,id:(await this.request("PUT",`/zones/${r}/dns_records/${_}`,n)).result.id,message:"Record updated successfully"}}return{success:!0,id:(await this.request("POST",`/zones/${r}/dns_records`,n)).result.id,message:"Record created successfully"}}catch(r){return this.createRecord(t,e)}}async deleteRecord(t,e){try{let r=await this.getZoneId(t),d=this.getFullRecordName(e.name,t),E=await this.request("GET",`/zones/${r}/dns_records?type=${e.type}&name=${encodeURIComponent(d)}`);if(!E.result||E.result.length===0)return{success:!1,message:"Record not found"};let n=E.result.find((c)=>c.content===e.content);if(!n)return{success:!1,message:"Record with matching content not found"};return await this.request("DELETE",`/zones/${r}/dns_records/${n.id}`),{success:!0,message:"Record deleted successfully"}}catch(r){return{success:!1,message:r instanceof Error?r.message:"Unknown error"}}}async listRecords(t,e){try{let d=`/zones/${await this.getZoneId(t)}/dns_records?per_page=100`;if(e)d+=`&type=${e}`;let E=[],n=1,c=!0;while(c){let _=await this.request("GET",`${d}&page=${n}`);if(E.push(..._.result||[]),_.result_info)c=n<_.result_info.total_pages,n++;else c=!1}return{success:!0,records:E.map((_)=>this.fromCloudflareRecord(_))}}catch(r){return{success:!1,records:[],message:r instanceof Error?r.message:"Unknown error"}}}async canManageDomain(t){try{return await this.getZoneId(t),!0}catch{return!1}}async listDomains(){try{let t=[],e=1,r=!0;while(r){let d=await this.request("GET",`/zones?per_page=50&page=${e}`);if(t.push(...d.result||[]),d.result_info)r=e<d.result_info.total_pages,e++;else r=!1}return t.map((d)=>d.name)}catch{return[]}}async getZoneDetails(t){try{let e=await this.getZoneId(t),r=await this.request("GET",`/zones/${e}`);return{id:r.result.id,name:r.result.name,status:r.result.status,nameServers:r.result.name_servers,paused:r.result.paused}}catch{return null}}async purgeCache(t,e){try{let r=await this.getZoneId(t),d={};if(e?.purgeEverything)d.purge_everything=!0;else{if(e?.files)d.files=e.files;if(e?.tags)d.tags=e.tags;if(e?.hosts)d.hosts=e.hosts}if(Object.keys(d).length===0)d.purge_everything=!0;return await this.request("POST",`/zones/${r}/purge_cache`,d),!0}catch{return!1}}async getRecordProxyStatus(t,e){try{let r=await this.getZoneId(t),d=this.getFullRecordName(e.name,t),E=await this.request("GET",`/zones/${r}/dns_records?type=${e.type}&name=${encodeURIComponent(d)}`);if(E.result&&E.result.length>0)return E.result.find((c)=>c.content===e.content)?.proxied??null;return null}catch{return null}}async setRecordProxyStatus(t,e,r){try{let d=await this.getZoneId(t),E=this.getFullRecordName(e.name,t),n=await this.request("GET",`/zones/${d}/dns_records?type=${e.type}&name=${encodeURIComponent(E)}`);if(!n.result||n.result.length===0)return!1;let c=n.result.find((_)=>_.content===e.content);if(!c)return!1;return await this.request("PATCH",`/zones/${d}/dns_records/${c.id}`,{proxied:r}),!0}catch{return!1}}}n_();class eh{name="route53";client;hostedZoneCache=new Map;providedHostedZoneId;constructor(t="us-east-1",e){this.client=new Md(t),this.providedHostedZoneId=e}getRootDomain(t){let e=t.replace(/\.$/,"").split(".");if(e.length>=2)return e.slice(-2).join(".");return t}async getHostedZoneId(t){if(this.providedHostedZoneId)return this.providedHostedZoneId;let e=this.getRootDomain(t),r=this.hostedZoneCache.get(e);if(r)return r;let d=await this.client.findHostedZoneForDomain(t);if(d){let E=d.Id.replace("/hostedzone/","");return this.hostedZoneCache.set(e,E),E}return null}normalizeName(t,e){let r=t.replace(/\.$/,""),d=e.replace(/\.$/,"");if(!d||d==="@")return`${r}.`;if(d===r||d.endsWith(`.${r}`))return`${d}.`;return`${d}.${r}.`}async createRecord(t,e){try{let r=await this.getHostedZoneId(t);if(!r)return{success:!1,message:`No hosted zone found for domain: ${t}`};let d=this.normalizeName(t,e.name),E=e.content;if(e.type==="TXT"&&!E.startsWith('"'))E=`"${E}"`;if(e.type==="MX"&&e.priority!==void 0)E=`${e.priority} ${E}`;return{success:!0,id:(await this.client.changeResourceRecordSets({HostedZoneId:r,ChangeBatch:{Comment:"Created by ts-cloud DNS provider",Changes:[{Action:"CREATE",ResourceRecordSet:{Name:d,Type:e.type,TTL:e.ttl||300,ResourceRecords:[{Value:E}]}}]}})).ChangeInfo?.Id,message:"Record created successfully"}}catch(r){return{success:!1,message:r instanceof Error?r.message:"Unknown error"}}}async upsertRecord(t,e){try{let r=await this.getHostedZoneId(t);if(!r)return{success:!1,message:`No hosted zone found for domain: ${t}`};let d=this.normalizeName(t,e.name),E=e.content;if(e.type==="TXT"&&!E.startsWith('"'))E=`"${E}"`;if(e.type==="MX"&&e.priority!==void 0)E=`${e.priority} ${E}`;return{success:!0,id:(await this.client.changeResourceRecordSets({HostedZoneId:r,ChangeBatch:{Comment:"Upserted by ts-cloud DNS provider",Changes:[{Action:"UPSERT",ResourceRecordSet:{Name:d,Type:e.type,TTL:e.ttl||300,ResourceRecords:[{Value:E}]}}]}})).ChangeInfo?.Id,message:"Record upserted successfully"}}catch(r){return{success:!1,message:r instanceof Error?r.message:"Unknown error"}}}async deleteRecord(t,e){try{let r=await this.getHostedZoneId(t);if(!r)return{success:!1,message:`No hosted zone found for domain: ${t}`};let d=this.normalizeName(t,e.name),E=e.content;if(e.type==="TXT"&&!E.startsWith('"'))E=`"${E}"`;if(e.type==="MX"&&e.priority!==void 0)E=`${e.priority} ${E}`;return await this.client.changeResourceRecordSets({HostedZoneId:r,ChangeBatch:{Comment:"Deleted by ts-cloud DNS provider",Changes:[{Action:"DELETE",ResourceRecordSet:{Name:d,Type:e.type,TTL:e.ttl||300,ResourceRecords:[{Value:E}]}}]}}),{success:!0,message:"Record deleted successfully"}}catch(r){return{success:!1,message:r instanceof Error?r.message:"Unknown error"}}}async listRecords(t,e){try{let r=await this.getHostedZoneId(t);if(!r)return{success:!1,records:[],message:`No hosted zone found for domain: ${t}`};let d=await this.client.listResourceRecordSets({HostedZoneId:r,StartRecordType:e}),E=[];for(let n of d.ResourceRecordSets){if(e&&n.Type!==e)continue;if(n.AliasTarget)continue;for(let c of n.ResourceRecords||[]){let _=c.Value,T;if(n.Type==="MX"){let i=_.split(" ");if(i.length>=2)T=Number.parseInt(i[0],10),_=i.slice(1).join(" ")}if(n.Type==="TXT"&&_.startsWith('"')&&_.endsWith('"'))_=_.slice(1,-1);E.push({name:n.Name.replace(/\.$/,""),type:n.Type,content:_,ttl:n.TTL,priority:T})}}return{success:!0,records:E}}catch(r){return{success:!1,records:[],message:r instanceof Error?r.message:"Unknown error"}}}async canManageDomain(t){return await this.getHostedZoneId(t)!==null}async listDomains(){try{return(await this.client.listHostedZones()).HostedZones.map((e)=>e.Name.replace(/\.$/,""))}catch{return[]}}getRoute53Client(){return this.client}async createAliasRecord(t){try{let e=await this.getHostedZoneId(t.domain);if(!e)return{success:!1,message:`No hosted zone found for domain: ${t.domain}`};return{success:!0,id:(await this.client.createAliasRecord({HostedZoneId:e,Name:this.normalizeName(t.domain,t.name),TargetHostedZoneId:t.targetHostedZoneId,TargetDNSName:t.targetDnsName,EvaluateTargetHealth:t.evaluateTargetHealth,Type:t.type})).ChangeInfo?.Id,message:"Alias record created successfully"}}catch(e){return{success:!1,message:e instanceof Error?e.message:"Unknown error"}}}async createCloudFrontAlias(t){return this.createAliasRecord({domain:t.domain,name:t.name,targetHostedZoneId:Md.CloudFrontHostedZoneId,targetDnsName:t.cloudFrontDomainName,evaluateTargetHealth:!1})}async createAlbAlias(t){let e=Md.ALBHostedZoneIds[t.region];if(!e)return{success:!1,message:`Unknown region for ALB: ${t.region}`};return this.createAliasRecord({domain:t.domain,name:t.name,targetHostedZoneId:e,targetDnsName:t.albDnsName,evaluateTargetHealth:!0})}}function f_(t){switch(t.provider){case"route53":return new eh(t.region,t.hostedZoneId);case"porkbun":return new pn(t.apiKey,t.secretKey);case"godaddy":return new pi(t.apiKey,t.apiSecret,t.environment);case"cloudflare":return new th(t.apiToken);default:throw Error(`Unknown DNS provider: ${t.provider}`)}}class GD{providers=new Map;configs=[];addConfig(t){return this.configs.push(t),this}addRoute53(t,e){return this.configs.push({provider:"route53",region:t,hostedZoneId:e}),this}addPorkbun(t,e){return this.configs.push({provider:"porkbun",apiKey:t,secretKey:e}),this}addGoDaddy(t,e,r){return this.configs.push({provider:"godaddy",apiKey:t,apiSecret:e,environment:r}),this}addCloudflare(t){return this.configs.push({provider:"cloudflare",apiToken:t}),this}loadFromEnv(){if(process.env.AWS_ACCESS_KEY_ID||process.env.AWS_REGION)this.addRoute53(process.env.AWS_REGION);let t=process.env.PORKBUN_API_KEY,e=process.env.PORKBUN_SECRET_KEY;if(t&&e)this.addPorkbun(t,e);let r=process.env.GODADDY_API_KEY,d=process.env.GODADDY_API_SECRET;if(r&&d){let n=process.env.GODADDY_ENVIRONMENT;this.addGoDaddy(r,d,n)}let E=process.env.CLOUDFLARE_API_TOKEN;if(E)this.addCloudflare(E);return this}getProvider(t){let e=this.providers.get(t);if(e)return e;let r=this.configs.find((E)=>E.provider===t);if(!r)return null;let d=f_(r);return this.providers.set(t,d),d}async getProviderForDomain(t){for(let e of this.configs){let r=f_(e);if(await r.canManageDomain(t))return r}return null}getAllProviders(){return this.configs.map((t)=>f_(t))}}var T4=new GD;VD();Lt();class U_{client;region;constructor(t="us-east-1",e){this.region=t,this.client=new dt(void 0,{profile:e})}async describeServices(t){let e={cluster:t.cluster,services:t.services};return await this.client.request({service:"ecs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonEC2ContainerServiceV20141113.DescribeServices","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(e)})}async listServices(t,e={}){let r={cluster:t,...e};return await this.client.request({service:"ecs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonEC2ContainerServiceV20141113.ListServices","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(r)})}async listTasks(t,e,r={}){let d={cluster:t,...r};if(e)d.serviceName=e;return await this.client.request({service:"ecs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonEC2ContainerServiceV20141113.ListTasks","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(d)})}async describeTasks(t,e){let r={cluster:t,tasks:e};return await this.client.request({service:"ecs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonEC2ContainerServiceV20141113.DescribeTasks","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(r)})}async updateService(t){let e={cluster:t.cluster,service:t.service};if(t.forceNewDeployment!==void 0)e.forceNewDeployment=t.forceNewDeployment;if(t.desiredCount!==void 0)e.desiredCount=t.desiredCount;if(t.taskDefinition)e.taskDefinition=t.taskDefinition;return await this.client.request({service:"ecs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonEC2ContainerServiceV20141113.UpdateService","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(e)})}async createService(t){let e={cluster:t.cluster,serviceName:t.serviceName,taskDefinition:t.taskDefinition,desiredCount:t.desiredCount};if(t.launchType)e.launchType=t.launchType;if(t.networkConfiguration)e.networkConfiguration=t.networkConfiguration;if(t.loadBalancers)e.loadBalancers=t.loadBalancers;if(t.healthCheckGracePeriodSeconds!==void 0)e.healthCheckGracePeriodSeconds=t.healthCheckGracePeriodSeconds;if(t.deploymentConfiguration)e.deploymentConfiguration=t.deploymentConfiguration;return await this.client.request({service:"ecs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonEC2ContainerServiceV20141113.CreateService","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(e)})}async deleteService(t){let e={cluster:t.cluster,service:t.service};if(t.force!==void 0)e.force=t.force;return await this.client.request({service:"ecs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonEC2ContainerServiceV20141113.DeleteService","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(e)})}async listClusters(t={}){return await this.client.request({service:"ecs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonEC2ContainerServiceV20141113.ListClusters","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(t)})}async describeClusters(t){let e={clusters:t,include:["ATTACHMENTS","CONFIGURATIONS","SETTINGS","STATISTICS","TAGS"]};return await this.client.request({service:"ecs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonEC2ContainerServiceV20141113.DescribeClusters","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(e)})}async stopTask(t){let e={cluster:t.cluster,task:t.task};if(t.reason)e.reason=t.reason;return await this.client.request({service:"ecs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonEC2ContainerServiceV20141113.StopTask","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(e)})}async runTask(t){let e={cluster:t.cluster,taskDefinition:t.taskDefinition};if(t.count!==void 0)e.count=t.count;if(t.launchType)e.launchType=t.launchType;if(t.networkConfiguration)e.networkConfiguration=t.networkConfiguration;if(t.overrides)e.overrides=t.overrides;return await this.client.request({service:"ecs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonEC2ContainerServiceV20141113.RunTask","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(e)})}async registerTaskDefinition(t){return await this.client.request({service:"ecs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonEC2ContainerServiceV20141113.RegisterTaskDefinition","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(t)})}async deregisterTaskDefinition(t){return await this.client.request({service:"ecs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonEC2ContainerServiceV20141113.DeregisterTaskDefinition","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify({taskDefinition:t})})}async describeTaskDefinition(t){return await this.client.request({service:"ecs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonEC2ContainerServiceV20141113.DescribeTaskDefinition","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify({taskDefinition:t,include:["TAGS"]})})}async listTaskDefinitionFamilies(t){let e={};if(t?.familyPrefix)e.familyPrefix=t.familyPrefix;if(t?.status)e.status=t.status;return await this.client.request({service:"ecs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"AmazonEC2ContainerServiceV20141113.ListTaskDefinitionFamilies","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(e)})}async waitForServiceStable(t,e,r=40,d=15000){for(let E=0;E<r;E++){let c=(await this.describeServices({cluster:t,services:[e]})).services?.[0];if(c){let _=c.deployments?.find((T)=>T.status==="PRIMARY");if(_&&_.runningCount===_.desiredCount&&c.deployments?.length===1)return!0}await new Promise((_)=>setTimeout(_,d))}return!1}async forceNewDeployment(t,e){return this.updateService({cluster:t,service:e,forceNewDeployment:!0})}async scaleService(t,e,r){return this.updateService({cluster:t,service:e,desiredCount:r})}}Lt();xT();qT();Lt();Lt();class sd{client;region;constructor(t="us-east-1",e){this.region=t,this.client=new dt}async createQueue(t){let r={Action:"CreateQueue",QueueName:t.fifo&&!t.queueName.endsWith(".fifo")?`${t.queueName}.fifo`:t.queueName,Version:"2012-11-05"},d=1;if(t.visibilityTimeout!==void 0)r[`Attribute.${d}.Name`]="VisibilityTimeout",r[`Attribute.${d}.Value`]=t.visibilityTimeout.toString(),d++;if(t.messageRetentionPeriod!==void 0)r[`Attribute.${d}.Name`]="MessageRetentionPeriod",r[`Attribute.${d}.Value`]=t.messageRetentionPeriod.toString(),d++;if(t.delaySeconds!==void 0)r[`Attribute.${d}.Name`]="DelaySeconds",r[`Attribute.${d}.Value`]=t.delaySeconds.toString(),d++;if(t.maxMessageSize!==void 0)r[`Attribute.${d}.Name`]="MaximumMessageSize",r[`Attribute.${d}.Value`]=t.maxMessageSize.toString(),d++;if(t.receiveMessageWaitTime!==void 0)r[`Attribute.${d}.Name`]="ReceiveMessageWaitTimeSeconds",r[`Attribute.${d}.Value`]=t.receiveMessageWaitTime.toString(),d++;if(t.fifo){if(r[`Attribute.${d}.Name`]="FifoQueue",r[`Attribute.${d}.Value`]="true",d++,t.contentBasedDeduplication)r[`Attribute.${d}.Name`]="ContentBasedDeduplication",r[`Attribute.${d}.Value`]="true",d++}if(t.deadLetterTargetArn&&t.maxReceiveCount)r[`Attribute.${d}.Name`]="RedrivePolicy",r[`Attribute.${d}.Value`]=JSON.stringify({deadLetterTargetArn:t.deadLetterTargetArn,maxReceiveCount:t.maxReceiveCount}),d++;if(t.tags&&Object.keys(t.tags).length>0){let n=1;for(let[c,_]of Object.entries(t.tags))r[`Tag.${n}.Key`]=c,r[`Tag.${n}.Value`]=_,n++}let E=await this.client.request({service:"sqs",region:this.region,method:"POST",path:"/",body:new URLSearchParams(r).toString()});return{QueueUrl:E.QueueUrl||E.CreateQueueResult?.QueueUrl}}async listQueues(t){let e={Action:"ListQueues",Version:"2012-11-05"};if(t)e.QueueNamePrefix=t;let r=await this.client.request({service:"sqs",region:this.region,method:"POST",path:"/",body:new URLSearchParams(e).toString()}),d=[];if(r.QueueUrl)d.push(r.QueueUrl);else if(r.ListQueuesResult?.QueueUrl)if(Array.isArray(r.ListQueuesResult.QueueUrl))d.push(...r.ListQueuesResult.QueueUrl);else d.push(r.ListQueuesResult.QueueUrl);return{QueueUrls:d}}async getQueueAttributes(t){let e={Action:"GetQueueAttributes",QueueUrl:t,Version:"2012-11-05","AttributeName.1":"All"},r=await this.client.request({service:"sqs",region:this.region,method:"POST",path:"/",body:new URLSearchParams(e).toString()});return{Attributes:r.Attributes||r.GetQueueAttributesResult?.Attributes||{}}}async getQueueUrl(t){let e={Action:"GetQueueUrl",QueueName:t,Version:"2012-11-05"},r=await this.client.request({service:"sqs",region:this.region,method:"POST",path:"/",body:new URLSearchParams(e).toString()});return{QueueUrl:r.QueueUrl||r.GetQueueUrlResult?.QueueUrl}}async deleteQueue(t){let e={Action:"DeleteQueue",QueueUrl:t,Version:"2012-11-05"};await this.client.request({service:"sqs",region:this.region,method:"POST",path:"/",body:new URLSearchParams(e).toString()})}async purgeQueue(t){let e={Action:"PurgeQueue",QueueUrl:t,Version:"2012-11-05"};await this.client.request({service:"sqs",region:this.region,method:"POST",path:"/",body:new URLSearchParams(e).toString()})}async sendMessage(t){let e={Action:"SendMessage",QueueUrl:t.queueUrl,MessageBody:t.messageBody,Version:"2012-11-05"};if(t.delaySeconds!==void 0)e.DelaySeconds=t.delaySeconds;if(t.messageGroupId)e.MessageGroupId=t.messageGroupId;if(t.messageDeduplicationId)e.MessageDeduplicationId=t.messageDeduplicationId;let r=await this.client.request({service:"sqs",region:this.region,method:"POST",path:"/",body:new URLSearchParams(e).toString()});return{MessageId:r.MessageId||r.SendMessageResult?.MessageId}}async receiveMessages(t){let e={Action:"ReceiveMessage",QueueUrl:t.queueUrl,Version:"2012-11-05"};if(t.maxMessages!==void 0)e.MaxNumberOfMessages=t.maxMessages;if(t.visibilityTimeout!==void 0)e.VisibilityTimeout=t.visibilityTimeout;if(t.waitTimeSeconds!==void 0)e.WaitTimeSeconds=t.waitTimeSeconds;let r=await this.client.request({service:"sqs",region:this.region,method:"POST",path:"/",body:new URLSearchParams(e).toString()}),d=[],E=r.Message||r.ReceiveMessageResult?.Message;if(E)if(Array.isArray(E))d.push(...E.map((n)=>({MessageId:n.MessageId,ReceiptHandle:n.ReceiptHandle,Body:n.Body})));else d.push({MessageId:E.MessageId,ReceiptHandle:E.ReceiptHandle,Body:E.Body});return{Messages:d}}async deleteMessage(t,e){let r={Action:"DeleteMessage",QueueUrl:t,ReceiptHandle:e,Version:"2012-11-05"};await this.client.request({service:"sqs",region:this.region,method:"POST",path:"/",body:new URLSearchParams(r).toString()})}}Lt();import{deflateRawSync as XP}from"zlib";function KD(t,e){let r=typeof e==="string"?Buffer.from(e,"utf-8"):e,d=XP(r),E=aP(r),n=new Date,c=(n.getHours()<<11|n.getMinutes()<<5|n.getSeconds()>>1)&65535,_=(n.getFullYear()-1980<<9|n.getMonth()+1<<5|n.getDate())&65535,T=Buffer.from(t,"utf-8"),i=Buffer.alloc(30+T.length);i.writeUInt32LE(67324752,0),i.writeUInt16LE(20,4),i.writeUInt16LE(0,6),i.writeUInt16LE(8,8),i.writeUInt16LE(c,10),i.writeUInt16LE(_,12),i.writeUInt32LE(E,14),i.writeUInt32LE(d.length,18),i.writeUInt32LE(r.length,22),i.writeUInt16LE(T.length,26),i.writeUInt16LE(0,28),T.copy(i,30);let h=Buffer.alloc(46+T.length);h.writeUInt32LE(33639248,0),h.writeUInt16LE(20,4),h.writeUInt16LE(20,6),h.writeUInt16LE(0,8),h.writeUInt16LE(8,10),h.writeUInt16LE(c,12),h.writeUInt16LE(_,14),h.writeUInt32LE(E,16),h.writeUInt32LE(d.length,20),h.writeUInt32LE(r.length,24),h.writeUInt16LE(T.length,28),h.writeUInt16LE(0,30),h.writeUInt16LE(0,32),h.writeUInt16LE(0,34),h.writeUInt16LE(0,36),h.writeUInt32LE(0,38),h.writeUInt32LE(0,42),T.copy(h,46);let R=i.length+d.length,N=h.length,A=Buffer.alloc(22);return A.writeUInt32LE(101010256,0),A.writeUInt16LE(0,4),A.writeUInt16LE(0,6),A.writeUInt16LE(1,8),A.writeUInt16LE(1,10),A.writeUInt32LE(N,12),A.writeUInt32LE(R,16),A.writeUInt16LE(0,20),Buffer.concat([i,d,h,A])}function aP(t){let e=[];for(let d=0;d<256;d++){let E=d;for(let n=0;n<8;n++)E=E&1?3988292384^E>>>1:E>>>1;e[d]=E}let r=4294967295;for(let d=0;d<t.length;d++)r=e[(r^t[d])&255]^r>>>8;return(r^4294967295)>>>0}class dr{client;region;constructor(t="us-east-1",e){this.region=t,this.client=new dt(void 0,{profile:e})}async createFunction(t){return await this.client.request({service:"lambda",region:this.region,method:"POST",path:"/2015-03-31/functions",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)})}async getFunction(t){return await this.client.request({service:"lambda",region:this.region,method:"GET",path:`/2015-03-31/functions/${encodeURIComponent(t)}`,headers:{"Content-Type":"application/json"}})}async updateFunctionCode(t){let{FunctionName:e,...r}=t;return await this.client.request({service:"lambda",region:this.region,method:"PUT",path:`/2015-03-31/functions/${encodeURIComponent(e)}/code`,headers:{"Content-Type":"application/json"},body:JSON.stringify(r)})}async updateFunctionCodeInline(t,e,r="index.js"){let d=KD(r,e);return this.updateFunctionCode({FunctionName:t,ZipFile:d.toString("base64")})}async updateFunctionConfiguration(t){let{FunctionName:e,...r}=t;return await this.client.request({service:"lambda",region:this.region,method:"PUT",path:`/2015-03-31/functions/${encodeURIComponent(e)}/configuration`,headers:{"Content-Type":"application/json"},body:JSON.stringify(r)})}async deleteFunction(t){await this.client.request({service:"lambda",region:this.region,method:"DELETE",path:`/2015-03-31/functions/${encodeURIComponent(t)}`,headers:{"Content-Type":"application/json"}})}async invoke(t){let{FunctionName:e,InvocationType:r="RequestResponse",Payload:d,LogType:E}=t,n={"Content-Type":"application/json","X-Amz-Invocation-Type":r};if(E)n["X-Amz-Log-Type"]=E;let c=d?typeof d==="string"?d:JSON.stringify(d):void 0,_=await this.client.request({service:"lambda",region:this.region,method:"POST",path:`/2015-03-31/functions/${encodeURIComponent(e)}/invocations`,headers:n,body:c,returnHeaders:!0});return{StatusCode:_.statusCode||200,FunctionError:_.headers?.["x-amz-function-error"],LogResult:_.headers?.["x-amz-log-result"],Payload:typeof _.body==="string"?_.body:JSON.stringify(_.body),ExecutedVersion:_.headers?.["x-amz-executed-version"]}}async listFunctions(t){let e={};if(t?.MaxItems)e.MaxItems=String(t.MaxItems);if(t?.Marker)e.Marker=t.Marker;if(t?.FunctionVersion)e.FunctionVersion=t.FunctionVersion;return await this.client.request({service:"lambda",region:this.region,method:"GET",path:"/2015-03-31/functions",queryParams:Object.keys(e).length>0?e:void 0,headers:{"Content-Type":"application/json"}})}async addPermission(t){let{FunctionName:e,...r}=t;return await this.client.request({service:"lambda",region:this.region,method:"POST",path:`/2015-03-31/functions/${encodeURIComponent(e)}/policy`,headers:{"Content-Type":"application/json"},body:JSON.stringify(r)})}async removePermission(t,e){await this.client.request({service:"lambda",region:this.region,method:"DELETE",path:`/2015-03-31/functions/${encodeURIComponent(t)}/policy/${encodeURIComponent(e)}`,headers:{"Content-Type":"application/json"}})}async publishVersion(t){let{FunctionName:e,...r}=t;return await this.client.request({service:"lambda",region:this.region,method:"POST",path:`/2015-03-31/functions/${encodeURIComponent(e)}/versions`,headers:{"Content-Type":"application/json"},body:JSON.stringify(r)})}async createAlias(t){let{FunctionName:e,...r}=t;return await this.client.request({service:"lambda",region:this.region,method:"POST",path:`/2015-03-31/functions/${encodeURIComponent(e)}/aliases`,headers:{"Content-Type":"application/json"},body:JSON.stringify(r)})}async updateAlias(t){let{FunctionName:e,Name:r,...d}=t;return this.client.request({service:"lambda",region:this.region,method:"PUT",path:`/2015-03-31/functions/${encodeURIComponent(e)}/aliases/${encodeURIComponent(r)}`,headers:{"Content-Type":"application/json"},body:JSON.stringify(d)})}async getAlias(t,e){try{return await this.client.request({service:"lambda",region:this.region,method:"GET",path:`/2015-03-31/functions/${encodeURIComponent(t)}/aliases/${encodeURIComponent(e)}`})}catch(r){if(/ResourceNotFound/i.test(String(r?.message)))return null;throw r}}async getProvisionedConcurrencyConfig(t,e){try{return await this.client.request({service:"lambda",region:this.region,method:"GET",path:`/2019-09-30/functions/${encodeURIComponent(t)}/provisioned-concurrency`,queryParams:{Qualifier:e}})}catch(r){if(/ProvisionedConcurrencyConfigNotFound|ResourceNotFound/i.test(String(r?.message)))return null;throw r}}async putProvisionedConcurrencyConfig(t){let{FunctionName:e,Qualifier:r,ProvisionedConcurrentExecutions:d}=t;return this.client.request({service:"lambda",region:this.region,method:"PUT",path:`/2019-09-30/functions/${encodeURIComponent(e)}/provisioned-concurrency`,queryParams:{Qualifier:r},headers:{"Content-Type":"application/json"},body:JSON.stringify({ProvisionedConcurrentExecutions:d})})}async deleteProvisionedConcurrencyConfig(t,e){await this.client.request({service:"lambda",region:this.region,method:"DELETE",path:`/2019-09-30/functions/${encodeURIComponent(t)}/provisioned-concurrency`,queryParams:{Qualifier:e}})}async waitForFunctionActive(t,e=60){let r=Date.now(),d=e*1000;while(Date.now()-r<d)try{let E=await this.getFunction(t),n=E.Configuration?.State;if(n==="Active")return E.Configuration;if(n==="Failed")throw Error(`Function ${t} failed: ${E.Configuration?.StateReason}`);await new Promise((c)=>setTimeout(c,2000))}catch(E){if(E.code==="ResourceNotFoundException"){await new Promise((n)=>setTimeout(n,2000));continue}throw E}throw Error(`Timeout waiting for function ${t} to become active`)}async functionExists(t){try{return await this.getFunction(t),!0}catch(e){if(e.code==="ResourceNotFoundException"||e.statusCode===404)return!1;throw e}}async createFunctionUrl(t){let{FunctionName:e,...r}=t;return await this.client.request({service:"lambda",region:this.region,method:"POST",path:`/2021-10-31/functions/${encodeURIComponent(e)}/url`,headers:{"Content-Type":"application/json"},body:JSON.stringify(r)})}async getFunctionUrl(t){try{return await this.client.request({service:"lambda",region:this.region,method:"GET",path:`/2021-10-31/functions/${encodeURIComponent(t)}/url`,headers:{"Content-Type":"application/json"}})}catch(e){if(e.statusCode===404)return null;throw e}}async deleteFunctionUrl(t){await this.client.request({service:"lambda",region:this.region,method:"DELETE",path:`/2021-10-31/functions/${encodeURIComponent(t)}/url`,headers:{"Content-Type":"application/json"}})}async createFunctionWithCode(t){let{Code:e,Filename:r="index.js",...d}=t,E=KD(r,e);return this.createFunction({...d,Code:{ZipFile:E.toString("base64")}})}async addFunctionUrlPermission(t){return this.addPermission({FunctionName:t,StatementId:"FunctionURLAllowPublicAccess",Action:"lambda:InvokeFunctionUrl",Principal:"*",FunctionUrlAuthType:"NONE"})}async publishLayerVersion(t){let{LayerName:e,...r}=t;return await this.client.request({service:"lambda",region:this.region,method:"POST",path:`/2018-10-31/layers/${encodeURIComponent(e)}/versions`,headers:{"Content-Type":"application/json"},body:JSON.stringify(r)})}async listLayerVersions(t,e){let r={};if(e?.CompatibleRuntime)r.CompatibleRuntime=e.CompatibleRuntime;if(e?.CompatibleArchitecture)r.CompatibleArchitecture=e.CompatibleArchitecture;if(e?.MaxItems)r.MaxItems=String(e.MaxItems);if(e?.Marker)r.Marker=e.Marker;return await this.client.request({service:"lambda",region:this.region,method:"GET",path:`/2018-10-31/layers/${encodeURIComponent(t)}/versions`,queryParams:Object.keys(r).length>0?r:void 0,headers:{"Content-Type":"application/json"}})}async getLayerVersion(t,e){return await this.client.request({service:"lambda",region:this.region,method:"GET",path:`/2018-10-31/layers/${encodeURIComponent(t)}/versions/${e}`,headers:{"Content-Type":"application/json"}})}async addLayerVersionPermission(t){let{LayerName:e,VersionNumber:r,...d}=t;return await this.client.request({service:"lambda",region:this.region,method:"POST",path:`/2018-10-31/layers/${encodeURIComponent(e)}/versions/${r}/policy`,headers:{"Content-Type":"application/json"},body:JSON.stringify(d)})}async deleteLayerVersion(t,e){await this.client.request({service:"lambda",region:this.region,method:"DELETE",path:`/2018-10-31/layers/${encodeURIComponent(t)}/versions/${e}`,headers:{"Content-Type":"application/json"}})}}Lt();class w_{client;region;constructor(t="us-east-1",e){this.region=t,this.client=new dt(void 0,{profile:e})}async createLogGroup(t,e){await this.client.request({service:"logs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"Logs_20140328.CreateLogGroup","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify({logGroupName:t,...e?{tags:e}:{}})})}async putRetentionPolicy(t,e){if(![1,3,5,7,14,30,60,90,120,150,180,365,400,545,731,1096,1827,2192,2557,2922,3288,3653].includes(e))throw Error("Unsupported CloudWatch Logs retention period");await this.client.request({service:"logs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"Logs_20140328.PutRetentionPolicy","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify({logGroupName:t,retentionInDays:e})})}async describeLogStreams(t){let e={logGroupName:t.logGroupName};if(t.logStreamNamePrefix)e.logStreamNamePrefix=t.logStreamNamePrefix;if(t.orderBy)e.orderBy=t.orderBy;if(t.descending!==void 0)e.descending=t.descending;if(t.limit)e.limit=t.limit;return await this.client.request({service:"logs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"Logs_20140328.DescribeLogStreams","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(e)})}async getLogEvents(t){let e={logGroupName:t.logGroupName,logStreamName:t.logStreamName};if(t.startTime)e.startTime=t.startTime;if(t.endTime)e.endTime=t.endTime;if(t.limit)e.limit=t.limit;if(t.startFromHead!==void 0)e.startFromHead=t.startFromHead;return await this.client.request({service:"logs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"Logs_20140328.GetLogEvents","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(e)})}async describeLogGroups(t){let e={};if(t?.logGroupNamePrefix)e.logGroupNamePrefix=t.logGroupNamePrefix;if(t?.limit)e.limit=t.limit;return await this.client.request({service:"logs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"Logs_20140328.DescribeLogGroups","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(e)})}async deleteLogGroup(t){await this.client.request({service:"logs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"Logs_20140328.DeleteLogGroup","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify({logGroupName:t})})}async filterLogEvents(t){let e={logGroupName:t.logGroupName};if(t.logStreamNames)e.logStreamNames=t.logStreamNames;if(t.startTime)e.startTime=t.startTime;if(t.endTime)e.endTime=t.endTime;if(t.filterPattern)e.filterPattern=t.filterPattern;if(t.limit)e.limit=t.limit;return await this.client.request({service:"logs",region:this.region,method:"POST",path:"/",headers:{"X-Amz-Target":"Logs_20140328.FilterLogEvents","Content-Type":"application/x-amz-json-1.1"},body:JSON.stringify(e)})}}Lt();Lt();Pn();Lt();Lt();Lt();Lt();Lt();Lt();Lt();Lt();Lt();Lt();Lt();Lt();class vA{client;region;constructor(t="us-east-1"){this.region=t,this.client=new dt}async request(t,e){return this.client.request({service:"events",region:this.region,method:"POST",path:"/",headers:{"Content-Type":"application/x-amz-json-1.1","X-Amz-Target":`AWSEvents.${t}`},body:JSON.stringify(e)})}async putRule(t){return this.request("PutRule",t)}async deleteRule(t){return this.request("DeleteRule",t)}async describeRule(t){return this.request("DescribeRule",t)}async listRules(t){return this.request("ListRules",t||{})}async listEventBuses(t){return this.request("ListEventBuses",t||{})}async enableRule(t){return this.request("EnableRule",t)}async disableRule(t){return this.request("DisableRule",t)}async putTargets(t){return this.request("PutTargets",t)}async removeTargets(t){return this.request("RemoveTargets",t)}async listTargetsByRule(t){return this.request("ListTargetsByRule",t)}async putEvents(t){return this.request("PutEvents",t)}async createSchedule(t){return this.client.request({service:"scheduler",region:this.region,method:"POST",path:`/schedules/${t.Name}`,headers:{"Content-Type":"application/json"},body:JSON.stringify(t)})}}Lt();kT();Lt();tr();tr();xT();tr();tr();Lt();Lt();tr();Lt();class QA{client;region;constructor(t="us-east-1"){this.region=t,this.client=new dt}async describeFileSystems(t){let e=[];if(t?.FileSystemId)e.push(`FileSystemId=${encodeURIComponent(t.FileSystemId)}`);if(t?.CreationToken)e.push(`CreationToken=${encodeURIComponent(t.CreationToken)}`);let r=`/2015-02-01/file-systems${e.length>0?`?${e.join("&")}`:""}`;return{FileSystems:((await this.client.request({service:"elasticfilesystem",region:this.region,method:"GET",path:r,headers:{"Content-Type":"application/json"}})).FileSystems||[]).map((E)=>({FileSystemId:E.FileSystemId,Name:E.Name,CreationTime:E.CreationTime,LifeCycleState:E.LifeCycleState,NumberOfMountTargets:E.NumberOfMountTargets,SizeInBytes:E.SizeInBytes?{Value:E.SizeInBytes.Value,Timestamp:E.SizeInBytes.Timestamp}:void 0,PerformanceMode:E.PerformanceMode,Encrypted:E.Encrypted,ThroughputMode:E.ThroughputMode,Tags:E.Tags}))}}}await Ht();await Ht();import{readFileSync as Af}from"node:fs";import{join as Sj}from"node:path";function od(t){if(!t)return;let e=t.trim();if(!e)return;if(!e.includes("/"))return e;let[r]=e.split("/");if(!r.endsWith("::"))return r||void 0;return`${r}1`}tr();await Ht();var ZD={php:"php.net",nginx:"nginx.org",composer:"getcomposer.org",mysql:"mysql.com",mariadb:"mariadb.com/server",postgres:"postgresql.org",vitess:"vitess.io",etcd:"etcd.io",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"};var We="/opt/pantry";function rh(t){return`'${t.split("'").join("'\\''")}'`}function dh(t={}){return["export DEBIAN_FRONTEND=noninteractive","export PANTRY_SERVICE_SCOPE=system","export PANTRY_INSTALL_DIR=/usr/local/bin",t.version?`export PANTRY_VERSION=${rh(t.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 tc(){return'eval "$(cd /opt/pantry && pantry env 2>/dev/null)" || true'}function md(t){if(t.length===0)return[];return[`(cd /opt/pantry && pantry install ${[...new Set(t)].map(rh).join(" ")})`]}function Eh(t){return[...new Set(t)].flatMap((e)=>[`(cd /opt/pantry && pantry start ${rh(e)})`,`(cd /opt/pantry && pantry enable ${rh(e)})`])}var Ir=`${We}/pantry/.bin`,GA=15306,YA=15991,ch=15999,kD=16101,_h=2379,Cd="/var/lib/vitess",VA=100;function jP(t){return t===!0||typeof t==="object"&&t!==null}function zP(t){return typeof t==="object"&&t!==null?t:{}}function Ue(t){return`'${String(t).split("'").join("'\\''")}'`}function FP(t){let r=[t.version?`vitess.io@${t.version}`:"vitess.io"];if(t.mode!=="combo"&&!t.etcdEndpoint)r.push("etcd.io");return r.push("mysql.com@8.0.43"),r}var lr="vitess",BP=`${Ir}:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin`,sD="/usr/local/lib/vitess",KA=new Map;function MA(t){return`${sD}/${t}.sh`}function ec(t,e){return KA.set(t,JP(e)),`/bin/sh ${MA(t)}`}function bD(){let t=[`mkdir -p ${sD}`];for(let[e,r]of KA)t.push(`cat > ${MA(e)} <<'TS_CLOUD_VITESS_LAUNCHER_EOF'`,r,"TS_CLOUD_VITESS_LAUNCHER_EOF",`chmod 0755 ${MA(e)}`);return t}function JP(t){return["#!/bin/sh","set -e",`cd ${We}`,`PANTRY_ENV="$(pantry env 2>/dev/null | grep -E '^(export [A-Za-z_]|[A-Za-z_][A-Za-z0-9_]*=)' || true)"`,'if [ -n "$PANTRY_ENV" ]; then eval "$PANTRY_ENV"; fi',`VT_MYSQL_ROOT="$(dirname "$(dirname "$(readlink -f ${Ir}/mysqld 2>/dev/null)")")"`,`VTROOT="$(dirname "$(dirname "$(readlink -f ${Ir}/mysqlctld 2>/dev/null)")")"`,"export VT_MYSQL_ROOT VTROOT",'LD_LIBRARY_PATH="$VT_MYSQL_ROOT/lib:$VTROOT/lib${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}"',"export LD_LIBRARY_PATH",`exec ${t.join(" ")}`].join(`
|
|
5764
5764
|
`)}function rc(t){let e=["[Unit]",`Description=${t.description}`,`After=network.target${t.after?.length?` ${t.after.join(" ")}`:""}`];if(t.requires?.length)e.push(`Requires=${t.requires.join(" ")}`);return e.push("","[Service]","Type=simple",`User=${lr}`,`Group=${lr}`,`Environment="PATH=${BP}"`,`Environment="VTDATAROOT=${Cd}"`,...Object.entries(t.environment??{}).map(([r,d])=>`Environment="${r}=${d}"`),...(t.execStartPre??[]).map((r)=>`ExecStartPre=${r}`),`ExecStart=${t.execStart}`,"Restart=always","RestartSec=5","LimitNOFILE=65535","","[Install]","WantedBy=multi-user.target"),e.join(`
|
|
5765
|
-
`)}function xD(t,e){return[`cat > /etc/systemd/system/${t}.service <<'TS_CLOUD_VITESS_UNIT_EOF'`,e,"TS_CLOUD_VITESS_UNIT_EOF"]}function HP(t){let e=t.cell??"zone1",r=t.vtgatePort??GA,E=`${((t.keyspaces?.length)?t.keyspaces:[{name:"app"}]).map((n)=>{let c=(n.sharded?["-80","80-"]:["0"]).map((_)=>`shards:{name:"${_}"}`).join(" ");return`keyspaces:{name:"${n.name}" ${c}}`}).join(" ")} cells:"${e}"`;return rc({description:"Vitess (vtcombo, single-process development stack)",execStart:ec("vtcombo",[`${jr}/vtcombo`,`--cell ${e}`,`--proto-topo ${Ue(E)}`,`--mysql-server-port ${r}`,"--mysql-server-bind-address 127.0.0.1","--mysql-auth-server-impl none","--start-mysql",`--port ${YA}`,`--grpc-port ${ch}`])})}function WP(){return rc({description:"etcd (Vitess topology store)",execStart:ec("etcd",[`${jr}/etcd`,`--data-dir ${Cd}/etcd`,`--listen-client-urls http://127.0.0.1:${_h}`,`--advertise-client-urls http://127.0.0.1:${_h}`]),execStartPre:[`+/bin/mkdir -p ${Cd}/etcd`,`+/bin/chown ${lr}:${lr} ${Cd}/etcd`]})}function ZA(t){return["--topo-implementation etcd2",`--topo-global-server-address ${t.etcdEndpoint??`http://127.0.0.1:${_h}`}`,"--topo-global-root /vitess/global"]}function vP(t){let e=!t.etcdEndpoint;return rc({description:"Vitess vtctld (control plane)",after:e?["vitess-etcd.service"]:[],requires:e?["vitess-etcd.service"]:[],execStart:ec("vtctld",[`${jr}/vtctld`,...ZA(t),`--cell ${t.cell??"zone1"}`,"--service-map grpc-vtctl,grpc-vtctld",`--grpc-port ${ch}`,`--port ${ch+1}`])})}function QP(t,e,r){let d=t.cell??"zone1";return rc({description:`Vitess vttablet (${e}/${r})`,after:["vitess-vtctld.service","vitess-mysqlctld.service"],requires:["vitess-mysqlctld.service"],execStart:ec("vttablet",[`${jr}/vttablet`,...ZA(t),`--tablet-path ${d}-${String(VA).padStart(10,"0")}`,`--init-keyspace ${e}`,`--init-shard ${r}`,"--init-tablet-type replica",`--service-map ${Ue("grpc-queryservice,grpc-tabletmanager,grpc-updatestream")}`,`--port ${kD}`,`--grpc-port ${kD+1}`,`--db-port ${t.mysqlPort??3306}`,`--mycnf-mysql-port ${t.mysqlPort??3306}`])})}function YP(t){return rc({description:"Vitess mysqlctld (managed mysqld)",execStart:ec("mysqlctld",[`${jr}/mysqlctld`,`--tablet-uid ${VA}`,`--mysql-port ${t.mysqlPort??3306}`,'--init-db-sql-file "$VTROOT/config/init_db.sql"',"--wait-time 2m"]),execStartPre:[`+/bin/mkdir -p ${Cd}`,`+/bin/chown ${lr}:${lr} ${Cd}`]})}var nh="/etc/vitess/auth.json";function MP(t){let e=t.username??"vitess",r=t.password??"",d=JSON.stringify({[e]:[{MysqlNativePassword:"",Password:r,UserData:e}]});return["mkdir -p /etc/vitess",`cat > ${nh} <<'TS_CLOUD_VITESS_AUTH_EOF'`,d,"TS_CLOUD_VITESS_AUTH_EOF",`chown ${lr}:${lr} ${nh}`,`chmod 0600 ${nh}`]}function GP(t){let e=t.cell??"zone1";return rc({description:"Vitess vtgate (query router)",after:["vitess-vtctld.service"],execStart:ec("vtgate",[`${jr}/vtgate`,...ZA(t),`--cell ${e}`,`--cells-to-watch ${e}`,"--tablet-types-to-wait PRIMARY,REPLICA",`--service-map ${Ue("grpc-vtgateservice")}`,`--mysql-server-port ${t.vtgatePort??GA}`,`--mysql-server-bind-address ${t.bindAddress??"127.0.0.1"}`,"--mysql-auth-server-impl static",`--mysql-auth-server-static-file ${nh}`,`--port ${YA}`,`--grpc-port ${YA+1}`])})}function VP(t){let e=t.cell??"zone1",r=t.etcdEndpoint??`http://127.0.0.1:${_h}`,d=`${jr}/vtctldclient --server 127.0.0.1:${ch}`,E=[`for i in $(seq 1 30); do ${d} GetCellInfoNames >/dev/null 2>&1 && break; sleep 2; done`,`if ! ${d} GetCellInfoNames 2>/dev/null | grep -qx ${Ue(e)}; then`,` ${d} AddCellInfo --root ${Ue(`/vitess/${e}`)} --server-address ${Ue(r)} ${Ue(e)}`,"fi"];for(let n of t.keyspaces??[]){let c=n.sharded?" --sharded":"";E.push(`if ! ${d} GetKeyspace ${Ue(n.name)} >/dev/null 2>&1; then`,` ${d} CreateKeyspace${c} ${Ue(n.name)}`,"fi");let _=`${e}-${String(VA).padStart(10,"0")}`;for(let T of n.sharded?["-80","80-"]:["0"]){let i=`${n.name}/${T}`;E.push(`for i in $(seq 1 30); do ${d} GetTablet ${Ue(_)} >/dev/null 2>&1 && break; sleep 2; done`,`if ! ${d} GetShard ${Ue(i)} 2>/dev/null | grep -q '"primary_alias"'; then`,` ${d} PlannedReparentShard ${Ue(i)} --new-primary ${Ue(_)} || ${d} InitShardPrimary --force ${Ue(i)} ${Ue(_)}`,"fi")}}return E}function qD(t){let e=t.vtgatePort??GA;return["for i in $(seq 1 60); do",` if (cd ${We} && eval "$(pantry env 2>/dev/null)"; MYSQL_PWD=${Ue(t.password??"")} ${jr}/mysql -h 127.0.0.1 -P ${e} -u ${Ue(t.username??"vitess")} --connect-timeout=2 -e 'SHOW KEYSPACES') >/dev/null 2>&1; then`,` echo "vtgate is serving on ${e}"; exit 0`," fi"," sleep 2","done",`echo "vtgate did not become ready on port ${e}" >&2`,"exit 1"]}function oD(t){if(!jP(t))return[];let e=zP(t),r=e.mode==="combo";KA.clear();let d=[...md(FP(e)),`id -u ${lr} >/dev/null 2>&1 || useradd --system --home-dir ${Cd} --shell /usr/sbin/nologin ${lr}`,`mkdir -p ${Cd}`,`chown -R ${lr}:${lr} ${Cd}`];if(r)return d.push(...xD("vitess-vtcombo",HP(e)),...bD(),"systemctl daemon-reload","systemctl enable --now vitess-vtcombo.service",...qD(e)),d;d.push(...MP(e));let E=[];if(!e.etcdEndpoint)E.push(["vitess-etcd",WP()]);E.push(["vitess-vtctld",vP(e)],["vitess-mysqlctld",YP(e)],["vitess-vtgate",GP(e)]);for(let n of e.keyspaces??[])for(let c of n.sharded?["-80","80-"]:["0"])E.push([`vitess-vttablet-${n.name}-${c.replace(/-/g,"x")}`,QP(e,n.name,c)]);for(let[n,c]of E)d.push(...xD(n,c));d.push(...bD()),d.push("systemctl daemon-reload");for(let[n]of E)d.push(`systemctl enable --now ${n}.service`);return d.push(...VP(e),...qD(e)),d}var KP=new Set(["singlestore","vitess"]);function mD(t){if(t?.engine&&KP.has(t.engine))return!1;return!t?.host||t.host==="127.0.0.1"||t.host==="localhost"}function dc(t,e="psql"){let r=t?.port??5432;if(mD(t))return`${e} -p ${r} -U postgres`;let d=t?.username||"postgres";return`${t?.password?`PGPASSWORD='${t.password.replace(/'/g,"'\\''")}' `:""}${e} -h ${t.host} -p ${r} -U ${d} -w`}function ld(t){return t===!0||typeof t==="object"&&t!=null}function ZP(t){let e=[],r=[];if(ld(t.mysql))e.push(typeof t.mysql==="object"&&t.mysql.version?`mysql.com@${t.mysql.version}`:"mysql.com@8.0.43"),r.push("mysql");else if(ld(t.mariadb))e.push(ZD.mariadb),r.push("mariadb");if(ld(t.postgres))e.push("postgresql.org"),r.push("postgres");if(ld(t.redis))e.push("redis.io"),r.push("redis");if(ld(t.memcached))e.push("memcached.org"),r.push("memcached");if(ld(t.meilisearch))e.push("meilisearch.com"),r.push("meilisearch");return{packages:e,services:r}}function Th(t={},e={}){let r=ZP(t),d=oD(t.vitess);if(r.packages.length===0)return d;return[...md(r.packages),...Eh(r.services),...d]}function g_(t,e={}){if(!t?.name)return[];if(!mD(t))return[];let r=t.name,d=t.username||r,E=t.password||"",n=ld(e.postgres)||t.engine==="postgres",c=ld(e.mariadb)||t.engine==="mariadb",_=ld(e.mysql)||t.engine==="mysql";if(n&&!_&&!c){let A=(P)=>`"${P.replace(/"/g,'""')}"`,u=(P)=>`'${P.replace(/'/g,"''")}'`,f=(P,j)=>["DO $$ BEGIN",` IF NOT EXISTS (SELECT FROM pg_roles WHERE rolname = ${u(P)}) THEN`,` CREATE ROLE ${A(P)} LOGIN PASSWORD ${u(j)};`," ELSE",` ALTER ROLE ${A(P)} LOGIN PASSWORD ${u(j)};`," END IF;","END $$;"],w=(P)=>{let j=P.databases&&P.databases.length>0?P.databases:[r],H=[];for(let F of j)if(P.access==="readonly")H.push(`GRANT CONNECT ON DATABASE ${A(F)} TO ${A(P.username)};`,`\\connect ${A(F)}`,`GRANT USAGE ON SCHEMA public TO ${A(P.username)};`,`GRANT SELECT ON ALL TABLES IN SCHEMA public TO ${A(P.username)};`,`ALTER DEFAULT PRIVILEGES FOR ROLE ${A(d)} IN SCHEMA public GRANT SELECT ON TABLES TO ${A(P.username)};`,"\\connect postgres");else H.push(`GRANT ALL PRIVILEGES ON DATABASE ${A(F)} TO ${A(P.username)};`);return H},I=t.users||[],a=t.port??5432;return[tc(),`for i in $(seq 1 30); do pg_isready -p ${a} -q && break; sleep 2; done`,`${dc(t)} <<'TS_CLOUD_PG_EOF'`,...f(d,E),`SELECT 'CREATE DATABASE ${A(r)} OWNER ${A(d)}' WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = ${u(r)})\\gexec`,...I.flatMap((P)=>[...f(P.username,P.password),...w(P)]),"TS_CLOUD_PG_EOF"]}let T=c?"/var/lib/pantry/mariadb/mariadbd.sock":"/var/lib/pantry/mysql/mysqld.sock",i=(A)=>A.replace(/`/g,"``"),h=(A)=>A.replace(/\\/g,"\\\\").replace(/'/g,"\\'"),R=(A)=>{let u=A.databases&&A.databases.length>0?A.databases:[r],f=A.access==="readonly"?"SELECT":"ALL PRIVILEGES",w=[`CREATE USER IF NOT EXISTS '${h(A.username)}'@'%' IDENTIFIED BY '${h(A.password)}';`,`CREATE USER IF NOT EXISTS '${h(A.username)}'@'localhost' IDENTIFIED BY '${h(A.password)}';`,`ALTER USER '${h(A.username)}'@'%' IDENTIFIED BY '${h(A.password)}';`,`ALTER USER '${h(A.username)}'@'localhost' IDENTIFIED BY '${h(A.password)}';`];for(let I of u)w.push(`GRANT ${f} ON \`${i(I)}\`.* TO '${h(A.username)}'@'%';`,`GRANT ${f} ON \`${i(I)}\`.* TO '${h(A.username)}'@'localhost';`);return w},N=t.users||[];return[tc(),`for i in $(seq 1 30); do mysqladmin --socket=${T} -u root ping 2>/dev/null | grep -q alive && break; sleep 2; done`,`mysql --socket=${T} -u root <<'TS_CLOUD_SQL_EOF'`,`CREATE DATABASE IF NOT EXISTS \`${i(r)}\` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;`,...R({username:d,password:E}),...N.flatMap(R),"FLUSH PRIVILEGES;","TS_CLOUD_SQL_EOF"]}var kA="/var/backups/ts-cloud",kP="/etc/ts-cloud/backups.config.ts",pD="/etc/cron.d/ts-cloud-backups",Ec="/usr/local/bin/ts-cloud-backup.sh";function bP(t){if(!t.name)return null;let e=t.host||"127.0.0.1",r=t.engine==="postgres",d=r?"postgresql":"mysql",E=t.port??(r?5432:3306),n=(c)=>c.replace(/\\/g,"\\\\").replace(/'/g,"\\'");return[" {",` type: '${d}',`,` name: '${n(t.name)}',`," connection: {",` hostname: '${n(e)}',`,` port: ${E},`,` database: '${n(t.name)}',`,` username: '${n(t.username||t.name)}',`,` password: '${n(t.password||"")}',`," ssl: false,"," },"," includeSchema: true,"," includeData: true,"," },"].join(`
|
|
5765
|
+
`)}function xD(t,e){return[`cat > /etc/systemd/system/${t}.service <<'TS_CLOUD_VITESS_UNIT_EOF'`,e,"TS_CLOUD_VITESS_UNIT_EOF"]}function HP(t){let e=t.cell??"zone1",r=t.vtgatePort??GA,E=`${((t.keyspaces?.length)?t.keyspaces:[{name:"app"}]).map((n)=>{let c=(n.sharded?["-80","80-"]:["0"]).map((_)=>`shards:{name:"${_}"}`).join(" ");return`keyspaces:{name:"${n.name}" ${c}}`}).join(" ")} cells:"${e}"`;return rc({description:"Vitess (vtcombo, single-process development stack)",execStart:ec("vtcombo",[`${Ir}/vtcombo`,`--cell ${e}`,`--proto-topo ${Ue(E)}`,`--mysql-server-port ${r}`,"--mysql-server-bind-address 127.0.0.1","--mysql-auth-server-impl none","--start-mysql",`--port ${YA}`,`--grpc-port ${ch}`])})}function WP(){return rc({description:"etcd (Vitess topology store)",execStart:ec("etcd",[`${Ir}/etcd`,`--data-dir ${Cd}/etcd`,`--listen-client-urls http://127.0.0.1:${_h}`,`--advertise-client-urls http://127.0.0.1:${_h}`]),execStartPre:[`+/bin/mkdir -p ${Cd}/etcd`,`+/bin/chown ${lr}:${lr} ${Cd}/etcd`]})}function ZA(t){return["--topo-implementation etcd2",`--topo-global-server-address ${t.etcdEndpoint??`http://127.0.0.1:${_h}`}`,"--topo-global-root /vitess/global"]}function vP(t){let e=!t.etcdEndpoint;return rc({description:"Vitess vtctld (control plane)",after:e?["vitess-etcd.service"]:[],requires:e?["vitess-etcd.service"]:[],execStart:ec("vtctld",[`${Ir}/vtctld`,...ZA(t),`--cell ${t.cell??"zone1"}`,"--service-map grpc-vtctl,grpc-vtctld",`--grpc-port ${ch}`,`--port ${ch+1}`])})}function QP(t,e,r){let d=t.cell??"zone1";return rc({description:`Vitess vttablet (${e}/${r})`,after:["vitess-vtctld.service","vitess-mysqlctld.service"],requires:["vitess-mysqlctld.service"],execStart:ec("vttablet",[`${Ir}/vttablet`,...ZA(t),`--tablet-path ${d}-${String(VA).padStart(10,"0")}`,`--init-keyspace ${e}`,`--init-shard ${r}`,"--init-tablet-type replica",`--service-map ${Ue("grpc-queryservice,grpc-tabletmanager,grpc-updatestream")}`,`--port ${kD}`,`--grpc-port ${kD+1}`,`--db-port ${t.mysqlPort??3306}`,`--mycnf-mysql-port ${t.mysqlPort??3306}`])})}function YP(t){return rc({description:"Vitess mysqlctld (managed mysqld)",execStart:ec("mysqlctld",[`${Ir}/mysqlctld`,`--tablet-uid ${VA}`,`--mysql-port ${t.mysqlPort??3306}`,'--init-db-sql-file "$VTROOT/config/init_db.sql"',"--wait-time 2m"]),execStartPre:[`+/bin/mkdir -p ${Cd}`,`+/bin/chown ${lr}:${lr} ${Cd}`]})}var nh="/etc/vitess/auth.json";function MP(t){let e=t.username??"vitess",r=t.password??"",d=JSON.stringify({[e]:[{MysqlNativePassword:"",Password:r,UserData:e}]});return["mkdir -p /etc/vitess",`cat > ${nh} <<'TS_CLOUD_VITESS_AUTH_EOF'`,d,"TS_CLOUD_VITESS_AUTH_EOF",`chown ${lr}:${lr} ${nh}`,`chmod 0600 ${nh}`]}function GP(t){let e=t.cell??"zone1";return rc({description:"Vitess vtgate (query router)",after:["vitess-vtctld.service"],execStart:ec("vtgate",[`${Ir}/vtgate`,...ZA(t),`--cell ${e}`,`--cells-to-watch ${e}`,"--tablet-types-to-wait PRIMARY,REPLICA",`--service-map ${Ue("grpc-vtgateservice")}`,`--mysql-server-port ${t.vtgatePort??GA}`,`--mysql-server-bind-address ${t.bindAddress??"127.0.0.1"}`,"--mysql-auth-server-impl static",`--mysql-auth-server-static-file ${nh}`,`--port ${YA}`,`--grpc-port ${YA+1}`])})}function VP(t){let e=t.cell??"zone1",r=t.etcdEndpoint??`http://127.0.0.1:${_h}`,d=`${Ir}/vtctldclient --server 127.0.0.1:${ch}`,E=[`for i in $(seq 1 30); do ${d} GetCellInfoNames >/dev/null 2>&1 && break; sleep 2; done`,`if ! ${d} GetCellInfoNames 2>/dev/null | grep -qx ${Ue(e)}; then`,` ${d} AddCellInfo --root ${Ue(`/vitess/${e}`)} --server-address ${Ue(r)} ${Ue(e)}`,"fi"];for(let n of t.keyspaces??[]){let c=n.sharded?" --sharded":"";E.push(`if ! ${d} GetKeyspace ${Ue(n.name)} >/dev/null 2>&1; then`,` ${d} CreateKeyspace${c} ${Ue(n.name)}`,"fi");let _=`${e}-${String(VA).padStart(10,"0")}`;for(let T of n.sharded?["-80","80-"]:["0"]){let i=`${n.name}/${T}`;E.push("for i in $(seq 1 90); do",` if ${d} GetShard ${Ue(i)} 2>/dev/null | grep -q '"primary_alias": *"[^"]'; then break; fi`,` ${d} PlannedReparentShard ${Ue(i)} --new-primary ${Ue(_)} >/dev/null 2>&1 && break`,` ${d} InitShardPrimary --force ${Ue(i)} ${Ue(_)} >/dev/null 2>&1 && break`," sleep 2","done",`if ! ${d} GetShard ${Ue(i)} 2>/dev/null | grep -q '"primary_alias": *"[^"]'; then`,` echo "no primary could be elected for ${i}" >&2; exit 1`,"fi")}}return E}function qD(t){let e=t.vtgatePort??GA;return["for i in $(seq 1 60); do",` if (cd ${We} && eval "$(pantry env 2>/dev/null)"; MYSQL_PWD=${Ue(t.password??"")} ${Ir}/mysql -h 127.0.0.1 -P ${e} -u ${Ue(t.username??"vitess")} --connect-timeout=2 -e 'SHOW KEYSPACES') >/dev/null 2>&1; then`,` echo "vtgate is serving on ${e}"; exit 0`," fi"," sleep 2","done",`echo "vtgate did not become ready on port ${e}" >&2`,"exit 1"]}function oD(t){if(!jP(t))return[];let e=zP(t),r=e.mode==="combo";KA.clear();let d=[...md(FP(e)),`VT_MYSQL_LIB="$(dirname "$(dirname "$(readlink -f ${Ir}/mysqld)")")/lib"`,'if [ -d "$VT_MYSQL_LIB" ]; then',` printf '%s\\n' "$VT_MYSQL_LIB" > /etc/ld.so.conf.d/vitess-mysql.conf`," ldconfig","else",' echo "mysqld library directory not found under $VT_MYSQL_LIB" >&2; exit 1',"fi",`id -u ${lr} >/dev/null 2>&1 || useradd --system --home-dir ${Cd} --shell /usr/sbin/nologin ${lr}`,`mkdir -p ${Cd}`,`chown -R ${lr}:${lr} ${Cd}`];if(r)return d.push(...xD("vitess-vtcombo",HP(e)),...bD(),"systemctl daemon-reload","systemctl enable --now vitess-vtcombo.service",...qD(e)),d;d.push(...MP(e));let E=[];if(!e.etcdEndpoint)E.push(["vitess-etcd",WP()]);E.push(["vitess-vtctld",vP(e)],["vitess-mysqlctld",YP(e)],["vitess-vtgate",GP(e)]);for(let n of e.keyspaces??[])for(let c of n.sharded?["-80","80-"]:["0"])E.push([`vitess-vttablet-${n.name}-${c.replace(/-/g,"x")}`,QP(e,n.name,c)]);for(let[n,c]of E)d.push(...xD(n,c));d.push(...bD()),d.push("systemctl daemon-reload");for(let[n]of E)d.push(`systemctl enable --now ${n}.service`);return d.push(...VP(e),...qD(e)),d}var KP=new Set(["singlestore","vitess"]);function mD(t){if(t?.engine&&KP.has(t.engine))return!1;return!t?.host||t.host==="127.0.0.1"||t.host==="localhost"}function dc(t,e="psql"){let r=t?.port??5432;if(mD(t))return`${e} -p ${r} -U postgres`;let d=t?.username||"postgres";return`${t?.password?`PGPASSWORD='${t.password.replace(/'/g,"'\\''")}' `:""}${e} -h ${t.host} -p ${r} -U ${d} -w`}function ld(t){return t===!0||typeof t==="object"&&t!=null}function ZP(t){let e=[],r=[];if(ld(t.mysql))e.push(typeof t.mysql==="object"&&t.mysql.version?`mysql.com@${t.mysql.version}`:"mysql.com@8.0.43"),r.push("mysql");else if(ld(t.mariadb))e.push(ZD.mariadb),r.push("mariadb");if(ld(t.postgres))e.push("postgresql.org"),r.push("postgres");if(ld(t.redis))e.push("redis.io"),r.push("redis");if(ld(t.memcached))e.push("memcached.org"),r.push("memcached");if(ld(t.meilisearch))e.push("meilisearch.com"),r.push("meilisearch");return{packages:e,services:r}}function Th(t={},e={}){let r=ZP(t),d=oD(t.vitess);if(r.packages.length===0)return d;return[...md(r.packages),...Eh(r.services),...d]}function g_(t,e={}){if(!t?.name)return[];if(!mD(t))return[];let r=t.name,d=t.username||r,E=t.password||"",n=ld(e.postgres)||t.engine==="postgres",c=ld(e.mariadb)||t.engine==="mariadb",_=ld(e.mysql)||t.engine==="mysql";if(n&&!_&&!c){let A=(P)=>`"${P.replace(/"/g,'""')}"`,u=(P)=>`'${P.replace(/'/g,"''")}'`,f=(P,j)=>["DO $$ BEGIN",` IF NOT EXISTS (SELECT FROM pg_roles WHERE rolname = ${u(P)}) THEN`,` CREATE ROLE ${A(P)} LOGIN PASSWORD ${u(j)};`," ELSE",` ALTER ROLE ${A(P)} LOGIN PASSWORD ${u(j)};`," END IF;","END $$;"],w=(P)=>{let j=P.databases&&P.databases.length>0?P.databases:[r],H=[];for(let F of j)if(P.access==="readonly")H.push(`GRANT CONNECT ON DATABASE ${A(F)} TO ${A(P.username)};`,`\\connect ${A(F)}`,`GRANT USAGE ON SCHEMA public TO ${A(P.username)};`,`GRANT SELECT ON ALL TABLES IN SCHEMA public TO ${A(P.username)};`,`ALTER DEFAULT PRIVILEGES FOR ROLE ${A(d)} IN SCHEMA public GRANT SELECT ON TABLES TO ${A(P.username)};`,"\\connect postgres");else H.push(`GRANT ALL PRIVILEGES ON DATABASE ${A(F)} TO ${A(P.username)};`);return H},I=t.users||[],a=t.port??5432;return[tc(),`for i in $(seq 1 30); do pg_isready -p ${a} -q && break; sleep 2; done`,`${dc(t)} <<'TS_CLOUD_PG_EOF'`,...f(d,E),`SELECT 'CREATE DATABASE ${A(r)} OWNER ${A(d)}' WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = ${u(r)})\\gexec`,...I.flatMap((P)=>[...f(P.username,P.password),...w(P)]),"TS_CLOUD_PG_EOF"]}let T=c?"/var/lib/pantry/mariadb/mariadbd.sock":"/var/lib/pantry/mysql/mysqld.sock",i=(A)=>A.replace(/`/g,"``"),h=(A)=>A.replace(/\\/g,"\\\\").replace(/'/g,"\\'"),R=(A)=>{let u=A.databases&&A.databases.length>0?A.databases:[r],f=A.access==="readonly"?"SELECT":"ALL PRIVILEGES",w=[`CREATE USER IF NOT EXISTS '${h(A.username)}'@'%' IDENTIFIED BY '${h(A.password)}';`,`CREATE USER IF NOT EXISTS '${h(A.username)}'@'localhost' IDENTIFIED BY '${h(A.password)}';`,`ALTER USER '${h(A.username)}'@'%' IDENTIFIED BY '${h(A.password)}';`,`ALTER USER '${h(A.username)}'@'localhost' IDENTIFIED BY '${h(A.password)}';`];for(let I of u)w.push(`GRANT ${f} ON \`${i(I)}\`.* TO '${h(A.username)}'@'%';`,`GRANT ${f} ON \`${i(I)}\`.* TO '${h(A.username)}'@'localhost';`);return w},N=t.users||[];return[tc(),`for i in $(seq 1 30); do mysqladmin --socket=${T} -u root ping 2>/dev/null | grep -q alive && break; sleep 2; done`,`mysql --socket=${T} -u root <<'TS_CLOUD_SQL_EOF'`,`CREATE DATABASE IF NOT EXISTS \`${i(r)}\` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;`,...R({username:d,password:E}),...N.flatMap(R),"FLUSH PRIVILEGES;","TS_CLOUD_SQL_EOF"]}var kA="/var/backups/ts-cloud",kP="/etc/ts-cloud/backups.config.ts",pD="/etc/cron.d/ts-cloud-backups",Ec="/usr/local/bin/ts-cloud-backup.sh";function bP(t){if(!t.name)return null;let e=t.host||"127.0.0.1",r=t.engine==="postgres",d=r?"postgresql":"mysql",E=t.port??(r?5432:3306),n=(c)=>c.replace(/\\/g,"\\\\").replace(/'/g,"\\'");return[" {",` type: '${d}',`,` name: '${n(t.name)}',`," connection: {",` hostname: '${n(e)}',`,` port: ${E},`,` database: '${n(t.name)}',`,` username: '${n(t.username||t.name)}',`,` password: '${n(t.password||"")}',`," ssl: false,"," },"," includeSchema: true,"," includeData: true,"," },"].join(`
|
|
5766
5766
|
`)}function xP(t,e){let r=t?bP(t):null,d=e.bucket?[" destinations: ["," {"," type: 's3',",` bucket: '${e.bucket}',`," prefix: 'db-backups',",...e.endpoint?[` endpoint: '${e.endpoint}',`]:[]," optional: false,"," },"," ],"]:[];return["import type { BackupConfig } from 'ts-backups'","","const config: BackupConfig = {"," verbose: true,",` outputPath: '${kA}',`," retention: {",` count: ${e.retentionCount??5},`,` maxAge: ${e.retentionDays??30},`," },"," databases: [",...r?[r]:[]," ],",...d,"}","","export default config",""].join(`
|
|
5767
5767
|
`)}function ih(t){let{database:e,backups:r}=t;if(!r.enabled)return[];let d=r.schedule||"0 2 * * *",E=xP(e,r);return["export DEBIAN_FRONTEND=noninteractive",`mkdir -p /etc/ts-cloud ${kA}`,"command -v bun >/dev/null 2>&1 || (curl -fsSL https://bun.sh/install | bash && ln -sf /root/.bun/bin/bun /usr/local/bin/bun)","bun add -g ts-backups || true",`cat > ${kP} <<'TS_CLOUD_BACKUP_CFG_EOF'`,E.replace(/\n$/,""),"TS_CLOUD_BACKUP_CFG_EOF",`cat > ${Ec} <<'TS_CLOUD_BACKUP_RUN_EOF'`,"#!/bin/bash","set -uo pipefail",'export PATH="/root/.bun/bin:/usr/local/bin:$PATH"','notify() { [ -x /usr/local/bin/ts-cloud-notify ] && /usr/local/bin/ts-cloud-notify "$1" || true; }',"cd /etc/ts-cloud",'if ! ts-backups backup --config /etc/ts-cloud/backups.config.ts; then notify "❌ ts-cloud backup failed"; exit 1; fi',"TS_CLOUD_BACKUP_RUN_EOF",`chmod +x ${Ec}`,`cat > ${pD} <<'TS_CLOUD_BACKUP_CRON_EOF'`,`${d} root ${Ec} >> /var/log/ts-cloud-backup.log 2>&1`,"TS_CLOUD_BACKUP_CRON_EOF",`chmod 644 ${pD}`]}function qP(t){return t==="mariadb"?"/var/lib/pantry/mariadb/mariadbd.sock":"/var/lib/pantry/mysql/mysqld.sock"}function tf(t,e={}){if(!t?.name)return[];let r=t.name,d=t.engine==="postgres",E=e.from?`TS_CLOUD_DUMP="${e.from}"`:`TS_CLOUD_DUMP="$(find ${kA} -type f -name '*${r}*.sql' -o -type f -name '*${r}*.sql.gz' 2>/dev/null | xargs -r ls -1t 2>/dev/null | head -1)"`,n=d?`${dc(t)} -d "${r}"`:`mysql --socket=${qP(t.engine)} -u root "${r}"`;return["set -uo pipefail",'eval "$(cd /opt/pantry && pantry env 2>/dev/null)" || true',E,'[ -n "$TS_CLOUD_DUMP" ] && [ -f "$TS_CLOUD_DUMP" ] || { echo "no backup dump found to restore" >&2; exit 1; }','echo "[ts-cloud] restoring '+r+' from $TS_CLOUD_DUMP"',`case "$TS_CLOUD_DUMP" in *.gz) gunzip -c "$TS_CLOUD_DUMP" ;; *) cat "$TS_CLOUD_DUMP" ;; esac | ${n}`,'echo "restore complete"']}function ME(t=!0){if(!t)return[];return["export DEBIAN_FRONTEND=noninteractive","dpkg-query -W -f='${Status}' unattended-upgrades 2>/dev/null | grep -q 'ok installed' || apt-get install -y unattended-upgrades","cat > /etc/apt/apt.conf.d/20auto-upgrades <<'TS_CLOUD_AUTOUPD_EOF'",'APT::Periodic::Update-Package-Lists "1";','APT::Periodic::Unattended-Upgrade "1";','APT::Periodic::Download-Upgradeable-Packages "1";','APT::Periodic::AutocleanInterval "7";',"TS_CLOUD_AUTOUPD_EOF","systemctl enable --now unattended-upgrades 2>/dev/null || true"]}var ef=[["nginx",80],["https",443],["phpFpm",9074],["mysql",3306],["postgres",5432],["redis",6379],["meilisearch",7700],["typesense",8108],["smtp",25]];function sP(t=!0){let e=typeof t==="object"?t:{};return{enabled:typeof t==="boolean"?t:t.enabled!==!1,cpuLoadPerCore:e.alerts?.cpuLoadPerCore??2,memPercent:e.alerts?.memPercent??90,diskPercent:e.alerts?.diskPercent??90}}function GE(t=!0){let{enabled:e,cpuLoadPerCore:r,memPercent:d,diskPercent:E}=sP(t);if(!e)return[];let n=ef.map(([_,T])=>`SVC_${_.toUpperCase()}=$(probe ${T})`),c=ef.map(([_])=>`"${_}":"$SVC_${_.toUpperCase()}"`).join(",");return["if ! command -v sadf >/dev/null 2>&1; then export DEBIAN_FRONTEND=noninteractive; apt-get update -qq; apt-get install -y -qq sysstat; fi","systemctl enable --now sysstat.service 2>/dev/null || true","mkdir -p /var/lib/ts-cloud","cat > /usr/local/bin/ts-cloud-metrics.sh <<'TS_CLOUD_METRICS_EOF'","#!/bin/bash","set -uo pipefail","LOAD=$(cut -d' ' -f1 /proc/loadavg)","CPUS=$(nproc)",`read MEM_TOTAL MEM_USED SWAP_TOTAL SWAP_USED <<EOF
|
|
5768
5768
|
$(free -m | awk '/^Mem:/{total=$2; used=$3} /^Swap:/{print total, used, $2, $3}')
|
|
5769
|
-
EOF`,`DISK_PCT=$(df -P / | awk 'NR==2{gsub("%","",$5); print $5}')`,"UPTIME_SEC=$(cut -d' ' -f1 /proc/uptime | cut -d. -f1)",`RX_BYTES=$(awk -F'[: ]+' 'NR>2 && $2!="lo"{rx+=$3} END{print rx+0}' /proc/net/dev)`,`TX_BYTES=$(awk -F'[: ]+' 'NR>2 && $2!="lo"{tx+=$11} END{print tx+0}' /proc/net/dev)`,"probe(){ (exec 3<>/dev/tcp/127.0.0.1/$1) 2>/dev/null && echo up || echo down; }",...n,"LOAD=${LOAD:-0}; CPUS=${CPUS:-1}; MEM_TOTAL=${MEM_TOTAL:-0}; MEM_USED=${MEM_USED:-0}","SWAP_TOTAL=${SWAP_TOTAL:-0}; SWAP_USED=${SWAP_USED:-0}; DISK_PCT=${DISK_PCT:-0}","UPTIME_SEC=${UPTIME_SEC:-0}; RX_BYTES=${RX_BYTES:-0}; TX_BYTES=${TX_BYTES:-0}","MEM_PCT=$(( MEM_TOTAL > 0 ? MEM_USED * 100 / MEM_TOTAL : 0 ))","cat > /var/lib/ts-cloud/metrics.json.tmp <<JSON",'{"load":$LOAD,"cpus":$CPUS,"memTotalMb":$MEM_TOTAL,"memUsedMb":$MEM_USED,"memUsedPct":$MEM_PCT,"swapTotalMb":$SWAP_TOTAL,"swapUsedMb":$SWAP_USED,"diskUsedPct":$DISK_PCT,"uptimeSec":$UPTIME_SEC,"network":{"rxBytes":$RX_BYTES,"txBytes":$TX_BYTES},"services":{'+c+"}}","JSON","mv -f /var/lib/ts-cloud/metrics.json.tmp /var/lib/ts-cloud/metrics.json",'ALERTS=""',`if awk -v l="$LOAD" -v c="$CPUS" -v t=${r} 'BEGIN{exit !(c>0 && l/c > t)}'; then ALERTS="$ALERTS load=$LOAD/${r}xCPU"; fi`,`if [ "\${MEM_PCT:-0}" -ge ${d} ]; then ALERTS="$ALERTS mem=\${MEM_PCT}%"; fi`,`if [ "\${DISK_PCT:-0}" -ge ${E} ]; then ALERTS="$ALERTS disk=\${DISK_PCT}%"; fi`,"PREV=$(cat /var/lib/ts-cloud/alert-state 2>/dev/null || echo ok)",'if [ -n "$ALERTS" ]; then',' if [ "$PREV" != alert ] && [ -x /usr/local/bin/ts-cloud-notify ]; then /usr/local/bin/ts-cloud-notify "⚠️ $(hostname): resource alert —$ALERTS" || true; fi'," echo alert > /var/lib/ts-cloud/alert-state","else",' if [ "$PREV" = alert ] && [ -x /usr/local/bin/ts-cloud-notify ]; then /usr/local/bin/ts-cloud-notify "✅ $(hostname): resource usage back to normal" || true; fi'," echo ok > /var/lib/ts-cloud/alert-state","fi","TS_CLOUD_METRICS_EOF","chmod +x /usr/local/bin/ts-cloud-metrics.sh","cat > /etc/systemd/system/ts-cloud-metrics.service <<'TS_CLOUD_METRICS_SVC_EOF'","[Unit]","Description=ts-cloud metrics collector","","[Service]","Type=oneshot","ExecStart=/usr/local/bin/ts-cloud-metrics.sh","TS_CLOUD_METRICS_SVC_EOF","cat > /etc/systemd/system/ts-cloud-metrics.timer <<'TS_CLOUD_METRICS_TMR_EOF'","[Unit]","Description=Run ts-cloud metrics collector every minute","","[Timer]","OnCalendar=*-*-* *:*:00","AccuracySec=1s","RandomizedDelaySec=5s","Persistent=true","","[Install]","WantedBy=timers.target","TS_CLOUD_METRICS_TMR_EOF","systemctl daemon-reload","systemctl enable --now ts-cloud-metrics.timer","systemctl start ts-cloud-metrics.service"]}var oP={"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 mP(t={}){let e=t.versions?.length?t.versions:["8.3"];return t.default&&e.includes(t.default)?t.default:e[0]}function pP(t={}){return{...t.optimizeForProduction===!1?{}:{...oP},...t.ini||{}}}function tj(t={}){let e=pP(t),r=Object.keys(e);if(r.length===0)return[];let d=r.map((n)=>`${n}=${e[n]}`),E="ts-cloud-managed";return[tc(),"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'`,`; ${E} — production PHP tuning`,...d,"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 '/; ${E} BEGIN/,/; ${E} END/d' "$TS_CLOUD_LOADED_INI"`,` cat >> "$TS_CLOUD_LOADED_INI" <<'TS_CLOUD_PHPINI_EOF'`,`; ${E} BEGIN`,...d,`; ${E} END`,"TS_CLOUD_PHPINI_EOF","fi",`(cd ${We} && pantry restart php-fpm) 2>/dev/null || true`]}function hh(t={}){let e=mP(t),r=t.installNginx!==!1,d=t.installComposer!==!1,E=[`php.net@${e}`];if(d)E.push("getcomposer.org");if(r)E.push("nginx.org");return[...md(E),...Eh(["php-fpm"]),...tj(t)]}var nc="/usr/local/bin/ts-cloud-nginx";function rf(t="/opt/pantry"){return[...dh(),...md(["nginx.org"]),"mkdir -p /etc/nginx/sites-available /etc/nginx/sites-enabled /var/log/nginx /var/lib/nginx/body /var/lib/nginx/proxy /var/lib/nginx/fastcgi /var/lib/nginx/uwsgi /var/lib/nginx/scgi","getent passwd www-data >/dev/null || useradd --system --no-create-home --shell /usr/sbin/nologin www-data","chown -R www-data:www-data /var/lib/nginx /var/log/nginx",`cat > ${nc} <<'TS_CLOUD_NGINXBIN_EOF'`,"#!/bin/sh",`eval "$(cd ${t} && pantry env 2>/dev/null)"`,"NGINX_BIN=/opt/pantry/pantry/.bin/nginx",'if [ ! -x "$NGINX_BIN" ]; then NGINX_BIN=$(command -v nginx || true); fi','if [ -z "$NGINX_BIN" ]; then echo "nginx binary not found; run pantry install nginx.org or install nginx explicitly" >&2; exit 1; fi','exec "$NGINX_BIN" -c /etc/nginx/nginx.conf "$@"',"TS_CLOUD_NGINXBIN_EOF",`chmod +x ${nc}`,"cat > /etc/nginx/fastcgi_params <<'TS_CLOUD_FCGI_EOF'","fastcgi_param QUERY_STRING $query_string;","fastcgi_param REQUEST_METHOD $request_method;","fastcgi_param CONTENT_TYPE $content_type;","fastcgi_param CONTENT_LENGTH $content_length;","fastcgi_param SCRIPT_NAME $fastcgi_script_name;","fastcgi_param REQUEST_URI $request_uri;","fastcgi_param DOCUMENT_URI $document_uri;","fastcgi_param DOCUMENT_ROOT $document_root;","fastcgi_param SERVER_PROTOCOL $server_protocol;","fastcgi_param REQUEST_SCHEME $scheme;","fastcgi_param HTTPS $https if_not_empty;","fastcgi_param GATEWAY_INTERFACE CGI/1.1;","fastcgi_param SERVER_SOFTWARE nginx/$nginx_version;","fastcgi_param REMOTE_ADDR $remote_addr;","fastcgi_param REMOTE_PORT $remote_port;","fastcgi_param SERVER_ADDR $server_addr;","fastcgi_param SERVER_PORT $server_port;","fastcgi_param SERVER_NAME $server_name;","fastcgi_param REDIRECT_STATUS 200;","TS_CLOUD_FCGI_EOF","cat > /etc/nginx/nginx.conf <<'TS_CLOUD_NGINXCONF_EOF'","user www-data;","worker_processes auto;","pid /run/nginx.pid;","error_log /var/log/nginx/error.log;","events { worker_connections 1024; }","http {"," default_type application/octet-stream;"," types {"," text/html html htm;"," text/css css;"," application/javascript js;"," application/json json;"," image/svg+xml svg;"," image/png png;"," image/jpeg jpg jpeg;"," image/gif gif;"," image/x-icon ico;"," image/webp webp;"," font/woff2 woff2;"," font/woff woff;"," text/plain txt;"," }"," access_log /var/log/nginx/access.log;"," sendfile on;"," tcp_nopush on;"," keepalive_timeout 65;"," server_tokens off;"," client_max_body_size 100m;"," client_body_temp_path /var/lib/nginx/body;"," proxy_temp_path /var/lib/nginx/proxy;"," fastcgi_temp_path /var/lib/nginx/fastcgi;"," uwsgi_temp_path /var/lib/nginx/uwsgi;"," scgi_temp_path /var/lib/nginx/scgi;"," server {"," listen 80 default_server;"," listen [::]:80 default_server;"," server_name _;"," return 444;"," }"," include /etc/nginx/sites-enabled/*;","}","TS_CLOUD_NGINXCONF_EOF","cat > /etc/systemd/system/ts-cloud-nginx.service <<'TS_CLOUD_NGINXUNIT_EOF'","[Unit]","Description=ts-cloud nginx (pantry)","After=network.target","","[Service]","Type=simple",`ExecStartPre=${nc} -t`,`ExecStart=${nc} -g 'daemon off;'`,`ExecReload=${nc} -s reload`,"Restart=always","RestartSec=3","","[Install]","WantedBy=multi-user.target","TS_CLOUD_NGINXUNIT_EOF","systemctl daemon-reload","systemctl enable ts-cloud-nginx","ls /etc/nginx/sites-enabled/* >/dev/null 2>&1 && systemctl restart ts-cloud-nginx || true"]}function cc(t){if(!t)return[];let e=[];if(t.slack?.webhookUrl)e.push(`curl -fsS -X POST -H 'Content-Type: application/json' -d "{\\"text\\":\\"$MSG\\"}" ${t.slack.webhookUrl} || true`);if(t.discord?.webhookUrl)e.push(`curl -fsS -X POST -H 'Content-Type: application/json' -d "{\\"content\\":\\"$MSG\\"}" ${t.discord.webhookUrl} || true`);if(t.telegram?.botToken&&t.telegram.chatId)e.push(`curl -fsS -X POST "https://api.telegram.org/bot${t.telegram.botToken}/sendMessage" --data-urlencode "chat_id=${t.telegram.chatId}" --data-urlencode "text=$MSG" || true`);if(t.webhook?.url)e.push(`curl -fsS -X POST -H 'Content-Type: application/json' -d "{\\"message\\":\\"$MSG\\"}" ${t.webhook.url} || true`);if(e.length===0)return[];return["cat > /usr/local/bin/ts-cloud-notify <<'TS_CLOUD_NOTIFY_EOF'","#!/bin/bash",'MSG="$1"',...e,"TS_CLOUD_NOTIFY_EOF","chmod +x /usr/local/bin/ts-cloud-notify"]}await Ht();function Id(t,e){return`/var/www/${t}-${e}`}var ej=new Set(["laravel","php","statamic","wordpress"]);function bA(t){return t.type!=null&&ej.has(t.type)}function rj(t){if(t.deploy)return t.deploy;if(bA(t))return"server";if(t.start)return"server";return"bucket"}function Ir(t){if(t.redirect)return"redirect";if(bA(t))return"server-php";if(rj(t)==="bucket")return"bucket";return t.start?"server-app":"server-static"}var sA="/etc/rpx/certs",dj="/var/www/acme-challenge";function Ej(t){if(typeof t==="string")return{to:t};let e={to:t.to};if(t.status!=null)e.status=t.status;if(t.preservePath!=null)e.preservePath=t.preservePath;return e}function nj(t){let e=t.auth;if(!e||e.enabled===!1||!e.password)return;return{username:e.username||"admin",password:e.password,...e.realm?{realm:e.realm}:{}}}function df(t){if(!t||t==="/")return;let e=`/${t}`.replace(/\/+/g,"/").replace(/\/+$/,"");if(!e.startsWith("/"))e=`/${e}`;return e===""||e==="/"?void 0:e}function xA(t,e){let d=(e?`${t}${e}`:t).replace(/[^a-zA-Z0-9._-]+/g,"-").replace(/^-+|-+$/g,"").slice(0,128);return d.length>0?d:"rpx"}function cj(t,e){if(!e||e.length===0)return`localhost:${t}`;return e.map((r)=>`${r.privateIp??r.publicIp}:${t}`)}function Ef(t,e,r){let d=(e.wwwRoot??"/var/www").replace(/\/+$/,""),E=e.slug??"app",n=e.proxy.certsDir??sA,c=e.proxy.loadBalancer,_=[],T=new Set;for(let[R,N]of Object.entries(t)){if(!N||!N.domain)continue;let A=Ir(N);if(A==="bucket")continue;let u=df(N.path),f=xA(N.domain,u),w=nj(N);if(A==="redirect"){_.push({to:N.domain,path:u,redirect:Ej(N.redirect),id:f,...w?{auth:w}:{}}),T.add(N.domain);continue}if(A==="server-app"){if(typeof N.port!=="number")continue;let I=cj(N.port,r);_.push({to:N.domain,path:u,from:I,id:f,...w?{auth:w}:{},...Array.isArray(I)&&c?{loadBalancer:c}:{}})}else _.push({to:N.domain,path:u,static:{dir:`${d}/${E}-${R}/current`,spa:N.spa??!1,pathRewriteStyle:N.pathRewriteStyle??"directory"},cleanUrls:N.pathRewriteStyle!=="flat",...w?{auth:w}:{},id:f});T.add(N.domain)}if(e.proxy.autoWww!==!1)for(let R of[...T]){if(R.split(".").length!==2)continue;let N=`www.${R}`;if(T.has(N))continue;_.push({to:N,redirect:{to:`https://${R}`},id:xA(N)}),T.add(N)}_.sort((R,N)=>{if(R.to!==N.to)return R.to.localeCompare(N.to);return(N.path?.length??0)-(R.path?.length??0)});let i={proxies:_,productionCerts:{certsDir:n,certsDirServerNames:[...T]},https:!0,hostsManagement:!1,cleanup:{hosts:!1,certs:!1}};if(e.proxy.onDemandTls&&T.size>0)i.onDemandTls={enabled:!0,allowedSuffixes:[...T],email:e.proxy.onDemandTlsEmail,certsDir:n,staging:e.proxy.onDemandTlsStaging??!1};if(e.proxy.onDemandTls)i.acmeChallengeWebroot=e.proxy.acmeWebroot??dj;let h=e.proxy.cdn;if(h?.secret&&h.frontedHosts.length>0)i.originGuard={header:h.secretHeader??"X-Origin-Verify",value:h.secret,hosts:h.frontedHosts};return i}function Tc(t,e){return Ef(t,e)}function X_(t,e,r){return Ef(t,r,e)}function KE(t){return t?.webServer==="rpx"||t?.proxy?.engine==="rpx"}var y_="/etc/rpx",xe="/opt/rpx-gateway",qA="/etc/rpx/gateway.ts",$_="/etc/rpx/gateway",pd="rpx-gateway.service",VE="/etc/rpx/sites.d";function _j(t=VE,e=sA){return`// Generated by ts-cloud — rpx gateway assembler.
|
|
5769
|
+
EOF`,`DISK_PCT=$(df -P / | awk 'NR==2{gsub("%","",$5); print $5}')`,"UPTIME_SEC=$(cut -d' ' -f1 /proc/uptime | cut -d. -f1)",`RX_BYTES=$(awk -F'[: ]+' 'NR>2 && $2!="lo"{rx+=$3} END{print rx+0}' /proc/net/dev)`,`TX_BYTES=$(awk -F'[: ]+' 'NR>2 && $2!="lo"{tx+=$11} END{print tx+0}' /proc/net/dev)`,"probe(){ (exec 3<>/dev/tcp/127.0.0.1/$1) 2>/dev/null && echo up || echo down; }",...n,"LOAD=${LOAD:-0}; CPUS=${CPUS:-1}; MEM_TOTAL=${MEM_TOTAL:-0}; MEM_USED=${MEM_USED:-0}","SWAP_TOTAL=${SWAP_TOTAL:-0}; SWAP_USED=${SWAP_USED:-0}; DISK_PCT=${DISK_PCT:-0}","UPTIME_SEC=${UPTIME_SEC:-0}; RX_BYTES=${RX_BYTES:-0}; TX_BYTES=${TX_BYTES:-0}","MEM_PCT=$(( MEM_TOTAL > 0 ? MEM_USED * 100 / MEM_TOTAL : 0 ))","cat > /var/lib/ts-cloud/metrics.json.tmp <<JSON",'{"load":$LOAD,"cpus":$CPUS,"memTotalMb":$MEM_TOTAL,"memUsedMb":$MEM_USED,"memUsedPct":$MEM_PCT,"swapTotalMb":$SWAP_TOTAL,"swapUsedMb":$SWAP_USED,"diskUsedPct":$DISK_PCT,"uptimeSec":$UPTIME_SEC,"network":{"rxBytes":$RX_BYTES,"txBytes":$TX_BYTES},"services":{'+c+"}}","JSON","mv -f /var/lib/ts-cloud/metrics.json.tmp /var/lib/ts-cloud/metrics.json",'ALERTS=""',`if awk -v l="$LOAD" -v c="$CPUS" -v t=${r} 'BEGIN{exit !(c>0 && l/c > t)}'; then ALERTS="$ALERTS load=$LOAD/${r}xCPU"; fi`,`if [ "\${MEM_PCT:-0}" -ge ${d} ]; then ALERTS="$ALERTS mem=\${MEM_PCT}%"; fi`,`if [ "\${DISK_PCT:-0}" -ge ${E} ]; then ALERTS="$ALERTS disk=\${DISK_PCT}%"; fi`,"PREV=$(cat /var/lib/ts-cloud/alert-state 2>/dev/null || echo ok)",'if [ -n "$ALERTS" ]; then',' if [ "$PREV" != alert ] && [ -x /usr/local/bin/ts-cloud-notify ]; then /usr/local/bin/ts-cloud-notify "⚠️ $(hostname): resource alert —$ALERTS" || true; fi'," echo alert > /var/lib/ts-cloud/alert-state","else",' if [ "$PREV" = alert ] && [ -x /usr/local/bin/ts-cloud-notify ]; then /usr/local/bin/ts-cloud-notify "✅ $(hostname): resource usage back to normal" || true; fi'," echo ok > /var/lib/ts-cloud/alert-state","fi","TS_CLOUD_METRICS_EOF","chmod +x /usr/local/bin/ts-cloud-metrics.sh","cat > /etc/systemd/system/ts-cloud-metrics.service <<'TS_CLOUD_METRICS_SVC_EOF'","[Unit]","Description=ts-cloud metrics collector","","[Service]","Type=oneshot","ExecStart=/usr/local/bin/ts-cloud-metrics.sh","TS_CLOUD_METRICS_SVC_EOF","cat > /etc/systemd/system/ts-cloud-metrics.timer <<'TS_CLOUD_METRICS_TMR_EOF'","[Unit]","Description=Run ts-cloud metrics collector every minute","","[Timer]","OnCalendar=*-*-* *:*:00","AccuracySec=1s","RandomizedDelaySec=5s","Persistent=true","","[Install]","WantedBy=timers.target","TS_CLOUD_METRICS_TMR_EOF","systemctl daemon-reload","systemctl enable --now ts-cloud-metrics.timer","systemctl start ts-cloud-metrics.service"]}var oP={"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 mP(t={}){let e=t.versions?.length?t.versions:["8.3"];return t.default&&e.includes(t.default)?t.default:e[0]}function pP(t={}){return{...t.optimizeForProduction===!1?{}:{...oP},...t.ini||{}}}function tj(t={}){let e=pP(t),r=Object.keys(e);if(r.length===0)return[];let d=r.map((n)=>`${n}=${e[n]}`),E="ts-cloud-managed";return[tc(),"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'`,`; ${E} — production PHP tuning`,...d,"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 '/; ${E} BEGIN/,/; ${E} END/d' "$TS_CLOUD_LOADED_INI"`,` cat >> "$TS_CLOUD_LOADED_INI" <<'TS_CLOUD_PHPINI_EOF'`,`; ${E} BEGIN`,...d,`; ${E} END`,"TS_CLOUD_PHPINI_EOF","fi",`(cd ${We} && pantry restart php-fpm) 2>/dev/null || true`]}function hh(t={}){let e=mP(t),r=t.installNginx!==!1,d=t.installComposer!==!1,E=[`php.net@${e}`];if(d)E.push("getcomposer.org");if(r)E.push("nginx.org");return[...md(E),...Eh(["php-fpm"]),...tj(t)]}var nc="/usr/local/bin/ts-cloud-nginx";function rf(t="/opt/pantry"){return[...dh(),...md(["nginx.org"]),"mkdir -p /etc/nginx/sites-available /etc/nginx/sites-enabled /var/log/nginx /var/lib/nginx/body /var/lib/nginx/proxy /var/lib/nginx/fastcgi /var/lib/nginx/uwsgi /var/lib/nginx/scgi","getent passwd www-data >/dev/null || useradd --system --no-create-home --shell /usr/sbin/nologin www-data","chown -R www-data:www-data /var/lib/nginx /var/log/nginx",`cat > ${nc} <<'TS_CLOUD_NGINXBIN_EOF'`,"#!/bin/sh",`eval "$(cd ${t} && pantry env 2>/dev/null)"`,"NGINX_BIN=/opt/pantry/pantry/.bin/nginx",'if [ ! -x "$NGINX_BIN" ]; then NGINX_BIN=$(command -v nginx || true); fi','if [ -z "$NGINX_BIN" ]; then echo "nginx binary not found; run pantry install nginx.org or install nginx explicitly" >&2; exit 1; fi','exec "$NGINX_BIN" -c /etc/nginx/nginx.conf "$@"',"TS_CLOUD_NGINXBIN_EOF",`chmod +x ${nc}`,"cat > /etc/nginx/fastcgi_params <<'TS_CLOUD_FCGI_EOF'","fastcgi_param QUERY_STRING $query_string;","fastcgi_param REQUEST_METHOD $request_method;","fastcgi_param CONTENT_TYPE $content_type;","fastcgi_param CONTENT_LENGTH $content_length;","fastcgi_param SCRIPT_NAME $fastcgi_script_name;","fastcgi_param REQUEST_URI $request_uri;","fastcgi_param DOCUMENT_URI $document_uri;","fastcgi_param DOCUMENT_ROOT $document_root;","fastcgi_param SERVER_PROTOCOL $server_protocol;","fastcgi_param REQUEST_SCHEME $scheme;","fastcgi_param HTTPS $https if_not_empty;","fastcgi_param GATEWAY_INTERFACE CGI/1.1;","fastcgi_param SERVER_SOFTWARE nginx/$nginx_version;","fastcgi_param REMOTE_ADDR $remote_addr;","fastcgi_param REMOTE_PORT $remote_port;","fastcgi_param SERVER_ADDR $server_addr;","fastcgi_param SERVER_PORT $server_port;","fastcgi_param SERVER_NAME $server_name;","fastcgi_param REDIRECT_STATUS 200;","TS_CLOUD_FCGI_EOF","cat > /etc/nginx/nginx.conf <<'TS_CLOUD_NGINXCONF_EOF'","user www-data;","worker_processes auto;","pid /run/nginx.pid;","error_log /var/log/nginx/error.log;","events { worker_connections 1024; }","http {"," default_type application/octet-stream;"," types {"," text/html html htm;"," text/css css;"," application/javascript js;"," application/json json;"," image/svg+xml svg;"," image/png png;"," image/jpeg jpg jpeg;"," image/gif gif;"," image/x-icon ico;"," image/webp webp;"," font/woff2 woff2;"," font/woff woff;"," text/plain txt;"," }"," access_log /var/log/nginx/access.log;"," sendfile on;"," tcp_nopush on;"," keepalive_timeout 65;"," server_tokens off;"," client_max_body_size 100m;"," client_body_temp_path /var/lib/nginx/body;"," proxy_temp_path /var/lib/nginx/proxy;"," fastcgi_temp_path /var/lib/nginx/fastcgi;"," uwsgi_temp_path /var/lib/nginx/uwsgi;"," scgi_temp_path /var/lib/nginx/scgi;"," server {"," listen 80 default_server;"," listen [::]:80 default_server;"," server_name _;"," return 444;"," }"," include /etc/nginx/sites-enabled/*;","}","TS_CLOUD_NGINXCONF_EOF","cat > /etc/systemd/system/ts-cloud-nginx.service <<'TS_CLOUD_NGINXUNIT_EOF'","[Unit]","Description=ts-cloud nginx (pantry)","After=network.target","","[Service]","Type=simple",`ExecStartPre=${nc} -t`,`ExecStart=${nc} -g 'daemon off;'`,`ExecReload=${nc} -s reload`,"Restart=always","RestartSec=3","","[Install]","WantedBy=multi-user.target","TS_CLOUD_NGINXUNIT_EOF","systemctl daemon-reload","systemctl enable ts-cloud-nginx","ls /etc/nginx/sites-enabled/* >/dev/null 2>&1 && systemctl restart ts-cloud-nginx || true"]}function cc(t){if(!t)return[];let e=[];if(t.slack?.webhookUrl)e.push(`curl -fsS -X POST -H 'Content-Type: application/json' -d "{\\"text\\":\\"$MSG\\"}" ${t.slack.webhookUrl} || true`);if(t.discord?.webhookUrl)e.push(`curl -fsS -X POST -H 'Content-Type: application/json' -d "{\\"content\\":\\"$MSG\\"}" ${t.discord.webhookUrl} || true`);if(t.telegram?.botToken&&t.telegram.chatId)e.push(`curl -fsS -X POST "https://api.telegram.org/bot${t.telegram.botToken}/sendMessage" --data-urlencode "chat_id=${t.telegram.chatId}" --data-urlencode "text=$MSG" || true`);if(t.webhook?.url)e.push(`curl -fsS -X POST -H 'Content-Type: application/json' -d "{\\"message\\":\\"$MSG\\"}" ${t.webhook.url} || true`);if(e.length===0)return[];return["cat > /usr/local/bin/ts-cloud-notify <<'TS_CLOUD_NOTIFY_EOF'","#!/bin/bash",'MSG="$1"',...e,"TS_CLOUD_NOTIFY_EOF","chmod +x /usr/local/bin/ts-cloud-notify"]}await Ht();function Id(t,e){return`/var/www/${t}-${e}`}var ej=new Set(["laravel","php","statamic","wordpress"]);function bA(t){return t.type!=null&&ej.has(t.type)}function rj(t){if(t.deploy)return t.deploy;if(bA(t))return"server";if(t.start)return"server";return"bucket"}function Dr(t){if(t.redirect)return"redirect";if(bA(t))return"server-php";if(rj(t)==="bucket")return"bucket";return t.start?"server-app":"server-static"}var sA="/etc/rpx/certs",dj="/var/www/acme-challenge";function Ej(t){if(typeof t==="string")return{to:t};let e={to:t.to};if(t.status!=null)e.status=t.status;if(t.preservePath!=null)e.preservePath=t.preservePath;return e}function nj(t){let e=t.auth;if(!e||e.enabled===!1||!e.password)return;return{username:e.username||"admin",password:e.password,...e.realm?{realm:e.realm}:{}}}function df(t){if(!t||t==="/")return;let e=`/${t}`.replace(/\/+/g,"/").replace(/\/+$/,"");if(!e.startsWith("/"))e=`/${e}`;return e===""||e==="/"?void 0:e}function xA(t,e){let d=(e?`${t}${e}`:t).replace(/[^a-zA-Z0-9._-]+/g,"-").replace(/^-+|-+$/g,"").slice(0,128);return d.length>0?d:"rpx"}function cj(t,e){if(!e||e.length===0)return`localhost:${t}`;return e.map((r)=>`${r.privateIp??r.publicIp}:${t}`)}function Ef(t,e,r){let d=(e.wwwRoot??"/var/www").replace(/\/+$/,""),E=e.slug??"app",n=e.proxy.certsDir??sA,c=e.proxy.loadBalancer,_=[],T=new Set;for(let[R,N]of Object.entries(t)){if(!N||!N.domain)continue;let A=Dr(N);if(A==="bucket")continue;let u=df(N.path),f=xA(N.domain,u),w=nj(N);if(A==="redirect"){_.push({to:N.domain,path:u,redirect:Ej(N.redirect),id:f,...w?{auth:w}:{}}),T.add(N.domain);continue}if(A==="server-app"){if(typeof N.port!=="number")continue;let I=cj(N.port,r);_.push({to:N.domain,path:u,from:I,id:f,...w?{auth:w}:{},...Array.isArray(I)&&c?{loadBalancer:c}:{}})}else _.push({to:N.domain,path:u,static:{dir:`${d}/${E}-${R}/current`,spa:N.spa??!1,pathRewriteStyle:N.pathRewriteStyle??"directory"},cleanUrls:N.pathRewriteStyle!=="flat",...w?{auth:w}:{},id:f});T.add(N.domain)}if(e.proxy.autoWww!==!1)for(let R of[...T]){if(R.split(".").length!==2)continue;let N=`www.${R}`;if(T.has(N))continue;_.push({to:N,redirect:{to:`https://${R}`},id:xA(N)}),T.add(N)}_.sort((R,N)=>{if(R.to!==N.to)return R.to.localeCompare(N.to);return(N.path?.length??0)-(R.path?.length??0)});let i={proxies:_,productionCerts:{certsDir:n,certsDirServerNames:[...T]},https:!0,hostsManagement:!1,cleanup:{hosts:!1,certs:!1}};if(e.proxy.onDemandTls&&T.size>0)i.onDemandTls={enabled:!0,allowedSuffixes:[...T],email:e.proxy.onDemandTlsEmail,certsDir:n,staging:e.proxy.onDemandTlsStaging??!1};if(e.proxy.onDemandTls)i.acmeChallengeWebroot=e.proxy.acmeWebroot??dj;let h=e.proxy.cdn;if(h?.secret&&h.frontedHosts.length>0)i.originGuard={header:h.secretHeader??"X-Origin-Verify",value:h.secret,hosts:h.frontedHosts};return i}function Tc(t,e){return Ef(t,e)}function X_(t,e,r){return Ef(t,r,e)}function KE(t){return t?.webServer==="rpx"||t?.proxy?.engine==="rpx"}var y_="/etc/rpx",xe="/opt/rpx-gateway",qA="/etc/rpx/gateway.ts",$_="/etc/rpx/gateway",pd="rpx-gateway.service",VE="/etc/rpx/sites.d";function _j(t=VE,e=sA){return`// Generated by ts-cloud — rpx gateway assembler.
|
|
5770
5770
|
// Merges every app's fragment in ${t} so independent deploys compose
|
|
5771
5771
|
// without clobbering each other. Each deploy writes only its own <slug>.json.
|
|
5772
5772
|
import { startProxies } from '@stacksjs/rpx'
|
|
@@ -5987,7 +5987,7 @@ ${E}`:""}`}class eE{name="hetzner";usesCloudFormation=!1;client;sshPrivateKeyPat
|
|
|
5987
5987
|
`),r=[];for(let E of t.targets){if(!E.publicIp){r.push({instanceId:E.id,status:"Failed",error:"Missing public IP"});continue}try{let n=this.sshExec(E.publicIp,e);r.push({instanceId:E.id,status:"Success",output:n})}catch(n){r.push({instanceId:E.id,status:"Failed",error:n.message})}}let d=r.every((E)=>E.status==="Success");return{success:d,instanceCount:t.targets.length,perInstance:r,error:d?void 0:"One or more SSH deploy commands failed"}}async ensureSshKey(t,e,r){if(!wj(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 d=gj(this.sshPublicKeyPath,"utf8").trim(),E=j_(d),c=(await this.client.listSshKeys()).find((T)=>j_(T.public_key)===E);if(c)return c.id;return(await this.client.createSshKey({name:`${t}-${e}-deploy`,publicKey:d,labels:r})).id}async tryGetServer(t){try{return await this.client.getServer(t)}catch{return null}}refreshLbRoutes(t,e,r,d,E){let n=t.public_net.ipv4?.ip;if(!n){console.warn(`[ts-cloud] LB server '${t.name}' has no public IP — skipping the rpx route refresh; its routes may be stale.`);return}let c=r.filter((T)=>T.privateIp||T.publicIp);if(c.length===0){console.warn(`[ts-cloud] No routable app boxes found for LB '${t.name}' — leaving its current rpx routes untouched.`);return}let _=X_(e,c,{proxy:d,slug:E});this.sshExec(n,Rh({config:_,slug:E}).join(`
|
|
5988
5988
|
`))}async findExistingServer(t,e,r){let d=await this.client.listServers(),E=d.find((c)=>Er(c.labels,t,e,"app")||c.name===r);if(E)return E;let n=d.filter((c)=>c.status!=="off"&&c.labels?.[`${ve}/managed-by`]==="ts-cloud"&&c.labels?.[`${ve}/environment`]===e&&c.labels?.[`${ve}/role`]==="app");if(n.length===1){let c=n[0],_=c.labels?.[`${ve}/project`]??"unknown";return console.warn(`[ts-cloud] No server named '${r}' found; adopting existing ts-cloud app server '${c.name}' (project label '${_}') for project '${t}' — `+"updating it in place instead of provisioning a new server."),c}return}async ensureFirewall(t,e,r){let E=(await this.client.listFirewalls()).find((c)=>c.name===t);if(E)return await this.client.setFirewallRules(E.id,r),{firewall:E};let{firewall:n}=await this.client.createFirewall({name:t,labels:e,rules:r});return{firewall:n}}collectUpstreamPorts(t){let e=new Set;for(let r of Object.values(t))if(typeof r.port==="number")e.add(r.port);return[...e].filter((r)=>![80,443].includes(r))}async sleep(t){await new Promise((e)=>setTimeout(e,t))}async waitForSshReady(t){let{sshIntervalMs:e,sshTimeoutMs:r}=this.bootWait,d=Date.now(),E;while(Date.now()-d<r)try{EL(`ssh ${this.sshBaseArgs(t,["-o","ConnectTimeout=5"]).map((n)=>`'${n.replace(/'/g,"\\\"")}"`).join(" ")} true`,{stdio:"pipe",maxBuffer:nL});return}catch(n){E=n,await this.sleep(e)}throw Error(`Timed out waiting for SSH on ${t} after ${r}ms: ${E?.message??"unknown error"}`)}async waitForCloudInit(t){let{cloudInitIntervalMs:e,cloudInitTimeoutMs:r}=this.bootWait,d=Date.now();while(Date.now()-d<r){try{let E=this.sshExec(t,"if command -v cloud-init >/dev/null 2>&1; then cloud-init status --long 2>/dev/null || true; else echo 'status: done'; fi");if(/status:\s*error/.test(E))throw Error(`cloud-init reported an error on ${t}:
|
|
5989
5989
|
${E}`);if(/status:\s*(?:done|degraded)/.test(E))return}catch(E){if(E instanceof Error&&/cloud-init reported an error/.test(E.message))throw E}await this.sleep(e)}throw Error(`Timed out waiting for cloud-init to finish on ${t} after ${r}ms`)}outputsFromState(t,e){return{deployStoragePath:t.deployStoragePath||"/var/ts-cloud/staging",appInstanceId:t.serverId?String(t.serverId):void 0,appPublicIp:e?.public_net.ipv4?.ip||t.publicIp,appPublicIpv6:od(e?.public_net.ipv6?.ip)||t.publicIpv6,sshUser:t.sshUser||this.sshUser,servicesPrivateIp:t.servicesPrivateIp}}static SSH_HOST_KEY_OPTS=["-o","StrictHostKeyChecking=no","-o","UserKnownHostsFile=/dev/null","-o","LogLevel=ERROR"];static SSH_KEEPALIVE_OPTS=["-o","ConnectTimeout=30","-o","ServerAliveInterval=15","-o","ServerAliveCountMax=4"];sshBaseArgs(t,e=[]){return["-i",this.sshPrivateKeyPath,...eE.SSH_HOST_KEY_OPTS,...eE.SSH_KEEPALIVE_OPTS,"-o","BatchMode=yes",...e,`${this.sshUser}@${t}`]}scpToHost(t,e,r){let d=["scp","-i",this.sshPrivateKeyPath,...eE.SSH_HOST_KEY_OPTS,...eE.SSH_KEEPALIVE_OPTS,"-o","BatchMode=yes",e,`${this.sshUser}@${t}:${r}`].map((n)=>`"${n.replace(/"/g,"\\\"")}"`).join(" "),E=3;for(let n=1;n<=3;n++)try{EL(d,{stdio:"pipe",maxBuffer:nL});return}catch(c){if(n===3)throw Error(ff(c))}}sshExec(t,e){let r=e.replace(/'/g,"'\\''");try{return EL(`ssh ${this.sshBaseArgs(t).map((d)=>`"${d.replace(/"/g,"\\\"")}"`).join(" ")} '${r}'`,{encoding:"utf8",stdio:["pipe","pipe","pipe"],maxBuffer:nL})}catch(d){throw Error(ff(d))}}}class Oh{name="hetzner";usesCloudFormation=!1;async getComputeOutputs(){return{appPublicIp:"127.0.0.1",sshUser:"root"}}async uploadRelease(t){return{artifactRef:t.localPath}}async findComputeTargets(t){if((t.role||"app")!=="app")return[];return[{id:"localhost",name:"localhost",publicIp:"127.0.0.1",status:"running"}]}async runRemoteDeploy(t){let e=t.commands.join(`
|
|
5990
|
-
`);try{let r=Bun.spawn(["bash","-c",e],{stdout:"pipe",stderr:"pipe",env:process.env}),[d,E,n]=await Promise.all([new Response(r.stdout).text(),new Response(r.stderr).text(),r.exited]);return{success:n===0,instanceCount:1,perInstance:[{instanceId:"localhost",status:n===0?"Success":"Failed",output:d,error:E}]}}catch(r){return{success:!1,instanceCount:1,perInstance:[{instanceId:"localhost",status:"Failed",error:r?.message??String(r)}],error:r?.message??String(r)}}}}function cL(){let t=process.env.TS_CLOUD_DASHBOARD_BOX;return t!=null&&t!==""&&t!=="0"&&t.toLowerCase()!=="false"}function
|
|
5990
|
+
`);try{let r=Bun.spawn(["bash","-c",e],{stdout:"pipe",stderr:"pipe",env:process.env}),[d,E,n]=await Promise.all([new Response(r.stdout).text(),new Response(r.stderr).text(),r.exited]);return{success:n===0,instanceCount:1,perInstance:[{instanceId:"localhost",status:n===0?"Success":"Failed",output:d,error:E}]}}catch(r){return{success:!1,instanceCount:1,perInstance:[{instanceId:"localhost",status:"Failed",error:r?.message??String(r)}],error:r?.message??String(r)}}}}function cL(){let t=process.env.TS_CLOUD_DASHBOARD_BOX;return t!=null&&t!==""&&t!=="0"&&t.toLowerCase()!=="false"}function fr(t){if(cL())return new Oh;switch(t.provider??LE(t.config)){case"aws":return new Sh({region:t.config.project.region});case"hetzner":return new eE({apiToken:t.config.hetzner?.apiToken,allowStateOnly:Boolean(t.config.cloud?.attachTo),sshPrivateKeyPath:t.config.hetzner?.sshPrivateKeyPath,sshPublicKeyPath:t.config.hetzner?.sshPublicKeyPath,sshUser:t.config.hetzner?.sshUser,location:t.config.hetzner?.location});default:throw Error(`Unknown cloud provider: ${t.provider??LE(t.config)}`)}}class Uf{drivers=new Map;getDriver(t,e){let r=e??LE(t),d=`${r}:${t.project.slug}:${t.project.region||"default"}`,E=this.drivers.get(d);if(E)return E;let n=fr({config:t,provider:r});return this.drivers.set(d,n),n}}var vZ=new Uf;var KZ=String.raw`
|
|
5991
5991
|
const { readdir, readFile, readlink, stat } = await import('node:fs/promises')
|
|
5992
5992
|
|
|
5993
5993
|
const text = (command) => {
|
|
@@ -6111,8 +6111,8 @@ console.log(JSON.stringify({
|
|
|
6111
6111
|
publicTcpPorts: [...new Set(publicTcpPorts)].sort((a, b) => a - b),
|
|
6112
6112
|
}))
|
|
6113
6113
|
`;function zj(t){return`${t.replace(/\/+$/,"")}/.ts-cloud`}function Fj(t){return`${zj(t)}/shared-paths`}function Ch(t,e){let r=t.replace(/\/+$/,"");return{base:r,releases:`${r}/releases`,shared:`${r}/shared`,current:`${r}/current`,release:`${r}/releases/${e}`}}function gf(t,e){let r=Fj(t.base);return[`if [ -f ${r} ]; then`,' while IFS="\t" read -r TS_CLOUD_SP TS_CLOUD_TGT; do',' [ -n "$TS_CLOUD_SP" ] || continue',` [ -n "$TS_CLOUD_TGT" ] || TS_CLOUD_TGT="${t.shared}/$TS_CLOUD_SP"`,' [ -e "$TS_CLOUD_TGT" ] || continue',` rm -rf ${e}/"$TS_CLOUD_SP"`,` mkdir -p "$(dirname ${e}/"$TS_CLOUD_SP")"`,` ln -sfn "$TS_CLOUD_TGT" ${e}/"$TS_CLOUD_SP"`,` done < ${r}`,"fi"]}function $f(t,e={}){let r=e.to?[`[ -d ${t.releases}/${e.to} ] || { echo "rollback target ${t.releases}/${e.to} not found" >&2; exit 1; }`,...gf(t,`${t.releases}/${e.to}`),`ln -sfn ${t.releases}/${e.to} ${t.current}.tmp`,`mv -Tf ${t.current}.tmp ${t.current}`]:[`TS_CLOUD_CURRENT=$(readlink -f ${t.current} 2>/dev/null || true)`,`TS_CLOUD_PREV=$(ls -1dt ${t.releases}/*/ 2>/dev/null | sed 's#/$##' | while read -r r; do [ "$(readlink -f "$r")" != "$TS_CLOUD_CURRENT" ] && { echo "$r"; break; }; done)`,'[ -n "$TS_CLOUD_PREV" ] || { echo "no previous release to roll back to" >&2; exit 1; }',...gf(t,'"$TS_CLOUD_PREV"'),`ln -sfn "$TS_CLOUD_PREV" ${t.current}.tmp`,`mv -Tf ${t.current}.tmp ${t.current}`,'echo "rolled back to $TS_CLOUD_PREV"'];if(!e.unitBase)return r;let d=e.unitBase;return[...r,`TS_CLOUD_RB_ID=$(basename "$(readlink -f ${t.current})")`,`if [ -f /etc/systemd/system/${d}@.service ]; then systemctl start "${d}@\${TS_CLOUD_RB_ID}.service"; sleep 2; systemctl is-active --quiet "${d}@\${TS_CLOUD_RB_ID}.service" || { echo "rolled-back release failed to start" >&2; exit 1; }; systemctl enable "${d}@\${TS_CLOUD_RB_ID}.service" 2>/dev/null || true; systemctl list-units --plain --no-legend --type=service "${d}@*.service" 2>/dev/null | awk '{print $1}' | { grep -v "^${d}@\${TS_CLOUD_RB_ID}.service$" || true; } | while read -r TS_CLOUD_U; do systemctl stop "$TS_CLOUD_U" 2>/dev/null || true; systemctl disable "$TS_CLOUD_U" 2>/dev/null || true; done; elif [ -f /etc/systemd/system/${d}.service ]; then systemctl restart ${d}.service; fi`]}await Ht();import{chmodSync as Ik,copyFileSync as Dk,existsSync as lh,mkdirSync as fk,readFileSync as Uk,statSync as wk,writeFileSync as gk}from"node:fs";await Ht();import{basename as yk,dirname as Mj,isAbsolute as Xk,join as rE,resolve as ak}from"node:path";import{fileURLToPath as Gj}from"node:url";function yf(t){if(lh(rE(t,"packages","ui","pages"))||lh(rE(t,"packages","ui","package.json")))return{uiRoot:"packages/ui/dist",build:"cd packages/ui && bun install && bun run build"};let e=Mj(Gj(import.meta.url)),r=[rE(e,"ui"),rE(e,"..","ui"),rE(e,"..","..","ui"),rE(e,"..","dist","ui")];for(let d of r)if(lh(rE(d,"index.html"))||lh(rE(d,"serverless.html")))return{uiRoot:d,build:!1};return null}var Vj=new Set(["laravel","php","statamic","wordpress"]);function z_(t){if(t.framework)return t.framework;if(t.type&&Vj.has(t.type))return"laravel";return"stacks"}var Jk=`eval "$(cd ${We} && pantry env 2>/dev/null)"`;function Sc(t){return t?.split("/").at(-1)??t?.split(":").at(-1)??"unknown"}function Xf(t,e,r,d="ecs:aws",E=[]){let n=r.now??new Date;return t.map((c)=>{let _=c.serviceName??Sc(c.serviceArn),T=e.filter((I)=>!c.clusterArn||I.clusterArn===c.clusterArn),i=T.some((I)=>!!I.group)?T.filter((I)=>I.group===`service:${_}`):T,h=c.status==="ACTIVE"?(c.runningCount??0)<(c.desiredCount??0)?"degraded":"running":Od(c.status),R=E.find((I)=>I.taskDefinitionArn===c.taskDefinition),N=Array.isArray(R?.containerDefinitions)?R.containerDefinitions:[],A=[...new Set(N.map((I)=>I.logConfiguration?.options?.["awslogs-group"]).filter((I)=>typeof I==="string"))],u=N.flatMap((I)=>(I.mountPoints??[]).map((a)=>({source:a.sourceVolume,target:a.containerPath,type:"volume",readOnly:!!a.readOnly}))),f=N.flatMap((I)=>(I.portMappings??[]).map((a,P)=>({id:`${I.name??"container"}:${P}`,name:I.name,mode:R?.networkMode,ports:[{container:a.containerPort,host:a.hostPort,protocol:a.protocol}]}))),w=r.project&&r.environment&&_.startsWith(`${r.project}-${r.environment}-`)?_.slice(`${r.project}-${r.environment}-`.length):_;return{id:xr("ecs",d,c.serviceArn??_),provider:"ecs",kind:"service",name:_,status:h,rawStatus:c.status,health:h==="running"?"healthy":h==="failed"||h==="degraded"?"unhealthy":"unknown",desiredReplicas:c.desiredCount,runningReplicas:c.runningCount,image:N[0]?.image,runtime:c.launchType??"ECS",version:Sc(c.taskDefinition),ageSeconds:YE(c.deployments?.[0]?.createdAt,n),restartCount:0,tags:{},links:{project:r.project,environment:r.environment,service:w,release:Sc(c.taskDefinition),providerId:c.serviceArn},replicas:i.map((I)=>{let a=Od(I.lastStatus);return{id:xr("ecs",d,I.taskArn??Sc(I.taskArn)),name:Sc(I.taskArn),status:a,rawStatus:I.lastStatus,createdAt:I.createdAt,startedAt:I.startedAt,stoppedAt:I.stoppedAt,host:I.containerInstanceArn,containers:(I.containers??[]).map((P)=>({id:P.containerArn??P.name??"container",name:P.name??"container",image:N.find((j)=>j.name===P.name)?.image,imageDigest:P.imageDigest,status:Od(P.lastStatus),rawStatus:P.lastStatus,exitCode:P.exitCode,reason:P.reason,runtime:"ecs"}))}}),networks:f,mounts:u,capabilities:QE(["start","stop","restart","redeploy","scale","inspect",...A.length?["logs"]:[]],"This ECS runtime does not expose exec or file transfer; logs require an awslogs task-definition driver"),config:ud({clusterArn:c.clusterArn,taskDefinition:c.taskDefinition,launchType:c.launchType,pendingCount:c.pendingCount,deployments:c.deployments,logGroups:A,executionRoleArn:R?.executionRoleArn,taskRoleArn:R?.taskRoleArn,cpu:R?.cpu,memory:R?.memory}),discoveredAt:n.toISOString(),sourceId:d}})}function af(t,e,r="lambda:aws"){let d=e.now??new Date;return t.map((E)=>{let n=E.FunctionName??Sc(E.FunctionArn),c=E.State==="Active"?"running":Od(E.State);return{id:xr("lambda",r,E.FunctionArn??n),provider:"lambda",kind:"function",name:n,status:c,rawStatus:E.State,health:c==="running"?"healthy":c==="failed"?"unhealthy":"unknown",desiredReplicas:void 0,runningReplicas:void 0,image:void 0,runtime:E.Runtime,version:E.Version,architecture:E.Architectures?.join(", "),ageSeconds:YE(E.LastModified,d),restartCount:0,tags:{},links:{project:e.project,environment:e.environment,service:n,providerId:E.FunctionArn},resources:{memoryLimitBytes:E.MemorySize==null?void 0:E.MemorySize*1024*1024},replicas:[],networks:[],mounts:[],capabilities:QE(["logs","inspect"],"Lambda has no persistent process to start, stop, restart, exec, or browse files; deploy a release to replace code"),config:ud({handler:E.Handler,timeout:E.Timeout,codeSize:E.CodeSize,stateReason:E.StateReason,environmentKeys:Object.keys(E.Environment?.Variables??{})}),discoveredAt:d.toISOString(),sourceId:r}})}function mj(t){let e=t.trim();if(!e)return[];let r=JSON.parse(e);if(!Array.isArray(r))throw Error("Docker inspect output must be an array");return r.filter((d)=>d&&typeof d.Id==="string")}function pj(t){let e=Object.entries(t.NetworkSettings?.Ports??{}).flatMap(([r,d])=>{let[E,n]=r.split("/");return(d??[]).map((c)=>({container:Number(E)||void 0,host:Number(c.HostPort)||void 0,protocol:n,address:c.HostIp}))});return Object.entries(t.NetworkSettings?.Networks??{}).map(([r,d])=>({id:d.NetworkID||r,name:r,mode:t.HostConfig?.NetworkMode,addresses:[d.IPAddress,d.GlobalIPv6Address].filter(Boolean),ports:e}))}function tz(t){return(t.Mounts??[]).filter((e)=>!!e.Destination).map((e)=>({source:e.Source,target:e.Destination,type:e.Type,readOnly:e.RW===!1}))}function ez(t,e,r=e.server??"local"){let d=e.now??new Date;return t.map((E)=>{let n=E.State?.OOMKilled?"oomkilled":E.State?.Restarting?"starting":E.State?.Status,c=Od(n),_=(E.Name??E.Id.slice(0,12)).replace(/^\//,""),T=E.Config?.Labels??{},i=tz(E),h=pj(E),R={id:E.Id,name:_,image:E.Config?.Image,imageDigest:E.Image,runtime:"docker",status:c,rawStatus:n,exitCode:E.State?.ExitCode,reason:E.State?.Error,resources:{memoryLimitBytes:E.HostConfig?.Memory||void 0},networks:h,mounts:i};return{id:xr("docker",r,E.Id),provider:"docker",kind:"container",name:_,status:c,rawStatus:n,health:c==="running"?"healthy":c==="failed"?"unhealthy":"unknown",desiredReplicas:1,runningReplicas:c==="running"?1:0,image:E.Config?.Image,runtime:"docker",ageSeconds:YE(E.State?.StartedAt,d),restartCount:E.RestartCount??0,tags:T,links:{project:e.project,environment:e.environment,server:e.server??r.replace(/^docker:/,""),service:T["com.docker.compose.service"]??T["ts-cloud.service"]??_,release:T["ts-cloud.release"],providerId:E.Id},resources:R.resources,replicas:[{id:xr("docker",r,`${E.Id}:0`),name:_,status:c,rawStatus:n,startedAt:E.State?.StartedAt,stoppedAt:E.State?.FinishedAt,restartCount:E.RestartCount,containers:[R],resources:R.resources}],networks:h,mounts:i,capabilities:QE(["start","stop","restart","logs","exec","inspect","files"],"Use the owning Compose service for redeploy and scale"),config:ud({image:E.Config?.Image,labels:T,environmentKeys:(E.Config?.Env??[]).map((N)=>N.split("=",1)[0]),networkMode:E.HostConfig?.NetworkMode}),discoveredAt:d.toISOString(),sourceId:r}})}class _L{inspect;id;provider="docker";constructor(t,e="docker:local"){this.inspect=t;this.id=e}async discover(t){return ez(mj(await this.inspect(t)),t,this.id)}}function rz(t){let e=[];for(let r of t.split(`
|
|
6114
|
-
`)){if(!r.startsWith("TSCLOUD_SYSTEMD\t"))continue;let[,d,E,n,c,_,T,i,h,R,N,A,u,f]=r.split("\t");if(!d||!/^[A-Za-z0-9_.@:-]+\.service$/.test(d))continue;e.push({unit:d,load:E,active:n,sub:c,description:_,enabled:T,pid:Number(i)||void 0,memoryBytes:FD(h),restartCount:Number(R)||0,activeSince:N||void 0,fragmentPath:A||void 0,workingDirectory:u?.startsWith("/")?u:void 0,user:f||void 0})}return e}function dz(t,e,r=e.server??"local"){let d=e.now??new Date;return t.map((E)=>{let n=Od(E.active==="active"?E.sub||E.active:E.active),c=E.unit.replace(/\.service$/,""),_=/^(.*?) (?:release [^ ]+|queue worker|daemon |scheduler)(?: |$)/.exec(E.description??"")?.[1]??(e.project&&c.startsWith(`${e.project}-`)?c.slice(e.project.length+1).split("@",1)[0]:void 0),T=c.includes("@")?c.slice(c.indexOf("@")+1):void 0,i=E.workingDirectory?[{target:E.workingDirectory,type:"working-directory"}]:[],h=["start","stop","restart","logs","exec","inspect",...i.length?["files"]:[]];return{id:xr("systemd",r,E.unit),provider:"systemd",kind:"service",name:c,displayName:E.description||c,status:n,rawStatus:[E.load,E.active,E.sub].filter(Boolean).join("/"),health:n==="running"?"healthy":n==="failed"?"unhealthy":"unknown",desiredReplicas:1,runningReplicas:n==="running"?1:0,ageSeconds:YE(E.activeSince,d),restartCount:E.restartCount,tags:{enabled:E.enabled??"unknown"},links:{project:e.project,environment:e.environment,server:e.server??r.replace(/^systemd:/,""),service:_,release:T,providerId:E.unit},resources:{memoryBytes:E.memoryBytes},replicas:[{id:xr("systemd",r,`${E.unit}:main`),name:"main",status:n,pid:E.pid,startedAt:E.activeSince,restartCount:E.restartCount,resources:{memoryBytes:E.memoryBytes}}],networks:[],mounts:i,capabilities:QE(h,i.length?"This systemd runtime does not support redeploy or replica scaling through the scoped explorer":"File transfer requires a provider-reported service working directory; redeploy and scaling are unavailable"),config:ud({fragmentPath:E.fragmentPath,workingDirectory:E.workingDirectory,user:E.user,environment:E.environment,enabled:E.enabled}),discoveredAt:d.toISOString(),sourceId:r}})}class TL{read;id;provider="systemd";constructor(t,e="systemd:local"){this.read=t;this.id=e}async discover(t){return dz(rz(await this.read(t)),t,this.id)}}function Ez(t,e){if(!t.success)throw Error(t.error||t.perInstance?.[0]?.error||`${e} discovery failed`);return t.perInstance?.[0]?.output??""}function nz(){return["set -uo pipefail",'command -v systemctl >/dev/null 2>&1 || { echo "systemctl is unavailable" >&2; exit 127; }',"systemctl list-units --type=service --all --plain --no-legend 2>/dev/null | awk '{print $1}' | while IFS= read -r unit; do",' [ -n "$unit" ] || continue',' clean() { printf "%s" "$1" | tr "\\t\\r\\n" " "; }',' load=$(systemctl show "$unit" -p LoadState --value 2>/dev/null || true)',' active=$(systemctl show "$unit" -p ActiveState --value 2>/dev/null || true)',' sub=$(systemctl show "$unit" -p SubState --value 2>/dev/null || true)',' description=$(systemctl show "$unit" -p Description --value 2>/dev/null || true)',' enabled=$(systemctl is-enabled "$unit" 2>/dev/null || true)',' pid=$(systemctl show "$unit" -p MainPID --value 2>/dev/null || true)',' memory=$(systemctl show "$unit" -p MemoryCurrent --value 2>/dev/null || true)',' restarts=$(systemctl show "$unit" -p NRestarts --value 2>/dev/null || true)',' since=$(systemctl show "$unit" -p ActiveEnterTimestamp --value 2>/dev/null || true)',' fragment=$(systemctl show "$unit" -p FragmentPath --value 2>/dev/null || true)',' working=$(systemctl show "$unit" -p WorkingDirectory --value 2>/dev/null || true)',' user=$(systemctl show "$unit" -p User --value 2>/dev/null || true)',' printf "TSCLOUD_SYSTEMD\\t%s\\t%s\\t%s\\t%s\\t%s\\t%s\\t%s\\t%s\\t%s\\t%s\\t%s\\t%s\\t%s\\n" "$(clean "$unit")" "$(clean "$load")" "$(clean "$active")" "$(clean "$sub")" "$(clean "$description")" "$(clean "$enabled")" "$(clean "$pid")" "$(clean "$memory")" "$(clean "$restarts")" "$(clean "$since")" "$(clean "$fragment")" "$(clean "$working")" "$(clean "$user")"',"done"]}function cz(){return["set -uo pipefail",'if ! command -v docker >/dev/null 2>&1; then echo "[]"; exit 0; fi',"ids=$(docker ps -aq)",'if [ -z "$ids" ]; then echo "[]"; else docker inspect $ids; fi']}function Pf(t,e,r,d,E){let n=`${t}:${r.id}`,c=async()=>Ez(await e.runRemoteDeploy({targets:[r],commands:t==="systemd"?nz():cz(),timeoutSeconds:30,comment:`ts-cloud runtime discovery:${t}`,tags:{Project:d.project.slug,Environment:E,Role:"app"}}),n);return t==="systemd"?new TL(c,n):new _L(c,n)}async function Ih(t,e=100){let r=[],d;for(let E=0;E<e;E++){let n=await t(d);if(r.push(...n.items),!n.nextToken)return r;d=n.nextToken}throw Error(`Provider pagination exceeded ${e} pages`)}class jf{client;prefix;id="ecs:aws";provider="ecs";constructor(t,e){this.client=t;this.prefix=e}async discover(t){let e=await Ih(async(n)=>{let c=await this.client.listClusters({nextToken:n,maxResults:100});return{items:c.clusterArns??[],nextToken:c.nextToken}}),r=[],d=[],E=[];for(let n of e){let c=(await Ih(async(_)=>{let T=await this.client.listServices(n,{nextToken:_,maxResults:100});return{items:T.serviceArns??[],nextToken:T.nextToken}})).filter((_)=>_.split("/").at(-1)?.startsWith(this.prefix));for(let _=0;_<c.length;_+=10){let T=await this.client.describeServices({cluster:n,services:c.slice(_,_+10)});r.push(...T.services??[])}for(let _ of r.filter((T)=>T.clusterArn===n||!T.clusterArn)){let T=await Ih(async(i)=>{let h=await this.client.listTasks(n,_.serviceName,{nextToken:i,maxResults:100});return{items:h.taskArns??[],nextToken:h.nextToken}});for(let i=0;i<T.length;i+=100){let h=await this.client.describeTasks(n,T.slice(i,i+100));d.push(...h.tasks??[])}}}if(this.client.describeTaskDefinition)for(let n of[...new Set(r.map((c)=>c.taskDefinition).filter((c)=>!!c))]){let c=await this.client.describeTaskDefinition(n);if(c.taskDefinition)E.push(c.taskDefinition)}return Xf(r,d,t,this.id,E)}}class zf{client;prefix;id="lambda:aws";provider="lambda";constructor(t,e){this.client=t;this.prefix=e}async discover(t){let e=(await Ih(async(r)=>{let d=await this.client.listFunctions({Marker:r,MaxItems:50});return{items:d.Functions??[],nextToken:d.NextMarker}})).filter((r)=>r.FunctionName?.startsWith(this.prefix));return af(e,t,this.id)}}async function _z(t,e,r={}){let d=[],E=ed(t),n=LE(t),c=t.aws?.profile,_=t.aws?.region??t.project.region??"us-east-1",T=`${t.project.slug}-${e}`;if(E!=="serverless"){let i=r.driver??
|
|
6115
|
-
[output truncated]`}function Dh(t){return{success:!1,instanceCount:0,perInstance:[],error:t instanceof Error?t.message:String(t)}}function fr(t){return`'${t.replaceAll("'",`'"'"'`)}'`}function iz(t,e){return Number.isFinite(t)?Math.min(1e4,Math.max(0,Math.floor(t))):e}function hz(t){let e=t.config,r=typeof e.clusterArn==="string"?e.clusterArn:void 0,d=t.links.providerId||t.name;return r&&d?{cluster:r,service:d}:void 0}function Rz(t,e){return t.find((r)=>r.id===e.links.server)??(t.length===1?t[0]:void 0)}function Sz(t,e){if(t.provider==="systemd"){let r=t.links.providerId;if(!r||!fh.test(r)||!["start","stop","restart"].includes(e))return;return[`systemctl ${e} ${r}`,`systemctl is-active ${r} 2>/dev/null || true`]}if(t.provider==="docker"){let r=t.links.providerId;if(!r||!Uh.test(r)||!["start","stop","restart"].includes(e))return;return[`docker ${e} ${r}`,`docker inspect --format '{{.State.Status}}' ${r}`]}return}function Nz(t,e){if(!e.startsWith("/")||e.includes("\x00"))return{ok:!1,error:"An absolute path is required."};let r=[];for(let _ of e.split("/")){if(!_||_===".")continue;if(_===".."){if(!r.length)return{ok:!1,error:"Path traversal is not allowed."};r.pop()}else r.push(_)}let d=`/${r.join("/")}`;if(Tz.some((_)=>d===_||d.startsWith(`${_}/`)))return{ok:!1,error:"Sensitive host paths are not available through runtime file access."};let E=t.links.project?.replace(/[^A-Za-z0-9_-]/g,""),n=t.links.service?.replace(/[^A-Za-z0-9_-]/g,"");if(![...E&&n?[`/var/www/${E}/${n}`,`/srv/${E}/${n}`]:[],...t.mounts.map((_)=>_.target).filter((_)=>_.startsWith("/"))].some((_)=>d===_||d.startsWith(`${_.replace(/\/$/,"")}/`)))return{ok:!1,error:"Path is outside this service’s owned roots."};return{ok:!0,path:d}}function Az(t,e){let r=t.links.project?.replace(/[^A-Za-z0-9_-]/g,""),d=t.links.service?.replace(/[^A-Za-z0-9_-]/g,"");return[...r&&d?[`/var/www/${r}/${d}`,`/srv/${r}/${d}`]:[],...t.mounts.map((E)=>E.target).filter((E)=>E.startsWith("/"))].sort((E,n)=>n.length-E.length).find((E)=>e===E||e.startsWith(`${E.replace(/\/$/,"")}/`))}var Bf={process:["ps","-eo","pid,ppid,user,%cpu,%mem,etime,command","--sort=-%cpu"],sockets:["ss","-lntup"],filesystem:["df","-h"]};class sr{config;environment;dependencies;region;profile;constructor(t,e,r={}){this.config=t;this.environment=e;this.dependencies=r;this.region=t.aws?.region??t.project.region??"us-east-1",this.profile=t.aws?.profile}async inventory(){return this.dependencies.inventory?.()??Fr(this.config,this.environment,{driver:this.dependencies.driver})}async workload(t){return(await this.inventory()).workloads.find((e)=>e.id===t)}async remote(t,e,r,d){let E=this.dependencies.driver??Dr({config:this.config}),n=await E.findComputeTargets({slug:this.config.project.slug,environment:this.environment,role:"app"}),c=Rz(n,t);if(!c)throw Error("The workload server is no longer reachable in this scope.");return E.runRemoteDeploy({targets:[c],commands:e,timeoutSeconds:r,comment:d,tags:{Project:this.config.project.slug,Environment:this.environment,Role:"app"}})}async run(t){let e=await this.workload(t.workloadId),r={workloadId:t.workloadId,action:t.action};if(!e)return{...r,ok:!1,error:"Workload was not found in the current project and environment."};let d=e.capabilities[t.action];if(!d.supported)return{...r,ok:!1,error:d.reason??`${t.action} is unsupported for ${e.provider}.`};if(d.requiresConfirmation&&t.confirm!==e.name)return{...r,ok:!1,error:`Type "${e.name}" to ${t.action} this workload.`};if(d.requiresRecentAuth&&!t.recentAuth)return{...r,ok:!1,error:"Sign in again before using elevated runtime access."};if(t.action==="inspect")return{...r,ok:!0,workload:e};if(e.provider==="systemd"||e.provider==="docker"){let E=Sz(e,t.action);if(!E)return{...r,ok:!1,error:`${t.action} is not implemented for ${e.provider}.`};let n=await this.remote(e,["set -uo pipefail",...E],60,`ts-cloud runtime:${t.action}`).catch(Dh);return{...r,ok:n.success,command:E[0],stdout:Nc(n.perInstance?.[0]?.output??""),stderr:Nc(n.perInstance?.[0]?.error??n.error??""),error:n.success?void 0:n.error??"Runtime operation failed."}}if(e.provider==="ecs"){let E=hz(e);if(!E)return{...r,ok:!1,error:"ECS cluster or service identity is unavailable."};let n=this.dependencies.ecs??new U_(this.region,this.profile);if(t.action==="scale"){let c=iz(t.replicas,e.desiredReplicas??1);return await n.scaleService(E.cluster,E.service,c),{...r,ok:!0,command:`ecs scale ${e.name} ${c}`}}if(t.action==="start"||t.action==="stop"){let c=t.action==="stop"?0:Math.max(1,e.desiredReplicas??1);return await n.scaleService(E.cluster,E.service,c),{...r,ok:!0,command:`ecs scale ${e.name} ${c}`}}if(t.action==="restart"||t.action==="redeploy")return await n.forceNewDeployment(E.cluster,E.service),{...r,ok:!0,command:`ecs redeploy ${e.name}`}}return{...r,ok:!1,error:`${t.action} is not implemented for ${e.provider}.`}}async exec(t){let e={workloadId:t.workloadId,preset:t.preset},r=await this.workload(t.workloadId);if(!r)return{...e,ok:!1,error:"Workload was not found in the current project and environment."};if(process.env.TS_CLOUD_RUNTIME_EXEC==="0")return{...e,ok:!1,error:"Runtime exec is disabled by TS_CLOUD_RUNTIME_EXEC."};if(!r.capabilities.exec.supported)return{...e,ok:!1,error:r.capabilities.exec.reason??"Exec is unsupported for this workload."};if(t.confirm!==r.name)return{...e,ok:!1,error:`Type "${r.name}" to open exec access.`};if(!t.recentAuth)return{...e,ok:!1,error:"Sign in again before using elevated runtime access."};let d=t.preset&&Bf[t.preset];if(!d&&!t.command?.trim())return{...e,ok:!1,error:"Choose a diagnostic preset or provide a command."};if(t.command&&r.provider!=="docker")return{...e,ok:!1,error:"Free-form exec is restricted to isolated containers; use a diagnostic preset for system services."};let E=r.links.providerId??"",n;if(r.provider==="docker"&&Uh.test(E)){let _=t.command?.trim()||d.map(fr).join(" ");n=`docker exec ${E} sh -lc ${fr(_)}`}else if(r.provider==="systemd"&&fh.test(E)&&t.preset)n=t.preset==="process"?`systemctl status ${E} --no-pager --full`:Bf[t.preset].map(fr).join(" ");if(!n)return{...e,ok:!1,error:"Exec target identity is invalid or unsupported."};let c=await this.remote(r,["set -uo pipefail",n],60,"ts-cloud runtime:exec").catch(Dh);return{...e,ok:c.success,command:n,stdout:Nc(c.perInstance?.[0]?.output??""),stderr:Nc(c.perInstance?.[0]?.error??c.error??""),error:c.success?void 0:c.error??"Exec command failed."}}async readFile(t){let e={workloadId:t.workloadId,path:t.path},r=await this.fileTarget(t);if("error"in r)return{...e,ok:!1,error:r.error};let{workload:d,path:E,root:n,providerId:c}=r,T=`sh -c ${fr('resolved=$(realpath -m "$1"); root=$(realpath -m "$3"); case "$resolved" in "$root"|"$root"/*) ;; *) exit 73;; esac; test -f "$resolved"; size=$(wc -c < "$resolved"); printf "__TSCLOUD_SIZE__=%s\\n" "$size"; head -c "$2" "$resolved" | base64')} sh ${fr(E)} ${F_} ${fr(n)}`,i=d.provider==="docker"?`docker exec ${c} ${T}`:T,h=await this.remote(d,[i],30,"ts-cloud runtime:file-read").catch(Dh);if(!h.success)return{...e,ok:!1,error:h.error??h.perInstance?.[0]?.error??"File read failed."};let R=h.perInstance?.[0]?.output??"",N=/__TSCLOUD_SIZE__=(\d+)\r?\n/.exec(R);if(!N)return{...e,ok:!1,error:"The remote file response was invalid."};let A=Number(N[1]),u=R.slice((N.index??0)+N[0].length).replace(/\s+/g,"");if(Buffer.from(u,"base64").byteLength>F_)return{...e,ok:!1,error:"The remote file exceeded the transfer limit."};return{...e,ok:!0,contentBase64:u,size:A,truncated:A>F_}}async writeFile(t){let e={workloadId:t.workloadId,path:t.path},r=await this.fileTarget(t);if("error"in r)return{...e,ok:!1,error:r.error};if(!/^[A-Za-z0-9+/]*={0,2}$/.test(t.contentBase64))return{...e,ok:!1,error:"File content must be valid base64."};let d=Buffer.from(t.contentBase64,"base64");if(d.toString("base64")!==t.contentBase64)return{...e,ok:!1,error:"File content must be canonical base64."};if(d.byteLength>F_)return{...e,ok:!1,error:`File uploads are limited to ${F_} bytes.`};let{workload:E,path:n,root:c,providerId:_}=r,i=`sh -c ${fr('resolved=$(realpath -m "$1"); root=$(realpath -m "$2"); case "$resolved" in "$root"|"$root"/*) ;; *) exit 73;; esac; mkdir -p "$(dirname "$resolved")"; tmp="$resolved.ts-cloud-$$"; base64 -d > "$tmp"; chmod 600 "$tmp"; mv "$tmp" "$resolved"')} sh ${fr(n)} ${fr(c)}`,h=E.provider==="docker"?`printf %s ${fr(t.contentBase64)} | docker exec -i ${_} ${i}`:`printf %s ${fr(t.contentBase64)} | ${i}`,R=await this.remote(E,[h],30,"ts-cloud runtime:file-write").catch(Dh);return{...e,ok:R.success,size:d.byteLength,truncated:!1,error:R.success?void 0:R.error??R.perInstance?.[0]?.error??"File write failed."}}async fileTarget(t){let e=await this.workload(t.workloadId);if(!e)return{error:"Workload was not found in the current project and environment."};if(process.env.TS_CLOUD_RUNTIME_FILE_ACCESS==="0")return{error:"Runtime file access is disabled by TS_CLOUD_RUNTIME_FILE_ACCESS."};if(!e.capabilities.files.supported)return{error:e.capabilities.files.reason??"File access is unsupported for this workload."};if(t.confirm!==e.name)return{error:`Type "${e.name}" to access workload files.`};if(!t.recentAuth)return{error:"Sign in again before using elevated runtime access."};let r=Nz(e,t.path);if(!r.ok)return{error:r.error};let d=Az(e,r.path),E=e.links.providerId??"";if(!d||e.provider==="systemd"&&!fh.test(E)||e.provider==="docker"&&!Uh.test(E))return{error:"File target identity is invalid or unsupported."};return{workload:e,path:r.path,root:d,providerId:E}}async logs(t,e={}){let r=await this.workload(t);if(!r)throw Error("Workload was not found in the current project and environment.");if(!r.capabilities.logs.supported)throw Error(r.capabilities.logs.reason??"Logs are unsupported for this workload.");let d=Math.min(1000,Math.max(1,Math.floor(e.limit??200)));if(r.provider==="lambda"||r.provider==="ecs"){let h=this.dependencies.logs??new w_(this.region,this.profile),R=r.config.logGroups,N=r.provider==="lambda"?`/aws/lambda/${r.name}`:Array.isArray(R)&&typeof R[0]==="string"?R[0]:void 0;if(!N)throw Error("The ECS task definition does not declare an awslogs group.");let A=await h.filterLogEvents({logGroupName:N,startTime:e.since?.getTime(),limit:d}),u=(A.events??[]).slice(0,d).map((f)=>({timestamp:f.timestamp==null?void 0:new Date(f.timestamp).toISOString(),message:Nc(String(f.message??""))}));return{workloadId:t,provider:r.provider,lines:u,nextCursor:A.nextToken,truncated:(A.events?.length??0)>=d}}let E=r.links.providerId??"",n=e.since&&Number.isFinite(e.since.getTime())?e.since:void 0,c=r.provider==="systemd"&&fh.test(E)?`journalctl -u ${E} --no-pager -n ${d} -o short-iso${n?` --since ${fr(n.toISOString())}`:""}`:r.provider==="docker"&&Uh.test(E)?`docker logs --timestamps --tail ${d}${n?` --since ${Math.floor(n.getTime()/1000)}`:""} ${E} 2>&1`:void 0;if(!c)throw Error("Log target identity is invalid.");let _=await this.remote(r,[c],30,"ts-cloud runtime:logs");if(!_.success)throw Error(_.error??_.perInstance?.[0]?.error??"Log read failed.");let T=Nc(_.perInstance?.[0]?.output??""),i=T.split(`
|
|
6114
|
+
`)){if(!r.startsWith("TSCLOUD_SYSTEMD\t"))continue;let[,d,E,n,c,_,T,i,h,R,N,A,u,f]=r.split("\t");if(!d||!/^[A-Za-z0-9_.@:-]+\.service$/.test(d))continue;e.push({unit:d,load:E,active:n,sub:c,description:_,enabled:T,pid:Number(i)||void 0,memoryBytes:FD(h),restartCount:Number(R)||0,activeSince:N||void 0,fragmentPath:A||void 0,workingDirectory:u?.startsWith("/")?u:void 0,user:f||void 0})}return e}function dz(t,e,r=e.server??"local"){let d=e.now??new Date;return t.map((E)=>{let n=Od(E.active==="active"?E.sub||E.active:E.active),c=E.unit.replace(/\.service$/,""),_=/^(.*?) (?:release [^ ]+|queue worker|daemon |scheduler)(?: |$)/.exec(E.description??"")?.[1]??(e.project&&c.startsWith(`${e.project}-`)?c.slice(e.project.length+1).split("@",1)[0]:void 0),T=c.includes("@")?c.slice(c.indexOf("@")+1):void 0,i=E.workingDirectory?[{target:E.workingDirectory,type:"working-directory"}]:[],h=["start","stop","restart","logs","exec","inspect",...i.length?["files"]:[]];return{id:xr("systemd",r,E.unit),provider:"systemd",kind:"service",name:c,displayName:E.description||c,status:n,rawStatus:[E.load,E.active,E.sub].filter(Boolean).join("/"),health:n==="running"?"healthy":n==="failed"?"unhealthy":"unknown",desiredReplicas:1,runningReplicas:n==="running"?1:0,ageSeconds:YE(E.activeSince,d),restartCount:E.restartCount,tags:{enabled:E.enabled??"unknown"},links:{project:e.project,environment:e.environment,server:e.server??r.replace(/^systemd:/,""),service:_,release:T,providerId:E.unit},resources:{memoryBytes:E.memoryBytes},replicas:[{id:xr("systemd",r,`${E.unit}:main`),name:"main",status:n,pid:E.pid,startedAt:E.activeSince,restartCount:E.restartCount,resources:{memoryBytes:E.memoryBytes}}],networks:[],mounts:i,capabilities:QE(h,i.length?"This systemd runtime does not support redeploy or replica scaling through the scoped explorer":"File transfer requires a provider-reported service working directory; redeploy and scaling are unavailable"),config:ud({fragmentPath:E.fragmentPath,workingDirectory:E.workingDirectory,user:E.user,environment:E.environment,enabled:E.enabled}),discoveredAt:d.toISOString(),sourceId:r}})}class TL{read;id;provider="systemd";constructor(t,e="systemd:local"){this.read=t;this.id=e}async discover(t){return dz(rz(await this.read(t)),t,this.id)}}function Ez(t,e){if(!t.success)throw Error(t.error||t.perInstance?.[0]?.error||`${e} discovery failed`);return t.perInstance?.[0]?.output??""}function nz(){return["set -uo pipefail",'command -v systemctl >/dev/null 2>&1 || { echo "systemctl is unavailable" >&2; exit 127; }',"systemctl list-units --type=service --all --plain --no-legend 2>/dev/null | awk '{print $1}' | while IFS= read -r unit; do",' [ -n "$unit" ] || continue',' clean() { printf "%s" "$1" | tr "\\t\\r\\n" " "; }',' load=$(systemctl show "$unit" -p LoadState --value 2>/dev/null || true)',' active=$(systemctl show "$unit" -p ActiveState --value 2>/dev/null || true)',' sub=$(systemctl show "$unit" -p SubState --value 2>/dev/null || true)',' description=$(systemctl show "$unit" -p Description --value 2>/dev/null || true)',' enabled=$(systemctl is-enabled "$unit" 2>/dev/null || true)',' pid=$(systemctl show "$unit" -p MainPID --value 2>/dev/null || true)',' memory=$(systemctl show "$unit" -p MemoryCurrent --value 2>/dev/null || true)',' restarts=$(systemctl show "$unit" -p NRestarts --value 2>/dev/null || true)',' since=$(systemctl show "$unit" -p ActiveEnterTimestamp --value 2>/dev/null || true)',' fragment=$(systemctl show "$unit" -p FragmentPath --value 2>/dev/null || true)',' working=$(systemctl show "$unit" -p WorkingDirectory --value 2>/dev/null || true)',' user=$(systemctl show "$unit" -p User --value 2>/dev/null || true)',' printf "TSCLOUD_SYSTEMD\\t%s\\t%s\\t%s\\t%s\\t%s\\t%s\\t%s\\t%s\\t%s\\t%s\\t%s\\t%s\\t%s\\n" "$(clean "$unit")" "$(clean "$load")" "$(clean "$active")" "$(clean "$sub")" "$(clean "$description")" "$(clean "$enabled")" "$(clean "$pid")" "$(clean "$memory")" "$(clean "$restarts")" "$(clean "$since")" "$(clean "$fragment")" "$(clean "$working")" "$(clean "$user")"',"done"]}function cz(){return["set -uo pipefail",'if ! command -v docker >/dev/null 2>&1; then echo "[]"; exit 0; fi',"ids=$(docker ps -aq)",'if [ -z "$ids" ]; then echo "[]"; else docker inspect $ids; fi']}function Pf(t,e,r,d,E){let n=`${t}:${r.id}`,c=async()=>Ez(await e.runRemoteDeploy({targets:[r],commands:t==="systemd"?nz():cz(),timeoutSeconds:30,comment:`ts-cloud runtime discovery:${t}`,tags:{Project:d.project.slug,Environment:E,Role:"app"}}),n);return t==="systemd"?new TL(c,n):new _L(c,n)}async function Ih(t,e=100){let r=[],d;for(let E=0;E<e;E++){let n=await t(d);if(r.push(...n.items),!n.nextToken)return r;d=n.nextToken}throw Error(`Provider pagination exceeded ${e} pages`)}class jf{client;prefix;id="ecs:aws";provider="ecs";constructor(t,e){this.client=t;this.prefix=e}async discover(t){let e=await Ih(async(n)=>{let c=await this.client.listClusters({nextToken:n,maxResults:100});return{items:c.clusterArns??[],nextToken:c.nextToken}}),r=[],d=[],E=[];for(let n of e){let c=(await Ih(async(_)=>{let T=await this.client.listServices(n,{nextToken:_,maxResults:100});return{items:T.serviceArns??[],nextToken:T.nextToken}})).filter((_)=>_.split("/").at(-1)?.startsWith(this.prefix));for(let _=0;_<c.length;_+=10){let T=await this.client.describeServices({cluster:n,services:c.slice(_,_+10)});r.push(...T.services??[])}for(let _ of r.filter((T)=>T.clusterArn===n||!T.clusterArn)){let T=await Ih(async(i)=>{let h=await this.client.listTasks(n,_.serviceName,{nextToken:i,maxResults:100});return{items:h.taskArns??[],nextToken:h.nextToken}});for(let i=0;i<T.length;i+=100){let h=await this.client.describeTasks(n,T.slice(i,i+100));d.push(...h.tasks??[])}}}if(this.client.describeTaskDefinition)for(let n of[...new Set(r.map((c)=>c.taskDefinition).filter((c)=>!!c))]){let c=await this.client.describeTaskDefinition(n);if(c.taskDefinition)E.push(c.taskDefinition)}return Xf(r,d,t,this.id,E)}}class zf{client;prefix;id="lambda:aws";provider="lambda";constructor(t,e){this.client=t;this.prefix=e}async discover(t){let e=(await Ih(async(r)=>{let d=await this.client.listFunctions({Marker:r,MaxItems:50});return{items:d.Functions??[],nextToken:d.NextMarker}})).filter((r)=>r.FunctionName?.startsWith(this.prefix));return af(e,t,this.id)}}async function _z(t,e,r={}){let d=[],E=ed(t),n=LE(t),c=t.aws?.profile,_=t.aws?.region??t.project.region??"us-east-1",T=`${t.project.slug}-${e}`;if(E!=="serverless"){let i=r.driver??fr({config:t}),h=await i.findComputeTargets({slug:t.project.slug,environment:e,role:"app"});for(let R of h)d.push(Pf("systemd",i,R,t,e)),d.push(Pf("docker",i,R,t,e))}if(n==="aws")d.push(new jf(r.ecs??new U_(_,c),T)),d.push(new zf(r.lambda??new dr(_,c),T));return d}async function Fr(t,e,r={}){let d={project:t.project.slug,environment:e};try{return await BD(await _z(t,e,r),d)}catch(E){return{generatedAt:new Date().toISOString(),workloads:[],sources:[{id:"runtime:bootstrap",provider:LE(t)==="aws"?"ecs":"systemd",status:"error",discoveredAt:new Date().toISOString(),staleAfterSeconds:60,itemCount:0,message:String(E?.message??E).slice(0,500)}],degraded:!0}}}var Ff=65536,F_=49152,fh=/^[A-Za-z0-9_.@:-]+\.service$/,Uh=/^[a-fA-F0-9]{12,128}$/,Tz=["/boot","/dev","/etc","/proc","/root","/run","/sys","/var/run"];function Nc(t){let e=Buffer.from(t);return e.byteLength<=Ff?t:`${e.subarray(0,Ff-24).toString("utf8")}
|
|
6115
|
+
[output truncated]`}function Dh(t){return{success:!1,instanceCount:0,perInstance:[],error:t instanceof Error?t.message:String(t)}}function Ur(t){return`'${t.replaceAll("'",`'"'"'`)}'`}function iz(t,e){return Number.isFinite(t)?Math.min(1e4,Math.max(0,Math.floor(t))):e}function hz(t){let e=t.config,r=typeof e.clusterArn==="string"?e.clusterArn:void 0,d=t.links.providerId||t.name;return r&&d?{cluster:r,service:d}:void 0}function Rz(t,e){return t.find((r)=>r.id===e.links.server)??(t.length===1?t[0]:void 0)}function Sz(t,e){if(t.provider==="systemd"){let r=t.links.providerId;if(!r||!fh.test(r)||!["start","stop","restart"].includes(e))return;return[`systemctl ${e} ${r}`,`systemctl is-active ${r} 2>/dev/null || true`]}if(t.provider==="docker"){let r=t.links.providerId;if(!r||!Uh.test(r)||!["start","stop","restart"].includes(e))return;return[`docker ${e} ${r}`,`docker inspect --format '{{.State.Status}}' ${r}`]}return}function Nz(t,e){if(!e.startsWith("/")||e.includes("\x00"))return{ok:!1,error:"An absolute path is required."};let r=[];for(let _ of e.split("/")){if(!_||_===".")continue;if(_===".."){if(!r.length)return{ok:!1,error:"Path traversal is not allowed."};r.pop()}else r.push(_)}let d=`/${r.join("/")}`;if(Tz.some((_)=>d===_||d.startsWith(`${_}/`)))return{ok:!1,error:"Sensitive host paths are not available through runtime file access."};let E=t.links.project?.replace(/[^A-Za-z0-9_-]/g,""),n=t.links.service?.replace(/[^A-Za-z0-9_-]/g,"");if(![...E&&n?[`/var/www/${E}/${n}`,`/srv/${E}/${n}`]:[],...t.mounts.map((_)=>_.target).filter((_)=>_.startsWith("/"))].some((_)=>d===_||d.startsWith(`${_.replace(/\/$/,"")}/`)))return{ok:!1,error:"Path is outside this service’s owned roots."};return{ok:!0,path:d}}function Az(t,e){let r=t.links.project?.replace(/[^A-Za-z0-9_-]/g,""),d=t.links.service?.replace(/[^A-Za-z0-9_-]/g,"");return[...r&&d?[`/var/www/${r}/${d}`,`/srv/${r}/${d}`]:[],...t.mounts.map((E)=>E.target).filter((E)=>E.startsWith("/"))].sort((E,n)=>n.length-E.length).find((E)=>e===E||e.startsWith(`${E.replace(/\/$/,"")}/`))}var Bf={process:["ps","-eo","pid,ppid,user,%cpu,%mem,etime,command","--sort=-%cpu"],sockets:["ss","-lntup"],filesystem:["df","-h"]};class sr{config;environment;dependencies;region;profile;constructor(t,e,r={}){this.config=t;this.environment=e;this.dependencies=r;this.region=t.aws?.region??t.project.region??"us-east-1",this.profile=t.aws?.profile}async inventory(){return this.dependencies.inventory?.()??Fr(this.config,this.environment,{driver:this.dependencies.driver})}async workload(t){return(await this.inventory()).workloads.find((e)=>e.id===t)}async remote(t,e,r,d){let E=this.dependencies.driver??fr({config:this.config}),n=await E.findComputeTargets({slug:this.config.project.slug,environment:this.environment,role:"app"}),c=Rz(n,t);if(!c)throw Error("The workload server is no longer reachable in this scope.");return E.runRemoteDeploy({targets:[c],commands:e,timeoutSeconds:r,comment:d,tags:{Project:this.config.project.slug,Environment:this.environment,Role:"app"}})}async run(t){let e=await this.workload(t.workloadId),r={workloadId:t.workloadId,action:t.action};if(!e)return{...r,ok:!1,error:"Workload was not found in the current project and environment."};let d=e.capabilities[t.action];if(!d.supported)return{...r,ok:!1,error:d.reason??`${t.action} is unsupported for ${e.provider}.`};if(d.requiresConfirmation&&t.confirm!==e.name)return{...r,ok:!1,error:`Type "${e.name}" to ${t.action} this workload.`};if(d.requiresRecentAuth&&!t.recentAuth)return{...r,ok:!1,error:"Sign in again before using elevated runtime access."};if(t.action==="inspect")return{...r,ok:!0,workload:e};if(e.provider==="systemd"||e.provider==="docker"){let E=Sz(e,t.action);if(!E)return{...r,ok:!1,error:`${t.action} is not implemented for ${e.provider}.`};let n=await this.remote(e,["set -uo pipefail",...E],60,`ts-cloud runtime:${t.action}`).catch(Dh);return{...r,ok:n.success,command:E[0],stdout:Nc(n.perInstance?.[0]?.output??""),stderr:Nc(n.perInstance?.[0]?.error??n.error??""),error:n.success?void 0:n.error??"Runtime operation failed."}}if(e.provider==="ecs"){let E=hz(e);if(!E)return{...r,ok:!1,error:"ECS cluster or service identity is unavailable."};let n=this.dependencies.ecs??new U_(this.region,this.profile);if(t.action==="scale"){let c=iz(t.replicas,e.desiredReplicas??1);return await n.scaleService(E.cluster,E.service,c),{...r,ok:!0,command:`ecs scale ${e.name} ${c}`}}if(t.action==="start"||t.action==="stop"){let c=t.action==="stop"?0:Math.max(1,e.desiredReplicas??1);return await n.scaleService(E.cluster,E.service,c),{...r,ok:!0,command:`ecs scale ${e.name} ${c}`}}if(t.action==="restart"||t.action==="redeploy")return await n.forceNewDeployment(E.cluster,E.service),{...r,ok:!0,command:`ecs redeploy ${e.name}`}}return{...r,ok:!1,error:`${t.action} is not implemented for ${e.provider}.`}}async exec(t){let e={workloadId:t.workloadId,preset:t.preset},r=await this.workload(t.workloadId);if(!r)return{...e,ok:!1,error:"Workload was not found in the current project and environment."};if(process.env.TS_CLOUD_RUNTIME_EXEC==="0")return{...e,ok:!1,error:"Runtime exec is disabled by TS_CLOUD_RUNTIME_EXEC."};if(!r.capabilities.exec.supported)return{...e,ok:!1,error:r.capabilities.exec.reason??"Exec is unsupported for this workload."};if(t.confirm!==r.name)return{...e,ok:!1,error:`Type "${r.name}" to open exec access.`};if(!t.recentAuth)return{...e,ok:!1,error:"Sign in again before using elevated runtime access."};let d=t.preset&&Bf[t.preset];if(!d&&!t.command?.trim())return{...e,ok:!1,error:"Choose a diagnostic preset or provide a command."};if(t.command&&r.provider!=="docker")return{...e,ok:!1,error:"Free-form exec is restricted to isolated containers; use a diagnostic preset for system services."};let E=r.links.providerId??"",n;if(r.provider==="docker"&&Uh.test(E)){let _=t.command?.trim()||d.map(Ur).join(" ");n=`docker exec ${E} sh -lc ${Ur(_)}`}else if(r.provider==="systemd"&&fh.test(E)&&t.preset)n=t.preset==="process"?`systemctl status ${E} --no-pager --full`:Bf[t.preset].map(Ur).join(" ");if(!n)return{...e,ok:!1,error:"Exec target identity is invalid or unsupported."};let c=await this.remote(r,["set -uo pipefail",n],60,"ts-cloud runtime:exec").catch(Dh);return{...e,ok:c.success,command:n,stdout:Nc(c.perInstance?.[0]?.output??""),stderr:Nc(c.perInstance?.[0]?.error??c.error??""),error:c.success?void 0:c.error??"Exec command failed."}}async readFile(t){let e={workloadId:t.workloadId,path:t.path},r=await this.fileTarget(t);if("error"in r)return{...e,ok:!1,error:r.error};let{workload:d,path:E,root:n,providerId:c}=r,T=`sh -c ${Ur('resolved=$(realpath -m "$1"); root=$(realpath -m "$3"); case "$resolved" in "$root"|"$root"/*) ;; *) exit 73;; esac; test -f "$resolved"; size=$(wc -c < "$resolved"); printf "__TSCLOUD_SIZE__=%s\\n" "$size"; head -c "$2" "$resolved" | base64')} sh ${Ur(E)} ${F_} ${Ur(n)}`,i=d.provider==="docker"?`docker exec ${c} ${T}`:T,h=await this.remote(d,[i],30,"ts-cloud runtime:file-read").catch(Dh);if(!h.success)return{...e,ok:!1,error:h.error??h.perInstance?.[0]?.error??"File read failed."};let R=h.perInstance?.[0]?.output??"",N=/__TSCLOUD_SIZE__=(\d+)\r?\n/.exec(R);if(!N)return{...e,ok:!1,error:"The remote file response was invalid."};let A=Number(N[1]),u=R.slice((N.index??0)+N[0].length).replace(/\s+/g,"");if(Buffer.from(u,"base64").byteLength>F_)return{...e,ok:!1,error:"The remote file exceeded the transfer limit."};return{...e,ok:!0,contentBase64:u,size:A,truncated:A>F_}}async writeFile(t){let e={workloadId:t.workloadId,path:t.path},r=await this.fileTarget(t);if("error"in r)return{...e,ok:!1,error:r.error};if(!/^[A-Za-z0-9+/]*={0,2}$/.test(t.contentBase64))return{...e,ok:!1,error:"File content must be valid base64."};let d=Buffer.from(t.contentBase64,"base64");if(d.toString("base64")!==t.contentBase64)return{...e,ok:!1,error:"File content must be canonical base64."};if(d.byteLength>F_)return{...e,ok:!1,error:`File uploads are limited to ${F_} bytes.`};let{workload:E,path:n,root:c,providerId:_}=r,i=`sh -c ${Ur('resolved=$(realpath -m "$1"); root=$(realpath -m "$2"); case "$resolved" in "$root"|"$root"/*) ;; *) exit 73;; esac; mkdir -p "$(dirname "$resolved")"; tmp="$resolved.ts-cloud-$$"; base64 -d > "$tmp"; chmod 600 "$tmp"; mv "$tmp" "$resolved"')} sh ${Ur(n)} ${Ur(c)}`,h=E.provider==="docker"?`printf %s ${Ur(t.contentBase64)} | docker exec -i ${_} ${i}`:`printf %s ${Ur(t.contentBase64)} | ${i}`,R=await this.remote(E,[h],30,"ts-cloud runtime:file-write").catch(Dh);return{...e,ok:R.success,size:d.byteLength,truncated:!1,error:R.success?void 0:R.error??R.perInstance?.[0]?.error??"File write failed."}}async fileTarget(t){let e=await this.workload(t.workloadId);if(!e)return{error:"Workload was not found in the current project and environment."};if(process.env.TS_CLOUD_RUNTIME_FILE_ACCESS==="0")return{error:"Runtime file access is disabled by TS_CLOUD_RUNTIME_FILE_ACCESS."};if(!e.capabilities.files.supported)return{error:e.capabilities.files.reason??"File access is unsupported for this workload."};if(t.confirm!==e.name)return{error:`Type "${e.name}" to access workload files.`};if(!t.recentAuth)return{error:"Sign in again before using elevated runtime access."};let r=Nz(e,t.path);if(!r.ok)return{error:r.error};let d=Az(e,r.path),E=e.links.providerId??"";if(!d||e.provider==="systemd"&&!fh.test(E)||e.provider==="docker"&&!Uh.test(E))return{error:"File target identity is invalid or unsupported."};return{workload:e,path:r.path,root:d,providerId:E}}async logs(t,e={}){let r=await this.workload(t);if(!r)throw Error("Workload was not found in the current project and environment.");if(!r.capabilities.logs.supported)throw Error(r.capabilities.logs.reason??"Logs are unsupported for this workload.");let d=Math.min(1000,Math.max(1,Math.floor(e.limit??200)));if(r.provider==="lambda"||r.provider==="ecs"){let h=this.dependencies.logs??new w_(this.region,this.profile),R=r.config.logGroups,N=r.provider==="lambda"?`/aws/lambda/${r.name}`:Array.isArray(R)&&typeof R[0]==="string"?R[0]:void 0;if(!N)throw Error("The ECS task definition does not declare an awslogs group.");let A=await h.filterLogEvents({logGroupName:N,startTime:e.since?.getTime(),limit:d}),u=(A.events??[]).slice(0,d).map((f)=>({timestamp:f.timestamp==null?void 0:new Date(f.timestamp).toISOString(),message:Nc(String(f.message??""))}));return{workloadId:t,provider:r.provider,lines:u,nextCursor:A.nextToken,truncated:(A.events?.length??0)>=d}}let E=r.links.providerId??"",n=e.since&&Number.isFinite(e.since.getTime())?e.since:void 0,c=r.provider==="systemd"&&fh.test(E)?`journalctl -u ${E} --no-pager -n ${d} -o short-iso${n?` --since ${Ur(n.toISOString())}`:""}`:r.provider==="docker"&&Uh.test(E)?`docker logs --timestamps --tail ${d}${n?` --since ${Math.floor(n.getTime()/1000)}`:""} ${E} 2>&1`:void 0;if(!c)throw Error("Log target identity is invalid.");let _=await this.remote(r,[c],30,"ts-cloud runtime:logs");if(!_.success)throw Error(_.error??_.perInstance?.[0]?.error??"Log read failed.");let T=Nc(_.perInstance?.[0]?.output??""),i=T.split(`
|
|
6116
6116
|
`).filter(Boolean).slice(-d).map((h)=>{let R=/^(\d{4}-\d{2}-\d{2}T\S+)\s+(.*)$/.exec(h);return{timestamp:R?.[1],message:R?.[2]??h}});return{workloadId:t,provider:r.provider,lines:i,truncated:T.includes("[output truncated]")||i.length>=d}}}import{randomUUID as Lz}from"node:crypto";class iL{records=new Map;maxBufferBytes;ttlMs;now;constructor(t={}){this.maxBufferBytes=Math.max(1024,t.maxBufferBytes??262144),this.ttlMs=Math.max(1000,t.ttlMs??900000),this.now=t.now??(()=>new Date)}create(t,e){this.sweep();let r=this.now().toISOString(),d={id:Lz(),workloadId:e,kind:t,state:"open",chunks:[],cursor:0,droppedBytes:0,bufferedBytes:0,createdAt:r,updatedAt:r,abort:new AbortController,listeners:new Set};return this.records.set(d.id,d),this.snapshot(d,0)}signal(t){return this.records.get(t)?.abort.signal}append(t,e,r="stdout"){let d=this.records.get(t);if(!d||d.state!=="open"||!e)return d?this.snapshot(d,d.cursor):void 0;let E=Buffer.from(e),n=E.byteLength>this.maxBufferBytes?E.subarray(E.byteLength-this.maxBufferBytes).toString("utf8"):e,c={cursor:++d.cursor,stream:r,data:n,at:this.now().toISOString()};d.chunks.push(c),d.bufferedBytes+=Buffer.byteLength(n),d.updatedAt=c.at;while(d.bufferedBytes>this.maxBufferBytes&&d.chunks.length>1){let _=d.chunks.shift(),T=Buffer.byteLength(_.data);d.bufferedBytes-=T,d.droppedBytes+=T}return this.publish(d),this.snapshot(d,c.cursor-1)}read(t,e,r=0){let d=this.records.get(t);if(!d||d.workloadId!==e)return;return d.updatedAt=this.now().toISOString(),this.snapshot(d,Math.max(0,Math.floor(r)))}close(t,e="complete",r){let d=this.records.get(t);if(!d||d.state!=="open")return d?this.snapshot(d,d.cursor):void 0;if(d.state=e,d.error=r,d.updatedAt=this.now().toISOString(),e==="cancelled")d.abort.abort();return this.publish(d),this.snapshot(d,d.cursor)}cancel(t,e){let r=this.records.get(t);if(!r||r.workloadId!==e)return;return this.close(t,"cancelled")}subscribe(t,e,r){let d=this.records.get(t);if(!d||d.workloadId!==e)return;return d.listeners.add(r),()=>d.listeners.delete(r)}sweep(){let t=this.now().getTime()-this.ttlMs,e=0;for(let[r,d]of this.records){if(new Date(d.updatedAt).getTime()>t)continue;d.abort.abort(),this.records.delete(r),e++}return e}clear(){for(let t of this.records.values())t.abort.abort();this.records.clear()}snapshot(t,e){let r=t.chunks[0]?.cursor??t.cursor+1,d=e>0&&e<r-1;return{id:t.id,workloadId:t.workloadId,kind:t.kind,state:t.state,chunks:t.chunks.filter((E)=>d||E.cursor>e),cursor:t.cursor,reset:d,droppedBytes:t.droppedBytes,createdAt:t.createdAt,updatedAt:t.updatedAt,error:t.error}}publish(t){let e=this.snapshot(t,0);for(let r of t.listeners)r(e)}}import{createHash as uz}from"node:crypto";var NL={info:0,low:1,medium:2,high:3,critical:4},AL={record:0,warn:1,block:2},Jf=new Set(["skipped","unavailable","unsupported","stale"]);function xt(t){return typeof t==="string"?t:void 0}function dE(t,e){try{return JSON.parse(String(t))}catch{return e}}function Br(t){return JSON.stringify(ut(t))}function Oz(t){if(!t)return;return String(ut(t,2000))}function hL(t){return{id:String(t.id),organizationId:String(t.organization_id),projectId:xt(t.project_id),environmentId:xt(t.environment_id),resourceId:xt(t.resource_id),releaseId:xt(t.release_id),scannerId:String(t.scanner_id),scannerVersion:String(t.scanner_version),status:String(t.status),error:xt(t.error),metadata:dE(t.metadata,{}),findingsCount:Number(t.findings_count),startedAt:String(t.started_at),completedAt:String(t.completed_at),durationMs:Number(t.duration_ms)}}function Hf(t){return{id:String(t.id),fingerprint:String(t.fingerprint),organizationId:String(t.organization_id),projectId:xt(t.project_id),environmentId:xt(t.environment_id),resourceId:xt(t.resource_id),releaseId:xt(t.release_id),scanRunId:String(t.scan_run_id),scannerId:String(t.scanner_id),scannerVersion:String(t.scanner_version),ruleId:String(t.rule_id),severity:String(t.severity),title:String(t.title),description:String(t.description),evidence:dE(t.evidence,{}),remediation:xt(t.remediation),subject:String(t.subject),status:String(t.status),ownerActorId:xt(t.owner_actor_id),recurrenceCount:Number(t.recurrence_count),firstSeenAt:String(t.first_seen_at),lastSeenAt:String(t.last_seen_at),resolvedAt:xt(t.resolved_at),updatedAt:String(t.updated_at)}}function RL(t){return{id:String(t.id),organizationId:String(t.organization_id),environmentId:xt(t.environment_id),name:String(t.name),rules:dE(t.rules,[]),requiredScanners:dE(t.required_scanners,[]),scannerFailMode:String(t.scanner_fail_mode),enabled:Number(t.enabled)===1,version:Number(t.version),createdByActorId:xt(t.created_by_actor_id),createdAt:String(t.created_at),updatedAt:String(t.updated_at)}}function Wf(t,e){let r=xt(t.revoked_at),d=String(t.expires_at);return{id:String(t.id),findingId:String(t.finding_id),policyId:xt(t.policy_id),reason:String(t.reason),referenceUrl:xt(t.reference_url),createdByActorId:String(t.created_by_actor_id),expiresAt:d,revokedAt:r,state:r?"revoked":d<=e?"expired":"active",createdAt:String(t.created_at),updatedAt:String(t.updated_at)}}function SL(t){return{id:String(t.id),organizationId:String(t.organization_id),projectId:String(t.project_id),environmentId:xt(t.environment_id),releaseId:String(t.release_id),kind:String(t.kind),format:String(t.format),digest:String(t.digest),summary:dE(t.summary,{}),content:xt(t.content),sensitive:Number(t.sensitive)===1,createdAt:String(t.created_at)}}function vf(t){return{id:String(t.id),organizationId:String(t.organization_id),projectId:String(t.project_id),environmentId:String(t.environment_id),operationId:xt(t.operation_id),policyId:String(t.policy_id),policyVersion:Number(t.policy_version),outcome:String(t.outcome),scannerVersions:dE(t.scanner_versions,{}),findingIds:dE(t.finding_ids,[]),waiverIds:dE(t.waiver_ids,[]),explanation:String(t.explanation),createdAt:String(t.created_at)}}function Cz(t,e){let r=[t.trim().toLowerCase(),e.ruleId.trim().toLowerCase(),e.organizationId,e.projectId??"",e.environmentId??"",e.resourceId??"",e.releaseId??"",e.subject.trim().toLowerCase()].join("\x00");return uz("sha256").update(r).digest("hex")}function Qf(t){if(!t)return;let e=new URL(t);if(e.protocol!=="https:"&&e.protocol!=="http:")throw Error("Security references must use HTTP or HTTPS");return e.toString()}function Yf(t){if(!t.length)throw Error("A security policy needs at least one rule");return t.map((e)=>{if(!(e.minimumSeverity in NL))throw Error(`Unknown security severity: ${e.minimumSeverity}`);if(!(e.action in AL))throw Error(`Unknown security policy action: ${e.action}`);return{minimumSeverity:e.minimumSeverity,action:e.action,...e.scannerId?{scannerId:e.scannerId.trim()}:{}}})}class B_{controlPlane;nowFn;idFn;constructor(t,e={}){this.controlPlane=t;this.nowFn=e.now??(()=>new Date),this.idFn=e.id??(()=>crypto.randomUUID())}now(){return this.nowFn().toISOString()}run(t,e){this.controlPlane.database.run(t,e)}recordScan(t){if(!t.organizationId||!t.scannerId.trim()||!t.scannerVersion.trim())throw Error("Organization, scanner id, and scanner version are required");let e=t.completedAt??this.now(),r=t.startedAt??e,d=t.durationMs??Math.max(0,new Date(e).getTime()-new Date(r).getTime()),E=t.findings??[],n=this.idFn(),c=new Set,_=[];return this.controlPlane.transaction(()=>{this.run(`INSERT INTO security_scan_runs
|
|
6117
6117
|
(id, organization_id, project_id, environment_id, resource_id, release_id, scanner_id, scanner_version, status, error, metadata, findings_count, started_at, completed_at, duration_ms)
|
|
6118
6118
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,[n,t.organizationId,t.projectId??null,t.environmentId??null,t.resourceId??null,t.releaseId??null,t.scannerId.trim(),t.scannerVersion.trim(),t.status,Oz(t.error)??null,Br(t.metadata??{}),E.length,r,e,Math.max(0,Math.floor(d))]);for(let T of E){let i={...T,organizationId:t.organizationId,projectId:T.projectId??t.projectId,environmentId:T.environmentId??t.environmentId,resourceId:T.resourceId??t.resourceId,releaseId:T.releaseId??t.releaseId},h=i.fingerprint?.trim()||Cz(t.scannerId,i);c.add(h);let R=this.controlPlane.database.query("SELECT * FROM security_findings WHERE fingerprint = ?").get(h),N=R?this.controlPlane.database.query("SELECT * FROM security_waivers WHERE finding_id = ? AND revoked_at IS NULL AND expires_at > ? ORDER BY expires_at DESC LIMIT 1").get(String(R.id),e):void 0;if(R){let A=String(R.status)==="resolved"?Number(R.recurrence_count)+1:Number(R.recurrence_count),u=N?"waived":String(R.status)==="acknowledged"?"acknowledged":"open";this.run(`UPDATE security_findings SET scan_run_id = ?, scanner_version = ?, severity = ?, title = ?, description = ?, evidence = ?, remediation = ?,
|
|
@@ -6300,16 +6300,16 @@ $(free -m 2>/dev/null | awk '/^Mem:/{total=$2; used=$3; available=$7; cache=$6}
|
|
|
6300
6300
|
EOF`,'echo "MEMTOTAL=${MEMTOTAL:-0}"','echo "MEMUSED=${MEMUSED:-0}"','echo "MEMAVAILABLE=${MEMAVAILABLE:-0}"','echo "MEMCACHE=${MEMCACHE:-0}"','echo "SWAPTOTAL=${SWAPTOTAL:-0}"','echo "SWAPUSED=${SWAPUSED:-0}"',`read DISKTOTG DISKUSEDG DISKPCT <<EOF
|
|
6301
6301
|
$(df -BG -P / 2>/dev/null | awk 'NR==2{gsub("G","",$2); gsub("G","",$3); gsub("%","",$5); print $2, $3, $5}')
|
|
6302
6302
|
EOF`,'echo "DISKPCT=${DISKPCT:-0}"','echo "DISKUSEDG=${DISKUSEDG:-0}"','echo "DISKTOTG=${DISKTOTG:-0}"',`echo "INODEPCT=$(df -Pi / 2>/dev/null | awk 'NR==2{gsub("%","",$5);print $5}')"`,`echo "NETRX=$(awk -F'[: ]+' 'NR>2 && $2!="lo"{sum+=$3} END{print sum+0}' /proc/net/dev 2>/dev/null)"`,`echo "NETTX=$(awk -F'[: ]+' 'NR>2 && $2!="lo"{sum+=$11} END{print sum+0}' /proc/net/dev 2>/dev/null)"`,`echo "PROCESSES=$(ps -e --no-headers 2>/dev/null | awk 'END{print NR+0}')"`,`echo "UPTIME=$(uptime -p 2>/dev/null | sed 's/^up //' || echo unknown)"`,`echo "UPTIME_SECONDS=$(cut -d' ' -f1 /proc/uptime 2>/dev/null || echo 0)"`,'echo "OS=$(. /etc/os-release 2>/dev/null; echo "$PRETTY_NAME")"'];if(t.includeServices!==!1)e.push(`for s in ${tF.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`);if(t.includeSites!==!1)e.push(eF(t.projectFilter));return e.push("true"),e}function dF(t){let e={services:[],discoveredSites:[]};for(let r of t.split(`
|
|
6303
|
-
`)){let d=r.trim();if(d.startsWith("DISCOVERED_SITE="))try{let E=JSON.parse(Buffer.from(d.slice(16),"base64").toString("utf8"));if(E?.domain&&E?.route)e.discoveredSites.push(E)}catch{}else if(d.startsWith("SVC=")){let[,E,n,c,_,T]=/^SVC=([^=]+)=([^=]+)(?:=([^=]*)(?:=([^=]*)(?:=(.*))?)?)?$/.exec(d)??[];if(E)e.services.push({name:E,status:n,memBytes:Number(c||0),enabled:_||Qe,since:T||Qe})}else{let E=d.indexOf("=");if(E>0)e[d.slice(0,E)]=d.slice(E+1)}}return e}function cU(t){let e=t.infrastructure?.compute,r=[];if(e?.webServer==="rpx"||e?.proxy?.engine==="rpx")r.push({name:"rpx-gateway",status:"configured"});else if(e?.webServer==="nginx"||e?.webServer==null)r.push({name:"ts-cloud-nginx",status:"configured"});let d=e?.php?.versions??(e?.runtime==="php"?["8.3"]:[]);for(let c of d)r.push({name:`php${c}-fpm`,status:"configured"});let E=e?.managedServices??{},n=[["mysql","mysql"],["mariadb","mariadb"],["postgres","postgresql"],["redis","redis"],["memcached","memcached"],["meilisearch","meilisearch"]];for(let[c,_]of n)if(E[c])r.push({name:_,status:"configured"});return r}function EF(t){let e=t.infrastructure?.compute?.backups,r=!!e?.enabled,d=e?.schedule??"0 2 * * *";return{enabled:r,schedule:d,destination:r?e?.bucket??"local":"off",retention:r?e?.retentionCount??5:0,last:r?"pending first run":"not configured",size:r?Qe:"0 MB"}}function _U(t){return t.infrastructure?.compute?.provider??t.cloud?.provider??t.provider??"aws"}function nF(t){if(_U(t)==="hetzner")return pA(t);return t.project.region??"us-east-1"}function cF(t,e){let r=pz(process.cwd(),"storage","cloud","state",`${t.project.slug}-${e}.json`);if(!oz(r))return null;try{return JSON.parse(mz(r,"utf8"))}catch{return null}}function _F(t){let e=t.sites??{},r=[];for(let[d,E]of Object.entries(e)){let n=E.queues??E.workers;if(Array.isArray(n)){for(let c of n)if(typeof c==="string")r.push({name:`${d}:${c}`,site:d,processes:1,status:"configured"});else if(c?.name)r.push({name:`${d}:${c.name}`,site:d,processes:c.processes??1,status:"configured"})}}return r}function TU(t){if(!t||t==="")return"/";return t.startsWith("/")?t:`/${t}`}function TF(t){let e=TU(t.path);if(!t.domain)return{route:"internal"};return{route:e==="/"?t.domain:`${t.domain}${e}`,href:`https://${t.domain}${e==="/"?"":e}`}}function nU(t,e){let r=
|
|
6303
|
+
`)){let d=r.trim();if(d.startsWith("DISCOVERED_SITE="))try{let E=JSON.parse(Buffer.from(d.slice(16),"base64").toString("utf8"));if(E?.domain&&E?.route)e.discoveredSites.push(E)}catch{}else if(d.startsWith("SVC=")){let[,E,n,c,_,T]=/^SVC=([^=]+)=([^=]+)(?:=([^=]*)(?:=([^=]*)(?:=(.*))?)?)?$/.exec(d)??[];if(E)e.services.push({name:E,status:n,memBytes:Number(c||0),enabled:_||Qe,since:T||Qe})}else{let E=d.indexOf("=");if(E>0)e[d.slice(0,E)]=d.slice(E+1)}}return e}function cU(t){let e=t.infrastructure?.compute,r=[];if(e?.webServer==="rpx"||e?.proxy?.engine==="rpx")r.push({name:"rpx-gateway",status:"configured"});else if(e?.webServer==="nginx"||e?.webServer==null)r.push({name:"ts-cloud-nginx",status:"configured"});let d=e?.php?.versions??(e?.runtime==="php"?["8.3"]:[]);for(let c of d)r.push({name:`php${c}-fpm`,status:"configured"});let E=e?.managedServices??{},n=[["mysql","mysql"],["mariadb","mariadb"],["postgres","postgresql"],["redis","redis"],["memcached","memcached"],["meilisearch","meilisearch"]];for(let[c,_]of n)if(E[c])r.push({name:_,status:"configured"});return r}function EF(t){let e=t.infrastructure?.compute?.backups,r=!!e?.enabled,d=e?.schedule??"0 2 * * *";return{enabled:r,schedule:d,destination:r?e?.bucket??"local":"off",retention:r?e?.retentionCount??5:0,last:r?"pending first run":"not configured",size:r?Qe:"0 MB"}}function _U(t){return t.infrastructure?.compute?.provider??t.cloud?.provider??t.provider??"aws"}function nF(t){if(_U(t)==="hetzner")return pA(t);return t.project.region??"us-east-1"}function cF(t,e){let r=pz(process.cwd(),"storage","cloud","state",`${t.project.slug}-${e}.json`);if(!oz(r))return null;try{return JSON.parse(mz(r,"utf8"))}catch{return null}}function _F(t){let e=t.sites??{},r=[];for(let[d,E]of Object.entries(e)){let n=E.queues??E.workers;if(Array.isArray(n)){for(let c of n)if(typeof c==="string")r.push({name:`${d}:${c}`,site:d,processes:1,status:"configured"});else if(c?.name)r.push({name:`${d}:${c.name}`,site:d,processes:c.processes??1,status:"configured"})}}return r}function TU(t){if(!t||t==="")return"/";return t.startsWith("/")?t:`/${t}`}function TF(t){let e=TU(t.path);if(!t.domain)return{route:"internal"};return{route:e==="/"?t.domain:`${t.domain}${e}`,href:`https://${t.domain}${e==="/"?"":e}`}}function nU(t,e){let r=Dr(e);if(r==="redirect")return"redirect";let d=String(e.build??"").toLowerCase(),E=String(e.start??"").toLowerCase();if(t==="main"||E.includes("buddy/src/cli.ts serve"))return"stacks";if(t==="api"||E.includes("/serve/api"))return"api";if(d.includes("buildblog"))return"bunpress blog";if(d.includes("bunpress"))return"bunpress";if(d.includes("site:build")||d.includes("stx"))return"stx static";if(r==="server-static")return e.spa?"spa":"static";if(r==="server-app")return"app";if(r==="server-php")return e.type??"php";return"bucket"}function iF(t){let e=Dr(t);if(e==="redirect")return"—";let r=`${t.start??""} ${t.build??""}`.toLowerCase();if(e==="server-static")return r.includes("bunpress")||r.includes("bun ")||r.includes("bunx ")?"static/bun":"static";if(e==="server-app")return r.includes("bun")?"bun":"node";if(e==="server-php")return`php ${t.php??t.phpVersion??"8.3"}`;return"static"}function hF(t){let e=Dr(t);if(e==="redirect")return"redirect";if(e==="server-app")return"service";if(e==="server-static")return"server static";if(e==="server-php")return"php release";return"bucket"}function RF(t){let e=new Map;return Object.entries(t.sites??{}).map(([r,d])=>{let E=TU(d.path),{route:n,href:c}=TF(d),_=d.domain?`${d.domain}${E}`:"",T=_?e.get(_):void 0;if(_&&!T)e.set(_,r);return{name:r,route:n,href:c,domain:d.domain??"internal",path:E,kind:nU(r,d),type:nU(r,d),runtime:iF(d),deploy:hF(d),tls:d.domain?d.ssl===!1?"http":"https":"loopback",ssl:d.domain?d.ssl!==!1:!1,status:T?"shadowed":"live",shadowedBy:T,lastDeploy:Qe}})}function SF(t,e,r){let d=new Map(t.map((E)=>[String(E.route),{...E,project:r,managedBy:"owner"}]));for(let E of e){let n=d.get(E.route),c=n?.name??`${E.project}:${E.name}`;d.set(E.route,{...n,...E,name:c,kind:n?.kind??E.kind,type:n?.type??E.kind,runtime:n?.runtime??E.runtime,deploy:n?.deploy??E.deploy,root:n?.root??E.root,branch:n?.branch??E.branch,managedBy:E.project===r?"owner":"attached"})}return[...d.values()].sort((E,n)=>{if(E.managedBy!==n.managedBy)return E.managedBy==="owner"?-1:1;return String(E.route).localeCompare(String(n.route))})}function yL(t){return`'${t.replaceAll("'","'\\''")}'`}function iU(t){return t.replace(/[\\&/]/g,"\\$&")}function NF(t,e){if(t.length===0)return["true"];return["set +e",...t.map((r)=>{let d=yL(`${Id(e,r)}/.ts-cloud/deploy-history.log`),E=iU(r);return`TS_CLOUD_HISTORY=${d}; { [ -f "$TS_CLOUD_HISTORY" ] && tail -n 24 "$TS_CLOUD_HISTORY" | sed "s/^/DEPLOY=${E}\\t/"; } || true`}),"true"]}function hU(t){return[...new Set(Object.values(t.sites??{}).map((e)=>e.domain).filter((e)=>typeof e==="string"&&e.length>0))]}function AF(t){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',...hU(t).map((r)=>{return`TS_CLOUD_DOMAIN=${yL(r)}; 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 LF(t){let e=new Map,r=(n,c)=>{if(n&&c&&!e.has(c))e.set(c,{pattern:n,label:c})},d=t.infrastructure?.compute,E=t.project.slug;if(d?.webServer==="rpx"||d?.proxy?.engine==="rpx")r("rpx-gateway","rpx-gateway");else r("nginx","nginx");for(let n of cU(t))r(n.name,n.name);for(let[n,c]of Object.entries(t.sites??{})){if(Dr(c)!=="server-app")continue;if(r(`${E}-${n}`,`${E}-${n}`),Array.isArray(c.queues??c.workers)&&(c.queues??c.workers).length)r(`${E}-${n}-queue-*`,`${E}-${n}-queues`);if(Array.isArray(c.daemons)&&c.daemons.length)r(`${E}-${n}-daemon-*`,`${E}-${n}-daemons`)}return[...e.values()]}function uF(t){let e=LF(t);if(e.length===0)return["true"];return["set +e",...e.map((r)=>{let d=yL(r.pattern),E=iU(r.label);return`journalctl -u ${d} --no-pager -n 150 -o short-iso 2>/dev/null | sed "s/^/LOG=${E}\\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 XL(t){let e=new Date(t);if(Number.isNaN(e.getTime()))return t||Qe;let r=Math.max(0,Math.round((Date.now()-e.getTime())/1000));if(r<60)return`${r}s ago`;let d=Math.round(r/60);if(d<60)return`${d}m ago`;let E=Math.round(d/60);if(E<48)return`${E}h ago`;return`${Math.round(E/24)}d ago`}function RU(t){if(/(?:error|failed|panic|fatal|exception|denied|unhealthy)/i.test(t))return"error";if(/(?:warn|warning|retry|restart|deprecated|timeout)/i.test(t))return"warn";return"info"}function OF(t){let e=[];for(let r of t.split(`
|
|
6304
6304
|
`)){let d=r.trim();if(!d.startsWith("LOG="))continue;let E=d.indexOf("\t");if(E<0)continue;let n=d.slice(4,E),c=d.slice(E+1),_=/^(\d{4}-\d{2}-\d{2}T[^\s]+)\s+(\S+)\s+(.*)$/.exec(c),T=_?.[1]??"",i=_?.[2]??"",h=(_?.[3]??c).trim();if(!h)continue;e.push({source:n,timestamp:T,when:T?XL(T):Qe,host:i,message:h,level:RU(h)})}return e.sort((r,d)=>String(d.timestamp).localeCompare(String(r.timestamp))).slice(0,600)}function SU(t){if(/^(?:127\.|localhost:|\[?::1\]?)/.test(t))return"loopback";if(/^(?:10\.|192\.168\.|172\.(?:1[6-9]|2\d|3[01])\.|169\.254\.|\[?f[cd][0-9a-f:])/i.test(t))return"private";return"public"}function CF(t){if(SU(t)!=="public")return"ok";if(/:(?:22|80|443)$/.test(t)||/^\*:(?:22|80|443)$/.test(t))return"ok";return"warn"}function lF(t){if(t==null)return"warn";if(t<8)return"bad";if(t<30)return"warn";return"ok"}function IF(t){let e=[],r=[],d=[],E=[];for(let _ of t.split(`
|
|
6305
6305
|
`)){let T=_.trim();if(T.startsWith("PORT=")){let[i="",h="",R=""]=T.slice(5).split("\t");if(i&&h)e.push({proto:i,listen:h,processName:R||Qe,exposure:SU(h),tone:CF(h)})}else if(T.startsWith("FIREWALL=")){let i=T.slice(9).trim();if(i)r.push(i)}else if(T.startsWith("AUTH=")){let i=T.slice(5),h=/^(\d{4}-\d{2}-\d{2}T[^\s]+)\s+(\S+)\s+(.*)$/.exec(i),R=(h?.[3]??i).trim();if(R)d.push({timestamp:h?.[1]??"",when:h?.[1]?XL(h[1]):Qe,host:h?.[2]??"",message:R,level:RU(R)})}else if(T.startsWith("CERT=")){let[i="",h=""]=T.slice(5).split("\t");if(!i)continue;let R=new Date(h),N=Number.isNaN(R.getTime())?null:Math.ceil((R.getTime()-Date.now())/86400000);E.push({domain:i,expires:Number.isNaN(R.getTime())?h||Qe:R.toISOString().slice(0,10),daysRemaining:N,status:lF(N)})}}let n=r.some((_)=>/Status:\s*active/i.test(_)),c=r.some((_)=>/unavailable/i.test(_));return{ports:e.slice(0,80),firewall:{status:n?"active":c?"unavailable":"inactive",summary:n?"ufw active":c?"ufw unavailable":"ufw inactive or not configured",rules:r.filter((_)=>_&&!/^Status:/i.test(_)).slice(0,60)},tlsCertificates:E,authEvents:d.sort((_,T)=>String(T.timestamp).localeCompare(String(_.timestamp))).slice(0,30)}}function aL(t){let r=t.infrastructure?.compute?.firewall??{},d=[...new Set([22,80,443,...r.allowedPorts??[]])],E=hU(t);return{ports:d.map((n)=>({proto:"tcp",listen:`0.0.0.0:${n}`,processName:"configured firewall",exposure:"public",tone:[22,80,443].includes(Number(n))?"ok":"warn"})),firewall:{status:r.enabled===!1?"disabled":"configured",summary:r.enabled===!1?"host firewall disabled in config":"host firewall configured declaratively",rules:d.map((n)=>`ALLOW ${n}/tcp`)},tlsCertificates:E.map((n)=>({domain:n,expires:Qe,daysRemaining:null,status:"warn"})),authEvents:[]}}function NU(t,e){let r=e.security??aL(t),d=!!e._serverReachable&&!e.metricsUnavailable,E=e.sites??[],n=E.filter((i)=>i.status==="shadowed"),c=(e.services??[]).filter((i)=>["failed","stopped"].includes(i.status)),_=(r.tlsCertificates??[]).filter((i)=>i.status!=="ok"),T=e.sshKeys??[];return[{name:"Live server probe",status:d?"pass":"warn",detail:d?"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:c.length?"fail":"pass",detail:c.length?`${c.length} service(s) need attention.`:`${(e.services??[]).length} service(s) reported healthy or configured.`},{name:"Route conflicts",status:n.length?"warn":"pass",detail:n.length?`${n.map((i)=>i.name).join(", ")} is shadowed by an earlier route.`:`${E.length} site route(s) are unshadowed.`},{name:"SSH access",status:T.length?"pass":"warn",detail:T.length?`${T.length} declarative authorized key(s) configured.`:"No declarative SSH keys are configured."},{name:"Firewall",status:["active","configured"].includes(r.firewall?.status)?"pass":"warn",detail:r.firewall?.summary??"Firewall status unavailable."},{name:"TLS certificates",status:_.length?"warn":"pass",detail:_.length?`${_.length} certificate(s) need renewal visibility.`:`${(r.tlsCertificates??[]).length} certificate(s) look healthy.`}]}function AU(t){let e=[];for(let r of t.serverDeploymentsDetail??t.serverDeployments??[])e.push({type:"deploy",tone:r.status==="failed"?"bad":"ok",title:`${r.site} deployed ${r.sha}`,detail:`${r.branch} · ${r.status}`,when:r.when,timestamp:r.timestamp});for(let r of t.serverLogs??[])if(r.level==="error"||r.level==="warn")e.push({type:"log",tone:r.level==="error"?"bad":"warn",title:`${r.source} ${r.level}`,detail:r.message,when:r.when,timestamp:r.timestamp});for(let r of t.sshKeys??[])e.push({type:"ssh",tone:"ok",title:`${r.name} authorized`,detail:r.fingerprint,when:r.added??Qe,timestamp:""});return e.sort((r,d)=>String(d.timestamp).localeCompare(String(r.timestamp))).slice(0,80)}function DF(t,e={}){let r=[];for(let d of t.split(`
|
|
6306
|
-
`)){let E=d.trim();if(!E.startsWith("DEPLOY="))continue;let n=E.split("\t"),c=n[0]?.replace(/^DEPLOY=/,"")??"",[_,T,i,h,R]=n.slice(1);if(!c||!_||!T)continue;let N=e[c]??{},A=
|
|
6306
|
+
`)){let E=d.trim();if(!E.startsWith("DEPLOY="))continue;let n=E.split("\t"),c=n[0]?.replace(/^DEPLOY=/,"")??"",[_,T,i,h,R]=n.slice(1);if(!c||!_||!T)continue;let N=e[c]??{},A=Dr(N),u=(i||T).slice(0,7);r.push({sha:u,release:T,commit:i||T,site:c,branch:N.branch??(A==="server-static"?"build artifact":"main"),status:h||"unknown",when:XL(_),timestamp:_,took:"-",by:"ts-cloud",rc:R?.replace(/^rc=/,"")??"",steps:A==="server-static"?["upload artifact","publish static files"]:["upload artifact","restart service"]})}return r.sort((d,E)=>String(E.timestamp).localeCompare(String(d.timestamp)))}function fF(t,e){let r=cF(t,e),d=cU(t),E=RF(t),n=Math.max(1,Number(t.infrastructure?.compute?.disk?.size??1)),c={server:{name:r?.serverName??`${t.project.slug}-${e}-app`,provider:r?.provider??_U(t),region:nF(t),ip:r?.publicIp??Qe,os:"Linux",uptime:Qe,probeStatus:"unavailable"},systemMetrics:{load:0,load5:0,load15:0,cpuUsedPct:0,cpus:Math.max(1,Number(t.infrastructure?.compute?.instances??1)),memUsedMb:0,memTotalMb:0,memAvailableMb:0,memCacheMb:0,swapUsedMb:0,swapTotalMb:0,diskUsedPct:0,diskUsedGb:0,diskTotalGb:n,inodeUsedPct:0,networkRxBytes:0,networkTxBytes:0,processes:0,uptimeSeconds:0},metricsUnavailable:!0,services:d,servicesDetail:d.map((_)=>({..._,since:Qe,memMb:0,auto:!0})),backup:EF(t),backupHistory:[],workers:_F(t),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:aL(t),securityEmptyReason:"Live security checks are unavailable until the dashboard can reach the compute box.",sites:E,sitesDetail:E.map((_)=>{let T=t.sites?.[_.name]??{},i=Dr(T);return{..._,root:i==="server-static"?Id(t.project.slug,_.name):`${Id(t.project.slug,_.name)}/current`,branch:i==="server-static"?"build artifact":"main",build:T.build,php:T.php??T.phpVersion,aliases:Array.isArray(T.aliases)?T.aliases:[],redirects:T.redirects&&typeof T.redirects==="object"?T.redirects:{},envKeys:Object.keys(T.env??T.environment??{})}}),siteHealth:[],sshKeys:nE(t.infrastructure?.compute?.sshKeys??[]),_serverReachable:!1,_metricsStatus:"unavailable"};return c.diagnostics=NU(t,c),c.activity=AU(c),c}async function Ph(t,e,r={}){if(!t.infrastructure?.compute)return null;let d=null;try{d=fr({config:t})}catch{d=null}let E=null,n=0,c=[];if(d)try{if(c=await d.findComputeTargets({slug:t.project.slug,environment:e,role:"app"}),n=c.length,c.length){let R=(await d.runRemoteDeploy({targets:[c[0]],commands:rF({includeServices:!r.telemetryOnly,includeSites:r.includeSiteHealth!==!1,projectFilter:t.cloud?.attachTo?t.project.slug:void 0}),comment:`ts-cloud dashboard:build ${t.project.slug}`,tags:{Project:t.project.slug,Environment:e,Role:"app"}})).perInstance?.[0]?.output;if(R)E=dF(R)}}catch{}let _=fF(t,e),T=(h,R=0)=>{let N=Number(h);return Number.isFinite(N)?N:R};if(_.server.os=E?.OS||_.server.os,_.server.uptime=E?.UPTIME||_.server.uptime,E){if(_.server.probeStatus="live",_.metricsUnavailable=!1,_._metricsStatus="live",_.systemMetrics={load:T(E.LOAD),load5:T(E.LOAD5),load15:T(E.LOAD15),cpuUsedPct:T(E.CPUUSED),cpus:T(E.CPUS,1),memUsedMb:T(E.MEMUSED),memTotalMb:T(E.MEMTOTAL,1),memAvailableMb:T(E.MEMAVAILABLE),memCacheMb:T(E.MEMCACHE),swapUsedMb:T(E.SWAPUSED),swapTotalMb:T(E.SWAPTOTAL),diskUsedPct:T(E.DISKPCT),diskUsedGb:T(E.DISKUSEDG),diskTotalGb:T(E.DISKTOTG,1),inodeUsedPct:T(E.INODEPCT),networkRxBytes:T(E.NETRX),networkTxBytes:T(E.NETTX),processes:T(E.PROCESSES),uptimeSeconds:T(E.UPTIME_SECONDS)},E.services.length){let h=[...new Map(E.services.map((R)=>[R.name,R])).values()];_.services=h.map((R)=>({name:R.name,status:R.status==="active"?"running":R.status})),_.servicesDetail=h.map((R)=>({name:R.name,status:R.status==="active"?"running":R.status,since:R.since&&R.since!==Qe?R.since:_.server.uptime,memMb:Math.max(0,Math.round(Number(R.memBytes??0)/1024/1024)),auto:R.enabled?!["disabled","static","masked"].includes(R.enabled):!0}))}if(E.discoveredSites.length)_.sitesDetail=SF(_.sitesDetail,E.discoveredSites,t.project.slug),_.sites=_.sitesDetail.map((h)=>({name:h.name,project:h.project,managedBy:h.managedBy,route:h.route,href:h.href,domain:h.domain,path:h.path,kind:h.kind,type:h.type,runtime:h.runtime,deploy:h.deploy,tls:h.tls,status:h.status,httpStatus:h.httpStatus,responseMs:h.responseMs,tlsDaysRemaining:h.tlsDaysRemaining,checkedAt:h.checkedAt})),_.siteHealth=_.sitesDetail.map((h)=>({name:h.name,project:h.project,route:h.route,status:h.status,httpStatus:h.httpStatus,responseMs:h.responseMs,tlsDaysRemaining:h.tlsDaysRemaining,checkedAt:h.checkedAt}))}if(d&&c.length&&!r.telemetryOnly)await Promise.all([(async()=>{try{let h=Object.keys(t.sites??{}),N=(await d.runRemoteDeploy({targets:[c[0]],commands:NF(h,t.project.slug),comment:`ts-cloud dashboard:deploy-history ${t.project.slug}`,tags:{Project:t.project.slug,Environment:e,Role:"app"}})).perInstance?.[0]?.output??"",A=DF(N,t.sites);_.serverDeployments=A.slice(0,5),_.serverDeploymentsDetail=A.slice(0,50),_.deploymentsEmptyReason=A.length?void 0:"No deployment history was found on the server yet. Deploy again to populate this timeline."}catch{_.deploymentsEmptyReason="Deployment history could not be read from the server."}})(),(async()=>{try{let R=(await d.runRemoteDeploy({targets:[c[0]],commands:uF(t),comment:`ts-cloud dashboard:server-logs ${t.project.slug}`,tags:{Project:t.project.slug,Environment:e,Role:"app"}})).perInstance?.[0]?.output??"",N=OF(R);_.serverLogs=N,_.serverLogsEmptyReason=N.length?void 0:"No recent journal entries were found for the managed server units."}catch{_.serverLogsEmptyReason="Server logs could not be read from the box."}})(),(async()=>{try{let R=(await d.runRemoteDeploy({targets:[c[0]],commands:AF(t),comment:`ts-cloud dashboard:security ${t.project.slug}`,tags:{Project:t.project.slug,Environment:e,Role:"app"}})).perInstance?.[0]?.output??"",N=IF(R),A=aL(t);if(!N.ports.length)N.ports=A.ports;if(!N.tlsCertificates.length)N.tlsCertificates=A.tlsCertificates;_.security=N,_.securityEmptyReason=void 0}catch{_.securityEmptyReason="Server security checks could not be read from the box."}})()]);else if(d&&n===0)_.deploymentsEmptyReason="No app server target was found for this environment.";let i=t.infrastructure?.compute?.sshKeys??t.infrastructure?.ssh?.keys??t.infrastructure?.sshKeys;if(Array.isArray(i)&&i.length)_.sshKeys=nE(i);return _._serverReachable=n>0&&!!E,_.diagnostics=NU(t,_),_.activity=AU(_),_}await Ht();var UF=new Set(["singlestore","vitess"]);function Fh(t){return UF.has(t)}var zh={mysql:"/var/lib/pantry/mysql/mysqld.sock",mariadb:"/var/lib/pantry/mariadb/mariadbd.sock"};function Oc(t){return/^[A-Za-z_][A-Za-z0-9_]{0,62}$/.test(t)}function wF(t){if(t==="postgres"||t==="pgsql")return"postgres";if(t==="mariadb")return"mariadb";if(t==="singlestore")return"singlestore";if(t==="vitess")return"vitess";return"mysql"}function pE(t){let e=t.infrastructure?.compute,r=mt(t)?.engine;if(r)return wF(r);let d=e?.managedServices??{};if(d.postgres)return"postgres";if(d.mariadb)return"mariadb";return"mysql"}var PL=(t)=>t.replace(/`/g,"``"),or=(t)=>t.replace(/\\/g,"\\\\").replace(/'/g,"\\'"),mE=(t)=>`"${t.replace(/"/g,'""')}"`,jh=(t)=>`'${t.replace(/'/g,"''")}'`;function jL(t,e){return[`mysql --socket=${t==="mariadb"?zh.mariadb:zh.mysql} -u root <<'TS_CLOUD_SQL_EOF'`,...e,"TS_CLOUD_SQL_EOF"]}function zL(t,e){return[`${dc(e)} -tA <<'TS_CLOUD_PG_EOF'`,...t,"TS_CLOUD_PG_EOF"]}function gF(t,e){if(t==="vitess")return $F(e);if(t==="postgres")return zL(["SELECT 'DB=' || datname FROM pg_database WHERE datistemplate = false;","SELECT 'USER=' || usename FROM pg_user;"],e);return jL(t,["SELECT CONCAT('DB=', schema_name) FROM information_schema.schemata WHERE schema_name NOT IN ('information_schema', 'mysql', 'performance_schema', 'sys');","SELECT DISTINCT CONCAT('USER=', User) FROM mysql.user WHERE User NOT IN ('root', 'mysql.sys', 'mysql.session', 'mysql.infoschema', 'debian-sys-maint');"])}function Cc(t,e,r){let d=e?.host??"127.0.0.1",E=e?.username??"root",n=e?.password??"",c=e?.ssl===!1?"":" --ssl-mode=PREFERRED",_=(i)=>`'${String(i).replace(/'/g,"'\\''")}'`;return[`${n?`MYSQL_PWD=${_(n)} `:""}mysql -h ${_(d)} -P ${e?.port??r} -u ${_(E)}${c} --batch --skip-column-names <<'TS_CLOUD_SQL_EOF'`,...t,"TS_CLOUD_SQL_EOF"]}var lc=15306;function $F(t){let e=Cc(["SHOW KEYSPACES;"],t,lc);return e[0]=`${e[0]} | sed 's/^/DB=/'`,e}function yF(t){return Cc(["SHOW KEYSPACES;","SHOW VITESS_SHARDS;","SHOW VITESS_TABLETS;"],t,lc)}function XF(t){let e=[],r=[],d=[];for(let E of t.split(`
|
|
6307
6307
|
`)){let n=E.trim();if(!n)continue;let c=n.split("\t").map((_)=>_.trim()).filter(Boolean);if(c.length>=6){let[_,T,i,h,R,N,A]=c;d.push({cell:_??"",keyspace:T??"",shard:i??"",type:h??"",state:R??"",alias:N??"",hostname:A??""});continue}if(c.length===1){let _=c[0];if(_.includes("/")){let[T,i]=_.split("/");if(T&&i)r.push({keyspace:T,shard:i})}else e.push(_)}}return{keyspaces:[...new Set(e)].filter(Boolean).sort(),shards:r,tablets:d}}function aF(t,e,r){if(t==="postgres")return zL([`SELECT 'CREATE DATABASE ${mE(e)}' WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = ${jh(e)})\\gexec`],r);return jL(t,[`CREATE DATABASE IF NOT EXISTS \`${PL(e)}\` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;`])}function PF(t,e,r){let{username:d,password:E,database:n,access:c}=e;if(t==="postgres"){let i=["DO $$ BEGIN",` IF NOT EXISTS (SELECT FROM pg_roles WHERE rolname = ${jh(d)}) THEN CREATE ROLE ${mE(d)} LOGIN PASSWORD ${jh(E)};`,` ELSE ALTER ROLE ${mE(d)} LOGIN PASSWORD ${jh(E)}; END IF;`,"END $$;"];if(n)i.push(c==="readonly"?`GRANT CONNECT ON DATABASE ${mE(n)} TO ${mE(d)};`:`GRANT ALL PRIVILEGES ON DATABASE ${mE(n)} TO ${mE(d)};`);return zL(i,r)}let _=c==="readonly"?"SELECT":"ALL PRIVILEGES",T=[`CREATE USER IF NOT EXISTS '${or(d)}'@'%' IDENTIFIED BY '${or(E)}';`,`CREATE USER IF NOT EXISTS '${or(d)}'@'localhost' IDENTIFIED BY '${or(E)}';`,`ALTER USER '${or(d)}'@'%' IDENTIFIED BY '${or(E)}';`,`ALTER USER '${or(d)}'@'localhost' IDENTIFIED BY '${or(E)}';`];if(n)T.push(`GRANT ${_} ON \`${PL(n)}\`.* TO '${or(d)}'@'%';`,`GRANT ${_} ON \`${PL(n)}\`.* TO '${or(d)}'@'localhost';`);return T.push("FLUSH PRIVILEGES;"),jL(t,T)}function jF(t){let e=[],r=[];for(let d of t.split(`
|
|
6308
|
-
`)){let E=d.trim();if(E.startsWith("DB="))e.push(E.slice(3));else if(E.startsWith("USER="))r.push(E.slice(5))}return{databases:[...new Set(e)].filter(Boolean).sort(),users:[...new Set(r)].filter(Boolean).sort()}}async function nr(t,e,r,d){let E;try{E=
|
|
6308
|
+
`)){let E=d.trim();if(E.startsWith("DB="))e.push(E.slice(3));else if(E.startsWith("USER="))r.push(E.slice(5))}return{databases:[...new Set(e)].filter(Boolean).sort(),users:[...new Set(r)].filter(Boolean).sort()}}async function nr(t,e,r,d){let E;try{E=fr({config:t})}catch(T){return{ok:!1,error:`Could not initialize the cloud driver: ${T?.message??T}`}}let n=t.project.slug,c=await E.findComputeTargets({slug:n,environment:e,role:"app"});if(!c.length)return{ok:!1,error:"No app server target was found for this environment."};let _=await E.runRemoteDeploy({targets:[c[0]],commands:["set -uo pipefail",...r],comment:d,tags:{Project:n,Environment:e,Role:"app"}});return{ok:_.success,stdout:_.perInstance?.[0]?.output??"",stderr:_.perInstance?.[0]?.error??_.error??""}}function Bh(t,e){return{ok:!1,error:`${e} is not available for ${t}: it is an external cluster, so this box has no engine to administer. ${t==="vitess"?"Create a keyspace with `vtctldclient CreateKeyspace`, and manage vtgate credentials on the cluster.":"Use the provider console or the cluster's own admin connection."}`}}async function LU(t,e){let r=pE(t);if(Fh(r)&&r!=="vitess")return{...Bh(r,"Listing databases"),engine:r,databases:[],users:[]};let d=await nr(t,e,gF(r,mt(t)),"ts-cloud db:list"),E=d.ok&&d.stdout?jF(d.stdout):{databases:[],users:[]};return{...d,engine:r,...E}}async function uU(t,e,r){let d=pE(t);if(Fh(d))return Bh(d,"Creating a database");return nr(t,e,aF(d,r,mt(t)),`ts-cloud db:create ${r}`)}async function OU(t,e,r){let d=pE(t);if(Fh(d))return Bh(d,"Creating a database user");return nr(t,e,PF(d,r,mt(t)),`ts-cloud db:user ${r.username}`)}var FL="/var/backups/ts-cloud/databases";function zF(t,e,r=FL,d){let E=`${r}/${e}-$(date +%Y%m%d-%H%M%S).sql.gz`,n=`mkdir -p ${r}`;if(t==="postgres")return[n,`${dc(d,"pg_dump")} ${e} | gzip > "${E}"`,`echo "BACKUP=${E}"`,`ls -l "${E}"`];let c=t==="mariadb"?zh.mariadb:zh.mysql;return[n,`mysqldump --socket=${c} -u root ${e} | gzip > "${E}"`,`echo "BACKUP=${E}"`,`ls -l "${E}"`]}function FF(t=FL){return[`ls -1t ${t}/*.sql.gz 2>/dev/null | head -50 | sed 's|^|BACKUP=|' || true`]}function BF(t){let e=[];for(let r of t.split(`
|
|
6309
6309
|
`)){let d=r.trim();if(!d.startsWith("BACKUP="))continue;let E=d.slice(7),c=(E.split("/").pop()??E).replace(/-\d{8}-\d{6}\.sql\.gz$/,"");if(E)e.push({file:E,database:c})}return e}async function CU(t,e,r){if(!Oc(r))return{ok:!1,error:"Database name must be a valid identifier.",database:r};let d=pE(t);if(Fh(d))return{...Bh(d,"Backing up"),database:r};return{...await nr(t,e,zF(d,r,FL,mt(t)),`ts-cloud db:backup ${r}`),database:r}}async function lU(t,e){let r=await nr(t,e,FF(),"ts-cloud db:backups"),d=r.ok&&r.stdout?BF(r.stdout):[];return{...r,backups:d}}async function IU(t,e){let r=pE(t),d={keyspaces:[],shards:[],tablets:[]};if(r!=="vitess")return{ok:!1,error:"The configured database engine is not Vitess.",engine:r,...d};let E=await nr(t,e,yF(mt(t)),"ts-cloud vitess:topology"),n=E.ok&&E.stdout?XF(E.stdout):d;return{...E,engine:r,...n}}function DU(t){return t.filter((e)=>e.state.toUpperCase()!=="SERVING")}function fU(t){let e=new Set(t.tablets.filter((r)=>r.type.toUpperCase()==="PRIMARY"&&r.state.toUpperCase()==="SERVING").map((r)=>`${r.keyspace}/${r.shard}`));return t.shards.filter((r)=>!e.has(`${r.keyspace}/${r.shard}`))}await Ht();var BL="/usr/local/bin/vtctldclient",JF="21.0.0";function Hh(t){return`'${String(t).split("'").join("'\\''")}'`}function Wh(t){return mt(t)?.vitess??{}}function UU(t){return/^[A-Za-z_][A-Za-z0-9_]{0,63}$/.test(t)}function HF(t){return/^[0-9a-f]{8}(?:_[0-9a-f]{4}){3}_[0-9a-f]{12}$/i.test(t)}function WF(t=JF){let e=Hh(t);return[`if ${BL} --version 2>/dev/null | grep -q ${e}; then echo "vtctldclient ${t} already installed"; else`," command -v curl >/dev/null 2>&1 || (apt-get update -y && apt-get install -y curl ca-certificates)",' if [ "$(uname -m)" != "x86_64" ]; then',' echo "vtctldclient: Vitess publishes only an x86_64 release tarball; this box is $(uname -m). Build from source or install via pantry." >&2'," exit 1"," fi",' tmp="$(mktemp -d)"',` api="https://api.github.com/repos/vitessio/vitess/releases/tags/v${t}"`,` url="$(curl -fsSL "$api" | grep -oE '"browser_download_url"[[:space:]]*:[[:space:]]*"[^"]+vitess-[0-9][^"]*\\.tar\\.gz"' | head -1 | sed -E 's/.*"(https[^"]+)"/\\1/')"`,' if [ -z "$url" ]; then echo "vtctldclient: no release tarball found for v'+t+'" >&2; rm -rf "$tmp"; exit 1; fi',` curl -fsSL "$url" | tar -xz -C "$tmp" --strip-components=2 --wildcards --occurrence=1 '*/bin/vtctldclient' || true`,' if [ ! -s "$tmp/vtctldclient" ]; then',' echo "vtctldclient: could not extract the binary from $url" >&2',' rm -rf "$tmp"; exit 1'," fi",` install -m 0755 "$tmp/vtctldclient" ${BL}`,' rm -rf "$tmp"',` echo "installed vtctldclient ${t}"`,"fi"]}function wU(t){if(!t.vtctldAddr)return null;return`${BL} --server ${Hh(t.vtctldAddr)}`}function vF(t,e,r={}){let d=wU(t);if(!d)return null;let E=r.sharded?" --sharded":"";return[`${d} CreateKeyspace${E} ${Hh(e)}`]}function QF(t,e,r){let d=wU(t);if(!d)return null;return['vschema_tmp="$(mktemp)"',`cat > "$vschema_tmp" <<'TS_CLOUD_VSCHEMA_EOF'`,r,"TS_CLOUD_VSCHEMA_EOF",`${d} ApplyVSchema --vschema-file "$vschema_tmp" ${Hh(e)}`,'rm -f "$vschema_tmp"']}function YF(t,e,r="vitess"){return Cc([`SET @@ddl_strategy='${r}';`,e.endsWith(";")?e:`${e};`],t,lc)}function MF(t,e){let r=e?[`USE ${e.replace(/[^A-Z0-9_]/gi,"")};`,"SHOW VITESS_MIGRATIONS;"]:["SHOW VITESS_MIGRATIONS;"],d=Cc(r,t,lc);return d[0]=d[0].replace(" --skip-column-names",""),d}function GF(t){let e=t.split(`
|
|
6310
6310
|
`).map((c)=>c.trimEnd()).filter((c)=>c.trim().length>0);if(e.length===0)return[];let r=e[0].split("\t").map((c)=>c.trim()),d=(c)=>r.indexOf(c),E={uuid:d("migration_uuid"),keyspace:d("keyspace"),shard:d("shard"),table:d("mysql_table"),status:d("migration_status"),strategy:d("strategy"),added:d("added_timestamp"),completed:d("completed_timestamp"),progress:d("progress")};if(E.uuid===-1)return[];let n=[];for(let c of e.slice(1)){let _=c.split("\t"),T=(h)=>h>=0?(_[h]??"").trim():"",i=T(E.uuid);if(!i)continue;n.push({uuid:i,keyspace:T(E.keyspace),shard:T(E.shard),table:T(E.table),status:T(E.status),strategy:T(E.strategy),added:T(E.added),completed:T(E.completed),progress:T(E.progress)})}return n}function VF(t){return t.filter((e)=>e.status.toLowerCase()==="failed")}function KF(t){return t.filter((e)=>["running","queued","ready"].includes(e.status.toLowerCase()))}function ZF(t,e,r){let d=r.toUpperCase();return Cc([`ALTER VITESS_MIGRATION '${e}' ${d};`],t,lc)}function Ic(t){if(pE(t)!=="vitess")return{ok:!1,error:"The configured database engine is not Vitess."};return null}function Jh(t){if(!t.vtctldAddr)return{ok:!1,error:"No vtctld address is configured. Creating keyspaces and applying a VSchema are topology operations that vtgate cannot perform. Set `infrastructure.appDatabase.vitess.vtctldAddr` (for example `vtctld.internal:15999`) and redeploy."};return null}async function gU(t,e){let r=Ic(t);if(r)return r;let d=Wh(t);return nr(t,e,WF(d.clientVersion),"ts-cloud vitess:install-client")}async function $U(t,e,r,d={}){let E=Ic(t);if(E)return{...E,keyspace:r};if(!UU(r))return{ok:!1,error:"Keyspace name must be a valid identifier.",keyspace:r};let n=Wh(t),c=Jh(n);if(c)return{...c,keyspace:r};let _=vF(n,r,d);if(!_)return{...Jh({}),keyspace:r};return{...await nr(t,e,_,`ts-cloud vitess:create-keyspace ${r}`),keyspace:r}}async function yU(t,e,r,d){let E=Ic(t);if(E)return{...E,keyspace:r};if(!UU(r))return{ok:!1,error:"Keyspace name must be a valid identifier.",keyspace:r};try{let i=JSON.parse(d);if(!i||typeof i!=="object")return{ok:!1,error:"The VSchema must be a JSON object.",keyspace:r}}catch(i){return{ok:!1,error:`The VSchema is not valid JSON: ${i?.message??i}`,keyspace:r}}let n=Wh(t),c=Jh(n);if(c)return{...c,keyspace:r};let _=QF(n,r,d);if(!_)return{...Jh({}),keyspace:r};return{...await nr(t,e,_,`ts-cloud vitess:apply-vschema ${r}`),keyspace:r}}async function XU(t,e,r){let d=Ic(t);if(d)return d;if(!r.trim())return{ok:!1,error:"No SQL was provided."};let E=Wh(t);return nr(t,e,YF(mt(t),r,E.ddlStrategy??"vitess"),"ts-cloud vitess:apply-schema")}async function aU(t,e,r){let d=Ic(t);if(d)return{...d,migrations:[],failed:[],running:[]};let E=await nr(t,e,MF(mt(t),r),"ts-cloud vitess:migrations"),n=E.ok&&E.stdout?GF(E.stdout):[];return{...E,migrations:n,failed:VF(n),running:KF(n)}}async function PU(t,e,r,d){let E=Ic(t);if(E)return{...E,uuid:r};if(!HF(r))return{ok:!1,error:"Migration UUID is not in the expected format.",uuid:r};return{...await nr(t,e,ZF(mt(t),r,d),`ts-cloud vitess:migration ${d} ${r}`),uuid:r}}var kF={capability:"runtime:terminal",scope:"organization"};var bF={"GET /api/health":{capability:"project:read",anyUser:!0},"GET /api/dashboard-data":{capability:"project:read",anyUser:!0},"GET /api/config":{capability:"config:read",anyUser:!0},"GET /api/me":{capability:"project:read",anyUser:!0},"GET /api/search":{capability:"project:read",anyUser:!0},"GET /api/search/preferences":{capability:"project:read",anyUser:!0},"POST /api/search/preferences":{capability:"project:read",anyUser:!0},"DELETE /api/search/preferences":{capability:"project:read",anyUser:!0},"GET /api/auth/security":{capability:"project:read",anyUser:!0},"GET /api/auth/sessions":{capability:"project:read",anyUser:!0},"DELETE /api/auth/sessions":{capability:"project:read",anyUser:!0},"POST /api/auth/sessions/revoke-others":{capability:"project:read",anyUser:!0},"POST /api/auth/password/change":{capability:"project:read",anyUser:!0},"POST /api/auth/mfa/enroll":{capability:"project:read",anyUser:!0},"POST /api/auth/mfa/verify":{capability:"project:read",anyUser:!0},"DELETE /api/auth/mfa":{capability:"project:read",anyUser:!0},"POST /api/auth/step-up":{capability:"project:read",anyUser:!0},"GET /api/auth/oidc/providers":{capability:"users:read",scope:"organization"},"POST /api/auth/oidc/providers":{capability:"users:manage",scope:"organization"},"PATCH /api/auth/oidc/providers":{capability:"users:manage",scope:"organization"},"GET /api/automation":{capability:"users:read",scope:"organization"},"POST /api/automation/service-accounts":{capability:"users:manage",scope:"organization"},"PATCH /api/automation/service-accounts":{capability:"users:manage",scope:"organization"},"POST /api/automation/tokens":{capability:"users:manage",scope:"organization"},"POST /api/automation/tokens/rotate":{capability:"users:manage",scope:"organization"},"DELETE /api/automation/tokens":{capability:"users:manage",scope:"organization"},"GET /api/security/posture":{capability:"security:read"},"GET /api/security/export":{capability:"security:read"},"POST /api/security/scan":{capability:"security:manage"},"POST /api/security/review":{capability:"deployments:create"},"POST /api/security/policies":{capability:"security:manage"},"PATCH /api/security/policies":{capability:"security:manage"},"POST /api/security/waivers":{capability:"security:waive"},"DELETE /api/security/waivers":{capability:"security:waive"},"PATCH /api/security/findings":{capability:"security:manage"},"POST /api/security/comments":{capability:"security:manage"},"GET /api/sources":{capability:"sources:read"},"POST /api/sources/connections":{capability:"sources:manage"},"PATCH /api/sources/connections":{capability:"sources:manage"},"DELETE /api/sources/connections":{capability:"sources:manage"},"POST /api/sources/deploy-keys":{capability:"sources:manage"},"DELETE /api/sources/deploy-keys":{capability:"sources:manage"},"POST /api/sources/repositories/sync":{capability:"sources:manage"},"GET /api/sources/references":{capability:"sources:read"},"POST /api/sources/bindings":{capability:"sources:manage"},"PATCH /api/sources/bindings":{capability:"sources:manage"},"POST /api/sources/webhooks":{capability:"sources:manage"},"PATCH /api/sources/webhooks":{capability:"sources:manage"},"DELETE /api/sources/webhooks":{capability:"sources:manage"},"GET /api/onboarding":{capability:"applications:read"},"POST /api/onboarding/detect":{capability:"applications:manage"},"POST /api/onboarding/plan":{capability:"applications:manage"},"POST /api/onboarding/drafts":{capability:"applications:manage"},"PATCH /api/onboarding/drafts":{capability:"applications:manage"},"POST /api/onboarding/artifacts":{capability:"applications:manage"},"POST /api/onboarding/registries":{capability:"applications:manage"},"PATCH /api/onboarding/registries":{capability:"applications:manage"},"DELETE /api/onboarding/registries":{capability:"applications:manage"},"POST /api/onboarding/apply":{capability:"applications:manage"},"GET /api/compose":{capability:"applications:read",anyUser:!0},"POST /api/compose/preview":{capability:"applications:manage",anyUser:!0},"POST /api/compose/import":{capability:"applications:manage",anyUser:!0},"POST /api/compose/template":{capability:"applications:manage",anyUser:!0},"POST /api/compose/action":{capability:"project:read",anyUser:!0},"POST /api/compose/logs":{capability:"runtime:logs",anyUser:!0},"POST /api/compose/shell":{capability:"runtime:terminal",scope:"organization"},"GET /api/compose/import":{capability:"applications:manage"},"GET /api/compose/template":{capability:"applications:manage"},"GET /api/compose/logs":{capability:"runtime:logs"},"GET /api/compose/shell":{capability:"runtime:terminal",scope:"organization"},"GET /api/organization":{capability:"users:read",scope:"organization"},"GET /api/organization/invitations":{capability:"users:read",scope:"organization"},"POST /api/organization/invitations":{capability:"users:manage",scope:"organization"},"DELETE /api/organization/invitations":{capability:"users:manage",scope:"organization"},"POST /api/organization/invitations/resend":{capability:"users:manage",scope:"organization"},"PATCH /api/organization/memberships":{capability:"users:manage",scope:"organization"},"DELETE /api/organization/memberships":{capability:"users:manage",scope:"organization"},"POST /api/organization/grants":{capability:"users:manage",scope:"organization"},"DELETE /api/organization/grants":{capability:"users:manage",scope:"organization"},"GET /api/control-plane/operations":{capability:"deployments:read"},"GET /api/control-plane/events":{capability:"audit:read"},"GET /api/queue":{capability:"deployments:read",anyUser:!0},"GET /api/queue/logs":{capability:"deployments:read",anyUser:!0},"GET /api/queue/stream":{capability:"deployments:read",anyUser:!0},"POST /api/queue/cancel":{capability:"deployments:cancel",anyUser:!0},"POST /api/queue/retry":{capability:"deployments:create",anyUser:!0},"GET /api/queue/settings":{capability:"deployments:read"},"PATCH /api/queue/settings":{capability:"automation:manage",scope:"organization"},"DELETE /api/queue/history":{capability:"automation:manage",scope:"organization"},"GET /api/previews":{capability:"deployments:read",anyUser:!0},"GET /api/releases":{capability:"deployments:read",anyUser:!0},"POST /api/releases/action":{capability:"deployments:create",anyUser:!0},"POST /api/previews/deploy":{capability:"deployments:create",anyUser:!0},"POST /api/previews/destroy":{capability:"deployments:cancel",anyUser:!0},"POST /api/previews/extend":{capability:"deployments:create",anyUser:!0},"POST /api/previews/rebuild":{capability:"deployments:create",anyUser:!0},"POST /api/previews/definitions":{capability:"config:write",anyUser:!0},"POST /api/previews/cleanup":{capability:"automation:manage",scope:"organization"},"GET /api/tags":{capability:"project:read"},"POST /api/tags":{capability:"tags:manage"},"DELETE /api/tags":{capability:"tags:manage"},"POST /api/sites/deploy":{capability:"deployments:create",scope:"site",siteFrom:"body"},"PATCH /api/sites":{capability:"config:write",scope:"site",siteFrom:"body"},"POST /api/sites":{capability:"config:write"},"DELETE /api/sites":{capability:"config:write"},"POST /api/env":{capability:"config:write"},"GET /api/ssh-keys":{capability:"fleet:read"},"POST /api/ssh-keys":{capability:"fleet:manage"},"DELETE /api/ssh-keys":{capability:"fleet:manage"},"GET /api/firewall":{capability:"fleet:read"},"POST /api/firewall":{capability:"fleet:manage"},"DELETE /api/firewall":{capability:"fleet:manage"},"GET /api/databases":{capability:"data:read"},"POST /api/databases":{capability:"data:admin"},"GET /api/databases/vitess":{capability:"data:read"},"GET /api/databases/vitess/migrations":{capability:"data:read"},"POST /api/databases/vitess/migrations/action":{capability:"data:admin"},"POST /api/databases/vitess/keyspaces":{capability:"data:admin"},"POST /api/databases/vitess/vschema":{capability:"data:admin"},"POST /api/databases/vitess/schema":{capability:"data:admin"},"POST /api/databases/vitess/install-client":{capability:"data:admin"},"GET /api/databases/backups":{capability:"backups:read"},"POST /api/databases/backup":{capability:"backups:create"},"POST /api/databases/users":{capability:"data:admin"},"GET /api/data-services":{capability:"data:read"},"GET /api/data-services/capabilities":{capability:"data:read"},"GET /api/data-services/connections":{capability:"data:read"},"POST /api/data-services/preview":{capability:"data:read"},"POST /api/data-services":{capability:"data:admin"},"POST /api/data-services/action":{capability:"data:admin"},"POST /api/data-services/dependencies":{capability:"data:admin"},"POST /api/data-services/management":{capability:"data:admin"},"POST /api/data-services/reveal":{capability:"data:admin"},"GET /api/backups":{capability:"backups:read"},"POST /api/backups/destinations":{capability:"backups:create"},"POST /api/backups/destinations/test":{capability:"backups:create"},"POST /api/backups/policies":{capability:"backups:create"},"POST /api/backups/run":{capability:"backups:create"},"POST /api/backups/verify":{capability:"backups:create"},"POST /api/backups/restore":{capability:"backups:restore"},"POST /api/backups/recovery-points":{capability:"backups:create"},"POST /api/backups/retention":{capability:"backups:create"},"GET /api/configuration":{capability:"config:read"},"GET /api/configuration/export":{capability:"config:read"},"POST /api/configuration/plan":{capability:"config:read"},"POST /api/configuration":{capability:"config:write"},"POST /api/configuration/import":{capability:"config:write"},"POST /api/configuration/dependencies":{capability:"config:write"},"POST /api/configuration/transfer":{capability:"config:write"},"POST /api/configuration/bulk":{capability:"config:write"},"POST /api/configuration/reveal":{capability:"secrets:read"},"DELETE /api/configuration":{capability:"config:write"},"GET /api/volumes":{capability:"data:read"},"POST /api/volumes":{capability:"data:admin"},"POST /api/volumes/attach":{capability:"data:admin"},"POST /api/volumes/detach":{capability:"data:admin"},"POST /api/volumes/resize":{capability:"data:admin"},"POST /api/volumes/snapshot":{capability:"backups:create"},"POST /api/volumes/restore":{capability:"backups:restore"},"POST /api/volumes/adopt":{capability:"data:admin"},"POST /api/volumes/discover":{capability:"data:read"},"DELETE /api/volumes":{capability:"data:admin"},"GET /api/fleet":{capability:"fleet:read"},"POST /api/fleet":{capability:"fleet:manage"},"POST /api/fleet/action":{capability:"fleet:manage"},"GET /api/capacity":{capability:"fleet:read"},"POST /api/capacity":{capability:"fleet:manage"},"POST /api/capacity/member":{capability:"fleet:manage"},"POST /api/capacity/explain":{capability:"fleet:read"},"POST /api/capacity/action":{capability:"fleet:manage"},"GET /api/regions":{capability:"config:read"},"POST /api/regions":{capability:"config:write"},"POST /api/regions/action":{capability:"config:write"},"GET /api/maintenance":{capability:"automation:read"},"POST /api/maintenance/cleanup-preview":{capability:"automation:manage"},"POST /api/maintenance/cleanup-apply":{capability:"automation:manage"},"POST /api/maintenance/drill":{capability:"automation:manage"},"POST /api/maintenance/drill-run":{capability:"automation:manage"},"GET /api/actions":{capability:"runtime:read"},"GET /api/runtime/workloads":{capability:"runtime:read"},"GET /api/runtime/logs":{capability:"runtime:logs"},"POST /api/runtime/log-sessions":{capability:"runtime:logs"},"GET /api/runtime/log-sessions":{capability:"runtime:logs"},"GET /api/runtime/log-stream":{capability:"runtime:logs"},"DELETE /api/runtime/log-sessions":{capability:"runtime:logs"},"POST /api/runtime/exec-sessions":{capability:"runtime:terminal",scope:"organization"},"GET /api/runtime/exec-sessions":{capability:"runtime:terminal",scope:"organization"},"GET /api/runtime/exec-stream":{capability:"runtime:terminal",scope:"organization"},"DELETE /api/runtime/exec-sessions":{capability:"runtime:terminal",scope:"organization"},"POST /api/runtime/files/read":{capability:"runtime:terminal",scope:"organization"},"POST /api/runtime/files/write":{capability:"runtime:terminal",scope:"organization"},"POST /api/runtime/operations":{capability:"runtime:restart"},"GET /api/telemetry/status":{capability:"runtime:read"},"GET /api/telemetry/settings":{capability:"runtime:read"},"PATCH /api/telemetry/settings":{capability:"config:write",scope:"organization"},"GET /api/telemetry/query":{capability:"runtime:logs"},"GET /api/telemetry/tail":{capability:"runtime:logs"},"GET /api/telemetry/series":{capability:"runtime:read"},"POST /api/telemetry/refresh":{capability:"runtime:logs"},"POST /api/telemetry/export":{capability:"runtime:logs"},"GET /api/telemetry/saved-queries":{capability:"runtime:logs"},"POST /api/telemetry/saved-queries":{capability:"runtime:logs"},"DELETE /api/telemetry/saved-queries":{capability:"runtime:logs"},"GET /api/health/checks":{capability:"runtime:read"},"POST /api/health/checks":{capability:"config:write"},"PATCH /api/health/checks":{capability:"config:write"},"POST /api/health/checks/test":{capability:"runtime:read"},"POST /api/health/checks/run":{capability:"runtime:restart"},"GET /api/alerts":{capability:"runtime:read"},"GET /api/alerts/rules":{capability:"runtime:read"},"POST /api/alerts/rules":{capability:"config:write"},"PATCH /api/alerts/rules":{capability:"config:write"},"POST /api/alerts/evaluate":{capability:"runtime:restart"},"POST /api/alerts/action":{capability:"runtime:restart"},"POST /api/alerts/silences":{capability:"config:write"},"GET /api/notifications/channels":{capability:"automation:read",scope:"organization"},"POST /api/notifications/channels":{capability:"automation:manage",scope:"organization"},"PATCH /api/notifications/channels":{capability:"automation:manage",scope:"organization"},"POST /api/notifications/channels/test":{capability:"automation:manage",scope:"organization"},"GET /api/notifications/routes":{capability:"automation:read",scope:"organization"},"POST /api/notifications/routes":{capability:"automation:manage",scope:"organization"},"PATCH /api/notifications/routes":{capability:"automation:manage",scope:"organization"},"POST /api/notifications/routes/preview":{capability:"automation:read",scope:"organization"},"GET /api/notifications/deliveries":{capability:"automation:read",scope:"organization"},"POST /api/notifications/deliveries/retry":{capability:"automation:manage",scope:"organization"},"GET /api/jobs":{capability:"automation:read"},"POST /api/jobs":{capability:"automation:manage"},"PATCH /api/jobs":{capability:"automation:manage"},"POST /api/jobs/preview":{capability:"automation:read"},"POST /api/jobs/action":{capability:"automation:manage"},"POST /api/jobs/reconcile":{capability:"automation:manage"},"GET /api/jobs/history":{capability:"automation:read"},"GET /api/workers":{capability:"automation:read"},"POST /api/workers/action":{capability:"automation:manage"},"POST /api/actions/run":{capability:"fleet:manage"},"GET /api/server/operations":{capability:"fleet:read"},"POST /api/server/operations/run":{capability:"fleet:manage"},"POST /api/server/command":{capability:"runtime:terminal",scope:"organization"},"GET /api/terminal":{capability:"runtime:terminal",scope:"organization"},"GET /api/users":{capability:"users:read",scope:"organization"},"POST /api/users":{capability:"users:manage",scope:"organization"},"DELETE /api/users":{capability:"users:manage",scope:"organization"},"GET /api/serverless/operations":{capability:"deployments:read"},"POST /api/serverless/operations/run":{capability:"deployments:create"},"POST /api/serverless/command":{capability:"runtime:terminal",scope:"organization"},"GET /api/serverless/dlq":{capability:"data:read"},"POST /api/serverless/dlq/redrive":{capability:"data:write"},"POST /api/serverless/dlq/purge":{capability:"data:admin"},"GET /api/serverless/secrets":{capability:"secrets:read"},"POST /api/serverless/secrets":{capability:"secrets:write"},"DELETE /api/serverless/secrets":{capability:"secrets:write"},"POST /api/serverless/functions/config":{capability:"config:write"},"GET /api/serverless/alarms":{capability:"runtime:read"},"POST /api/serverless/alarms":{capability:"config:write"},"DELETE /api/serverless/alarms":{capability:"config:write"},"GET /api/serverless/traces":{capability:"runtime:read"},"POST /api/serverless/scheduler":{capability:"automation:manage"}};function JL(t,e){return bF[`${t.toUpperCase()} ${e}`]??kF}await Ht();import{createHmac as xF,randomBytes as qF,timingSafeEqual as sF}from"node:crypto";import{chmodSync as oF,existsSync as mF,mkdirSync as pF,readFileSync as tB,writeFileSync as eB}from"node:fs";import{dirname as rB}from"node:path";var M_="ts_cloud_session";var dB=28800000;function jU(t){let e=process.env.TS_CLOUD_DASHBOARD_SECRET?.trim();if(e)return e;let r=ne(t,"dashboard-secret");try{if(mF(r)){let E=tB(r,"utf8").trim();if(E)return E}}catch{}let d=qF(32).toString("base64url");try{pF(rB(r),{recursive:!0}),eB(r,`${d}
|
|
6311
6311
|
`),oF(r,384)}catch{}return d}function EB(t,e){return xF("sha256",e).update(t).digest("base64url")}function zU(t,e){if(!t)return null;let r=t.lastIndexOf(".");if(r<=0)return null;let d=t.slice(0,r),E=t.slice(r+1),n=EB(d,e),c=Buffer.from(E),_=Buffer.from(n);if(c.length!==_.length||!sF(c,_))return null;try{let T=JSON.parse(Buffer.from(d,"base64url").toString("utf8"));if(typeof T?.u!=="string"||typeof T?.exp!=="number")return null;if(T.mv!==void 0&&(!T.mv||typeof T.mv!=="object"||Array.isArray(T.mv)||Object.values(T.mv).some((i)=>!Number.isInteger(i)||i<1)))return null;if(Date.now()>=T.exp)return null;return T}catch{return null}}function HL(t,e){if(!t)return;for(let r of t.split(";")){let d=r.indexOf("=");if(d<0)continue;if(r.slice(0,d).trim()===e)return decodeURIComponent(r.slice(d+1).trim())}return}function Dc(t,e={secure:!0}){let r=Math.floor((e.maxAgeMs??dB)/1000),d=[`${M_}=${encodeURIComponent(t)}`,"Path=/","HttpOnly","SameSite=Lax",`Max-Age=${r}`];if(e.secure)d.push("Secure");return d.join("; ")}function vh(t={secure:!0}){let e=[`${M_}=`,"Path=/","HttpOnly","SameSite=Lax","Max-Age=0"];if(t.secure)e.push("Secure");return e.join("; ")}await Ht();import{chmodSync as nB,existsSync as cB,mkdirSync as _B,readFileSync as TB,writeFileSync as iB}from"node:fs";import{dirname as hB}from"node:path";function FU(){return Nn("dashboard-users.json")}function Qh(t){return/^[a-z0-9][a-z0-9._-]{1,31}$/i.test(t)}function RB(t){if(!t||typeof t.username!=="string"||!Qh(t.username)||typeof t.passwordHash!=="string")return null;let e=t.role==="admin"?"admin":"member",r={};if(t.sites&&typeof t.sites==="object"){for(let[d,E]of Object.entries(t.sites))if(E==="owner"||E==="collaborator")r[d]=E}return{username:t.username,passwordHash:t.passwordHash,role:e,sites:r,name:typeof t.name==="string"?t.name:void 0,email:typeof t.email==="string"?t.email.trim().toLowerCase():void 0,createdAt:typeof t.createdAt==="string"?t.createdAt:void 0}}function SB(t){try{let e=JSON.parse(t);if(!Array.isArray(e?.users))return[];return e.users.map(RB).filter((r)=>r!==null)}catch{return[]}}function BU(t){return ne(t,"dashboard-users.json")}function Ye(t){let e=BU(t);if(!cB(e))return[];try{return SB(TB(e,"utf8"))}catch{return[]}}function Yh(t,e){let r=BU(t);_B(hB(r),{recursive:!0}),iB(r,`${JSON.stringify({users:e},null,2)}
|
|
6312
|
-
`),nB(r,384)}function
|
|
6312
|
+
`),nB(r,384)}function wr(t,e){let r=e.trim().toLowerCase();return t.find((d)=>d.username.toLowerCase()===r)}function JU(t,e="admin"){let r=Ye(t);if(r.some((c)=>c.role==="admin"))return{users:r};let d=process.env.TS_CLOUD_UI_PASSWORD?.trim()||lL(),E={username:e,passwordHash:EE(d),role:"admin",sites:{},name:"Administrator",createdAt:new Date().toISOString()},n=[...r,E];return Yh(t,n),{users:n,generated:{username:e,password:d}}}function G_(t,e){let r=Ye(t),d=wr(r,e.username),E=e.password?.trim()||(d?void 0:lL()),n={username:d?.username??e.username,passwordHash:E?EE(E):d.passwordHash,role:d?.role??"member",sites:e.sites,name:e.name??d?.name,email:e.email?.trim().toLowerCase()??d?.email,createdAt:d?.createdAt??new Date().toISOString()},c=d?r.map((_)=>_.username.toLowerCase()===n.username.toLowerCase()?n:_):[...r,n];return Yh(t,c),{user:n,password:E}}function Mh(t,e,r){let d=Ye(t),E=wr(d,e);if(!E)throw Error("Authentication user was not found");let n={...E,passwordHash:r};return Yh(t,d.map((c)=>c.username.toLowerCase()===E.username.toLowerCase()?n:c)),n}function WL(t,e){let r=Ye(t),d=wr(r,e);if(!d)return{ok:!1,error:`No such user: ${e}`};if(d.role==="admin"&&r.filter((E)=>E.role==="admin").length===1)return{ok:!1,error:"Cannot remove the last admin."};return Yh(t,r.filter((E)=>E.username.toLowerCase()!==d.username.toLowerCase())),{ok:!0}}function fc(t){return{username:t.username,name:t.name??t.username,role:t.role,email:t.email,sites:t.sites,siteCount:Object.keys(t.sites).length,createdAt:t.createdAt}}var NB={username:"local",passwordHash:"",role:"admin",sites:{},name:"Local (auth disabled)"};function HU(t){let{cwd:e,enabled:r,secret:d,authorization:E,authentication:n}=t,c=(T)=>{if(!n)return;let i=HL(T.headers.get("cookie"),M_);return i?.startsWith("v2.")?n.verifySessionToken(i):void 0},_=(T)=>{let i=E.store.getActorByExternalId("user",`dashboard:${T.username.toLowerCase()}`),h=i?E.store.getMembershipForActor(E.organizationId,i.id):void 0;return{actor:i,membership:h}};return{enabled:r,resolveUser(T){if(!r)return NB;let i=HL(T.headers.get("cookie"),M_),h=c(T),R=h?void 0:zU(i,d),N=h?.identity.username??R?.u;if(!N)return null;let A=wr(Ye(e),N);if(!A)return null;let{membership:u}=_(A);if(!u||u.status!=="active"||!h&&R?.mv?.[E.organizationId]!==u.sessionVersion)return null;if(!u.lastActiveAt||Date.now()-new Date(u.lastActiveAt).getTime()>300000)E.store.touchMembership(u.id);return A},resolveSession(T){return c(T)?.session??null},check(T,i,h,R){if(!r)return{ok:!0};if(!h)return{ok:!1,status:401,error:"Sign in to continue.",unauthenticated:!0};let N=JL(T.method,i);if(N.anyUser)return{ok:!0};if(N.siteFrom==="body"&&!R)return{ok:!1,status:400,error:"This request must name a site."};let{membership:A}=_(h);if(!A)return{ok:!1,status:401,error:"Sign in to continue.",unauthenticated:!0};let u=N.scope==="organization"?{organizationId:E.organizationId}:E.store.resolveAuthorizationTarget(E.organizationId,{type:"project",id:E.projectId});if(N.scope==="site"){let w=new URL(T.url).searchParams.get("env")??E.defaultEnvironment,I=E.store.getEnvironmentBySlug(E.projectId,w),a=E.store.listResources(E.projectId,I?.id).find((P)=>P.kind==="application"&&P.slug===R);u=a?E.store.resolveAuthorizationTarget(E.organizationId,{type:"resource",id:a.id}):void 0}if(!(u?Ve({membership:A,grants:E.store.listGrants(A.id),capability:N.capability,target:u}):{allowed:!1}).allowed)return{ok:!1,status:403,error:"You do not have access to this."};return{ok:!0}}}}async function WU(t,e){if(JL(t.method,e).siteFrom!=="body")return;try{let d=await t.clone().json();return String(d?.name??"").trim()||void 0}catch{return}}import{createHash as AB}from"node:crypto";function vU(t,e,r){for(let d of r){let E=ie(e.store,d);if(t.getIdentityByActor(E.id))continue;t.createIdentity({actorId:E.id,username:d.username,email:d.email,emailVerified:!!d.email,passwordHash:d.passwordHash,requiresPasswordUpgrade:!0})}}function LB(t,e,r){let d=r.split("@")[0].toLowerCase().replace(/[^a-z0-9._-]/g,"-").replace(/^[^a-z0-9]+/,"").slice(0,24),E=/^[a-z0-9][a-z0-9._-]{1,31}$/.test(d)?d:"sso-user";if(!t.getIdentityByUsername(E)&&!wr(e,E))return E;let n=AB("sha256").update(r).digest("hex").slice(0,7);return`${E.slice(0,24)}-${n}`}function QU(t,e,r,d){if(d.provider.organizationId!==e.organization.id)throw Error("OIDC provider is not configured for this organization");let E=t.getOidcSubject(d.provider.id,d.subject),n=E?t.getIdentity(E.identityId):t.getIdentityByEmail(d.email);if(n?.disabledAt)throw Error("OIDC identity is disabled");if(!E&&n&&!n.emailVerifiedAt)throw Error("OIDC cannot automatically link an unverified local email address");let c=Ye(r),_=!1,T=n?wr(c,n.username):void 0;if(n&&!T)throw Error("OIDC identity has no dashboard user");if(!n){let R=LB(t,c,d.email);T=G_(r,{username:R,name:d.name,email:d.email,sites:{}}).user;let A=ie(e.store,T);n=t.createIdentity({actorId:A.id,username:T.username,email:d.email,emailVerified:!0,passwordHash:T.passwordHash}),_=!0}else if(n.email!==d.email)n=t.setVerifiedEmail(n.id,d.email);let i=e.store.getActor(n.actorId);if(!i)throw Error("OIDC identity actor was not found");let h=e.store.getMembershipForActor(e.organization.id,i.id);if(h?.status==="revoked")throw Error("OIDC organization membership is revoked");if(!h)e.store.createMembership({organizationId:e.organization.id,actorId:i.id,roleTemplate:d.provider.defaultRole,scope:{type:"organization"},source:"manual"});return t.linkOidcSubject(d.provider.id,n.id,d.subject,d.email),{identity:n,user:T,provisioned:_}}function YU(t,e,r){let d=e.store.getMembershipForActor(e.organization.id,r.actorId);if(!d||d.status!=="active"||d.roleTemplate==="owner"||!r.emailVerifiedAt||!r.email)return!1;let E=r.email.split("@")[1]?.toLowerCase();return t.listOidcProviders(e.organization.id).some((n)=>n.enforceSso&&!!E&&n.allowedDomains.includes(E))}function uB(t){return t.replace(/[&<>"']/g,(e)=>({"&":"&","<":"<",">":">",'"':""","'":"'"})[e])}function MU(t=!1,e=[]){let r=t?"/serverless":"/",d=e.map((n)=>`<a class="sso-button" href="/auth/oidc/${encodeURIComponent(n.slug)}/start?return=${encodeURIComponent(r)}">Continue with ${uB(n.name)}</a>`).join("");return`<!doctype html>
|
|
6313
6313
|
<html lang="en">
|
|
6314
6314
|
<head>
|
|
6315
6315
|
<meta charset="UTF-8">
|
|
@@ -6588,7 +6588,7 @@ EOF`,'echo "DISKPCT=${DISKPCT:-0}"','echo "DISKUSEDG=${DISKUSEDG:-0}"','echo "DI
|
|
|
6588
6588
|
</body>
|
|
6589
6589
|
</html>`}await Ht();var VU={info:()=>{},warn:()=>{},error:()=>{},step:()=>{},success:()=>{}};async function KU(t){return await t.driver.findComputeTargets({slug:t.slug,environment:t.environment,role:t.role||"app"})}async function ZU(t,e){let r=t.logger||VU,d=await KU(t);if(d.length===0)return{success:!1,error:`No '${t.role||"app"}' servers found for ${t.slug}/${t.environment}.`};let E=Id(t.slug,e.siteName),n=Ch(E,e.to||"unused"),c=["set -uo pipefail",...$f(n,{...e.to?{to:e.to}:{},unitBase:`${t.slug}-${e.siteName}`}),`(cd ${We} && pantry restart php-fpm) 2>/dev/null || true`,`(cd ${n.current} && eval "$(cd ${We} && pantry env 2>/dev/null)" && php artisan queue:restart) 2>/dev/null || true`];r.step(`Rolling back ${e.siteName}${e.to?` to ${e.to}`:" to the previous release"} on ${d.length} server(s)...`);let _=await t.driver.runRemoteDeploy({targets:d,commands:c,comment:`ts-cloud rollback ${t.slug}/${e.siteName}`,tags:{Project:t.slug,Environment:t.environment,Role:t.role||"app"}});if(!_.success)r.error(`Rollback failed: ${_.error||"unknown error"}`);else r.success(`Rolled back ${e.siteName}.`);return{success:_.success,error:_.error,perInstance:_.perInstance}}async function kU(t,e){let r=t.logger||VU;if(!e.database?.name)return{success:!1,error:"No appDatabase configured to restore."};let d=await KU(t);if(d.length===0)return{success:!1,error:`No '${t.role||"app"}' servers found for ${t.slug}/${t.environment}.`};r.step(`Restoring database '${e.database.name}'${e.from?` from ${e.from}`:" from the latest backup"} on ${d.length} server(s)...`);let E=await t.driver.runRemoteDeploy({targets:d,commands:tf(e.database,{from:e.from}),comment:`ts-cloud db:restore ${t.slug}/${e.database.name}`,tags:{Project:t.slug,Environment:t.environment,Role:t.role||"app"}});if(!E.success)r.error(`Restore failed: ${E.error||"unknown error"}`);else r.success(`Restored ${e.database.name}.`);return{success:E.success,error:E.error,perInstance:E.perInstance}}var OB=["restart","reload","start","stop","enable","disable"],bU=65536;function Uc(t){return t.length<=bU?t:`${t.slice(0,bU)}
|
|
6590
6590
|
|
|
6591
|
-
[output truncated]`}function CB(t){return/^[A-Za-z0-9_.@:-]+$/.test(t)}function vL(t){return/^[A-Za-z0-9_-]+$/.test(t)}function lB(t){return t.charAt(0).toUpperCase()+t.slice(1)}function Gh(t,e){let r=[],d=e.servicesDetail??e.services??[];for(let c of d){let _=String(c?.name??"");if(!_||!CB(_))continue;for(let T of OB)r.push({id:`${T}:${_}`,label:`${lB(T)} ${_}`,group:"service",target:_,mutates:!0,confirm:_,danger:T==="stop"||T==="disable"})}for(let[c,_]of Object.entries(t.sites??{})){if(!_||!vL(c))continue;let T=Ir(_);if(T==="server-app"||T==="server-php")r.push({id:`rollback:${c}`,label:`Rollback ${c}`,group:"deploy",target:c,mutates:!0,confirm:c,danger:!0})}let E=new Set;for(let c of e.workers??[]){let _=String(c?.name??"").split(":")[0];if(_&&vL(_))E.add(_)}for(let c of E)r.push({id:`worker:restart:${c}`,label:`Restart workers (${c})`,group:"worker",target:c,mutates:!0,confirm:c});for(let[c,_]of Object.entries(t.sites??{})){if(!_||!vL(c))continue;if(_.scheduler||_.schedule){let T=z_(_)==="laravel";r.push({id:`scheduler:run:${c}`,label:`${T?"Run":"Restart"} scheduler (${c})`,group:"scheduler",target:c,mutates:!0,confirm:c})}}if(t.infrastructure?.compute?.backups?.enabled){if(r.push({id:"backup:run",label:"Run backup now",group:"backup",target:"backup",mutates:!0,confirm:"backup"}),mt(t))r.push({id:"backup:restore",label:"Restore latest DB backup",group:"backup",target:"database",mutates:!0,confirm:"restore",danger:!0})}return r}function QL(t,e,r){return Gh(e,r).find((d)=>d.id===t)}function IB(t,e){let r=t==="enable"||t==="disable"?`systemctl is-enabled ${e} 2>/dev/null || true`:`systemctl is-active ${e} 2>/dev/null || true`;return["set -o pipefail",`systemctl ${t} ${e}`,r]}function DB(){return`eval "$(cd ${We} && pantry env 2>/dev/null)"`}function qU(t,e,r){let d=`${Id(t,e)}/current`;return["set -uo pipefail",`[ -d ${d} ] || { echo "site ${e} has no current release" >&2; exit 1; }`,`cd ${d} && ${DB()} && php artisan ${r}`]}function fB(t,e,r){if(t==="laravel")return qU(e,r,"queue:restart");let d=`${e}-${r}-queue-*.service`;return["set -uo pipefail",`units=$(systemctl list-units --type=service --all --no-legend '${d}' 2>/dev/null | awk '{print $1}')`,`[ -n "$units" ] || { echo "no queue-worker units found for ${r} (${d})" >&2; exit 1; }`,"systemctl restart $units",`systemctl --no-legend --type=service list-units '${d}' 2>/dev/null || true`]}function UB(t,e,r){if(t==="laravel")return qU(e,r,"schedule:run");let d=`${e}-${r}-scheduler.service`;return["set -uo pipefail",`systemctl restart ${d}`,`systemctl is-active ${d} 2>/dev/null || true`]}function wB(){return["set -uo pipefail",`[ -x ${Ec} ] || { echo "scheduled backups are not provisioned on this server" >&2; exit 1; }`,Ec]}function xU(t,e,r){return{operation:t,command:e,ok:r.success,stdout:Uc(r.perInstance?.[0]?.output??""),stderr:Uc(r.perInstance?.[0]?.error??r.error??"")}}async function Vh(t,e,r,d={}){let E=t.project.slug,n;try{n=Dr({config:t})}catch(R){return{operation:r.id,ok:!1,error:`Could not initialize the cloud driver: ${R?.message??R}`}}let c={driver:n,slug:E,environment:e,role:"app"};if(r.group==="deploy"){let R=d.to&&/^[A-Za-z0-9._-]+$/.test(d.to)?d.to:void 0,N=await ZU(c,{siteName:r.target,to:R});return xU(r.id,`rollback ${r.target}${R?` → ${R}`:""}`,N)}if(r.id==="backup:restore"){let R=await kU(c,{database:mt(t)});return xU(r.id,"db restore",R)}let _=await n.findComputeTargets({slug:E,environment:e,role:"app"});if(!_.length)return{operation:r.id,ok:!1,error:"No app server target was found for this environment."};let T,i;if(r.group==="service"){let[R,...N]=r.id.split(":");T=IB(R,N.join(":")),i=`systemctl ${R} ${r.target}`}else if(r.group==="worker"){let R=z_(t.sites?.[r.target]??{});T=fB(R,E,r.target),i=R==="laravel"?`queue:restart (${r.target})`:`restart queue units (${r.target})`}else if(r.group==="scheduler"){let R=z_(t.sites?.[r.target]??{});T=UB(R,E,r.target),i=R==="laravel"?`schedule:run (${r.target})`:`restart scheduler (${r.target})`}else if(r.id==="backup:run")T=wB(),i="ts-cloud backup";else return{operation:r.id,ok:!1,error:"Unknown operation."};let h=await n.runRemoteDeploy({targets:[_[0]],commands:T,comment:`ts-cloud dashboard:${r.id}`,tags:{Project:E,Environment:e,Role:"app"}});return{operation:r.id,command:i,ok:h.success,stdout:Uc(h.perInstance?.[0]?.output??""),stderr:Uc(h.perInstance?.[0]?.error??h.error??"")}}async function V_(t,e,r){let d=r.trim();if(!d)return{operation:"command",ok:!1,error:"A command is required."};let E;try{E=Dr({config:t})}catch(T){return{operation:"command",ok:!1,error:`Could not initialize the cloud driver: ${T?.message??T}`}}let n=t.project.slug,c=await E.findComputeTargets({slug:n,environment:e,role:"app"});if(!c.length)return{operation:"command",ok:!1,error:"No app server target was found for this environment."};let _=await E.runRemoteDeploy({targets:[c[0]],commands:["set -o pipefail",d],comment:"ts-cloud dashboard:command",tags:{Project:n,Environment:e,Role:"app"}});return{operation:"command",command:d,ok:_.success,stdout:Uc(_.perInstance?.[0]?.output??""),stderr:Uc(_.perInstance?.[0]?.error??_.error??"")}}var gB=[{id:"server.overview",path:"/",label:"Dashboard",group:"overview",modes:["server"],adminOnly:!0,legacyPaths:["/server"]},{id:"server.activity",path:"/server/activity",label:"Activity",group:"overview",modes:["server"],adminOnly:!0,legacyPaths:["/activity"]},{id:"services.list",path:"/server/sites",label:"Services",group:"applications",modes:["server"],adminOnly:!1,legacyPaths:["/sites","/services"]},{id:"deployments.list",path:"/server/deployments",label:"Deployments",group:"applications",modes:["server"],adminOnly:!1,legacyPaths:["/deployments"]},{id:"logs.list",path:"/server/logs",label:"Logs",group:"applications",modes:["server"],adminOnly:!1,legacyPaths:["/logs"]},{id:"sources.integrations",path:"/integrations",label:"Git integrations",group:"applications",modes:["server","serverless"],adminOnly:!1},{id:"applications.create",path:"/applications/new",label:"Create application",group:"applications",modes:["server","serverless"],adminOnly:!1},{id:"applications.compose",path:"/applications/compose",label:"Compose applications",group:"applications",modes:["server"],adminOnly:!1},{id:"operations.queue",path:"/operations/queue",label:"Deployment queue",group:"operations",modes:["server","serverless"],adminOnly:!1},{id:"operations.previews",path:"/operations/previews",label:"Preview environments",group:"operations",modes:["server","serverless"],adminOnly:!1},{id:"operations.releases",path:"/operations/releases",label:"Releases & promotion",group:"operations",modes:["server","serverless"],adminOnly:!1},{id:"runtime.workloads",path:"/operations/workloads",label:"Workloads",group:"operations",modes:["server","serverless"],adminOnly:!1},{id:"observability.overview",path:"/operations/observability",label:"Observability",group:"operations",modes:["server","serverless"],adminOnly:!1},{id:"alerts.overview",path:"/operations/alerts",label:"Alerts & health",group:"operations",modes:["server","serverless"],adminOnly:!1},{id:"automation.jobs",path:"/operations/jobs",label:"Workers & schedules",group:"operations",modes:["server","serverless"],adminOnly:!1,legacyPaths:["/server/workers","/serverless/scheduler"]},{id:"configuration.entries",path:"/operations/configuration",label:"Environment & secrets",group:"operations",modes:["server","serverless"],adminOnly:!1,legacyPaths:["/serverless/secrets"]},{id:"metrics.overview",path:"/server/metrics",label:"Metrics",group:"operations",modes:["server"],adminOnly:!0},{id:"runtime.services",path:"/server/services",label:"Runtime services",group:"operations",modes:["server"],adminOnly:!0},{id:"backups.list",path:"/data/backups",label:"Backups & recovery",group:"operations",modes:["server","serverless"],adminOnly:!1,legacyPaths:["/server/backups"]},{id:"volumes.list",path:"/data/volumes",label:"Persistent volumes",group:"operations",modes:["server","serverless"],adminOnly:!1,legacyPaths:[]},{id:"fleet.list",path:"/server/fleet",label:"Fleet inventory",group:"operations",modes:["server"],adminOnly:!1,legacyPaths:[]},{id:"operations.run",path:"/server/actions",label:"Run operations",group:"operations",modes:["server"],adminOnly:!0},{id:"data.services",path:"/data/services",label:"Data services",group:"infrastructure",modes:["server","serverless"],adminOnly:!1,legacyPaths:["/database","/databases","/server/database","/serverless/data"]},{id:"network.firewall",path:"/server/firewall",label:"Network & firewall",group:"infrastructure",modes:["server"],adminOnly:!0},{id:"security.posture",path:"/security",label:"Security posture",group:"infrastructure",modes:["server","serverless"],adminOnly:!1,legacyPaths:["/server/security"]},{id:"access.ssh",path:"/server/ssh-keys",label:"SSH keys",group:"infrastructure",modes:["server"],adminOnly:!0},{id:"runtime.terminal",path:"/server/terminal",label:"Terminal",group:"infrastructure",modes:["server"],adminOnly:!0},{id:"organization.people",path:"/server/team",label:"People & access",group:"organization",modes:["server","serverless"],adminOnly:!0,legacyPaths:["/team"]},{id:"organization.automation",path:"/account/automation",label:"API & automation",group:"organization",modes:["server","serverless"],adminOnly:!0},{id:"serverless.overview",path:"/serverless",label:"Dashboard",group:"overview",modes:["serverless"],adminOnly:!0},{id:"serverless.deployments",path:"/serverless/deployments",label:"Deployments",group:"overview",modes:["serverless"],adminOnly:!0},{id:"serverless.logs",path:"/serverless/logs",label:"Logs",group:"overview",modes:["serverless"],adminOnly:!0},{id:"serverless.metrics",path:"/serverless/metrics",label:"Metrics",group:"overview",modes:["serverless"],adminOnly:!0},{id:"serverless.traces",path:"/serverless/traces",label:"Traces",group:"overview",modes:["serverless"],adminOnly:!0},{id:"serverless.functions",path:"/serverless/functions",label:"Functions",group:"compute-data",modes:["serverless"],adminOnly:!0},{id:"serverless.queues",path:"/serverless/queues",label:"Queues",group:"compute-data",modes:["serverless"],adminOnly:!0},{id:"serverless.assets",path:"/serverless/assets",label:"Assets",group:"compute-data",modes:["serverless"],adminOnly:!0},{id:"serverless.network",path:"/serverless/firewall",label:"Network",group:"settings",modes:["serverless"],adminOnly:!0},{id:"serverless.alerts",path:"/serverless/alarms",label:"Alerts",group:"settings",modes:["serverless"],adminOnly:!0},{id:"serverless.cost",path:"/serverless/cost",label:"Costs",group:"settings",modes:["serverless"],adminOnly:!0}],$B=new Map(gB.flatMap((t)=>(t.legacyPaths??[]).map((e)=>[e,t.path])));function sU(t){return $B.get(t)}function yB(t,e){return[`${t}-${e}`,`${t}-${e}-queues`,`${t}-${e}-daemons`]}function oU(t,e,r){return r.some((d)=>yB(e,d).includes(t))}function YL(t,e){let{user:r,slug:d}=e;if(r.role==="admin")return t;let E=(t.sites??[]).map((u)=>u.name).filter(Boolean),n=CL(r,E),c=new Set(n),_=(t.sites??[]).filter((u)=>c.has(u.name)),T=(t.sitesDetail??[]).filter((u)=>c.has(u.name)),i=new Set(T.map((u)=>u.domain).filter(Boolean)),h=(t.serverDeploymentsDetail??t.serverDeployments??[]).filter((u)=>c.has(u.site)),R=(t.serverLogs??[]).filter((u)=>oU(u.source,d,n)),N=(t.security?.tlsCertificates??[]).filter((u)=>i.has(u.domain)),A=(t.activity??[]).filter((u)=>{if(u.type==="deploy")return n.some((f)=>String(u.title??"").startsWith(`${f} `));if(u.type==="log")return oU(String(u.title??"").split(" ")[0],d,n);return!1});return{mode:t.mode,environment:t.environment,environments:t.environments,scoped:!0,server:{name:""},sites:_,sitesDetail:T,workers:(t.workers??[]).filter((u)=>c.has(u.site)),serverDeployments:h.slice(0,5),serverDeploymentsDetail:h.slice(0,50),deploymentsEmptyReason:h.length?void 0:"No deployments have been recorded for your sites yet.",serverLogs:R,serverLogsEmptyReason:R.length?void 0:"No recent log entries for your sites.",security:{tlsCertificates:N,ports:[],firewall:null,authEvents:[]},diagnostics:(t.diagnostics??[]).filter((u)=>["Route conflicts","TLS certificates"].includes(u.name)),activity:A}}function mU(t,e){if(e.role==="admin")return t;let r=new Set(CL(e,Object.keys(t.sites??{})));return{project:{name:t.project?.name},environment:t.environment,environments:t.environments,sites:Object.fromEntries(Object.entries(t.sites??{}).filter(([d])=>r.has(d)))}}var XB=new Set(["name","ssl","env","redirects","aliases","domain","path"]),pU={build:"build runs as a shell command on the server",start:"start runs as a shell command on the server",root:"root is a filesystem path on the shared server",port:"ports are allocated by the server owner",type:"the deploy type is set by the server owner",php:"the PHP runtime is set by the server owner"};function ew(t){let e=Object.keys(t).filter((E)=>t[E]!==void 0),r=e.filter((E)=>(E in pU));if(r.length)return{ok:!1,error:`Only the server owner can change ${r.map((n)=>`${n} (${pU[n]})`).join(", ")}.`};let d=e.filter((E)=>!XB.has(E));if(d.length)return{ok:!1,error:`Only the server owner can change ${d.join(", ")}.`};return{ok:!0}}function Kh(t){return String(t??"").trim().toLowerCase().replace(/\.$/,"")}function tw(t){let e=String(t??"/").trim();if(!e||e==="/")return"/";return(e.startsWith("/")?e:`/${e}`).replace(/\/+$/,"")||"/"}function aB(t){let e=[Kh(t?.domain)];if(Array.isArray(t?.aliases))e.push(...t.aliases.map(Kh));return e.filter(Boolean)}function rw({siteName:t,body:e,sites:r,ownSites:d}){let E=r[t]??{},n=new Set(d),c=new Set;if(e.domain!==void 0)c.add(Kh(e.domain));if(Array.isArray(e.aliases))for(let T of e.aliases)c.add(Kh(T));if(c.delete(""),c.size===0)return{ok:!0};let _=tw(e.path!==void 0?e.path:E.path);for(let[T,i]of Object.entries(r)){if(T===t||n.has(T))continue;let h=tw(i?.path);for(let R of aB(i)){if(!c.has(R))continue;if(h===_)return{ok:!1,error:`${R}${_==="/"?"":_} is already served by another site on this server.`}}}return{ok:!0}}class K_{maxAttempts;lockoutMs;windowMs;attempts=new Map;constructor(t=8,e=900000,r=900000){this.maxAttempts=t;this.lockoutMs=e;this.windowMs=r}key(t,e){return`${t.trim().toLowerCase()}\x00${e}`}check(t,e,r=Date.now()){let d=this.attempts.get(this.key(t,e));if(!d?.until)return{allowed:!0};if(r>=d.until)return this.attempts.delete(this.key(t,e)),{allowed:!0};return{allowed:!1,retryAfterSeconds:Math.ceil((d.until-r)/1000)}}recordFailure(t,e,r=Date.now()){let d=this.key(t,e),E=this.attempts.get(d),c=!E||r-E.last>this.windowMs?1:E.count+1,_={count:c,last:r};if(c>=this.maxAttempts)_.until=r+this.lockoutMs;this.attempts.set(d,_)}recordSuccess(t,e){this.attempts.delete(this.key(t,e))}prune(t=Date.now()){for(let[e,r]of this.attempts)if(r.until?t>=r.until:t-r.last>this.windowMs)this.attempts.delete(e)}get size(){return this.attempts.size}}var Ew=new Set([22,80,443]);function Z_(t){return Number.isInteger(t)&&t>=1&&t<=65535}function tn(t){return[...new Set(t.filter((e)=>Z_(e)&&!Ew.has(e)))].sort((e,r)=>e-r)}function nw(t,e,r=[]){if(!Z_(e))throw Error("Port must be an integer between 1 and 65535.");if(Ew.has(e))throw Error(`Port ${e} (SSH/HTTP/HTTPS) is always open and is not managed here.`);return _w({configText:t,ports:tn([...r,e])})}function cw(t,e,r=[]){return _w({configText:t,ports:tn(r.filter((d)=>d!==e))})}function dw(t,e,r,d,E){let n=t.slice(e,r),c=new RegExp(`\\b${d}\\s*:\\s*\\${E}`).exec(n);if(!c)return null;let _=e+c.index,T=t.indexOf(E,_);return{propStart:_,open:T,close:Y_(t,T,E,E==="{"?"}":"]")}}function ML(t){return`allowedPorts: [${t.join(", ")}]`}function _w(t){let{configText:e}=t,r=tn(t.ports),d=/\bcompute\s*:\s*{/.exec(e);if(!d)throw Error("Could not find infrastructure.compute in the cloud config.");let E=e.indexOf("{",d.index),n=Y_(e,E,"{","}"),c=dw(e,E+1,n,"firewall","{");if(c){let h=dw(e,c.open+1,c.close,"allowedPorts","[");if(h){let u=h.propStart;while(u>0&&e[u-1]!==`
|
|
6591
|
+
[output truncated]`}function CB(t){return/^[A-Za-z0-9_.@:-]+$/.test(t)}function vL(t){return/^[A-Za-z0-9_-]+$/.test(t)}function lB(t){return t.charAt(0).toUpperCase()+t.slice(1)}function Gh(t,e){let r=[],d=e.servicesDetail??e.services??[];for(let c of d){let _=String(c?.name??"");if(!_||!CB(_))continue;for(let T of OB)r.push({id:`${T}:${_}`,label:`${lB(T)} ${_}`,group:"service",target:_,mutates:!0,confirm:_,danger:T==="stop"||T==="disable"})}for(let[c,_]of Object.entries(t.sites??{})){if(!_||!vL(c))continue;let T=Dr(_);if(T==="server-app"||T==="server-php")r.push({id:`rollback:${c}`,label:`Rollback ${c}`,group:"deploy",target:c,mutates:!0,confirm:c,danger:!0})}let E=new Set;for(let c of e.workers??[]){let _=String(c?.name??"").split(":")[0];if(_&&vL(_))E.add(_)}for(let c of E)r.push({id:`worker:restart:${c}`,label:`Restart workers (${c})`,group:"worker",target:c,mutates:!0,confirm:c});for(let[c,_]of Object.entries(t.sites??{})){if(!_||!vL(c))continue;if(_.scheduler||_.schedule){let T=z_(_)==="laravel";r.push({id:`scheduler:run:${c}`,label:`${T?"Run":"Restart"} scheduler (${c})`,group:"scheduler",target:c,mutates:!0,confirm:c})}}if(t.infrastructure?.compute?.backups?.enabled){if(r.push({id:"backup:run",label:"Run backup now",group:"backup",target:"backup",mutates:!0,confirm:"backup"}),mt(t))r.push({id:"backup:restore",label:"Restore latest DB backup",group:"backup",target:"database",mutates:!0,confirm:"restore",danger:!0})}return r}function QL(t,e,r){return Gh(e,r).find((d)=>d.id===t)}function IB(t,e){let r=t==="enable"||t==="disable"?`systemctl is-enabled ${e} 2>/dev/null || true`:`systemctl is-active ${e} 2>/dev/null || true`;return["set -o pipefail",`systemctl ${t} ${e}`,r]}function DB(){return`eval "$(cd ${We} && pantry env 2>/dev/null)"`}function qU(t,e,r){let d=`${Id(t,e)}/current`;return["set -uo pipefail",`[ -d ${d} ] || { echo "site ${e} has no current release" >&2; exit 1; }`,`cd ${d} && ${DB()} && php artisan ${r}`]}function fB(t,e,r){if(t==="laravel")return qU(e,r,"queue:restart");let d=`${e}-${r}-queue-*.service`;return["set -uo pipefail",`units=$(systemctl list-units --type=service --all --no-legend '${d}' 2>/dev/null | awk '{print $1}')`,`[ -n "$units" ] || { echo "no queue-worker units found for ${r} (${d})" >&2; exit 1; }`,"systemctl restart $units",`systemctl --no-legend --type=service list-units '${d}' 2>/dev/null || true`]}function UB(t,e,r){if(t==="laravel")return qU(e,r,"schedule:run");let d=`${e}-${r}-scheduler.service`;return["set -uo pipefail",`systemctl restart ${d}`,`systemctl is-active ${d} 2>/dev/null || true`]}function wB(){return["set -uo pipefail",`[ -x ${Ec} ] || { echo "scheduled backups are not provisioned on this server" >&2; exit 1; }`,Ec]}function xU(t,e,r){return{operation:t,command:e,ok:r.success,stdout:Uc(r.perInstance?.[0]?.output??""),stderr:Uc(r.perInstance?.[0]?.error??r.error??"")}}async function Vh(t,e,r,d={}){let E=t.project.slug,n;try{n=fr({config:t})}catch(R){return{operation:r.id,ok:!1,error:`Could not initialize the cloud driver: ${R?.message??R}`}}let c={driver:n,slug:E,environment:e,role:"app"};if(r.group==="deploy"){let R=d.to&&/^[A-Za-z0-9._-]+$/.test(d.to)?d.to:void 0,N=await ZU(c,{siteName:r.target,to:R});return xU(r.id,`rollback ${r.target}${R?` → ${R}`:""}`,N)}if(r.id==="backup:restore"){let R=await kU(c,{database:mt(t)});return xU(r.id,"db restore",R)}let _=await n.findComputeTargets({slug:E,environment:e,role:"app"});if(!_.length)return{operation:r.id,ok:!1,error:"No app server target was found for this environment."};let T,i;if(r.group==="service"){let[R,...N]=r.id.split(":");T=IB(R,N.join(":")),i=`systemctl ${R} ${r.target}`}else if(r.group==="worker"){let R=z_(t.sites?.[r.target]??{});T=fB(R,E,r.target),i=R==="laravel"?`queue:restart (${r.target})`:`restart queue units (${r.target})`}else if(r.group==="scheduler"){let R=z_(t.sites?.[r.target]??{});T=UB(R,E,r.target),i=R==="laravel"?`schedule:run (${r.target})`:`restart scheduler (${r.target})`}else if(r.id==="backup:run")T=wB(),i="ts-cloud backup";else return{operation:r.id,ok:!1,error:"Unknown operation."};let h=await n.runRemoteDeploy({targets:[_[0]],commands:T,comment:`ts-cloud dashboard:${r.id}`,tags:{Project:E,Environment:e,Role:"app"}});return{operation:r.id,command:i,ok:h.success,stdout:Uc(h.perInstance?.[0]?.output??""),stderr:Uc(h.perInstance?.[0]?.error??h.error??"")}}async function V_(t,e,r){let d=r.trim();if(!d)return{operation:"command",ok:!1,error:"A command is required."};let E;try{E=fr({config:t})}catch(T){return{operation:"command",ok:!1,error:`Could not initialize the cloud driver: ${T?.message??T}`}}let n=t.project.slug,c=await E.findComputeTargets({slug:n,environment:e,role:"app"});if(!c.length)return{operation:"command",ok:!1,error:"No app server target was found for this environment."};let _=await E.runRemoteDeploy({targets:[c[0]],commands:["set -o pipefail",d],comment:"ts-cloud dashboard:command",tags:{Project:n,Environment:e,Role:"app"}});return{operation:"command",command:d,ok:_.success,stdout:Uc(_.perInstance?.[0]?.output??""),stderr:Uc(_.perInstance?.[0]?.error??_.error??"")}}var gB=[{id:"server.overview",path:"/",label:"Dashboard",group:"overview",modes:["server"],adminOnly:!0,legacyPaths:["/server"]},{id:"server.activity",path:"/server/activity",label:"Activity",group:"overview",modes:["server"],adminOnly:!0,legacyPaths:["/activity"]},{id:"services.list",path:"/server/sites",label:"Services",group:"applications",modes:["server"],adminOnly:!1,legacyPaths:["/sites","/services"]},{id:"deployments.list",path:"/server/deployments",label:"Deployments",group:"applications",modes:["server"],adminOnly:!1,legacyPaths:["/deployments"]},{id:"logs.list",path:"/server/logs",label:"Logs",group:"applications",modes:["server"],adminOnly:!1,legacyPaths:["/logs"]},{id:"sources.integrations",path:"/integrations",label:"Git integrations",group:"applications",modes:["server","serverless"],adminOnly:!1},{id:"applications.create",path:"/applications/new",label:"Create application",group:"applications",modes:["server","serverless"],adminOnly:!1},{id:"applications.compose",path:"/applications/compose",label:"Compose applications",group:"applications",modes:["server"],adminOnly:!1},{id:"operations.queue",path:"/operations/queue",label:"Deployment queue",group:"operations",modes:["server","serverless"],adminOnly:!1},{id:"operations.previews",path:"/operations/previews",label:"Preview environments",group:"operations",modes:["server","serverless"],adminOnly:!1},{id:"operations.releases",path:"/operations/releases",label:"Releases & promotion",group:"operations",modes:["server","serverless"],adminOnly:!1},{id:"runtime.workloads",path:"/operations/workloads",label:"Workloads",group:"operations",modes:["server","serverless"],adminOnly:!1},{id:"observability.overview",path:"/operations/observability",label:"Observability",group:"operations",modes:["server","serverless"],adminOnly:!1},{id:"alerts.overview",path:"/operations/alerts",label:"Alerts & health",group:"operations",modes:["server","serverless"],adminOnly:!1},{id:"automation.jobs",path:"/operations/jobs",label:"Workers & schedules",group:"operations",modes:["server","serverless"],adminOnly:!1,legacyPaths:["/server/workers","/serverless/scheduler"]},{id:"configuration.entries",path:"/operations/configuration",label:"Environment & secrets",group:"operations",modes:["server","serverless"],adminOnly:!1,legacyPaths:["/serverless/secrets"]},{id:"metrics.overview",path:"/server/metrics",label:"Metrics",group:"operations",modes:["server"],adminOnly:!0},{id:"runtime.services",path:"/server/services",label:"Runtime services",group:"operations",modes:["server"],adminOnly:!0},{id:"backups.list",path:"/data/backups",label:"Backups & recovery",group:"operations",modes:["server","serverless"],adminOnly:!1,legacyPaths:["/server/backups"]},{id:"volumes.list",path:"/data/volumes",label:"Persistent volumes",group:"operations",modes:["server","serverless"],adminOnly:!1,legacyPaths:[]},{id:"fleet.list",path:"/server/fleet",label:"Fleet inventory",group:"operations",modes:["server"],adminOnly:!1,legacyPaths:[]},{id:"operations.run",path:"/server/actions",label:"Run operations",group:"operations",modes:["server"],adminOnly:!0},{id:"data.services",path:"/data/services",label:"Data services",group:"infrastructure",modes:["server","serverless"],adminOnly:!1,legacyPaths:["/database","/databases","/server/database","/serverless/data"]},{id:"network.firewall",path:"/server/firewall",label:"Network & firewall",group:"infrastructure",modes:["server"],adminOnly:!0},{id:"security.posture",path:"/security",label:"Security posture",group:"infrastructure",modes:["server","serverless"],adminOnly:!1,legacyPaths:["/server/security"]},{id:"access.ssh",path:"/server/ssh-keys",label:"SSH keys",group:"infrastructure",modes:["server"],adminOnly:!0},{id:"runtime.terminal",path:"/server/terminal",label:"Terminal",group:"infrastructure",modes:["server"],adminOnly:!0},{id:"organization.people",path:"/server/team",label:"People & access",group:"organization",modes:["server","serverless"],adminOnly:!0,legacyPaths:["/team"]},{id:"organization.automation",path:"/account/automation",label:"API & automation",group:"organization",modes:["server","serverless"],adminOnly:!0},{id:"serverless.overview",path:"/serverless",label:"Dashboard",group:"overview",modes:["serverless"],adminOnly:!0},{id:"serverless.deployments",path:"/serverless/deployments",label:"Deployments",group:"overview",modes:["serverless"],adminOnly:!0},{id:"serverless.logs",path:"/serverless/logs",label:"Logs",group:"overview",modes:["serverless"],adminOnly:!0},{id:"serverless.metrics",path:"/serverless/metrics",label:"Metrics",group:"overview",modes:["serverless"],adminOnly:!0},{id:"serverless.traces",path:"/serverless/traces",label:"Traces",group:"overview",modes:["serverless"],adminOnly:!0},{id:"serverless.functions",path:"/serverless/functions",label:"Functions",group:"compute-data",modes:["serverless"],adminOnly:!0},{id:"serverless.queues",path:"/serverless/queues",label:"Queues",group:"compute-data",modes:["serverless"],adminOnly:!0},{id:"serverless.assets",path:"/serverless/assets",label:"Assets",group:"compute-data",modes:["serverless"],adminOnly:!0},{id:"serverless.network",path:"/serverless/firewall",label:"Network",group:"settings",modes:["serverless"],adminOnly:!0},{id:"serverless.alerts",path:"/serverless/alarms",label:"Alerts",group:"settings",modes:["serverless"],adminOnly:!0},{id:"serverless.cost",path:"/serverless/cost",label:"Costs",group:"settings",modes:["serverless"],adminOnly:!0}],$B=new Map(gB.flatMap((t)=>(t.legacyPaths??[]).map((e)=>[e,t.path])));function sU(t){return $B.get(t)}function yB(t,e){return[`${t}-${e}`,`${t}-${e}-queues`,`${t}-${e}-daemons`]}function oU(t,e,r){return r.some((d)=>yB(e,d).includes(t))}function YL(t,e){let{user:r,slug:d}=e;if(r.role==="admin")return t;let E=(t.sites??[]).map((u)=>u.name).filter(Boolean),n=CL(r,E),c=new Set(n),_=(t.sites??[]).filter((u)=>c.has(u.name)),T=(t.sitesDetail??[]).filter((u)=>c.has(u.name)),i=new Set(T.map((u)=>u.domain).filter(Boolean)),h=(t.serverDeploymentsDetail??t.serverDeployments??[]).filter((u)=>c.has(u.site)),R=(t.serverLogs??[]).filter((u)=>oU(u.source,d,n)),N=(t.security?.tlsCertificates??[]).filter((u)=>i.has(u.domain)),A=(t.activity??[]).filter((u)=>{if(u.type==="deploy")return n.some((f)=>String(u.title??"").startsWith(`${f} `));if(u.type==="log")return oU(String(u.title??"").split(" ")[0],d,n);return!1});return{mode:t.mode,environment:t.environment,environments:t.environments,scoped:!0,server:{name:""},sites:_,sitesDetail:T,workers:(t.workers??[]).filter((u)=>c.has(u.site)),serverDeployments:h.slice(0,5),serverDeploymentsDetail:h.slice(0,50),deploymentsEmptyReason:h.length?void 0:"No deployments have been recorded for your sites yet.",serverLogs:R,serverLogsEmptyReason:R.length?void 0:"No recent log entries for your sites.",security:{tlsCertificates:N,ports:[],firewall:null,authEvents:[]},diagnostics:(t.diagnostics??[]).filter((u)=>["Route conflicts","TLS certificates"].includes(u.name)),activity:A}}function mU(t,e){if(e.role==="admin")return t;let r=new Set(CL(e,Object.keys(t.sites??{})));return{project:{name:t.project?.name},environment:t.environment,environments:t.environments,sites:Object.fromEntries(Object.entries(t.sites??{}).filter(([d])=>r.has(d)))}}var XB=new Set(["name","ssl","env","redirects","aliases","domain","path"]),pU={build:"build runs as a shell command on the server",start:"start runs as a shell command on the server",root:"root is a filesystem path on the shared server",port:"ports are allocated by the server owner",type:"the deploy type is set by the server owner",php:"the PHP runtime is set by the server owner"};function ew(t){let e=Object.keys(t).filter((E)=>t[E]!==void 0),r=e.filter((E)=>(E in pU));if(r.length)return{ok:!1,error:`Only the server owner can change ${r.map((n)=>`${n} (${pU[n]})`).join(", ")}.`};let d=e.filter((E)=>!XB.has(E));if(d.length)return{ok:!1,error:`Only the server owner can change ${d.join(", ")}.`};return{ok:!0}}function Kh(t){return String(t??"").trim().toLowerCase().replace(/\.$/,"")}function tw(t){let e=String(t??"/").trim();if(!e||e==="/")return"/";return(e.startsWith("/")?e:`/${e}`).replace(/\/+$/,"")||"/"}function aB(t){let e=[Kh(t?.domain)];if(Array.isArray(t?.aliases))e.push(...t.aliases.map(Kh));return e.filter(Boolean)}function rw({siteName:t,body:e,sites:r,ownSites:d}){let E=r[t]??{},n=new Set(d),c=new Set;if(e.domain!==void 0)c.add(Kh(e.domain));if(Array.isArray(e.aliases))for(let T of e.aliases)c.add(Kh(T));if(c.delete(""),c.size===0)return{ok:!0};let _=tw(e.path!==void 0?e.path:E.path);for(let[T,i]of Object.entries(r)){if(T===t||n.has(T))continue;let h=tw(i?.path);for(let R of aB(i)){if(!c.has(R))continue;if(h===_)return{ok:!1,error:`${R}${_==="/"?"":_} is already served by another site on this server.`}}}return{ok:!0}}class K_{maxAttempts;lockoutMs;windowMs;attempts=new Map;constructor(t=8,e=900000,r=900000){this.maxAttempts=t;this.lockoutMs=e;this.windowMs=r}key(t,e){return`${t.trim().toLowerCase()}\x00${e}`}check(t,e,r=Date.now()){let d=this.attempts.get(this.key(t,e));if(!d?.until)return{allowed:!0};if(r>=d.until)return this.attempts.delete(this.key(t,e)),{allowed:!0};return{allowed:!1,retryAfterSeconds:Math.ceil((d.until-r)/1000)}}recordFailure(t,e,r=Date.now()){let d=this.key(t,e),E=this.attempts.get(d),c=!E||r-E.last>this.windowMs?1:E.count+1,_={count:c,last:r};if(c>=this.maxAttempts)_.until=r+this.lockoutMs;this.attempts.set(d,_)}recordSuccess(t,e){this.attempts.delete(this.key(t,e))}prune(t=Date.now()){for(let[e,r]of this.attempts)if(r.until?t>=r.until:t-r.last>this.windowMs)this.attempts.delete(e)}get size(){return this.attempts.size}}var Ew=new Set([22,80,443]);function Z_(t){return Number.isInteger(t)&&t>=1&&t<=65535}function tn(t){return[...new Set(t.filter((e)=>Z_(e)&&!Ew.has(e)))].sort((e,r)=>e-r)}function nw(t,e,r=[]){if(!Z_(e))throw Error("Port must be an integer between 1 and 65535.");if(Ew.has(e))throw Error(`Port ${e} (SSH/HTTP/HTTPS) is always open and is not managed here.`);return _w({configText:t,ports:tn([...r,e])})}function cw(t,e,r=[]){return _w({configText:t,ports:tn(r.filter((d)=>d!==e))})}function dw(t,e,r,d,E){let n=t.slice(e,r),c=new RegExp(`\\b${d}\\s*:\\s*\\${E}`).exec(n);if(!c)return null;let _=e+c.index,T=t.indexOf(E,_);return{propStart:_,open:T,close:Y_(t,T,E,E==="{"?"}":"]")}}function ML(t){return`allowedPorts: [${t.join(", ")}]`}function _w(t){let{configText:e}=t,r=tn(t.ports),d=/\bcompute\s*:\s*{/.exec(e);if(!d)throw Error("Could not find infrastructure.compute in the cloud config.");let E=e.indexOf("{",d.index),n=Y_(e,E,"{","}"),c=dw(e,E+1,n,"firewall","{");if(c){let h=dw(e,c.open+1,c.close,"allowedPorts","[");if(h){let u=h.propStart;while(u>0&&e[u-1]!==`
|
|
6592
6592
|
`&&/\s/.test(e[u-1]))u--;let f=e.slice(u,h.propStart);return`${e.slice(0,u)}${f}${ML(r)}${e.slice(h.close+1)}`}let R=e.slice(0,c.close).trimEnd(),N=e.slice(c.close),A=R.endsWith(",")||R.endsWith("{")?"":",";return`${R}${A}
|
|
6593
6593
|
${ML(r)},
|
|
6594
6594
|
${N}`}let _=e.slice(0,n).trimEnd(),T=e.slice(n),i=_.endsWith(",")||_.endsWith("{")?"":",";return`${_}${i}
|
|
@@ -6642,9 +6642,9 @@ ${T}`);return null}return d}catch(E){if(d)dn(d,{recursive:!0,force:!0});if(proce
|
|
|
6642
6642
|
Saved (hashed) to ${FU()}. This password is shown once.
|
|
6643
6643
|
`)}else console.warn(" ts-cloud dashboard: authentication is DISABLED (TS_CLOUD_DASHBOARD_AUTH=0). Every request runs as an admin.");let Xd=r!=="127.0.0.1"&&r!=="localhost",dR=(C)=>VB("sha256").update(`${x}:${C}`).digest("hex").slice(0,16),Tg=yS({controlPlane:c.store,identities:Rt,sources:m,applications:{drafts:te,artifacts:ge,registries:qe}}),Iu=(C)=>C.headers.get("user-agent")?.trim().slice(0,256)||void 0,tT=(C,p,Tt,s="local")=>Q.createSession({identityId:C,authMethod:s,userAgent:Iu(p),networkHint:dR(Tt)}),nt=(C)=>{let p=c.store.getActorByExternalId("user",`dashboard:${C.username.toLowerCase()}`),Tt=p?c.store.getMembershipForActor(c.organization.id,p.id):void 0;return{actor:p,membership:Tt,grants:Tt?c.store.listGrants(Tt.id):[]}},En=(C,p,Tt)=>{if(C.role==="admin")return!0;let s=c.store.getOperation(p),Nt=nt(C);if(!s||!Nt.membership)return!1;let Jt=s.resourceId?{type:"resource",id:s.resourceId}:s.environmentId?{type:"environment",id:s.environmentId}:s.projectId?{type:"project",id:s.projectId}:{type:"organization"},U=c.store.resolveAuthorizationTarget(c.organization.id,Jt);return!!U&&Ve({membership:Nt.membership,grants:Nt.grants,capability:Tt,target:U}).allowed},Le=(C,p,Tt)=>{if(C.role==="admin")return!0;let s=nt(C);if(!s.membership)return!1;let Nt=c.store.resolveAuthorizationTarget(c.organization.id,{type:"resource",id:p});return!!Nt&&Ve({membership:s.membership,grants:s.grants,capability:Tt,target:Nt}).allowed},Xc=(C,p,Tt)=>{if(C.role==="admin")return!0;let s=nt(C);if(!s.membership)return!1;let Nt=c.store.resolveAuthorizationTarget(c.organization.id,{type:"environment",id:p});return!!Nt&&Ve({membership:s.membership,grants:s.grants,capability:Tt,target:Nt}).allowed},nn=Bun.serve({hostname:r,port:d,idleTimeout:30,websocket:{open(C){if(!$){C.send(`The web terminal is disabled (TS_CLOUD_DASHBOARD_TERMINAL=0).\r
|
|
6644
6644
|
`),C.close();return}let p=Qw((Tt)=>C.send(Tt),{cwd:e,onExit:()=>{try{C.close()}catch{}}});ft.set(C,p),C.send(`Connected to ${r==="127.0.0.1"?"localhost":r} shell. This is a line-oriented shell (no full-screen apps).\r
|
|
6645
|
-
`)},message(C,p){ft.get(C)?.write(typeof p==="string"?p:new TextDecoder().decode(p))},close(C){ft.get(C)?.close(),ft.delete(C)}},async fetch(C,p){let Tt=Date.now(),s=C.clone(),Nt=C.headers.get("x-request-id")?.slice(0,128)||crypto.randomUUID(),Jt=!["GET","HEAD","OPTIONS"].includes(C.method.toUpperCase()),U=new URL(C.url),ot=await(async()=>{let Ct=p??nn,Dt=nJ(r,Ct.port??d),ue=await Tg(C,dR(Ct.requestIP(C)?.address??"unknown"));if(ue)return ue;let he=U.searchParams.get("env"),V=_J(_,T,he),Vt=R.get(V);if(!Vt)Vt=await a(V);try{if(!RJ(C))return O({ok:!1,error:"Cross-site requests are not allowed."},403);let hE=/^\/api\/source\/webhooks\/([A-Za-z0-9_-]{16,200})$/.exec(U.pathname);if(hE&&C.method==="POST"){let S=await N0({sources:m,controlPlane:c.store,endpointToken:hE[1],headers:C.headers,rawBody:new Uint8Array(await C.arrayBuffer())});return O({accepted:S.accepted,duplicate:S.duplicate,status:S.status,operationIds:S.operations.map((L)=>L.id),message:S.message},S.accepted?202:404)}let cn=/^\/auth\/oidc\/([a-z0-9-]+)\/(start|callback)$/.exec(U.pathname);if(cn&&C.method==="GET"){let[,S,L]=cn;if(!Dt)return new Response(null,{status:302,headers:{location:"/login?sso_error=configuration"}});if(L==="start")try{let l=await MS(Q,S,Dt,U.searchParams.get("return")??void 0,t.oidcFetch);return new Response(null,{status:302,headers:{location:l.authorizationUrl,"cache-control":"no-store"}})}catch(l){return c.store.appendEvent({organizationId:c.organization.id,type:"auth.oidc.start_failed",level:"warning",payload:{provider:S,reason:l instanceof Error?l.message.slice(0,200):"unknown"}}),new Response(null,{status:302,headers:{location:"/login?sso_error=start","cache-control":"no-store"}})}try{if(U.searchParams.has("error")){let X=Q.getOidcProviderBySlug(S),y=U.searchParams.get("state");if(X&&y)Q.consumeOidcTransaction(X.id,y);throw Error("OIDC provider returned an authorization error")}let l=await GS(Q,{providerSlug:S,state:U.searchParams.get("state")??"",code:U.searchParams.get("code")??"",origin:Dt},t.oidcFetch),D=QU(Q,c,e,l.identity);Q.recordLogin(D.identity.id);let g=tT(D.identity.id,C,Ct.requestIP(C)?.address??"unknown","oidc");return q(),c.store.appendEvent({organizationId:c.organization.id,actorId:D.identity.actorId,type:"auth.login.succeeded",payload:{method:"oidc",provider:S,provisioned:D.provisioned}}),new Response(null,{status:302,headers:{location:l.returnPath,"cache-control":"no-store","set-cookie":Dc(g.token,{secure:Xd,maxAgeMs:Qd})}})}catch(l){return c.store.appendEvent({organizationId:c.organization.id,type:"auth.oidc.callback_failed",level:"warning",payload:{provider:S,reason:l instanceof Error?l.message.slice(0,200):"unknown"}}),new Response(null,{status:302,headers:{location:"/login?sso_error=callback","cache-control":"no-store"}})}}if(U.pathname==="/api/invitations/accept"&&C.method==="POST"){let S=await v(C),L=String(S.token??"").trim(),l=String(S.username??"").trim(),D=String(S.password??"");if(!L||!Qh(l)||D.length<12)return O({ok:!1,error:"Invitation token, valid username, and a password of at least 12 characters are required."},422);let g=c.store.inspectInvitationToken(L);if(!g||g.state!=="pending")return O({ok:!1,error:g?`Invitation is ${g.state}`:"Invitation is invalid"},g?409:404);let X=
|
|
6645
|
+
`)},message(C,p){ft.get(C)?.write(typeof p==="string"?p:new TextDecoder().decode(p))},close(C){ft.get(C)?.close(),ft.delete(C)}},async fetch(C,p){let Tt=Date.now(),s=C.clone(),Nt=C.headers.get("x-request-id")?.slice(0,128)||crypto.randomUUID(),Jt=!["GET","HEAD","OPTIONS"].includes(C.method.toUpperCase()),U=new URL(C.url),ot=await(async()=>{let Ct=p??nn,Dt=nJ(r,Ct.port??d),ue=await Tg(C,dR(Ct.requestIP(C)?.address??"unknown"));if(ue)return ue;let he=U.searchParams.get("env"),V=_J(_,T,he),Vt=R.get(V);if(!Vt)Vt=await a(V);try{if(!RJ(C))return O({ok:!1,error:"Cross-site requests are not allowed."},403);let hE=/^\/api\/source\/webhooks\/([A-Za-z0-9_-]{16,200})$/.exec(U.pathname);if(hE&&C.method==="POST"){let S=await N0({sources:m,controlPlane:c.store,endpointToken:hE[1],headers:C.headers,rawBody:new Uint8Array(await C.arrayBuffer())});return O({accepted:S.accepted,duplicate:S.duplicate,status:S.status,operationIds:S.operations.map((L)=>L.id),message:S.message},S.accepted?202:404)}let cn=/^\/auth\/oidc\/([a-z0-9-]+)\/(start|callback)$/.exec(U.pathname);if(cn&&C.method==="GET"){let[,S,L]=cn;if(!Dt)return new Response(null,{status:302,headers:{location:"/login?sso_error=configuration"}});if(L==="start")try{let l=await MS(Q,S,Dt,U.searchParams.get("return")??void 0,t.oidcFetch);return new Response(null,{status:302,headers:{location:l.authorizationUrl,"cache-control":"no-store"}})}catch(l){return c.store.appendEvent({organizationId:c.organization.id,type:"auth.oidc.start_failed",level:"warning",payload:{provider:S,reason:l instanceof Error?l.message.slice(0,200):"unknown"}}),new Response(null,{status:302,headers:{location:"/login?sso_error=start","cache-control":"no-store"}})}try{if(U.searchParams.has("error")){let X=Q.getOidcProviderBySlug(S),y=U.searchParams.get("state");if(X&&y)Q.consumeOidcTransaction(X.id,y);throw Error("OIDC provider returned an authorization error")}let l=await GS(Q,{providerSlug:S,state:U.searchParams.get("state")??"",code:U.searchParams.get("code")??"",origin:Dt},t.oidcFetch),D=QU(Q,c,e,l.identity);Q.recordLogin(D.identity.id);let g=tT(D.identity.id,C,Ct.requestIP(C)?.address??"unknown","oidc");return q(),c.store.appendEvent({organizationId:c.organization.id,actorId:D.identity.actorId,type:"auth.login.succeeded",payload:{method:"oidc",provider:S,provisioned:D.provisioned}}),new Response(null,{status:302,headers:{location:l.returnPath,"cache-control":"no-store","set-cookie":Dc(g.token,{secure:Xd,maxAgeMs:Qd})}})}catch(l){return c.store.appendEvent({organizationId:c.organization.id,type:"auth.oidc.callback_failed",level:"warning",payload:{provider:S,reason:l instanceof Error?l.message.slice(0,200):"unknown"}}),new Response(null,{status:302,headers:{location:"/login?sso_error=callback","cache-control":"no-store"}})}}if(U.pathname==="/api/invitations/accept"&&C.method==="POST"){let S=await v(C),L=String(S.token??"").trim(),l=String(S.username??"").trim(),D=String(S.password??"");if(!L||!Qh(l)||D.length<12)return O({ok:!1,error:"Invitation token, valid username, and a password of at least 12 characters are required."},422);let g=c.store.inspectInvitationToken(L);if(!g||g.state!=="pending")return O({ok:!1,error:g?`Invitation is ${g.state}`:"Invitation is invalid"},g?409:404);let X=wr(Ye(e),l),y=Q.getIdentityByUsername(l);if(X&&!Hr(D,y?.passwordHash??X.passwordHash))return O({ok:!1,error:"That username already exists; enter its current password to continue."},401);let z=Q.getIdentityByEmail(g.email);if(z&&z.id!==y?.id)return O({ok:!1,error:"This invitation belongs to an existing account. Sign in with that account or ask an owner to resend it."},409);let M=G_(e,{username:l,password:X?void 0:D,name:typeof S.name==="string"?S.name:void 0,email:g.email,sites:X?.sites??{}}),b=ie(c.store,M.user);try{let wt=c.store.acceptInvitation(L,b.id),k=y?Q.setVerifiedEmail(y.id,wt.invitation.email):Q.createIdentity({actorId:b.id,username:M.user.username,email:wt.invitation.email,emailVerified:!0,passwordHash:M.user.passwordHash}),_t=tT(k.id,C,Ct.requestIP(C)?.address??"unknown");return q(),O({ok:!0,user:fc(M.user),organization:c.organization,membership:wt.membership},200,{"set-cookie":Dc(_t.token,{secure:Xd,maxAgeMs:Qd})})}catch(wt){if(!X)WL(e,M.user.username);let k=wt instanceof Error?wt.message:"Invitation could not be accepted.";return O({ok:!1,error:k},k.includes("expired")||k.includes("revoked")||k.includes("accepted")?409:404)}}if(U.pathname==="/api/auth/password-reset/request"&&C.method==="POST"){let S=await v(C),L=String(S.identifier??"").trim().toLowerCase(),l=Ct.requestIP(C)?.address??"unknown",D=rR.check(L,l),g=L.includes("@")?Q.getIdentityByEmail(L):Q.getIdentityByUsername(L);if(D.allowed)rR.recordFailure(L,l);if(D.allowed&&g?.email&&g.emailVerifiedAt&&!g.disabledAt){Q.revokeActionTokens(g.id,"password_reset");let X=Q.createActionToken(g.id,"password_reset"),y=`${U.origin}/reset-password?token=${encodeURIComponent(X.token)}`,z=await c_(n,{to:g.email,subject:"Reset your ts-cloud password",text:`Reset your ts-cloud password: ${y}
|
|
6646
6646
|
|
|
6647
|
-
This link expires in one hour and can be used once.`});c.store.appendEvent({organizationId:c.organization.id,actorId:g.actorId,type:"auth.password_reset.requested",payload:{delivered:z}})}return O({ok:!0,message:"If that account has a verified email, a reset link has been sent."},202)}if(U.pathname==="/api/auth/password-reset/complete"&&C.method==="POST"){let S=await v(C),L=String(S.token??"").trim(),l=String(S.password??"");if(!L||l.length<12)return O({ok:!1,error:"A valid reset token and password of at least 12 characters are required."},422);try{let D=Q.consumeActionToken(L,"password_reset"),g=EE(l),X=Q.updatePassword(D.identityId,g);return Mh(e,X.username,g),c.store.appendEvent({organizationId:c.organization.id,actorId:X.actorId,type:"auth.password_reset.completed"}),O({ok:!0,message:"Password changed. Sign in again."},200,{"set-cookie":vh({secure:Xd})})}catch(D){let g=D instanceof Error?D.message:"Password reset failed.";return O({ok:!1,error:g.replace("Action token","Reset link")},g.includes("consumed")||g.includes("expired")?409:404)}}if(U.pathname==="/api/login"&&C.method==="POST"){let S=await v(C),L=String(S.username??"").trim(),l=String(S.password??""),D=Ct.requestIP(C)?.address??"unknown",g=m_.check(L,D);if(!g.allowed)return O({ok:!1,error:`Too many failed attempts. Try again in ${Math.ceil((g.retryAfterSeconds??0)/60)} minute(s).`},429,{"retry-after":String(g.retryAfterSeconds??60)});let X=Ur(Ye(e),L),y=Q.getIdentityByUsername(L),z=y?.passwordHash??X?.passwordHash??EJ;if(!(Hr(l,z)&&!!X&&!!y&&!y.disabledAt))return m_.recordFailure(L,D),O({ok:!1,error:"Incorrect username or password."},401);if(YU(Q,c,y))return O({ok:!1,error:"Single sign-on is required for this account."},403);m_.recordSuccess(L,D);let b=y,wt=b.requiresPasswordUpgrade||Zf(b.passwordHash);if(wt){let _t=EE(l);b=Q.rehashPassword(b.id,_t),Mh(e,b.username,_t)}if(Q.recordLogin(b.id),Q.getMfaFactor(b.id)?.state==="active"){let _t=Q.createMfaChallenge(b.id,"login");return c.store.appendEvent({organizationId:c.organization.id,actorId:b.actorId,type:"auth.mfa.challenge.created",payload:{purpose:"login"}}),O({ok:!0,mfaRequired:!0,challengeToken:_t.token,passwordUpgraded:wt})}let k=tT(b.id,C,D);return c.store.appendEvent({organizationId:c.organization.id,actorId:b.actorId,type:"auth.login.succeeded",payload:{method:"local"}}),O({ok:!0,user:fc(X),passwordUpgraded:wt},200,{"set-cookie":Dc(k.token,{secure:Xd,maxAgeMs:Qd})})}if(U.pathname==="/api/auth/mfa/complete"&&C.method==="POST"){let S=await v(C),L=String(S.challengeToken??"").trim(),l=String(S.code??"").trim(),D=Ct.requestIP(C)?.address??"unknown",X=Q.inspectMfaChallengeToken(L,"login")?.identityId??"unknown-mfa",y=p_.check(X,D);if(!y.allowed)return O({ok:!1,error:"Too many MFA attempts. Try again later."},429,{"retry-after":String(y.retryAfterSeconds??60)});try{let z=Q.completeMfaChallenge(L,l,"login");p_.recordSuccess(X,D);let M=new Date().toISOString(),b=Q.createSession({identityId:z.identity.id,userAgent:Iu(C),networkHint:dR(D),mfaAt:M,recentAuthAt:M});return c.store.appendEvent({organizationId:c.organization.id,actorId:z.identity.actorId,type:"auth.mfa.succeeded",payload:{purpose:"login",method:z.method}}),O({ok:!0},200,{"set-cookie":Dc(b.token,{secure:Xd,maxAgeMs:Qd})})}catch{return p_.recordFailure(X,D),O({ok:!1,error:"Authenticator or recovery code is incorrect."},401)}}if(U.pathname==="/api/logout"&&C.method==="POST"){let S=kt.resolveSession(C);if(S)Q.revokeSession(S.identityId,S.id);let L=vh({secure:Xd});if(C.headers.get("accept")?.includes("text/html"))return new Response(null,{status:302,headers:{location:"/login","set-cookie":L}});return O({ok:!0},200,{"set-cookie":L})}if(U.pathname==="/login"){let S=Q.listOidcProviders(c.organization.id).map((L)=>({slug:L.slug,name:L.name}));return new Response(MU(h?.mode==="serverless",S),{headers:{"content-type":"text/html; charset=utf-8"}})}if(U.pathname==="/forgot-password"||U.pathname==="/reset-password")return new Response(GU(U.pathname==="/reset-password"?"reset":"request"),{headers:{"content-type":"text/html; charset=utf-8"}});if(U.pathname==="/accept-invitation")return xw(It,U.pathname);let Y=kt.resolveUser(C);if(!Y){if(!U.pathname.startsWith("/api/")&&C.headers.get("accept")?.includes("text/html"))return new Response(null,{status:302,headers:{location:"/login"}});return O({ok:!1,error:"Sign in to continue."},401)}let Tr=tt(Y,V);if(U.pathname==="/api/me"){let S=c.store.getActorByExternalId("user",`dashboard:${Y.username.toLowerCase()}`),L=S?c.store.getMembershipForActor(c.organization.id,S.id):void 0,l=c.store.resolveAuthorizationTarget(c.organization.id,L?.scope??{type:"project",id:c.project.id})??c.store.resolveAuthorizationTarget(c.organization.id,{type:"project",id:c.project.id});return O({ok:!0,user:fc(Y),authEnabled:G,organization:c.organization,membership:L,capabilities:un({membership:L,grants:L?c.store.listGrants(L.id):[],target:l})})}if(U.pathname.startsWith("/api/")){let S=await WU(C,U.pathname),L=kt.check(C,U.pathname,Y,S);if(!L.ok)return O({ok:!1,error:L.error},L.status??403);if(G&&AJ.has(`${C.method.toUpperCase()} ${U.pathname}`)){let l=kt.resolveSession(C);if(!l||!Q.isRecentlyAuthenticated(l))return O({ok:!1,error:"Recent authentication is required for this change.",stepUpRequired:!0},401)}}if(U.pathname==="/api/auth/security"&&C.method==="GET"){let S=nt(Y),L=S.actor?Q.getIdentityByActor(S.actor.id):void 0,l=kt.resolveSession(C);return O({identity:L?{username:L.username,email:L.email,emailVerifiedAt:L.emailVerifiedAt,requiresPasswordUpgrade:L.requiresPasswordUpgrade,lastLoginAt:L.lastLoginAt}:void 0,currentSessionId:l?.id,sessions:L?Q.listSessions(L.id,{includeInactive:!0}):[],mfa:L?{factor:Q.getMfaFactor(L.id),recoveryCodesRemaining:Q.remainingRecoveryCodes(L.id)}:void 0})}if(U.pathname==="/api/auth/oidc/providers"&&C.method==="GET")return O({providers:Q.listOidcProviders(c.organization.id,{includeDisabled:!0}),callbackOrigin:Dt,callbackPattern:Dt?`${Dt}/auth/oidc/{slug}/callback`:void 0,localOwnerRecovery:!0});if(U.pathname==="/api/auth/oidc/providers"&&C.method==="POST"){let S=await v(C),L=nt(Y),l=L.actor?Q.getIdentityByActor(L.actor.id):void 0,D=S.enforceSso===!0;if(D&&(!l?.emailVerifiedAt||Q.remainingRecoveryCodes(l.id)<1))return O({ok:!1,error:"Verify the owner email and generate MFA recovery codes before enforcing SSO."},409);try{let g=bh(S.defaultRole),X=Q.upsertOidcProvider({id:typeof S.id==="string"?S.id:void 0,organizationId:c.organization.id,slug:String(S.slug??""),name:String(S.name??""),issuer:String(S.issuer??""),clientId:String(S.clientId??""),clientSecret:typeof S.clientSecret==="string"&&S.clientSecret?S.clientSecret:void 0,scopes:Array.isArray(S.scopes)?S.scopes.map(String):void 0,allowedDomains:Array.isArray(S.allowedDomains)?S.allowedDomains.map(String):[],defaultRole:g&&g!=="owner"?g:void 0,enabled:S.enabled!==!1,enforceSso:D});return c.store.appendEvent({organizationId:c.organization.id,actorId:L.actor?.id,type:"auth.oidc.provider.configured",payload:{providerId:X.id,issuer:X.issuer,enabled:X.enabled,enforceSso:X.enforceSso}}),O({ok:!0,provider:X})}catch(g){return O({ok:!1,error:g instanceof Error?g.message:"OIDC provider could not be saved."},422)}}if(U.pathname==="/api/auth/oidc/providers"&&C.method==="PATCH"){let S=await v(C),L=Q.getOidcProvider(String(S.id??""));if(!L||L.organizationId!==c.organization.id)return O({ok:!1,error:"OIDC provider was not found."},404);let l=nt(Y),D=Q.setOidcProviderEnabled(L.id,S.enabled===!0);return c.store.appendEvent({organizationId:c.organization.id,actorId:l.actor?.id,type:D.enabled?"auth.oidc.provider.enabled":"auth.oidc.provider.disabled",payload:{providerId:L.id}}),O({ok:!0,provider:D})}if(U.pathname==="/api/automation"&&C.method==="GET"){let S=Rt.listServiceAccounts(c.organization.id,{includeDisabled:!0}).map((L)=>{let l=c.store.getMembershipForActor(c.organization.id,L.actorId),D=L.createdByActorId?c.store.getActor(L.createdByActorId):void 0,g=Rt.listTokens(L.id,{includeInactive:!0}).map((X)=>({...X,createdBy:X.createdByActorId?c.store.getActor(X.createdByActorId):void 0}));return{account:L,createdBy:D,membership:l,tokens:g}});return O({accounts:S,apiBaseUrl:`${U.origin}/api/v1`,openApiUrl:`${U.origin}/api/v1/openapi.json`,tokenEnvironmentVariable:"TS_CLOUD_API_TOKEN"})}if(U.pathname==="/api/automation/service-accounts"&&C.method==="POST"){let S=await v(C),L=nt(Y),l=bh(S.roleTemplate),D=b_(S);if(!L.actor||!l||l==="owner"||!D)return O({ok:!1,error:"A non-owner role and valid organization scope are required."},422);try{let g=Rt.createServiceAccount({organizationId:c.organization.id,slug:String(S.slug??""),name:String(S.name??""),description:typeof S.description==="string"?S.description:void 0,roleTemplate:l,scope:D,createdByActorId:L.actor.id});return O({ok:!0,...g},201)}catch(g){return O({ok:!1,error:g instanceof Error?g.message:"Service account could not be created."},422)}}if(U.pathname==="/api/automation/service-accounts"&&C.method==="PATCH"){let S=await v(C),L=nt(Y),l=Rt.getServiceAccount(String(S.id??""));if(!l||l.organizationId!==c.organization.id)return O({ok:!1,error:"Service account was not found."},404);return O({ok:!0,account:Rt.disableServiceAccount(l.id,L.actor?.id)})}if(U.pathname==="/api/automation/tokens"&&C.method==="POST"){let S=await v(C),L=nt(Y),l=Rt.getServiceAccount(String(S.serviceAccountId??"")),D=b_(S);if(!L.actor||!l||l.organizationId!==c.organization.id||!D||!Array.isArray(S.capabilities))return O({ok:!1,error:"Service account, explicit capabilities, and valid scope are required."},422);try{let g=Rt.createToken({serviceAccountId:l.id,name:String(S.name??"API token"),capabilities:S.capabilities.map(String),scope:D,expiresAt:typeof S.expiresAt==="string"?S.expiresAt:void 0,createdByActorId:L.actor.id});return O({ok:!0,token:g.token,secret:g.secret,revealOnce:!0},201)}catch(g){return O({ok:!1,error:g instanceof Error?g.message:"API token could not be created."},422)}}if(U.pathname==="/api/automation/tokens/rotate"&&C.method==="POST"){let S=await v(C),L=nt(Y),l=Rt.getToken(String(S.id??"")),D=l?Rt.getServiceAccount(l.serviceAccountId):void 0;if(!L.actor||!l||D?.organizationId!==c.organization.id)return O({ok:!1,error:"API token was not found."},404);try{let g=Rt.rotateToken(l.id,L.actor.id);return O({ok:!0,token:g.token,secret:g.secret,revealOnce:!0,overlap:!0},201)}catch(g){return O({ok:!1,error:g instanceof Error?g.message:"API token could not be rotated."},409)}}if(U.pathname==="/api/automation/tokens"&&C.method==="DELETE"){let S=await v(C),L=nt(Y),l=Rt.getToken(String(S.id??"")),D=l?Rt.getServiceAccount(l.serviceAccountId):void 0;if(!l||D?.organizationId!==c.organization.id)return O({ok:!1,error:"API token was not found."},404);return O({ok:!0,token:Rt.revokeToken(l.id,L.actor?.id)})}if(U.pathname==="/api/onboarding"&&C.method==="GET"){let S=m.listConnections(c.organization.id);return O({drafts:te.list(c.project.id),artifacts:ge.list(c.project.id),registries:qe.list(c.organization.id),sourceConnections:S,repositories:S.flatMap((L)=>m.listRepositories(L.id)),project:{id:c.project.id,slug:c.project.slug,name:c.project.name},environments:[...c.environments.values()].map((L)=>({id:L.id,slug:L.slug,name:L.name,kind:L.kind,region:L.region})),resources:c.store.listResources(c.project.id).filter((L)=>L.kind==="application").map((L)=>({id:L.id,slug:L.slug,name:L.name,environmentId:L.environmentId}))})}if(U.pathname==="/api/onboarding/detect"&&C.method==="POST"){let S=await v(C);try{if(S.source?.kind==="git"){let D=m.getConnection(String(S.source.connectionId??"")),g=m.getRepository(String(S.source.repositoryId??""));if(!D||D.organizationId!==c.organization.id||!g||g.connectionId!==D.id)throw Error("Authorized Git repository was not found");let X=typeof S.source.deployKeyId==="string"?m.getDeployKey(S.source.deployKeyId):void 0;if(X&&X.connectionId!==D.id)throw Error("Deploy key does not belong to this connection");let y=eu(Wt(qh(),"ts-cloud-onboarding-git-"));try{let z=await fS({remote:g.cloneUrl,destination:Wt(y,"checkout"),ref:String(S.source.ref??g.defaultBranch),sparsePaths:Array.isArray(S.source.sparsePaths)?S.source.sparsePaths.map(String):void 0,binding:{id:"detection",projectId:c.project.id,connectionId:D.id,repositoryId:g.id,repositoryFullName:g.fullName,defaultBranch:g.defaultBranch,monorepoRoot:String(S.source.monorepoRoot??"."),includePaths:[],excludePaths:[],submodules:S.source.submodules===!0,cloneDepth:1,deployKeyId:X?.id,autoDeploy:!1,pullRequestPreviews:!1,status:"active",version:1,createdAt:new Date().toISOString(),updatedAt:new Date().toISOString()}},{credential:m.getCredential(D.id),deployKey:X?{...X,privateKey:m.getDeployPrivateKey(X.id)}:void 0,timeoutMs:120000});return O({ok:!0,commitSha:z.commitSha,candidates:gn(ES(z.directory))})}finally{dn(y,{recursive:!0,force:!0})}}if(Array.isArray(S.files)){if(S.files.length>1e4)throw Error("Detection file-count limit exceeded");let D=S.files.map((g)=>({path:String(g.path??""),size:Number(g.size??0),content:typeof g.content==="string"?g.content.slice(0,262144):void 0}));return O({ok:!0,candidates:gn(D)})}let L=bB(e,String(S.root??".")),l=kB(e,L);if(l===".."||l.startsWith(`..${xB}`))throw Error("Detection root must stay inside the project");return O({ok:!0,candidates:gn(ES(L))})}catch(L){return O({ok:!1,error:L instanceof Error?L.message:"Application detection failed."},422)}}if(U.pathname==="/api/onboarding/plan"&&C.method==="POST"){let S=await v(C);try{return O({ok:!0,plan:$r(S.draft,Array.isArray(S.suppliedSecretNames)?S.suppliedSecretNames.map(String):[])})}catch(L){return O({ok:!1,error:L instanceof Error?L.message:"Application plan could not be generated."},422)}}if(U.pathname==="/api/onboarding/drafts"&&C.method==="POST"){let S=await v(C),L=nt(Y);try{return O({ok:!0,draft:te.create({organizationId:c.organization.id,projectId:c.project.id,name:String(S.name??S.draft?.name??"Application draft"),draft:{...S.draft,projectId:c.project.id},step:S.step,suppliedSecretNames:Array.isArray(S.suppliedSecretNames)?S.suppliedSecretNames.map(String):[],actorId:L.actor?.id})},201)}catch(l){return O({ok:!1,error:l instanceof Error?l.message:"Application draft could not be saved."},422)}}if(U.pathname==="/api/onboarding/drafts"&&C.method==="PATCH"){let S=await v(C),L=nt(Y),l=te.get(String(S.id??""));if(!l||l.projectId!==c.project.id)return O({ok:!1,error:"Application draft was not found."},404);try{return O({ok:!0,draft:te.update(l.id,Number(S.version),{draft:{...S.draft,projectId:c.project.id},step:S.step,suppliedSecretNames:Array.isArray(S.suppliedSecretNames)?S.suppliedSecretNames.map(String):void 0,actorId:L.actor?.id})})}catch(D){return O({ok:!1,error:D instanceof Error?D.message:"Application draft could not be updated."},409)}}if(U.pathname==="/api/onboarding/artifacts"&&C.method==="POST"){let S=nt(Y);if(Number(C.headers.get("content-length")??0)>104857600)return O({ok:!1,error:"Artifact exceeds the 100 MB upload limit."},413);try{let l=new Uint8Array(await C.arrayBuffer());return O({ok:!0,artifact:ge.create({organizationId:c.organization.id,projectId:c.project.id,filename:C.headers.get("x-artifact-filename")??"application.zip",bytes:l,actorId:S.actor?.id})},201)}catch(l){return O({ok:!1,error:l instanceof Error?l.message:"Artifact could not be inspected."},422)}}if(U.pathname==="/api/onboarding/registries"&&C.method==="POST"){let S=await v(C),L=nt(Y);try{return O({ok:!0,registry:qe.create({organizationId:c.organization.id,provider:S.provider,name:String(S.name??"Container registry"),host:String(S.host??""),credential:S.token||S.password?{username:typeof S.username==="string"?S.username:void 0,password:typeof S.password==="string"?S.password:void 0,token:typeof S.token==="string"?S.token:void 0}:void 0,credentialExpiresAt:typeof S.credentialExpiresAt==="string"?S.credentialExpiresAt:void 0,actorId:L.actor?.id})},201)}catch(l){return O({ok:!1,error:l instanceof Error?l.message:"Registry connection could not be created."},422)}}if(U.pathname==="/api/onboarding/registries"&&C.method==="PATCH"){let S=await v(C),L=nt(Y),l=qe.get(String(S.id??""));if(!l||l.organizationId!==c.organization.id)return O({ok:!1,error:"Registry connection was not found."},404);try{if(S.action==="test")return O({ok:!0,registry:await qe.test(l.id,{image:typeof S.image==="string"?S.image:void 0})});if(S.action==="rotate")return O({ok:!0,registry:qe.rotate(l.id,{username:typeof S.username==="string"?S.username:void 0,password:typeof S.password==="string"?S.password:void 0,token:typeof S.token==="string"?S.token:void 0},{expiresAt:typeof S.expiresAt==="string"?S.expiresAt:void 0,actorId:L.actor?.id})});return O({ok:!1,error:"Registry action must be test or rotate."},422)}catch(D){return O({ok:!1,error:D instanceof Error?D.message:"Registry connection could not be updated."},422)}}if(U.pathname==="/api/onboarding/registries"&&C.method==="DELETE"){let S=await v(C),L=nt(Y),l=qe.get(String(S.id??""));if(!l||l.organizationId!==c.organization.id)return O({ok:!1,error:"Registry connection was not found."},404);let D=te.list(c.project.id).filter((g)=>g.input.source.kind==="image"&&g.input.source.registryConnectionId===l.id||g.input.build.kind==="prebuilt_image"&&g.input.build.registryConnectionId===l.id);if(S.preview===!0)return O({ok:!0,preview:!0,affectedDrafts:D});return O({ok:!0,registry:qe.disconnect(l.id,L.actor?.id),affectedDrafts:D})}if(U.pathname==="/api/onboarding/apply"&&C.method==="POST"){let S=await v(C),L=nt(Y);try{let l=BT({controlPlane:c.store,drafts:te,draftId:String(S.id??""),expectedVersion:Number(S.version),confirmEnvironment:String(S.confirmEnvironment??""),actorId:L.actor?.id});return O({ok:!0,resource:l.resource,operation:l.operation,plan:l.plan},202)}catch(l){return O({ok:!1,error:l instanceof Error?l.message:"Application plan could not be applied."},422)}}if(U.pathname==="/api/sources"&&C.method==="GET"){let S=m.listConnections(c.organization.id);return O({connections:S,bindings:m.listBindings({projectId:c.project.id}),repositories:S.flatMap((L)=>m.listRepositories(L.id)),deployKeys:S.flatMap((L)=>m.listDeployKeys(L.id)),webhooks:S.flatMap((L)=>m.listWebhooks(L.id)).map((L)=>({...L,deliveries:m.listDeliveries(L.id,20)})),project:{id:c.project.id,slug:c.project.slug},environment:Jr(c,String(V)),resources:c.store.listResources(c.project.id,Jr(c,String(V)).environmentId).filter((L)=>L.kind==="application").map((L)=>({id:L.id,slug:L.slug,name:L.name}))})}if(U.pathname==="/api/sources/connections"&&C.method==="POST"){let S=await v(C),L=nt(Y),l=String(S.provider??"");if(!["github","gitlab","bitbucket","gitea","generic_https","generic_ssh"].includes(l))return O({ok:!1,error:"A supported Git provider is required."},422);try{let D=l==="github"&&(S.privateKey||S.appId)?{appId:typeof S.appId==="string"?S.appId:void 0,installationId:typeof S.installationId==="string"?S.installationId:void 0,privateKey:typeof S.privateKey==="string"?S.privateKey:void 0}:l!=="generic_ssh"&&S.token?{token:typeof S.token==="string"?S.token:void 0,username:typeof S.username==="string"?S.username:void 0}:void 0,g={github:"https://github.com",gitlab:"https://gitlab.com",bitbucket:"https://bitbucket.org",gitea:"https://gitea.com"},X,y,z;if(c.store.database.transaction(()=>{if(X=m.createConnection({organizationId:c.organization.id,provider:l,name:String(S.name??l),host:String(S.host??g[l]??""),owner:typeof S.owner==="string"?S.owner:void 0,authKind:S.authKind,credential:D,grantedScopes:Array.isArray(S.grantedScopes)?S.grantedScopes.map(String):[],credentialExpiresAt:typeof S.credentialExpiresAt==="string"?S.credentialExpiresAt:void 0,createdByActorId:L.actor?.id}),typeof S.repositoryUrl==="string"&&typeof S.repositoryFullName==="string")y=m.upsertRepository({connectionId:X.id,providerRepositoryId:`manual:${S.repositoryFullName}`,fullName:S.repositoryFullName,cloneUrl:S.repositoryUrl,defaultBranch:String(S.defaultBranch??"main"),visibility:"unknown",archived:!1,metadata:{source:"manual"}});if(l==="generic_ssh")z=m.createDeployKey({connectionId:X.id,name:String(S.deployKeyName??"Repository deploy key"),publicKey:String(S.publicKey??""),privateKey:String(S.deployPrivateKey??""),host:String(S.sshHost??""),hostKey:String(S.hostKey??""),actorId:L.actor?.id})})(),S.test===!0)X=await US(m,X.id,y?.id);return O({ok:!0,connection:X,repository:y,deployKey:z},201)}catch(D){return O({ok:!1,error:D instanceof Error?D.message:"Source connection could not be created."},422)}}if(U.pathname==="/api/sources/connections"&&C.method==="PATCH"){let S=await v(C),L=nt(Y),l=m.getConnection(String(S.id??""));if(!l||l.organizationId!==c.organization.id)return O({ok:!1,error:"Source connection was not found."},404);try{if(S.action==="test")return O({ok:!0,connection:await US(m,l.id,typeof S.repositoryId==="string"?S.repositoryId:void 0)});if(S.action==="rotate")return O({ok:!0,connection:m.rotateCredential(l.id,{token:typeof S.token==="string"?S.token:void 0,username:typeof S.username==="string"?S.username:void 0,appId:typeof S.appId==="string"?S.appId:void 0,installationId:typeof S.installationId==="string"?S.installationId:void 0,privateKey:typeof S.privateKey==="string"?S.privateKey:void 0},{expiresAt:typeof S.expiresAt==="string"?S.expiresAt:void 0,actorId:L.actor?.id})});return O({ok:!1,error:"Connection action must be test or rotate."},422)}catch(D){return O({ok:!1,error:D instanceof Error?D.message:"Source connection could not be updated."},422)}}if(U.pathname==="/api/sources/connections"&&C.method==="DELETE"){let S=await v(C),L=nt(Y),l=m.getConnection(String(S.id??""));if(!l||l.organizationId!==c.organization.id)return O({ok:!1,error:"Source connection was not found."},404);let D=m.listBindings({connectionId:l.id,status:"active"});if(S.preview===!0)return O({ok:!0,preview:!0,affectedBindings:D});return O({ok:!0,...m.disconnectConnection(l.id,L.actor?.id)})}if(U.pathname==="/api/sources/deploy-keys"&&C.method==="POST"){let S=await v(C),L=nt(Y),l=m.getConnection(String(S.connectionId??""));if(!l||l.organizationId!==c.organization.id)return O({ok:!1,error:"Source connection was not found."},404);try{return O({ok:!0,deployKey:m.createDeployKey({connectionId:l.id,name:String(S.name??"Repository deploy key"),publicKey:String(S.publicKey??""),privateKey:String(S.privateKey??""),host:String(S.host??""),hostKey:String(S.hostKey??""),actorId:L.actor?.id})},201)}catch(D){return O({ok:!1,error:D instanceof Error?D.message:"Deploy key could not be stored."},422)}}if(U.pathname==="/api/sources/deploy-keys"&&C.method==="DELETE"){let S=await v(C),L=nt(Y),l=m.getDeployKey(String(S.id??"")),D=l?m.getConnection(l.connectionId):void 0;if(!l||!D||D.organizationId!==c.organization.id)return O({ok:!1,error:"Deploy key was not found."},404);let g=m.listBindings({connectionId:D.id}).filter((X)=>X.deployKeyId===l.id);if(S.preview===!0)return O({ok:!0,preview:!0,affectedBindings:g});return O({ok:!0,...m.revokeDeployKey(l.id,L.actor?.id)})}if(U.pathname==="/api/sources/repositories/sync"&&C.method==="POST"){let S=await v(C),L=m.getConnection(String(S.connectionId??""));if(!L||L.organizationId!==c.organization.id)return O({ok:!1,error:"Source connection was not found."},404);try{return O({ok:!0,repositories:await vT(m,String(S.connectionId??""),{search:typeof S.search==="string"?S.search:void 0})})}catch(l){return O({ok:!1,error:l instanceof Error?l.message:"Repositories could not be synchronized."},422)}}if(U.pathname==="/api/sources/references"&&C.method==="GET"){let S=m.getConnection(String(U.searchParams.get("connectionId")??""));if(!S||S.organizationId!==c.organization.id)return O({ok:!1,error:"Source connection was not found."},404);try{return O(await QT(m,{connectionId:String(U.searchParams.get("connectionId")??""),repository:String(U.searchParams.get("repository")??""),repositoryId:U.searchParams.get("repositoryId")??void 0,deployKeyId:U.searchParams.get("deployKeyId")??void 0,type:U.searchParams.get("type")==="tags"?"tags":"branches",cursor:U.searchParams.get("cursor")??void 0}))}catch(L){return O({ok:!1,error:L instanceof Error?L.message:"References could not be listed."},422)}}if(U.pathname==="/api/sources/bindings"&&C.method==="POST"){let S=await v(C),L=nt(Y),l=Jr(c,String(V)),D=m.getConnection(String(S.connectionId??""));if(!D||D.organizationId!==c.organization.id)return O({ok:!1,error:"Source connection was not found."},404);try{return O({ok:!0,binding:m.createBinding({projectId:c.project.id,environmentId:l.environmentId,resourceId:typeof S.resourceId==="string"?S.resourceId:void 0,connectionId:String(S.connectionId??""),repositoryId:typeof S.repositoryId==="string"?S.repositoryId:void 0,repositoryFullName:String(S.repositoryFullName??""),defaultBranch:String(S.defaultBranch??"main"),branchRule:typeof S.branchRule==="string"?S.branchRule:void 0,tagRule:typeof S.tagRule==="string"?S.tagRule:void 0,monorepoRoot:String(S.monorepoRoot??"."),includePaths:Array.isArray(S.includePaths)?S.includePaths.map(String):[],excludePaths:Array.isArray(S.excludePaths)?S.excludePaths.map(String):[],submodules:S.submodules===!0,cloneDepth:S.cloneDepth?Number(S.cloneDepth):void 0,deployKeyId:typeof S.deployKeyId==="string"&&S.deployKeyId?S.deployKeyId:void 0,autoDeploy:S.autoDeploy!==!1,pullRequestPreviews:S.pullRequestPreviews!==!1,actorId:L.actor?.id})},201)}catch(g){return O({ok:!1,error:g instanceof Error?g.message:"Source binding could not be created."},422)}}if(U.pathname==="/api/sources/bindings"&&C.method==="PATCH"){let S=await v(C),L=nt(Y),l=m.getBinding(String(S.id??""));if(!l||l.projectId!==c.project.id)return O({ok:!1,error:"Source binding was not found."},404);try{return O({ok:!0,binding:m.updateBinding(l.id,Number(S.version),{defaultBranch:S.defaultBranch,branchRule:S.branchRule,tagRule:S.tagRule,monorepoRoot:S.monorepoRoot,includePaths:S.includePaths,excludePaths:S.excludePaths,submodules:S.submodules,cloneDepth:S.cloneDepth,deployKeyId:S.deployKeyId,autoDeploy:S.autoDeploy,pullRequestPreviews:S.pullRequestPreviews,status:S.status,disabledReason:S.disabledReason,actorId:L.actor?.id})})}catch(D){return O({ok:!1,error:D instanceof Error?D.message:"Source binding could not be updated."},409)}}if(U.pathname==="/api/sources/webhooks"&&C.method==="POST"){let S=await v(C),L=m.getConnection(String(S.connectionId??""));if(!L||L.organizationId!==c.organization.id)return O({ok:!1,error:"Source connection was not found."},404);try{let l=m.createWebhook({connectionId:String(S.connectionId??""),repositoryId:typeof S.repositoryId==="string"?S.repositoryId:void 0,repositoryFullName:String(S.repositoryFullName??""),events:Array.isArray(S.events)?S.events.map(String):void 0,secret:typeof S.secret==="string"?S.secret:void 0}),D=process.env.TS_CLOUD_WEBHOOK_BASE_URL?.trim()||Dt,g=D?Xn(D,l.webhook):void 0,X=S.reconcile!==!1&&D?await e_(m,l.webhook.id,D):l.webhook;return O({ok:!0,webhook:X,endpoint:g,endpointRevealOnce:!0},201)}catch(l){return O({ok:!1,error:l instanceof Error?l.message:"Source webhook could not be created."},422)}}if(U.pathname==="/api/sources/webhooks"&&C.method==="PATCH"){let S=await v(C),L=process.env.TS_CLOUD_WEBHOOK_BASE_URL?.trim()||Dt,l=m.getWebhook(String(S.id??"")),D=l?m.getConnection(l.connectionId):void 0;if(!l||!D||D.organizationId!==c.organization.id)return O({ok:!1,error:"Source webhook was not found."},404);if(!L)return O({ok:!1,error:"Set TS_CLOUD_WEBHOOK_BASE_URL to reconcile provider webhooks."},422);try{return O({ok:!0,webhook:await e_(m,String(S.id??""),L)})}catch(g){return O({ok:!1,error:g instanceof Error?g.message:"Source webhook could not be reconciled."},422)}}if(U.pathname==="/api/sources/webhooks"&&C.method==="DELETE"){let S=await v(C),L=m.getWebhook(String(S.id??"")),l=L?m.getConnection(L.connectionId):void 0;if(!L||!l||l.organizationId!==c.organization.id)return O({ok:!1,error:"Source webhook was not found."},404);try{return O({ok:!0,webhook:await C0(m,String(S.id??""))})}catch(D){return O({ok:!1,error:D instanceof Error?D.message:"Source webhook could not be removed."},422)}}if(U.pathname==="/api/security/posture"&&C.method==="GET"){let S=Jr(c,String(V)),L=ct.listFindings({...S,limit:500});return O({scope:S,summary:ct.summary(S.organizationId,S.projectId,S.environmentId),findings:L,scans:ct.listScanRuns({...S,limit:100}),policies:ct.listPolicies(S.organizationId).filter((l)=>!l.environmentId||l.environmentId===S.environmentId),waivers:L.flatMap((l)=>ct.listWaivers(l.id)),decisions:ct.listDecisions(S.environmentId,50),actors:c.store.listMemberships(c.organization.id).map((l)=>c.store.getActor(l.actorId)).filter(Boolean)})}if(U.pathname==="/api/security/export"&&C.method==="GET")return O(ct.exportPosture(c.organization.id));if(U.pathname==="/api/security/scan"&&C.method==="POST"){let S=Jr(c,String(V)),L=await new Ac(ct).run(new J_,{...S,artifactRoot:e}),l=gh(ct,S,Vt??{});return O({ok:!0,source:L,host:l,summary:ct.summary(S.organizationId,S.projectId,S.environmentId)})}if(U.pathname==="/api/security/review"&&C.method==="POST")try{let S=Jr(c,String(V));return O({ok:!0,...$h(ct,{scope:S,desiredConfigHash:c.project.desiredConfigHash})})}catch(S){return O({ok:!1,error:S instanceof Error?S.message:"Security change review failed."},409)}if(U.pathname==="/api/security/policies"&&C.method==="POST"){let S=await v(C),L=nt(Y);if(!L.actor)return O({ok:!1,error:"An organization actor is required."},403);try{let l=ct.createPolicy({organizationId:c.organization.id,environmentId:S.environmentId===null?void 0:String(S.environmentId??Jr(c,String(V)).environmentId),name:String(S.name??""),scannerFailMode:S.scannerFailMode==="open"?"open":"closed",requiredScanners:Array.isArray(S.requiredScanners)?S.requiredScanners.map(String):[],rules:Array.isArray(S.rules)?S.rules.map((D)=>({minimumSeverity:String(D.minimumSeverity),action:String(D.action),scannerId:D.scannerId?String(D.scannerId):void 0})):[],actorId:L.actor.id});return O({ok:!0,policy:l},201)}catch(l){return O({ok:!1,error:l instanceof Error?l.message:"Security policy could not be created."},422)}}if(U.pathname==="/api/security/policies"&&C.method==="PATCH"){let S=await v(C),L=nt(Y),l=ct.getPolicy(String(S.id??""));if(!L.actor||!l||l.organizationId!==c.organization.id)return O({ok:!1,error:"Security policy was not found."},404);try{return O({ok:!0,policy:ct.updatePolicy(l.id,Number(S.version),{name:typeof S.name==="string"?S.name:void 0,scannerFailMode:S.scannerFailMode==="open"||S.scannerFailMode==="closed"?S.scannerFailMode:void 0,requiredScanners:Array.isArray(S.requiredScanners)?S.requiredScanners.map(String):void 0,rules:Array.isArray(S.rules)?S.rules.map((D)=>({minimumSeverity:String(D.minimumSeverity),action:String(D.action),scannerId:D.scannerId?String(D.scannerId):void 0})):void 0,enabled:typeof S.enabled==="boolean"?S.enabled:void 0,actorId:L.actor.id})})}catch(D){return O({ok:!1,error:D instanceof Error?D.message:"Security policy could not be updated."},409)}}if(U.pathname==="/api/security/waivers"&&C.method==="POST"){let S=await v(C),L=nt(Y);if(!L.actor)return O({ok:!1,error:"An organization actor is required."},403);try{return O({ok:!0,waiver:ct.createWaiver({findingId:String(S.findingId??""),policyId:typeof S.policyId==="string"?S.policyId:void 0,reason:String(S.reason??""),referenceUrl:typeof S.referenceUrl==="string"?S.referenceUrl:void 0,expiresAt:String(S.expiresAt??""),actorId:L.actor.id})},201)}catch(l){return O({ok:!1,error:l instanceof Error?l.message:"Security waiver could not be created."},422)}}if(U.pathname==="/api/security/waivers"&&C.method==="DELETE"){let S=await v(C),L=nt(Y);if(!L.actor)return O({ok:!1,error:"An organization actor is required."},403);try{return O({ok:!0,waiver:ct.revokeWaiver(String(S.id??""),L.actor.id)})}catch(l){return O({ok:!1,error:l instanceof Error?l.message:"Security waiver could not be revoked."},404)}}if(U.pathname==="/api/security/findings"&&C.method==="PATCH"){let S=await v(C),L=nt(Y),l=ct.getFinding(String(S.id??""));if(!L.actor||!l||l.organizationId!==c.organization.id)return O({ok:!1,error:"Security finding was not found."},404);try{let D=S.action==="acknowledge"?ct.acknowledgeFinding(l.id,L.actor.id):ct.assignFinding(l.id,typeof S.ownerActorId==="string"&&S.ownerActorId?S.ownerActorId:void 0,L.actor.id);return O({ok:!0,finding:D})}catch(D){return O({ok:!1,error:D instanceof Error?D.message:"Security finding could not be updated."},422)}}if(U.pathname==="/api/security/comments"&&C.method==="POST"){let S=await v(C),L=nt(Y);if(!L.actor)return O({ok:!1,error:"An organization actor is required."},403);try{return O({ok:!0,comment:ct.addComment({findingId:String(S.findingId??""),actorId:L.actor.id,body:String(S.body??""),referenceUrl:typeof S.referenceUrl==="string"?S.referenceUrl:void 0})},201)}catch(l){return O({ok:!1,error:l instanceof Error?l.message:"Comment could not be saved."},422)}}if(U.pathname==="/api/auth/sessions"&&C.method==="GET"){let S=kt.resolveSession(C);return O({currentSessionId:S?.id,sessions:S?Q.listSessions(S.identityId,{includeInactive:!0}):[]})}if(U.pathname==="/api/auth/sessions"&&C.method==="DELETE"){let S=await v(C),L=kt.resolveSession(C);if(!L)return O({ok:!1,error:"Sign in again to manage sessions."},401);let l=String(S.id??""),D=Q.revokeSession(L.identityId,l),g=l===L.id&&D?{"set-cookie":vh({secure:Xd})}:void 0;return O({ok:D,signedOut:l===L.id&&D},D?200:404,g)}if(U.pathname==="/api/auth/sessions/revoke-others"&&C.method==="POST"){let S=kt.resolveSession(C);if(!S)return O({ok:!1,error:"Sign in again to manage sessions."},401);return O({ok:!0,revoked:Q.revokeOtherSessions(S.identityId,S.id)})}if(U.pathname==="/api/auth/password/change"&&C.method==="POST"){let S=await v(C),L=String(S.currentPassword??""),l=String(S.password??""),D=nt(Y),g=D.actor?Q.getIdentityByActor(D.actor.id):void 0;if(!g||!Hr(L,g.passwordHash))return O({ok:!1,error:"Current password is incorrect."},401);if(l.length<12)return O({ok:!1,error:"New password must be at least 12 characters."},422);if(Hr(l,g.passwordHash))return O({ok:!1,error:"Choose a different password."},409);let X=EE(l),y=Q.updatePassword(g.id,X);Mh(e,y.username,X);let z=tT(y.id,C,Ct.requestIP(C)?.address??"unknown");return c.store.appendEvent({organizationId:c.organization.id,actorId:y.actorId,type:"auth.password.changed"}),O({ok:!0,message:"Password changed and other sessions were signed out."},200,{"set-cookie":Dc(z.token,{secure:Xd,maxAgeMs:Qd})})}if(U.pathname==="/api/auth/mfa/enroll"&&C.method==="POST"){let S=await v(C),L=kt.resolveSession(C),l=nt(Y),D=l.actor?Q.getIdentityByActor(l.actor.id):void 0;if(!L||!D)return O({ok:!1,error:"Sign in again before enabling MFA."},401);if(!Hr(String(S.password??""),D.passwordHash))return O({ok:!1,error:"Current password is incorrect."},401);try{let g=Q.beginTotpEnrollment(D.id,{issuer:c.organization.name});return c.store.appendEvent({organizationId:c.organization.id,actorId:D.actorId,type:"auth.mfa.enrollment.started"}),O({factor:g.factor,secret:g.secret,uri:g.uri})}catch(g){return O({ok:!1,error:g instanceof Error?g.message:"MFA enrollment failed."},409)}}if(U.pathname==="/api/auth/mfa/verify"&&C.method==="POST"){let S=await v(C),L=kt.resolveSession(C),l=nt(Y),D=l.actor?Q.getIdentityByActor(l.actor.id):void 0;if(!L||!D)return O({ok:!1,error:"Sign in again before enabling MFA."},401);try{let g=Q.verifyTotpEnrollment(D.id,String(S.code??""));return Q.markSessionStepUp(L.id,!0),c.store.appendEvent({organizationId:c.organization.id,actorId:D.actorId,type:"auth.mfa.enabled",payload:{recoveryCodeCount:g.recoveryCodes.length}}),O(g)}catch(g){return O({ok:!1,error:g instanceof Error?g.message:"MFA enrollment failed."},422)}}if(U.pathname==="/api/auth/mfa"&&C.method==="DELETE"){let S=await v(C),L=kt.resolveSession(C),l=nt(Y),D=l.actor?Q.getIdentityByActor(l.actor.id):void 0;if(!L||!D||!Hr(String(S.password??""),D.passwordHash))return O({ok:!1,error:"Current password is incorrect."},401);let g=Q.verifyMfaCode(D.id,String(S.code??""));if(!g.valid||!g.method)return O({ok:!1,error:"Authenticator or recovery code is incorrect."},401);return Q.disableMfa(D.id),Q.revokeOtherSessions(D.id,L.id),Q.markSessionStepUp(L.id),c.store.appendEvent({organizationId:c.organization.id,actorId:D.actorId,type:"auth.mfa.disabled",payload:{method:g.method}}),O({ok:!0})}if(U.pathname==="/api/auth/step-up"&&C.method==="POST"){let S=await v(C),L=kt.resolveSession(C),l=nt(Y),D=l.actor?Q.getIdentityByActor(l.actor.id):void 0;if(!L||!D||!Hr(String(S.password??""),D.passwordHash))return O({ok:!1,error:"Current password is incorrect."},401);let g=Q.getMfaFactor(D.id);if(g?.state==="active"){if(!Q.verifyMfaCode(D.id,String(S.code??"")).valid)return O({ok:!1,error:"Authenticator or recovery code is incorrect."},401)}let X=Q.markSessionStepUp(L.id,g?.state==="active");return c.store.appendEvent({organizationId:c.organization.id,actorId:D.actorId,type:"auth.step_up.succeeded",payload:{mfa:g?.state==="active"}}),O({ok:!0,recentAuthAt:X.recentAuthAt})}if(U.pathname==="/api/terminal"){if(!$)return O({ok:!1,error:"The web terminal is disabled."},403);if(Ct.upgrade(C))return;return sh("WebSocket upgrade failed",400)}if(U.pathname==="/api/health"){let S=c.store.health();return O({ok:!0,cwd:e,environment:V,environments:_,uiRoot:await Et(Y,V),liveData:F.size>0,terminal:$,localPackage:import.meta.url.includes("/Code/Libraries/ts-cloud/"),controlPlane:{schemaVersion:S.schemaVersion,supportedSchemaVersion:S.supportedSchemaVersion,integrity:S.integrity,pendingRetryableOperations:S.pendingRetryableOperations}})}if(U.pathname==="/api/control-plane/operations"){let S=U.searchParams.get("state"),L=S&&["queued","running","succeeded","failed","cancelled","timed_out"].includes(S)?S:void 0;return O({operations:c.store.listOperations({projectId:c.project.id,state:L,kind:U.searchParams.get("kind")??void 0,limit:Number(U.searchParams.get("limit"))||100})})}if(U.pathname==="/api/queue"&&C.method==="GET"){let S=U.searchParams.get("state"),L=S&&["queued","running","succeeded","failed","cancelled","timed_out"].includes(S)?S:void 0,l=zt.list({projectId:c.project.id,state:L,limit:Number(U.searchParams.get("limit"))||250}).filter((D)=>En(Y,D.operation.id,"deployments:read")).map((D)=>{let g=D.operation.resourceId?c.store.getResource(D.operation.resourceId):void 0,X=D.operation.environmentId?c.store.listEnvironments(c.project.id).find((M)=>M.id===D.operation.environmentId):void 0,y=D.operation.actorId?c.store.getActor(D.operation.actorId):void 0,z=D.operation.input;return{...D,target:g?{id:g.id,name:g.name,slug:g.slug,kind:g.kind}:X?{id:X.id,name:X.name,slug:X.slug,kind:"environment"}:{id:c.project.id,name:c.project.name,slug:c.project.slug,kind:"project"},actor:y?{id:y.id,name:y.displayName,kind:y.kind}:void 0,commit:z.revision??z.source?.commitSha??null}});return O({operations:l,concurrency:zt.limits})}if(U.pathname==="/api/queue/logs"&&C.method==="GET"){let S=String(U.searchParams.get("id")??"");if(!En(Y,S,"deployments:read"))return O({ok:!1,error:"Operation was not found in this scope."},404);let L=zt.logs(S,{after:Number(U.searchParams.get("after"))||0,limit:Number(U.searchParams.get("limit"))||500});return O({entries:L,cursor:L.at(-1)?.sequence??(Number(U.searchParams.get("after"))||0),operation:c.store.getOperation(S)})}if(U.pathname==="/api/queue/stream"&&C.method==="GET"){let S=String(U.searchParams.get("id")??"");if(!En(Y,S,"deployments:read"))return O({ok:!1,error:"Operation was not found in this scope."},404);let L=C.headers.get("last-event-id")?.trim(),l=Number(L||U.searchParams.get("after")||0),D=new TextEncoder,g,X=!1,y=new ReadableStream({start(z){let M=()=>{if(X)return;let b=kt.resolveUser(C);if(!b||!En(b,S,"deployments:read")){if(X=!0,g)clearInterval(g);z.close();return}let wt=zt.logs(S,{after:l,limit:500});for(let _t of wt)l=_t.sequence,z.enqueue(D.encode(`id: ${_t.sequence}
|
|
6647
|
+
This link expires in one hour and can be used once.`});c.store.appendEvent({organizationId:c.organization.id,actorId:g.actorId,type:"auth.password_reset.requested",payload:{delivered:z}})}return O({ok:!0,message:"If that account has a verified email, a reset link has been sent."},202)}if(U.pathname==="/api/auth/password-reset/complete"&&C.method==="POST"){let S=await v(C),L=String(S.token??"").trim(),l=String(S.password??"");if(!L||l.length<12)return O({ok:!1,error:"A valid reset token and password of at least 12 characters are required."},422);try{let D=Q.consumeActionToken(L,"password_reset"),g=EE(l),X=Q.updatePassword(D.identityId,g);return Mh(e,X.username,g),c.store.appendEvent({organizationId:c.organization.id,actorId:X.actorId,type:"auth.password_reset.completed"}),O({ok:!0,message:"Password changed. Sign in again."},200,{"set-cookie":vh({secure:Xd})})}catch(D){let g=D instanceof Error?D.message:"Password reset failed.";return O({ok:!1,error:g.replace("Action token","Reset link")},g.includes("consumed")||g.includes("expired")?409:404)}}if(U.pathname==="/api/login"&&C.method==="POST"){let S=await v(C),L=String(S.username??"").trim(),l=String(S.password??""),D=Ct.requestIP(C)?.address??"unknown",g=m_.check(L,D);if(!g.allowed)return O({ok:!1,error:`Too many failed attempts. Try again in ${Math.ceil((g.retryAfterSeconds??0)/60)} minute(s).`},429,{"retry-after":String(g.retryAfterSeconds??60)});let X=wr(Ye(e),L),y=Q.getIdentityByUsername(L),z=y?.passwordHash??X?.passwordHash??EJ;if(!(Hr(l,z)&&!!X&&!!y&&!y.disabledAt))return m_.recordFailure(L,D),O({ok:!1,error:"Incorrect username or password."},401);if(YU(Q,c,y))return O({ok:!1,error:"Single sign-on is required for this account."},403);m_.recordSuccess(L,D);let b=y,wt=b.requiresPasswordUpgrade||Zf(b.passwordHash);if(wt){let _t=EE(l);b=Q.rehashPassword(b.id,_t),Mh(e,b.username,_t)}if(Q.recordLogin(b.id),Q.getMfaFactor(b.id)?.state==="active"){let _t=Q.createMfaChallenge(b.id,"login");return c.store.appendEvent({organizationId:c.organization.id,actorId:b.actorId,type:"auth.mfa.challenge.created",payload:{purpose:"login"}}),O({ok:!0,mfaRequired:!0,challengeToken:_t.token,passwordUpgraded:wt})}let k=tT(b.id,C,D);return c.store.appendEvent({organizationId:c.organization.id,actorId:b.actorId,type:"auth.login.succeeded",payload:{method:"local"}}),O({ok:!0,user:fc(X),passwordUpgraded:wt},200,{"set-cookie":Dc(k.token,{secure:Xd,maxAgeMs:Qd})})}if(U.pathname==="/api/auth/mfa/complete"&&C.method==="POST"){let S=await v(C),L=String(S.challengeToken??"").trim(),l=String(S.code??"").trim(),D=Ct.requestIP(C)?.address??"unknown",X=Q.inspectMfaChallengeToken(L,"login")?.identityId??"unknown-mfa",y=p_.check(X,D);if(!y.allowed)return O({ok:!1,error:"Too many MFA attempts. Try again later."},429,{"retry-after":String(y.retryAfterSeconds??60)});try{let z=Q.completeMfaChallenge(L,l,"login");p_.recordSuccess(X,D);let M=new Date().toISOString(),b=Q.createSession({identityId:z.identity.id,userAgent:Iu(C),networkHint:dR(D),mfaAt:M,recentAuthAt:M});return c.store.appendEvent({organizationId:c.organization.id,actorId:z.identity.actorId,type:"auth.mfa.succeeded",payload:{purpose:"login",method:z.method}}),O({ok:!0},200,{"set-cookie":Dc(b.token,{secure:Xd,maxAgeMs:Qd})})}catch{return p_.recordFailure(X,D),O({ok:!1,error:"Authenticator or recovery code is incorrect."},401)}}if(U.pathname==="/api/logout"&&C.method==="POST"){let S=kt.resolveSession(C);if(S)Q.revokeSession(S.identityId,S.id);let L=vh({secure:Xd});if(C.headers.get("accept")?.includes("text/html"))return new Response(null,{status:302,headers:{location:"/login","set-cookie":L}});return O({ok:!0},200,{"set-cookie":L})}if(U.pathname==="/login"){let S=Q.listOidcProviders(c.organization.id).map((L)=>({slug:L.slug,name:L.name}));return new Response(MU(h?.mode==="serverless",S),{headers:{"content-type":"text/html; charset=utf-8"}})}if(U.pathname==="/forgot-password"||U.pathname==="/reset-password")return new Response(GU(U.pathname==="/reset-password"?"reset":"request"),{headers:{"content-type":"text/html; charset=utf-8"}});if(U.pathname==="/accept-invitation")return xw(It,U.pathname);let Y=kt.resolveUser(C);if(!Y){if(!U.pathname.startsWith("/api/")&&C.headers.get("accept")?.includes("text/html"))return new Response(null,{status:302,headers:{location:"/login"}});return O({ok:!1,error:"Sign in to continue."},401)}let Tr=tt(Y,V);if(U.pathname==="/api/me"){let S=c.store.getActorByExternalId("user",`dashboard:${Y.username.toLowerCase()}`),L=S?c.store.getMembershipForActor(c.organization.id,S.id):void 0,l=c.store.resolveAuthorizationTarget(c.organization.id,L?.scope??{type:"project",id:c.project.id})??c.store.resolveAuthorizationTarget(c.organization.id,{type:"project",id:c.project.id});return O({ok:!0,user:fc(Y),authEnabled:G,organization:c.organization,membership:L,capabilities:un({membership:L,grants:L?c.store.listGrants(L.id):[],target:l})})}if(U.pathname.startsWith("/api/")){let S=await WU(C,U.pathname),L=kt.check(C,U.pathname,Y,S);if(!L.ok)return O({ok:!1,error:L.error},L.status??403);if(G&&AJ.has(`${C.method.toUpperCase()} ${U.pathname}`)){let l=kt.resolveSession(C);if(!l||!Q.isRecentlyAuthenticated(l))return O({ok:!1,error:"Recent authentication is required for this change.",stepUpRequired:!0},401)}}if(U.pathname==="/api/auth/security"&&C.method==="GET"){let S=nt(Y),L=S.actor?Q.getIdentityByActor(S.actor.id):void 0,l=kt.resolveSession(C);return O({identity:L?{username:L.username,email:L.email,emailVerifiedAt:L.emailVerifiedAt,requiresPasswordUpgrade:L.requiresPasswordUpgrade,lastLoginAt:L.lastLoginAt}:void 0,currentSessionId:l?.id,sessions:L?Q.listSessions(L.id,{includeInactive:!0}):[],mfa:L?{factor:Q.getMfaFactor(L.id),recoveryCodesRemaining:Q.remainingRecoveryCodes(L.id)}:void 0})}if(U.pathname==="/api/auth/oidc/providers"&&C.method==="GET")return O({providers:Q.listOidcProviders(c.organization.id,{includeDisabled:!0}),callbackOrigin:Dt,callbackPattern:Dt?`${Dt}/auth/oidc/{slug}/callback`:void 0,localOwnerRecovery:!0});if(U.pathname==="/api/auth/oidc/providers"&&C.method==="POST"){let S=await v(C),L=nt(Y),l=L.actor?Q.getIdentityByActor(L.actor.id):void 0,D=S.enforceSso===!0;if(D&&(!l?.emailVerifiedAt||Q.remainingRecoveryCodes(l.id)<1))return O({ok:!1,error:"Verify the owner email and generate MFA recovery codes before enforcing SSO."},409);try{let g=bh(S.defaultRole),X=Q.upsertOidcProvider({id:typeof S.id==="string"?S.id:void 0,organizationId:c.organization.id,slug:String(S.slug??""),name:String(S.name??""),issuer:String(S.issuer??""),clientId:String(S.clientId??""),clientSecret:typeof S.clientSecret==="string"&&S.clientSecret?S.clientSecret:void 0,scopes:Array.isArray(S.scopes)?S.scopes.map(String):void 0,allowedDomains:Array.isArray(S.allowedDomains)?S.allowedDomains.map(String):[],defaultRole:g&&g!=="owner"?g:void 0,enabled:S.enabled!==!1,enforceSso:D});return c.store.appendEvent({organizationId:c.organization.id,actorId:L.actor?.id,type:"auth.oidc.provider.configured",payload:{providerId:X.id,issuer:X.issuer,enabled:X.enabled,enforceSso:X.enforceSso}}),O({ok:!0,provider:X})}catch(g){return O({ok:!1,error:g instanceof Error?g.message:"OIDC provider could not be saved."},422)}}if(U.pathname==="/api/auth/oidc/providers"&&C.method==="PATCH"){let S=await v(C),L=Q.getOidcProvider(String(S.id??""));if(!L||L.organizationId!==c.organization.id)return O({ok:!1,error:"OIDC provider was not found."},404);let l=nt(Y),D=Q.setOidcProviderEnabled(L.id,S.enabled===!0);return c.store.appendEvent({organizationId:c.organization.id,actorId:l.actor?.id,type:D.enabled?"auth.oidc.provider.enabled":"auth.oidc.provider.disabled",payload:{providerId:L.id}}),O({ok:!0,provider:D})}if(U.pathname==="/api/automation"&&C.method==="GET"){let S=Rt.listServiceAccounts(c.organization.id,{includeDisabled:!0}).map((L)=>{let l=c.store.getMembershipForActor(c.organization.id,L.actorId),D=L.createdByActorId?c.store.getActor(L.createdByActorId):void 0,g=Rt.listTokens(L.id,{includeInactive:!0}).map((X)=>({...X,createdBy:X.createdByActorId?c.store.getActor(X.createdByActorId):void 0}));return{account:L,createdBy:D,membership:l,tokens:g}});return O({accounts:S,apiBaseUrl:`${U.origin}/api/v1`,openApiUrl:`${U.origin}/api/v1/openapi.json`,tokenEnvironmentVariable:"TS_CLOUD_API_TOKEN"})}if(U.pathname==="/api/automation/service-accounts"&&C.method==="POST"){let S=await v(C),L=nt(Y),l=bh(S.roleTemplate),D=b_(S);if(!L.actor||!l||l==="owner"||!D)return O({ok:!1,error:"A non-owner role and valid organization scope are required."},422);try{let g=Rt.createServiceAccount({organizationId:c.organization.id,slug:String(S.slug??""),name:String(S.name??""),description:typeof S.description==="string"?S.description:void 0,roleTemplate:l,scope:D,createdByActorId:L.actor.id});return O({ok:!0,...g},201)}catch(g){return O({ok:!1,error:g instanceof Error?g.message:"Service account could not be created."},422)}}if(U.pathname==="/api/automation/service-accounts"&&C.method==="PATCH"){let S=await v(C),L=nt(Y),l=Rt.getServiceAccount(String(S.id??""));if(!l||l.organizationId!==c.organization.id)return O({ok:!1,error:"Service account was not found."},404);return O({ok:!0,account:Rt.disableServiceAccount(l.id,L.actor?.id)})}if(U.pathname==="/api/automation/tokens"&&C.method==="POST"){let S=await v(C),L=nt(Y),l=Rt.getServiceAccount(String(S.serviceAccountId??"")),D=b_(S);if(!L.actor||!l||l.organizationId!==c.organization.id||!D||!Array.isArray(S.capabilities))return O({ok:!1,error:"Service account, explicit capabilities, and valid scope are required."},422);try{let g=Rt.createToken({serviceAccountId:l.id,name:String(S.name??"API token"),capabilities:S.capabilities.map(String),scope:D,expiresAt:typeof S.expiresAt==="string"?S.expiresAt:void 0,createdByActorId:L.actor.id});return O({ok:!0,token:g.token,secret:g.secret,revealOnce:!0},201)}catch(g){return O({ok:!1,error:g instanceof Error?g.message:"API token could not be created."},422)}}if(U.pathname==="/api/automation/tokens/rotate"&&C.method==="POST"){let S=await v(C),L=nt(Y),l=Rt.getToken(String(S.id??"")),D=l?Rt.getServiceAccount(l.serviceAccountId):void 0;if(!L.actor||!l||D?.organizationId!==c.organization.id)return O({ok:!1,error:"API token was not found."},404);try{let g=Rt.rotateToken(l.id,L.actor.id);return O({ok:!0,token:g.token,secret:g.secret,revealOnce:!0,overlap:!0},201)}catch(g){return O({ok:!1,error:g instanceof Error?g.message:"API token could not be rotated."},409)}}if(U.pathname==="/api/automation/tokens"&&C.method==="DELETE"){let S=await v(C),L=nt(Y),l=Rt.getToken(String(S.id??"")),D=l?Rt.getServiceAccount(l.serviceAccountId):void 0;if(!l||D?.organizationId!==c.organization.id)return O({ok:!1,error:"API token was not found."},404);return O({ok:!0,token:Rt.revokeToken(l.id,L.actor?.id)})}if(U.pathname==="/api/onboarding"&&C.method==="GET"){let S=m.listConnections(c.organization.id);return O({drafts:te.list(c.project.id),artifacts:ge.list(c.project.id),registries:qe.list(c.organization.id),sourceConnections:S,repositories:S.flatMap((L)=>m.listRepositories(L.id)),project:{id:c.project.id,slug:c.project.slug,name:c.project.name},environments:[...c.environments.values()].map((L)=>({id:L.id,slug:L.slug,name:L.name,kind:L.kind,region:L.region})),resources:c.store.listResources(c.project.id).filter((L)=>L.kind==="application").map((L)=>({id:L.id,slug:L.slug,name:L.name,environmentId:L.environmentId}))})}if(U.pathname==="/api/onboarding/detect"&&C.method==="POST"){let S=await v(C);try{if(S.source?.kind==="git"){let D=m.getConnection(String(S.source.connectionId??"")),g=m.getRepository(String(S.source.repositoryId??""));if(!D||D.organizationId!==c.organization.id||!g||g.connectionId!==D.id)throw Error("Authorized Git repository was not found");let X=typeof S.source.deployKeyId==="string"?m.getDeployKey(S.source.deployKeyId):void 0;if(X&&X.connectionId!==D.id)throw Error("Deploy key does not belong to this connection");let y=eu(Wt(qh(),"ts-cloud-onboarding-git-"));try{let z=await fS({remote:g.cloneUrl,destination:Wt(y,"checkout"),ref:String(S.source.ref??g.defaultBranch),sparsePaths:Array.isArray(S.source.sparsePaths)?S.source.sparsePaths.map(String):void 0,binding:{id:"detection",projectId:c.project.id,connectionId:D.id,repositoryId:g.id,repositoryFullName:g.fullName,defaultBranch:g.defaultBranch,monorepoRoot:String(S.source.monorepoRoot??"."),includePaths:[],excludePaths:[],submodules:S.source.submodules===!0,cloneDepth:1,deployKeyId:X?.id,autoDeploy:!1,pullRequestPreviews:!1,status:"active",version:1,createdAt:new Date().toISOString(),updatedAt:new Date().toISOString()}},{credential:m.getCredential(D.id),deployKey:X?{...X,privateKey:m.getDeployPrivateKey(X.id)}:void 0,timeoutMs:120000});return O({ok:!0,commitSha:z.commitSha,candidates:gn(ES(z.directory))})}finally{dn(y,{recursive:!0,force:!0})}}if(Array.isArray(S.files)){if(S.files.length>1e4)throw Error("Detection file-count limit exceeded");let D=S.files.map((g)=>({path:String(g.path??""),size:Number(g.size??0),content:typeof g.content==="string"?g.content.slice(0,262144):void 0}));return O({ok:!0,candidates:gn(D)})}let L=bB(e,String(S.root??".")),l=kB(e,L);if(l===".."||l.startsWith(`..${xB}`))throw Error("Detection root must stay inside the project");return O({ok:!0,candidates:gn(ES(L))})}catch(L){return O({ok:!1,error:L instanceof Error?L.message:"Application detection failed."},422)}}if(U.pathname==="/api/onboarding/plan"&&C.method==="POST"){let S=await v(C);try{return O({ok:!0,plan:yr(S.draft,Array.isArray(S.suppliedSecretNames)?S.suppliedSecretNames.map(String):[])})}catch(L){return O({ok:!1,error:L instanceof Error?L.message:"Application plan could not be generated."},422)}}if(U.pathname==="/api/onboarding/drafts"&&C.method==="POST"){let S=await v(C),L=nt(Y);try{return O({ok:!0,draft:te.create({organizationId:c.organization.id,projectId:c.project.id,name:String(S.name??S.draft?.name??"Application draft"),draft:{...S.draft,projectId:c.project.id},step:S.step,suppliedSecretNames:Array.isArray(S.suppliedSecretNames)?S.suppliedSecretNames.map(String):[],actorId:L.actor?.id})},201)}catch(l){return O({ok:!1,error:l instanceof Error?l.message:"Application draft could not be saved."},422)}}if(U.pathname==="/api/onboarding/drafts"&&C.method==="PATCH"){let S=await v(C),L=nt(Y),l=te.get(String(S.id??""));if(!l||l.projectId!==c.project.id)return O({ok:!1,error:"Application draft was not found."},404);try{return O({ok:!0,draft:te.update(l.id,Number(S.version),{draft:{...S.draft,projectId:c.project.id},step:S.step,suppliedSecretNames:Array.isArray(S.suppliedSecretNames)?S.suppliedSecretNames.map(String):void 0,actorId:L.actor?.id})})}catch(D){return O({ok:!1,error:D instanceof Error?D.message:"Application draft could not be updated."},409)}}if(U.pathname==="/api/onboarding/artifacts"&&C.method==="POST"){let S=nt(Y);if(Number(C.headers.get("content-length")??0)>104857600)return O({ok:!1,error:"Artifact exceeds the 100 MB upload limit."},413);try{let l=new Uint8Array(await C.arrayBuffer());return O({ok:!0,artifact:ge.create({organizationId:c.organization.id,projectId:c.project.id,filename:C.headers.get("x-artifact-filename")??"application.zip",bytes:l,actorId:S.actor?.id})},201)}catch(l){return O({ok:!1,error:l instanceof Error?l.message:"Artifact could not be inspected."},422)}}if(U.pathname==="/api/onboarding/registries"&&C.method==="POST"){let S=await v(C),L=nt(Y);try{return O({ok:!0,registry:qe.create({organizationId:c.organization.id,provider:S.provider,name:String(S.name??"Container registry"),host:String(S.host??""),credential:S.token||S.password?{username:typeof S.username==="string"?S.username:void 0,password:typeof S.password==="string"?S.password:void 0,token:typeof S.token==="string"?S.token:void 0}:void 0,credentialExpiresAt:typeof S.credentialExpiresAt==="string"?S.credentialExpiresAt:void 0,actorId:L.actor?.id})},201)}catch(l){return O({ok:!1,error:l instanceof Error?l.message:"Registry connection could not be created."},422)}}if(U.pathname==="/api/onboarding/registries"&&C.method==="PATCH"){let S=await v(C),L=nt(Y),l=qe.get(String(S.id??""));if(!l||l.organizationId!==c.organization.id)return O({ok:!1,error:"Registry connection was not found."},404);try{if(S.action==="test")return O({ok:!0,registry:await qe.test(l.id,{image:typeof S.image==="string"?S.image:void 0})});if(S.action==="rotate")return O({ok:!0,registry:qe.rotate(l.id,{username:typeof S.username==="string"?S.username:void 0,password:typeof S.password==="string"?S.password:void 0,token:typeof S.token==="string"?S.token:void 0},{expiresAt:typeof S.expiresAt==="string"?S.expiresAt:void 0,actorId:L.actor?.id})});return O({ok:!1,error:"Registry action must be test or rotate."},422)}catch(D){return O({ok:!1,error:D instanceof Error?D.message:"Registry connection could not be updated."},422)}}if(U.pathname==="/api/onboarding/registries"&&C.method==="DELETE"){let S=await v(C),L=nt(Y),l=qe.get(String(S.id??""));if(!l||l.organizationId!==c.organization.id)return O({ok:!1,error:"Registry connection was not found."},404);let D=te.list(c.project.id).filter((g)=>g.input.source.kind==="image"&&g.input.source.registryConnectionId===l.id||g.input.build.kind==="prebuilt_image"&&g.input.build.registryConnectionId===l.id);if(S.preview===!0)return O({ok:!0,preview:!0,affectedDrafts:D});return O({ok:!0,registry:qe.disconnect(l.id,L.actor?.id),affectedDrafts:D})}if(U.pathname==="/api/onboarding/apply"&&C.method==="POST"){let S=await v(C),L=nt(Y);try{let l=BT({controlPlane:c.store,drafts:te,draftId:String(S.id??""),expectedVersion:Number(S.version),confirmEnvironment:String(S.confirmEnvironment??""),actorId:L.actor?.id});return O({ok:!0,resource:l.resource,operation:l.operation,plan:l.plan},202)}catch(l){return O({ok:!1,error:l instanceof Error?l.message:"Application plan could not be applied."},422)}}if(U.pathname==="/api/sources"&&C.method==="GET"){let S=m.listConnections(c.organization.id);return O({connections:S,bindings:m.listBindings({projectId:c.project.id}),repositories:S.flatMap((L)=>m.listRepositories(L.id)),deployKeys:S.flatMap((L)=>m.listDeployKeys(L.id)),webhooks:S.flatMap((L)=>m.listWebhooks(L.id)).map((L)=>({...L,deliveries:m.listDeliveries(L.id,20)})),project:{id:c.project.id,slug:c.project.slug},environment:Jr(c,String(V)),resources:c.store.listResources(c.project.id,Jr(c,String(V)).environmentId).filter((L)=>L.kind==="application").map((L)=>({id:L.id,slug:L.slug,name:L.name}))})}if(U.pathname==="/api/sources/connections"&&C.method==="POST"){let S=await v(C),L=nt(Y),l=String(S.provider??"");if(!["github","gitlab","bitbucket","gitea","generic_https","generic_ssh"].includes(l))return O({ok:!1,error:"A supported Git provider is required."},422);try{let D=l==="github"&&(S.privateKey||S.appId)?{appId:typeof S.appId==="string"?S.appId:void 0,installationId:typeof S.installationId==="string"?S.installationId:void 0,privateKey:typeof S.privateKey==="string"?S.privateKey:void 0}:l!=="generic_ssh"&&S.token?{token:typeof S.token==="string"?S.token:void 0,username:typeof S.username==="string"?S.username:void 0}:void 0,g={github:"https://github.com",gitlab:"https://gitlab.com",bitbucket:"https://bitbucket.org",gitea:"https://gitea.com"},X,y,z;if(c.store.database.transaction(()=>{if(X=m.createConnection({organizationId:c.organization.id,provider:l,name:String(S.name??l),host:String(S.host??g[l]??""),owner:typeof S.owner==="string"?S.owner:void 0,authKind:S.authKind,credential:D,grantedScopes:Array.isArray(S.grantedScopes)?S.grantedScopes.map(String):[],credentialExpiresAt:typeof S.credentialExpiresAt==="string"?S.credentialExpiresAt:void 0,createdByActorId:L.actor?.id}),typeof S.repositoryUrl==="string"&&typeof S.repositoryFullName==="string")y=m.upsertRepository({connectionId:X.id,providerRepositoryId:`manual:${S.repositoryFullName}`,fullName:S.repositoryFullName,cloneUrl:S.repositoryUrl,defaultBranch:String(S.defaultBranch??"main"),visibility:"unknown",archived:!1,metadata:{source:"manual"}});if(l==="generic_ssh")z=m.createDeployKey({connectionId:X.id,name:String(S.deployKeyName??"Repository deploy key"),publicKey:String(S.publicKey??""),privateKey:String(S.deployPrivateKey??""),host:String(S.sshHost??""),hostKey:String(S.hostKey??""),actorId:L.actor?.id})})(),S.test===!0)X=await US(m,X.id,y?.id);return O({ok:!0,connection:X,repository:y,deployKey:z},201)}catch(D){return O({ok:!1,error:D instanceof Error?D.message:"Source connection could not be created."},422)}}if(U.pathname==="/api/sources/connections"&&C.method==="PATCH"){let S=await v(C),L=nt(Y),l=m.getConnection(String(S.id??""));if(!l||l.organizationId!==c.organization.id)return O({ok:!1,error:"Source connection was not found."},404);try{if(S.action==="test")return O({ok:!0,connection:await US(m,l.id,typeof S.repositoryId==="string"?S.repositoryId:void 0)});if(S.action==="rotate")return O({ok:!0,connection:m.rotateCredential(l.id,{token:typeof S.token==="string"?S.token:void 0,username:typeof S.username==="string"?S.username:void 0,appId:typeof S.appId==="string"?S.appId:void 0,installationId:typeof S.installationId==="string"?S.installationId:void 0,privateKey:typeof S.privateKey==="string"?S.privateKey:void 0},{expiresAt:typeof S.expiresAt==="string"?S.expiresAt:void 0,actorId:L.actor?.id})});return O({ok:!1,error:"Connection action must be test or rotate."},422)}catch(D){return O({ok:!1,error:D instanceof Error?D.message:"Source connection could not be updated."},422)}}if(U.pathname==="/api/sources/connections"&&C.method==="DELETE"){let S=await v(C),L=nt(Y),l=m.getConnection(String(S.id??""));if(!l||l.organizationId!==c.organization.id)return O({ok:!1,error:"Source connection was not found."},404);let D=m.listBindings({connectionId:l.id,status:"active"});if(S.preview===!0)return O({ok:!0,preview:!0,affectedBindings:D});return O({ok:!0,...m.disconnectConnection(l.id,L.actor?.id)})}if(U.pathname==="/api/sources/deploy-keys"&&C.method==="POST"){let S=await v(C),L=nt(Y),l=m.getConnection(String(S.connectionId??""));if(!l||l.organizationId!==c.organization.id)return O({ok:!1,error:"Source connection was not found."},404);try{return O({ok:!0,deployKey:m.createDeployKey({connectionId:l.id,name:String(S.name??"Repository deploy key"),publicKey:String(S.publicKey??""),privateKey:String(S.privateKey??""),host:String(S.host??""),hostKey:String(S.hostKey??""),actorId:L.actor?.id})},201)}catch(D){return O({ok:!1,error:D instanceof Error?D.message:"Deploy key could not be stored."},422)}}if(U.pathname==="/api/sources/deploy-keys"&&C.method==="DELETE"){let S=await v(C),L=nt(Y),l=m.getDeployKey(String(S.id??"")),D=l?m.getConnection(l.connectionId):void 0;if(!l||!D||D.organizationId!==c.organization.id)return O({ok:!1,error:"Deploy key was not found."},404);let g=m.listBindings({connectionId:D.id}).filter((X)=>X.deployKeyId===l.id);if(S.preview===!0)return O({ok:!0,preview:!0,affectedBindings:g});return O({ok:!0,...m.revokeDeployKey(l.id,L.actor?.id)})}if(U.pathname==="/api/sources/repositories/sync"&&C.method==="POST"){let S=await v(C),L=m.getConnection(String(S.connectionId??""));if(!L||L.organizationId!==c.organization.id)return O({ok:!1,error:"Source connection was not found."},404);try{return O({ok:!0,repositories:await vT(m,String(S.connectionId??""),{search:typeof S.search==="string"?S.search:void 0})})}catch(l){return O({ok:!1,error:l instanceof Error?l.message:"Repositories could not be synchronized."},422)}}if(U.pathname==="/api/sources/references"&&C.method==="GET"){let S=m.getConnection(String(U.searchParams.get("connectionId")??""));if(!S||S.organizationId!==c.organization.id)return O({ok:!1,error:"Source connection was not found."},404);try{return O(await QT(m,{connectionId:String(U.searchParams.get("connectionId")??""),repository:String(U.searchParams.get("repository")??""),repositoryId:U.searchParams.get("repositoryId")??void 0,deployKeyId:U.searchParams.get("deployKeyId")??void 0,type:U.searchParams.get("type")==="tags"?"tags":"branches",cursor:U.searchParams.get("cursor")??void 0}))}catch(L){return O({ok:!1,error:L instanceof Error?L.message:"References could not be listed."},422)}}if(U.pathname==="/api/sources/bindings"&&C.method==="POST"){let S=await v(C),L=nt(Y),l=Jr(c,String(V)),D=m.getConnection(String(S.connectionId??""));if(!D||D.organizationId!==c.organization.id)return O({ok:!1,error:"Source connection was not found."},404);try{return O({ok:!0,binding:m.createBinding({projectId:c.project.id,environmentId:l.environmentId,resourceId:typeof S.resourceId==="string"?S.resourceId:void 0,connectionId:String(S.connectionId??""),repositoryId:typeof S.repositoryId==="string"?S.repositoryId:void 0,repositoryFullName:String(S.repositoryFullName??""),defaultBranch:String(S.defaultBranch??"main"),branchRule:typeof S.branchRule==="string"?S.branchRule:void 0,tagRule:typeof S.tagRule==="string"?S.tagRule:void 0,monorepoRoot:String(S.monorepoRoot??"."),includePaths:Array.isArray(S.includePaths)?S.includePaths.map(String):[],excludePaths:Array.isArray(S.excludePaths)?S.excludePaths.map(String):[],submodules:S.submodules===!0,cloneDepth:S.cloneDepth?Number(S.cloneDepth):void 0,deployKeyId:typeof S.deployKeyId==="string"&&S.deployKeyId?S.deployKeyId:void 0,autoDeploy:S.autoDeploy!==!1,pullRequestPreviews:S.pullRequestPreviews!==!1,actorId:L.actor?.id})},201)}catch(g){return O({ok:!1,error:g instanceof Error?g.message:"Source binding could not be created."},422)}}if(U.pathname==="/api/sources/bindings"&&C.method==="PATCH"){let S=await v(C),L=nt(Y),l=m.getBinding(String(S.id??""));if(!l||l.projectId!==c.project.id)return O({ok:!1,error:"Source binding was not found."},404);try{return O({ok:!0,binding:m.updateBinding(l.id,Number(S.version),{defaultBranch:S.defaultBranch,branchRule:S.branchRule,tagRule:S.tagRule,monorepoRoot:S.monorepoRoot,includePaths:S.includePaths,excludePaths:S.excludePaths,submodules:S.submodules,cloneDepth:S.cloneDepth,deployKeyId:S.deployKeyId,autoDeploy:S.autoDeploy,pullRequestPreviews:S.pullRequestPreviews,status:S.status,disabledReason:S.disabledReason,actorId:L.actor?.id})})}catch(D){return O({ok:!1,error:D instanceof Error?D.message:"Source binding could not be updated."},409)}}if(U.pathname==="/api/sources/webhooks"&&C.method==="POST"){let S=await v(C),L=m.getConnection(String(S.connectionId??""));if(!L||L.organizationId!==c.organization.id)return O({ok:!1,error:"Source connection was not found."},404);try{let l=m.createWebhook({connectionId:String(S.connectionId??""),repositoryId:typeof S.repositoryId==="string"?S.repositoryId:void 0,repositoryFullName:String(S.repositoryFullName??""),events:Array.isArray(S.events)?S.events.map(String):void 0,secret:typeof S.secret==="string"?S.secret:void 0}),D=process.env.TS_CLOUD_WEBHOOK_BASE_URL?.trim()||Dt,g=D?Xn(D,l.webhook):void 0,X=S.reconcile!==!1&&D?await e_(m,l.webhook.id,D):l.webhook;return O({ok:!0,webhook:X,endpoint:g,endpointRevealOnce:!0},201)}catch(l){return O({ok:!1,error:l instanceof Error?l.message:"Source webhook could not be created."},422)}}if(U.pathname==="/api/sources/webhooks"&&C.method==="PATCH"){let S=await v(C),L=process.env.TS_CLOUD_WEBHOOK_BASE_URL?.trim()||Dt,l=m.getWebhook(String(S.id??"")),D=l?m.getConnection(l.connectionId):void 0;if(!l||!D||D.organizationId!==c.organization.id)return O({ok:!1,error:"Source webhook was not found."},404);if(!L)return O({ok:!1,error:"Set TS_CLOUD_WEBHOOK_BASE_URL to reconcile provider webhooks."},422);try{return O({ok:!0,webhook:await e_(m,String(S.id??""),L)})}catch(g){return O({ok:!1,error:g instanceof Error?g.message:"Source webhook could not be reconciled."},422)}}if(U.pathname==="/api/sources/webhooks"&&C.method==="DELETE"){let S=await v(C),L=m.getWebhook(String(S.id??"")),l=L?m.getConnection(L.connectionId):void 0;if(!L||!l||l.organizationId!==c.organization.id)return O({ok:!1,error:"Source webhook was not found."},404);try{return O({ok:!0,webhook:await C0(m,String(S.id??""))})}catch(D){return O({ok:!1,error:D instanceof Error?D.message:"Source webhook could not be removed."},422)}}if(U.pathname==="/api/security/posture"&&C.method==="GET"){let S=Jr(c,String(V)),L=ct.listFindings({...S,limit:500});return O({scope:S,summary:ct.summary(S.organizationId,S.projectId,S.environmentId),findings:L,scans:ct.listScanRuns({...S,limit:100}),policies:ct.listPolicies(S.organizationId).filter((l)=>!l.environmentId||l.environmentId===S.environmentId),waivers:L.flatMap((l)=>ct.listWaivers(l.id)),decisions:ct.listDecisions(S.environmentId,50),actors:c.store.listMemberships(c.organization.id).map((l)=>c.store.getActor(l.actorId)).filter(Boolean)})}if(U.pathname==="/api/security/export"&&C.method==="GET")return O(ct.exportPosture(c.organization.id));if(U.pathname==="/api/security/scan"&&C.method==="POST"){let S=Jr(c,String(V)),L=await new Ac(ct).run(new J_,{...S,artifactRoot:e}),l=gh(ct,S,Vt??{});return O({ok:!0,source:L,host:l,summary:ct.summary(S.organizationId,S.projectId,S.environmentId)})}if(U.pathname==="/api/security/review"&&C.method==="POST")try{let S=Jr(c,String(V));return O({ok:!0,...$h(ct,{scope:S,desiredConfigHash:c.project.desiredConfigHash})})}catch(S){return O({ok:!1,error:S instanceof Error?S.message:"Security change review failed."},409)}if(U.pathname==="/api/security/policies"&&C.method==="POST"){let S=await v(C),L=nt(Y);if(!L.actor)return O({ok:!1,error:"An organization actor is required."},403);try{let l=ct.createPolicy({organizationId:c.organization.id,environmentId:S.environmentId===null?void 0:String(S.environmentId??Jr(c,String(V)).environmentId),name:String(S.name??""),scannerFailMode:S.scannerFailMode==="open"?"open":"closed",requiredScanners:Array.isArray(S.requiredScanners)?S.requiredScanners.map(String):[],rules:Array.isArray(S.rules)?S.rules.map((D)=>({minimumSeverity:String(D.minimumSeverity),action:String(D.action),scannerId:D.scannerId?String(D.scannerId):void 0})):[],actorId:L.actor.id});return O({ok:!0,policy:l},201)}catch(l){return O({ok:!1,error:l instanceof Error?l.message:"Security policy could not be created."},422)}}if(U.pathname==="/api/security/policies"&&C.method==="PATCH"){let S=await v(C),L=nt(Y),l=ct.getPolicy(String(S.id??""));if(!L.actor||!l||l.organizationId!==c.organization.id)return O({ok:!1,error:"Security policy was not found."},404);try{return O({ok:!0,policy:ct.updatePolicy(l.id,Number(S.version),{name:typeof S.name==="string"?S.name:void 0,scannerFailMode:S.scannerFailMode==="open"||S.scannerFailMode==="closed"?S.scannerFailMode:void 0,requiredScanners:Array.isArray(S.requiredScanners)?S.requiredScanners.map(String):void 0,rules:Array.isArray(S.rules)?S.rules.map((D)=>({minimumSeverity:String(D.minimumSeverity),action:String(D.action),scannerId:D.scannerId?String(D.scannerId):void 0})):void 0,enabled:typeof S.enabled==="boolean"?S.enabled:void 0,actorId:L.actor.id})})}catch(D){return O({ok:!1,error:D instanceof Error?D.message:"Security policy could not be updated."},409)}}if(U.pathname==="/api/security/waivers"&&C.method==="POST"){let S=await v(C),L=nt(Y);if(!L.actor)return O({ok:!1,error:"An organization actor is required."},403);try{return O({ok:!0,waiver:ct.createWaiver({findingId:String(S.findingId??""),policyId:typeof S.policyId==="string"?S.policyId:void 0,reason:String(S.reason??""),referenceUrl:typeof S.referenceUrl==="string"?S.referenceUrl:void 0,expiresAt:String(S.expiresAt??""),actorId:L.actor.id})},201)}catch(l){return O({ok:!1,error:l instanceof Error?l.message:"Security waiver could not be created."},422)}}if(U.pathname==="/api/security/waivers"&&C.method==="DELETE"){let S=await v(C),L=nt(Y);if(!L.actor)return O({ok:!1,error:"An organization actor is required."},403);try{return O({ok:!0,waiver:ct.revokeWaiver(String(S.id??""),L.actor.id)})}catch(l){return O({ok:!1,error:l instanceof Error?l.message:"Security waiver could not be revoked."},404)}}if(U.pathname==="/api/security/findings"&&C.method==="PATCH"){let S=await v(C),L=nt(Y),l=ct.getFinding(String(S.id??""));if(!L.actor||!l||l.organizationId!==c.organization.id)return O({ok:!1,error:"Security finding was not found."},404);try{let D=S.action==="acknowledge"?ct.acknowledgeFinding(l.id,L.actor.id):ct.assignFinding(l.id,typeof S.ownerActorId==="string"&&S.ownerActorId?S.ownerActorId:void 0,L.actor.id);return O({ok:!0,finding:D})}catch(D){return O({ok:!1,error:D instanceof Error?D.message:"Security finding could not be updated."},422)}}if(U.pathname==="/api/security/comments"&&C.method==="POST"){let S=await v(C),L=nt(Y);if(!L.actor)return O({ok:!1,error:"An organization actor is required."},403);try{return O({ok:!0,comment:ct.addComment({findingId:String(S.findingId??""),actorId:L.actor.id,body:String(S.body??""),referenceUrl:typeof S.referenceUrl==="string"?S.referenceUrl:void 0})},201)}catch(l){return O({ok:!1,error:l instanceof Error?l.message:"Comment could not be saved."},422)}}if(U.pathname==="/api/auth/sessions"&&C.method==="GET"){let S=kt.resolveSession(C);return O({currentSessionId:S?.id,sessions:S?Q.listSessions(S.identityId,{includeInactive:!0}):[]})}if(U.pathname==="/api/auth/sessions"&&C.method==="DELETE"){let S=await v(C),L=kt.resolveSession(C);if(!L)return O({ok:!1,error:"Sign in again to manage sessions."},401);let l=String(S.id??""),D=Q.revokeSession(L.identityId,l),g=l===L.id&&D?{"set-cookie":vh({secure:Xd})}:void 0;return O({ok:D,signedOut:l===L.id&&D},D?200:404,g)}if(U.pathname==="/api/auth/sessions/revoke-others"&&C.method==="POST"){let S=kt.resolveSession(C);if(!S)return O({ok:!1,error:"Sign in again to manage sessions."},401);return O({ok:!0,revoked:Q.revokeOtherSessions(S.identityId,S.id)})}if(U.pathname==="/api/auth/password/change"&&C.method==="POST"){let S=await v(C),L=String(S.currentPassword??""),l=String(S.password??""),D=nt(Y),g=D.actor?Q.getIdentityByActor(D.actor.id):void 0;if(!g||!Hr(L,g.passwordHash))return O({ok:!1,error:"Current password is incorrect."},401);if(l.length<12)return O({ok:!1,error:"New password must be at least 12 characters."},422);if(Hr(l,g.passwordHash))return O({ok:!1,error:"Choose a different password."},409);let X=EE(l),y=Q.updatePassword(g.id,X);Mh(e,y.username,X);let z=tT(y.id,C,Ct.requestIP(C)?.address??"unknown");return c.store.appendEvent({organizationId:c.organization.id,actorId:y.actorId,type:"auth.password.changed"}),O({ok:!0,message:"Password changed and other sessions were signed out."},200,{"set-cookie":Dc(z.token,{secure:Xd,maxAgeMs:Qd})})}if(U.pathname==="/api/auth/mfa/enroll"&&C.method==="POST"){let S=await v(C),L=kt.resolveSession(C),l=nt(Y),D=l.actor?Q.getIdentityByActor(l.actor.id):void 0;if(!L||!D)return O({ok:!1,error:"Sign in again before enabling MFA."},401);if(!Hr(String(S.password??""),D.passwordHash))return O({ok:!1,error:"Current password is incorrect."},401);try{let g=Q.beginTotpEnrollment(D.id,{issuer:c.organization.name});return c.store.appendEvent({organizationId:c.organization.id,actorId:D.actorId,type:"auth.mfa.enrollment.started"}),O({factor:g.factor,secret:g.secret,uri:g.uri})}catch(g){return O({ok:!1,error:g instanceof Error?g.message:"MFA enrollment failed."},409)}}if(U.pathname==="/api/auth/mfa/verify"&&C.method==="POST"){let S=await v(C),L=kt.resolveSession(C),l=nt(Y),D=l.actor?Q.getIdentityByActor(l.actor.id):void 0;if(!L||!D)return O({ok:!1,error:"Sign in again before enabling MFA."},401);try{let g=Q.verifyTotpEnrollment(D.id,String(S.code??""));return Q.markSessionStepUp(L.id,!0),c.store.appendEvent({organizationId:c.organization.id,actorId:D.actorId,type:"auth.mfa.enabled",payload:{recoveryCodeCount:g.recoveryCodes.length}}),O(g)}catch(g){return O({ok:!1,error:g instanceof Error?g.message:"MFA enrollment failed."},422)}}if(U.pathname==="/api/auth/mfa"&&C.method==="DELETE"){let S=await v(C),L=kt.resolveSession(C),l=nt(Y),D=l.actor?Q.getIdentityByActor(l.actor.id):void 0;if(!L||!D||!Hr(String(S.password??""),D.passwordHash))return O({ok:!1,error:"Current password is incorrect."},401);let g=Q.verifyMfaCode(D.id,String(S.code??""));if(!g.valid||!g.method)return O({ok:!1,error:"Authenticator or recovery code is incorrect."},401);return Q.disableMfa(D.id),Q.revokeOtherSessions(D.id,L.id),Q.markSessionStepUp(L.id),c.store.appendEvent({organizationId:c.organization.id,actorId:D.actorId,type:"auth.mfa.disabled",payload:{method:g.method}}),O({ok:!0})}if(U.pathname==="/api/auth/step-up"&&C.method==="POST"){let S=await v(C),L=kt.resolveSession(C),l=nt(Y),D=l.actor?Q.getIdentityByActor(l.actor.id):void 0;if(!L||!D||!Hr(String(S.password??""),D.passwordHash))return O({ok:!1,error:"Current password is incorrect."},401);let g=Q.getMfaFactor(D.id);if(g?.state==="active"){if(!Q.verifyMfaCode(D.id,String(S.code??"")).valid)return O({ok:!1,error:"Authenticator or recovery code is incorrect."},401)}let X=Q.markSessionStepUp(L.id,g?.state==="active");return c.store.appendEvent({organizationId:c.organization.id,actorId:D.actorId,type:"auth.step_up.succeeded",payload:{mfa:g?.state==="active"}}),O({ok:!0,recentAuthAt:X.recentAuthAt})}if(U.pathname==="/api/terminal"){if(!$)return O({ok:!1,error:"The web terminal is disabled."},403);if(Ct.upgrade(C))return;return sh("WebSocket upgrade failed",400)}if(U.pathname==="/api/health"){let S=c.store.health();return O({ok:!0,cwd:e,environment:V,environments:_,uiRoot:await Et(Y,V),liveData:F.size>0,terminal:$,localPackage:import.meta.url.includes("/Code/Libraries/ts-cloud/"),controlPlane:{schemaVersion:S.schemaVersion,supportedSchemaVersion:S.supportedSchemaVersion,integrity:S.integrity,pendingRetryableOperations:S.pendingRetryableOperations}})}if(U.pathname==="/api/control-plane/operations"){let S=U.searchParams.get("state"),L=S&&["queued","running","succeeded","failed","cancelled","timed_out"].includes(S)?S:void 0;return O({operations:c.store.listOperations({projectId:c.project.id,state:L,kind:U.searchParams.get("kind")??void 0,limit:Number(U.searchParams.get("limit"))||100})})}if(U.pathname==="/api/queue"&&C.method==="GET"){let S=U.searchParams.get("state"),L=S&&["queued","running","succeeded","failed","cancelled","timed_out"].includes(S)?S:void 0,l=zt.list({projectId:c.project.id,state:L,limit:Number(U.searchParams.get("limit"))||250}).filter((D)=>En(Y,D.operation.id,"deployments:read")).map((D)=>{let g=D.operation.resourceId?c.store.getResource(D.operation.resourceId):void 0,X=D.operation.environmentId?c.store.listEnvironments(c.project.id).find((M)=>M.id===D.operation.environmentId):void 0,y=D.operation.actorId?c.store.getActor(D.operation.actorId):void 0,z=D.operation.input;return{...D,target:g?{id:g.id,name:g.name,slug:g.slug,kind:g.kind}:X?{id:X.id,name:X.name,slug:X.slug,kind:"environment"}:{id:c.project.id,name:c.project.name,slug:c.project.slug,kind:"project"},actor:y?{id:y.id,name:y.displayName,kind:y.kind}:void 0,commit:z.revision??z.source?.commitSha??null}});return O({operations:l,concurrency:zt.limits})}if(U.pathname==="/api/queue/logs"&&C.method==="GET"){let S=String(U.searchParams.get("id")??"");if(!En(Y,S,"deployments:read"))return O({ok:!1,error:"Operation was not found in this scope."},404);let L=zt.logs(S,{after:Number(U.searchParams.get("after"))||0,limit:Number(U.searchParams.get("limit"))||500});return O({entries:L,cursor:L.at(-1)?.sequence??(Number(U.searchParams.get("after"))||0),operation:c.store.getOperation(S)})}if(U.pathname==="/api/queue/stream"&&C.method==="GET"){let S=String(U.searchParams.get("id")??"");if(!En(Y,S,"deployments:read"))return O({ok:!1,error:"Operation was not found in this scope."},404);let L=C.headers.get("last-event-id")?.trim(),l=Number(L||U.searchParams.get("after")||0),D=new TextEncoder,g,X=!1,y=new ReadableStream({start(z){let M=()=>{if(X)return;let b=kt.resolveUser(C);if(!b||!En(b,S,"deployments:read")){if(X=!0,g)clearInterval(g);z.close();return}let wt=zt.logs(S,{after:l,limit:500});for(let _t of wt)l=_t.sequence,z.enqueue(D.encode(`id: ${_t.sequence}
|
|
6648
6648
|
event: log
|
|
6649
6649
|
data: ${JSON.stringify(_t)}
|
|
6650
6650
|
|
|
@@ -6668,4 +6668,4 @@ data: ${JSON.stringify({message:RE instanceof Error?RE.message:String(RE)})}
|
|
|
6668
6668
|
data: ${JSON.stringify({cursor:et,at:new Date().toISOString()})}
|
|
6669
6669
|
|
|
6670
6670
|
`))},5000),lt.unref?.(),C.signal.addEventListener("abort",ad,{once:!0})},cancel(){if(Ut=!0,lt)clearInterval(lt)}});return new Response(oe,{headers:{"cache-control":"no-cache, no-transform",connection:"keep-alive","content-type":"text/event-stream; charset=utf-8","x-accel-buffering":"no"}})}if(U.pathname==="/api/telemetry/series"&&C.method==="GET"){b(!1);let k=wt(),_t=["sum","avg","min","max","count","p50","p90","p95","p99"].includes(String(M.aggregation))?M.aggregation:"avg",K=z({...M,kinds:"metric",limit:5000}),et=L.series({...K,bucketMs:Number(M.bucketMs)||60000,aggregation:_t,timezone:String(M.timezone??"UTC"),compareFrom:M.compareFrom,compareTo:M.compareTo});return O({ok:!0,collection:{generatedAt:k.generatedAt,cached:k.cached},query:{aggregation:_t,bucketMs:Number(M.bucketMs)||60000,timezone:String(M.timezone??"UTC")},series:et})}if(U.pathname==="/api/telemetry/refresh"&&C.method==="POST")return O({ok:!0,...await b(!0)});if(U.pathname==="/api/telemetry/export"&&C.method==="POST"){let k=await v(C);await b(!1);let _t=L.query({...z(k),limit:Math.min(5000,Number(k.limit)||5000),cursor:void 0});if((k.format==="csv"?"csv":"json")==="json")return new Response(JSON.stringify({exportedAt:new Date().toISOString(),query:z(k),..._t},null,2),{headers:{"content-disposition":'attachment; filename="ts-cloud-telemetry.json"',"content-type":"application/json; charset=utf-8"}});let et=["timestamp","kind","source","name","level","value","unit","message","traceId","requestId","deploymentId","releaseId","workloadId"],lt=[et.join(","),..._t.records.map((Ut)=>et.map((Ft)=>`"${String(Ut[Ft]??"").replaceAll('"','""')}"`).join(","))].join(`
|
|
6671
|
-
`);return new Response(lt,{headers:{"content-disposition":'attachment; filename="ts-cloud-telemetry.csv"',"content-type":"text/csv; charset=utf-8"}})}if(U.pathname==="/api/telemetry/saved-queries"&&C.method==="GET"){let k=nt(Y);return O({ok:!0,queries:L.listSavedQueries(c.project.id,k.actor?.id)})}if(U.pathname==="/api/telemetry/saved-queries"&&C.method==="POST"){let k=await v(C),_t=nt(Y);return O({ok:!0,query:L.saveQuery(c.project.id,_t.actor?.id,String(k.name??""),z(k.query??k))},201)}if(U.pathname==="/api/telemetry/saved-queries"&&C.method==="DELETE"){let k=await v(C),_t=nt(Y),K=L.deleteSavedQuery(c.project.id,_t.actor?.id,String(k.id??""));return O({ok:K},K?200:404)}}if(U.pathname.startsWith("/api/configuration")){let S=c.environments.get(V),L=Y.role==="admin"||!!Tr.capabilities?.includes("secrets:read"),l=Y.role==="admin"||!!Tr.capabilities?.includes("secrets:write"),D={projectId:c.project.id,environmentId:S?.id},g={"cache-control":"no-store"};if(U.pathname==="/api/configuration"&&C.method==="GET"){let X=Object.fromEntries(U.searchParams),y=X.scopeType||X.scopeId?wc(X,D):void 0,z=["variable","secret"].includes(String(X.kind))?X.kind:void 0,M=y?.type==="preview"?st.previews.getInstance(y.id):void 0,b=M?st.previews.getDefinition(M.definitionId):void 0,wt=y?await Ge.resolve({projectId:c.project.id,environmentId:y.environmentId,resourceId:y.resourceId,functionId:y.type==="function"?y.id:void 0,previewId:y.previewId,trustedPreview:!!M&&!M.fork,allowedPreviewSecrets:b?.inheritedSecrets,nativeReferences:!0,canReadSecretMetadata:L}):void 0,k=c.store.listResources(c.project.id);return O({ok:!0,entries:Ge.list({projectId:c.project.id,scope:y,kind:z,search:X.search,canReadSecretMetadata:L}),effectiveEntries:wt?Object.values(wt.entries).filter((_t)=>!z||_t.kind===z).filter((_t)=>!X.search||_t.key.toLowerCase().includes(String(X.search).toLowerCase())):[],configurationHash:wt?.configurationHash,warnings:wt?.warnings??[],scopes:{project:c.project,environments:c.store.listEnvironments(c.project.id),resources:k.filter((_t)=>_t.kind!=="function"),functions:k.filter((_t)=>_t.kind==="function"),previews:st.previews.listInstances({projectId:c.project.id}).filter((_t)=>_t.status!=="destroyed").map((_t)=>({id:_t.id,name:_t.name,environmentId:_t.baseEnvironmentId,resourceId:_t.resourceId,fork:_t.fork,status:_t.status}))}},200,g)}if(U.pathname==="/api/configuration/export"&&C.method==="GET"){let X=wc(Object.fromEntries(U.searchParams),D);return new Response(Ge.exportVariables({projectId:c.project.id,scope:X}),{headers:{...g,"content-disposition":'attachment; filename="ts-cloud.env"',"content-type":"text/plain; charset=utf-8"}})}if(U.pathname==="/api/configuration/plan"&&C.method==="POST"){let X=await v(C),y=wc(X,D),z=X.values&&typeof X.values==="object"&&!Array.isArray(X.values)?Object.fromEntries(Object.entries(X.values).map(([M,b])=>[M,String(b)])):{};return O({ok:!0,plan:Ge.plan({projectId:c.project.id,scope:y,values:z,removeMissing:X.removeMissing===!0})},200,g)}if(U.pathname==="/api/configuration"&&C.method==="POST"){let X=await v(C),y=wc(X,D),z=X.kind==="secret"?"secret":"variable",M=String(X.key??"");if(z==="secret"&&!l)return O({ok:!1,error:"Secret write permission is required."},403,g);try{let b=await Ge.set({organizationId:c.organization.id,projectId:c.project.id,scope:y,key:M,kind:z,value:X.value==null?void 0:String(X.value),reference:X.reference==null?void 0:String(X.reference),backend:X.backend,required:X.required===!0,expectedVersion:X.expectedVersion==null?void 0:Number(X.expectedVersion),confirmed:String(X.confirm??"")===M,idempotencyKey:C.headers.get("idempotency-key")??X.idempotencyKey,actorId:nt(Y).actor?.id});return O({ok:!0,entry:Ge.list({projectId:c.project.id,scope:y,canReadSecretMetadata:L}).find((wt)=>wt.id===b.entry.id),mutation:b.mutation,warnings:b.warnings},b.mutation.added.length?201:200,g)}catch(b){return O({ok:!1,error:b instanceof Error?b.message:String(b)},409,g)}}if(U.pathname==="/api/configuration/import"&&C.method==="POST"){let X=await v(C),y=wc(X,D),z=Array.isArray(X.secretKeys)?X.secretKeys.map(String):[];if(z.length&&!l)return O({ok:!1,error:"Secret write permission is required."},403,g);try{let M=await Ge.importDotenv({organizationId:c.organization.id,projectId:c.project.id,scope:y,source:String(X.source??""),secretKeys:z,backend:X.backend,confirmed:X.confirm==="import",idempotencyKey:C.headers.get("idempotency-key")??X.idempotencyKey,actorId:nt(Y).actor?.id});return O({ok:M.document.valid,diagnostics:M.document.diagnostics,mutation:M.mutation,warnings:M.warnings},M.document.valid?200:422,g)}catch(M){return O({ok:!1,error:M instanceof Error?M.message:String(M)},409,g)}}if(U.pathname==="/api/configuration/dependencies"&&C.method==="POST"){let X=await v(C),y=wd.get(String(X.entryId??"")),z=c.store.getResource(String(X.resourceId??""));if(!y||y.projectId!==c.project.id||!z||z.projectId!==c.project.id)return O({ok:!1,error:"Configuration entry or dependent resource was not found."},404,g);return O({ok:!0,dependency:wd.setDependency({entryId:y.id,resourceId:z.id,injectionTarget:["native_reference","file"].includes(String(X.injectionTarget))?X.injectionTarget:"environment",required:X.required!==!1,requiresRedeploy:X.requiresRedeploy!==!1,lastDeployedVersion:X.lastDeployedVersion==null?void 0:Number(X.lastDeployedVersion)})},200,g)}if(U.pathname==="/api/configuration/transfer"&&C.method==="POST"){let X=await v(C),y=wd.get(String(X.id??"")),z=wc({...X,scopeType:X.targetScopeType,scopeId:X.targetScopeId},D);if(!y||y.projectId!==c.project.id)return O({ok:!1,error:"Configuration entry was not found."},404,g);if(y.kind==="secret"&&!l)return O({ok:!1,error:"Secret write permission is required."},403,g);try{let M=await Ge.transfer({entryId:y.id,targetScope:z,mode:X.mode==="move"?"move":"copy",confirmed:X.confirm===y.key,actorId:nt(Y).actor?.id,idempotencyKey:C.headers.get("idempotency-key")??X.idempotencyKey});return O({ok:!0,entry:Ge.list({projectId:c.project.id,scope:z,canReadSecretMetadata:L}).find((b)=>b.id===M.entry.id),mutation:M.mutation},200,g)}catch(M){return O({ok:!1,error:M instanceof Error?M.message:String(M)},409,g)}}if(U.pathname==="/api/configuration/bulk"&&C.method==="POST"){let X=await v(C),y=Array.isArray(X.ids)?X.ids.map(String).slice(0,500):[],z=y.map((b)=>wd.get(b)).filter((b)=>!!b&&b.projectId===c.project.id);if(z.length!==y.length)return O({ok:!1,error:"One or more configuration entries were not found."},404,g);if(z.some((b)=>b.kind==="secret")&&!l)return O({ok:!1,error:"Secret write permission is required."},403,g);if(X.action!=="delete"||X.confirm!=="bulk")return O({ok:!1,error:"Bulk deletion requires action delete and confirm bulk."},409,g);let M=[];try{for(let b of z)M.push(await Ge.remove({entryId:b.id,expectedVersion:b.version,confirmed:!0,actorId:nt(Y).actor?.id}));return O({ok:!0,removed:M.flatMap((b)=>b.removed),affectedResourceIds:[...new Set(M.flatMap((b)=>b.affectedResourceIds))].sort()},200,g)}catch(b){return O({ok:!1,error:b instanceof Error?b.message:String(b),partial:M.flatMap((wt)=>wt.removed)},409,g)}}if(U.pathname==="/api/configuration/reveal"&&C.method==="POST"){let X=await v(C),y=kt.resolveSession(C);try{return O({ok:!0,value:await Ge.reveal({entryId:String(X.id??""),canRevealSecrets:L,recentlyAuthenticated:!G||!!y&&Q.isRecentlyAuthenticated(y),actorId:nt(Y).actor?.id})},200,g)}catch(z){return O({ok:!1,error:z instanceof Error?z.message:String(z)},403,g)}}if(U.pathname==="/api/configuration"&&C.method==="DELETE"){let X=await v(C),y=wd.get(String(X.id??""));if(y?.kind==="secret"&&!l)return O({ok:!1,error:"Secret write permission is required."},403,g);if(!y||y.projectId!==c.project.id)return O({ok:!1,error:"Configuration entry was not found."},404,g);try{return O({ok:!0,mutation:await Ge.remove({entryId:y.id,expectedVersion:Number(X.expectedVersion),confirmed:String(X.confirm??"")===y.key,actorId:nt(Y).actor?.id})},200,g)}catch(z){return O({ok:!1,error:z instanceof Error?z.message:String(z)},409,g)}}}if(U.pathname.startsWith("/api/fleet")){let S=nt(Y).actor?.id,L=(l,D=409)=>O({ok:!1,error:l instanceof Error?l.message:String(l)},D,{"cache-control":"no-store"});if(U.pathname==="/api/fleet"&&C.method==="GET")return O({ok:!0,servers:yc.list(c.project.id),resources:c.store.listResources(c.project.id),operations:zt.list({projectId:c.project.id,limit:200}).filter((l)=>l.operation.kind.startsWith("fleet."))},200,{"cache-control":"no-store"});if(U.pathname==="/api/fleet"&&C.method==="POST"){let l=await v(C);try{return O({ok:!0,server:Wr.enroll({organizationId:c.organization.id,projectId:c.project.id,name:String(l.name??""),provider:["aws","hetzner"].includes(String(l.provider))?l.provider:"ssh",providerId:l.providerId?String(l.providerId):void 0,region:l.region?String(l.region):void 0,zone:l.zone?String(l.zone):void 0,endpoint:String(l.endpoint??""),sshUser:String(l.sshUser??"deploy"),sshPort:l.sshPort?Number(l.sshPort):22,credentialRef:String(l.credentialRef??""),roles:Array.isArray(l.roles)?l.roles:[],labels:l.labels&&typeof l.labels==="object"?l.labels:{}})},201)}catch(D){return L(D,422)}}if(U.pathname==="/api/fleet/action"&&C.method==="POST"){let l=await v(C),D=String(l.id??""),g=String(l.action??"");try{if(g==="test")return O({ok:!0,server:await Wr.test(D)});if(g==="validate")return O({ok:!0,server:await Wr.validate(D)});if(g==="review_host_key")return O({ok:!0,server:Wr.reviewHostKey(D,String(l.fingerprint??""))});if(g==="bootstrap")return O({ok:!0,...Wr.bootstrap(D,l.confirmed===!0)},l.confirmed===!0?202:200);if(g==="heartbeat")return O({ok:!0,server:Wr.heartbeat(D,{usage:l.usage&&typeof l.usage==="object"?l.usage:{}})});if(g==="drain")return O({ok:!0,server:Wr.drain(D,l.completed===!0)});if(g==="uncordon")return O({ok:!0,server:Wr.uncordon(D)});if(g==="archive")return O({ok:!0,server:Wr.archive(D,String(l.confirmation??""))});return L("Unsupported fleet action.",422)}catch(X){return L(X)}}}if(U.pathname.startsWith("/api/capacity")){let S=(L,l=409)=>O({ok:!1,error:L instanceof Error?L.message:String(L)},l,{"cache-control":"no-store"});if(U.pathname==="/api/capacity"&&C.method==="GET")return O({ok:!0,pools:$d.listPools(c.project.id),placements:$d.listPlacements(c.project.id),servers:yc.list(c.project.id)},200,{"cache-control":"no-store"});if(U.pathname==="/api/capacity"&&C.method==="POST"){let L=await v(C);try{return O({ok:!0,pool:$d.createPool({organizationId:c.organization.id,projectId:c.project.id,name:String(L.name??""),purpose:String(L.purpose??"application"),backend:String(L.backend??"server"),region:L.region?String(L.region):void 0,architecture:L.architecture?String(L.architecture):void 0,labels:L.labels&&typeof L.labels==="object"?L.labels:{},requiredServerLabels:L.requiredServerLabels&&typeof L.requiredServerLabels==="object"?L.requiredServerLabels:{},toleratedTaints:Array.isArray(L.toleratedTaints)?L.toleratedTaints.map(String):[],capacity:L.capacity&&typeof L.capacity==="object"?L.capacity:{},maxWorkloads:Number(L.maxWorkloads??10),costWeight:Number(L.costWeight??1),spreadKey:L.spreadKey?String(L.spreadKey):void 0,concurrency:Number(L.concurrency??1),ephemeralWorkspaces:!0,allowProductionSecrets:!1,status:"active"})},201)}catch(l){return S(l,422)}}if(U.pathname==="/api/capacity/member"&&C.method==="POST"){let L=await v(C);try{return $d.addMember(String(L.poolId??""),String(L.serverId??"")),O({ok:!0,pool:$d.getPool(String(L.poolId??""))})}catch(l){return S(l,422)}}if(U.pathname==="/api/capacity/explain"&&C.method==="POST"){let L=await v(C);try{return O({ok:!0,decisions:cu.explain(c.project.id,{purpose:String(L.purpose??"application"),resources:L.resources&&typeof L.resources==="object"?L.resources:{},region:L.region?String(L.region):void 0,architecture:L.architecture?String(L.architecture):void 0,labels:L.labels&&typeof L.labels==="object"?L.labels:{}})})}catch(l){return S(l,422)}}if(U.pathname==="/api/capacity/action"&&C.method==="POST"){let L=await v(C);try{if(L.action==="drain")return O({ok:!0,...cu.drainPool(String(L.poolId??""))});if(L.action==="enable")return O({ok:!0,pool:$d.updatePool(String(L.poolId??""),{status:"active"})});if(L.action==="disable")return O({ok:!0,pool:$d.updatePool(String(L.poolId??""),{status:"disabled"})});return S("Unsupported capacity action.",422)}catch(l){return S(l,422)}}}if(U.pathname.startsWith("/api/regions")){let S=(L,l=409)=>O({ok:!1,error:L instanceof Error?L.message:String(L)},l,{"cache-control":"no-store"});if(U.pathname==="/api/regions"&&C.method==="GET")return O({ok:!0,topologies:iE.list(c.project.id).map((L)=>({topology:L,targets:iE.targets(L.id),channels:iE.channels(L.id),route:iE.route(L.id),executions:iE.executions(L.id)}))},200,{"cache-control":"no-store"});if(U.pathname==="/api/regions"&&C.method==="POST"){let L=await v(C);try{return O({ok:!0,topology:_u.create({organizationId:c.organization.id,projectId:c.project.id,environmentId:c.environments.get(V)?.id,name:String(L.name??""),hostname:String(L.hostname??""),regions:Array.isArray(L.regions)?L.regions:[],trafficPolicy:L.trafficPolicy==="weighted"||L.trafficPolicy==="latency"?L.trafficPolicy:"active_passive",dataPolicy:{replicate:Array.isArray(L.replicate)?L.replicate:["s3","dynamodb","secrets"],maxLagSeconds:Number(L.maxLagSeconds??30),retainOnDestroy:L.retainOnDestroy!==!1},dnsProvider:"route53",cdnEnabled:L.cdnEnabled===!0,wafEnabled:L.wafEnabled===!0})},201)}catch(l){return S(l,422)}}if(U.pathname==="/api/regions/action"&&C.method==="POST"){let L=await v(C);try{return O({ok:!0,..._u.enqueue({topologyId:String(L.topologyId??""),kind:String(L.action??""),targetRegion:L.targetRegion?String(L.targetRegion):void 0,revision:L.revision?String(L.revision):void 0,manifest:L.manifest&&typeof L.manifest==="object"?L.manifest:{},confirmation:L.confirmation?String(L.confirmation):void 0,deleteData:L.deleteData===!0})},202)}catch(l){return S(l,422)}}}if(U.pathname.startsWith("/api/maintenance")){let S=(L,l=409)=>O({ok:!1,error:L instanceof Error?L.message:String(L)},l,{"cache-control":"no-store"});if(U.pathname==="/api/maintenance"&&C.method==="GET")return O({ok:!0,manifests:td.manifests(c.organization.id),windows:td.windows(c.project.id),campaigns:td.campaigns(c.project.id).map((L)=>({campaign:L,targets:td.targets(L.id)})),cleanups:td.cleanups(c.project.id),drills:td.drills(c.project.id)},200,{"cache-control":"no-store"});if(U.pathname==="/api/maintenance/cleanup-preview"&&C.method==="POST"){let L=await v(C);try{return O({ok:!0,plan:await tR.previewCleanup({projectId:c.project.id,kind:String(L.kind??"operations"),criteria:{olderThanDays:Number(L.olderThanDays??30)}},Tu)},201)}catch(l){return S(l,422)}}if(U.pathname==="/api/maintenance/cleanup-apply"&&C.method==="POST"){let L=await v(C);try{return O({ok:!0,...tR.enqueueCleanup(String(L.planId??""),String(L.confirmation??""))},202)}catch(l){return S(l,422)}}if(U.pathname==="/api/maintenance/drill"&&C.method==="POST"){let L=await v(C);try{return O({ok:!0,drill:td.createDrill({projectId:c.project.id,scenario:String(L.scenario??"control_plane"),isolatedTarget:String(L.isolatedTarget??""),expectedRpoMinutes:Number(L.expectedRpoMinutes??60),expectedRtoMinutes:Number(L.expectedRtoMinutes??30),recoveryPointId:L.recoveryPointId?String(L.recoveryPointId):void 0,topologyId:L.topologyId?String(L.topologyId):void 0})},201)}catch(l){return S(l,422)}}if(U.pathname==="/api/maintenance/drill-run"&&C.method==="POST"){let L=await v(C);try{return O({ok:!0,...tR.enqueueDrill(String(L.drillId??""))},202)}catch(l){return S(l,422)}}}if(U.pathname.startsWith("/api/volumes")){let S=c.environments.get(V),L=nt(Y).actor?.id,l=(D,g=409)=>O({ok:!1,error:D instanceof Error?D.message:String(D)},g,{"cache-control":"no-store"});if(U.pathname==="/api/volumes"&&C.method==="GET"){let D=mh.inventory(c.project.id,S?.id),g=c.store.listResources(c.project.id,S?.id).map((X)=>({id:X.id,name:X.name,slug:X.slug,kind:X.kind,provider:X.provider,providerId:X.providerId}));return O({ok:!0,volumes:D,resources:g,operations:zt.list({projectId:c.project.id,limit:100}).filter((X)=>X.operation.kind.startsWith("volume.")),recoveryPoints:ee.listRecoveryPoints(c.project.id).filter((X)=>X.kind==="volume"),providers:ph.map((X)=>({provider:X.provider,type:X.type,capabilities:X.capabilities()}))},200,{"cache-control":"no-store"})}if(U.pathname==="/api/volumes"&&C.method==="POST"){let D=await v(C);try{return O({ok:!0,...pr.create({organizationId:c.organization.id,projectId:c.project.id,environmentId:S?.id,resourceId:D.resourceId?String(D.resourceId):void 0,name:String(D.name??""),provider:String(D.provider??"docker"),type:D.type==="docker"?"docker":D.type,capacityBytes:D.capacityBytes==null?void 0:Number(D.capacityBytes),filesystem:D.filesystem?String(D.filesystem):void 0,encrypted:D.encrypted===!0,desiredState:D.desiredState&&typeof D.desiredState==="object"?D.desiredState:{},actorId:L})},202,{"cache-control":"no-store"})}catch(g){return l(g,422)}}if(U.pathname==="/api/volumes/attach"&&C.method==="POST"){let D=await v(C);try{return O({ok:!0,...pr.attach(String(D.volumeId??""),{resourceId:String(D.resourceId??""),targetPath:String(D.targetPath??""),readOnly:D.readOnly===!0,uid:D.uid==null?void 0:Number(D.uid),gid:D.gid==null?void 0:Number(D.gid),mode:D.mode?String(D.mode):void 0,propagation:D.propagation,driverOptions:D.driverOptions&&typeof D.driverOptions==="object"?D.driverOptions:{},actorId:L})},202)}catch(g){return l(g,422)}}if(U.pathname==="/api/volumes/detach"&&C.method==="POST"){let D=await v(C);try{return O({ok:!0,...pr.detach(String(D.volumeId??""),String(D.attachmentId??""),{force:D.force===!0,drained:D.drained===!0,unmounted:D.unmounted===!0,confirmation:D.confirmation?String(D.confirmation):void 0,actorId:L})},202)}catch(g){return l(g)}}if(U.pathname==="/api/volumes/resize"&&C.method==="POST"){let D=await v(C);try{return O({ok:!0,...pr.resize(String(D.volumeId??""),Number(D.capacityBytes),{drained:D.drained===!0,actorId:L})},202)}catch(g){return l(g,422)}}if(U.pathname==="/api/volumes/snapshot"&&C.method==="POST"){let D=await v(C);try{return O({ok:!0,...pr.snapshot(String(D.volumeId??""),{name:D.name?String(D.name):void 0,actorId:L})},202)}catch(g){return l(g,422)}}if(U.pathname==="/api/volumes/restore"&&C.method==="POST"){let D=await v(C);try{return O({ok:!0,...pr.restore(String(D.snapshotId??""),{name:String(D.name??""),actorId:L})},202)}catch(g){return l(g,422)}}if(U.pathname==="/api/volumes/discover"&&C.method==="POST")try{return O({ok:!0,volumes:await pr.discover({organizationId:c.organization.id,projectId:c.project.id,environmentId:S?.id,actorId:L})})}catch(D){return l(D,502)}if(U.pathname==="/api/volumes/adopt"&&C.method==="POST"){let D=await v(C);try{return O({ok:!0,volume:pr.adopt(String(D.volumeId??""),{name:String(D.name??""),actorId:L})})}catch(g){return l(g,422)}}if(U.pathname==="/api/volumes"&&C.method==="DELETE"){let D=await v(C),g=kt.resolveSession(C);try{return O({ok:!0,...pr.delete(String(D.volumeId??""),{recentAuthAt:!G||g&&Q.isRecentlyAuthenticated(g)?new Date().toISOString():void 0,confirmation:D.confirmation?String(D.confirmation):void 0,backupOverride:D.backupOverride===!0,backupOverrideConfirmation:D.backupOverrideConfirmation?String(D.backupOverrideConfirmation):void 0,actorId:L})},202)}catch(X){return l(X)}}}if(U.pathname==="/api/backups"&&C.method==="GET"){let S=c.environments.get(V),L=ee.listPolicies(c.project.id,S?.id),l=new Set(L.map((z)=>z.id)),D=ee.listRecoveryPoints(c.project.id).filter((z)=>!z.policyId||l.has(z.policyId)),g=ee.listJobs(c.project.id).filter((z)=>!z.policyId||l.has(z.policyId)),X=(z)=>({...z,credentialRef:void 0,encryptionKeyRef:void 0,credentialsConfigured:!!z.credentialRef,clientEncryptionConfigured:!!z.encryptionKeyRef}),y=await Promise.all(ee.listDestinations(c.project.id).map(async(z)=>({...X(z),credentialStatus:await Rl(z,se)})));return O({ok:!0,destinations:y,policies:L,recoveryPoints:D,jobs:g,coverage:ee.coverage(c.project.id).filter((z)=>l.has(z.policy.id)),resources:S?c.store.listResources(c.project.id,S.id).map((z)=>({id:z.id,name:z.name,slug:z.slug,kind:z.kind})):[]})}if(U.pathname==="/api/backups/destinations"&&C.method==="POST"){let S=await v(C),L=String(S.name??"").trim(),l=String(S.provider??""),D=String(S.encryption??"provider"),g=`secret://data-services/backups/${c.project.id}/${L}`,X=[];if(!["aws_s3","s3_compatible","aws_backup"].includes(l))return O({ok:!1,error:"A supported backup destination provider is required."},422);if(!["provider","client_side","both"].includes(D))return O({ok:!1,error:"Encryption must be provider, client_side, or both."},422);try{let y,z;if(S.credentials&&typeof S.credentials==="object"&&!Array.isArray(S.credentials))y=`${g}/credentials`,await se.put(y,JSON.stringify(S.credentials)),X.push(y);if(D!=="provider"){let b=String(S.encryptionKey??"");if(b.length<32)throw Error("Client-side encryption keys must contain at least 32 characters.");z=`${g}/encryption-key`,await se.put(z,b),X.push(z)}let M=ee.createDestination({organizationId:c.organization.id,projectId:c.project.id,name:L,provider:l,endpoint:S.endpoint?String(S.endpoint):void 0,endpointPolicy:S.endpointPolicy==="allow_private"?"allow_private":"public_https",bucket:S.bucket?String(S.bucket):void 0,prefix:String(S.prefix??""),region:S.region?String(S.region):gd,forcePathStyle:S.forcePathStyle===!0,credentialRef:y,encryption:D,encryptionKeyRef:z,immutability:S.immutability&&typeof S.immutability==="object"&&!Array.isArray(S.immutability)?S.immutability:{},status:"untested"});return O({ok:!0,destination:{...M,credentialRef:void 0,encryptionKeyRef:void 0,credentialsConfigured:!!y,clientEncryptionConfigured:!!z}},201)}catch(y){for(let z of X)await se.remove(z).catch(()=>{});return O({ok:!1,error:y instanceof Error?y.message:String(y)},422)}}if(U.pathname==="/api/backups/destinations/test"&&C.method==="POST"){let S=await v(C),L=ee.getDestination(String(S.id??""));if(!L||L.projectId!==c.project.id)return O({ok:!1,error:"Backup destination was not found."},404);if(L.provider==="aws_backup")return O({ok:!1,error:"AWS Backup destinations are verified by creating a provider recovery point."},422);try{return await nu.test(L),O({ok:!0,destination:ee.recordDestinationTest(L.id,{ok:!0})})}catch(l){let D=l instanceof Error?l.message:String(l);return ee.recordDestinationTest(L.id,{ok:!1,error:D}),O({ok:!1,error:D},502)}}if(U.pathname==="/api/backups/policies"&&C.method==="POST"){let S=await v(C),L=c.environments.get(V),l=ee.getDestination(String(S.destinationId??"")),D=String(S.resourceKind??""),g=S.dataServiceId?String(S.dataServiceId):void 0,X=g?Gt.get(g):void 0,y=S.resourceId?String(S.resourceId):void 0,z=y?c.store.getResource(y):void 0;if(!L)return O({ok:!1,error:"Environment was not found."},404);if(!l||l.projectId!==c.project.id)return O({ok:!1,error:"Backup destination was not found."},404);if(!["managed_database","logical_database","volume","files","control_plane","infrastructure"].includes(D))return O({ok:!1,error:"A supported backup resource kind is required."},422);if(g&&(!X||X.projectId!==c.project.id||X.environmentId!==L.id))return O({ok:!1,error:"Data service was not found in this environment."},404);if(y&&(!z||z.projectId!==c.project.id||z.environmentId!==L.id))return O({ok:!1,error:"Resource was not found in this environment."},404);if(D==="managed_database"&&!X)return O({ok:!1,error:"Managed database policies require a data service."},422);if(D==="logical_database"&&(!X||!["container","server"].includes(X.provider)))return O({ok:!1,error:"Logical database policies require an on-box data service."},422);if(D==="volume"&&(!z||!/^[A-Za-z0-9][A-Za-z0-9_.-]{1,127}$/.test(String(S.volumeName??""))))return O({ok:!1,error:"Volume policies require a scoped resource and valid volumeName."},422);let M=Array.isArray(S.includePatterns)?S.includePatterns.map(String).filter(Boolean):[];if(D==="files"&&(!z||!M.length))return O({ok:!1,error:"File policies require a scoped resource and at least one project-relative include path."},422);if(D==="control_plane"&&l.encryption==="provider")return O({ok:!1,error:"Control-plane policies require a destination with client-side encryption."},422);if(D==="infrastructure"&&(l.provider!=="aws_backup"||!M.some((b)=>b.startsWith("resource:arn:"))||!M.some((b)=>b.startsWith("role:arn:"))))return O({ok:!1,error:"Infrastructure policies require an AWS Backup destination plus resource:<arn> and role:<arn> include values."},422);try{let b=ee.createPolicy({organizationId:c.organization.id,projectId:c.project.id,environmentId:L.id,resourceId:y,dataServiceId:g,destinationId:l.id,name:String(S.name??"").trim(),resourceKind:D,schedule:String(S.schedule??"daily"),timezone:String(S.timezone??"UTC"),retention:S.retention&&typeof S.retention==="object"&&!Array.isArray(S.retention)?S.retention:{keepLast:7,expireAfterDays:30},compression:["none","gzip","zstd"].includes(String(S.compression))?S.compression:"gzip",encryption:["destination","client_side","both"].includes(String(S.encryption))?S.encryption:"destination",includePatterns:D==="volume"?[String(S.volumeName),...M]:M,excludePatterns:Array.isArray(S.excludePatterns)?S.excludePatterns.map(String):[],expectedRpoMinutes:Math.max(1,Number(S.expectedRpoMinutes)||1440),expectedRtoMinutes:Math.max(1,Number(S.expectedRtoMinutes)||120),healthCheckId:S.healthCheckId?String(S.healthCheckId):void 0,enabled:S.enabled!==!1});return O({ok:!0,policy:b},201)}catch(b){return O({ok:!1,error:b instanceof Error?b.message:String(b)},422)}}if(U.pathname==="/api/backups/run"&&C.method==="POST"){let S=await v(C),L=ee.getPolicy(String(S.policyId??"")),l=c.environments.get(V);if(!L||L.projectId!==c.project.id||L.environmentId!==l?.id)return O({ok:!1,error:"Backup policy was not found in this environment."},404);try{let D=TE.enqueueBackup(L,new Date().toISOString(),nt(Y).actor?.id);return O({ok:!0,job:D},202)}catch(D){return O({ok:!1,error:D instanceof Error?D.message:String(D)},409)}}if(U.pathname==="/api/backups/verify"&&C.method==="POST"){let S=await v(C),L=ee.getRecoveryPoint(String(S.recoveryPointId??""));if(!L||L.projectId!==c.project.id)return O({ok:!1,error:"Recovery point was not found."},404);return O({ok:!0,job:TE.enqueueVerification(L)},202)}if(U.pathname==="/api/backups/restore"&&C.method==="POST"){let S=await v(C),L=ee.getRecoveryPoint(String(S.recoveryPointId??"")),l=S.mode==="in_place"?"in_place":"isolated",D=S.target&&typeof S.target==="object"&&!Array.isArray(S.target)?{...S.target,inPlace:l==="in_place"}:{inPlace:l==="in_place"},g=kt.resolveSession(C),X={mode:l,target:D,targetName:String(S.targetName??""),confirm:S.confirm?String(S.confirm):void 0,recentAuth:!G||!!g&&Q.isRecentlyAuthenticated(g),downtimeAcknowledged:S.downtimeAcknowledged===!0,safetyBackupId:S.safetyBackupId?String(S.safetyBackupId):void 0};if(!L||L.projectId!==c.project.id)return O({ok:!1,error:"Recovery point was not found."},404);if(S.drill===!0&&l!=="isolated")return O({ok:!1,error:"Recovery drills must use an isolated target."},422);try{let y=TE.planRestore(L,X);if(S.execute!==!0)return O({ok:!0,plan:y,executionCreated:!1});let z=TE.enqueueRestore(L,{...X,drill:S.drill===!0,actorId:nt(Y).actor?.id});return O({ok:!0,plan:y,job:z},202)}catch(y){return O({ok:!1,error:y instanceof Error?y.message:String(y)},409)}}if(U.pathname==="/api/backups/recovery-points"&&C.method==="POST"){let S=await v(C),L=ee.getRecoveryPoint(String(S.id??""));if(!L||L.projectId!==c.project.id)return O({ok:!1,error:"Recovery point was not found."},404);if(S.held==null&&S.pinned==null)return O({ok:!1,error:"held or pinned must be provided."},422);return O({ok:!0,recoveryPoint:ee.updateRecoveryPoint(L.id,{held:S.held==null?L.held:S.held===!0,pinned:S.pinned==null?L.pinned:S.pinned===!0})})}if(U.pathname==="/api/backups/retention"&&C.method==="POST")return O({ok:!0,jobs:TE.enqueueRetention()},202);if(U.pathname==="/api/data-services/capabilities"&&C.method==="GET"){let S=String(U.searchParams.get("engine")??""),L=String(U.searchParams.get("provider")??"");if(!["postgres","mysql","mariadb","redis","mongodb","libsql"].includes(S)||!["aws_rds","aws_aurora","aws_elasticache","server","container","external"].includes(L))return O({ok:!1,error:"A supported engine and provider are required."},422);return O({ok:!0,engine:S,provider:L,capabilities:i_(S,L)})}if(U.pathname==="/api/data-services"&&C.method==="GET"){let S=c.environments.get(V),L=Gt.list(c.project.id,S?.id).map((l)=>{let D=Gt.credential(l.id);return{...l,credentialRef:void 0,credential:D?{configured:!0,username:D.username,version:D.version,rotatedAt:D.rotatedAt}:void 0,dependencies:Gt.dependencies(l.id).map((g)=>({resourceId:g.resourceId,requiresRedeploy:g.requiresRedeploy}))}});return O({ok:!0,services:L})}if(U.pathname==="/api/data-services/preview"&&C.method==="POST"){let S=await v(C);if(S.id){let D=Gt.get(String(S.id)),g=c.environments.get(V),X=String(S.action??"");if(!D||D.projectId!==c.project.id||D.environmentId!==g?.id)return O({ok:!1,error:"Data service was not found in this environment."},404);if(!xh.includes(X))return O({ok:!1,error:`Action must be one of: ${xh.join(", ")}.`},422);try{return O({ok:!0,plan:s_.plan(D,X,S.changes??{})})}catch(y){return O({ok:!1,error:y instanceof Error?y.message:String(y)},422)}}let L=String(S.engine??""),l=String(S.provider??"");if(!["postgres","mysql","mariadb","redis","mongodb","libsql"].includes(L)||!["aws_rds","aws_aurora","aws_elasticache","server","container","external"].includes(l))return O({ok:!1,error:"A supported engine and provider are required."},422);return O({ok:!0,capabilities:i_(L,l),defaults:{publicExposure:!1,backupRetentionDays:7,deletionProtection:!0},productionExecutionCreated:!1})}if(U.pathname==="/api/data-services"&&C.method==="POST"){let S=await v(C),L=String(S.engine??""),l=String(S.provider??""),D=c.environments.get(V),g=nt(Y);if(!D)return O({ok:!1,error:"Environment was not found."},404);if(!["postgres","mysql","mariadb","redis","mongodb","libsql"].includes(L)||!["aws_rds","aws_aurora","aws_elasticache","server","container","external"].includes(l))return O({ok:!1,error:"A supported engine and provider are required."},422);let X={organizationId:c.organization.id,projectId:c.project.id,environmentId:D.id,resourceId:S.resourceId?String(S.resourceId):void 0,name:String(S.name??"").trim(),engine:L,provider:l,placement:String(S.placement??S.name??"").trim(),engineVersion:S.engineVersion?String(S.engineVersion):void 0,plan:String(S.plan??(l==="aws_elasticache"?"cache.t4g.micro":l==="aws_aurora"?"db.serverless":"db.t4g.micro")),storageGb:S.storageGb==null?void 0:Number(S.storageGb),highAvailability:S.highAvailability===!0,publicExposure:S.publicExposure===!0,allowedCidrs:Array.isArray(S.allowedCidrs)?S.allowedCidrs.map(String):[],desiredState:S.desiredState&&typeof S.desiredState==="object"&&!Array.isArray(S.desiredState)?S.desiredState:{},observedState:{},origin:S.adopt===!0?"adopted":"managed",managementEnabled:S.adopt!==!0,ownerActorId:g.actor?.id,username:S.username?String(S.username):void 0};try{if(S.adopt===!0){let z=Gt.create({...X,status:"adopted",credentialRef:void 0});return O({ok:!0,service:z,readOnly:!0},201)}if(!Eu({provider:l,engine:L}))return O({ok:!1,error:`No ${l}/${L} provisioning adapter is configured; adopt it read-only or choose a supported provider.`},422);let y=await s_.create(X);return O({ok:!0,service:y.service,operationId:y.operationId,oneTimeCredential:y.credential},201)}catch(y){return O({ok:!1,error:y instanceof Error?y.message:String(y)},422)}}if(U.pathname==="/api/data-services/connections"&&C.method==="GET"){let S=Gt.get(String(U.searchParams.get("id")??"")),L=c.environments.get(V);if(!S||S.projectId!==c.project.id||S.environmentId!==L?.id)return O({ok:!1,error:"Data service was not found in this environment."},404);let l=typeof S.observedState.endpoint==="string"?S.observedState.endpoint:void 0,D=typeof S.observedState.readerEndpoint==="string"?S.observedState.readerEndpoint:void 0,g=Number(S.observedState.port)||(S.engine==="postgres"?5432:S.engine==="redis"?6379:S.engine==="mongodb"?27017:S.engine==="libsql"?8080:3306),X=typeof S.observedState.database==="string"?S.observedState.database:void 0,y=typeof S.observedState.tls==="boolean"?S.observedState.tls:S.provider.startsWith("aws_"),z=[...l?[{type:S.publicExposure?"external":"internal",host:l,port:g,database:X,tls:y}]:[],...D?[{type:"internal",host:D,port:g,database:X,tls:y}]:[],{type:"tunnel",host:l??S.placement,port:g,database:X,tls:y}];return O({ok:!0,serviceId:S.id,guidance:Ll(S,z)})}if(U.pathname==="/api/data-services/action"&&C.method==="POST"){let S=await v(C),L=Gt.get(String(S.id??"")),l=c.environments.get(V),D=String(S.action??"");if(!L||L.projectId!==c.project.id||L.environmentId!==l?.id)return O({ok:!1,error:"Data service was not found in this environment."},404);if(!xh.includes(D))return O({ok:!1,error:`Action must be one of: ${xh.join(", ")}.`},422);let g=S.changes&&typeof S.changes==="object"&&!Array.isArray(S.changes)?S.changes:{};try{let X=s_.plan(L,D,g);if(S.execute!==!0)return O({ok:!0,plan:X,productionExecutionCreated:!1});let y=s_.enqueue(L,D,g,nt(Y).actor?.id);return O({ok:!0,plan:X,operationId:y},202)}catch(X){return O({ok:!1,error:X instanceof Error?X.message:String(X)},409)}}if(U.pathname==="/api/data-services/dependencies"&&C.method==="POST"){let S=await v(C),L=Gt.get(String(S.id??"")),l=c.environments.get(V),D=c.store.getResource(String(S.resourceId??""));if(!L||L.projectId!==c.project.id||L.environmentId!==l?.id)return O({ok:!1,error:"Data service was not found in this environment."},404);if(!D||D.projectId!==c.project.id||D.environmentId!==l?.id)return O({ok:!1,error:"Dependent resource was not found in this environment."},404);if(S.remove===!0)return O({ok:Gt.removeDependency(L.id,D.id)});return Gt.addDependency({serviceId:L.id,resourceId:D.id,secretRef:L.credentialRef??`secret://data-services/${L.projectId}/${L.name}`,requiresRedeploy:S.requiresRedeploy!==!1}),O({ok:!0,dependencies:Gt.dependencies(L.id).map((g)=>({resourceId:g.resourceId,requiresRedeploy:g.requiresRedeploy}))})}if(U.pathname==="/api/data-services/management"&&C.method==="POST"){let S=await v(C),L=Gt.get(String(S.id??"")),l=c.environments.get(V);if(!L||L.projectId!==c.project.id||L.environmentId!==l?.id)return O({ok:!1,error:"Data service was not found in this environment."},404);if(L.origin!=="adopted"||S.reviewed!==!0||S.confirm!==L.name)return O({ok:!1,error:`Enabling management requires reviewed=true and typing ${L.name}.`},409);return O({ok:!0,service:Gt.update(L.id,L.version,{managementEnabled:!0})})}if(U.pathname==="/api/data-services/reveal"&&C.method==="POST"){let S=await v(C),L=Gt.get(String(S.id??"")),l=c.environments.get(V),D=L?Gt.credential(L.id):void 0;if(!L||L.projectId!==c.project.id||L.environmentId!==l?.id)return O({ok:!1,error:"Data service was not found in this environment."},404);if(!D)return O({ok:!1,error:"No managed credential is configured."},404);return O({ok:!0,credential:{username:D.username,password:await se.resolve(D.secretRef),version:D.version}},200,{"cache-control":"no-store"})}if(U.pathname==="/api/databases"&&C.method==="GET")return O(await LU(n,V));if(U.pathname==="/api/databases"&&C.method==="POST"){let S=await v(C),L=String(S.name??"").trim();if(!Oc(L))return O({ok:!1,error:"Database name must be a valid identifier (letters, numbers, underscore; not starting with a digit)."},422);return O({...await uU(n,V,L),name:L})}if(U.pathname==="/api/databases/vitess"&&C.method==="GET"){let S=await IU(n,V);return O({...S,unhealthy:DU(S.tablets),missingPrimary:fU(S)})}if(U.pathname==="/api/databases/vitess/migrations"&&C.method==="GET"){let S=U.searchParams.get("keyspace")??void 0;return O(await aU(n,V,S))}if(U.pathname==="/api/databases/vitess/migrations/action"&&C.method==="POST"){let S=await v(C),L=String(S.uuid??"").trim(),l=String(S.action??"");if(!["retry","cancel","cleanup","complete"].includes(l))return O({ok:!1,error:"Unknown migration action."},422);return O(await PU(n,V,L,l))}if(U.pathname==="/api/databases/vitess/keyspaces"&&C.method==="POST"){let S=await v(C),L=String(S.name??"").trim(),l=S.sharded===!0;return O(await $U(n,V,L,{sharded:l}))}if(U.pathname==="/api/databases/vitess/vschema"&&C.method==="POST"){let S=await v(C),L=String(S.keyspace??"").trim(),l=typeof S.vschema==="string"?S.vschema:JSON.stringify(S.vschema??null);return O(await yU(n,V,L,l))}if(U.pathname==="/api/databases/vitess/schema"&&C.method==="POST"){let S=await v(C),L=String(S.sql??"");return O(await XU(n,V,L))}if(U.pathname==="/api/databases/vitess/install-client"&&C.method==="POST")return O(await gU(n,V));if(U.pathname==="/api/databases/backups"&&C.method==="GET")return O(await lU(n,V));if(U.pathname==="/api/databases/backup"&&C.method==="POST"){let S=await v(C),L=String(S.database??"").trim();if(!Oc(L))return O({ok:!1,error:"Database name must be a valid identifier."},422);if(S.confirm!==L)return O({ok:!1,error:`Type "${L}" to back up this database.`},409);return O(await CU(n,V,L))}if(U.pathname==="/api/databases/users"&&C.method==="POST"){let S=await v(C),L=String(S.username??"").trim(),l=String(S.password??""),D=String(S.database??"").trim()||void 0,g=S.access==="readonly"?"readonly":"all";if(!Oc(L))return O({ok:!1,error:"Username must be a valid identifier."},422);if(!l)return O({ok:!1,error:"Password is required."},422);if(D&&!Oc(D))return O({ok:!1,error:"Database must be a valid identifier."},422);return O({...await OU(n,V,{username:L,password:l,database:D,access:g}),username:L})}if(U.pathname==="/api/dashboard-data")return Vt=R.get(V)??await a(V),a(V),O(YL(Vt,{user:Tr,slug:n.project.slug}));if(U.pathname==="/api/users"&&C.method==="GET")return O({ok:!0,users:Ye(e).map(fc)});if(U.pathname==="/api/users"&&C.method==="POST"){let S=await v(C),L=String(S.username??"").trim();if(!Qh(L))return O({ok:!1,error:"Username must be 2-32 characters: letters, numbers, dot, dash or underscore."},422);let l=S.sites&&typeof S.sites==="object"?S.sites:{},D=new Set(Object.keys(n.sites??{})),g={};for(let[z,M]of Object.entries(l)){if(!D.has(z))return O({ok:!1,error:`Site '${z}' was not found.`},404);if(M!=="owner"&&M!=="collaborator")return O({ok:!1,error:`Unknown site role '${M}'. Use 'owner' or 'collaborator'.`},422);g[z]=M}let X=typeof S.password==="string"&&S.password.trim()?S.password.trim():void 0;if(X&&X.length<12)return O({ok:!1,error:"Password must be at least 12 characters."},422);let y=G_(e,{username:L,password:X,name:typeof S.name==="string"?S.name:void 0,sites:g});return yh(c,Ye(e)),q(),O({ok:!0,user:fc(y.user),password:y.password})}if(U.pathname==="/api/users"&&C.method==="DELETE"){let S=await v(C),L=String(S.username??"").trim();if(L.toLowerCase()===Y.username.toLowerCase())return O({ok:!1,error:"You cannot remove your own account."},409);let l=Ur(Ye(e),L),D=l?c.store.getActorByExternalId("user",`dashboard:${l.username.toLowerCase()}`):void 0,g=D?c.store.getMembershipForActor(c.organization.id,D.id):void 0;if(g&&g.source!=="legacy")return O({ok:!1,error:"Organization members must be removed from Organization access."},409);let X=WL(e,L);if(!X.ok)return O(X,409);return yh(c,Ye(e)),F.clear(),O({ok:!0,username:L})}if(U.pathname==="/api/actions/run"&&C.method==="POST"){let S=await C.json().catch(()=>({})),L=S.action?lJ(S.action,V):void 0;if(!L)return O({ok:!1,error:"Unknown dashboard action."},404);if(L.mutates&&S.confirm!==L.confirm)return O({ok:!1,error:`Type "${L.confirm}" to run this action.`},409);let l=await Dd({controlPlane:c,environment:V,actor:Y,kind:`dashboard.action.${L.id}`,input:{action:L.id},execute:()=>tu(L,{cwd:e,cliEntry:E})});return O({...l.result,controlPlaneOperation:l.operation})}if(U.pathname==="/api/server/operations/run"&&C.method==="POST"){let S=await C.json().catch(()=>({})),L=S.operation?QL(S.operation,n,Vt):void 0;if(!L)return O({ok:!1,error:"Unknown or unavailable server operation."},404);if(L.mutates&&S.confirm!==L.confirm)return O({ok:!1,error:`Type "${L.confirm}" to run this operation.`},409);let l=Jr(c,String(V));await new Ac(ct).run(new J_,{...l,artifactRoot:e});let D=$h(ct,{scope:l,desiredConfigHash:c.project.desiredConfigHash});if(D.decision.outcome==="block")return O({ok:!1,error:`Operation blocked by security policy: ${D.decision.explanation}`,securityReview:D},409);let g=await Dd({controlPlane:c,environment:V,actor:Y,kind:`dashboard.server.${L.id}`,resourceSlug:L.target,input:{operation:L.id,target:L.target,to:S.to??null},execute:()=>Vh(n,V,L,{to:S.to})});return O({...g.result,controlPlaneOperation:g.operation,securityReview:D})}if(U.pathname==="/api/server/command"&&C.method==="POST"){let S=await C.json().catch(()=>({}));if(S.confirm!=="run")return O({ok:!1,error:'Type "run" to execute this command on the server.'},409);let L=await Dd({controlPlane:c,environment:V,actor:Y,kind:"dashboard.server.command",input:{source:"interactive-command"},execute:()=>V_(n,V,String(S.command??""))});return O({...L.result,controlPlaneOperation:L.operation})}if(U.pathname==="/api/serverless/operations")return O(ZL(n,V,Vt));if(U.pathname==="/api/serverless/operations/run"&&C.method==="POST"){let S=await C.json().catch(()=>({})),L=S.operation?iw(S.operation,n,V,Vt):void 0;if(!L)return O({ok:!1,error:"Unknown or unavailable serverless operation."},404);if(L.mutates&&S.confirm!==L.confirm)return O({ok:!1,error:`Type "${L.confirm}" to run this operation.`},409);let l=await Dd({controlPlane:c,environment:V,actor:Y,kind:`dashboard.serverless.${L.id}`,input:{operation:L.id,min:S.min??null,max:S.max??null},execute:()=>hw(n,V,L,{min:S.min,max:S.max})});return Vt=await rn(n,V),R.set(V,Vt),O({...l.result,controlPlaneOperation:l.operation})}if(U.pathname==="/api/serverless/command"&&C.method==="POST"){let S=await C.json().catch(()=>({}));if(S.confirm!=="run")return O({ok:!1,error:'Type "run" to execute this command.'},409);return O(await Rw(n,V,String(S.command??"")))}if(U.pathname==="/api/serverless/dlq"&&C.method==="GET"){let S=Number(U.searchParams.get("max"))||10;return O(await Sw(n,V,S))}if(U.pathname==="/api/serverless/dlq/redrive"&&C.method==="POST"){let S=await C.json().catch(()=>({}));if(S.confirm!=="redrive")return O({ok:!1,error:'Type "redrive" to move messages back onto a source queue.'},409);return O(await Nw(n,V,{max:S.max,targetQueue:S.targetQueue}))}if(U.pathname==="/api/serverless/dlq/purge"&&C.method==="POST"){if((await C.json().catch(()=>({}))).confirm!=="purge")return O({ok:!1,error:'Type "purge" to permanently discard every DLQ message.'},409);return O(await Aw(n,V))}if(U.pathname==="/api/serverless/secrets"&&C.method==="GET")return O({secrets:Lw(n,V)});if(U.pathname==="/api/serverless/secrets"&&C.method==="POST"){let S=await C.json().catch(()=>({})),L=String(S.secretId??"").trim();if(!L)return O({ok:!1,error:"A secret id is required."},422);if(typeof S.value!=="string"||S.value==="")return O({ok:!1,error:"A non-empty value is required."},422);return O(await uw(n,V,L,S.value))}if(U.pathname==="/api/serverless/secrets"&&C.method==="DELETE"){let S=await C.json().catch(()=>({})),L=String(S.secretId??"").trim();if(!L)return O({ok:!1,error:"A secret id is required."},422);if(S.confirm!==L)return O({ok:!1,error:`Type "${L}" to delete this secret.`},409);return O(await Ow(n,V,L))}if(U.pathname==="/api/serverless/functions/config"&&C.method==="POST"){let S=await C.json().catch(()=>({})),L=String(S.mode??"").trim();if(S.confirm!==L)return O({ok:!1,error:`Type "${L}" to update this function.`},409);return O(await Cw(n,V,L,{memory:S.memory,timeout:S.timeout}))}if(U.pathname==="/api/serverless/alarms"&&C.method==="GET")return O(await lw(n,V));if(U.pathname==="/api/serverless/alarms"&&C.method==="POST"){let S=await C.json().catch(()=>({})),L=String(S.preset??"").trim(),l=Number(S.threshold);if(!L)return O({ok:!1,error:"An alarm metric is required."},422);if(!Number.isFinite(l))return O({ok:!1,error:"A numeric threshold is required."},422);return O(await Iw(n,V,L,l))}if(U.pathname==="/api/serverless/alarms"&&C.method==="DELETE"){let S=await C.json().catch(()=>({})),L=String(S.name??"").trim();if(!L)return O({ok:!1,error:"An alarm name is required."},422);if(S.confirm!==L)return O({ok:!1,error:`Type "${L}" to delete this alarm.`},409);return O(await Dw(n,V,L))}if(U.pathname==="/api/serverless/traces"&&C.method==="GET"){let S=Number(U.searchParams.get("minutes"))||30;return O(await Zh(n,V,S))}if(U.pathname==="/api/serverless/scheduler"&&C.method==="POST"){let S=await C.json().catch(()=>({})),L=String(S.action??"").trim();if(L!=="enable"&&L!=="disable"&&L!=="run")return O({ok:!1,error:"Unknown scheduler action."},422);if(S.confirm!==L)return O({ok:!1,error:`Type "${L}" to ${L} the scheduler.`},409);return O(await xL(n,V,L))}if(!bw(U.pathname,Tr))return new Response(null,{status:302,headers:{location:`/access-denied?env=${encodeURIComponent(V)}`}});let _n=await Et(Y,V);if(!_n)return sh("ts-cloud dashboard UI is unavailable.",503);return xw(_n,U.pathname)}catch(hE){if(t.verbose)console.error(hE);return O({ok:!1,error:hE?.message??String(hE)},500)}})();if(!ot)return ot;if(Jt&&(U.pathname.startsWith("/api/")||U.pathname.startsWith("/auth/"))){let Ct;if((s.headers.get("content-type")||"").includes("application/json"))Ct=await s.json().catch(()=>{return});let ue=kt.resolveUser(C),he=ue?nt(ue).actor:void 0;c.store.appendEvent({organizationId:c.organization.id,projectId:c.project.id,actorId:he?.id,correlationId:Nt,type:ot.status<400?"dashboard.mutation.succeeded":"dashboard.mutation.failed",level:ot.status<400?"info":"warning",payload:dJ(C.method,U.pathname,Ct,ot.status,Date.now()-Tt)})}return ot.headers.set("x-request-id",Nt),ot}});o_?.start();let ig=nn.stop.bind(nn);return nn.stop=(C)=>{clearInterval(Ou),clearInterval(Cu),clearInterval(lu),clearInterval(uu),clearInterval(Lu),clearInterval(Ru),clearInterval(Su),clearInterval(Nu),clearInterval(Au),q(),re.clear(),o_?.stop();let p=ig(C);if(o_)o_.settled().finally(()=>c.store.close());else c.store.close();return p},{server:nn,url:`http://${r}:${nn.port}/`}}function ru(t){let e=q_.argv.indexOf(t);return e===-1?void 0:q_.argv[e+1]}function pw(t){return q_.argv.includes(t)}async function gJ(){let t=await mw({host:ru("--host")??"127.0.0.1",port:Number(ru("--port")??7676),environment:ru("--env"),box:pw("--box"),verbose:pw("--verbose")});console.log("ts-cloud Local Dashboard"),console.log(`Serving ${t.url}`),await new Promise((e)=>{let r=()=>{t.server.stop(!0),e()};q_.once("SIGINT",r),q_.once("SIGTERM",r)})}gJ();
|
|
6671
|
+
`);return new Response(lt,{headers:{"content-disposition":'attachment; filename="ts-cloud-telemetry.csv"',"content-type":"text/csv; charset=utf-8"}})}if(U.pathname==="/api/telemetry/saved-queries"&&C.method==="GET"){let k=nt(Y);return O({ok:!0,queries:L.listSavedQueries(c.project.id,k.actor?.id)})}if(U.pathname==="/api/telemetry/saved-queries"&&C.method==="POST"){let k=await v(C),_t=nt(Y);return O({ok:!0,query:L.saveQuery(c.project.id,_t.actor?.id,String(k.name??""),z(k.query??k))},201)}if(U.pathname==="/api/telemetry/saved-queries"&&C.method==="DELETE"){let k=await v(C),_t=nt(Y),K=L.deleteSavedQuery(c.project.id,_t.actor?.id,String(k.id??""));return O({ok:K},K?200:404)}}if(U.pathname.startsWith("/api/configuration")){let S=c.environments.get(V),L=Y.role==="admin"||!!Tr.capabilities?.includes("secrets:read"),l=Y.role==="admin"||!!Tr.capabilities?.includes("secrets:write"),D={projectId:c.project.id,environmentId:S?.id},g={"cache-control":"no-store"};if(U.pathname==="/api/configuration"&&C.method==="GET"){let X=Object.fromEntries(U.searchParams),y=X.scopeType||X.scopeId?wc(X,D):void 0,z=["variable","secret"].includes(String(X.kind))?X.kind:void 0,M=y?.type==="preview"?st.previews.getInstance(y.id):void 0,b=M?st.previews.getDefinition(M.definitionId):void 0,wt=y?await Ge.resolve({projectId:c.project.id,environmentId:y.environmentId,resourceId:y.resourceId,functionId:y.type==="function"?y.id:void 0,previewId:y.previewId,trustedPreview:!!M&&!M.fork,allowedPreviewSecrets:b?.inheritedSecrets,nativeReferences:!0,canReadSecretMetadata:L}):void 0,k=c.store.listResources(c.project.id);return O({ok:!0,entries:Ge.list({projectId:c.project.id,scope:y,kind:z,search:X.search,canReadSecretMetadata:L}),effectiveEntries:wt?Object.values(wt.entries).filter((_t)=>!z||_t.kind===z).filter((_t)=>!X.search||_t.key.toLowerCase().includes(String(X.search).toLowerCase())):[],configurationHash:wt?.configurationHash,warnings:wt?.warnings??[],scopes:{project:c.project,environments:c.store.listEnvironments(c.project.id),resources:k.filter((_t)=>_t.kind!=="function"),functions:k.filter((_t)=>_t.kind==="function"),previews:st.previews.listInstances({projectId:c.project.id}).filter((_t)=>_t.status!=="destroyed").map((_t)=>({id:_t.id,name:_t.name,environmentId:_t.baseEnvironmentId,resourceId:_t.resourceId,fork:_t.fork,status:_t.status}))}},200,g)}if(U.pathname==="/api/configuration/export"&&C.method==="GET"){let X=wc(Object.fromEntries(U.searchParams),D);return new Response(Ge.exportVariables({projectId:c.project.id,scope:X}),{headers:{...g,"content-disposition":'attachment; filename="ts-cloud.env"',"content-type":"text/plain; charset=utf-8"}})}if(U.pathname==="/api/configuration/plan"&&C.method==="POST"){let X=await v(C),y=wc(X,D),z=X.values&&typeof X.values==="object"&&!Array.isArray(X.values)?Object.fromEntries(Object.entries(X.values).map(([M,b])=>[M,String(b)])):{};return O({ok:!0,plan:Ge.plan({projectId:c.project.id,scope:y,values:z,removeMissing:X.removeMissing===!0})},200,g)}if(U.pathname==="/api/configuration"&&C.method==="POST"){let X=await v(C),y=wc(X,D),z=X.kind==="secret"?"secret":"variable",M=String(X.key??"");if(z==="secret"&&!l)return O({ok:!1,error:"Secret write permission is required."},403,g);try{let b=await Ge.set({organizationId:c.organization.id,projectId:c.project.id,scope:y,key:M,kind:z,value:X.value==null?void 0:String(X.value),reference:X.reference==null?void 0:String(X.reference),backend:X.backend,required:X.required===!0,expectedVersion:X.expectedVersion==null?void 0:Number(X.expectedVersion),confirmed:String(X.confirm??"")===M,idempotencyKey:C.headers.get("idempotency-key")??X.idempotencyKey,actorId:nt(Y).actor?.id});return O({ok:!0,entry:Ge.list({projectId:c.project.id,scope:y,canReadSecretMetadata:L}).find((wt)=>wt.id===b.entry.id),mutation:b.mutation,warnings:b.warnings},b.mutation.added.length?201:200,g)}catch(b){return O({ok:!1,error:b instanceof Error?b.message:String(b)},409,g)}}if(U.pathname==="/api/configuration/import"&&C.method==="POST"){let X=await v(C),y=wc(X,D),z=Array.isArray(X.secretKeys)?X.secretKeys.map(String):[];if(z.length&&!l)return O({ok:!1,error:"Secret write permission is required."},403,g);try{let M=await Ge.importDotenv({organizationId:c.organization.id,projectId:c.project.id,scope:y,source:String(X.source??""),secretKeys:z,backend:X.backend,confirmed:X.confirm==="import",idempotencyKey:C.headers.get("idempotency-key")??X.idempotencyKey,actorId:nt(Y).actor?.id});return O({ok:M.document.valid,diagnostics:M.document.diagnostics,mutation:M.mutation,warnings:M.warnings},M.document.valid?200:422,g)}catch(M){return O({ok:!1,error:M instanceof Error?M.message:String(M)},409,g)}}if(U.pathname==="/api/configuration/dependencies"&&C.method==="POST"){let X=await v(C),y=wd.get(String(X.entryId??"")),z=c.store.getResource(String(X.resourceId??""));if(!y||y.projectId!==c.project.id||!z||z.projectId!==c.project.id)return O({ok:!1,error:"Configuration entry or dependent resource was not found."},404,g);return O({ok:!0,dependency:wd.setDependency({entryId:y.id,resourceId:z.id,injectionTarget:["native_reference","file"].includes(String(X.injectionTarget))?X.injectionTarget:"environment",required:X.required!==!1,requiresRedeploy:X.requiresRedeploy!==!1,lastDeployedVersion:X.lastDeployedVersion==null?void 0:Number(X.lastDeployedVersion)})},200,g)}if(U.pathname==="/api/configuration/transfer"&&C.method==="POST"){let X=await v(C),y=wd.get(String(X.id??"")),z=wc({...X,scopeType:X.targetScopeType,scopeId:X.targetScopeId},D);if(!y||y.projectId!==c.project.id)return O({ok:!1,error:"Configuration entry was not found."},404,g);if(y.kind==="secret"&&!l)return O({ok:!1,error:"Secret write permission is required."},403,g);try{let M=await Ge.transfer({entryId:y.id,targetScope:z,mode:X.mode==="move"?"move":"copy",confirmed:X.confirm===y.key,actorId:nt(Y).actor?.id,idempotencyKey:C.headers.get("idempotency-key")??X.idempotencyKey});return O({ok:!0,entry:Ge.list({projectId:c.project.id,scope:z,canReadSecretMetadata:L}).find((b)=>b.id===M.entry.id),mutation:M.mutation},200,g)}catch(M){return O({ok:!1,error:M instanceof Error?M.message:String(M)},409,g)}}if(U.pathname==="/api/configuration/bulk"&&C.method==="POST"){let X=await v(C),y=Array.isArray(X.ids)?X.ids.map(String).slice(0,500):[],z=y.map((b)=>wd.get(b)).filter((b)=>!!b&&b.projectId===c.project.id);if(z.length!==y.length)return O({ok:!1,error:"One or more configuration entries were not found."},404,g);if(z.some((b)=>b.kind==="secret")&&!l)return O({ok:!1,error:"Secret write permission is required."},403,g);if(X.action!=="delete"||X.confirm!=="bulk")return O({ok:!1,error:"Bulk deletion requires action delete and confirm bulk."},409,g);let M=[];try{for(let b of z)M.push(await Ge.remove({entryId:b.id,expectedVersion:b.version,confirmed:!0,actorId:nt(Y).actor?.id}));return O({ok:!0,removed:M.flatMap((b)=>b.removed),affectedResourceIds:[...new Set(M.flatMap((b)=>b.affectedResourceIds))].sort()},200,g)}catch(b){return O({ok:!1,error:b instanceof Error?b.message:String(b),partial:M.flatMap((wt)=>wt.removed)},409,g)}}if(U.pathname==="/api/configuration/reveal"&&C.method==="POST"){let X=await v(C),y=kt.resolveSession(C);try{return O({ok:!0,value:await Ge.reveal({entryId:String(X.id??""),canRevealSecrets:L,recentlyAuthenticated:!G||!!y&&Q.isRecentlyAuthenticated(y),actorId:nt(Y).actor?.id})},200,g)}catch(z){return O({ok:!1,error:z instanceof Error?z.message:String(z)},403,g)}}if(U.pathname==="/api/configuration"&&C.method==="DELETE"){let X=await v(C),y=wd.get(String(X.id??""));if(y?.kind==="secret"&&!l)return O({ok:!1,error:"Secret write permission is required."},403,g);if(!y||y.projectId!==c.project.id)return O({ok:!1,error:"Configuration entry was not found."},404,g);try{return O({ok:!0,mutation:await Ge.remove({entryId:y.id,expectedVersion:Number(X.expectedVersion),confirmed:String(X.confirm??"")===y.key,actorId:nt(Y).actor?.id})},200,g)}catch(z){return O({ok:!1,error:z instanceof Error?z.message:String(z)},409,g)}}}if(U.pathname.startsWith("/api/fleet")){let S=nt(Y).actor?.id,L=(l,D=409)=>O({ok:!1,error:l instanceof Error?l.message:String(l)},D,{"cache-control":"no-store"});if(U.pathname==="/api/fleet"&&C.method==="GET")return O({ok:!0,servers:yc.list(c.project.id),resources:c.store.listResources(c.project.id),operations:zt.list({projectId:c.project.id,limit:200}).filter((l)=>l.operation.kind.startsWith("fleet."))},200,{"cache-control":"no-store"});if(U.pathname==="/api/fleet"&&C.method==="POST"){let l=await v(C);try{return O({ok:!0,server:Wr.enroll({organizationId:c.organization.id,projectId:c.project.id,name:String(l.name??""),provider:["aws","hetzner"].includes(String(l.provider))?l.provider:"ssh",providerId:l.providerId?String(l.providerId):void 0,region:l.region?String(l.region):void 0,zone:l.zone?String(l.zone):void 0,endpoint:String(l.endpoint??""),sshUser:String(l.sshUser??"deploy"),sshPort:l.sshPort?Number(l.sshPort):22,credentialRef:String(l.credentialRef??""),roles:Array.isArray(l.roles)?l.roles:[],labels:l.labels&&typeof l.labels==="object"?l.labels:{}})},201)}catch(D){return L(D,422)}}if(U.pathname==="/api/fleet/action"&&C.method==="POST"){let l=await v(C),D=String(l.id??""),g=String(l.action??"");try{if(g==="test")return O({ok:!0,server:await Wr.test(D)});if(g==="validate")return O({ok:!0,server:await Wr.validate(D)});if(g==="review_host_key")return O({ok:!0,server:Wr.reviewHostKey(D,String(l.fingerprint??""))});if(g==="bootstrap")return O({ok:!0,...Wr.bootstrap(D,l.confirmed===!0)},l.confirmed===!0?202:200);if(g==="heartbeat")return O({ok:!0,server:Wr.heartbeat(D,{usage:l.usage&&typeof l.usage==="object"?l.usage:{}})});if(g==="drain")return O({ok:!0,server:Wr.drain(D,l.completed===!0)});if(g==="uncordon")return O({ok:!0,server:Wr.uncordon(D)});if(g==="archive")return O({ok:!0,server:Wr.archive(D,String(l.confirmation??""))});return L("Unsupported fleet action.",422)}catch(X){return L(X)}}}if(U.pathname.startsWith("/api/capacity")){let S=(L,l=409)=>O({ok:!1,error:L instanceof Error?L.message:String(L)},l,{"cache-control":"no-store"});if(U.pathname==="/api/capacity"&&C.method==="GET")return O({ok:!0,pools:$d.listPools(c.project.id),placements:$d.listPlacements(c.project.id),servers:yc.list(c.project.id)},200,{"cache-control":"no-store"});if(U.pathname==="/api/capacity"&&C.method==="POST"){let L=await v(C);try{return O({ok:!0,pool:$d.createPool({organizationId:c.organization.id,projectId:c.project.id,name:String(L.name??""),purpose:String(L.purpose??"application"),backend:String(L.backend??"server"),region:L.region?String(L.region):void 0,architecture:L.architecture?String(L.architecture):void 0,labels:L.labels&&typeof L.labels==="object"?L.labels:{},requiredServerLabels:L.requiredServerLabels&&typeof L.requiredServerLabels==="object"?L.requiredServerLabels:{},toleratedTaints:Array.isArray(L.toleratedTaints)?L.toleratedTaints.map(String):[],capacity:L.capacity&&typeof L.capacity==="object"?L.capacity:{},maxWorkloads:Number(L.maxWorkloads??10),costWeight:Number(L.costWeight??1),spreadKey:L.spreadKey?String(L.spreadKey):void 0,concurrency:Number(L.concurrency??1),ephemeralWorkspaces:!0,allowProductionSecrets:!1,status:"active"})},201)}catch(l){return S(l,422)}}if(U.pathname==="/api/capacity/member"&&C.method==="POST"){let L=await v(C);try{return $d.addMember(String(L.poolId??""),String(L.serverId??"")),O({ok:!0,pool:$d.getPool(String(L.poolId??""))})}catch(l){return S(l,422)}}if(U.pathname==="/api/capacity/explain"&&C.method==="POST"){let L=await v(C);try{return O({ok:!0,decisions:cu.explain(c.project.id,{purpose:String(L.purpose??"application"),resources:L.resources&&typeof L.resources==="object"?L.resources:{},region:L.region?String(L.region):void 0,architecture:L.architecture?String(L.architecture):void 0,labels:L.labels&&typeof L.labels==="object"?L.labels:{}})})}catch(l){return S(l,422)}}if(U.pathname==="/api/capacity/action"&&C.method==="POST"){let L=await v(C);try{if(L.action==="drain")return O({ok:!0,...cu.drainPool(String(L.poolId??""))});if(L.action==="enable")return O({ok:!0,pool:$d.updatePool(String(L.poolId??""),{status:"active"})});if(L.action==="disable")return O({ok:!0,pool:$d.updatePool(String(L.poolId??""),{status:"disabled"})});return S("Unsupported capacity action.",422)}catch(l){return S(l,422)}}}if(U.pathname.startsWith("/api/regions")){let S=(L,l=409)=>O({ok:!1,error:L instanceof Error?L.message:String(L)},l,{"cache-control":"no-store"});if(U.pathname==="/api/regions"&&C.method==="GET")return O({ok:!0,topologies:iE.list(c.project.id).map((L)=>({topology:L,targets:iE.targets(L.id),channels:iE.channels(L.id),route:iE.route(L.id),executions:iE.executions(L.id)}))},200,{"cache-control":"no-store"});if(U.pathname==="/api/regions"&&C.method==="POST"){let L=await v(C);try{return O({ok:!0,topology:_u.create({organizationId:c.organization.id,projectId:c.project.id,environmentId:c.environments.get(V)?.id,name:String(L.name??""),hostname:String(L.hostname??""),regions:Array.isArray(L.regions)?L.regions:[],trafficPolicy:L.trafficPolicy==="weighted"||L.trafficPolicy==="latency"?L.trafficPolicy:"active_passive",dataPolicy:{replicate:Array.isArray(L.replicate)?L.replicate:["s3","dynamodb","secrets"],maxLagSeconds:Number(L.maxLagSeconds??30),retainOnDestroy:L.retainOnDestroy!==!1},dnsProvider:"route53",cdnEnabled:L.cdnEnabled===!0,wafEnabled:L.wafEnabled===!0})},201)}catch(l){return S(l,422)}}if(U.pathname==="/api/regions/action"&&C.method==="POST"){let L=await v(C);try{return O({ok:!0,..._u.enqueue({topologyId:String(L.topologyId??""),kind:String(L.action??""),targetRegion:L.targetRegion?String(L.targetRegion):void 0,revision:L.revision?String(L.revision):void 0,manifest:L.manifest&&typeof L.manifest==="object"?L.manifest:{},confirmation:L.confirmation?String(L.confirmation):void 0,deleteData:L.deleteData===!0})},202)}catch(l){return S(l,422)}}}if(U.pathname.startsWith("/api/maintenance")){let S=(L,l=409)=>O({ok:!1,error:L instanceof Error?L.message:String(L)},l,{"cache-control":"no-store"});if(U.pathname==="/api/maintenance"&&C.method==="GET")return O({ok:!0,manifests:td.manifests(c.organization.id),windows:td.windows(c.project.id),campaigns:td.campaigns(c.project.id).map((L)=>({campaign:L,targets:td.targets(L.id)})),cleanups:td.cleanups(c.project.id),drills:td.drills(c.project.id)},200,{"cache-control":"no-store"});if(U.pathname==="/api/maintenance/cleanup-preview"&&C.method==="POST"){let L=await v(C);try{return O({ok:!0,plan:await tR.previewCleanup({projectId:c.project.id,kind:String(L.kind??"operations"),criteria:{olderThanDays:Number(L.olderThanDays??30)}},Tu)},201)}catch(l){return S(l,422)}}if(U.pathname==="/api/maintenance/cleanup-apply"&&C.method==="POST"){let L=await v(C);try{return O({ok:!0,...tR.enqueueCleanup(String(L.planId??""),String(L.confirmation??""))},202)}catch(l){return S(l,422)}}if(U.pathname==="/api/maintenance/drill"&&C.method==="POST"){let L=await v(C);try{return O({ok:!0,drill:td.createDrill({projectId:c.project.id,scenario:String(L.scenario??"control_plane"),isolatedTarget:String(L.isolatedTarget??""),expectedRpoMinutes:Number(L.expectedRpoMinutes??60),expectedRtoMinutes:Number(L.expectedRtoMinutes??30),recoveryPointId:L.recoveryPointId?String(L.recoveryPointId):void 0,topologyId:L.topologyId?String(L.topologyId):void 0})},201)}catch(l){return S(l,422)}}if(U.pathname==="/api/maintenance/drill-run"&&C.method==="POST"){let L=await v(C);try{return O({ok:!0,...tR.enqueueDrill(String(L.drillId??""))},202)}catch(l){return S(l,422)}}}if(U.pathname.startsWith("/api/volumes")){let S=c.environments.get(V),L=nt(Y).actor?.id,l=(D,g=409)=>O({ok:!1,error:D instanceof Error?D.message:String(D)},g,{"cache-control":"no-store"});if(U.pathname==="/api/volumes"&&C.method==="GET"){let D=mh.inventory(c.project.id,S?.id),g=c.store.listResources(c.project.id,S?.id).map((X)=>({id:X.id,name:X.name,slug:X.slug,kind:X.kind,provider:X.provider,providerId:X.providerId}));return O({ok:!0,volumes:D,resources:g,operations:zt.list({projectId:c.project.id,limit:100}).filter((X)=>X.operation.kind.startsWith("volume.")),recoveryPoints:ee.listRecoveryPoints(c.project.id).filter((X)=>X.kind==="volume"),providers:ph.map((X)=>({provider:X.provider,type:X.type,capabilities:X.capabilities()}))},200,{"cache-control":"no-store"})}if(U.pathname==="/api/volumes"&&C.method==="POST"){let D=await v(C);try{return O({ok:!0,...pr.create({organizationId:c.organization.id,projectId:c.project.id,environmentId:S?.id,resourceId:D.resourceId?String(D.resourceId):void 0,name:String(D.name??""),provider:String(D.provider??"docker"),type:D.type==="docker"?"docker":D.type,capacityBytes:D.capacityBytes==null?void 0:Number(D.capacityBytes),filesystem:D.filesystem?String(D.filesystem):void 0,encrypted:D.encrypted===!0,desiredState:D.desiredState&&typeof D.desiredState==="object"?D.desiredState:{},actorId:L})},202,{"cache-control":"no-store"})}catch(g){return l(g,422)}}if(U.pathname==="/api/volumes/attach"&&C.method==="POST"){let D=await v(C);try{return O({ok:!0,...pr.attach(String(D.volumeId??""),{resourceId:String(D.resourceId??""),targetPath:String(D.targetPath??""),readOnly:D.readOnly===!0,uid:D.uid==null?void 0:Number(D.uid),gid:D.gid==null?void 0:Number(D.gid),mode:D.mode?String(D.mode):void 0,propagation:D.propagation,driverOptions:D.driverOptions&&typeof D.driverOptions==="object"?D.driverOptions:{},actorId:L})},202)}catch(g){return l(g,422)}}if(U.pathname==="/api/volumes/detach"&&C.method==="POST"){let D=await v(C);try{return O({ok:!0,...pr.detach(String(D.volumeId??""),String(D.attachmentId??""),{force:D.force===!0,drained:D.drained===!0,unmounted:D.unmounted===!0,confirmation:D.confirmation?String(D.confirmation):void 0,actorId:L})},202)}catch(g){return l(g)}}if(U.pathname==="/api/volumes/resize"&&C.method==="POST"){let D=await v(C);try{return O({ok:!0,...pr.resize(String(D.volumeId??""),Number(D.capacityBytes),{drained:D.drained===!0,actorId:L})},202)}catch(g){return l(g,422)}}if(U.pathname==="/api/volumes/snapshot"&&C.method==="POST"){let D=await v(C);try{return O({ok:!0,...pr.snapshot(String(D.volumeId??""),{name:D.name?String(D.name):void 0,actorId:L})},202)}catch(g){return l(g,422)}}if(U.pathname==="/api/volumes/restore"&&C.method==="POST"){let D=await v(C);try{return O({ok:!0,...pr.restore(String(D.snapshotId??""),{name:String(D.name??""),actorId:L})},202)}catch(g){return l(g,422)}}if(U.pathname==="/api/volumes/discover"&&C.method==="POST")try{return O({ok:!0,volumes:await pr.discover({organizationId:c.organization.id,projectId:c.project.id,environmentId:S?.id,actorId:L})})}catch(D){return l(D,502)}if(U.pathname==="/api/volumes/adopt"&&C.method==="POST"){let D=await v(C);try{return O({ok:!0,volume:pr.adopt(String(D.volumeId??""),{name:String(D.name??""),actorId:L})})}catch(g){return l(g,422)}}if(U.pathname==="/api/volumes"&&C.method==="DELETE"){let D=await v(C),g=kt.resolveSession(C);try{return O({ok:!0,...pr.delete(String(D.volumeId??""),{recentAuthAt:!G||g&&Q.isRecentlyAuthenticated(g)?new Date().toISOString():void 0,confirmation:D.confirmation?String(D.confirmation):void 0,backupOverride:D.backupOverride===!0,backupOverrideConfirmation:D.backupOverrideConfirmation?String(D.backupOverrideConfirmation):void 0,actorId:L})},202)}catch(X){return l(X)}}}if(U.pathname==="/api/backups"&&C.method==="GET"){let S=c.environments.get(V),L=ee.listPolicies(c.project.id,S?.id),l=new Set(L.map((z)=>z.id)),D=ee.listRecoveryPoints(c.project.id).filter((z)=>!z.policyId||l.has(z.policyId)),g=ee.listJobs(c.project.id).filter((z)=>!z.policyId||l.has(z.policyId)),X=(z)=>({...z,credentialRef:void 0,encryptionKeyRef:void 0,credentialsConfigured:!!z.credentialRef,clientEncryptionConfigured:!!z.encryptionKeyRef}),y=await Promise.all(ee.listDestinations(c.project.id).map(async(z)=>({...X(z),credentialStatus:await Rl(z,se)})));return O({ok:!0,destinations:y,policies:L,recoveryPoints:D,jobs:g,coverage:ee.coverage(c.project.id).filter((z)=>l.has(z.policy.id)),resources:S?c.store.listResources(c.project.id,S.id).map((z)=>({id:z.id,name:z.name,slug:z.slug,kind:z.kind})):[]})}if(U.pathname==="/api/backups/destinations"&&C.method==="POST"){let S=await v(C),L=String(S.name??"").trim(),l=String(S.provider??""),D=String(S.encryption??"provider"),g=`secret://data-services/backups/${c.project.id}/${L}`,X=[];if(!["aws_s3","s3_compatible","aws_backup"].includes(l))return O({ok:!1,error:"A supported backup destination provider is required."},422);if(!["provider","client_side","both"].includes(D))return O({ok:!1,error:"Encryption must be provider, client_side, or both."},422);try{let y,z;if(S.credentials&&typeof S.credentials==="object"&&!Array.isArray(S.credentials))y=`${g}/credentials`,await se.put(y,JSON.stringify(S.credentials)),X.push(y);if(D!=="provider"){let b=String(S.encryptionKey??"");if(b.length<32)throw Error("Client-side encryption keys must contain at least 32 characters.");z=`${g}/encryption-key`,await se.put(z,b),X.push(z)}let M=ee.createDestination({organizationId:c.organization.id,projectId:c.project.id,name:L,provider:l,endpoint:S.endpoint?String(S.endpoint):void 0,endpointPolicy:S.endpointPolicy==="allow_private"?"allow_private":"public_https",bucket:S.bucket?String(S.bucket):void 0,prefix:String(S.prefix??""),region:S.region?String(S.region):gd,forcePathStyle:S.forcePathStyle===!0,credentialRef:y,encryption:D,encryptionKeyRef:z,immutability:S.immutability&&typeof S.immutability==="object"&&!Array.isArray(S.immutability)?S.immutability:{},status:"untested"});return O({ok:!0,destination:{...M,credentialRef:void 0,encryptionKeyRef:void 0,credentialsConfigured:!!y,clientEncryptionConfigured:!!z}},201)}catch(y){for(let z of X)await se.remove(z).catch(()=>{});return O({ok:!1,error:y instanceof Error?y.message:String(y)},422)}}if(U.pathname==="/api/backups/destinations/test"&&C.method==="POST"){let S=await v(C),L=ee.getDestination(String(S.id??""));if(!L||L.projectId!==c.project.id)return O({ok:!1,error:"Backup destination was not found."},404);if(L.provider==="aws_backup")return O({ok:!1,error:"AWS Backup destinations are verified by creating a provider recovery point."},422);try{return await nu.test(L),O({ok:!0,destination:ee.recordDestinationTest(L.id,{ok:!0})})}catch(l){let D=l instanceof Error?l.message:String(l);return ee.recordDestinationTest(L.id,{ok:!1,error:D}),O({ok:!1,error:D},502)}}if(U.pathname==="/api/backups/policies"&&C.method==="POST"){let S=await v(C),L=c.environments.get(V),l=ee.getDestination(String(S.destinationId??"")),D=String(S.resourceKind??""),g=S.dataServiceId?String(S.dataServiceId):void 0,X=g?Gt.get(g):void 0,y=S.resourceId?String(S.resourceId):void 0,z=y?c.store.getResource(y):void 0;if(!L)return O({ok:!1,error:"Environment was not found."},404);if(!l||l.projectId!==c.project.id)return O({ok:!1,error:"Backup destination was not found."},404);if(!["managed_database","logical_database","volume","files","control_plane","infrastructure"].includes(D))return O({ok:!1,error:"A supported backup resource kind is required."},422);if(g&&(!X||X.projectId!==c.project.id||X.environmentId!==L.id))return O({ok:!1,error:"Data service was not found in this environment."},404);if(y&&(!z||z.projectId!==c.project.id||z.environmentId!==L.id))return O({ok:!1,error:"Resource was not found in this environment."},404);if(D==="managed_database"&&!X)return O({ok:!1,error:"Managed database policies require a data service."},422);if(D==="logical_database"&&(!X||!["container","server"].includes(X.provider)))return O({ok:!1,error:"Logical database policies require an on-box data service."},422);if(D==="volume"&&(!z||!/^[A-Za-z0-9][A-Za-z0-9_.-]{1,127}$/.test(String(S.volumeName??""))))return O({ok:!1,error:"Volume policies require a scoped resource and valid volumeName."},422);let M=Array.isArray(S.includePatterns)?S.includePatterns.map(String).filter(Boolean):[];if(D==="files"&&(!z||!M.length))return O({ok:!1,error:"File policies require a scoped resource and at least one project-relative include path."},422);if(D==="control_plane"&&l.encryption==="provider")return O({ok:!1,error:"Control-plane policies require a destination with client-side encryption."},422);if(D==="infrastructure"&&(l.provider!=="aws_backup"||!M.some((b)=>b.startsWith("resource:arn:"))||!M.some((b)=>b.startsWith("role:arn:"))))return O({ok:!1,error:"Infrastructure policies require an AWS Backup destination plus resource:<arn> and role:<arn> include values."},422);try{let b=ee.createPolicy({organizationId:c.organization.id,projectId:c.project.id,environmentId:L.id,resourceId:y,dataServiceId:g,destinationId:l.id,name:String(S.name??"").trim(),resourceKind:D,schedule:String(S.schedule??"daily"),timezone:String(S.timezone??"UTC"),retention:S.retention&&typeof S.retention==="object"&&!Array.isArray(S.retention)?S.retention:{keepLast:7,expireAfterDays:30},compression:["none","gzip","zstd"].includes(String(S.compression))?S.compression:"gzip",encryption:["destination","client_side","both"].includes(String(S.encryption))?S.encryption:"destination",includePatterns:D==="volume"?[String(S.volumeName),...M]:M,excludePatterns:Array.isArray(S.excludePatterns)?S.excludePatterns.map(String):[],expectedRpoMinutes:Math.max(1,Number(S.expectedRpoMinutes)||1440),expectedRtoMinutes:Math.max(1,Number(S.expectedRtoMinutes)||120),healthCheckId:S.healthCheckId?String(S.healthCheckId):void 0,enabled:S.enabled!==!1});return O({ok:!0,policy:b},201)}catch(b){return O({ok:!1,error:b instanceof Error?b.message:String(b)},422)}}if(U.pathname==="/api/backups/run"&&C.method==="POST"){let S=await v(C),L=ee.getPolicy(String(S.policyId??"")),l=c.environments.get(V);if(!L||L.projectId!==c.project.id||L.environmentId!==l?.id)return O({ok:!1,error:"Backup policy was not found in this environment."},404);try{let D=TE.enqueueBackup(L,new Date().toISOString(),nt(Y).actor?.id);return O({ok:!0,job:D},202)}catch(D){return O({ok:!1,error:D instanceof Error?D.message:String(D)},409)}}if(U.pathname==="/api/backups/verify"&&C.method==="POST"){let S=await v(C),L=ee.getRecoveryPoint(String(S.recoveryPointId??""));if(!L||L.projectId!==c.project.id)return O({ok:!1,error:"Recovery point was not found."},404);return O({ok:!0,job:TE.enqueueVerification(L)},202)}if(U.pathname==="/api/backups/restore"&&C.method==="POST"){let S=await v(C),L=ee.getRecoveryPoint(String(S.recoveryPointId??"")),l=S.mode==="in_place"?"in_place":"isolated",D=S.target&&typeof S.target==="object"&&!Array.isArray(S.target)?{...S.target,inPlace:l==="in_place"}:{inPlace:l==="in_place"},g=kt.resolveSession(C),X={mode:l,target:D,targetName:String(S.targetName??""),confirm:S.confirm?String(S.confirm):void 0,recentAuth:!G||!!g&&Q.isRecentlyAuthenticated(g),downtimeAcknowledged:S.downtimeAcknowledged===!0,safetyBackupId:S.safetyBackupId?String(S.safetyBackupId):void 0};if(!L||L.projectId!==c.project.id)return O({ok:!1,error:"Recovery point was not found."},404);if(S.drill===!0&&l!=="isolated")return O({ok:!1,error:"Recovery drills must use an isolated target."},422);try{let y=TE.planRestore(L,X);if(S.execute!==!0)return O({ok:!0,plan:y,executionCreated:!1});let z=TE.enqueueRestore(L,{...X,drill:S.drill===!0,actorId:nt(Y).actor?.id});return O({ok:!0,plan:y,job:z},202)}catch(y){return O({ok:!1,error:y instanceof Error?y.message:String(y)},409)}}if(U.pathname==="/api/backups/recovery-points"&&C.method==="POST"){let S=await v(C),L=ee.getRecoveryPoint(String(S.id??""));if(!L||L.projectId!==c.project.id)return O({ok:!1,error:"Recovery point was not found."},404);if(S.held==null&&S.pinned==null)return O({ok:!1,error:"held or pinned must be provided."},422);return O({ok:!0,recoveryPoint:ee.updateRecoveryPoint(L.id,{held:S.held==null?L.held:S.held===!0,pinned:S.pinned==null?L.pinned:S.pinned===!0})})}if(U.pathname==="/api/backups/retention"&&C.method==="POST")return O({ok:!0,jobs:TE.enqueueRetention()},202);if(U.pathname==="/api/data-services/capabilities"&&C.method==="GET"){let S=String(U.searchParams.get("engine")??""),L=String(U.searchParams.get("provider")??"");if(!["postgres","mysql","mariadb","redis","mongodb","libsql"].includes(S)||!["aws_rds","aws_aurora","aws_elasticache","server","container","external"].includes(L))return O({ok:!1,error:"A supported engine and provider are required."},422);return O({ok:!0,engine:S,provider:L,capabilities:i_(S,L)})}if(U.pathname==="/api/data-services"&&C.method==="GET"){let S=c.environments.get(V),L=Gt.list(c.project.id,S?.id).map((l)=>{let D=Gt.credential(l.id);return{...l,credentialRef:void 0,credential:D?{configured:!0,username:D.username,version:D.version,rotatedAt:D.rotatedAt}:void 0,dependencies:Gt.dependencies(l.id).map((g)=>({resourceId:g.resourceId,requiresRedeploy:g.requiresRedeploy}))}});return O({ok:!0,services:L})}if(U.pathname==="/api/data-services/preview"&&C.method==="POST"){let S=await v(C);if(S.id){let D=Gt.get(String(S.id)),g=c.environments.get(V),X=String(S.action??"");if(!D||D.projectId!==c.project.id||D.environmentId!==g?.id)return O({ok:!1,error:"Data service was not found in this environment."},404);if(!xh.includes(X))return O({ok:!1,error:`Action must be one of: ${xh.join(", ")}.`},422);try{return O({ok:!0,plan:s_.plan(D,X,S.changes??{})})}catch(y){return O({ok:!1,error:y instanceof Error?y.message:String(y)},422)}}let L=String(S.engine??""),l=String(S.provider??"");if(!["postgres","mysql","mariadb","redis","mongodb","libsql"].includes(L)||!["aws_rds","aws_aurora","aws_elasticache","server","container","external"].includes(l))return O({ok:!1,error:"A supported engine and provider are required."},422);return O({ok:!0,capabilities:i_(L,l),defaults:{publicExposure:!1,backupRetentionDays:7,deletionProtection:!0},productionExecutionCreated:!1})}if(U.pathname==="/api/data-services"&&C.method==="POST"){let S=await v(C),L=String(S.engine??""),l=String(S.provider??""),D=c.environments.get(V),g=nt(Y);if(!D)return O({ok:!1,error:"Environment was not found."},404);if(!["postgres","mysql","mariadb","redis","mongodb","libsql"].includes(L)||!["aws_rds","aws_aurora","aws_elasticache","server","container","external"].includes(l))return O({ok:!1,error:"A supported engine and provider are required."},422);let X={organizationId:c.organization.id,projectId:c.project.id,environmentId:D.id,resourceId:S.resourceId?String(S.resourceId):void 0,name:String(S.name??"").trim(),engine:L,provider:l,placement:String(S.placement??S.name??"").trim(),engineVersion:S.engineVersion?String(S.engineVersion):void 0,plan:String(S.plan??(l==="aws_elasticache"?"cache.t4g.micro":l==="aws_aurora"?"db.serverless":"db.t4g.micro")),storageGb:S.storageGb==null?void 0:Number(S.storageGb),highAvailability:S.highAvailability===!0,publicExposure:S.publicExposure===!0,allowedCidrs:Array.isArray(S.allowedCidrs)?S.allowedCidrs.map(String):[],desiredState:S.desiredState&&typeof S.desiredState==="object"&&!Array.isArray(S.desiredState)?S.desiredState:{},observedState:{},origin:S.adopt===!0?"adopted":"managed",managementEnabled:S.adopt!==!0,ownerActorId:g.actor?.id,username:S.username?String(S.username):void 0};try{if(S.adopt===!0){let z=Gt.create({...X,status:"adopted",credentialRef:void 0});return O({ok:!0,service:z,readOnly:!0},201)}if(!Eu({provider:l,engine:L}))return O({ok:!1,error:`No ${l}/${L} provisioning adapter is configured; adopt it read-only or choose a supported provider.`},422);let y=await s_.create(X);return O({ok:!0,service:y.service,operationId:y.operationId,oneTimeCredential:y.credential},201)}catch(y){return O({ok:!1,error:y instanceof Error?y.message:String(y)},422)}}if(U.pathname==="/api/data-services/connections"&&C.method==="GET"){let S=Gt.get(String(U.searchParams.get("id")??"")),L=c.environments.get(V);if(!S||S.projectId!==c.project.id||S.environmentId!==L?.id)return O({ok:!1,error:"Data service was not found in this environment."},404);let l=typeof S.observedState.endpoint==="string"?S.observedState.endpoint:void 0,D=typeof S.observedState.readerEndpoint==="string"?S.observedState.readerEndpoint:void 0,g=Number(S.observedState.port)||(S.engine==="postgres"?5432:S.engine==="redis"?6379:S.engine==="mongodb"?27017:S.engine==="libsql"?8080:3306),X=typeof S.observedState.database==="string"?S.observedState.database:void 0,y=typeof S.observedState.tls==="boolean"?S.observedState.tls:S.provider.startsWith("aws_"),z=[...l?[{type:S.publicExposure?"external":"internal",host:l,port:g,database:X,tls:y}]:[],...D?[{type:"internal",host:D,port:g,database:X,tls:y}]:[],{type:"tunnel",host:l??S.placement,port:g,database:X,tls:y}];return O({ok:!0,serviceId:S.id,guidance:Ll(S,z)})}if(U.pathname==="/api/data-services/action"&&C.method==="POST"){let S=await v(C),L=Gt.get(String(S.id??"")),l=c.environments.get(V),D=String(S.action??"");if(!L||L.projectId!==c.project.id||L.environmentId!==l?.id)return O({ok:!1,error:"Data service was not found in this environment."},404);if(!xh.includes(D))return O({ok:!1,error:`Action must be one of: ${xh.join(", ")}.`},422);let g=S.changes&&typeof S.changes==="object"&&!Array.isArray(S.changes)?S.changes:{};try{let X=s_.plan(L,D,g);if(S.execute!==!0)return O({ok:!0,plan:X,productionExecutionCreated:!1});let y=s_.enqueue(L,D,g,nt(Y).actor?.id);return O({ok:!0,plan:X,operationId:y},202)}catch(X){return O({ok:!1,error:X instanceof Error?X.message:String(X)},409)}}if(U.pathname==="/api/data-services/dependencies"&&C.method==="POST"){let S=await v(C),L=Gt.get(String(S.id??"")),l=c.environments.get(V),D=c.store.getResource(String(S.resourceId??""));if(!L||L.projectId!==c.project.id||L.environmentId!==l?.id)return O({ok:!1,error:"Data service was not found in this environment."},404);if(!D||D.projectId!==c.project.id||D.environmentId!==l?.id)return O({ok:!1,error:"Dependent resource was not found in this environment."},404);if(S.remove===!0)return O({ok:Gt.removeDependency(L.id,D.id)});return Gt.addDependency({serviceId:L.id,resourceId:D.id,secretRef:L.credentialRef??`secret://data-services/${L.projectId}/${L.name}`,requiresRedeploy:S.requiresRedeploy!==!1}),O({ok:!0,dependencies:Gt.dependencies(L.id).map((g)=>({resourceId:g.resourceId,requiresRedeploy:g.requiresRedeploy}))})}if(U.pathname==="/api/data-services/management"&&C.method==="POST"){let S=await v(C),L=Gt.get(String(S.id??"")),l=c.environments.get(V);if(!L||L.projectId!==c.project.id||L.environmentId!==l?.id)return O({ok:!1,error:"Data service was not found in this environment."},404);if(L.origin!=="adopted"||S.reviewed!==!0||S.confirm!==L.name)return O({ok:!1,error:`Enabling management requires reviewed=true and typing ${L.name}.`},409);return O({ok:!0,service:Gt.update(L.id,L.version,{managementEnabled:!0})})}if(U.pathname==="/api/data-services/reveal"&&C.method==="POST"){let S=await v(C),L=Gt.get(String(S.id??"")),l=c.environments.get(V),D=L?Gt.credential(L.id):void 0;if(!L||L.projectId!==c.project.id||L.environmentId!==l?.id)return O({ok:!1,error:"Data service was not found in this environment."},404);if(!D)return O({ok:!1,error:"No managed credential is configured."},404);return O({ok:!0,credential:{username:D.username,password:await se.resolve(D.secretRef),version:D.version}},200,{"cache-control":"no-store"})}if(U.pathname==="/api/databases"&&C.method==="GET")return O(await LU(n,V));if(U.pathname==="/api/databases"&&C.method==="POST"){let S=await v(C),L=String(S.name??"").trim();if(!Oc(L))return O({ok:!1,error:"Database name must be a valid identifier (letters, numbers, underscore; not starting with a digit)."},422);return O({...await uU(n,V,L),name:L})}if(U.pathname==="/api/databases/vitess"&&C.method==="GET"){let S=await IU(n,V);return O({...S,unhealthy:DU(S.tablets),missingPrimary:fU(S)})}if(U.pathname==="/api/databases/vitess/migrations"&&C.method==="GET"){let S=U.searchParams.get("keyspace")??void 0;return O(await aU(n,V,S))}if(U.pathname==="/api/databases/vitess/migrations/action"&&C.method==="POST"){let S=await v(C),L=String(S.uuid??"").trim(),l=String(S.action??"");if(!["retry","cancel","cleanup","complete"].includes(l))return O({ok:!1,error:"Unknown migration action."},422);return O(await PU(n,V,L,l))}if(U.pathname==="/api/databases/vitess/keyspaces"&&C.method==="POST"){let S=await v(C),L=String(S.name??"").trim(),l=S.sharded===!0;return O(await $U(n,V,L,{sharded:l}))}if(U.pathname==="/api/databases/vitess/vschema"&&C.method==="POST"){let S=await v(C),L=String(S.keyspace??"").trim(),l=typeof S.vschema==="string"?S.vschema:JSON.stringify(S.vschema??null);return O(await yU(n,V,L,l))}if(U.pathname==="/api/databases/vitess/schema"&&C.method==="POST"){let S=await v(C),L=String(S.sql??"");return O(await XU(n,V,L))}if(U.pathname==="/api/databases/vitess/install-client"&&C.method==="POST")return O(await gU(n,V));if(U.pathname==="/api/databases/backups"&&C.method==="GET")return O(await lU(n,V));if(U.pathname==="/api/databases/backup"&&C.method==="POST"){let S=await v(C),L=String(S.database??"").trim();if(!Oc(L))return O({ok:!1,error:"Database name must be a valid identifier."},422);if(S.confirm!==L)return O({ok:!1,error:`Type "${L}" to back up this database.`},409);return O(await CU(n,V,L))}if(U.pathname==="/api/databases/users"&&C.method==="POST"){let S=await v(C),L=String(S.username??"").trim(),l=String(S.password??""),D=String(S.database??"").trim()||void 0,g=S.access==="readonly"?"readonly":"all";if(!Oc(L))return O({ok:!1,error:"Username must be a valid identifier."},422);if(!l)return O({ok:!1,error:"Password is required."},422);if(D&&!Oc(D))return O({ok:!1,error:"Database must be a valid identifier."},422);return O({...await OU(n,V,{username:L,password:l,database:D,access:g}),username:L})}if(U.pathname==="/api/dashboard-data")return Vt=R.get(V)??await a(V),a(V),O(YL(Vt,{user:Tr,slug:n.project.slug}));if(U.pathname==="/api/users"&&C.method==="GET")return O({ok:!0,users:Ye(e).map(fc)});if(U.pathname==="/api/users"&&C.method==="POST"){let S=await v(C),L=String(S.username??"").trim();if(!Qh(L))return O({ok:!1,error:"Username must be 2-32 characters: letters, numbers, dot, dash or underscore."},422);let l=S.sites&&typeof S.sites==="object"?S.sites:{},D=new Set(Object.keys(n.sites??{})),g={};for(let[z,M]of Object.entries(l)){if(!D.has(z))return O({ok:!1,error:`Site '${z}' was not found.`},404);if(M!=="owner"&&M!=="collaborator")return O({ok:!1,error:`Unknown site role '${M}'. Use 'owner' or 'collaborator'.`},422);g[z]=M}let X=typeof S.password==="string"&&S.password.trim()?S.password.trim():void 0;if(X&&X.length<12)return O({ok:!1,error:"Password must be at least 12 characters."},422);let y=G_(e,{username:L,password:X,name:typeof S.name==="string"?S.name:void 0,sites:g});return yh(c,Ye(e)),q(),O({ok:!0,user:fc(y.user),password:y.password})}if(U.pathname==="/api/users"&&C.method==="DELETE"){let S=await v(C),L=String(S.username??"").trim();if(L.toLowerCase()===Y.username.toLowerCase())return O({ok:!1,error:"You cannot remove your own account."},409);let l=wr(Ye(e),L),D=l?c.store.getActorByExternalId("user",`dashboard:${l.username.toLowerCase()}`):void 0,g=D?c.store.getMembershipForActor(c.organization.id,D.id):void 0;if(g&&g.source!=="legacy")return O({ok:!1,error:"Organization members must be removed from Organization access."},409);let X=WL(e,L);if(!X.ok)return O(X,409);return yh(c,Ye(e)),F.clear(),O({ok:!0,username:L})}if(U.pathname==="/api/actions/run"&&C.method==="POST"){let S=await C.json().catch(()=>({})),L=S.action?lJ(S.action,V):void 0;if(!L)return O({ok:!1,error:"Unknown dashboard action."},404);if(L.mutates&&S.confirm!==L.confirm)return O({ok:!1,error:`Type "${L.confirm}" to run this action.`},409);let l=await Dd({controlPlane:c,environment:V,actor:Y,kind:`dashboard.action.${L.id}`,input:{action:L.id},execute:()=>tu(L,{cwd:e,cliEntry:E})});return O({...l.result,controlPlaneOperation:l.operation})}if(U.pathname==="/api/server/operations/run"&&C.method==="POST"){let S=await C.json().catch(()=>({})),L=S.operation?QL(S.operation,n,Vt):void 0;if(!L)return O({ok:!1,error:"Unknown or unavailable server operation."},404);if(L.mutates&&S.confirm!==L.confirm)return O({ok:!1,error:`Type "${L.confirm}" to run this operation.`},409);let l=Jr(c,String(V));await new Ac(ct).run(new J_,{...l,artifactRoot:e});let D=$h(ct,{scope:l,desiredConfigHash:c.project.desiredConfigHash});if(D.decision.outcome==="block")return O({ok:!1,error:`Operation blocked by security policy: ${D.decision.explanation}`,securityReview:D},409);let g=await Dd({controlPlane:c,environment:V,actor:Y,kind:`dashboard.server.${L.id}`,resourceSlug:L.target,input:{operation:L.id,target:L.target,to:S.to??null},execute:()=>Vh(n,V,L,{to:S.to})});return O({...g.result,controlPlaneOperation:g.operation,securityReview:D})}if(U.pathname==="/api/server/command"&&C.method==="POST"){let S=await C.json().catch(()=>({}));if(S.confirm!=="run")return O({ok:!1,error:'Type "run" to execute this command on the server.'},409);let L=await Dd({controlPlane:c,environment:V,actor:Y,kind:"dashboard.server.command",input:{source:"interactive-command"},execute:()=>V_(n,V,String(S.command??""))});return O({...L.result,controlPlaneOperation:L.operation})}if(U.pathname==="/api/serverless/operations")return O(ZL(n,V,Vt));if(U.pathname==="/api/serverless/operations/run"&&C.method==="POST"){let S=await C.json().catch(()=>({})),L=S.operation?iw(S.operation,n,V,Vt):void 0;if(!L)return O({ok:!1,error:"Unknown or unavailable serverless operation."},404);if(L.mutates&&S.confirm!==L.confirm)return O({ok:!1,error:`Type "${L.confirm}" to run this operation.`},409);let l=await Dd({controlPlane:c,environment:V,actor:Y,kind:`dashboard.serverless.${L.id}`,input:{operation:L.id,min:S.min??null,max:S.max??null},execute:()=>hw(n,V,L,{min:S.min,max:S.max})});return Vt=await rn(n,V),R.set(V,Vt),O({...l.result,controlPlaneOperation:l.operation})}if(U.pathname==="/api/serverless/command"&&C.method==="POST"){let S=await C.json().catch(()=>({}));if(S.confirm!=="run")return O({ok:!1,error:'Type "run" to execute this command.'},409);return O(await Rw(n,V,String(S.command??"")))}if(U.pathname==="/api/serverless/dlq"&&C.method==="GET"){let S=Number(U.searchParams.get("max"))||10;return O(await Sw(n,V,S))}if(U.pathname==="/api/serverless/dlq/redrive"&&C.method==="POST"){let S=await C.json().catch(()=>({}));if(S.confirm!=="redrive")return O({ok:!1,error:'Type "redrive" to move messages back onto a source queue.'},409);return O(await Nw(n,V,{max:S.max,targetQueue:S.targetQueue}))}if(U.pathname==="/api/serverless/dlq/purge"&&C.method==="POST"){if((await C.json().catch(()=>({}))).confirm!=="purge")return O({ok:!1,error:'Type "purge" to permanently discard every DLQ message.'},409);return O(await Aw(n,V))}if(U.pathname==="/api/serverless/secrets"&&C.method==="GET")return O({secrets:Lw(n,V)});if(U.pathname==="/api/serverless/secrets"&&C.method==="POST"){let S=await C.json().catch(()=>({})),L=String(S.secretId??"").trim();if(!L)return O({ok:!1,error:"A secret id is required."},422);if(typeof S.value!=="string"||S.value==="")return O({ok:!1,error:"A non-empty value is required."},422);return O(await uw(n,V,L,S.value))}if(U.pathname==="/api/serverless/secrets"&&C.method==="DELETE"){let S=await C.json().catch(()=>({})),L=String(S.secretId??"").trim();if(!L)return O({ok:!1,error:"A secret id is required."},422);if(S.confirm!==L)return O({ok:!1,error:`Type "${L}" to delete this secret.`},409);return O(await Ow(n,V,L))}if(U.pathname==="/api/serverless/functions/config"&&C.method==="POST"){let S=await C.json().catch(()=>({})),L=String(S.mode??"").trim();if(S.confirm!==L)return O({ok:!1,error:`Type "${L}" to update this function.`},409);return O(await Cw(n,V,L,{memory:S.memory,timeout:S.timeout}))}if(U.pathname==="/api/serverless/alarms"&&C.method==="GET")return O(await lw(n,V));if(U.pathname==="/api/serverless/alarms"&&C.method==="POST"){let S=await C.json().catch(()=>({})),L=String(S.preset??"").trim(),l=Number(S.threshold);if(!L)return O({ok:!1,error:"An alarm metric is required."},422);if(!Number.isFinite(l))return O({ok:!1,error:"A numeric threshold is required."},422);return O(await Iw(n,V,L,l))}if(U.pathname==="/api/serverless/alarms"&&C.method==="DELETE"){let S=await C.json().catch(()=>({})),L=String(S.name??"").trim();if(!L)return O({ok:!1,error:"An alarm name is required."},422);if(S.confirm!==L)return O({ok:!1,error:`Type "${L}" to delete this alarm.`},409);return O(await Dw(n,V,L))}if(U.pathname==="/api/serverless/traces"&&C.method==="GET"){let S=Number(U.searchParams.get("minutes"))||30;return O(await Zh(n,V,S))}if(U.pathname==="/api/serverless/scheduler"&&C.method==="POST"){let S=await C.json().catch(()=>({})),L=String(S.action??"").trim();if(L!=="enable"&&L!=="disable"&&L!=="run")return O({ok:!1,error:"Unknown scheduler action."},422);if(S.confirm!==L)return O({ok:!1,error:`Type "${L}" to ${L} the scheduler.`},409);return O(await xL(n,V,L))}if(!bw(U.pathname,Tr))return new Response(null,{status:302,headers:{location:`/access-denied?env=${encodeURIComponent(V)}`}});let _n=await Et(Y,V);if(!_n)return sh("ts-cloud dashboard UI is unavailable.",503);return xw(_n,U.pathname)}catch(hE){if(t.verbose)console.error(hE);return O({ok:!1,error:hE?.message??String(hE)},500)}})();if(!ot)return ot;if(Jt&&(U.pathname.startsWith("/api/")||U.pathname.startsWith("/auth/"))){let Ct;if((s.headers.get("content-type")||"").includes("application/json"))Ct=await s.json().catch(()=>{return});let ue=kt.resolveUser(C),he=ue?nt(ue).actor:void 0;c.store.appendEvent({organizationId:c.organization.id,projectId:c.project.id,actorId:he?.id,correlationId:Nt,type:ot.status<400?"dashboard.mutation.succeeded":"dashboard.mutation.failed",level:ot.status<400?"info":"warning",payload:dJ(C.method,U.pathname,Ct,ot.status,Date.now()-Tt)})}return ot.headers.set("x-request-id",Nt),ot}});o_?.start();let ig=nn.stop.bind(nn);return nn.stop=(C)=>{clearInterval(Ou),clearInterval(Cu),clearInterval(lu),clearInterval(uu),clearInterval(Lu),clearInterval(Ru),clearInterval(Su),clearInterval(Nu),clearInterval(Au),q(),re.clear(),o_?.stop();let p=ig(C);if(o_)o_.settled().finally(()=>c.store.close());else c.store.close();return p},{server:nn,url:`http://${r}:${nn.port}/`}}function ru(t){let e=q_.argv.indexOf(t);return e===-1?void 0:q_.argv[e+1]}function pw(t){return q_.argv.includes(t)}async function gJ(){let t=await mw({host:ru("--host")??"127.0.0.1",port:Number(ru("--port")??7676),environment:ru("--env"),box:pw("--box"),verbose:pw("--verbose")});console.log("ts-cloud Local Dashboard"),console.log(`Serving ${t.url}`),await new Promise((e)=>{let r=()=>{t.server.stop(!0),e()};q_.once("SIGINT",r),q_.once("SIGTERM",r)})}gJ();
|