@stacksjs/ts-cloud 0.1.8 → 0.1.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin/cli.js +1 -1
- package/package.json +18 -16
- package/src/aws/acm.ts +768 -0
- package/src/aws/application-autoscaling.ts +845 -0
- package/src/aws/bedrock.ts +4074 -0
- package/src/aws/client.ts +891 -0
- package/src/aws/cloudformation.ts +896 -0
- package/src/aws/cloudfront.ts +1531 -0
- package/src/aws/cloudwatch-logs.ts +154 -0
- package/src/aws/comprehend.ts +839 -0
- package/src/aws/connect.ts +1056 -0
- package/src/aws/deploy-imap.ts +384 -0
- package/src/aws/dynamodb.ts +340 -0
- package/src/aws/ec2.ts +1385 -0
- package/src/aws/ecr.ts +621 -0
- package/src/aws/ecs.ts +615 -0
- package/src/aws/elasticache.ts +301 -0
- package/src/aws/elbv2.ts +942 -0
- package/src/aws/email.ts +928 -0
- package/src/aws/eventbridge.ts +248 -0
- package/src/aws/iam.ts +1689 -0
- package/src/aws/imap-server.ts +2100 -0
- package/src/aws/index.ts +213 -0
- package/src/aws/kendra.ts +1097 -0
- package/src/aws/lambda.ts +786 -0
- package/src/aws/opensearch.ts +158 -0
- package/src/aws/personalize.ts +977 -0
- package/src/aws/polly.ts +559 -0
- package/src/aws/rds.ts +888 -0
- package/src/aws/rekognition.ts +846 -0
- package/src/aws/route53-domains.ts +359 -0
- package/src/aws/route53.ts +1046 -0
- package/src/aws/s3.ts +2334 -0
- package/src/aws/scheduler.ts +571 -0
- package/src/aws/secrets-manager.ts +769 -0
- package/src/aws/ses.ts +1081 -0
- package/src/aws/setup-phone.ts +104 -0
- package/src/aws/setup-sms.ts +580 -0
- package/src/aws/sms.ts +1735 -0
- package/src/aws/smtp-server.ts +531 -0
- package/src/aws/sns.ts +758 -0
- package/src/aws/sqs.ts +382 -0
- package/src/aws/ssm.ts +807 -0
- package/src/aws/sts.ts +92 -0
- package/src/aws/support.ts +391 -0
- package/src/aws/test-imap.ts +86 -0
- package/src/aws/textract.ts +780 -0
- package/src/aws/transcribe.ts +108 -0
- package/src/aws/translate.ts +641 -0
- package/src/aws/voice.ts +1379 -0
- package/src/config.ts +35 -0
- package/src/deploy/index.ts +7 -0
- package/src/deploy/static-site-external-dns.ts +945 -0
- package/src/deploy/static-site.ts +1175 -0
- package/src/dns/cloudflare.ts +548 -0
- package/src/dns/godaddy.ts +412 -0
- package/src/dns/index.ts +205 -0
- package/src/dns/porkbun.ts +362 -0
- package/src/dns/route53-adapter.ts +414 -0
- package/src/dns/types.ts +119 -0
- package/src/dns/validator.ts +369 -0
- package/src/generators/index.ts +5 -0
- package/src/generators/infrastructure.ts +1660 -0
- package/src/index.ts +163 -0
- package/src/push/apns.ts +452 -0
- package/src/push/fcm.ts +506 -0
- package/src/push/index.ts +58 -0
- package/src/security/pre-deploy-scanner.ts +655 -0
- package/src/ssl/acme-client.ts +478 -0
- package/src/ssl/index.ts +7 -0
- package/src/ssl/letsencrypt.ts +747 -0
- package/src/types.ts +2 -0
- package/src/utils/cli.ts +398 -0
- package/src/validation/index.ts +5 -0
- package/src/validation/template.ts +405 -0
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AWS ElastiCache Operations
|
|
3
|
+
* Direct API calls without AWS CLI dependency
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { AWSClient } from './client'
|
|
7
|
+
|
|
8
|
+
export interface CacheCluster {
|
|
9
|
+
CacheClusterId: string
|
|
10
|
+
CacheClusterStatus: string
|
|
11
|
+
Engine: string
|
|
12
|
+
EngineVersion: string
|
|
13
|
+
CacheNodeType: string
|
|
14
|
+
NumCacheNodes: number
|
|
15
|
+
PreferredAvailabilityZone?: string
|
|
16
|
+
CacheClusterCreateTime: string
|
|
17
|
+
CacheNodes?: Array<{
|
|
18
|
+
CacheNodeId: string
|
|
19
|
+
CacheNodeStatus: string
|
|
20
|
+
Endpoint?: {
|
|
21
|
+
Address: string
|
|
22
|
+
Port: number
|
|
23
|
+
}
|
|
24
|
+
}>
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface ReplicationGroup {
|
|
28
|
+
ReplicationGroupId: string
|
|
29
|
+
Status: string
|
|
30
|
+
Description?: string
|
|
31
|
+
MemberClusters?: string[]
|
|
32
|
+
NodeGroups?: Array<{
|
|
33
|
+
NodeGroupId: string
|
|
34
|
+
Status: string
|
|
35
|
+
PrimaryEndpoint?: {
|
|
36
|
+
Address: string
|
|
37
|
+
Port: number
|
|
38
|
+
}
|
|
39
|
+
}>
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export interface CacheEngineVersion {
|
|
43
|
+
Engine: string
|
|
44
|
+
EngineVersion: string
|
|
45
|
+
CacheParameterGroupFamily: string
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* ElastiCache management using direct API calls
|
|
50
|
+
*/
|
|
51
|
+
export class ElastiCacheClient {
|
|
52
|
+
private client: AWSClient
|
|
53
|
+
private region: string
|
|
54
|
+
|
|
55
|
+
constructor(region: string = 'us-east-1', profile?: string) {
|
|
56
|
+
this.region = region
|
|
57
|
+
this.client = new AWSClient()
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* List all cache clusters
|
|
62
|
+
*/
|
|
63
|
+
async describeCacheClusters(cacheClusterId?: string): Promise<{ CacheClusters: CacheCluster[] }> {
|
|
64
|
+
const params: Record<string, any> = {
|
|
65
|
+
Action: 'DescribeCacheClusters',
|
|
66
|
+
Version: '2015-02-02',
|
|
67
|
+
ShowCacheNodeInfo: 'true',
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (cacheClusterId) {
|
|
71
|
+
params.CacheClusterId = cacheClusterId
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const result = await this.client.request({
|
|
75
|
+
service: 'elasticache',
|
|
76
|
+
region: this.region,
|
|
77
|
+
method: 'POST',
|
|
78
|
+
path: '/',
|
|
79
|
+
body: new URLSearchParams(params).toString(),
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
return { CacheClusters: this.parseCacheClusters(result) }
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* List all replication groups (Redis clusters)
|
|
87
|
+
*/
|
|
88
|
+
async describeReplicationGroups(replicationGroupId?: string): Promise<{ ReplicationGroups: ReplicationGroup[] }> {
|
|
89
|
+
const params: Record<string, any> = {
|
|
90
|
+
Action: 'DescribeReplicationGroups',
|
|
91
|
+
Version: '2015-02-02',
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if (replicationGroupId) {
|
|
95
|
+
params.ReplicationGroupId = replicationGroupId
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const result = await this.client.request({
|
|
99
|
+
service: 'elasticache',
|
|
100
|
+
region: this.region,
|
|
101
|
+
method: 'POST',
|
|
102
|
+
path: '/',
|
|
103
|
+
body: new URLSearchParams(params).toString(),
|
|
104
|
+
})
|
|
105
|
+
|
|
106
|
+
return { ReplicationGroups: [] } // TODO: Parse response
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Create a cache cluster
|
|
111
|
+
*/
|
|
112
|
+
async createCacheCluster(options: {
|
|
113
|
+
cacheClusterId: string
|
|
114
|
+
engine: 'memcached' | 'redis'
|
|
115
|
+
cacheNodeType: string
|
|
116
|
+
numCacheNodes?: number
|
|
117
|
+
engineVersion?: string
|
|
118
|
+
port?: number
|
|
119
|
+
securityGroupIds?: string[]
|
|
120
|
+
subnetGroupName?: string
|
|
121
|
+
tags?: Array<{ Key: string, Value: string }>
|
|
122
|
+
}): Promise<{ CacheCluster: CacheCluster }> {
|
|
123
|
+
const params: Record<string, any> = {
|
|
124
|
+
Action: 'CreateCacheCluster',
|
|
125
|
+
Version: '2015-02-02',
|
|
126
|
+
CacheClusterId: options.cacheClusterId,
|
|
127
|
+
Engine: options.engine,
|
|
128
|
+
CacheNodeType: options.cacheNodeType,
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
if (options.numCacheNodes) {
|
|
132
|
+
params.NumCacheNodes = options.numCacheNodes
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
if (options.engineVersion) {
|
|
136
|
+
params.EngineVersion = options.engineVersion
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
if (options.port) {
|
|
140
|
+
params.Port = options.port
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
if (options.securityGroupIds && options.securityGroupIds.length > 0) {
|
|
144
|
+
options.securityGroupIds.forEach((id, index) => {
|
|
145
|
+
params[`SecurityGroupIds.member.${index + 1}`] = id
|
|
146
|
+
})
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
if (options.subnetGroupName) {
|
|
150
|
+
params.CacheSubnetGroupName = options.subnetGroupName
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
if (options.tags && options.tags.length > 0) {
|
|
154
|
+
options.tags.forEach((tag, index) => {
|
|
155
|
+
params[`Tags.member.${index + 1}.Key`] = tag.Key
|
|
156
|
+
params[`Tags.member.${index + 1}.Value`] = tag.Value
|
|
157
|
+
})
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
const result = await this.client.request({
|
|
161
|
+
service: 'elasticache',
|
|
162
|
+
region: this.region,
|
|
163
|
+
method: 'POST',
|
|
164
|
+
path: '/',
|
|
165
|
+
body: new URLSearchParams(params).toString(),
|
|
166
|
+
})
|
|
167
|
+
|
|
168
|
+
return { CacheCluster: this.parseCacheCluster(result) }
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Delete a cache cluster
|
|
173
|
+
*/
|
|
174
|
+
async deleteCacheCluster(cacheClusterId: string, finalSnapshotId?: string): Promise<void> {
|
|
175
|
+
const params: Record<string, any> = {
|
|
176
|
+
Action: 'DeleteCacheCluster',
|
|
177
|
+
Version: '2015-02-02',
|
|
178
|
+
CacheClusterId: cacheClusterId,
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
if (finalSnapshotId) {
|
|
182
|
+
params.FinalSnapshotIdentifier = finalSnapshotId
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
await this.client.request({
|
|
186
|
+
service: 'elasticache',
|
|
187
|
+
region: this.region,
|
|
188
|
+
method: 'POST',
|
|
189
|
+
path: '/',
|
|
190
|
+
body: new URLSearchParams(params).toString(),
|
|
191
|
+
})
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Reboot cache cluster nodes
|
|
196
|
+
*/
|
|
197
|
+
async rebootCacheCluster(cacheClusterId: string, nodeIds: string[]): Promise<void> {
|
|
198
|
+
const params: Record<string, any> = {
|
|
199
|
+
Action: 'RebootCacheCluster',
|
|
200
|
+
Version: '2015-02-02',
|
|
201
|
+
CacheClusterId: cacheClusterId,
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
nodeIds.forEach((id, index) => {
|
|
205
|
+
params[`CacheNodeIdsToReboot.member.${index + 1}`] = id
|
|
206
|
+
})
|
|
207
|
+
|
|
208
|
+
await this.client.request({
|
|
209
|
+
service: 'elasticache',
|
|
210
|
+
region: this.region,
|
|
211
|
+
method: 'POST',
|
|
212
|
+
path: '/',
|
|
213
|
+
body: new URLSearchParams(params).toString(),
|
|
214
|
+
})
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* List available cache engine versions
|
|
219
|
+
*/
|
|
220
|
+
async describeCacheEngineVersions(engine?: string): Promise<{ CacheEngineVersions: CacheEngineVersion[] }> {
|
|
221
|
+
const params: Record<string, any> = {
|
|
222
|
+
Action: 'DescribeCacheEngineVersions',
|
|
223
|
+
Version: '2015-02-02',
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
if (engine) {
|
|
227
|
+
params.Engine = engine
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
const result = await this.client.request({
|
|
231
|
+
service: 'elasticache',
|
|
232
|
+
region: this.region,
|
|
233
|
+
method: 'POST',
|
|
234
|
+
path: '/',
|
|
235
|
+
body: new URLSearchParams(params).toString(),
|
|
236
|
+
})
|
|
237
|
+
|
|
238
|
+
return { CacheEngineVersions: [] } // TODO: Parse response
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* Get cache cluster statistics (mock for now)
|
|
243
|
+
*/
|
|
244
|
+
async getCacheStatistics(cacheClusterId: string): Promise<{
|
|
245
|
+
cpuUtilization?: number
|
|
246
|
+
evictions?: number
|
|
247
|
+
hits?: number
|
|
248
|
+
misses?: number
|
|
249
|
+
connections?: number
|
|
250
|
+
}> {
|
|
251
|
+
const result = await this.describeCacheClusters(cacheClusterId)
|
|
252
|
+
|
|
253
|
+
if (!result.CacheClusters || result.CacheClusters.length === 0) {
|
|
254
|
+
throw new Error(`Cache cluster ${cacheClusterId} not found`)
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
return {
|
|
258
|
+
// In a real implementation, these would come from CloudWatch metrics
|
|
259
|
+
cpuUtilization: 0,
|
|
260
|
+
evictions: 0,
|
|
261
|
+
hits: 0,
|
|
262
|
+
misses: 0,
|
|
263
|
+
connections: 0,
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* Parse cache clusters from response
|
|
269
|
+
*/
|
|
270
|
+
private parseCacheClusters(result: any): CacheCluster[] {
|
|
271
|
+
// Simplified parser - would need proper XML parsing in production
|
|
272
|
+
if (result.CacheClusterId) {
|
|
273
|
+
return [{
|
|
274
|
+
CacheClusterId: result.CacheClusterId,
|
|
275
|
+
CacheClusterStatus: result.CacheClusterStatus || 'available',
|
|
276
|
+
Engine: result.Engine || 'redis',
|
|
277
|
+
EngineVersion: result.EngineVersion || '7.0',
|
|
278
|
+
CacheNodeType: result.CacheNodeType || 'cache.t3.micro',
|
|
279
|
+
NumCacheNodes: Number.parseInt(result.NumCacheNodes || '1'),
|
|
280
|
+
CacheClusterCreateTime: result.CacheClusterCreateTime || new Date().toISOString(),
|
|
281
|
+
}]
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
return []
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
/**
|
|
288
|
+
* Parse single cache cluster from response
|
|
289
|
+
*/
|
|
290
|
+
private parseCacheCluster(result: any): CacheCluster {
|
|
291
|
+
return {
|
|
292
|
+
CacheClusterId: result.CacheClusterId,
|
|
293
|
+
CacheClusterStatus: result.CacheClusterStatus || 'creating',
|
|
294
|
+
Engine: result.Engine || 'redis',
|
|
295
|
+
EngineVersion: result.EngineVersion || '7.0',
|
|
296
|
+
CacheNodeType: result.CacheNodeType || 'cache.t3.micro',
|
|
297
|
+
NumCacheNodes: Number.parseInt(result.NumCacheNodes || '1'),
|
|
298
|
+
CacheClusterCreateTime: result.CacheClusterCreateTime || new Date().toISOString(),
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
}
|