@stacksjs/ts-cloud 0.1.7 → 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.
Files changed (77) hide show
  1. package/dist/aws/s3.d.ts +1 -1
  2. package/dist/bin/cli.js +223 -222
  3. package/dist/index.js +132 -132
  4. package/package.json +18 -16
  5. package/src/aws/acm.ts +768 -0
  6. package/src/aws/application-autoscaling.ts +845 -0
  7. package/src/aws/bedrock.ts +4074 -0
  8. package/src/aws/client.ts +891 -0
  9. package/src/aws/cloudformation.ts +896 -0
  10. package/src/aws/cloudfront.ts +1531 -0
  11. package/src/aws/cloudwatch-logs.ts +154 -0
  12. package/src/aws/comprehend.ts +839 -0
  13. package/src/aws/connect.ts +1056 -0
  14. package/src/aws/deploy-imap.ts +384 -0
  15. package/src/aws/dynamodb.ts +340 -0
  16. package/src/aws/ec2.ts +1385 -0
  17. package/src/aws/ecr.ts +621 -0
  18. package/src/aws/ecs.ts +615 -0
  19. package/src/aws/elasticache.ts +301 -0
  20. package/src/aws/elbv2.ts +942 -0
  21. package/src/aws/email.ts +928 -0
  22. package/src/aws/eventbridge.ts +248 -0
  23. package/src/aws/iam.ts +1689 -0
  24. package/src/aws/imap-server.ts +2100 -0
  25. package/src/aws/index.ts +213 -0
  26. package/src/aws/kendra.ts +1097 -0
  27. package/src/aws/lambda.ts +786 -0
  28. package/src/aws/opensearch.ts +158 -0
  29. package/src/aws/personalize.ts +977 -0
  30. package/src/aws/polly.ts +559 -0
  31. package/src/aws/rds.ts +888 -0
  32. package/src/aws/rekognition.ts +846 -0
  33. package/src/aws/route53-domains.ts +359 -0
  34. package/src/aws/route53.ts +1046 -0
  35. package/src/aws/s3.ts +2334 -0
  36. package/src/aws/scheduler.ts +571 -0
  37. package/src/aws/secrets-manager.ts +769 -0
  38. package/src/aws/ses.ts +1081 -0
  39. package/src/aws/setup-phone.ts +104 -0
  40. package/src/aws/setup-sms.ts +580 -0
  41. package/src/aws/sms.ts +1735 -0
  42. package/src/aws/smtp-server.ts +531 -0
  43. package/src/aws/sns.ts +758 -0
  44. package/src/aws/sqs.ts +382 -0
  45. package/src/aws/ssm.ts +807 -0
  46. package/src/aws/sts.ts +92 -0
  47. package/src/aws/support.ts +391 -0
  48. package/src/aws/test-imap.ts +86 -0
  49. package/src/aws/textract.ts +780 -0
  50. package/src/aws/transcribe.ts +108 -0
  51. package/src/aws/translate.ts +641 -0
  52. package/src/aws/voice.ts +1379 -0
  53. package/src/config.ts +35 -0
  54. package/src/deploy/index.ts +7 -0
  55. package/src/deploy/static-site-external-dns.ts +945 -0
  56. package/src/deploy/static-site.ts +1175 -0
  57. package/src/dns/cloudflare.ts +548 -0
  58. package/src/dns/godaddy.ts +412 -0
  59. package/src/dns/index.ts +205 -0
  60. package/src/dns/porkbun.ts +362 -0
  61. package/src/dns/route53-adapter.ts +414 -0
  62. package/src/dns/types.ts +119 -0
  63. package/src/dns/validator.ts +369 -0
  64. package/src/generators/index.ts +5 -0
  65. package/src/generators/infrastructure.ts +1660 -0
  66. package/src/index.ts +163 -0
  67. package/src/push/apns.ts +452 -0
  68. package/src/push/fcm.ts +506 -0
  69. package/src/push/index.ts +58 -0
  70. package/src/security/pre-deploy-scanner.ts +655 -0
  71. package/src/ssl/acme-client.ts +478 -0
  72. package/src/ssl/index.ts +7 -0
  73. package/src/ssl/letsencrypt.ts +747 -0
  74. package/src/types.ts +2 -0
  75. package/src/utils/cli.ts +398 -0
  76. package/src/validation/index.ts +5 -0
  77. package/src/validation/template.ts +405 -0
@@ -0,0 +1,571 @@
1
+ /**
2
+ * AWS EventBridge Scheduler Operations
3
+ * Direct API calls without AWS CLI dependency
4
+ */
5
+
6
+ import { AWSClient } from './client'
7
+
8
+ export interface Schedule {
9
+ Name: string
10
+ Arn?: string
11
+ State?: 'ENABLED' | 'DISABLED'
12
+ ScheduleExpression?: string
13
+ ScheduleExpressionTimezone?: string
14
+ Target?: {
15
+ Arn: string
16
+ RoleArn: string
17
+ Input?: string
18
+ }
19
+ FlexibleTimeWindow?: {
20
+ Mode: 'OFF' | 'FLEXIBLE'
21
+ MaximumWindowInMinutes?: number
22
+ }
23
+ GroupName?: string
24
+ Description?: string
25
+ StartDate?: string
26
+ EndDate?: string
27
+ CreationDate?: string
28
+ LastModificationDate?: string
29
+ }
30
+
31
+ export interface CreateScheduleInput {
32
+ Name: string
33
+ GroupName?: string
34
+ ScheduleExpression: string
35
+ ScheduleExpressionTimezone?: string
36
+ Description?: string
37
+ State?: 'ENABLED' | 'DISABLED'
38
+ FlexibleTimeWindow: {
39
+ Mode: 'OFF' | 'FLEXIBLE'
40
+ MaximumWindowInMinutes?: number
41
+ }
42
+ Target: {
43
+ Arn: string
44
+ RoleArn: string
45
+ Input?: string
46
+ }
47
+ StartDate?: Date
48
+ EndDate?: Date
49
+ }
50
+
51
+ export interface UpdateScheduleInput {
52
+ Name: string
53
+ GroupName?: string
54
+ ScheduleExpression?: string
55
+ ScheduleExpressionTimezone?: string
56
+ Description?: string
57
+ State?: 'ENABLED' | 'DISABLED'
58
+ FlexibleTimeWindow?: {
59
+ Mode: 'OFF' | 'FLEXIBLE'
60
+ MaximumWindowInMinutes?: number
61
+ }
62
+ Target?: {
63
+ Arn: string
64
+ RoleArn: string
65
+ Input?: string
66
+ }
67
+ }
68
+
69
+ export interface ScheduleGroup {
70
+ Name: string
71
+ Arn?: string
72
+ State?: string
73
+ CreationDate?: string
74
+ LastModificationDate?: string
75
+ }
76
+
77
+ export interface CreateScheduleOptions {
78
+ name: string
79
+ scheduleExpression: string
80
+ targetArn: string
81
+ roleArn: string
82
+ input?: string
83
+ groupName?: string
84
+ state?: 'ENABLED' | 'DISABLED'
85
+ description?: string
86
+ flexibleTimeWindow?: {
87
+ mode: 'OFF' | 'FLEXIBLE'
88
+ maxWindowMinutes?: number
89
+ }
90
+ }
91
+
92
+ export interface SchedulerRule {
93
+ Name: string
94
+ Arn: string
95
+ EventPattern?: string
96
+ ScheduleExpression?: string
97
+ State: 'ENABLED' | 'DISABLED'
98
+ Description?: string
99
+ }
100
+
101
+ export interface SchedulerTarget {
102
+ Id: string
103
+ Arn: string
104
+ RoleArn?: string
105
+ Input?: string
106
+ InputPath?: string
107
+ }
108
+
109
+ /**
110
+ * EventBridge Scheduler management using direct API calls
111
+ */
112
+ export class SchedulerClient {
113
+ private client: AWSClient
114
+ private region: string
115
+
116
+ constructor(region: string = 'us-east-1', profile?: string) {
117
+ this.region = region
118
+ this.client = new AWSClient()
119
+ }
120
+
121
+ /**
122
+ * Create a new schedule (EventBridge rule)
123
+ */
124
+ async createRule(options: {
125
+ name: string
126
+ scheduleExpression: string
127
+ description?: string
128
+ state?: 'ENABLED' | 'DISABLED'
129
+ }): Promise<{ RuleArn: string }> {
130
+ const params: Record<string, any> = {
131
+ Action: 'PutRule',
132
+ Name: options.name,
133
+ ScheduleExpression: options.scheduleExpression,
134
+ Version: '2015-10-07',
135
+ }
136
+
137
+ if (options.description) {
138
+ params.Description = options.description
139
+ }
140
+
141
+ if (options.state) {
142
+ params.State = options.state
143
+ }
144
+ else {
145
+ params.State = 'ENABLED'
146
+ }
147
+
148
+ const result = await this.client.request({
149
+ service: 'events',
150
+ region: this.region,
151
+ method: 'POST',
152
+ path: '/',
153
+ headers: {
154
+ 'X-Amz-Target': 'AWSEvents.PutRule',
155
+ 'Content-Type': 'application/x-amz-json-1.1',
156
+ },
157
+ body: JSON.stringify({
158
+ Name: options.name,
159
+ ScheduleExpression: options.scheduleExpression,
160
+ State: options.state || 'ENABLED',
161
+ Description: options.description,
162
+ }),
163
+ })
164
+
165
+ return { RuleArn: result.RuleArn }
166
+ }
167
+
168
+ /**
169
+ * Add target to a rule
170
+ */
171
+ async putTargets(ruleName: string, targets: SchedulerTarget[]): Promise<void> {
172
+ await this.client.request({
173
+ service: 'events',
174
+ region: this.region,
175
+ method: 'POST',
176
+ path: '/',
177
+ headers: {
178
+ 'X-Amz-Target': 'AWSEvents.PutTargets',
179
+ 'Content-Type': 'application/x-amz-json-1.1',
180
+ },
181
+ body: JSON.stringify({
182
+ Rule: ruleName,
183
+ Targets: targets,
184
+ }),
185
+ })
186
+ }
187
+
188
+ /**
189
+ * List all rules
190
+ */
191
+ async listRules(namePrefix?: string): Promise<{ Rules: SchedulerRule[] }> {
192
+ const payload: any = {}
193
+
194
+ if (namePrefix) {
195
+ payload.NamePrefix = namePrefix
196
+ }
197
+
198
+ const result = await this.client.request({
199
+ service: 'events',
200
+ region: this.region,
201
+ method: 'POST',
202
+ path: '/',
203
+ headers: {
204
+ 'X-Amz-Target': 'AWSEvents.ListRules',
205
+ 'Content-Type': 'application/x-amz-json-1.1',
206
+ },
207
+ body: JSON.stringify(payload),
208
+ })
209
+
210
+ return { Rules: result.Rules || [] }
211
+ }
212
+
213
+ /**
214
+ * Describe a rule
215
+ */
216
+ async describeRule(name: string): Promise<SchedulerRule> {
217
+ const result = await this.client.request({
218
+ service: 'events',
219
+ region: this.region,
220
+ method: 'POST',
221
+ path: '/',
222
+ headers: {
223
+ 'X-Amz-Target': 'AWSEvents.DescribeRule',
224
+ 'Content-Type': 'application/x-amz-json-1.1',
225
+ },
226
+ body: JSON.stringify({
227
+ Name: name,
228
+ }),
229
+ })
230
+
231
+ return {
232
+ Name: result.Name,
233
+ Arn: result.Arn,
234
+ ScheduleExpression: result.ScheduleExpression,
235
+ State: result.State,
236
+ Description: result.Description,
237
+ }
238
+ }
239
+
240
+ /**
241
+ * List targets for a rule
242
+ */
243
+ async listTargetsByRule(ruleName: string): Promise<{ Targets: SchedulerTarget[] }> {
244
+ const result = await this.client.request({
245
+ service: 'events',
246
+ region: this.region,
247
+ method: 'POST',
248
+ path: '/',
249
+ headers: {
250
+ 'X-Amz-Target': 'AWSEvents.ListTargetsByRule',
251
+ 'Content-Type': 'application/x-amz-json-1.1',
252
+ },
253
+ body: JSON.stringify({
254
+ Rule: ruleName,
255
+ }),
256
+ })
257
+
258
+ return { Targets: result.Targets || [] }
259
+ }
260
+
261
+ /**
262
+ * Delete a rule
263
+ */
264
+ async deleteRule(name: string, force?: boolean): Promise<void> {
265
+ // First, remove all targets
266
+ if (force) {
267
+ try {
268
+ const targets = await this.listTargetsByRule(name)
269
+ if (targets.Targets && targets.Targets.length > 0) {
270
+ await this.removeTargets(name, targets.Targets.map(t => t.Id))
271
+ }
272
+ }
273
+ catch {
274
+ // Ignore errors when removing targets
275
+ }
276
+ }
277
+
278
+ await this.client.request({
279
+ service: 'events',
280
+ region: this.region,
281
+ method: 'POST',
282
+ path: '/',
283
+ headers: {
284
+ 'X-Amz-Target': 'AWSEvents.DeleteRule',
285
+ 'Content-Type': 'application/x-amz-json-1.1',
286
+ },
287
+ body: JSON.stringify({
288
+ Name: name,
289
+ Force: force || false,
290
+ }),
291
+ })
292
+ }
293
+
294
+ /**
295
+ * Remove targets from a rule
296
+ */
297
+ async removeTargets(ruleName: string, targetIds: string[]): Promise<void> {
298
+ await this.client.request({
299
+ service: 'events',
300
+ region: this.region,
301
+ method: 'POST',
302
+ path: '/',
303
+ headers: {
304
+ 'X-Amz-Target': 'AWSEvents.RemoveTargets',
305
+ 'Content-Type': 'application/x-amz-json-1.1',
306
+ },
307
+ body: JSON.stringify({
308
+ Rule: ruleName,
309
+ Ids: targetIds,
310
+ }),
311
+ })
312
+ }
313
+
314
+ /**
315
+ * Enable a rule
316
+ */
317
+ async enableRule(name: string): Promise<void> {
318
+ await this.client.request({
319
+ service: 'events',
320
+ region: this.region,
321
+ method: 'POST',
322
+ path: '/',
323
+ headers: {
324
+ 'X-Amz-Target': 'AWSEvents.EnableRule',
325
+ 'Content-Type': 'application/x-amz-json-1.1',
326
+ },
327
+ body: JSON.stringify({
328
+ Name: name,
329
+ }),
330
+ })
331
+ }
332
+
333
+ /**
334
+ * Disable a rule
335
+ */
336
+ async disableRule(name: string): Promise<void> {
337
+ await this.client.request({
338
+ service: 'events',
339
+ region: this.region,
340
+ method: 'POST',
341
+ path: '/',
342
+ headers: {
343
+ 'X-Amz-Target': 'AWSEvents.DisableRule',
344
+ 'Content-Type': 'application/x-amz-json-1.1',
345
+ },
346
+ body: JSON.stringify({
347
+ Name: name,
348
+ }),
349
+ })
350
+ }
351
+
352
+ /**
353
+ * Create a Lambda-triggered schedule
354
+ */
355
+ async createLambdaSchedule(options: {
356
+ name: string
357
+ scheduleExpression: string
358
+ functionArn: string
359
+ description?: string
360
+ input?: string
361
+ }): Promise<{ RuleArn: string }> {
362
+ // Create the rule
363
+ const rule = await this.createRule({
364
+ name: options.name,
365
+ scheduleExpression: options.scheduleExpression,
366
+ description: options.description,
367
+ state: 'ENABLED',
368
+ })
369
+
370
+ // Add Lambda as target
371
+ await this.putTargets(options.name, [
372
+ {
373
+ Id: '1',
374
+ Arn: options.functionArn,
375
+ Input: options.input,
376
+ },
377
+ ])
378
+
379
+ return rule
380
+ }
381
+
382
+ /**
383
+ * Create an ECS task schedule
384
+ */
385
+ async createEcsSchedule(options: {
386
+ name: string
387
+ scheduleExpression: string
388
+ clusterArn: string
389
+ taskDefinitionArn: string
390
+ roleArn: string
391
+ subnets: string[]
392
+ securityGroups?: string[]
393
+ description?: string
394
+ }): Promise<{ RuleArn: string }> {
395
+ // Create the rule
396
+ const rule = await this.createRule({
397
+ name: options.name,
398
+ scheduleExpression: options.scheduleExpression,
399
+ description: options.description,
400
+ state: 'ENABLED',
401
+ })
402
+
403
+ // Add ECS task as target
404
+ await this.putTargets(options.name, [
405
+ {
406
+ Id: '1',
407
+ Arn: options.clusterArn,
408
+ RoleArn: options.roleArn,
409
+ Input: JSON.stringify({
410
+ containerOverrides: [],
411
+ }),
412
+ },
413
+ ])
414
+
415
+ return rule
416
+ }
417
+
418
+ // ─── EventBridge Scheduler API methods ─────────────────────────────
419
+
420
+ /**
421
+ * List schedules (EventBridge Scheduler API)
422
+ */
423
+ async listSchedules(options?: { GroupName?: string; NamePrefix?: string; State?: string }): Promise<{ Schedules: Schedule[] }> {
424
+ const queryParams: Record<string, string> = {}
425
+ if (options?.NamePrefix) {
426
+ queryParams.NamePrefix = options.NamePrefix
427
+ }
428
+ if (options?.State) {
429
+ queryParams.State = options.State
430
+ }
431
+
432
+ const groupName = options?.GroupName || 'default'
433
+ const result = await this.client.request({
434
+ service: 'scheduler',
435
+ region: this.region,
436
+ method: 'GET',
437
+ path: `/schedules`,
438
+ queryParams: {
439
+ ...queryParams,
440
+ ScheduleGroup: groupName,
441
+ },
442
+ })
443
+
444
+ return { Schedules: result?.Schedules || [] }
445
+ }
446
+
447
+ /**
448
+ * Get a schedule by name (EventBridge Scheduler API)
449
+ */
450
+ async getSchedule(options: { Name: string; GroupName?: string }): Promise<Schedule | null> {
451
+ try {
452
+ const queryParams: Record<string, string> = {}
453
+ if (options.GroupName) {
454
+ queryParams.groupName = options.GroupName
455
+ }
456
+
457
+ const result = await this.client.request({
458
+ service: 'scheduler',
459
+ region: this.region,
460
+ method: 'GET',
461
+ path: `/schedules/${encodeURIComponent(options.Name)}`,
462
+ queryParams: Object.keys(queryParams).length > 0 ? queryParams : undefined,
463
+ })
464
+
465
+ return result as Schedule
466
+ }
467
+ catch (error: any) {
468
+ if (error.statusCode === 404 || error.code === 'ResourceNotFoundException') {
469
+ return null
470
+ }
471
+ throw error
472
+ }
473
+ }
474
+
475
+ /**
476
+ * Create a schedule (EventBridge Scheduler API)
477
+ */
478
+ async createSchedule(input: CreateScheduleInput): Promise<{ ScheduleArn: string }> {
479
+ const body: Record<string, any> = {
480
+ ScheduleExpression: input.ScheduleExpression,
481
+ FlexibleTimeWindow: input.FlexibleTimeWindow,
482
+ Target: input.Target,
483
+ }
484
+
485
+ if (input.GroupName) body.GroupName = input.GroupName
486
+ if (input.ScheduleExpressionTimezone) body.ScheduleExpressionTimezone = input.ScheduleExpressionTimezone
487
+ if (input.Description) body.Description = input.Description
488
+ if (input.State) body.State = input.State
489
+ if (input.StartDate) body.StartDate = input.StartDate.toISOString()
490
+ if (input.EndDate) body.EndDate = input.EndDate.toISOString()
491
+
492
+ const result = await this.client.request({
493
+ service: 'scheduler',
494
+ region: this.region,
495
+ method: 'POST',
496
+ path: `/schedules/${encodeURIComponent(input.Name)}`,
497
+ headers: {
498
+ 'Content-Type': 'application/json',
499
+ },
500
+ body: JSON.stringify(body),
501
+ })
502
+
503
+ return { ScheduleArn: result?.ScheduleArn || '' }
504
+ }
505
+
506
+ /**
507
+ * Update a schedule (EventBridge Scheduler API)
508
+ */
509
+ async updateSchedule(input: UpdateScheduleInput): Promise<{ ScheduleArn: string }> {
510
+ const body: Record<string, any> = {}
511
+
512
+ if (input.GroupName) body.GroupName = input.GroupName
513
+ if (input.ScheduleExpression) body.ScheduleExpression = input.ScheduleExpression
514
+ if (input.ScheduleExpressionTimezone) body.ScheduleExpressionTimezone = input.ScheduleExpressionTimezone
515
+ if (input.Description !== undefined) body.Description = input.Description
516
+ if (input.State) body.State = input.State
517
+ if (input.FlexibleTimeWindow) body.FlexibleTimeWindow = input.FlexibleTimeWindow
518
+ if (input.Target) body.Target = input.Target
519
+
520
+ const result = await this.client.request({
521
+ service: 'scheduler',
522
+ region: this.region,
523
+ method: 'PUT',
524
+ path: `/schedules/${encodeURIComponent(input.Name)}`,
525
+ headers: {
526
+ 'Content-Type': 'application/json',
527
+ },
528
+ body: JSON.stringify(body),
529
+ })
530
+
531
+ return { ScheduleArn: result?.ScheduleArn || '' }
532
+ }
533
+
534
+ /**
535
+ * Delete a schedule (EventBridge Scheduler API)
536
+ */
537
+ async deleteSchedule(options: { Name: string; GroupName?: string }): Promise<void> {
538
+ const queryParams: Record<string, string> = {}
539
+ if (options.GroupName) {
540
+ queryParams.groupName = options.GroupName
541
+ }
542
+
543
+ await this.client.request({
544
+ service: 'scheduler',
545
+ region: this.region,
546
+ method: 'DELETE',
547
+ path: `/schedules/${encodeURIComponent(options.Name)}`,
548
+ queryParams: Object.keys(queryParams).length > 0 ? queryParams : undefined,
549
+ })
550
+ }
551
+
552
+ /**
553
+ * List schedule groups (EventBridge Scheduler API)
554
+ */
555
+ async listScheduleGroups(options?: { NamePrefix?: string }): Promise<{ ScheduleGroups: ScheduleGroup[] }> {
556
+ const queryParams: Record<string, string> = {}
557
+ if (options?.NamePrefix) {
558
+ queryParams.NamePrefix = options.NamePrefix
559
+ }
560
+
561
+ const result = await this.client.request({
562
+ service: 'scheduler',
563
+ region: this.region,
564
+ method: 'GET',
565
+ path: '/schedule-groups',
566
+ queryParams: Object.keys(queryParams).length > 0 ? queryParams : undefined,
567
+ })
568
+
569
+ return { ScheduleGroups: result?.ScheduleGroups || [] }
570
+ }
571
+ }