@stacksjs/ts-cloud-core 0.1.1
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/LICENSE.md +21 -0
- package/README.md +321 -0
- package/package.json +31 -0
- package/src/advanced-features.test.ts +465 -0
- package/src/aws/cloudformation.ts +421 -0
- package/src/aws/cloudfront.ts +158 -0
- package/src/aws/credentials.test.ts +132 -0
- package/src/aws/credentials.ts +545 -0
- package/src/aws/index.ts +87 -0
- package/src/aws/s3.test.ts +188 -0
- package/src/aws/s3.ts +1088 -0
- package/src/aws/signature.test.ts +670 -0
- package/src/aws/signature.ts +1155 -0
- package/src/backup/disaster-recovery.test.ts +726 -0
- package/src/backup/disaster-recovery.ts +500 -0
- package/src/backup/index.ts +34 -0
- package/src/backup/manager.test.ts +498 -0
- package/src/backup/manager.ts +432 -0
- package/src/cicd/circleci.ts +430 -0
- package/src/cicd/github-actions.ts +424 -0
- package/src/cicd/gitlab-ci.ts +255 -0
- package/src/cicd/index.ts +8 -0
- package/src/cli/history.ts +396 -0
- package/src/cli/index.ts +10 -0
- package/src/cli/progress.ts +458 -0
- package/src/cli/repl.ts +454 -0
- package/src/cli/suggestions.ts +327 -0
- package/src/cli/table.test.ts +319 -0
- package/src/cli/table.ts +332 -0
- package/src/cloudformation/builder.test.ts +327 -0
- package/src/cloudformation/builder.ts +378 -0
- package/src/cloudformation/builders/api-gateway.ts +449 -0
- package/src/cloudformation/builders/cache.ts +334 -0
- package/src/cloudformation/builders/cdn.ts +278 -0
- package/src/cloudformation/builders/compute.ts +485 -0
- package/src/cloudformation/builders/database.ts +392 -0
- package/src/cloudformation/builders/functions.ts +343 -0
- package/src/cloudformation/builders/messaging.ts +140 -0
- package/src/cloudformation/builders/monitoring.ts +300 -0
- package/src/cloudformation/builders/network.ts +264 -0
- package/src/cloudformation/builders/queue.ts +147 -0
- package/src/cloudformation/builders/security.ts +399 -0
- package/src/cloudformation/builders/storage.ts +285 -0
- package/src/cloudformation/index.ts +30 -0
- package/src/cloudformation/types.ts +173 -0
- package/src/compliance/aws-config.ts +543 -0
- package/src/compliance/cloudtrail.ts +376 -0
- package/src/compliance/compliance.test.ts +423 -0
- package/src/compliance/guardduty.ts +446 -0
- package/src/compliance/index.ts +66 -0
- package/src/compliance/security-hub.ts +456 -0
- package/src/containers/build-optimization.ts +416 -0
- package/src/containers/containers.test.ts +508 -0
- package/src/containers/image-scanning.ts +360 -0
- package/src/containers/index.ts +9 -0
- package/src/containers/registry.ts +293 -0
- package/src/containers/service-mesh.ts +520 -0
- package/src/database/database.test.ts +762 -0
- package/src/database/index.ts +9 -0
- package/src/database/migrations.ts +444 -0
- package/src/database/performance.ts +528 -0
- package/src/database/replicas.ts +534 -0
- package/src/database/users.ts +494 -0
- package/src/dependency-graph.ts +143 -0
- package/src/deployment/ab-testing.ts +582 -0
- package/src/deployment/blue-green.ts +452 -0
- package/src/deployment/canary.ts +500 -0
- package/src/deployment/deployment.test.ts +526 -0
- package/src/deployment/index.ts +61 -0
- package/src/deployment/progressive.ts +62 -0
- package/src/dns/dns.test.ts +641 -0
- package/src/dns/dnssec.ts +315 -0
- package/src/dns/index.ts +8 -0
- package/src/dns/resolver.ts +496 -0
- package/src/dns/routing.ts +593 -0
- package/src/email/advanced/analytics.ts +445 -0
- package/src/email/advanced/index.ts +11 -0
- package/src/email/advanced/rules.ts +465 -0
- package/src/email/advanced/scheduling.ts +352 -0
- package/src/email/advanced/search.ts +412 -0
- package/src/email/advanced/shared-mailboxes.ts +404 -0
- package/src/email/advanced/templates.ts +455 -0
- package/src/email/advanced/threading.ts +281 -0
- package/src/email/analytics.ts +467 -0
- package/src/email/bounce-handling.ts +425 -0
- package/src/email/email.test.ts +431 -0
- package/src/email/handlers/__tests__/inbound.test.ts +38 -0
- package/src/email/handlers/__tests__/outbound.test.ts +37 -0
- package/src/email/handlers/converter.ts +227 -0
- package/src/email/handlers/feedback.ts +228 -0
- package/src/email/handlers/inbound.ts +169 -0
- package/src/email/handlers/outbound.ts +178 -0
- package/src/email/index.ts +15 -0
- package/src/email/reputation.ts +303 -0
- package/src/email/templates.ts +352 -0
- package/src/errors/index.test.ts +434 -0
- package/src/errors/index.ts +416 -0
- package/src/health-checks/index.ts +40 -0
- package/src/index.ts +360 -0
- package/src/intrinsic-functions.ts +118 -0
- package/src/lambda/concurrency.ts +330 -0
- package/src/lambda/destinations.ts +345 -0
- package/src/lambda/dlq.ts +425 -0
- package/src/lambda/index.ts +11 -0
- package/src/lambda/lambda.test.ts +840 -0
- package/src/lambda/layers.ts +263 -0
- package/src/lambda/versions.ts +376 -0
- package/src/lambda/vpc.ts +399 -0
- package/src/local/config.ts +114 -0
- package/src/local/index.ts +6 -0
- package/src/local/mock-aws.ts +351 -0
- package/src/modules/ai.ts +340 -0
- package/src/modules/api.ts +478 -0
- package/src/modules/auth.ts +805 -0
- package/src/modules/cache.ts +417 -0
- package/src/modules/cdn.ts +1062 -0
- package/src/modules/communication.ts +1094 -0
- package/src/modules/compute.ts +3348 -0
- package/src/modules/database.ts +554 -0
- package/src/modules/deployment.ts +1079 -0
- package/src/modules/dns.ts +337 -0
- package/src/modules/email.ts +1538 -0
- package/src/modules/filesystem.ts +515 -0
- package/src/modules/index.ts +32 -0
- package/src/modules/messaging.ts +486 -0
- package/src/modules/monitoring.ts +2086 -0
- package/src/modules/network.ts +664 -0
- package/src/modules/parameter-store.ts +325 -0
- package/src/modules/permissions.ts +1081 -0
- package/src/modules/phone.ts +494 -0
- package/src/modules/queue.ts +1260 -0
- package/src/modules/redirects.ts +464 -0
- package/src/modules/registry.ts +699 -0
- package/src/modules/search.ts +401 -0
- package/src/modules/secrets.ts +416 -0
- package/src/modules/security.ts +731 -0
- package/src/modules/sms.ts +389 -0
- package/src/modules/storage.ts +1120 -0
- package/src/modules/workflow.ts +680 -0
- package/src/multi-account/config.ts +521 -0
- package/src/multi-account/index.ts +7 -0
- package/src/multi-account/manager.ts +427 -0
- package/src/multi-region/cross-region.ts +410 -0
- package/src/multi-region/index.ts +8 -0
- package/src/multi-region/manager.ts +483 -0
- package/src/multi-region/regions.ts +435 -0
- package/src/network-security/index.ts +48 -0
- package/src/observability/index.ts +9 -0
- package/src/observability/logs.ts +522 -0
- package/src/observability/metrics.ts +460 -0
- package/src/observability/observability.test.ts +782 -0
- package/src/observability/synthetics.ts +568 -0
- package/src/observability/xray.ts +358 -0
- package/src/phone/advanced/analytics.ts +349 -0
- package/src/phone/advanced/callbacks.ts +428 -0
- package/src/phone/advanced/index.ts +8 -0
- package/src/phone/advanced/ivr-builder.ts +504 -0
- package/src/phone/advanced/recording.ts +310 -0
- package/src/phone/handlers/__tests__/incoming-call.test.ts +40 -0
- package/src/phone/handlers/incoming-call.ts +117 -0
- package/src/phone/handlers/missed-call.ts +116 -0
- package/src/phone/handlers/voicemail.ts +179 -0
- package/src/phone/index.ts +9 -0
- package/src/presets/api-backend.ts +134 -0
- package/src/presets/data-pipeline.ts +204 -0
- package/src/presets/extend.test.ts +295 -0
- package/src/presets/extend.ts +297 -0
- package/src/presets/fullstack-app.ts +144 -0
- package/src/presets/index.ts +27 -0
- package/src/presets/jamstack.ts +135 -0
- package/src/presets/microservices.ts +167 -0
- package/src/presets/ml-api.ts +208 -0
- package/src/presets/nodejs-server.ts +104 -0
- package/src/presets/nodejs-serverless.ts +114 -0
- package/src/presets/realtime-app.ts +184 -0
- package/src/presets/static-site.ts +64 -0
- package/src/presets/traditional-web-app.ts +339 -0
- package/src/presets/wordpress.ts +138 -0
- package/src/preview/github.test.ts +249 -0
- package/src/preview/github.ts +297 -0
- package/src/preview/index.ts +37 -0
- package/src/preview/manager.test.ts +440 -0
- package/src/preview/manager.ts +326 -0
- package/src/preview/notifications.test.ts +582 -0
- package/src/preview/notifications.ts +341 -0
- package/src/queue/batch-processing.ts +402 -0
- package/src/queue/dlq-monitoring.ts +402 -0
- package/src/queue/fifo.ts +342 -0
- package/src/queue/index.ts +9 -0
- package/src/queue/management.ts +428 -0
- package/src/queue/queue.test.ts +429 -0
- package/src/resource-mgmt/index.ts +39 -0
- package/src/resource-naming.ts +62 -0
- package/src/s3/index.ts +523 -0
- package/src/schema/cloud-config.schema.json +554 -0
- package/src/schema/index.ts +68 -0
- package/src/security/certificate-manager.ts +492 -0
- package/src/security/index.ts +9 -0
- package/src/security/scanning.ts +545 -0
- package/src/security/secrets-manager.ts +476 -0
- package/src/security/secrets-rotation.ts +456 -0
- package/src/security/security.test.ts +738 -0
- package/src/sms/advanced/ab-testing.ts +389 -0
- package/src/sms/advanced/analytics.ts +336 -0
- package/src/sms/advanced/campaigns.ts +523 -0
- package/src/sms/advanced/chatbot.ts +224 -0
- package/src/sms/advanced/index.ts +10 -0
- package/src/sms/advanced/link-tracking.ts +248 -0
- package/src/sms/advanced/mms.ts +308 -0
- package/src/sms/handlers/__tests__/send.test.ts +40 -0
- package/src/sms/handlers/delivery-status.ts +133 -0
- package/src/sms/handlers/receive.ts +162 -0
- package/src/sms/handlers/send.ts +174 -0
- package/src/sms/index.ts +9 -0
- package/src/stack-diff.ts +389 -0
- package/src/static-site/index.ts +85 -0
- package/src/template-builder.ts +110 -0
- package/src/template-validator.ts +574 -0
- package/src/utils/cache.ts +291 -0
- package/src/utils/diff.ts +269 -0
- package/src/utils/hash.ts +227 -0
- package/src/utils/index.ts +8 -0
- package/src/utils/parallel.ts +294 -0
- package/src/validators/credentials.test.ts +274 -0
- package/src/validators/credentials.ts +233 -0
- package/src/validators/quotas.test.ts +434 -0
- package/src/validators/quotas.ts +217 -0
- package/test/ai.test.ts +327 -0
- package/test/api.test.ts +511 -0
- package/test/auth.test.ts +632 -0
- package/test/cache.test.ts +406 -0
- package/test/cdn.test.ts +247 -0
- package/test/compute.test.ts +861 -0
- package/test/database.test.ts +523 -0
- package/test/deployment.test.ts +499 -0
- package/test/dns.test.ts +270 -0
- package/test/email.test.ts +439 -0
- package/test/filesystem.test.ts +382 -0
- package/test/integration.test.ts +350 -0
- package/test/messaging.test.ts +514 -0
- package/test/monitoring.test.ts +634 -0
- package/test/network.test.ts +425 -0
- package/test/permissions.test.ts +488 -0
- package/test/queue.test.ts +484 -0
- package/test/registry.test.ts +306 -0
- package/test/security.test.ts +462 -0
- package/test/storage.test.ts +463 -0
- package/test/template-validator.test.ts +559 -0
- package/test/workflow.test.ts +592 -0
- package/tsconfig.json +16 -0
- package/tsconfig.tsbuildinfo +1 -0
|
@@ -0,0 +1,326 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Preview Environment Manager
|
|
3
|
+
* Manages ephemeral environments for PR previews
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { CloudConfig } from '@stacksjs/ts-cloud-types'
|
|
7
|
+
|
|
8
|
+
export interface PreviewEnvironment {
|
|
9
|
+
id: string
|
|
10
|
+
name: string
|
|
11
|
+
branch: string
|
|
12
|
+
pr?: number
|
|
13
|
+
commitSha: string
|
|
14
|
+
createdAt: Date
|
|
15
|
+
expiresAt: Date
|
|
16
|
+
url?: string
|
|
17
|
+
status: 'creating' | 'active' | 'failed' | 'destroying' | 'destroyed'
|
|
18
|
+
stackName: string
|
|
19
|
+
region: string
|
|
20
|
+
resources: string[]
|
|
21
|
+
cost?: number
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface PreviewEnvironmentOptions {
|
|
25
|
+
branch: string
|
|
26
|
+
pr?: number
|
|
27
|
+
commitSha: string
|
|
28
|
+
ttl?: number // Time to live in hours
|
|
29
|
+
baseConfig: CloudConfig
|
|
30
|
+
region?: string
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export interface PreviewCleanupOptions {
|
|
34
|
+
maxAge?: number // Max age in hours
|
|
35
|
+
keepCount?: number // Keep N most recent environments
|
|
36
|
+
dryRun?: boolean
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Preview Environment Manager
|
|
41
|
+
*/
|
|
42
|
+
export class PreviewEnvironmentManager {
|
|
43
|
+
private environments: Map<string, PreviewEnvironment> = new Map()
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Create a new preview environment
|
|
47
|
+
*/
|
|
48
|
+
async createPreviewEnvironment(options: PreviewEnvironmentOptions): Promise<PreviewEnvironment> {
|
|
49
|
+
const {
|
|
50
|
+
branch,
|
|
51
|
+
pr,
|
|
52
|
+
commitSha,
|
|
53
|
+
ttl = 24, // Default: 24 hours
|
|
54
|
+
baseConfig,
|
|
55
|
+
region = 'us-east-1',
|
|
56
|
+
} = options
|
|
57
|
+
|
|
58
|
+
// Generate unique ID for preview environment
|
|
59
|
+
const id = this.generatePreviewId(branch, pr, commitSha)
|
|
60
|
+
const name = this.generatePreviewName(branch, pr)
|
|
61
|
+
const stackName = `preview-${name}`
|
|
62
|
+
|
|
63
|
+
// Calculate expiration
|
|
64
|
+
const createdAt = new Date()
|
|
65
|
+
const expiresAt = new Date(createdAt.getTime() + ttl * 60 * 60 * 1000)
|
|
66
|
+
|
|
67
|
+
const environment: PreviewEnvironment = {
|
|
68
|
+
id,
|
|
69
|
+
name,
|
|
70
|
+
branch,
|
|
71
|
+
pr,
|
|
72
|
+
commitSha,
|
|
73
|
+
createdAt,
|
|
74
|
+
expiresAt,
|
|
75
|
+
status: 'creating',
|
|
76
|
+
stackName,
|
|
77
|
+
region,
|
|
78
|
+
resources: [],
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
this.environments.set(id, environment)
|
|
82
|
+
|
|
83
|
+
try {
|
|
84
|
+
// Create modified config for preview environment
|
|
85
|
+
const previewConfig = this.createPreviewConfig(baseConfig, name)
|
|
86
|
+
|
|
87
|
+
// Deploy preview environment (implementation would use CloudFormation)
|
|
88
|
+
// This is a placeholder - actual implementation would:
|
|
89
|
+
// 1. Generate CloudFormation template
|
|
90
|
+
// 2. Deploy stack
|
|
91
|
+
// 3. Wait for completion
|
|
92
|
+
// 4. Extract outputs (URL, etc.)
|
|
93
|
+
|
|
94
|
+
environment.status = 'active'
|
|
95
|
+
environment.url = `https://${name}.preview.example.com`
|
|
96
|
+
|
|
97
|
+
return environment
|
|
98
|
+
}
|
|
99
|
+
catch (error) {
|
|
100
|
+
environment.status = 'failed'
|
|
101
|
+
throw error
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Destroy a preview environment
|
|
107
|
+
*/
|
|
108
|
+
async destroyPreviewEnvironment(id: string): Promise<void> {
|
|
109
|
+
const environment = this.environments.get(id)
|
|
110
|
+
|
|
111
|
+
if (!environment) {
|
|
112
|
+
throw new Error(`Preview environment ${id} not found`)
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
environment.status = 'destroying'
|
|
116
|
+
|
|
117
|
+
try {
|
|
118
|
+
// Delete CloudFormation stack
|
|
119
|
+
// This is a placeholder - actual implementation would:
|
|
120
|
+
// 1. Delete CloudFormation stack
|
|
121
|
+
// 2. Wait for deletion
|
|
122
|
+
// 3. Clean up any remaining resources
|
|
123
|
+
|
|
124
|
+
environment.status = 'destroyed'
|
|
125
|
+
this.environments.delete(id)
|
|
126
|
+
}
|
|
127
|
+
catch (error) {
|
|
128
|
+
throw new Error(`Failed to destroy preview environment: ${error}`)
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Get preview environment by ID
|
|
134
|
+
*/
|
|
135
|
+
getPreviewEnvironment(id: string): PreviewEnvironment | undefined {
|
|
136
|
+
return this.environments.get(id)
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Get preview environment by branch
|
|
141
|
+
*/
|
|
142
|
+
getPreviewEnvironmentByBranch(branch: string): PreviewEnvironment | undefined {
|
|
143
|
+
return Array.from(this.environments.values()).find(env => env.branch === branch)
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Get preview environment by PR number
|
|
148
|
+
*/
|
|
149
|
+
getPreviewEnvironmentByPR(pr: number): PreviewEnvironment | undefined {
|
|
150
|
+
return Array.from(this.environments.values()).find(env => env.pr === pr)
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* List all preview environments
|
|
155
|
+
*/
|
|
156
|
+
listPreviewEnvironments(): PreviewEnvironment[] {
|
|
157
|
+
return Array.from(this.environments.values())
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* List active preview environments
|
|
162
|
+
*/
|
|
163
|
+
listActivePreviewEnvironments(): PreviewEnvironment[] {
|
|
164
|
+
return this.listPreviewEnvironments().filter(env => env.status === 'active')
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Clean up expired preview environments
|
|
169
|
+
*/
|
|
170
|
+
async cleanupExpiredEnvironments(options: PreviewCleanupOptions = {}): Promise<{
|
|
171
|
+
destroyed: string[]
|
|
172
|
+
failed: string[]
|
|
173
|
+
}> {
|
|
174
|
+
const { maxAge, keepCount, dryRun = false } = options
|
|
175
|
+
|
|
176
|
+
const destroyed: string[] = []
|
|
177
|
+
const failed: string[] = []
|
|
178
|
+
const now = new Date()
|
|
179
|
+
|
|
180
|
+
// Get all environments sorted by creation date (newest first)
|
|
181
|
+
const environments = this.listPreviewEnvironments().sort(
|
|
182
|
+
(a, b) => b.createdAt.getTime() - a.createdAt.getTime(),
|
|
183
|
+
)
|
|
184
|
+
|
|
185
|
+
for (let i = 0; i < environments.length; i++) {
|
|
186
|
+
const env = environments[i]
|
|
187
|
+
|
|
188
|
+
// Skip if not active or already being destroyed
|
|
189
|
+
if (env.status !== 'active') {
|
|
190
|
+
continue
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
let shouldDestroy = false
|
|
194
|
+
|
|
195
|
+
// Check if expired by TTL
|
|
196
|
+
if (env.expiresAt < now) {
|
|
197
|
+
shouldDestroy = true
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// Check if older than maxAge
|
|
201
|
+
if (maxAge) {
|
|
202
|
+
const ageHours = (now.getTime() - env.createdAt.getTime()) / (1000 * 60 * 60)
|
|
203
|
+
if (ageHours > maxAge) {
|
|
204
|
+
shouldDestroy = true
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// Keep only N most recent environments
|
|
209
|
+
if (keepCount && i >= keepCount) {
|
|
210
|
+
shouldDestroy = true
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
if (shouldDestroy) {
|
|
214
|
+
if (dryRun) {
|
|
215
|
+
destroyed.push(env.id)
|
|
216
|
+
}
|
|
217
|
+
else {
|
|
218
|
+
try {
|
|
219
|
+
await this.destroyPreviewEnvironment(env.id)
|
|
220
|
+
destroyed.push(env.id)
|
|
221
|
+
}
|
|
222
|
+
catch (error) {
|
|
223
|
+
failed.push(env.id)
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
return { destroyed, failed }
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* Update preview environment from new commit
|
|
234
|
+
*/
|
|
235
|
+
async updatePreviewEnvironment(id: string, commitSha: string): Promise<PreviewEnvironment> {
|
|
236
|
+
const environment = this.environments.get(id)
|
|
237
|
+
|
|
238
|
+
if (!environment) {
|
|
239
|
+
throw new Error(`Preview environment ${id} not found`)
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
environment.commitSha = commitSha
|
|
243
|
+
environment.status = 'creating'
|
|
244
|
+
|
|
245
|
+
try {
|
|
246
|
+
// Update CloudFormation stack
|
|
247
|
+
// This is a placeholder - actual implementation would:
|
|
248
|
+
// 1. Generate updated CloudFormation template
|
|
249
|
+
// 2. Update stack
|
|
250
|
+
// 3. Wait for completion
|
|
251
|
+
|
|
252
|
+
environment.status = 'active'
|
|
253
|
+
|
|
254
|
+
return environment
|
|
255
|
+
}
|
|
256
|
+
catch (error) {
|
|
257
|
+
environment.status = 'failed'
|
|
258
|
+
throw error
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* Get cost estimate for preview environments
|
|
264
|
+
*/
|
|
265
|
+
async getPreviewEnvironmentsCost(): Promise<{
|
|
266
|
+
total: number
|
|
267
|
+
byEnvironment: Record<string, number>
|
|
268
|
+
}> {
|
|
269
|
+
const byEnvironment: Record<string, number> = {}
|
|
270
|
+
let total = 0
|
|
271
|
+
|
|
272
|
+
for (const env of this.environments.values()) {
|
|
273
|
+
// This is a placeholder - actual implementation would:
|
|
274
|
+
// 1. Query AWS Cost Explorer API
|
|
275
|
+
// 2. Filter by stack tags
|
|
276
|
+
// 3. Sum costs
|
|
277
|
+
const cost = 0 // Placeholder
|
|
278
|
+
|
|
279
|
+
byEnvironment[env.id] = cost
|
|
280
|
+
total += cost
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
return { total, byEnvironment }
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
/**
|
|
287
|
+
* Generate preview environment ID
|
|
288
|
+
*/
|
|
289
|
+
private generatePreviewId(branch: string, pr?: number, commitSha?: string): string {
|
|
290
|
+
const sanitizedBranch = branch.replace(/[^a-z0-9-]/gi, '-').toLowerCase()
|
|
291
|
+
const shortSha = commitSha?.substring(0, 7) || Date.now().toString()
|
|
292
|
+
|
|
293
|
+
return pr ? `pr-${pr}-${shortSha}` : `${sanitizedBranch}-${shortSha}`
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
/**
|
|
297
|
+
* Generate preview environment name
|
|
298
|
+
*/
|
|
299
|
+
private generatePreviewName(branch: string, pr?: number): string {
|
|
300
|
+
const sanitizedBranch = branch.replace(/[^a-z0-9-]/gi, '-').toLowerCase()
|
|
301
|
+
|
|
302
|
+
return pr ? `pr-${pr}` : sanitizedBranch
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
/**
|
|
306
|
+
* Create modified config for preview environment
|
|
307
|
+
*/
|
|
308
|
+
private createPreviewConfig(baseConfig: CloudConfig, name: string): CloudConfig {
|
|
309
|
+
return {
|
|
310
|
+
...baseConfig,
|
|
311
|
+
project: {
|
|
312
|
+
...baseConfig.project,
|
|
313
|
+
name: `${baseConfig.project.name} Preview (${name})`,
|
|
314
|
+
slug: `${baseConfig.project.slug}-preview-${name}`,
|
|
315
|
+
},
|
|
316
|
+
// Add preview-specific tags
|
|
317
|
+
// Add cost allocation tags
|
|
318
|
+
// Reduce resource sizes for cost optimization
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
/**
|
|
324
|
+
* Global preview environment manager instance
|
|
325
|
+
*/
|
|
326
|
+
export const previewManager: PreviewEnvironmentManager = new PreviewEnvironmentManager()
|