@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,341 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Preview environment notifications
|
|
3
|
+
* Send notifications to Slack, Discord, email, etc. when preview environments are created/destroyed
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { PreviewEnvironment } from './manager'
|
|
7
|
+
|
|
8
|
+
export interface NotificationChannel {
|
|
9
|
+
type: 'slack' | 'discord' | 'email' | 'webhook'
|
|
10
|
+
config: SlackConfig | DiscordConfig | EmailConfig | WebhookConfig
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface SlackConfig {
|
|
14
|
+
webhookUrl: string
|
|
15
|
+
channel?: string
|
|
16
|
+
username?: string
|
|
17
|
+
iconEmoji?: string
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface DiscordConfig {
|
|
21
|
+
webhookUrl: string
|
|
22
|
+
username?: string
|
|
23
|
+
avatarUrl?: string
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface EmailConfig {
|
|
27
|
+
from: string
|
|
28
|
+
to: string[]
|
|
29
|
+
smtpHost: string
|
|
30
|
+
smtpPort: number
|
|
31
|
+
smtpUser?: string
|
|
32
|
+
smtpPassword?: string
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export interface WebhookConfig {
|
|
36
|
+
url: string
|
|
37
|
+
method?: 'POST' | 'GET'
|
|
38
|
+
headers?: Record<string, string>
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export interface NotificationEvent {
|
|
42
|
+
type: 'created' | 'updated' | 'destroyed' | 'failed' | 'expired'
|
|
43
|
+
environment: PreviewEnvironment
|
|
44
|
+
timestamp: Date
|
|
45
|
+
metadata?: Record<string, any>
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Preview environment notification service
|
|
50
|
+
*/
|
|
51
|
+
export class PreviewNotificationService {
|
|
52
|
+
private channels: NotificationChannel[] = []
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Add notification channel
|
|
56
|
+
*/
|
|
57
|
+
addChannel(channel: NotificationChannel): void {
|
|
58
|
+
this.channels.push(channel)
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Remove notification channel
|
|
63
|
+
*/
|
|
64
|
+
removeChannel(type: NotificationChannel['type']): void {
|
|
65
|
+
this.channels = this.channels.filter(c => c.type !== type)
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Send notification to all channels
|
|
70
|
+
*/
|
|
71
|
+
async notify(event: NotificationEvent): Promise<void> {
|
|
72
|
+
const promises = this.channels.map(channel => this.sendToChannel(channel, event))
|
|
73
|
+
|
|
74
|
+
await Promise.allSettled(promises)
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Send notification to specific channel
|
|
79
|
+
*/
|
|
80
|
+
private async sendToChannel(channel: NotificationChannel, event: NotificationEvent): Promise<void> {
|
|
81
|
+
switch (channel.type) {
|
|
82
|
+
case 'slack':
|
|
83
|
+
await this.sendToSlack(channel.config as SlackConfig, event)
|
|
84
|
+
break
|
|
85
|
+
case 'discord':
|
|
86
|
+
await this.sendToDiscord(channel.config as DiscordConfig, event)
|
|
87
|
+
break
|
|
88
|
+
case 'email':
|
|
89
|
+
await this.sendToEmail(channel.config as EmailConfig, event)
|
|
90
|
+
break
|
|
91
|
+
case 'webhook':
|
|
92
|
+
await this.sendToWebhook(channel.config as WebhookConfig, event)
|
|
93
|
+
break
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Send notification to Slack
|
|
99
|
+
*/
|
|
100
|
+
private async sendToSlack(config: SlackConfig, event: NotificationEvent): Promise<void> {
|
|
101
|
+
const message = this.formatSlackMessage(event, config)
|
|
102
|
+
|
|
103
|
+
const response = await fetch(config.webhookUrl, {
|
|
104
|
+
method: 'POST',
|
|
105
|
+
headers: {
|
|
106
|
+
'Content-Type': 'application/json',
|
|
107
|
+
},
|
|
108
|
+
body: JSON.stringify(message),
|
|
109
|
+
})
|
|
110
|
+
|
|
111
|
+
if (!response.ok) {
|
|
112
|
+
throw new Error(`Failed to send Slack notification: ${response.statusText}`)
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Format Slack message
|
|
118
|
+
*/
|
|
119
|
+
private formatSlackMessage(event: NotificationEvent, config: SlackConfig): any {
|
|
120
|
+
const { environment, type } = event
|
|
121
|
+
|
|
122
|
+
const emoji = {
|
|
123
|
+
created: ':rocket:',
|
|
124
|
+
updated: ':arrows_counterclockwise:',
|
|
125
|
+
destroyed: ':wastebasket:',
|
|
126
|
+
failed: ':x:',
|
|
127
|
+
expired: ':hourglass_flowing_sand:',
|
|
128
|
+
}[type]
|
|
129
|
+
|
|
130
|
+
const color = {
|
|
131
|
+
created: '#36a64f',
|
|
132
|
+
updated: '#2196F3',
|
|
133
|
+
destroyed: '#808080',
|
|
134
|
+
failed: '#f44336',
|
|
135
|
+
expired: '#ff9800',
|
|
136
|
+
}[type]
|
|
137
|
+
|
|
138
|
+
const title = {
|
|
139
|
+
created: 'Preview Environment Created',
|
|
140
|
+
updated: 'Preview Environment Updated',
|
|
141
|
+
destroyed: 'Preview Environment Destroyed',
|
|
142
|
+
failed: 'Preview Environment Failed',
|
|
143
|
+
expired: 'Preview Environment Expired',
|
|
144
|
+
}[type]
|
|
145
|
+
|
|
146
|
+
return {
|
|
147
|
+
username: config.username || 'ts-cloud',
|
|
148
|
+
icon_emoji: config.iconEmoji || ':cloud:',
|
|
149
|
+
channel: config.channel,
|
|
150
|
+
attachments: [
|
|
151
|
+
{
|
|
152
|
+
color,
|
|
153
|
+
title: `${emoji} ${title}`,
|
|
154
|
+
fields: [
|
|
155
|
+
{
|
|
156
|
+
title: 'Environment',
|
|
157
|
+
value: environment.name,
|
|
158
|
+
short: true,
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
title: 'Branch',
|
|
162
|
+
value: environment.branch,
|
|
163
|
+
short: true,
|
|
164
|
+
},
|
|
165
|
+
...(environment.pr
|
|
166
|
+
? [
|
|
167
|
+
{
|
|
168
|
+
title: 'PR',
|
|
169
|
+
value: `#${environment.pr}`,
|
|
170
|
+
short: true,
|
|
171
|
+
},
|
|
172
|
+
]
|
|
173
|
+
: []),
|
|
174
|
+
{
|
|
175
|
+
title: 'Commit',
|
|
176
|
+
value: environment.commitSha.substring(0, 7),
|
|
177
|
+
short: true,
|
|
178
|
+
},
|
|
179
|
+
...(environment.url
|
|
180
|
+
? [
|
|
181
|
+
{
|
|
182
|
+
title: 'URL',
|
|
183
|
+
value: environment.url,
|
|
184
|
+
short: false,
|
|
185
|
+
},
|
|
186
|
+
]
|
|
187
|
+
: []),
|
|
188
|
+
...(type === 'created'
|
|
189
|
+
? [
|
|
190
|
+
{
|
|
191
|
+
title: 'Expires',
|
|
192
|
+
value: environment.expiresAt.toLocaleString(),
|
|
193
|
+
short: true,
|
|
194
|
+
},
|
|
195
|
+
]
|
|
196
|
+
: []),
|
|
197
|
+
],
|
|
198
|
+
footer: 'ts-cloud Preview Environments',
|
|
199
|
+
ts: Math.floor(event.timestamp.getTime() / 1000),
|
|
200
|
+
},
|
|
201
|
+
],
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* Send notification to Discord
|
|
207
|
+
*/
|
|
208
|
+
private async sendToDiscord(config: DiscordConfig, event: NotificationEvent): Promise<void> {
|
|
209
|
+
const message = this.formatDiscordMessage(event, config)
|
|
210
|
+
|
|
211
|
+
const response = await fetch(config.webhookUrl, {
|
|
212
|
+
method: 'POST',
|
|
213
|
+
headers: {
|
|
214
|
+
'Content-Type': 'application/json',
|
|
215
|
+
},
|
|
216
|
+
body: JSON.stringify(message),
|
|
217
|
+
})
|
|
218
|
+
|
|
219
|
+
if (!response.ok) {
|
|
220
|
+
throw new Error(`Failed to send Discord notification: ${response.statusText}`)
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* Format Discord message
|
|
226
|
+
*/
|
|
227
|
+
private formatDiscordMessage(event: NotificationEvent, config: DiscordConfig): any {
|
|
228
|
+
const { environment, type } = event
|
|
229
|
+
|
|
230
|
+
const emoji = {
|
|
231
|
+
created: ':rocket:',
|
|
232
|
+
updated: ':arrows_counterclockwise:',
|
|
233
|
+
destroyed: ':wastebasket:',
|
|
234
|
+
failed: ':x:',
|
|
235
|
+
expired: ':hourglass:',
|
|
236
|
+
}[type]
|
|
237
|
+
|
|
238
|
+
const color = {
|
|
239
|
+
created: 0x36A64F,
|
|
240
|
+
updated: 0x2196F3,
|
|
241
|
+
destroyed: 0x808080,
|
|
242
|
+
failed: 0xF44336,
|
|
243
|
+
expired: 0xFF9800,
|
|
244
|
+
}[type]
|
|
245
|
+
|
|
246
|
+
const title = {
|
|
247
|
+
created: 'Preview Environment Created',
|
|
248
|
+
updated: 'Preview Environment Updated',
|
|
249
|
+
destroyed: 'Preview Environment Destroyed',
|
|
250
|
+
failed: 'Preview Environment Failed',
|
|
251
|
+
expired: 'Preview Environment Expired',
|
|
252
|
+
}[type]
|
|
253
|
+
|
|
254
|
+
return {
|
|
255
|
+
username: config.username || 'ts-cloud',
|
|
256
|
+
avatar_url: config.avatarUrl,
|
|
257
|
+
embeds: [
|
|
258
|
+
{
|
|
259
|
+
title: `${emoji} ${title}`,
|
|
260
|
+
color,
|
|
261
|
+
fields: [
|
|
262
|
+
{
|
|
263
|
+
name: 'Environment',
|
|
264
|
+
value: environment.name,
|
|
265
|
+
inline: true,
|
|
266
|
+
},
|
|
267
|
+
{
|
|
268
|
+
name: 'Branch',
|
|
269
|
+
value: environment.branch,
|
|
270
|
+
inline: true,
|
|
271
|
+
},
|
|
272
|
+
...(environment.pr
|
|
273
|
+
? [
|
|
274
|
+
{
|
|
275
|
+
name: 'PR',
|
|
276
|
+
value: `#${environment.pr}`,
|
|
277
|
+
inline: true,
|
|
278
|
+
},
|
|
279
|
+
]
|
|
280
|
+
: []),
|
|
281
|
+
{
|
|
282
|
+
name: 'Commit',
|
|
283
|
+
value: `\`${environment.commitSha.substring(0, 7)}\``,
|
|
284
|
+
inline: true,
|
|
285
|
+
},
|
|
286
|
+
...(environment.url
|
|
287
|
+
? [
|
|
288
|
+
{
|
|
289
|
+
name: 'URL',
|
|
290
|
+
value: environment.url,
|
|
291
|
+
inline: false,
|
|
292
|
+
},
|
|
293
|
+
]
|
|
294
|
+
: []),
|
|
295
|
+
],
|
|
296
|
+
timestamp: event.timestamp.toISOString(),
|
|
297
|
+
footer: {
|
|
298
|
+
text: 'ts-cloud Preview Environments',
|
|
299
|
+
},
|
|
300
|
+
},
|
|
301
|
+
],
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
/**
|
|
306
|
+
* Send notification via email
|
|
307
|
+
*/
|
|
308
|
+
private async sendToEmail(config: EmailConfig, event: NotificationEvent): Promise<void> {
|
|
309
|
+
// This is a placeholder - actual implementation would use nodemailer or similar
|
|
310
|
+
// For now, we'll just log that email would be sent
|
|
311
|
+
console.log(`Email notification would be sent to ${config.to.join(', ')}`)
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
/**
|
|
315
|
+
* Send notification to custom webhook
|
|
316
|
+
*/
|
|
317
|
+
private async sendToWebhook(config: WebhookConfig, event: NotificationEvent): Promise<void> {
|
|
318
|
+
const response = await fetch(config.url, {
|
|
319
|
+
method: config.method || 'POST',
|
|
320
|
+
headers: {
|
|
321
|
+
'Content-Type': 'application/json',
|
|
322
|
+
...config.headers,
|
|
323
|
+
},
|
|
324
|
+
body: JSON.stringify({
|
|
325
|
+
event: event.type,
|
|
326
|
+
environment: event.environment,
|
|
327
|
+
timestamp: event.timestamp.toISOString(),
|
|
328
|
+
metadata: event.metadata,
|
|
329
|
+
}),
|
|
330
|
+
})
|
|
331
|
+
|
|
332
|
+
if (!response.ok) {
|
|
333
|
+
throw new Error(`Failed to send webhook notification: ${response.statusText}`)
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
/**
|
|
339
|
+
* Global notification service instance
|
|
340
|
+
*/
|
|
341
|
+
export const previewNotifications: PreviewNotificationService = new PreviewNotificationService()
|