@stacksjs/cloud 0.72.78 → 0.72.79

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.
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Build query string for AWS API calls
3
+ */
4
+ export declare function buildQueryParams(params: Record<string, any>): Record<string, string>;
5
+ export declare interface AWSCredentials {
6
+ accessKeyId: string
7
+ secretAccessKey: string
8
+ sessionToken?: string
9
+ }
10
+ export declare interface AWSRequestOptions {
11
+ service: string
12
+ region: string
13
+ method: string
14
+ path: string
15
+ queryParams?: Record<string, string>
16
+ headers?: Record<string, string>
17
+ body?: string
18
+ credentials?: AWSCredentials
19
+ retries?: number
20
+ cacheKey?: string
21
+ cacheTTL?: number
22
+ returnHeaders?: boolean
23
+ rawResponse?: boolean
24
+ }
25
+ export declare interface AWSClientConfig {
26
+ maxRetries?: number
27
+ retryDelay?: number
28
+ cacheEnabled?: boolean
29
+ defaultCacheTTL?: number
30
+ }
31
+ export declare interface AWSError extends Error {
32
+ code?: string
33
+ statusCode?: number
34
+ requestId?: string
35
+ type?: string
36
+ }
37
+ /**
38
+ * AWS API Client - Makes authenticated requests to AWS services
39
+ */
40
+ export declare class AWSClient {
41
+ constructor(credentials?: AWSCredentials, config?: AWSClientConfig);
42
+ request(options: AWSRequestOptions): Promise<any>;
43
+ clearCache(): void;
44
+ clearExpiredCache(): void;
45
+ }
@@ -0,0 +1,178 @@
1
+ export declare interface S3SyncOptions {
2
+ source: string
3
+ bucket: string
4
+ prefix?: string
5
+ delete?: boolean
6
+ acl?: 'private' | 'public-read' | 'public-read-write' | 'authenticated-read'
7
+ cacheControl?: string
8
+ contentType?: string
9
+ metadata?: Record<string, string>
10
+ exclude?: string[]
11
+ include?: string[]
12
+ dryRun?: boolean
13
+ }
14
+ export declare interface S3CopyOptions {
15
+ source: string
16
+ bucket: string
17
+ key: string
18
+ acl?: 'private' | 'public-read' | 'public-read-write' | 'authenticated-read'
19
+ cacheControl?: string
20
+ contentType?: string
21
+ metadata?: Record<string, string>
22
+ }
23
+ export declare interface S3ListOptions {
24
+ bucket: string
25
+ prefix?: string
26
+ maxKeys?: number
27
+ }
28
+ export declare interface S3Object {
29
+ Key: string
30
+ LastModified: string
31
+ Size: number
32
+ ETag?: string
33
+ }
34
+ /**
35
+ * S3 client using direct API calls
36
+ */
37
+ export declare class S3Client {
38
+ constructor(region?: string, profile?: string);
39
+ listBuckets(): Promise<{ Buckets: Array<{ Name: string, CreationDate?: string }> }>;
40
+ createBucket(bucket: string, options?: { acl?: string }): Promise<void>;
41
+ deleteBucket(bucket: string): Promise<void>;
42
+ emptyAndDeleteBucket(bucket: string): Promise<void>;
43
+ listAllObjects(options: S3ListOptions): Promise<S3Object[]>;
44
+ list(options: S3ListOptions): Promise<S3Object[]>;
45
+ putObject(options: {
46
+ bucket: string
47
+ key: string
48
+ body: string | Buffer
49
+ acl?: string
50
+ cacheControl?: string
51
+ contentType?: string
52
+ metadata?: Record<string, string>
53
+ }): Promise<void>;
54
+ getObject(bucket: string, key: string): Promise<string>;
55
+ copyObject(options: {
56
+ sourceBucket: string
57
+ sourceKey: string
58
+ destinationBucket: string
59
+ destinationKey: string
60
+ contentType?: string
61
+ metadata?: Record<string, string>
62
+ metadataDirective?: 'COPY' | 'REPLACE'
63
+ }): Promise<void>;
64
+ deleteObject(bucket: string, key: string): Promise<void>;
65
+ deleteObjects(bucket: string, keys: string[]): Promise<void>;
66
+ bucketExists(bucket: string): Promise<boolean>;
67
+ copy(options: S3CopyOptions): Promise<void>;
68
+ sync(options: S3SyncOptions): Promise<void>;
69
+ delete(bucket: string, key: string): Promise<void>;
70
+ deletePrefix(bucket: string, prefix: string): Promise<void>;
71
+ getBucketSize(bucket: string, prefix?: string): Promise<number>;
72
+ putBucketPolicy(bucket: string, policy: object | string): Promise<void>;
73
+ getBucketPolicy(bucket: string): Promise<object | null>;
74
+ deleteBucketPolicy(bucket: string): Promise<void>;
75
+ headBucket(bucket: string): Promise<{ exists: boolean; region?: string }>;
76
+ headObject(bucket: string, key: string): Promise<{
77
+ ContentLength?: number
78
+ ContentType?: string
79
+ ETag?: string
80
+ LastModified?: string
81
+ Metadata?: Record<string, string>
82
+ ServerSideEncryption?: string
83
+ } | null>;
84
+ getObjectBuffer(bucket: string, key: string): Promise<Buffer>;
85
+ getObjectJson<T = any>(bucket: string, key: string): Promise<T>;
86
+ putObjectJson(bucket: string, key: string, data: any, options?: {
87
+ acl?: string
88
+ cacheControl?: string
89
+ metadata?: Record<string, string>
90
+ }): Promise<void>;
91
+ getBucketVersioning(bucket: string): Promise<{ Status?: 'Enabled' | 'Suspended' }>;
92
+ putBucketVersioning(bucket: string, status: 'Enabled' | 'Suspended'): Promise<void>;
93
+ getBucketLifecycleConfiguration(bucket: string): Promise<any>;
94
+ putBucketLifecycleConfiguration(bucket: string, rules: Array<{
95
+ ID: string
96
+ Status: 'Enabled' | 'Disabled'
97
+ Filter?: { Prefix?: string }
98
+ Expiration?: { Days?: number; Date?: string }
99
+ Transitions?: Array<{ Days?: number; StorageClass: string }>
100
+ NoncurrentVersionExpiration?: { NoncurrentDays: number }
101
+ }>): Promise<void>;
102
+ deleteBucketLifecycleConfiguration(bucket: string): Promise<void>;
103
+ getBucketCors(bucket: string): Promise<any>;
104
+ putBucketCors(bucket: string, rules: Array<{
105
+ AllowedOrigins: string[]
106
+ AllowedMethods: string[]
107
+ AllowedHeaders?: string[]
108
+ ExposeHeaders?: string[]
109
+ MaxAgeSeconds?: number
110
+ }>): Promise<void>;
111
+ deleteBucketCors(bucket: string): Promise<void>;
112
+ getBucketEncryption(bucket: string): Promise<any>;
113
+ putBucketEncryption(bucket: string, sseAlgorithm: 'AES256' | 'aws:kms', kmsKeyId?: string): Promise<void>;
114
+ deleteBucketEncryption(bucket: string): Promise<void>;
115
+ getBucketTagging(bucket: string): Promise<Array<{ Key: string; Value: string }>>;
116
+ putBucketTagging(bucket: string, tags: Array<{ Key: string; Value: string }>): Promise<void>;
117
+ deleteBucketTagging(bucket: string): Promise<void>;
118
+ getObjectTagging(bucket: string, key: string): Promise<Array<{ Key: string; Value: string }>>;
119
+ putObjectTagging(bucket: string, key: string, tags: Array<{ Key: string; Value: string }>): Promise<void>;
120
+ deleteObjectTagging(bucket: string, key: string): Promise<void>;
121
+ getBucketAcl(bucket: string): Promise<any>;
122
+ putBucketAcl(bucket: string, acl: 'private' | 'public-read' | 'public-read-write' | 'authenticated-read'): Promise<void>;
123
+ getObjectAcl(bucket: string, key: string): Promise<any>;
124
+ putObjectAcl(bucket: string, key: string, acl: 'private' | 'public-read' | 'public-read-write' | 'authenticated-read'): Promise<void>;
125
+ getBucketLocation(bucket: string): Promise<string>;
126
+ getBucketLogging(bucket: string): Promise<any>;
127
+ putBucketLogging(bucket: string, targetBucket: string, targetPrefix: string): Promise<void>;
128
+ getBucketNotificationConfiguration(bucket: string): Promise<any>;
129
+ putBucketNotificationConfiguration(bucket: string, config: {
130
+ LambdaFunctionConfigurations?: Array<{
131
+ Id?: string
132
+ LambdaFunctionArn: string
133
+ Events: string[]
134
+ Filter?: { Key?: { FilterRules: Array<{ Name: string; Value: string }> } }
135
+ }>
136
+ TopicConfigurations?: Array<{
137
+ Id?: string
138
+ TopicArn: string
139
+ Events: string[]
140
+ Filter?: { Key?: { FilterRules: Array<{ Name: string; Value: string }> } }
141
+ }>
142
+ QueueConfigurations?: Array<{
143
+ Id?: string
144
+ QueueArn: string
145
+ Events: string[]
146
+ Filter?: { Key?: { FilterRules: Array<{ Name: string; Value: string }> } }
147
+ }>
148
+ }): Promise<void>;
149
+ getBucketWebsite(bucket: string): Promise<any>;
150
+ putBucketWebsite(bucket: string, config: {
151
+ IndexDocument: string
152
+ ErrorDocument?: string
153
+ RedirectAllRequestsTo?: { HostName: string; Protocol?: string }
154
+ }): Promise<void>;
155
+ deleteBucketWebsite(bucket: string): Promise<void>;
156
+ getBucketReplication(bucket: string): Promise<any>;
157
+ deleteBucketReplication(bucket: string): Promise<void>;
158
+ getPublicAccessBlock(bucket: string): Promise<any>;
159
+ putPublicAccessBlock(bucket: string, config: {
160
+ BlockPublicAcls?: boolean
161
+ IgnorePublicAcls?: boolean
162
+ BlockPublicPolicy?: boolean
163
+ RestrictPublicBuckets?: boolean
164
+ }): Promise<void>;
165
+ deletePublicAccessBlock(bucket: string): Promise<void>;
166
+ generatePresignedGetUrl(bucket: string, key: string, expiresInSeconds?: number): string;
167
+ generatePresignedPutUrl(bucket: string, key: string, contentType: string, expiresInSeconds?: number): string;
168
+ createMultipartUpload(bucket: string, key: string, options?: {
169
+ contentType?: string
170
+ metadata?: Record<string, string>
171
+ }): Promise<{ UploadId: string }>;
172
+ uploadPart(bucket: string, key: string, uploadId: string, partNumber: number, body: Buffer): Promise<{ ETag: string }>;
173
+ completeMultipartUpload(bucket: string, key: string, uploadId: string, parts: Array<{ PartNumber: number; ETag: string }>): Promise<void>;
174
+ abortMultipartUpload(bucket: string, key: string, uploadId: string): Promise<void>;
175
+ listMultipartUploads(bucket: string): Promise<Array<{ Key: string; UploadId: string; Initiated: string }>>;
176
+ restoreObject(bucket: string, key: string, days: number, tier?: 'Standard' | 'Bulk' | 'Expedited'): Promise<void>;
177
+ selectObjectContent(bucket: string, key: string, expression: string, inputFormat: 'CSV' | 'JSON' | 'Parquet', outputFormat?: 'CSV' | 'JSON'): Promise<string>;
178
+ }
@@ -0,0 +1,167 @@
1
+ export declare interface Secret {
2
+ ARN?: string
3
+ Name?: string
4
+ Description?: string
5
+ KmsKeyId?: string
6
+ RotationEnabled?: boolean
7
+ RotationLambdaARN?: string
8
+ RotationRules?: {
9
+ AutomaticallyAfterDays?: number
10
+ Duration?: string
11
+ ScheduleExpression?: string
12
+ }
13
+ LastRotatedDate?: string
14
+ LastChangedDate?: string
15
+ LastAccessedDate?: string
16
+ DeletedDate?: string
17
+ NextRotationDate?: string
18
+ Tags?: { Key: string, Value: string }[]
19
+ SecretVersionsToStages?: Record<string, string[]>
20
+ CreatedDate?: string
21
+ PrimaryRegion?: string
22
+ }
23
+ export declare interface SecretValue {
24
+ ARN?: string
25
+ Name?: string
26
+ VersionId?: string
27
+ SecretBinary?: string
28
+ SecretString?: string
29
+ VersionStages?: string[]
30
+ CreatedDate?: string
31
+ }
32
+ export declare interface CreateSecretOptions {
33
+ Name: string
34
+ Description?: string
35
+ KmsKeyId?: string
36
+ SecretBinary?: string
37
+ SecretString?: string
38
+ Tags?: { Key: string, Value: string }[]
39
+ AddReplicaRegions?: { Region: string, KmsKeyId?: string }[]
40
+ ForceOverwriteReplicaSecret?: boolean
41
+ ClientRequestToken?: string
42
+ }
43
+ export declare interface UpdateSecretOptions {
44
+ SecretId: string
45
+ Description?: string
46
+ KmsKeyId?: string
47
+ SecretBinary?: string
48
+ SecretString?: string
49
+ ClientRequestToken?: string
50
+ }
51
+ export declare interface PutSecretValueOptions {
52
+ SecretId: string
53
+ SecretBinary?: string
54
+ SecretString?: string
55
+ VersionStages?: string[]
56
+ ClientRequestToken?: string
57
+ }
58
+ export declare interface GetSecretValueOptions {
59
+ SecretId: string
60
+ VersionId?: string
61
+ VersionStage?: string
62
+ }
63
+ export declare interface RotationRules {
64
+ AutomaticallyAfterDays?: number
65
+ Duration?: string
66
+ ScheduleExpression?: string
67
+ }
68
+ /**
69
+ * Secrets Manager client using direct API calls
70
+ */
71
+ export declare class SecretsManagerClient {
72
+ constructor(region?: string, profile?: string);
73
+ createSecret(options: CreateSecretOptions): Promise<{
74
+ ARN?: string
75
+ Name?: string
76
+ VersionId?: string
77
+ ReplicationStatus?: { Region: string, Status: string, StatusMessage?: string }[]
78
+ }>;
79
+ updateSecret(options: UpdateSecretOptions): Promise<{
80
+ ARN?: string
81
+ Name?: string
82
+ VersionId?: string
83
+ }>;
84
+ putSecretValue(options: PutSecretValueOptions): Promise<{
85
+ ARN?: string
86
+ Name?: string
87
+ VersionId?: string
88
+ VersionStages?: string[]
89
+ }>;
90
+ getSecretValue(options: GetSecretValueOptions): Promise<SecretValue>;
91
+ describeSecret(secretId: string): Promise<Secret>;
92
+ listSecrets(options?: {
93
+ MaxResults?: number
94
+ NextToken?: string
95
+ Filters?: { Key: string, Values: string[] }[]
96
+ SortOrder?: 'asc' | 'desc'
97
+ }): Promise<{
98
+ SecretList?: Secret[]
99
+ NextToken?: string
100
+ }>;
101
+ deleteSecret(options: {
102
+ SecretId: string
103
+ RecoveryWindowInDays?: number
104
+ ForceDeleteWithoutRecovery?: boolean
105
+ }): Promise<{
106
+ ARN?: string
107
+ Name?: string
108
+ DeletionDate?: string
109
+ }>;
110
+ restoreSecret(secretId: string): Promise<{
111
+ ARN?: string
112
+ Name?: string
113
+ }>;
114
+ rotateSecret(options: {
115
+ SecretId: string
116
+ ClientRequestToken?: string
117
+ RotationLambdaARN?: string
118
+ RotationRules?: RotationRules
119
+ RotateImmediately?: boolean
120
+ }): Promise<{
121
+ ARN?: string
122
+ Name?: string
123
+ VersionId?: string
124
+ }>;
125
+ cancelRotateSecret(secretId: string): Promise<{
126
+ ARN?: string
127
+ Name?: string
128
+ }>;
129
+ getResourcePolicy(secretId: string): Promise<{
130
+ ARN?: string
131
+ Name?: string
132
+ ResourcePolicy?: string
133
+ }>;
134
+ putResourcePolicy(options: {
135
+ SecretId: string
136
+ ResourcePolicy: string
137
+ BlockPublicPolicy?: boolean
138
+ }): Promise<{
139
+ ARN?: string
140
+ Name?: string
141
+ }>;
142
+ deleteResourcePolicy(secretId: string): Promise<{
143
+ ARN?: string
144
+ Name?: string
145
+ }>;
146
+ tagResource(options: {
147
+ SecretId: string
148
+ Tags: { Key: string, Value: string }[]
149
+ }): Promise<void>;
150
+ untagResource(options: {
151
+ SecretId: string
152
+ TagKeys: string[]
153
+ }): Promise<void>;
154
+ setString(name: string, value: string, options?: {
155
+ description?: string
156
+ kmsKeyId?: string
157
+ tags?: { Key: string, Value: string }[]
158
+ }): Promise<{ ARN?: string, VersionId?: string }>;
159
+ setJson(name: string, value: Record<string, any>, options?: {
160
+ description?: string
161
+ kmsKeyId?: string
162
+ tags?: { Key: string, Value: string }[]
163
+ }): Promise<{ ARN?: string, VersionId?: string }>;
164
+ getString(secretId: string): Promise<string | undefined>;
165
+ getJson<T = Record<string, any>>(secretId: string): Promise<T | undefined>;
166
+ listAll(): Promise<Secret[]>;
167
+ }
@@ -0,0 +1,283 @@
1
+ export declare interface EmailIdentity {
2
+ IdentityType?: 'EMAIL_ADDRESS' | 'DOMAIN' | 'MANAGED_DOMAIN'
3
+ IdentityName?: string
4
+ SendingEnabled?: boolean
5
+ VerificationStatus?: 'PENDING' | 'SUCCESS' | 'FAILED' | 'TEMPORARY_FAILURE' | 'NOT_STARTED'
6
+ DkimAttributes?: {
7
+ SigningEnabled?: boolean
8
+ Status?: 'PENDING' | 'SUCCESS' | 'FAILED' | 'TEMPORARY_FAILURE' | 'NOT_STARTED'
9
+ Tokens?: string[]
10
+ SigningAttributesOrigin?: 'AWS_SES' | 'EXTERNAL'
11
+ }
12
+ MailFromAttributes?: {
13
+ MailFromDomain?: string
14
+ MailFromDomainStatus?: 'PENDING' | 'SUCCESS' | 'FAILED' | 'TEMPORARY_FAILURE'
15
+ BehaviorOnMxFailure?: 'USE_DEFAULT_VALUE' | 'REJECT_MESSAGE'
16
+ }
17
+ }
18
+ export declare interface SendEmailResult {
19
+ MessageId?: string
20
+ }
21
+ /**
22
+ * SES email service management using direct API calls
23
+ */
24
+ export declare class SESClient {
25
+ constructor(region?: string);
26
+ createEmailIdentity(params: {
27
+ EmailIdentity: string
28
+ DkimSigningAttributes?: {
29
+ DomainSigningSelector?: string
30
+ DomainSigningPrivateKey?: string
31
+ }
32
+ Tags?: Array<{ Key: string, Value: string }>
33
+ }): Promise<{
34
+ IdentityType?: string
35
+ VerifiedForSendingStatus?: boolean
36
+ DkimAttributes?: {
37
+ SigningEnabled?: boolean
38
+ Status?: string
39
+ Tokens?: string[]
40
+ SigningAttributesOrigin?: string
41
+ }
42
+ }>;
43
+ getEmailIdentity(emailIdentity: string): Promise<EmailIdentity>;
44
+ putEmailIdentityMailFromAttributes(emailIdentity: string, params: {
45
+ MailFromDomain?: string
46
+ BehaviorOnMxFailure?: 'USE_DEFAULT_VALUE' | 'REJECT_MESSAGE'
47
+ }): Promise<void>;
48
+ listEmailIdentities(params?: {
49
+ PageSize?: number
50
+ NextToken?: string
51
+ }): Promise<{
52
+ EmailIdentities?: Array<{
53
+ IdentityType?: string
54
+ IdentityName?: string
55
+ SendingEnabled?: boolean
56
+ }>
57
+ NextToken?: string
58
+ }>;
59
+ deleteEmailIdentity(emailIdentity: string): Promise<void>;
60
+ putEmailIdentityDkimAttributes(params: {
61
+ EmailIdentity: string
62
+ SigningEnabled: boolean
63
+ }): Promise<void>;
64
+ sendEmail(params: {
65
+ FromEmailAddress: string
66
+ Destination: {
67
+ ToAddresses?: string[]
68
+ CcAddresses?: string[]
69
+ BccAddresses?: string[]
70
+ }
71
+ Content: {
72
+ Simple?: {
73
+ Subject: { Data: string, Charset?: string }
74
+ Body: {
75
+ Text?: { Data: string, Charset?: string }
76
+ Html?: { Data: string, Charset?: string }
77
+ }
78
+ }
79
+ Raw?: {
80
+ }
81
+ Template?: {
82
+ TemplateName: string
83
+ TemplateData?: string
84
+ }
85
+ }
86
+ ReplyToAddresses?: string[]
87
+ ConfigurationSetName?: string
88
+ }): Promise<SendEmailResult>;
89
+ sendBulkEmail(params: {
90
+ FromEmailAddress: string
91
+ BulkEmailEntries: Array<{
92
+ Destination: {
93
+ ToAddresses?: string[]
94
+ CcAddresses?: string[]
95
+ BccAddresses?: string[]
96
+ }
97
+ ReplacementEmailContent?: {
98
+ ReplacementTemplate?: {
99
+ ReplacementTemplateData?: string
100
+ }
101
+ }
102
+ }>
103
+ DefaultContent: {
104
+ Template: {
105
+ TemplateName: string
106
+ TemplateData?: string
107
+ }
108
+ }
109
+ ConfigurationSetName?: string
110
+ }): Promise<{
111
+ BulkEmailEntryResults?: Array<{
112
+ Status?: string
113
+ Error?: string
114
+ MessageId?: string
115
+ }>
116
+ }>;
117
+ createEmailTemplate(params: {
118
+ TemplateName: string
119
+ TemplateContent: {
120
+ Subject?: string
121
+ Text?: string
122
+ Html?: string
123
+ }
124
+ }): Promise<void>;
125
+ getEmailTemplate(templateName: string): Promise<{
126
+ TemplateName?: string
127
+ TemplateContent?: {
128
+ Subject?: string
129
+ Text?: string
130
+ Html?: string
131
+ }
132
+ }>;
133
+ deleteEmailTemplate(templateName: string): Promise<void>;
134
+ listEmailTemplates(params?: {
135
+ PageSize?: number
136
+ NextToken?: string
137
+ }): Promise<{
138
+ TemplatesMetadata?: Array<{
139
+ TemplateName?: string
140
+ CreatedTimestamp?: string
141
+ }>
142
+ NextToken?: string
143
+ }>;
144
+ getSendStatistics(): Promise<{
145
+ SendDataPoints?: Array<{
146
+ Timestamp?: string
147
+ DeliveryAttempts?: number
148
+ Bounces?: number
149
+ Complaints?: number
150
+ Rejects?: number
151
+ }>
152
+ }>;
153
+ getSendQuota(): Promise<{
154
+ Max24HourSend?: number
155
+ MaxSendRate?: number
156
+ SentLast24Hours?: number
157
+ }>;
158
+ verifyDomain(domain: string): Promise<{
159
+ dkimTokens?: string[]
160
+ verificationStatus?: string
161
+ }>;
162
+ sendSimpleEmail(params: {
163
+ from: string
164
+ to: string | string[]
165
+ subject: string
166
+ text?: string
167
+ html?: string
168
+ replyTo?: string | string[]
169
+ }): Promise<SendEmailResult>;
170
+ sendTemplatedEmail(params: {
171
+ from: string
172
+ to: string | string[]
173
+ templateName: string
174
+ templateData: Record<string, any>
175
+ replyTo?: string | string[]
176
+ }): Promise<SendEmailResult>;
177
+ getDkimRecords(domain: string): Promise<Array<{
178
+ name: string
179
+ type: string
180
+ value: string
181
+ }>>;
182
+ isDomainVerified(domain: string): Promise<boolean>;
183
+ waitForDomainVerification(domain: string, maxAttempts?: number, delayMs?: number): Promise<boolean>;
184
+ createReceiptRuleSet(ruleSetName: string): Promise<void>;
185
+ deleteReceiptRuleSet(ruleSetName: string): Promise<void>;
186
+ setActiveReceiptRuleSet(ruleSetName: string): Promise<void>;
187
+ listReceiptRuleSets(nextToken?: string): Promise<{
188
+ RuleSets?: Array<{ Name?: string, CreatedTimestamp?: string }>
189
+ NextToken?: string
190
+ }>;
191
+ describeReceiptRuleSet(ruleSetName: string): Promise<{
192
+ Metadata?: { Name?: string, CreatedTimestamp?: string }
193
+ Rules?: Array<{
194
+ Name?: string
195
+ Enabled?: boolean
196
+ Recipients?: string[]
197
+ Actions?: Array<{
198
+ S3Action?: { BucketName?: string, ObjectKeyPrefix?: string }
199
+ LambdaAction?: { FunctionArn?: string, InvocationType?: string }
200
+ SNSAction?: { TopicArn?: string }
201
+ }>
202
+ }>
203
+ }>;
204
+ createReceiptRule(params: {
205
+ RuleSetName: string
206
+ Rule: {
207
+ Name: string
208
+ Enabled?: boolean
209
+ TlsPolicy?: 'Require' | 'Optional'
210
+ Recipients?: string[]
211
+ ScanEnabled?: boolean
212
+ Actions: Array<{
213
+ S3Action?: {
214
+ BucketName: string
215
+ ObjectKeyPrefix?: string
216
+ KmsKeyArn?: string
217
+ }
218
+ LambdaAction?: {
219
+ FunctionArn: string
220
+ InvocationType?: 'Event' | 'RequestResponse'
221
+ }
222
+ SNSAction?: {
223
+ TopicArn: string
224
+ Encoding?: 'UTF-8' | 'Base64'
225
+ }
226
+ StopAction?: {
227
+ Scope: 'RuleSet'
228
+ TopicArn?: string
229
+ }
230
+ }>
231
+ }
232
+ After?: string
233
+ }): Promise<void>;
234
+ deleteReceiptRule(ruleSetName: string, ruleName: string): Promise<void>;
235
+ receiptRuleSetExists(ruleSetName: string): Promise<boolean>;
236
+ getActiveReceiptRuleSet(): Promise<{
237
+ Metadata?: { Name?: string, CreatedTimestamp?: string }
238
+ Rules?: Array<{
239
+ Name?: string
240
+ Enabled?: boolean
241
+ Recipients?: string[]
242
+ Actions?: Array<{
243
+ S3Action?: { BucketName?: string, ObjectKeyPrefix?: string }
244
+ LambdaAction?: { FunctionArn?: string, InvocationType?: string }
245
+ SNSAction?: { TopicArn?: string }
246
+ }>
247
+ }>
248
+ } | null>;
249
+ updateReceiptRule(params: {
250
+ RuleSetName: string
251
+ Rule: {
252
+ Name: string
253
+ Enabled?: boolean
254
+ TlsPolicy?: 'Require' | 'Optional'
255
+ Recipients?: string[]
256
+ ScanEnabled?: boolean
257
+ Actions: Array<{
258
+ S3Action?: {
259
+ BucketName: string
260
+ ObjectKeyPrefix?: string
261
+ KmsKeyArn?: string
262
+ }
263
+ LambdaAction?: {
264
+ FunctionArn: string
265
+ InvocationType?: 'Event' | 'RequestResponse'
266
+ }
267
+ SNSAction?: {
268
+ TopicArn: string
269
+ Encoding?: 'UTF-8' | 'Base64'
270
+ }
271
+ StopAction?: {
272
+ Scope: 'RuleSet'
273
+ TopicArn?: string
274
+ }
275
+ }>
276
+ }
277
+ }): Promise<void>;
278
+ sendRawEmail(params: {
279
+ source: string
280
+ destinations: string[]
281
+ rawMessage: string
282
+ }): Promise<{ MessageId?: string }>;
283
+ }
@@ -0,0 +1,27 @@
1
+ import * as tls from 'node:tls';
2
+ /**
3
+ * Start an SMTP server with the given configuration
4
+ */
5
+ export declare function startSmtpServer(config: SmtpServerConfig): Promise<SmtpServer>;
6
+ export declare interface SmtpServerConfig {
7
+ port?: number
8
+ tlsPort?: number
9
+ host?: string
10
+ region?: string
11
+ domain: string
12
+ users: Record<string, { password: string; email: string }>
13
+ tls?: {
14
+ key: string
15
+ cert: string
16
+ }
17
+ sentBucket?: string
18
+ sentPrefix?: string
19
+ }
20
+ /**
21
+ * SMTP Server that relays emails through AWS SES
22
+ */
23
+ export declare class SmtpServer {
24
+ constructor(config: SmtpServerConfig);
25
+ start(): Promise<void>;
26
+ stop(): Promise<void>;
27
+ }
package/dist/index.d.ts CHANGED
@@ -1,3 +1,11 @@
1
1
  export type * from './types';
2
2
  export * from './cloud/index';
3
3
  export * from './helpers';
4
+ /*` export, to a `dist/imap/s3.js` that the build never
5
+ * writes. Reaching them by relative path instead is what those commands used to
6
+ * do, and it only ever worked inside this repository.
7
+ */
8
+ export * from './imap/client';
9
+ export * from './imap/s3';
10
+ export * from './imap/secrets-manager';
11
+ export * from './imap/smtp-server';
package/dist/index.js CHANGED
@@ -1,11 +1,95 @@
1
1
  // @bun
2
- import{config as D}from"@stacksjs/config";import{InfrastructureGenerator as F}from"@stacksjs/ts-cloud";class O{generator;cloudConfig;props;constructor(t,e){this.cloudConfig=t,this.props=e;let n=(e.appEnv==="local"?"development":e.appEnv)||"production";this.generator=new F({config:this.cloudConfig,environment:n})}generate(){return this.generator.generate().toJSON()}shouldDeployApi(){return D.cloud.api?.deploy??!1}}import{AWSClient as I,AWSCloudFormationClient as A,CloudWatchLogsClient as M,EC2Client as h,IAMClient as L,LambdaClient as j,Route53DomainsClient as B,S3Client as v,SSMClient as x}from"@stacksjs/ts-cloud";import{config as y}from"@stacksjs/config";import{err as o,handleError as p,ok as c}from"@stacksjs/error-handling";import{log as m}from"@stacksjs/logging";import{path as E}from"@stacksjs/path";import{slug as V}from"@stacksjs/strings";var U=y.app.env==="local"?"dev":y.app.env,b=`stacks-cloud-${U}`;async function P(t,e={}){let n=new I,a={Action:t,Version:"2016-11-15",...e};return await n.request({service:"ec2",region:"us-east-1",method:"POST",path:"/",queryParams:a})}async function G(t,e,n){return await new I().request({service:"logs",region:t,method:"POST",path:"/",headers:{"Content-Type":"application/x-amz-json-1.1","X-Amz-Target":`Logs_20140328.${e}`},body:JSON.stringify(n)})}async function K(t,e,n){return await new I().request({service:"elasticfilesystem",region:"us-east-1",method:e,path:n})}async function z(t){let e=new h("us-east-1"),{SecurityGroups:n}=await e.describeSecurityGroups({Filters:[{Name:"group-name",Values:[t]}]});if(!n)return o(`Security group ${t} not found`);if(n[0])return c(n[0].GroupId);return o(`Security group ${t} not found`)}function se(t,e){let n=new B,a=e.contactType.toUpperCase()||"PERSON",r=(s)=>s.toString().includes("+")?s.toString():`+${s.toString()}`;try{return c(n.registerDomain({DomainName:t,DurationInYears:e.years||1,AutoRenew:e.autoRenew||!0,AdminContact:{FirstName:e.adminFirstName,LastName:e.adminLastName,ContactType:a,OrganizationName:e.adminOrganization,AddressLine1:e.adminAddressLine1,AddressLine2:e.adminAddressLine2,City:e.adminCity,State:e.adminState,CountryCode:e.adminCountry,ZipCode:e.adminZip.toString(),PhoneNumber:r(e.adminPhone),Email:e.adminEmail},RegistrantContact:{FirstName:e.registrantFirstName,LastName:e.registrantLastName,ContactType:a,OrganizationName:e.registrantOrganization,AddressLine1:e.registrantAddressLine1,AddressLine2:e.registrantAddressLine2,City:e.registrantCity,State:e.registrantState,CountryCode:e.registrantCountry,ZipCode:e.registrantZip.toString(),PhoneNumber:r(e.registrantPhone),Email:e.registrantEmail},TechContact:{FirstName:e.techFirstName,LastName:e.techLastName,ContactType:a,OrganizationName:e.techOrganization,AddressLine1:e.techAddressLine1,AddressLine2:e.techAddressLine2,City:e.techCity,State:e.techState,CountryCode:e.techCountry,ZipCode:e.techZip.toString(),PhoneNumber:r(e.techPhone),Email:e.techEmail},PrivacyProtectAdminContact:e.privacyAdmin||e.privacy||!0,PrivacyProtectRegistrantContact:e.privacyRegistrant||e.privacy||!0,PrivacyProtectTechContact:e.privacyTech||e.privacy||!0}))}catch(s){return o(s)}}async function R(t){if(!t)t=`${b}/JumpBox`;let n=await new h("us-east-1").describeInstances({Filters:[{Name:"tag:Name",Values:[t]}]});if(n.Reservations?.[0]?.Instances?.[0])return n.Reservations[0].Instances[0].InstanceId;return}async function J(t,e){if(!e)e=b;if(!t)return o(`Instance ${t} not found`);return await new h("us-east-1").terminateInstances([t]),c(`Instance ${t} is being terminated`)}async function ae(t){if(!t)t=b;let e=await R();if(!e)return o("Jump-box not found");return m.info(`Deleting jump-box ${e}...`),await J(e,t)}async function ie(){let t=new L("us-east-1"),e=await t.listUsers(),n=V(y.team.name),a=e.Users?.filter((s)=>{let i=s.UserName?.toLowerCase();return i!=="stacks"&&i!==n.toLowerCase()&&i?.includes(n.toLowerCase())})||[];if(!a||a.length===0)return c(`No Stacks IAM users found for team ${n}`);let r=a.map(async(s)=>{let i=s.UserName||"";m.info(`Deleting IAM user: ${i}`);let u=await t.listAttachedUserPolicies({UserName:i});await Promise.all(u.AttachedPolicies?.map((g)=>{let w=g;return t.detachUserPolicy({UserName:i,PolicyArn:w.PolicyArn||""})})||[]);let l=await t.listAccessKeys({UserName:i});return await Promise.all(l.AccessKeyMetadata?.map((g)=>{let w=g;return t.deleteAccessKey({UserName:i,AccessKeyId:w.AccessKeyId||""})})||[]),t.deleteUser({UserName:i})});try{await Promise.all(r)}catch(s){return console.error(s),o(p("Error deleting Stacks IAM users").message)}return c(`Stacks IAM users deleted for team ${n}`)}async function oe(){try{let t=new v("us-east-1"),n=(await t.listBuckets()).Buckets?.filter((r)=>r.Name?.includes("stacks"));if(!n)return o("No stacks buckets found");let a=n.map(async(r)=>{let s=r.Name||"";m.info(`Deleting bucket ${s}...`);let f,i=!0;while(i){let u=await t.listObjects({bucket:s,continuationToken:f});if(u.objects&&u.objects.length>0)m.info(`Deleting ${u.objects.length} objects from bucket ${s}...`),await Promise.all(u.objects.map((l)=>{let g=l;return t.deleteObject(s,g.Key||"")})).catch((l)=>{throw m.error(`Failed to delete objects from bucket ${s}:`,l),l});i=!!u.nextContinuationToken,f=u.nextContinuationToken}m.info(`Finished deleting objects from bucket ${s}`),m.info(`Deleting bucket ${s} versions...`);try{let u,l,g=!0;while(g){let d=await t.listObjectVersions({bucket:s,keyMarker:u,versionIdMarker:l});if(d.versions&&d.versions.length>0)await Promise.all(d.versions.map((k)=>{let C=k;return t.deleteObject(s,C.Key||"")})).catch((k)=>p(k)),m.info(`Deleted ${d.versions.length} versions from bucket ${s}`);if(d.deleteMarkers&&d.deleteMarkers.length>0)await Promise.all(d.deleteMarkers.map((k)=>{let C=k;return t.deleteObject(s,C.Key||"")})).catch((k)=>p(k)),m.info(`Deleted ${d.deleteMarkers.length} delete markers from bucket ${s}`);g=!!d.nextKeyMarker,u=d.nextKeyMarker,l=d.nextVersionIdMarker}m.info(`Finished deleting all versions from bucket ${s}`);let w=await t.listMultipartUploads(s);if(w&&w.length>0)m.info("Aborting bucket multipart uploads..."),await Promise.all(w.map((d)=>{let k=d;return t.abortMultipartUpload(s,k.Key||"",k.UploadId||"")})).catch((d)=>p(d)),m.info(`Finished aborting multipart uploads from bucket ${s}`);await t.deleteBucket(s).catch((d)=>p(d)),m.info(`Bucket ${s} deleted`)}catch(u){m.info(`Error listing bucket ${s} versions`,u)}});return await Promise.all(a).catch((r)=>(console.error(r),o(p("Error deleting stacks buckets")))),c("Stacks buckets deleted")}catch(t){return o(p("Error deleting stacks buckets",t))}}async function ce(){let t=new j("us-east-1"),n=(await t.listFunctions()).Functions?.filter((r)=>r.FunctionName?.includes("stacks"))||[];if(!n||n.length===0)return c("No stacks functions found");let a=n.map((r)=>{let s=r;return t.deleteFunction(s.FunctionName||"")});try{await Promise.all(a)}catch(r){let s=r;if(s.message.includes("it is a replicated function"))return m.info("Function is replicated, skipping..."),c("CloudFront is still deleting the some functions. Try again later.");return o(p("Error deleting stacks functions",s).message)}return c("Stacks functions deleted")}async function ue(){try{let t=await P("DescribeRegions"),n=t.regionInfo?.item??t.Regions??t.regionSet??[],a=[];if(Array.isArray(n))for(let r of n){let s=r.regionName??r.RegionName;if(s)a.push(s)}for(let r of a){let f=await new M(r).describeLogGroups();if(f?.logGroups)for(let i of f.logGroups){let u=y.app.name?.toLocaleLowerCase()||"stacks";if(i.logGroupName?.includes(u))await G(r,"DeleteLogGroup",{logGroupName:i.logGroupName})}}return c("Log groups deleted in all regions")}catch(t){return o(p("Error deleting log groups",t))}}async function de(){let t=new x("us-east-1"),e=await t.describeParameters();if(!e.Parameters)return c("No parameters found");let n=y.app.name?.toLocaleLowerCase()||"stacks",a=e.Parameters.filter((s)=>s.Name?.includes(n))||[];if(!a||a.length===0)return c("No stacks parameters found");let r=a.map((s)=>{let f=s;return t.deleteParameter({Name:f.Name||""})});try{await Promise.all(r)}catch(s){return o(p("Error deleting parameter store",s).message)}return c("Parameter store deleted")}async function me(){let t=new h("us-east-1"),e=y.app.name?`${y.app.name.toLowerCase()}-`:"stacks-";try{let{Vpcs:n}=await t.describeVpcs();if(!n||n.length===0)return c("No VPCs found");let a=n.filter((r)=>r.Tags?.some((i)=>i.Key==="Name"&&i.Value===e));if(a.length===0)return c(`No VPCs found matching the pattern: ${e}`);for(let r of a)if(r.VpcId)await P("DeleteVpc",{VpcId:r.VpcId}),m.info(`Deleted VPC: ${r.VpcId} (${e})`);return c(`Deleted ${a.length} VPCs matching the pattern: ${e}`)}catch(n){return o(p(`Error deleting VPCs: ${n}`))}}async function le(){try{return await Bun.$`rm -rf ${E.cloudPath("cdk.out/")} ${E.cloudPath("cdk.context.json")}`.text(),c("CDK remnants deleted")}catch(t){return o(p("Error deleting CDK remnants",t))}}async function ge(){let t=new h("us-east-1"),e=y.app.name?`${y.app.name.toLowerCase()}-`:"stacks-";try{let{Subnets:n}=await t.describeSubnets();if(!n||n.length===0)return c("No subnets found");let a=n.filter((r)=>r.Tags?.some((i)=>i.Key==="Name"&&i.Value?.startsWith(e)));if(a.length===0)return c(`No subnets found matching the pattern: ${e}`);for(let r of a)if(r.SubnetId){let i=(await P("DescribeNetworkInterfaces",{"Filter.1.Name":"subnet-id","Filter.1.Value.1":r.SubnetId})).networkInterfaceSet?.item??[];for(let u of Array.isArray(i)?i:[]){let l=u.networkInterfaceId;if(l){let g=u.attachment;if(g?.instanceId)await t.terminateInstances([g.instanceId]),m.info(`Terminated instance: ${g.instanceId}`),await new Promise((w)=>setTimeout(w,60000));if(g?.attachmentId)await P("DetachNetworkInterface",{AttachmentId:g.attachmentId,Force:"true"}),m.info(`Detached network interface: ${l}`),await new Promise((w)=>setTimeout(w,1e4));await P("DeleteNetworkInterface",{NetworkInterfaceId:l}),m.info(`Deleted network interface: ${l}`)}}await P("DeleteSubnet",{SubnetId:r.SubnetId}),m.info(`Deleted subnet: ${r.SubnetId} (${r.Tags?.find((u)=>u.Key==="Name")?.Value})`)}return c(`Deleted ${a.length} subnets matching the pattern: ${e}`)}catch(n){return o(p(`Error deleting subnets: ${n}`))}}async function fe(){let t=new v("us-east-1");try{let e=await t.listBuckets();return c(e.Buckets?.some((n)=>n.Name?.includes(y.app.name?.toLocaleLowerCase()||"stacks"))||!1)}catch(e){return console.error(e),o(p("Error checking if the app has been deployed"))}}async function _(){let a=(await new L("us-east-1").listInstanceProfiles()).InstanceProfiles?.find((r)=>r.InstanceProfileName?.includes("JumpBox"))?.InstanceProfileName;if(!a)return o("Jump-box IAM instance profile not found");return c(a)}async function pe(t){if(!t)t=b;if(await R())return o("The jump-box you are trying to add already exists. Please remove it & wait until it finished terminating.");let e=new h("us-east-1"),n=await Z();if(n.isErr)return o(n.error);if(!n.value)return o("Security group not found when adding jump-box");let a=await z(n.value);if(a.isErr)return o(a.error);let r=a.value;if(!r)return o("Security group not found when adding jump-box");let f=(await K("DescribeFileSystems","GET","/2015-02-01/file-systems")).FileSystems??[],i=`stacks-${y.app.env}-efs`,u=f.find((T)=>T.Name===i),l=u?.FileSystemId;if(!u||!l)return o(`EFS file system ${i} not found`);let g=`
2
+ import{config as re}from"@stacksjs/config";import{InfrastructureGenerator as ne}from"@stacksjs/ts-cloud";class se{generator;cloudConfig;props;constructor(e,t){this.cloudConfig=e,this.props=t;let r=(t.appEnv==="local"?"development":t.appEnv)||"production";this.generator=new ne({config:this.cloudConfig,environment:r})}generate(){return this.generator.generate().toJSON()}shouldDeployApi(){return re.cloud.api?.deploy??!1}}import{AWSClient as V,AWSCloudFormationClient as J,CloudWatchLogsClient as ie,EC2Client as L,IAMClient as X,LambdaClient as ae,Route53DomainsClient as oe,S3Client as Q,SSMClient as Y}from"@stacksjs/ts-cloud";import{config as x}from"@stacksjs/config";import{err as y,handleError as k,ok as p}from"@stacksjs/error-handling";import{log as R}from"@stacksjs/logging";import{path as G}from"@stacksjs/path";import{slug as ce}from"@stacksjs/strings";var ue=x.app.env==="local"?"dev":x.app.env,F=`stacks-cloud-${ue}`;async function B(e,t={}){let r=new V,n={Action:e,Version:"2016-11-15",...t};return await r.request({service:"ec2",region:"us-east-1",method:"POST",path:"/",queryParams:n})}async function le(e,t,r){return await new V().request({service:"logs",region:e,method:"POST",path:"/",headers:{"Content-Type":"application/x-amz-json-1.1","X-Amz-Target":`Logs_20140328.${t}`},body:JSON.stringify(r)})}async function de(e,t,r){return await new V().request({service:"elasticfilesystem",region:"us-east-1",method:t,path:r})}async function ge(e){let t=new L("us-east-1"),{SecurityGroups:r}=await t.describeSecurityGroups({Filters:[{Name:"group-name",Values:[e]}]});if(!r)return y(`Security group ${e} not found`);if(r[0])return p(r[0].GroupId);return y(`Security group ${e} not found`)}function Ne(e,t){let r=new oe,n=t.contactType.toUpperCase()||"PERSON",s=(i)=>i.toString().includes("+")?i.toString():`+${i.toString()}`;try{return p(r.registerDomain({DomainName:e,DurationInYears:t.years||1,AutoRenew:t.autoRenew||!0,AdminContact:{FirstName:t.adminFirstName,LastName:t.adminLastName,ContactType:n,OrganizationName:t.adminOrganization,AddressLine1:t.adminAddressLine1,AddressLine2:t.adminAddressLine2,City:t.adminCity,State:t.adminState,CountryCode:t.adminCountry,ZipCode:t.adminZip.toString(),PhoneNumber:s(t.adminPhone),Email:t.adminEmail},RegistrantContact:{FirstName:t.registrantFirstName,LastName:t.registrantLastName,ContactType:n,OrganizationName:t.registrantOrganization,AddressLine1:t.registrantAddressLine1,AddressLine2:t.registrantAddressLine2,City:t.registrantCity,State:t.registrantState,CountryCode:t.registrantCountry,ZipCode:t.registrantZip.toString(),PhoneNumber:s(t.registrantPhone),Email:t.registrantEmail},TechContact:{FirstName:t.techFirstName,LastName:t.techLastName,ContactType:n,OrganizationName:t.techOrganization,AddressLine1:t.techAddressLine1,AddressLine2:t.techAddressLine2,City:t.techCity,State:t.techState,CountryCode:t.techCountry,ZipCode:t.techZip.toString(),PhoneNumber:s(t.techPhone),Email:t.techEmail},PrivacyProtectAdminContact:t.privacyAdmin||t.privacy||!0,PrivacyProtectRegistrantContact:t.privacyRegistrant||t.privacy||!0,PrivacyProtectTechContact:t.privacyTech||t.privacy||!0}))}catch(i){return y(i)}}async function H(e){if(!e)e=`${F}/JumpBox`;let r=await new L("us-east-1").describeInstances({Filters:[{Name:"tag:Name",Values:[e]}]});if(r.Reservations?.[0]?.Instances?.[0])return r.Reservations[0].Instances[0].InstanceId;return}async function me(e,t){if(!t)t=F;if(!e)return y(`Instance ${e} not found`);return await new L("us-east-1").terminateInstances([e]),p(`Instance ${e} is being terminated`)}async function $e(e){if(!e)e=F;let t=await H();if(!t)return y("Jump-box not found");return R.info(`Deleting jump-box ${t}...`),await me(t,e)}async function xe(){let e=new X("us-east-1"),t=await e.listUsers(),r=ce(x.team.name),n=t.Users?.filter((i)=>{let o=i.UserName?.toLowerCase();return o!=="stacks"&&o!==r.toLowerCase()&&o?.includes(r.toLowerCase())})||[];if(!n||n.length===0)return p(`No Stacks IAM users found for team ${r}`);let s=n.map(async(i)=>{let o=i.UserName||"";R.info(`Deleting IAM user: ${o}`);let c=await e.listAttachedUserPolicies({UserName:o});await Promise.all(c.AttachedPolicies?.map((m)=>{let l=m;return e.detachUserPolicy({UserName:o,PolicyArn:l.PolicyArn||""})})||[]);let d=await e.listAccessKeys({UserName:o});return await Promise.all(d.AccessKeyMetadata?.map((m)=>{let l=m;return e.deleteAccessKey({UserName:o,AccessKeyId:l.AccessKeyId||""})})||[]),e.deleteUser({UserName:o})});try{await Promise.all(s)}catch(i){return console.error(i),y(k("Error deleting Stacks IAM users").message)}return p(`Stacks IAM users deleted for team ${r}`)}async function Ie(){try{let e=new Q("us-east-1"),r=(await e.listBuckets()).Buckets?.filter((s)=>s.Name?.includes("stacks"));if(!r)return y("No stacks buckets found");let n=r.map(async(s)=>{let i=s.Name||"";R.info(`Deleting bucket ${i}...`);let a,o=!0;while(o){let c=await e.listObjects({bucket:i,continuationToken:a});if(c.objects&&c.objects.length>0)R.info(`Deleting ${c.objects.length} objects from bucket ${i}...`),await Promise.all(c.objects.map((d)=>{let m=d;return e.deleteObject(i,m.Key||"")})).catch((d)=>{throw R.error(`Failed to delete objects from bucket ${i}:`,d),d});o=!!c.nextContinuationToken,a=c.nextContinuationToken}R.info(`Finished deleting objects from bucket ${i}`),R.info(`Deleting bucket ${i} versions...`);try{let c,d,m=!0;while(m){let u=await e.listObjectVersions({bucket:i,keyMarker:c,versionIdMarker:d});if(u.versions&&u.versions.length>0)await Promise.all(u.versions.map((h)=>{let S=h;return e.deleteObject(i,S.Key||"")})).catch((h)=>k(h)),R.info(`Deleted ${u.versions.length} versions from bucket ${i}`);if(u.deleteMarkers&&u.deleteMarkers.length>0)await Promise.all(u.deleteMarkers.map((h)=>{let S=h;return e.deleteObject(i,S.Key||"")})).catch((h)=>k(h)),R.info(`Deleted ${u.deleteMarkers.length} delete markers from bucket ${i}`);m=!!u.nextKeyMarker,c=u.nextKeyMarker,d=u.nextVersionIdMarker}R.info(`Finished deleting all versions from bucket ${i}`);let l=await e.listMultipartUploads(i);if(l&&l.length>0)R.info("Aborting bucket multipart uploads..."),await Promise.all(l.map((u)=>{let h=u;return e.abortMultipartUpload(i,h.Key||"",h.UploadId||"")})).catch((u)=>k(u)),R.info(`Finished aborting multipart uploads from bucket ${i}`);await e.deleteBucket(i).catch((u)=>k(u)),R.info(`Bucket ${i} deleted`)}catch(c){R.info(`Error listing bucket ${i} versions`,c)}});return await Promise.all(n).catch((s)=>(console.error(s),y(k("Error deleting stacks buckets")))),p("Stacks buckets deleted")}catch(e){return y(k("Error deleting stacks buckets",e))}}async function De(){let e=new ae("us-east-1"),r=(await e.listFunctions()).Functions?.filter((s)=>s.FunctionName?.includes("stacks"))||[];if(!r||r.length===0)return p("No stacks functions found");let n=r.map((s)=>{let i=s;return e.deleteFunction(i.FunctionName||"")});try{await Promise.all(n)}catch(s){let i=s;if(i.message.includes("it is a replicated function"))return R.info("Function is replicated, skipping..."),p("CloudFront is still deleting the some functions. Try again later.");return y(k("Error deleting stacks functions",i).message)}return p("Stacks functions deleted")}async function Oe(){try{let e=await B("DescribeRegions"),r=e.regionInfo?.item??e.Regions??e.regionSet??[],n=[];if(Array.isArray(r))for(let s of r){let i=s.regionName??s.RegionName;if(i)n.push(i)}for(let s of n){let a=await new ie(s).describeLogGroups();if(a?.logGroups)for(let o of a.logGroups){let c=x.app.name?.toLocaleLowerCase()||"stacks";if(o.logGroupName?.includes(c))await le(s,"DeleteLogGroup",{logGroupName:o.logGroupName})}}return p("Log groups deleted in all regions")}catch(e){return y(k("Error deleting log groups",e))}}async function qe(){let e=new Y("us-east-1"),t=await e.describeParameters();if(!t.Parameters)return p("No parameters found");let r=x.app.name?.toLocaleLowerCase()||"stacks",n=t.Parameters.filter((i)=>i.Name?.includes(r))||[];if(!n||n.length===0)return p("No stacks parameters found");let s=n.map((i)=>{let a=i;return e.deleteParameter({Name:a.Name||""})});try{await Promise.all(s)}catch(i){return y(k("Error deleting parameter store",i).message)}return p("Parameter store deleted")}async function Le(){let e=new L("us-east-1"),t=x.app.name?`${x.app.name.toLowerCase()}-`:"stacks-";try{let{Vpcs:r}=await e.describeVpcs();if(!r||r.length===0)return p("No VPCs found");let n=r.filter((s)=>s.Tags?.some((o)=>o.Key==="Name"&&o.Value===t));if(n.length===0)return p(`No VPCs found matching the pattern: ${t}`);for(let s of n)if(s.VpcId)await B("DeleteVpc",{VpcId:s.VpcId}),R.info(`Deleted VPC: ${s.VpcId} (${t})`);return p(`Deleted ${n.length} VPCs matching the pattern: ${t}`)}catch(r){return y(k(`Error deleting VPCs: ${r}`))}}async function Ke(){try{return await Bun.$`rm -rf ${G.cloudPath("cdk.out/")} ${G.cloudPath("cdk.context.json")}`.text(),p("CDK remnants deleted")}catch(e){return y(k("Error deleting CDK remnants",e))}}async function Be(){let e=new L("us-east-1"),t=x.app.name?`${x.app.name.toLowerCase()}-`:"stacks-";try{let{Subnets:r}=await e.describeSubnets();if(!r||r.length===0)return p("No subnets found");let n=r.filter((s)=>s.Tags?.some((o)=>o.Key==="Name"&&o.Value?.startsWith(t)));if(n.length===0)return p(`No subnets found matching the pattern: ${t}`);for(let s of n)if(s.SubnetId){let o=(await B("DescribeNetworkInterfaces",{"Filter.1.Name":"subnet-id","Filter.1.Value.1":s.SubnetId})).networkInterfaceSet?.item??[];for(let c of Array.isArray(o)?o:[]){let d=c.networkInterfaceId;if(d){let m=c.attachment;if(m?.instanceId)await e.terminateInstances([m.instanceId]),R.info(`Terminated instance: ${m.instanceId}`),await new Promise((l)=>setTimeout(l,60000));if(m?.attachmentId)await B("DetachNetworkInterface",{AttachmentId:m.attachmentId,Force:"true"}),R.info(`Detached network interface: ${d}`),await new Promise((l)=>setTimeout(l,1e4));await B("DeleteNetworkInterface",{NetworkInterfaceId:d}),R.info(`Deleted network interface: ${d}`)}}await B("DeleteSubnet",{SubnetId:s.SubnetId}),R.info(`Deleted subnet: ${s.SubnetId} (${s.Tags?.find((c)=>c.Key==="Name")?.Value})`)}return p(`Deleted ${n.length} subnets matching the pattern: ${t}`)}catch(r){return y(k(`Error deleting subnets: ${r}`))}}async function Fe(){let e=new Q("us-east-1");try{let t=await e.listBuckets();return p(t.Buckets?.some((r)=>r.Name?.includes(x.app.name?.toLocaleLowerCase()||"stacks"))||!1)}catch(t){return console.error(t),y(k("Error checking if the app has been deployed"))}}async function he(){let n=(await new X("us-east-1").listInstanceProfiles()).InstanceProfiles?.find((s)=>s.InstanceProfileName?.includes("JumpBox"))?.InstanceProfileName;if(!n)return y("Jump-box IAM instance profile not found");return p(n)}async function je(e){if(!e)e=F;if(await H())return y("The jump-box you are trying to add already exists. Please remove it & wait until it finished terminating.");let t=new L("us-east-1"),r=await ye();if(r.isErr)return y(r.error);if(!r.value)return y("Security group not found when adding jump-box");let n=await ge(r.value);if(n.isErr)return y(n.error);let s=n.value;if(!s)return y("Security group not found when adding jump-box");let a=(await de("DescribeFileSystems","GET","/2015-02-01/file-systems")).FileSystems??[],o=`stacks-${x.app.env}-efs`,c=a.find((w)=>w.Name===o),d=c?.FileSystemId;if(!c||!d)return y(`EFS file system ${o} not found`);let m=`
3
3
  #!/bin/bash
4
4
  yum update -y
5
5
  yum install -y amazon-efs-utils
6
6
  yum install -y git
7
7
  yum install -y https://s3.us-east-1.amazonaws.com/amazon-ssm-us-east-1/latest/linux_amd64/amazon-ssm-agent.rpm
8
8
  mkdir /mnt/efs
9
- mount -t efs ${l}:/ /mnt/efs
9
+ mount -t efs ${d}:/ /mnt/efs
10
10
  git clone https://github.com/stacksjs/stacks.git /mnt/efs
11
- `,w=btoa(g),d=await _();if(d.isErr)return o(d.error);let k=d.value;if(!k)return o("Jump-box IAM instance profile not found");let S=(await P("RunInstances",{ImageId:"ami-03a6eaae9938c858c",InstanceType:"t2.micro",MaxCount:"1",MinCount:"1","SecurityGroupId.1":r,SubnetId:"subnet-004c5f196358b00f0","TagSpecification.1.ResourceType":"instance","TagSpecification.1.Tag.1.Key":"Name","TagSpecification.1.Tag.1.Value":`${b}-jump-box`,UserData:w,"IamInstanceProfile.Name":k})).instancesSet?.item??[],N=Array.isArray(S)?S[0]:void 0;return N?c(`Jump-box created with id ${N.instanceId}`):o("Jump-box creation failed")}async function Z(){let t=await R();if(!t)return o("Jump-box not found");let n=await new h("us-east-1").describeInstances({InstanceIds:[t]});if(n.Reservations?.[0]?.Instances?.[0]){let r=n.Reservations[0].Instances[0].SecurityGroups;if(r?.[0])return c(r[0].GroupName)}return o("Security group not found")}async function we(t){let n=await new h("us-east-1").describeInstances({InstanceIds:[t]});if(n.Reservations?.[0]?.Instances?.[0]){let r=n.Reservations[0].Instances[0].SecurityGroups;if(r?.[0])return r[0].GroupId}return}async function ke(){let t=b;return!(await new A("us-east-1").listStacks(["CREATE_COMPLETE","UPDATE_COMPLETE"])).StackSummaries?.some((r)=>r.StackName===t)}async function ye(){return!(await new A("us-east-1").listStacks(["CREATE_FAILED","UPDATE_FAILED","ROLLBACK_COMPLETE","UPDATE_ROLLBACK_COMPLETE"])).StackSummaries?.some((a)=>a.StackName===b)}async function he(){let e=new x("us-east-1");try{let n=await e.getParameter({Name:"/stacks/timestamp"}),a=n.Parameter?n.Parameter.Value:void 0;if(!a)throw Error("Timestamp parameter not found");return a}catch(n){let a=new Date().getTime().toString();return m.debug(`Creating timestamp parameter /stacks/timestamp with value ${a}`,n),await e.putParameter({Name:"/stacks/timestamp",Value:a,Type:"String"}),a}}async function Pe(){return""}export{O as Cloud,pe as addJumpBox,le as deleteCdkRemnants,J as deleteEc2Instance,ie as deleteIamUsers,ae as deleteJumpBox,ue as deleteLogGroups,de as deleteParameterStore,oe as deleteStacksBuckets,ce as deleteStacksFunctions,ge as deleteSubnets,me as deleteVpcs,Pe as getCloudFrontDistributionId,R as getJumpBoxInstanceId,_ as getJumpBoxInstanceProfileName,Z as getJumpBoxSecurityGroupName,he as getOrCreateTimestamp,we as getSecurityGroupFromInstanceId,z as getSecurityGroupId,fe as hasBeenDeployed,ye as isFailedState,ke as isFirstDeployment,se as purchaseDomain};
11
+ `,l=btoa(m),u=await he();if(u.isErr)return y(u.error);let h=u.value;if(!h)return y("Jump-box IAM instance profile not found");let A=(await B("RunInstances",{ImageId:"ami-03a6eaae9938c858c",InstanceType:"t2.micro",MaxCount:"1",MinCount:"1","SecurityGroupId.1":s,SubnetId:"subnet-004c5f196358b00f0","TagSpecification.1.ResourceType":"instance","TagSpecification.1.Tag.1.Key":"Name","TagSpecification.1.Tag.1.Value":`${F}-jump-box`,UserData:l,"IamInstanceProfile.Name":h})).instancesSet?.item??[],T=Array.isArray(A)?A[0]:void 0;return T?p(`Jump-box created with id ${T.instanceId}`):y("Jump-box creation failed")}async function ye(){let e=await H();if(!e)return y("Jump-box not found");let r=await new L("us-east-1").describeInstances({InstanceIds:[e]});if(r.Reservations?.[0]?.Instances?.[0]){let s=r.Reservations[0].Instances[0].SecurityGroups;if(s?.[0])return p(s[0].GroupName)}return y("Security group not found")}async function Me(e){let r=await new L("us-east-1").describeInstances({InstanceIds:[e]});if(r.Reservations?.[0]?.Instances?.[0]){let s=r.Reservations[0].Instances[0].SecurityGroups;if(s?.[0])return s[0].GroupId}return}async function Ue(){let e=F;return!(await new J("us-east-1").listStacks(["CREATE_COMPLETE","UPDATE_COMPLETE"])).StackSummaries?.some((s)=>s.StackName===e)}async function ze(){return!(await new J("us-east-1").listStacks(["CREATE_FAILED","UPDATE_FAILED","ROLLBACK_COMPLETE","UPDATE_ROLLBACK_COMPLETE"])).StackSummaries?.some((n)=>n.StackName===F)}async function Ve(){let t=new Y("us-east-1");try{let r=await t.getParameter({Name:"/stacks/timestamp"}),n=r.Parameter?r.Parameter.Value:void 0;if(!n)throw Error("Timestamp parameter not found");return n}catch(r){let n=new Date().getTime().toString();return R.debug(`Creating timestamp parameter /stacks/timestamp with value ${n}`,r),await t.putParameter({Name:"/stacks/timestamp",Value:n,Type:"String"}),n}}async function He(){return""}import*as K from"crypto";import{XMLParser as pe}from"@stacksjs/ts-xml";class j{credentials;config;cache;xmlParser;constructor(e,t){this.credentials=e||this.loadCredentials(),this.config={maxRetries:3,retryDelay:1000,cacheEnabled:!0,defaultCacheTTL:60000,...t},this.cache=new Map,this.xmlParser=new pe({ignoreAttributes:!1,attributeNamePrefix:"@_",textNodeName:"#text",parseAttributeValue:!0,trimValues:!0})}loadCredentials(){let e=process.env.AWS_ACCESS_KEY_ID,t=process.env.AWS_SECRET_ACCESS_KEY,r=process.env.AWS_SESSION_TOKEN;if(e&&t)return{accessKeyId:e,secretAccessKey:t,sessionToken:r};return{accessKeyId:"",secretAccessKey:""}}ec2CredentialsCache;async getCredentials(){let e=process.env.AWS_ACCESS_KEY_ID,t=process.env.AWS_SECRET_ACCESS_KEY;if(e&&t)return{accessKeyId:e,secretAccessKey:t,sessionToken:process.env.AWS_SESSION_TOKEN};if(this.ec2CredentialsCache){let r=Date.now();if(this.ec2CredentialsCache.expiration>r+300000)return this.ec2CredentialsCache.credentials}try{let n=await(await fetch("http://169.254.169.254/latest/api/token",{method:"PUT",headers:{"X-aws-ec2-metadata-token-ttl-seconds":"21600"}})).text(),i=await(await fetch("http://169.254.169.254/latest/meta-data/iam/security-credentials/",{headers:{"X-aws-ec2-metadata-token":n}})).text(),o=await(await fetch(`http://169.254.169.254/latest/meta-data/iam/security-credentials/${i}`,{headers:{"X-aws-ec2-metadata-token":n}})).json(),c={accessKeyId:o.AccessKeyId,secretAccessKey:o.SecretAccessKey,sessionToken:o.Token};return this.ec2CredentialsCache={credentials:c,expiration:new Date(o.Expiration).getTime()},c}catch(r){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(e){if(e.method==="GET"&&this.config.cacheEnabled&&e.cacheKey){let n=this.getFromCache(e.cacheKey);if(n!==null)return n}let t=e.retries??this.config.maxRetries??3,r=null;for(let n=0;n<=t;n++)try{let s=await this.makeRequest(e);if(e.method==="GET"&&this.config.cacheEnabled&&e.cacheKey)this.setInCache(e.cacheKey,s,e.cacheTTL??this.config.defaultCacheTTL??60000);return s}catch(s){if(r=s,!this.shouldRetry(s))throw s;if(n===t)throw s;let a=this.calculateRetryDelay(n);await this.sleep(a)}throw r||Error("Request failed after retries")}async makeRequest(e){let t=e.credentials||await this.getCredentials();if(!t||!t.accessKeyId||!t.secretAccessKey)throw Error("AWS credentials not provided");let r=this.buildUrl(e),n=this.signRequest(e,t),s=await fetch(r,{method:e.method,headers:n,body:e.body}),i=await s.text();if(!s.ok)throw this.parseError(i,s.status,s.headers);if(!i||i.trim()===""){if(e.returnHeaders)return{body:null,headers:this.headersToObject(s.headers)};return null}if(e.rawResponse){if(e.returnHeaders)return{body:i,headers:this.headersToObject(s.headers)};return i}let a;if(i.startsWith("<"))a=this.parseXmlResponse(i);else try{a=JSON.parse(i)}catch{a=i}if(e.returnHeaders)return{body:a,headers:this.headersToObject(s.headers)};return a}headersToObject(e){let t={};return e.forEach((r,n)=>{t[n]=r}),t}buildUrl(e){let{service:t,region:r,path:n,queryParams:s}=e,i;if(t==="s3")i=`s3.${r}.amazonaws.com`;else if(t==="cloudfront")i="cloudfront.amazonaws.com";else if(t==="iam")i="iam.amazonaws.com";else if(t==="route53")i="route53.amazonaws.com";else if(t==="route53domains")i="route53domains.us-east-1.amazonaws.com";else if(t==="ecr")i=`api.ecr.${r}.amazonaws.com`;else if(t==="ses")i=`email.${r}.amazonaws.com`;else i=`${t}.${r}.amazonaws.com`;let a=`https://${i}${n}`;if(s&&Object.keys(s).length>0){let o=new URLSearchParams(s).toString();a+=`?${o}`}return a}signRequest(e,t){let{service:r,region:n,method:s,path:i,queryParams:a,body:o}=e,c=new Date,d=this.getAmzDate(c),m=this.getDateStamp(c),l;if(r==="s3")l=`s3.${n}.amazonaws.com`;else if(r==="cloudfront")l="cloudfront.amazonaws.com";else if(r==="iam")l="iam.amazonaws.com";else if(r==="route53")l="route53.amazonaws.com";else if(r==="route53domains")l="route53domains.us-east-1.amazonaws.com";else if(r==="ecr")l=`api.ecr.${n}.amazonaws.com`;else if(r==="ses")l=`email.${n}.amazonaws.com`;else l=`${r}.${n}.amazonaws.com`;let u={host:l,"x-amz-date":d,...e.headers||{}};if(t.sessionToken)u["x-amz-security-token"]=t.sessionToken;if(o){if(!Object.keys(u).some((b)=>b.toLowerCase()==="content-type"))u["content-type"]="application/x-www-form-urlencoded";u["content-length"]=Buffer.byteLength(o).toString()}let h=this.sha256(o||"");u["x-amz-content-sha256"]=h;let S=i,P=a?new URLSearchParams(a).toString():"",A=Object.keys(u).sort((f,b)=>f.toLowerCase().localeCompare(b.toLowerCase())),T=A.map((f)=>`${f.toLowerCase()}:${u[f].trim()}
12
+ `).join(""),w=A.map((f)=>f.toLowerCase()).join(";"),v=[s,S,P,T,w,h].join(`
13
+ `),I="AWS4-HMAC-SHA256",N=r;if(r==="email")N="ses";if(r==="pinpoint")N="mobiletargeting";let D=`${m}/${n}/${N}/aws4_request`,O=[I,d,D,this.sha256(v)].join(`
14
+ `),q=this.getSignatureKey(t.secretAccessKey,m,n,N),E=this.hmac(q,O),C=`${I} Credential=${t.accessKeyId}/${D}, SignedHeaders=${w}, Signature=${E}`;return{...u,Authorization:C}}getAmzDate(e){return e.toISOString().replace(/[:-]|\.\d{3}/g,"")}getDateStamp(e){return e.toISOString().slice(0,10).replace(/-/g,"")}sha256(e){return K.createHash("sha256").update(e,"utf8").digest("hex")}hmac(e,t){return K.createHmac("sha256",e).update(t,"utf8").digest("hex")}getSignatureKey(e,t,r,n){let s=K.createHmac("sha256",`AWS4${e}`).update(t).digest(),i=K.createHmac("sha256",s).update(r).digest(),a=K.createHmac("sha256",i).update(n).digest();return K.createHmac("sha256",a).update("aws4_request").digest()}parseXmlResponse(e){try{let t=this.xmlParser.parse(e);if(t.ErrorResponse)throw this.createErrorFromXml(t.ErrorResponse.Error);let r=Object.keys(t);if(r.length===1)return t[r[0]];return t}catch(t){if(t.code||t.statusCode)throw t;return{}}}parseError(e,t,r){let n=Error();if(n.statusCode=t,n.requestId=r.get("x-amzn-requestid")||r.get("x-amz-request-id")||void 0,e.startsWith("<"))try{let s=this.xmlParser.parse(e);if(s.ErrorResponse?.Error){let i=s.ErrorResponse.Error;return n.code=i.Code,n.message=`AWS Error [${i.Code}]: ${i.Message||"Unknown error"}`,n.type=i.Type,n}if(s.Error)return n.code=s.Error.Code,n.message=`AWS Error [${s.Error.Code}]: ${s.Error.Message||"Unknown error"}`,n}catch{}try{let s=JSON.parse(e);if(s.__type||s.code)return n.code=s.__type||s.code,n.message=`AWS Error [${n.code}]: ${s.message||s.Message||"Unknown error"}`,n}catch{}return n.message=`AWS API Error (${t}): ${e}`,n}createErrorFromXml(e){let t=Error();return t.code=e.Code,t.message=`AWS Error [${e.Code}]: ${e.Message||"Unknown error"}`,t.type=e.Type,t}isRetryableError(e){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(e)}isRetryableStatusCode(e){return e>=500||e===429}shouldRetry(e){if(e.name==="FetchError"||e.name==="TypeError"||e.code==="ECONNRESET")return!0;if(e.code&&this.isRetryableError(e.code))return!0;if(e.statusCode&&this.isRetryableStatusCode(e.statusCode))return!0;if(e.statusCode&&e.statusCode>=400&&e.statusCode<500&&e.statusCode!==429)return!1;if(e.statusCode)return!1;return!0}calculateRetryDelay(e){let t=this.config.retryDelay??1000,r=30000,n=Math.min(t*2**e,30000),s=Math.random()*0.3*n;return n+s}sleep(e){return new Promise((t)=>setTimeout(t,e))}getFromCache(e){let t=this.cache.get(e);if(!t)return null;if(Date.now()>t.expires)return this.cache.delete(e),null;return t.data}setInCache(e,t,r){this.cache.set(e,{data:t,expires:Date.now()+r})}clearCache(){this.cache.clear()}clearExpiredCache(){let e=Date.now();for(let[t,r]of this.cache.entries())if(e>r.expires)this.cache.delete(t)}}function Ge(e){let t={};for(let[r,n]of Object.entries(e)){if(n===void 0||n===null)continue;if(Array.isArray(n))n.forEach((s,i)=>{t[`${r}.${i+1}`]=String(s)});else if(typeof n==="object")for(let[s,i]of Object.entries(n))t[`${r}.${s}`]=String(i);else t[r]=String(n)}return t}import*as g from"crypto";import{readdir as Se}from"fs/promises";import{join as fe}from"path";import{readFileSync as Z}from"fs";class W{client;region;constructor(e="us-east-1",t){this.region=e,this.client=new j}getCredentials(){let e=process.env.AWS_ACCESS_KEY_ID,t=process.env.AWS_SECRET_ACCESS_KEY,r=process.env.AWS_SESSION_TOKEN;if(!e||!t)throw Error("AWS credentials not found. Set AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment variables.");return{accessKeyId:e,secretAccessKey:t,sessionToken:r}}async listBuckets(){let e=await this.client.request({service:"s3",region:this.region,method:"GET",path:"/"}),t=[],r=e?.ListAllMyBucketsResult?.Buckets?.Bucket;if(r){let n=Array.isArray(r)?r:[r];for(let s of n)t.push({Name:s.Name,CreationDate:s.CreationDate})}return{Buckets:t}}async createBucket(e,t){let r={};if(t?.acl)r["x-amz-acl"]=t.acl;let n;if(this.region!=="us-east-1")n=`<?xml version="1.0" encoding="UTF-8"?>
15
+ <CreateBucketConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
16
+ <LocationConstraint>${this.region}</LocationConstraint>
17
+ </CreateBucketConfiguration>`,r["Content-Type"]="application/xml";await this.client.request({service:"s3",region:this.region,method:"PUT",path:`/${e}`,headers:r,body:n})}async deleteBucket(e){await this.client.request({service:"s3",region:this.region,method:"DELETE",path:`/${e}`})}async emptyAndDeleteBucket(e){let t=!0;while(t){let r=await this.listAllObjects({bucket:e});if(r.length===0){t=!1;break}let n=r.map((s)=>s.Key);for(let s=0;s<n.length;s+=1000){let i=n.slice(s,s+1000);await this.deleteObjects(e,i)}}await this.deleteBucket(e)}async listAllObjects(e){let t=[],r;do{let n={"list-type":"2","max-keys":"1000"};if(e.prefix)n.prefix=e.prefix;if(r)n["continuation-token"]=r;let s=await this.client.request({service:"s3",region:this.region,method:"GET",path:`/${e.bucket}`,queryParams:n}),i=s?.ListBucketResult?.Contents;if(i){let o=Array.isArray(i)?i:[i];for(let c of o)t.push({Key:c.Key,LastModified:c.LastModified||"",Size:Number.parseInt(c.Size||"0",10),ETag:c.ETag})}let a=s?.ListBucketResult?.IsTruncated;r=a==="true"||a===!0?s?.ListBucketResult?.NextContinuationToken:void 0}while(r);return t}async list(e){let t=await this.client.request({service:"s3",region:this.region,method:"GET",path:`/${e.bucket}`}),r=[],n=t?.ListBucketResult?.Contents;if(n){let s=Array.isArray(n)?n:[n];for(let i of s){if(e.prefix&&!i.Key?.startsWith(e.prefix))continue;if(r.push({Key:i.Key||"",LastModified:i.LastModified||"",Size:Number.parseInt(i.Size||"0",10),ETag:i.ETag}),e.maxKeys&&r.length>=e.maxKeys)break}}return r}async putObject(e){let t={};if(e.acl)t["x-amz-acl"]=e.acl;if(e.cacheControl)t["Cache-Control"]=e.cacheControl;if(e.contentType)t["Content-Type"]=e.contentType;if(e.metadata)for(let[n,s]of Object.entries(e.metadata))t[`x-amz-meta-${n}`]=s;let r=typeof e.body==="string"?e.body:Buffer.isBuffer(e.body)?e.body.toString("base64"):String(e.body);if(Buffer.isBuffer(e.body)){let{accessKeyId:n,secretAccessKey:s,sessionToken:i}=this.getCredentials(),a=`${e.bucket}.s3.${this.region}.amazonaws.com`,o=`https://${a}/${e.key}`,c=new Date,d=c.toISOString().replace(/[:-]|\.\d{3}/g,""),m=c.toISOString().slice(0,10).replace(/-/g,""),l=g.createHash("sha256").update(e.body).digest("hex"),u={host:a,"x-amz-date":d,"x-amz-content-sha256":l,...t};if(i)u["x-amz-security-token"]=i;let h=Object.keys(u).sort().map((C)=>`${C.toLowerCase()}:${u[C].trim()}
18
+ `).join(""),S=Object.keys(u).sort().map((C)=>C.toLowerCase()).join(";"),P=["PUT",`/${e.key}`,"",h,S,l].join(`
19
+ `),A="AWS4-HMAC-SHA256",T=`${m}/${this.region}/s3/aws4_request`,w=[A,d,T,g.createHash("sha256").update(P).digest("hex")].join(`
20
+ `),v=g.createHmac("sha256",`AWS4${s}`).update(m).digest(),I=g.createHmac("sha256",v).update(this.region).digest(),N=g.createHmac("sha256",I).update("s3").digest(),D=g.createHmac("sha256",N).update("aws4_request").digest(),O=g.createHmac("sha256",D).update(w).digest("hex"),q=`${A} Credential=${n}/${T}, SignedHeaders=${S}, Signature=${O}`,E=await fetch(o,{method:"PUT",headers:{...u,Authorization:q},body:typeof e.body==="string"?e.body:new Uint8Array(e.body)});if(!E.ok){let C=await E.text();throw Error(`S3 PUT failed: ${E.status} ${C}`)}return}await this.client.request({service:"s3",region:this.region,method:"PUT",path:`/${e.bucket}/${e.key}`,headers:t,body:r})}async getObject(e,t){return await this.client.request({service:"s3",region:this.region,method:"GET",path:`/${e}/${t}`,rawResponse:!0})}async copyObject(e){let t={"x-amz-copy-source":`/${e.sourceBucket}/${e.sourceKey}`};if(e.metadataDirective)t["x-amz-metadata-directive"]=e.metadataDirective;if(e.contentType)t["Content-Type"]=e.contentType;if(e.metadata)for(let[r,n]of Object.entries(e.metadata))t[`x-amz-meta-${r}`]=n;await this.client.request({service:"s3",region:this.region,method:"PUT",path:`/${e.destinationBucket}/${e.destinationKey}`,headers:t})}async deleteObject(e,t){await this.client.request({service:"s3",region:this.region,method:"DELETE",path:`/${e}/${t}`})}async deleteObjects(e,t){let r=`<?xml version="1.0" encoding="UTF-8"?>
21
+ <Delete>
22
+ ${t.map((n)=>`<Object><Key>${n}</Key></Object>`).join(`
23
+ `)}
24
+ </Delete>`;await this.client.request({service:"s3",region:this.region,method:"POST",path:`/${e}`,queryParams:{delete:""},body:r,headers:{"Content-Type":"application/xml"}})}async bucketExists(e){try{return await this.client.request({service:"s3",region:this.region,method:"HEAD",path:`/${e}`}),!0}catch{return!1}}async copy(e){let t=Z(e.source);await this.putObject({bucket:e.bucket,key:e.key,body:t,acl:e.acl,cacheControl:e.cacheControl,contentType:e.contentType,metadata:e.metadata})}async sync(e){let t=await this.listFilesRecursive(e.source);for(let r of t){if(e.exclude&&e.exclude.some((i)=>r.includes(i)))continue;if(e.include&&!e.include.some((i)=>r.includes(i)))continue;let n=r.substring(e.source.length+1),s=e.prefix?`${e.prefix}/${n}`:n;if(!e.dryRun){let i=Z(r);await this.putObject({bucket:e.bucket,key:s,body:i,acl:e.acl,cacheControl:e.cacheControl,contentType:e.contentType,metadata:e.metadata})}}}async delete(e,t){await this.deleteObject(e,t)}async deletePrefix(e,t){let n=(await this.list({bucket:e,prefix:t})).map((s)=>s.Key);if(n.length>0)await this.deleteObjects(e,n)}async getBucketSize(e,t){return(await this.list({bucket:e,prefix:t})).reduce((n,s)=>n+s.Size,0)}async listFilesRecursive(e){let t=[],r=await Se(e,{withFileTypes:!0});for(let n of r){let s=fe(e,n.name);if(n.isDirectory()){let i=await this.listFilesRecursive(s);t.push(...i)}else t.push(s)}return t}async putBucketPolicy(e,t){let{accessKeyId:r,secretAccessKey:n,sessionToken:s}=this.getCredentials(),i=`s3.${this.region}.amazonaws.com`,a=typeof t==="string"?t:JSON.stringify(t),o=new Date,c=o.toISOString().replace(/[:-]|\.\d{3}/g,""),d=o.toISOString().slice(0,10).replace(/-/g,""),m=g.createHash("sha256").update(a).digest("hex"),l=`/${e}`,u="policy=",h={host:i,"x-amz-date":c,"x-amz-content-sha256":m,"content-type":"application/json"};if(s)h["x-amz-security-token"]=s;let S=Object.keys(h).sort().map((b)=>`${b.toLowerCase()}:${h[b].trim()}
25
+ `).join(""),P=Object.keys(h).sort().map((b)=>b.toLowerCase()).join(";"),A=["PUT",l,"policy=",S,P,m].join(`
26
+ `),T="AWS4-HMAC-SHA256",w=`${d}/${this.region}/s3/aws4_request`,v=[T,c,w,g.createHash("sha256").update(A).digest("hex")].join(`
27
+ `),I=g.createHmac("sha256",`AWS4${n}`).update(d).digest(),N=g.createHmac("sha256",I).update(this.region).digest(),D=g.createHmac("sha256",N).update("s3").digest(),O=g.createHmac("sha256",D).update("aws4_request").digest(),q=g.createHmac("sha256",O).update(v).digest("hex"),E=`${T} Credential=${r}/${w}, SignedHeaders=${P}, Signature=${q}`,C=`https://${i}${l}?policy=`,f=await fetch(C,{method:"PUT",headers:{...h,Authorization:E},body:a});if(!f.ok){let b=await f.text();throw Error(`Failed to put bucket policy: ${f.status} ${b}`)}}async getBucketPolicy(e){let{accessKeyId:t,secretAccessKey:r,sessionToken:n}=this.getCredentials(),s=`s3.${this.region}.amazonaws.com`,i=new Date,a=i.toISOString().replace(/[:-]|\.\d{3}/g,""),o=i.toISOString().slice(0,10).replace(/-/g,""),c=g.createHash("sha256").update("").digest("hex"),d=`/${e}`,m="policy=",l={host:s,"x-amz-date":a,"x-amz-content-sha256":c};if(n)l["x-amz-security-token"]=n;let u=Object.keys(l).sort().map((f)=>`${f.toLowerCase()}:${l[f].trim()}
28
+ `).join(""),h=Object.keys(l).sort().map((f)=>f.toLowerCase()).join(";"),S=["GET",d,"policy=",u,h,c].join(`
29
+ `),P="AWS4-HMAC-SHA256",A=`${o}/${this.region}/s3/aws4_request`,T=[P,a,A,g.createHash("sha256").update(S).digest("hex")].join(`
30
+ `),w=g.createHmac("sha256",`AWS4${r}`).update(o).digest(),v=g.createHmac("sha256",w).update(this.region).digest(),I=g.createHmac("sha256",v).update("s3").digest(),N=g.createHmac("sha256",I).update("aws4_request").digest(),D=g.createHmac("sha256",N).update(T).digest("hex"),O=`${P} Credential=${t}/${A}, SignedHeaders=${h}, Signature=${D}`,q=`https://${s}${d}?policy=`,E=await fetch(q,{method:"GET",headers:{...l,Authorization:O}});if(E.status===404)return null;if(!E.ok){let f=await E.text();throw Error(`Failed to get bucket policy: ${E.status} ${f}`)}let C=await E.text();try{return JSON.parse(C)}catch{throw Error(`Failed to parse bucket policy JSON: ${C.slice(0,200)}`)}}async deleteBucketPolicy(e){await this.client.request({service:"s3",region:this.region,method:"DELETE",path:`/${e}`,queryParams:{policy:""}})}async headBucket(e){try{return{exists:!0,region:(await this.client.request({service:"s3",region:this.region,method:"HEAD",path:`/${e}`,returnHeaders:!0}))?.headers?.["x-amz-bucket-region"]}}catch(t){if(t.statusCode===404)return{exists:!1};throw t}}async headObject(e,t){try{let r=await this.client.request({service:"s3",region:this.region,method:"HEAD",path:`/${e}/${t}`,returnHeaders:!0});return{ContentLength:r?.headers?.["content-length"]?parseInt(r.headers["content-length"]):void 0,ContentType:r?.headers?.["content-type"],ETag:r?.headers?.etag,LastModified:r?.headers?.["last-modified"],ServerSideEncryption:r?.headers?.["x-amz-server-side-encryption"]}}catch(r){if(r.statusCode===404)return null;throw r}}async getObjectBuffer(e,t){let r=await this.getObject(e,t);return Buffer.from(r)}async getObjectJson(e,t){let r=await this.getObject(e,t);try{return JSON.parse(r)}catch{throw Error(`Failed to parse JSON from s3://${e}/${t}`)}}async putObjectJson(e,t,r,n){await this.putObject({bucket:e,key:t,body:JSON.stringify(r),contentType:"application/json",...n})}async getBucketVersioning(e){return{Status:(await this.client.request({service:"s3",region:this.region,method:"GET",path:`/${e}`,queryParams:{versioning:""}}))?.VersioningConfiguration?.Status}}async putBucketVersioning(e,t){let r=`<?xml version="1.0" encoding="UTF-8"?>
31
+ <VersioningConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
32
+ <Status>${t}</Status>
33
+ </VersioningConfiguration>`;await this.client.request({service:"s3",region:this.region,method:"PUT",path:`/${e}`,queryParams:{versioning:""},headers:{"Content-Type":"application/xml"},body:r})}async getBucketLifecycleConfiguration(e){try{return(await this.client.request({service:"s3",region:this.region,method:"GET",path:`/${e}`,queryParams:{lifecycle:""}}))?.LifecycleConfiguration}catch(t){if(t.statusCode===404)return null;throw t}}async putBucketLifecycleConfiguration(e,t){let n=`<?xml version="1.0" encoding="UTF-8"?>
34
+ <LifecycleConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
35
+ ${t.map((s)=>{let i=`<Rule><ID>${s.ID}</ID><Status>${s.Status}</Status>`;if(s.Filter)i+=`<Filter><Prefix>${s.Filter.Prefix||""}</Prefix></Filter>`;else i+="<Filter><Prefix></Prefix></Filter>";if(s.Expiration){if(s.Expiration.Days)i+=`<Expiration><Days>${s.Expiration.Days}</Days></Expiration>`;else if(s.Expiration.Date)i+=`<Expiration><Date>${s.Expiration.Date}</Date></Expiration>`}if(s.Transitions)for(let a of s.Transitions)i+=`<Transition><Days>${a.Days}</Days><StorageClass>${a.StorageClass}</StorageClass></Transition>`;if(s.NoncurrentVersionExpiration)i+=`<NoncurrentVersionExpiration><NoncurrentDays>${s.NoncurrentVersionExpiration.NoncurrentDays}</NoncurrentDays></NoncurrentVersionExpiration>`;return i+="</Rule>",i}).join("")}
36
+ </LifecycleConfiguration>`;await this.client.request({service:"s3",region:this.region,method:"PUT",path:`/${e}`,queryParams:{lifecycle:""},headers:{"Content-Type":"application/xml"},body:n})}async deleteBucketLifecycleConfiguration(e){await this.client.request({service:"s3",region:this.region,method:"DELETE",path:`/${e}`,queryParams:{lifecycle:""}})}async getBucketCors(e){try{return(await this.client.request({service:"s3",region:this.region,method:"GET",path:`/${e}`,queryParams:{cors:""}}))?.CORSConfiguration}catch(t){if(t.statusCode===404)return null;throw t}}async putBucketCors(e,t){let n=`<?xml version="1.0" encoding="UTF-8"?>
37
+ <CORSConfiguration>
38
+ ${t.map((s)=>{let i="<CORSRule>";for(let a of s.AllowedOrigins)i+=`<AllowedOrigin>${a}</AllowedOrigin>`;for(let a of s.AllowedMethods)i+=`<AllowedMethod>${a}</AllowedMethod>`;if(s.AllowedHeaders)for(let a of s.AllowedHeaders)i+=`<AllowedHeader>${a}</AllowedHeader>`;if(s.ExposeHeaders)for(let a of s.ExposeHeaders)i+=`<ExposeHeader>${a}</ExposeHeader>`;if(s.MaxAgeSeconds)i+=`<MaxAgeSeconds>${s.MaxAgeSeconds}</MaxAgeSeconds>`;return i+="</CORSRule>",i}).join("")}
39
+ </CORSConfiguration>`;await this.client.request({service:"s3",region:this.region,method:"PUT",path:`/${e}`,queryParams:{cors:""},headers:{"Content-Type":"application/xml"},body:n})}async deleteBucketCors(e){await this.client.request({service:"s3",region:this.region,method:"DELETE",path:`/${e}`,queryParams:{cors:""}})}async getBucketEncryption(e){try{let t=await this.client.request({service:"s3",region:this.region,method:"GET",path:`/${e}`,queryParams:{encryption:""}});return t?.ServerSideEncryptionConfiguration||t}catch(t){if(t.statusCode===404)return null;throw t}}async putBucketEncryption(e,t,r){let n=`<ApplyServerSideEncryptionByDefault><SSEAlgorithm>${t}</SSEAlgorithm>`;if(r)n+=`<KMSMasterKeyID>${r}</KMSMasterKeyID>`;n+="</ApplyServerSideEncryptionByDefault>";let s=`<?xml version="1.0" encoding="UTF-8"?>
40
+ <ServerSideEncryptionConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
41
+ <Rule>${n}</Rule>
42
+ </ServerSideEncryptionConfiguration>`;await this.client.request({service:"s3",region:this.region,method:"PUT",path:`/${e}`,queryParams:{encryption:""},headers:{"Content-Type":"application/xml"},body:s})}async deleteBucketEncryption(e){await this.client.request({service:"s3",region:this.region,method:"DELETE",path:`/${e}`,queryParams:{encryption:""}})}async getBucketTagging(e){try{let r=(await this.client.request({service:"s3",region:this.region,method:"GET",path:`/${e}`,queryParams:{tagging:""}}))?.Tagging?.TagSet?.Tag;if(!r)return[];return Array.isArray(r)?r:[r]}catch(t){if(t.statusCode===404)return[];throw t}}async putBucketTagging(e,t){let n=`<?xml version="1.0" encoding="UTF-8"?>
43
+ <Tagging>
44
+ <TagSet>${t.map((s)=>`<Tag><Key>${s.Key}</Key><Value>${s.Value}</Value></Tag>`).join("")}</TagSet>
45
+ </Tagging>`;await this.client.request({service:"s3",region:this.region,method:"PUT",path:`/${e}`,queryParams:{tagging:""},headers:{"Content-Type":"application/xml"},body:n})}async deleteBucketTagging(e){await this.client.request({service:"s3",region:this.region,method:"DELETE",path:`/${e}`,queryParams:{tagging:""}})}async getObjectTagging(e,t){try{let n=(await this.client.request({service:"s3",region:this.region,method:"GET",path:`/${e}/${t}`,queryParams:{tagging:""}}))?.Tagging?.TagSet?.Tag;if(!n)return[];return Array.isArray(n)?n:[n]}catch(r){if(r.statusCode===404)return[];throw r}}async putObjectTagging(e,t,r){let s=`<?xml version="1.0" encoding="UTF-8"?>
46
+ <Tagging>
47
+ <TagSet>${r.map((i)=>`<Tag><Key>${i.Key}</Key><Value>${i.Value}</Value></Tag>`).join("")}</TagSet>
48
+ </Tagging>`;await this.client.request({service:"s3",region:this.region,method:"PUT",path:`/${e}/${t}`,queryParams:{tagging:""},headers:{"Content-Type":"application/xml"},body:s})}async deleteObjectTagging(e,t){await this.client.request({service:"s3",region:this.region,method:"DELETE",path:`/${e}/${t}`,queryParams:{tagging:""}})}async getBucketAcl(e){return(await this.client.request({service:"s3",region:this.region,method:"GET",path:`/${e}`,queryParams:{acl:""}}))?.AccessControlPolicy}async putBucketAcl(e,t){await this.client.request({service:"s3",region:this.region,method:"PUT",path:`/${e}`,queryParams:{acl:""},headers:{"x-amz-acl":t}})}async getObjectAcl(e,t){return(await this.client.request({service:"s3",region:this.region,method:"GET",path:`/${e}/${t}`,queryParams:{acl:""}}))?.AccessControlPolicy}async putObjectAcl(e,t,r){await this.client.request({service:"s3",region:this.region,method:"PUT",path:`/${e}/${t}`,queryParams:{acl:""},headers:{"x-amz-acl":r}})}async getBucketLocation(e){return(await this.client.request({service:"s3",region:this.region,method:"GET",path:`/${e}`,queryParams:{location:""}}))?.LocationConstraint||"us-east-1"}async getBucketLogging(e){return(await this.client.request({service:"s3",region:this.region,method:"GET",path:`/${e}`,queryParams:{logging:""}}))?.BucketLoggingStatus}async putBucketLogging(e,t,r){let n=`<?xml version="1.0" encoding="UTF-8"?>
49
+ <BucketLoggingStatus xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
50
+ <LoggingEnabled>
51
+ <TargetBucket>${t}</TargetBucket>
52
+ <TargetPrefix>${r}</TargetPrefix>
53
+ </LoggingEnabled>
54
+ </BucketLoggingStatus>`;await this.client.request({service:"s3",region:this.region,method:"PUT",path:`/${e}`,queryParams:{logging:""},headers:{"Content-Type":"application/xml"},body:n})}async getBucketNotificationConfiguration(e){return(await this.client.request({service:"s3",region:this.region,method:"GET",path:`/${e}`,queryParams:{notification:""}}))?.NotificationConfiguration}async putBucketNotificationConfiguration(e,t){let r="";if(t.LambdaFunctionConfigurations)for(let s of t.LambdaFunctionConfigurations){if(r+="<CloudFunctionConfiguration>",s.Id)r+=`<Id>${s.Id}</Id>`;r+=`<CloudFunction>${s.LambdaFunctionArn}</CloudFunction>`;for(let i of s.Events)r+=`<Event>${i}</Event>`;if(s.Filter?.Key?.FilterRules){r+="<Filter><S3Key>";for(let i of s.Filter.Key.FilterRules)r+=`<FilterRule><Name>${i.Name}</Name><Value>${i.Value}</Value></FilterRule>`;r+="</S3Key></Filter>"}r+="</CloudFunctionConfiguration>"}if(t.TopicConfigurations)for(let s of t.TopicConfigurations){if(r+="<TopicConfiguration>",s.Id)r+=`<Id>${s.Id}</Id>`;r+=`<Topic>${s.TopicArn}</Topic>`;for(let i of s.Events)r+=`<Event>${i}</Event>`;r+="</TopicConfiguration>"}if(t.QueueConfigurations)for(let s of t.QueueConfigurations){if(r+="<QueueConfiguration>",s.Id)r+=`<Id>${s.Id}</Id>`;r+=`<Queue>${s.QueueArn}</Queue>`;for(let i of s.Events)r+=`<Event>${i}</Event>`;r+="</QueueConfiguration>"}let n=`<?xml version="1.0" encoding="UTF-8"?>
55
+ <NotificationConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
56
+ ${r}
57
+ </NotificationConfiguration>`;await this.client.request({service:"s3",region:this.region,method:"PUT",path:`/${e}`,queryParams:{notification:""},headers:{"Content-Type":"application/xml"},body:n})}async getBucketWebsite(e){try{return(await this.client.request({service:"s3",region:this.region,method:"GET",path:`/${e}`,queryParams:{website:""}}))?.WebsiteConfiguration}catch(t){if(t.statusCode===404)return null;throw t}}async putBucketWebsite(e,t){let r="";if(t.RedirectAllRequestsTo)r=`<RedirectAllRequestsTo>
58
+ <HostName>${t.RedirectAllRequestsTo.HostName}</HostName>
59
+ ${t.RedirectAllRequestsTo.Protocol?`<Protocol>${t.RedirectAllRequestsTo.Protocol}</Protocol>`:""}
60
+ </RedirectAllRequestsTo>`;else if(r=`<IndexDocument><Suffix>${t.IndexDocument}</Suffix></IndexDocument>`,t.ErrorDocument)r+=`<ErrorDocument><Key>${t.ErrorDocument}</Key></ErrorDocument>`;let n=`<?xml version="1.0" encoding="UTF-8"?>
61
+ <WebsiteConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
62
+ ${r}
63
+ </WebsiteConfiguration>`;await this.client.request({service:"s3",region:this.region,method:"PUT",path:`/${e}`,queryParams:{website:""},headers:{"Content-Type":"application/xml"},body:n})}async deleteBucketWebsite(e){await this.client.request({service:"s3",region:this.region,method:"DELETE",path:`/${e}`,queryParams:{website:""}})}async getBucketReplication(e){try{return(await this.client.request({service:"s3",region:this.region,method:"GET",path:`/${e}`,queryParams:{replication:""}}))?.ReplicationConfiguration}catch(t){if(t.statusCode===404)return null;throw t}}async deleteBucketReplication(e){await this.client.request({service:"s3",region:this.region,method:"DELETE",path:`/${e}`,queryParams:{replication:""}})}async getPublicAccessBlock(e){try{return(await this.client.request({service:"s3",region:this.region,method:"GET",path:`/${e}`,queryParams:{publicAccessBlock:""}}))?.PublicAccessBlockConfiguration}catch(t){if(t.statusCode===404)return null;throw t}}async putPublicAccessBlock(e,t){let r=`<?xml version="1.0" encoding="UTF-8"?>
64
+ <PublicAccessBlockConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
65
+ <BlockPublicAcls>${t.BlockPublicAcls??!0}</BlockPublicAcls>
66
+ <IgnorePublicAcls>${t.IgnorePublicAcls??!0}</IgnorePublicAcls>
67
+ <BlockPublicPolicy>${t.BlockPublicPolicy??!0}</BlockPublicPolicy>
68
+ <RestrictPublicBuckets>${t.RestrictPublicBuckets??!0}</RestrictPublicBuckets>
69
+ </PublicAccessBlockConfiguration>`;await this.client.request({service:"s3",region:this.region,method:"PUT",path:`/${e}`,queryParams:{publicAccessBlock:""},headers:{"Content-Type":"application/xml"},body:r})}async deletePublicAccessBlock(e){await this.client.request({service:"s3",region:this.region,method:"DELETE",path:`/${e}`,queryParams:{publicAccessBlock:""}})}generatePresignedGetUrl(e,t,r=3600){let{accessKeyId:n,secretAccessKey:s}=this.getCredentials(),i=`${e}.s3.${this.region}.amazonaws.com`,a=new Date,o=a.toISOString().replace(/[:-]|\.\d{3}/g,""),c=a.toISOString().slice(0,10).replace(/-/g,""),d=`${c}/${this.region}/s3/aws4_request`,m=`${n}/${d}`,l=new URLSearchParams({"X-Amz-Algorithm":"AWS4-HMAC-SHA256","X-Amz-Credential":m,"X-Amz-Date":o,"X-Amz-Expires":r.toString(),"X-Amz-SignedHeaders":"host"}),u=["GET",`/${t}`,l.toString(),`host:${i}
70
+ `,"host","UNSIGNED-PAYLOAD"].join(`
71
+ `),h=["AWS4-HMAC-SHA256",o,d,g.createHash("sha256").update(u).digest("hex")].join(`
72
+ `),S=g.createHmac("sha256",`AWS4${s}`).update(c).digest(),P=g.createHmac("sha256",S).update(this.region).digest(),A=g.createHmac("sha256",P).update("s3").digest(),T=g.createHmac("sha256",A).update("aws4_request").digest(),w=g.createHmac("sha256",T).update(h).digest("hex");return l.append("X-Amz-Signature",w),`https://${i}/${t}?${l.toString()}`}generatePresignedPutUrl(e,t,r,n=3600){let{accessKeyId:s,secretAccessKey:i}=this.getCredentials(),a=`${e}.s3.${this.region}.amazonaws.com`,o=new Date,c=o.toISOString().replace(/[:-]|\.\d{3}/g,""),d=o.toISOString().slice(0,10).replace(/-/g,""),m=`${d}/${this.region}/s3/aws4_request`,l=`${s}/${m}`,u=new URLSearchParams({"X-Amz-Algorithm":"AWS4-HMAC-SHA256","X-Amz-Credential":l,"X-Amz-Date":c,"X-Amz-Expires":n.toString(),"X-Amz-SignedHeaders":"content-type;host"}),h=["PUT",`/${t}`,u.toString(),`content-type:${r}
73
+ host:${a}
74
+ `,"content-type;host","UNSIGNED-PAYLOAD"].join(`
75
+ `),S=["AWS4-HMAC-SHA256",c,m,g.createHash("sha256").update(h).digest("hex")].join(`
76
+ `),P=g.createHmac("sha256",`AWS4${i}`).update(d).digest(),A=g.createHmac("sha256",P).update(this.region).digest(),T=g.createHmac("sha256",A).update("s3").digest(),w=g.createHmac("sha256",T).update("aws4_request").digest(),v=g.createHmac("sha256",w).update(S).digest("hex");return u.append("X-Amz-Signature",v),`https://${a}/${t}?${u.toString()}`}async createMultipartUpload(e,t,r){let n={};if(r?.contentType)n["Content-Type"]=r.contentType;if(r?.metadata)for(let[i,a]of Object.entries(r.metadata))n[`x-amz-meta-${i}`]=a;return{UploadId:(await this.client.request({service:"s3",region:this.region,method:"POST",path:`/${e}/${t}`,queryParams:{uploads:""},headers:n}))?.InitiateMultipartUploadResult?.UploadId}}async uploadPart(e,t,r,n,s){let{accessKeyId:i,secretAccessKey:a,sessionToken:o}=this.getCredentials(),c=`${e}.s3.${this.region}.amazonaws.com`,d=`https://${c}/${t}?partNumber=${n}&uploadId=${encodeURIComponent(r)}`,m=new Date,l=m.toISOString().replace(/[:-]|\.\d{3}/g,""),u=m.toISOString().slice(0,10).replace(/-/g,""),h=g.createHash("sha256").update(s).digest("hex"),S={host:c,"x-amz-date":l,"x-amz-content-sha256":h};if(o)S["x-amz-security-token"]=o;let P=Object.keys(S).sort().map((b)=>`${b.toLowerCase()}:${S[b].trim()}
77
+ `).join(""),A=Object.keys(S).sort().map((b)=>b.toLowerCase()).join(";"),T=["PUT",`/${t}`,`partNumber=${n}&uploadId=${encodeURIComponent(r)}`,P,A,h].join(`
78
+ `),w="AWS4-HMAC-SHA256",v=`${u}/${this.region}/s3/aws4_request`,I=[w,l,v,g.createHash("sha256").update(T).digest("hex")].join(`
79
+ `),N=g.createHmac("sha256",`AWS4${a}`).update(u).digest(),D=g.createHmac("sha256",N).update(this.region).digest(),O=g.createHmac("sha256",D).update("s3").digest(),q=g.createHmac("sha256",O).update("aws4_request").digest(),E=g.createHmac("sha256",q).update(I).digest("hex"),C=`${w} Credential=${i}/${v}, SignedHeaders=${A}, Signature=${E}`,f=await fetch(d,{method:"PUT",headers:{...S,Authorization:C},body:new Uint8Array(s)});if(!f.ok){let b=await f.text();throw Error(`Upload part failed: ${f.status} ${b}`)}return{ETag:f.headers.get("etag")||""}}async completeMultipartUpload(e,t,r,n){let i=`<?xml version="1.0" encoding="UTF-8"?>
80
+ <CompleteMultipartUpload>${n.sort((a,o)=>a.PartNumber-o.PartNumber).map((a)=>`<Part><PartNumber>${a.PartNumber}</PartNumber><ETag>${a.ETag}</ETag></Part>`).join("")}</CompleteMultipartUpload>`;await this.client.request({service:"s3",region:this.region,method:"POST",path:`/${e}/${t}`,queryParams:{uploadId:r},headers:{"Content-Type":"application/xml"},body:i})}async abortMultipartUpload(e,t,r){await this.client.request({service:"s3",region:this.region,method:"DELETE",path:`/${e}/${t}`,queryParams:{uploadId:r}})}async listMultipartUploads(e){let r=(await this.client.request({service:"s3",region:this.region,method:"GET",path:`/${e}`,queryParams:{uploads:""}}))?.ListMultipartUploadsResult?.Upload;if(!r)return[];return(Array.isArray(r)?r:[r]).map((s)=>({Key:s.Key,UploadId:s.UploadId,Initiated:s.Initiated}))}async restoreObject(e,t,r,n="Standard"){let s=`<?xml version="1.0" encoding="UTF-8"?>
81
+ <RestoreRequest>
82
+ <Days>${r}</Days>
83
+ <GlacierJobParameters>
84
+ <Tier>${n}</Tier>
85
+ </GlacierJobParameters>
86
+ </RestoreRequest>`;await this.client.request({service:"s3",region:this.region,method:"POST",path:`/${e}/${t}`,queryParams:{restore:""},headers:{"Content-Type":"application/xml"},body:s})}async selectObjectContent(e,t,r,n,s="JSON"){let i="";if(n==="CSV")i="<CSV><FileHeaderInfo>USE</FileHeaderInfo></CSV>";else if(n==="JSON")i="<JSON><Type>DOCUMENT</Type></JSON>";else i="<Parquet/>";let a="";if(s==="CSV")a="<CSV/>";else a="<JSON/>";let o=`<?xml version="1.0" encoding="UTF-8"?>
87
+ <SelectObjectContentRequest>
88
+ <Expression>${r}</Expression>
89
+ <ExpressionType>SQL</ExpressionType>
90
+ <InputSerialization>${i}</InputSerialization>
91
+ <OutputSerialization>${a}</OutputSerialization>
92
+ </SelectObjectContentRequest>`;return await this.client.request({service:"s3",region:this.region,method:"POST",path:`/${e}/${t}`,queryParams:{select:"","select-type":"2"},headers:{"Content-Type":"application/xml"},body:o,rawResponse:!0})}}class Re{client;region;constructor(e="us-east-1",t){this.region=e,this.client=new j}async createSecret(e){let t={Name:e.Name};if(e.Description)t.Description=e.Description;if(e.KmsKeyId)t.KmsKeyId=e.KmsKeyId;if(e.SecretBinary)t.SecretBinary=e.SecretBinary;if(e.SecretString)t.SecretString=e.SecretString;if(e.Tags&&e.Tags.length>0)t.Tags=e.Tags;if(e.AddReplicaRegions&&e.AddReplicaRegions.length>0)t.AddReplicaRegions=e.AddReplicaRegions;if(e.ForceOverwriteReplicaSecret!==void 0)t.ForceOverwriteReplicaSecret=e.ForceOverwriteReplicaSecret;t.ClientRequestToken=e.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(t)});return{ARN:r.ARN,Name:r.Name,VersionId:r.VersionId,ReplicationStatus:r.ReplicationStatus}}async updateSecret(e){let t={SecretId:e.SecretId,ClientRequestToken:e.ClientRequestToken||crypto.randomUUID()};if(e.Description)t.Description=e.Description;if(e.KmsKeyId)t.KmsKeyId=e.KmsKeyId;if(e.SecretBinary)t.SecretBinary=e.SecretBinary;if(e.SecretString)t.SecretString=e.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(t)});return{ARN:r.ARN,Name:r.Name,VersionId:r.VersionId}}async putSecretValue(e){let t={SecretId:e.SecretId};if(e.SecretBinary)t.SecretBinary=e.SecretBinary;if(e.SecretString)t.SecretString=e.SecretString;if(e.VersionStages&&e.VersionStages.length>0)t.VersionStages=e.VersionStages;if(e.ClientRequestToken)t.ClientRequestToken=e.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(t)});return{ARN:r.ARN,Name:r.Name,VersionId:r.VersionId,VersionStages:r.VersionStages}}async getSecretValue(e){let t={SecretId:e.SecretId};if(e.VersionId)t.VersionId=e.VersionId;if(e.VersionStage)t.VersionStage=e.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(t)});return{ARN:r.ARN,Name:r.Name,VersionId:r.VersionId,SecretBinary:r.SecretBinary,SecretString:r.SecretString,VersionStages:r.VersionStages,CreatedDate:r.CreatedDate}}async describeSecret(e){let t={SecretId:e},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(t)});return this.parseSecret(r)}async listSecrets(e){let t={};if(e?.MaxResults)t.MaxResults=e.MaxResults;if(e?.NextToken)t.NextToken=e.NextToken;if(e?.Filters&&e.Filters.length>0)t.Filters=e.Filters;if(e?.SortOrder)t.SortOrder=e.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(t)});return{SecretList:r.SecretList?.map((n)=>this.parseSecret(n)),NextToken:r.NextToken}}async deleteSecret(e){let t={SecretId:e.SecretId};if(e.RecoveryWindowInDays!==void 0)t.RecoveryWindowInDays=e.RecoveryWindowInDays;if(e.ForceDeleteWithoutRecovery!==void 0)t.ForceDeleteWithoutRecovery=e.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(t)});return{ARN:r.ARN,Name:r.Name,DeletionDate:r.DeletionDate}}async restoreSecret(e){let t={SecretId:e},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(t)});return{ARN:r.ARN,Name:r.Name}}async rotateSecret(e){let t={SecretId:e.SecretId};if(e.ClientRequestToken)t.ClientRequestToken=e.ClientRequestToken;if(e.RotationLambdaARN)t.RotationLambdaARN=e.RotationLambdaARN;if(e.RotationRules)t.RotationRules=e.RotationRules;if(e.RotateImmediately!==void 0)t.RotateImmediately=e.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(t)});return{ARN:r.ARN,Name:r.Name,VersionId:r.VersionId}}async cancelRotateSecret(e){let t={SecretId:e},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(t)});return{ARN:r.ARN,Name:r.Name}}async getResourcePolicy(e){let t={SecretId:e},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(t)});return{ARN:r.ARN,Name:r.Name,ResourcePolicy:r.ResourcePolicy}}async putResourcePolicy(e){let t={SecretId:e.SecretId,ResourcePolicy:e.ResourcePolicy};if(e.BlockPublicPolicy!==void 0)t.BlockPublicPolicy=e.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(t)});return{ARN:r.ARN,Name:r.Name}}async deleteResourcePolicy(e){let t={SecretId:e},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(t)});return{ARN:r.ARN,Name:r.Name}}async tagResource(e){let t={SecretId:e.SecretId,Tags:e.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(t)})}async untagResource(e){let t={SecretId:e.SecretId,TagKeys:e.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(t)})}async setString(e,t,r){try{let n=await this.putSecretValue({SecretId:e,SecretString:t});return{ARN:n.ARN,VersionId:n.VersionId}}catch(n){if(n.code==="ResourceNotFoundException"){let s=await this.createSecret({Name:e,SecretString:t,Description:r?.description,KmsKeyId:r?.kmsKeyId,Tags:r?.tags});return{ARN:s.ARN,VersionId:s.VersionId}}throw n}}async setJson(e,t,r){return this.setString(e,JSON.stringify(t),r)}async getString(e){return(await this.getSecretValue({SecretId:e})).SecretString}async getJson(e){let t=await this.getString(e);if(t)try{return JSON.parse(t)}catch(r){throw Error(`Failed to parse secret "${e}" as JSON: ${r.message}`)}return}async listAll(){let e=[],t;do{let r=await this.listSecrets({NextToken:t});if(r.SecretList)e.push(...r.SecretList);t=r.NextToken}while(t);return e}parseSecret(e){return{ARN:e.ARN,Name:e.Name,Description:e.Description,KmsKeyId:e.KmsKeyId,RotationEnabled:e.RotationEnabled,RotationLambdaARN:e.RotationLambdaARN,RotationRules:e.RotationRules,LastRotatedDate:e.LastRotatedDate,LastChangedDate:e.LastChangedDate,LastAccessedDate:e.LastAccessedDate,DeletedDate:e.DeletedDate,NextRotationDate:e.NextRotationDate,Tags:e.Tags,SecretVersionsToStages:e.SecretVersionsToStages,CreatedDate:e.CreatedDate,PrimaryRegion:e.PrimaryRegion}}}import*as ee from"net";import*as z from"tls";import*as M from"fs";import*as U from"crypto";class _{client;region;constructor(e="us-east-1"){this.region=e,this.client=new j}async createEmailIdentity(e){return await this.client.request({service:"email",region:this.region,method:"POST",path:"/v2/email/identities",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)})}async getEmailIdentity(e){let t=await this.client.request({service:"email",region:this.region,method:"GET",path:`/v2/email/identities/${encodeURIComponent(e)}`,headers:{"Content-Type":"application/json"}});return{IdentityType:t.IdentityType,IdentityName:e,SendingEnabled:t.VerifiedForSendingStatus,VerificationStatus:t.VerificationStatus,DkimAttributes:t.DkimAttributes,MailFromAttributes:t.MailFromAttributes}}async putEmailIdentityMailFromAttributes(e,t){await this.client.request({service:"email",region:this.region,method:"PUT",path:`/v2/email/identities/${encodeURIComponent(e)}/mail-from`,headers:{"Content-Type":"application/json"},body:JSON.stringify(t)})}async listEmailIdentities(e){let t="/v2/email/identities",r=[];if(e?.PageSize)r.push(`PageSize=${e.PageSize}`);if(e?.NextToken)r.push(`NextToken=${encodeURIComponent(e.NextToken)}`);if(r.length>0)t+=`?${r.join("&")}`;let n=await this.client.request({service:"email",region:this.region,method:"GET",path:t,headers:{"Content-Type":"application/json"}});return{EmailIdentities:n.EmailIdentities,NextToken:n.NextToken}}async deleteEmailIdentity(e){await this.client.request({service:"email",region:this.region,method:"DELETE",path:`/v2/email/identities/${encodeURIComponent(e)}`,headers:{"Content-Type":"application/json"}})}async putEmailIdentityDkimAttributes(e){await this.client.request({service:"email",region:this.region,method:"PUT",path:`/v2/email/identities/${encodeURIComponent(e.EmailIdentity)}/dkim`,headers:{"Content-Type":"application/json"},body:JSON.stringify({SigningEnabled:e.SigningEnabled})})}async sendEmail(e){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(e)})).MessageId}}async sendBulkEmail(e){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(e)})).BulkEmailEntryResults}}async createEmailTemplate(e){await this.client.request({service:"email",region:this.region,method:"POST",path:"/v2/email/templates",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)})}async getEmailTemplate(e){return await this.client.request({service:"email",region:this.region,method:"GET",path:`/v2/email/templates/${encodeURIComponent(e)}`,headers:{"Content-Type":"application/json"}})}async deleteEmailTemplate(e){await this.client.request({service:"email",region:this.region,method:"DELETE",path:`/v2/email/templates/${encodeURIComponent(e)}`,headers:{"Content-Type":"application/json"}})}async listEmailTemplates(e){let t="/v2/email/templates",r=[];if(e?.PageSize)r.push(`PageSize=${e.PageSize}`);if(e?.NextToken)r.push(`NextToken=${encodeURIComponent(e.NextToken)}`);if(r.length>0)t+=`?${r.join("&")}`;return await this.client.request({service:"email",region:this.region,method:"GET",path:t,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 t=(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:t?.Max24HourSend?Number(t.Max24HourSend):void 0,MaxSendRate:t?.MaxSendRate?Number(t.MaxSendRate):void 0,SentLast24Hours:t?.SentLast24Hours?Number(t.SentLast24Hours):void 0}}async verifyDomain(e){let t=await this.createEmailIdentity({EmailIdentity:e});return{dkimTokens:t.DkimAttributes?.Tokens,verificationStatus:t.DkimAttributes?.Status}}async sendSimpleEmail(e){let t=Array.isArray(e.to)?e.to:[e.to],r=e.replyTo?Array.isArray(e.replyTo)?e.replyTo:[e.replyTo]:void 0,n={};if(e.text)n.Text={Data:e.text};if(e.html)n.Html={Data:e.html};return this.sendEmail({FromEmailAddress:e.from,Destination:{ToAddresses:t},Content:{Simple:{Subject:{Data:e.subject},Body:n}},ReplyToAddresses:r})}async sendTemplatedEmail(e){let t=Array.isArray(e.to)?e.to:[e.to],r=e.replyTo?Array.isArray(e.replyTo)?e.replyTo:[e.replyTo]:void 0;return this.sendEmail({FromEmailAddress:e.from,Destination:{ToAddresses:t},Content:{Template:{TemplateName:e.templateName,TemplateData:JSON.stringify(e.templateData)}},ReplyToAddresses:r})}async getDkimRecords(e){let t=await this.getEmailIdentity(e);if(!t.DkimAttributes?.Tokens)return[];return t.DkimAttributes.Tokens.map((r)=>({name:`${r}._domainkey.${e}`,type:"CNAME",value:`${r}.dkim.amazonses.com`}))}async isDomainVerified(e){try{let t=await this.getEmailIdentity(e);return t.VerificationStatus==="SUCCESS"&&t.SendingEnabled===!0}catch{return!1}}async waitForDomainVerification(e,t=60,r=30000){for(let n=0;n<t;n++){if(await this.isDomainVerified(e))return!0;await new Promise((i)=>setTimeout(i,r))}return!1}buildFormBody(e){return Object.entries(e).filter(([,r])=>r!==void 0).map(([r,n])=>`${encodeURIComponent(r)}=${encodeURIComponent(n)}`).join("&")}async createReceiptRuleSet(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:"CreateReceiptRuleSet",Version:"2010-12-01",RuleSetName:e})})}async deleteReceiptRuleSet(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:"DeleteReceiptRuleSet",Version:"2010-12-01",RuleSetName:e})})}async setActiveReceiptRuleSet(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:"SetActiveReceiptRuleSet",Version:"2010-12-01",RuleSetName:e})})}async listReceiptRuleSets(e){let t={Action:"ListReceiptRuleSets",Version:"2010-12-01"};if(e)t.NextToken=e;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(t)}),n=r?.ListReceiptRuleSetsResponse?.ListReceiptRuleSetsResult||r?.ListReceiptRuleSetsResult,s=n?.RuleSets?.member;return{RuleSets:Array.isArray(s)?s:s?[s]:[],NextToken:n?.NextToken}}async describeReceiptRuleSet(e){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:"DescribeReceiptRuleSet",Version:"2010-12-01",RuleSetName:e})}),r=t?.DescribeReceiptRuleSetResponse?.DescribeReceiptRuleSetResult||t?.DescribeReceiptRuleSetResult,n=r?.Rules?.member;return{Metadata:r?.Metadata,Rules:Array.isArray(n)?n:n?[n]:[]}}async createReceiptRule(e){let t={Action:"CreateReceiptRule",Version:"2010-12-01",RuleSetName:e.RuleSetName,"Rule.Name":e.Rule.Name,"Rule.Enabled":e.Rule.Enabled!==!1?"true":"false"};if(e.Rule.TlsPolicy)t["Rule.TlsPolicy"]=e.Rule.TlsPolicy;if(e.Rule.ScanEnabled!==void 0)t["Rule.ScanEnabled"]=e.Rule.ScanEnabled?"true":"false";if(e.After)t.After=e.After;if(e.Rule.Recipients)e.Rule.Recipients.forEach((r,n)=>{t[`Rule.Recipients.member.${n+1}`]=r});e.Rule.Actions.forEach((r,n)=>{let s=n+1;if(r.S3Action){if(t[`Rule.Actions.member.${s}.S3Action.BucketName`]=r.S3Action.BucketName,r.S3Action.ObjectKeyPrefix)t[`Rule.Actions.member.${s}.S3Action.ObjectKeyPrefix`]=r.S3Action.ObjectKeyPrefix;if(r.S3Action.KmsKeyArn)t[`Rule.Actions.member.${s}.S3Action.KmsKeyArn`]=r.S3Action.KmsKeyArn}if(r.LambdaAction)t[`Rule.Actions.member.${s}.LambdaAction.FunctionArn`]=r.LambdaAction.FunctionArn,t[`Rule.Actions.member.${s}.LambdaAction.InvocationType`]=r.LambdaAction.InvocationType||"Event";if(r.SNSAction){if(t[`Rule.Actions.member.${s}.SNSAction.TopicArn`]=r.SNSAction.TopicArn,r.SNSAction.Encoding)t[`Rule.Actions.member.${s}.SNSAction.Encoding`]=r.SNSAction.Encoding}if(r.StopAction){if(t[`Rule.Actions.member.${s}.StopAction.Scope`]=r.StopAction.Scope,r.StopAction.TopicArn)t[`Rule.Actions.member.${s}.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(t)})}async deleteReceiptRule(e,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:"DeleteReceiptRule",Version:"2010-12-01",RuleSetName:e,RuleName:t})})}async receiptRuleSetExists(e){try{return await this.describeReceiptRuleSet(e),!0}catch(t){if(t.code==="RuleSetDoesNotExist"||t.statusCode===400)return!1;throw t}}async getActiveReceiptRuleSet(){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:"DescribeActiveReceiptRuleSet",Version:"2010-12-01"})}),t=e?.DescribeActiveReceiptRuleSetResponse?.DescribeActiveReceiptRuleSetResult||e?.DescribeActiveReceiptRuleSetResult;if(!t?.Metadata)return null;let r=t?.Rules?.member;return{Metadata:t?.Metadata,Rules:Array.isArray(r)?r:r?[r]:[]}}async updateReceiptRule(e){let t={Action:"UpdateReceiptRule",Version:"2010-12-01",RuleSetName:e.RuleSetName,"Rule.Name":e.Rule.Name};if(e.Rule.Enabled!==void 0)t["Rule.Enabled"]=e.Rule.Enabled?"true":"false";if(e.Rule.TlsPolicy)t["Rule.TlsPolicy"]=e.Rule.TlsPolicy;if(e.Rule.ScanEnabled!==void 0)t["Rule.ScanEnabled"]=e.Rule.ScanEnabled?"true":"false";if(e.Rule.Recipients)e.Rule.Recipients.forEach((r,n)=>{t[`Rule.Recipients.member.${n+1}`]=r});e.Rule.Actions.forEach((r,n)=>{let s=n+1;if(r.S3Action){if(t[`Rule.Actions.member.${s}.S3Action.BucketName`]=r.S3Action.BucketName,r.S3Action.ObjectKeyPrefix)t[`Rule.Actions.member.${s}.S3Action.ObjectKeyPrefix`]=r.S3Action.ObjectKeyPrefix;if(r.S3Action.KmsKeyArn)t[`Rule.Actions.member.${s}.S3Action.KmsKeyArn`]=r.S3Action.KmsKeyArn}if(r.LambdaAction)t[`Rule.Actions.member.${s}.LambdaAction.FunctionArn`]=r.LambdaAction.FunctionArn,t[`Rule.Actions.member.${s}.LambdaAction.InvocationType`]=r.LambdaAction.InvocationType||"Event";if(r.SNSAction){if(t[`Rule.Actions.member.${s}.SNSAction.TopicArn`]=r.SNSAction.TopicArn,r.SNSAction.Encoding)t[`Rule.Actions.member.${s}.SNSAction.Encoding`]=r.SNSAction.Encoding}if(r.StopAction){if(t[`Rule.Actions.member.${s}.StopAction.Scope`]=r.StopAction.Scope,r.StopAction.TopicArn)t[`Rule.Actions.member.${s}.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(t)})}async sendRawEmail(e){let t=Buffer.from(e.rawMessage).toString("base64"),r={Action:"SendRawEmail",Version:"2010-12-01",Source:e.source,"RawMessage.Data":t};e.destinations.forEach((i,a)=>{r[`Destinations.member.${a+1}`]=i});let n=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:(n?.SendRawEmailResponse?.SendRawEmailResult||n?.SendRawEmailResult)?.MessageId}}}class te{config;ses;s3;server;tlsServer;sessions=new Map;constructor(e){if(this.config={port:587,tlsPort:465,host:"0.0.0.0",...e},this.ses=new _(e.region||"us-east-1"),e.sentBucket)this.s3=new W(e.region||"us-east-1")}async start(){if(this.server=ee.createServer((e)=>{this.handleConnection(e,!1)}),this.server.listen(this.config.port,this.config.host,()=>{console.log(`SMTP server listening on ${this.config.host}:${this.config.port} (STARTTLS)`)}),this.config.tls?.key&&this.config.tls?.cert){let e={key:M.readFileSync(this.config.tls.key),cert:M.readFileSync(this.config.tls.cert)};this.tlsServer=z.createServer(e,(t)=>{this.handleConnection(t,!0)}),this.tlsServer.listen(this.config.tlsPort,this.config.host,()=>{console.log(`SMTP server listening on ${this.config.host}:${this.config.tlsPort} (TLS)`)})}}async stop(){if(this.server)this.server.close();if(this.tlsServer)this.tlsServer.close();for(let e of this.sessions.values())e.socket.destroy();this.sessions.clear()}handleConnection(e,t){let r=U.randomUUID(),n={id:r,socket:e,secure:t,state:"greeting",authenticated:!1,rcptTo:[],dataBuffer:"",tlsUpgraded:t};this.sessions.set(r,n),console.log(`SMTP connection from ${e.remoteAddress} (session: ${r.slice(0,8)})`),this.send(n,`220 ${this.config.domain} ESMTP Mail Server`),n.state="ready";let s="";e.on("data",async(i)=>{s+=i.toString();let a;while((a=s.indexOf(`\r
93
+ `))!==-1){let o=s.slice(0,a);if(s=s.slice(a+2),n.state==="data")await this.handleDataLine(n,o);else await this.handleCommand(n,o)}}),e.on("close",()=>{console.log(`SMTP session ${r.slice(0,8)} closed`),this.sessions.delete(r)}),e.on("error",(i)=>{console.error(`SMTP session ${r.slice(0,8)} error:`,i.message),this.sessions.delete(r)})}send(e,t){if(!e.socket.destroyed)e.socket.write(`${t}\r
94
+ `)}async handleCommand(e,t){let r=t.trim();if(!r)return;let n=r.split(" ")[0]?.toUpperCase();if(!n)return;let s=r.slice(n.length).trim();switch(console.log(`SMTP CMD [${e.username||"anon"}]: ${n} ${s.includes("AUTH")?"***":s}`),n){case"EHLO":case"HELO":await this.handleEhlo(e,s);break;case"STARTTLS":await this.handleStartTls(e);break;case"AUTH":await this.handleAuth(e,s);break;case"MAIL":await this.handleMailFrom(e,s);break;case"RCPT":await this.handleRcptTo(e,s);break;case"DATA":await this.handleData(e);break;case"RSET":this.resetSession(e),this.send(e,"250 OK");break;case"NOOP":this.send(e,"250 OK");break;case"QUIT":this.send(e,`221 ${this.config.domain} closing connection`),e.socket.end();break;default:this.send(e,"500 Unrecognized command")}}async handleEhlo(e,t){let r=[`250-${this.config.domain} Hello ${t}`,"250-SIZE 26214400","250-8BITMIME","250-PIPELINING"];if(!e.secure&&this.config.tls?.key)r.push("250-STARTTLS");r.push("250-AUTH PLAIN LOGIN"),r.push("250 OK");for(let n of r)this.send(e,n)}async handleStartTls(e){if(e.secure||e.tlsUpgraded){this.send(e,"503 TLS already active");return}if(!this.config.tls?.key||!this.config.tls?.cert){this.send(e,"454 TLS not available");return}this.send(e,"220 Ready to start TLS");let t={key:M.readFileSync(this.config.tls.key),cert:M.readFileSync(this.config.tls.cert),isServer:!0},r=new z.TLSSocket(e.socket,t);e.socket=r,e.secure=!0,e.tlsUpgraded=!0,this.resetSession(e)}async handleAuth(e,t){let r=t.split(" "),n=r[0]?.toUpperCase();if(!n){this.send(e,"504 Authentication mechanism required");return}if(n==="PLAIN")if(r[1])await this.handleAuthPlain(e,r[1]);else this.send(e,"334 "),e.state="ready";else if(n==="LOGIN"){this.send(e,"334 VXNlcm5hbWU6");let s=e.socket.listeners("data")[0];e.socket.removeAllListeners("data");let i="username",a="";e.socket.on("data",async(o)=>{try{let c=o.toString().trim();if(i==="username")a=Buffer.from(c,"base64").toString("utf-8"),i="password",this.send(e,"334 UGFzc3dvcmQ6");else if(i==="password"){let d=Buffer.from(c,"base64").toString("utf-8");e.socket.removeAllListeners("data"),e.socket.on("data",s),await this.authenticateUser(e,a,d)}}catch(c){e.socket.removeAllListeners("data"),e.socket.on("data",s),this.send(e,"535 Authentication failed"),console.error(`SMTP AUTH LOGIN error: ${c.message}`)}})}else this.send(e,"504 Unrecognized authentication mechanism")}async handleAuthPlain(e,t){try{let n=Buffer.from(t,"base64").toString("utf-8").split("\x00"),s=n.length===3?n[1]:n[0],i=n.length===3?n[2]:n[1];if(!s||i===void 0)throw Error("Malformed AUTH PLAIN credentials");await this.authenticateUser(e,s,i)}catch(r){this.send(e,"535 Authentication failed")}}async authenticateUser(e,t,r){let n=t.includes("@")?t.split("@")[0]??"":t,s=this.config.users[n],i=s?(()=>{try{let a=Buffer.from(s.password,"utf-8"),o=Buffer.from(r,"utf-8");if(a.length!==o.length){let c=Math.max(a.length,o.length),d=Buffer.alloc(c),m=Buffer.alloc(c);return d.set(a),m.set(o),U.timingSafeEqual(d,m),!1}return U.timingSafeEqual(a,o)}catch{return!1}})():!1;if(s&&i)e.authenticated=!0,e.username=n,e.email=s.email,this.send(e,"235 Authentication successful"),console.log(`SMTP AUTH success: ${n}`);else this.send(e,"535 Authentication failed"),console.log(`SMTP AUTH failed: ${t}`)}async handleMailFrom(e,t){if(!e.authenticated){this.send(e,"530 Authentication required");return}let r=t.match(/FROM:\s*<([^>]*)>/i);if(!r){this.send(e,"501 Syntax error in MAIL FROM");return}let n=r[1];if(!n){this.send(e,"501 Syntax error in MAIL FROM");return}if(!n.endsWith(`@${this.config.domain}`)){this.send(e,`553 Sender address must be from @${this.config.domain}`);return}e.mailFrom=n,e.state="mail",this.send(e,"250 OK")}async handleRcptTo(e,t){if(!e.authenticated){this.send(e,"530 Authentication required");return}if(!e.mailFrom){this.send(e,"503 MAIL FROM required first");return}let r=t.match(/TO:\s*<([^>]*)>/i);if(!r){this.send(e,"501 Syntax error in RCPT TO");return}let n=r[1];if(!n){this.send(e,"501 Syntax error in RCPT TO");return}e.rcptTo.push(n),e.state="rcpt",this.send(e,"250 OK")}async handleData(e){if(!e.authenticated){this.send(e,"530 Authentication required");return}if(e.rcptTo.length===0){this.send(e,"503 RCPT TO required first");return}e.state="data",e.dataBuffer="",this.send(e,"354 Start mail input; end with <CRLF>.<CRLF>")}async handleDataLine(e,t){if(t===".")await this.sendEmail(e);else{let r=t.startsWith(".")?t.slice(1):t;e.dataBuffer+=`${r}\r
95
+ `}}async sendEmail(e){try{let t=e.dataBuffer,r=await this.ses.sendRawEmail({source:e.mailFrom,destinations:e.rcptTo,rawMessage:t});if(console.log(`SMTP: Email sent via SES, MessageId: ${r.MessageId}`),this.s3&&this.config.sentBucket)try{let n=`${this.config.sentPrefix||"sent/"}${e.email}/${Date.now()}-${r.MessageId}`;await this.s3.putObject({bucket:this.config.sentBucket,key:n,body:t,contentType:"message/rfc822"}),console.log(`SMTP: Email stored in S3: ${n}`)}catch(n){console.error("SMTP: Failed to store sent email in S3 (email was sent successfully):",n.message)}this.send(e,`250 OK Message accepted, ID: ${r.MessageId}`),this.resetSession(e)}catch(t){console.error("SMTP: Failed to send email:",t.message),this.send(e,`451 Failed to send: ${t.message}`),this.resetSession(e)}}resetSession(e){e.state="ready",e.mailFrom=void 0,e.rcptTo=[],e.dataBuffer=""}}async function ot(e){let t=new te(e);return await t.start(),t}export{j as AWSClient,se as Cloud,W as S3Client,Re as SecretsManagerClient,te as SmtpServer,je as addJumpBox,Ge as buildQueryParams,Ke as deleteCdkRemnants,me as deleteEc2Instance,xe as deleteIamUsers,$e as deleteJumpBox,Oe as deleteLogGroups,qe as deleteParameterStore,Ie as deleteStacksBuckets,De as deleteStacksFunctions,Be as deleteSubnets,Le as deleteVpcs,He as getCloudFrontDistributionId,H as getJumpBoxInstanceId,he as getJumpBoxInstanceProfileName,ye as getJumpBoxSecurityGroupName,Ve as getOrCreateTimestamp,Me as getSecurityGroupFromInstanceId,ge as getSecurityGroupId,Fe as hasBeenDeployed,ze as isFailedState,Ue as isFirstDeployment,Ne as purchaseDomain,ot as startSmtpServer};
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@stacksjs/cloud",
3
3
  "type": "module",
4
4
  "sideEffects": false,
5
- "version": "0.72.78",
5
+ "version": "0.72.79",
6
6
  "description": "The Stacks cloud/serverless integration & implementation.",
7
7
  "author": "Chris Breuer",
8
8
  "contributors": [
@@ -63,16 +63,16 @@
63
63
  "@stacksjs/ts-xml": "^0.1.0"
64
64
  },
65
65
  "devDependencies": {
66
- "@stacksjs/cli": "0.72.78",
67
- "@stacksjs/config": "0.72.78",
66
+ "@stacksjs/cli": "0.72.79",
67
+ "@stacksjs/config": "0.72.79",
68
68
  "better-dx": "^0.2.24",
69
- "@stacksjs/dns": "0.72.78",
70
- "@stacksjs/env": "0.72.78",
71
- "@stacksjs/logging": "0.72.78",
72
- "@stacksjs/path": "0.72.78",
73
- "@stacksjs/router": "0.72.78",
74
- "@stacksjs/storage": "0.72.78",
75
- "@stacksjs/utils": "0.72.78",
76
- "@stacksjs/validation": "0.72.78"
69
+ "@stacksjs/dns": "0.72.79",
70
+ "@stacksjs/env": "0.72.79",
71
+ "@stacksjs/logging": "0.72.79",
72
+ "@stacksjs/path": "0.72.79",
73
+ "@stacksjs/router": "0.72.79",
74
+ "@stacksjs/storage": "0.72.79",
75
+ "@stacksjs/utils": "0.72.79",
76
+ "@stacksjs/validation": "0.72.79"
77
77
  }
78
78
  }