@stacksjs/ts-cloud-core 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.
- package/package.json +7 -6
- 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
|
@@ -0,0 +1,352 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SES Email Template Management
|
|
3
|
+
* Template versioning, personalization, and testing
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export interface EmailTemplate {
|
|
7
|
+
id: string
|
|
8
|
+
name: string
|
|
9
|
+
subject: string
|
|
10
|
+
htmlPart: string
|
|
11
|
+
textPart: string
|
|
12
|
+
variables: string[]
|
|
13
|
+
createdAt: Date
|
|
14
|
+
updatedAt: Date
|
|
15
|
+
version: number
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface TemplateVersion {
|
|
19
|
+
id: string
|
|
20
|
+
templateId: string
|
|
21
|
+
version: number
|
|
22
|
+
subject: string
|
|
23
|
+
htmlPart: string
|
|
24
|
+
textPart: string
|
|
25
|
+
createdAt: Date
|
|
26
|
+
createdBy: string
|
|
27
|
+
changelog?: string
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface TemplateTest {
|
|
31
|
+
id: string
|
|
32
|
+
templateId: string
|
|
33
|
+
testData: Record<string, any>
|
|
34
|
+
renderedSubject: string
|
|
35
|
+
renderedHtml: string
|
|
36
|
+
renderedText: string
|
|
37
|
+
timestamp: Date
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Email template manager
|
|
42
|
+
*/
|
|
43
|
+
export class EmailTemplateManager {
|
|
44
|
+
private templates: Map<string, EmailTemplate> = new Map()
|
|
45
|
+
private versions: Map<string, TemplateVersion[]> = new Map()
|
|
46
|
+
private tests: Map<string, TemplateTest> = new Map()
|
|
47
|
+
private templateCounter = 0
|
|
48
|
+
private testCounter = 0
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Create template
|
|
52
|
+
*/
|
|
53
|
+
createTemplate(template: {
|
|
54
|
+
name: string
|
|
55
|
+
subject: string
|
|
56
|
+
htmlPart: string
|
|
57
|
+
textPart: string
|
|
58
|
+
}): EmailTemplate {
|
|
59
|
+
const id = `template-${Date.now()}-${this.templateCounter++}`
|
|
60
|
+
|
|
61
|
+
const variables = this.extractVariables(template.subject + template.htmlPart + template.textPart)
|
|
62
|
+
|
|
63
|
+
const emailTemplate: EmailTemplate = {
|
|
64
|
+
id,
|
|
65
|
+
variables,
|
|
66
|
+
createdAt: new Date(),
|
|
67
|
+
updatedAt: new Date(),
|
|
68
|
+
version: 1,
|
|
69
|
+
...template,
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
this.templates.set(id, emailTemplate)
|
|
73
|
+
|
|
74
|
+
// Store initial version
|
|
75
|
+
this.addVersion({
|
|
76
|
+
templateId: id,
|
|
77
|
+
version: 1,
|
|
78
|
+
subject: template.subject,
|
|
79
|
+
htmlPart: template.htmlPart,
|
|
80
|
+
textPart: template.textPart,
|
|
81
|
+
createdBy: 'system',
|
|
82
|
+
})
|
|
83
|
+
|
|
84
|
+
return emailTemplate
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Create welcome email template
|
|
89
|
+
*/
|
|
90
|
+
createWelcomeTemplate(options: {
|
|
91
|
+
name: string
|
|
92
|
+
companyName: string
|
|
93
|
+
}): EmailTemplate {
|
|
94
|
+
return this.createTemplate({
|
|
95
|
+
name: options.name,
|
|
96
|
+
subject: `Welcome to {{companyName}}!`,
|
|
97
|
+
htmlPart: `
|
|
98
|
+
<html>
|
|
99
|
+
<body>
|
|
100
|
+
<h1>Welcome, {{userName}}!</h1>
|
|
101
|
+
<p>Thank you for joining {{companyName}}. We're excited to have you on board.</p>
|
|
102
|
+
<p>Your account is now active and ready to use.</p>
|
|
103
|
+
<a href="{{loginUrl}}">Get Started</a>
|
|
104
|
+
</body>
|
|
105
|
+
</html>
|
|
106
|
+
`,
|
|
107
|
+
textPart: `Welcome, {{userName}}! Thank you for joining {{companyName}}. Visit {{loginUrl}} to get started.`,
|
|
108
|
+
})
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Create password reset template
|
|
113
|
+
*/
|
|
114
|
+
createPasswordResetTemplate(options: {
|
|
115
|
+
name: string
|
|
116
|
+
companyName: string
|
|
117
|
+
}): EmailTemplate {
|
|
118
|
+
return this.createTemplate({
|
|
119
|
+
name: options.name,
|
|
120
|
+
subject: 'Reset your password',
|
|
121
|
+
htmlPart: `
|
|
122
|
+
<html>
|
|
123
|
+
<body>
|
|
124
|
+
<h1>Password Reset Request</h1>
|
|
125
|
+
<p>Hi {{userName}},</p>
|
|
126
|
+
<p>We received a request to reset your password for your {{companyName}} account.</p>
|
|
127
|
+
<a href="{{resetUrl}}">Reset Password</a>
|
|
128
|
+
<p>This link will expire in {{expirationHours}} hours.</p>
|
|
129
|
+
<p>If you didn't request this, please ignore this email.</p>
|
|
130
|
+
</body>
|
|
131
|
+
</html>
|
|
132
|
+
`,
|
|
133
|
+
textPart: `Hi {{userName}}, reset your password at: {{resetUrl}}. This link expires in {{expirationHours}} hours.`,
|
|
134
|
+
})
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Update template
|
|
139
|
+
*/
|
|
140
|
+
updateTemplate(
|
|
141
|
+
templateId: string,
|
|
142
|
+
updates: {
|
|
143
|
+
subject?: string
|
|
144
|
+
htmlPart?: string
|
|
145
|
+
textPart?: string
|
|
146
|
+
},
|
|
147
|
+
changelog?: string
|
|
148
|
+
): EmailTemplate {
|
|
149
|
+
const template = this.templates.get(templateId)
|
|
150
|
+
|
|
151
|
+
if (!template) {
|
|
152
|
+
throw new Error(`Template not found: ${templateId}`)
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
if (updates.subject) template.subject = updates.subject
|
|
156
|
+
if (updates.htmlPart) template.htmlPart = updates.htmlPart
|
|
157
|
+
if (updates.textPart) template.textPart = updates.textPart
|
|
158
|
+
|
|
159
|
+
template.version++
|
|
160
|
+
template.updatedAt = new Date()
|
|
161
|
+
template.variables = this.extractVariables(template.subject + template.htmlPart + template.textPart)
|
|
162
|
+
|
|
163
|
+
// Store new version
|
|
164
|
+
this.addVersion({
|
|
165
|
+
templateId,
|
|
166
|
+
version: template.version,
|
|
167
|
+
subject: template.subject,
|
|
168
|
+
htmlPart: template.htmlPart,
|
|
169
|
+
textPart: template.textPart,
|
|
170
|
+
createdBy: 'system',
|
|
171
|
+
changelog,
|
|
172
|
+
})
|
|
173
|
+
|
|
174
|
+
return template
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Add template version
|
|
179
|
+
*/
|
|
180
|
+
private addVersion(version: Omit<TemplateVersion, 'id' | 'createdAt'>): TemplateVersion {
|
|
181
|
+
const id = `version-${version.templateId}-${version.version}`
|
|
182
|
+
|
|
183
|
+
const templateVersion: TemplateVersion = {
|
|
184
|
+
id,
|
|
185
|
+
createdAt: new Date(),
|
|
186
|
+
...version,
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
const versions = this.versions.get(version.templateId) || []
|
|
190
|
+
versions.push(templateVersion)
|
|
191
|
+
this.versions.set(version.templateId, versions)
|
|
192
|
+
|
|
193
|
+
return templateVersion
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Extract variables from template
|
|
198
|
+
*/
|
|
199
|
+
private extractVariables(text: string): string[] {
|
|
200
|
+
const regex = /\{\{([^}]+)\}\}/g
|
|
201
|
+
const variables = new Set<string>()
|
|
202
|
+
let match
|
|
203
|
+
|
|
204
|
+
while ((match = regex.exec(text)) !== null) {
|
|
205
|
+
variables.add(match[1].trim())
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
return Array.from(variables)
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Render template
|
|
213
|
+
*/
|
|
214
|
+
renderTemplate(templateId: string, data: Record<string, any>): {
|
|
215
|
+
subject: string
|
|
216
|
+
html: string
|
|
217
|
+
text: string
|
|
218
|
+
} {
|
|
219
|
+
const template = this.templates.get(templateId)
|
|
220
|
+
|
|
221
|
+
if (!template) {
|
|
222
|
+
throw new Error(`Template not found: ${templateId}`)
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
const render = (text: string): string => {
|
|
226
|
+
return text.replace(/\{\{([^}]+)\}\}/g, (match, variable) => {
|
|
227
|
+
const key = variable.trim()
|
|
228
|
+
return data[key] !== undefined ? String(data[key]) : match
|
|
229
|
+
})
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
return {
|
|
233
|
+
subject: render(template.subject),
|
|
234
|
+
html: render(template.htmlPart),
|
|
235
|
+
text: render(template.textPart),
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* Test template
|
|
241
|
+
*/
|
|
242
|
+
testTemplate(templateId: string, testData: Record<string, any>): TemplateTest {
|
|
243
|
+
const id = `test-${Date.now()}-${this.testCounter++}`
|
|
244
|
+
|
|
245
|
+
const rendered = this.renderTemplate(templateId, testData)
|
|
246
|
+
|
|
247
|
+
const test: TemplateTest = {
|
|
248
|
+
id,
|
|
249
|
+
templateId,
|
|
250
|
+
testData,
|
|
251
|
+
renderedSubject: rendered.subject,
|
|
252
|
+
renderedHtml: rendered.html,
|
|
253
|
+
renderedText: rendered.text,
|
|
254
|
+
timestamp: new Date(),
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
this.tests.set(id, test)
|
|
258
|
+
|
|
259
|
+
return test
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* Get template
|
|
264
|
+
*/
|
|
265
|
+
getTemplate(id: string): EmailTemplate | undefined {
|
|
266
|
+
return this.templates.get(id)
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
/**
|
|
270
|
+
* List templates
|
|
271
|
+
*/
|
|
272
|
+
listTemplates(): EmailTemplate[] {
|
|
273
|
+
return Array.from(this.templates.values())
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
/**
|
|
277
|
+
* Get template versions
|
|
278
|
+
*/
|
|
279
|
+
getTemplateVersions(templateId: string): TemplateVersion[] {
|
|
280
|
+
return this.versions.get(templateId) || []
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* Revert to version
|
|
285
|
+
*/
|
|
286
|
+
revertToVersion(templateId: string, versionNumber: number): EmailTemplate {
|
|
287
|
+
const template = this.templates.get(templateId)
|
|
288
|
+
|
|
289
|
+
if (!template) {
|
|
290
|
+
throw new Error(`Template not found: ${templateId}`)
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
const versions = this.versions.get(templateId) || []
|
|
294
|
+
const targetVersion = versions.find(v => v.version === versionNumber)
|
|
295
|
+
|
|
296
|
+
if (!targetVersion) {
|
|
297
|
+
throw new Error(`Version ${versionNumber} not found for template ${templateId}`)
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
template.subject = targetVersion.subject
|
|
301
|
+
template.htmlPart = targetVersion.htmlPart
|
|
302
|
+
template.textPart = targetVersion.textPart
|
|
303
|
+
template.version++
|
|
304
|
+
template.updatedAt = new Date()
|
|
305
|
+
|
|
306
|
+
// Store revert as new version
|
|
307
|
+
this.addVersion({
|
|
308
|
+
templateId,
|
|
309
|
+
version: template.version,
|
|
310
|
+
subject: template.subject,
|
|
311
|
+
htmlPart: template.htmlPart,
|
|
312
|
+
textPart: template.textPart,
|
|
313
|
+
createdBy: 'system',
|
|
314
|
+
changelog: `Reverted to version ${versionNumber}`,
|
|
315
|
+
})
|
|
316
|
+
|
|
317
|
+
return template
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
/**
|
|
321
|
+
* Generate CloudFormation for SES template
|
|
322
|
+
*/
|
|
323
|
+
generateTemplateCF(template: EmailTemplate): any {
|
|
324
|
+
return {
|
|
325
|
+
Type: 'AWS::SES::Template',
|
|
326
|
+
Properties: {
|
|
327
|
+
Template: {
|
|
328
|
+
TemplateName: template.name,
|
|
329
|
+
SubjectPart: template.subject,
|
|
330
|
+
HtmlPart: template.htmlPart,
|
|
331
|
+
TextPart: template.textPart,
|
|
332
|
+
},
|
|
333
|
+
},
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
/**
|
|
338
|
+
* Clear all data
|
|
339
|
+
*/
|
|
340
|
+
clear(): void {
|
|
341
|
+
this.templates.clear()
|
|
342
|
+
this.versions.clear()
|
|
343
|
+
this.tests.clear()
|
|
344
|
+
this.templateCounter = 0
|
|
345
|
+
this.testCounter = 0
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
/**
|
|
350
|
+
* Global email template manager instance
|
|
351
|
+
*/
|
|
352
|
+
export const emailTemplateManager: EmailTemplateManager = new EmailTemplateManager()
|