alchemy 0.22.4 → 0.23.0
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/lib/aws/bucket.d.ts.map +1 -1
- package/lib/aws/bucket.js +13 -12
- package/lib/aws/bucket.js.map +1 -1
- package/lib/aws/control/client.d.ts.map +1 -1
- package/lib/aws/control/client.js +5 -3
- package/lib/aws/control/client.js.map +1 -1
- package/lib/aws/control/resource.d.ts.map +1 -1
- package/lib/aws/control/resource.js +13 -4
- package/lib/aws/control/resource.js.map +1 -1
- package/lib/aws/control/types.d.ts +85129 -0
- package/lib/aws/function.d.ts.map +1 -1
- package/lib/aws/function.js +51 -42
- package/lib/aws/function.js.map +1 -1
- package/lib/aws/index.d.ts +1 -0
- package/lib/aws/index.d.ts.map +1 -1
- package/lib/aws/index.js +1 -0
- package/lib/aws/index.js.map +1 -1
- package/lib/aws/policy-attachment.d.ts.map +1 -1
- package/lib/aws/policy-attachment.js +5 -4
- package/lib/aws/policy-attachment.js.map +1 -1
- package/lib/aws/policy.d.ts.map +1 -1
- package/lib/aws/policy.js +21 -20
- package/lib/aws/policy.js.map +1 -1
- package/lib/aws/queue.d.ts.map +1 -1
- package/lib/aws/queue.js +19 -15
- package/lib/aws/queue.js.map +1 -1
- package/lib/aws/retry.d.ts +5 -0
- package/lib/aws/retry.d.ts.map +1 -0
- package/lib/aws/retry.js +27 -0
- package/lib/aws/retry.js.map +1 -0
- package/lib/aws/role.d.ts.map +1 -1
- package/lib/aws/role.js +31 -30
- package/lib/aws/role.js.map +1 -1
- package/lib/aws/ses.d.ts.map +1 -1
- package/lib/aws/ses.js +27 -26
- package/lib/aws/ses.js.map +1 -1
- package/lib/aws/ssm-parameter.d.ts +150 -0
- package/lib/aws/ssm-parameter.d.ts.map +1 -0
- package/lib/aws/ssm-parameter.js +184 -0
- package/lib/aws/ssm-parameter.js.map +1 -0
- package/lib/aws/table.d.ts.map +1 -1
- package/lib/aws/table.js +9 -27
- package/lib/aws/table.js.map +1 -1
- package/lib/cloudflare/account-id.d.ts +1 -0
- package/lib/cloudflare/account-id.d.ts.map +1 -1
- package/lib/cloudflare/account-id.js.map +1 -1
- package/lib/cloudflare/api.d.ts.map +1 -1
- package/lib/cloudflare/api.js +22 -2
- package/lib/cloudflare/api.js.map +1 -1
- package/lib/cloudflare/index.d.ts +2 -1
- package/lib/cloudflare/index.d.ts.map +1 -1
- package/lib/cloudflare/index.js +2 -1
- package/lib/cloudflare/index.js.map +1 -1
- package/lib/cloudflare/queue.d.ts.map +1 -1
- package/lib/cloudflare/queue.js +1 -0
- package/lib/cloudflare/queue.js.map +1 -1
- package/lib/cloudflare/route.d.ts +7 -0
- package/lib/cloudflare/route.d.ts.map +1 -1
- package/lib/cloudflare/route.js +44 -2
- package/lib/cloudflare/route.js.map +1 -1
- package/lib/cloudflare/worker-metadata.d.ts.map +1 -1
- package/lib/cloudflare/worker-metadata.js +1 -2
- package/lib/cloudflare/worker-metadata.js.map +1 -1
- package/lib/cloudflare/worker.d.ts +2 -1
- package/lib/cloudflare/worker.d.ts.map +1 -1
- package/lib/cloudflare/worker.js +17 -8
- package/lib/cloudflare/worker.js.map +1 -1
- package/lib/cloudflare/workflow.d.ts +7 -0
- package/lib/cloudflare/workflow.d.ts.map +1 -1
- package/lib/cloudflare/workflow.js +2 -0
- package/lib/cloudflare/workflow.js.map +1 -1
- package/lib/cloudflare/wrangler.json.d.ts +1 -0
- package/lib/cloudflare/wrangler.json.d.ts.map +1 -1
- package/lib/cloudflare/wrangler.json.js +1 -0
- package/lib/cloudflare/wrangler.json.js.map +1 -1
- package/lib/destroy.js +1 -1
- package/lib/destroy.js.map +1 -1
- package/lib/dns/godaddy.d.ts.map +1 -1
- package/lib/dns/godaddy.js +2 -1
- package/lib/dns/godaddy.js.map +1 -1
- package/lib/fs/file-system-state-store.d.ts.map +1 -1
- package/lib/fs/file-system-state-store.js +14 -2
- package/lib/fs/file-system-state-store.js.map +1 -1
- package/lib/github/secret.d.ts.map +1 -1
- package/lib/github/secret.js +1 -0
- package/lib/github/secret.js.map +1 -1
- package/lib/neon/api.d.ts.map +1 -1
- package/lib/neon/api.js +2 -1
- package/lib/neon/api.js.map +1 -1
- package/lib/runtime/shims.d.ts +6 -0
- package/lib/runtime/shims.d.ts.map +1 -0
- package/lib/runtime/shims.js +27 -0
- package/lib/runtime/shims.js.map +1 -0
- package/lib/sentry/api.d.ts.map +1 -1
- package/lib/sentry/api.js +2 -1
- package/lib/sentry/api.js.map +1 -1
- package/lib/test/bun.d.ts.map +1 -1
- package/lib/test/bun.js +1 -7
- package/lib/test/bun.js.map +1 -1
- package/lib/test/prune.d.ts +2 -1
- package/lib/test/prune.d.ts.map +1 -1
- package/lib/test/prune.js +29 -5
- package/lib/test/prune.js.map +1 -1
- package/lib/test/vitest.d.ts +92 -0
- package/lib/test/vitest.d.ts.map +1 -0
- package/lib/test/vitest.js +94 -0
- package/lib/test/vitest.js.map +1 -0
- package/lib/upstash/api.d.ts.map +1 -1
- package/lib/upstash/api.js +2 -1
- package/lib/upstash/api.js.map +1 -1
- package/lib/util/retry.js +2 -2
- package/lib/util/retry.js.map +1 -1
- package/lib/util/safe-fetch.d.ts +2 -0
- package/lib/util/safe-fetch.d.ts.map +1 -0
- package/lib/util/safe-fetch.js +48 -0
- package/lib/util/safe-fetch.js.map +1 -0
- package/lib/vercel/api.d.ts.map +1 -1
- package/lib/vercel/api.js +2 -1
- package/lib/vercel/api.js.map +1 -1
- package/lib/web/vitepress/process-front-matter-files.d.ts.map +1 -1
- package/lib/web/vitepress/process-front-matter-files.js +11 -7
- package/lib/web/vitepress/process-front-matter-files.js.map +1 -1
- package/package.json +10 -6
- package/src/alchemy.ts +2 -2
- package/src/aws/bucket.ts +55 -36
- package/src/aws/control/client.ts +13 -13
- package/src/aws/control/resource.ts +19 -3
- package/src/aws/function.ts +233 -178
- package/src/aws/index.ts +1 -0
- package/src/aws/policy-attachment.ts +15 -10
- package/src/aws/policy.ts +75 -54
- package/src/aws/queue.ts +53 -36
- package/src/aws/retry.ts +38 -0
- package/src/aws/role.ts +121 -90
- package/src/aws/ses.ts +101 -73
- package/src/aws/ssm-parameter.ts +315 -0
- package/src/aws/table.ts +61 -90
- package/src/cloudflare/account-id.ts +2 -0
- package/src/cloudflare/api.ts +26 -3
- package/src/cloudflare/index.ts +2 -1
- package/src/cloudflare/queue.ts +2 -0
- package/src/cloudflare/route.ts +86 -2
- package/src/cloudflare/worker-metadata.ts +1 -2
- package/src/cloudflare/worker.ts +21 -9
- package/src/cloudflare/workflow.ts +8 -0
- package/src/cloudflare/wrangler.json.ts +8 -1
- package/src/destroy.ts +1 -1
- package/src/dns/godaddy.ts +3 -1
- package/src/fs/file-system-state-store.ts +16 -2
- package/src/github/secret.ts +2 -0
- package/src/neon/api.ts +2 -1
- package/src/sentry/api.ts +2 -1
- package/src/test/bun.ts +1 -7
- package/src/test/prune.ts +31 -4
- package/src/test/vitest.ts +209 -0
- package/src/upstash/api.ts +2 -1
- package/src/util/retry.ts +3 -3
- package/src/util/safe-fetch.ts +61 -0
- package/src/vercel/api.ts +2 -1
- package/src/web/vitepress/process-front-matter-files.ts +15 -7
package/src/aws/role.ts
CHANGED
|
@@ -19,6 +19,7 @@ import type { Context } from "../context.ts";
|
|
|
19
19
|
import { Resource } from "../resource.ts";
|
|
20
20
|
import { ignore } from "../util/ignore.ts";
|
|
21
21
|
import type { PolicyDocument } from "./policy.ts";
|
|
22
|
+
import { retry } from "./retry.ts";
|
|
22
23
|
|
|
23
24
|
/**
|
|
24
25
|
* Properties for creating or updating an IAM role
|
|
@@ -229,11 +230,13 @@ export const Role = Resource(
|
|
|
229
230
|
if (props.policies) {
|
|
230
231
|
for (const policy of props.policies) {
|
|
231
232
|
await ignore(NoSuchEntityException.name, () =>
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
233
|
+
retry(() =>
|
|
234
|
+
client.send(
|
|
235
|
+
new DeleteRolePolicyCommand({
|
|
236
|
+
RoleName: props.roleName,
|
|
237
|
+
PolicyName: policy.policyName,
|
|
238
|
+
}),
|
|
239
|
+
),
|
|
237
240
|
),
|
|
238
241
|
);
|
|
239
242
|
}
|
|
@@ -242,10 +245,12 @@ export const Role = Resource(
|
|
|
242
245
|
// We need to detach managed policies before deleting the role
|
|
243
246
|
// First, get all attached policies
|
|
244
247
|
try {
|
|
245
|
-
const attachedPoliciesResponse = await
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
248
|
+
const attachedPoliciesResponse = await retry(() =>
|
|
249
|
+
client.send(
|
|
250
|
+
new ListAttachedRolePoliciesCommand({
|
|
251
|
+
RoleName: props.roleName,
|
|
252
|
+
}),
|
|
253
|
+
),
|
|
249
254
|
);
|
|
250
255
|
|
|
251
256
|
// Detach all managed policies
|
|
@@ -253,11 +258,13 @@ export const Role = Resource(
|
|
|
253
258
|
attachedPoliciesResponse.AttachedPolicies || [];
|
|
254
259
|
for (const policy of attachedPolicies) {
|
|
255
260
|
await ignore(NoSuchEntityException.name, () =>
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
+
retry(() =>
|
|
262
|
+
client.send(
|
|
263
|
+
new DetachRolePolicyCommand({
|
|
264
|
+
RoleName: props.roleName,
|
|
265
|
+
PolicyArn: policy.PolicyArn!,
|
|
266
|
+
}),
|
|
267
|
+
),
|
|
261
268
|
),
|
|
262
269
|
);
|
|
263
270
|
}
|
|
@@ -270,10 +277,12 @@ export const Role = Resource(
|
|
|
270
277
|
|
|
271
278
|
// Try to delete the role, ignoring if it doesn't exist
|
|
272
279
|
await ignore(NoSuchEntityException.name, () =>
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
280
|
+
retry(() =>
|
|
281
|
+
client.send(
|
|
282
|
+
new DeleteRoleCommand({
|
|
283
|
+
RoleName: props.roleName,
|
|
284
|
+
}),
|
|
285
|
+
),
|
|
277
286
|
),
|
|
278
287
|
);
|
|
279
288
|
} catch (error: any) {
|
|
@@ -294,29 +303,31 @@ export const Role = Resource(
|
|
|
294
303
|
try {
|
|
295
304
|
if (this.phase === "create") {
|
|
296
305
|
// Try to create the role
|
|
297
|
-
await
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
Key,
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
306
|
+
await retry(() =>
|
|
307
|
+
client.send(
|
|
308
|
+
new CreateRoleCommand({
|
|
309
|
+
RoleName: props.roleName,
|
|
310
|
+
AssumeRolePolicyDocument: assumeRolePolicyDocument,
|
|
311
|
+
Description: props.description,
|
|
312
|
+
Path: props.path,
|
|
313
|
+
MaxSessionDuration: props.maxSessionDuration,
|
|
314
|
+
PermissionsBoundary: props.permissionsBoundary,
|
|
315
|
+
Tags: [
|
|
316
|
+
...Object.entries(props.tags || {}).map(([Key, Value]) => ({
|
|
317
|
+
Key,
|
|
318
|
+
Value,
|
|
319
|
+
})),
|
|
320
|
+
{
|
|
321
|
+
Key: "alchemy_stage",
|
|
322
|
+
Value: this.stage,
|
|
323
|
+
},
|
|
324
|
+
{
|
|
325
|
+
Key: "alchemy_resource",
|
|
326
|
+
Value: this.id,
|
|
327
|
+
},
|
|
328
|
+
],
|
|
329
|
+
}),
|
|
330
|
+
),
|
|
320
331
|
);
|
|
321
332
|
}
|
|
322
333
|
} catch (error: any) {
|
|
@@ -325,10 +336,12 @@ export const Role = Resource(
|
|
|
325
336
|
this.phase === "create"
|
|
326
337
|
) {
|
|
327
338
|
// Check if we were the ones who created it
|
|
328
|
-
const existingRole = await
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
339
|
+
const existingRole = await retry(() =>
|
|
340
|
+
client.send(
|
|
341
|
+
new GetRoleCommand({
|
|
342
|
+
RoleName: props.roleName,
|
|
343
|
+
}),
|
|
344
|
+
),
|
|
332
345
|
);
|
|
333
346
|
const roleTags =
|
|
334
347
|
existingRole.Role?.Tags?.reduce(
|
|
@@ -351,19 +364,23 @@ export const Role = Resource(
|
|
|
351
364
|
}
|
|
352
365
|
|
|
353
366
|
// Get or update the role
|
|
354
|
-
role = await
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
367
|
+
role = await retry(() =>
|
|
368
|
+
client.send(
|
|
369
|
+
new GetRoleCommand({
|
|
370
|
+
RoleName: props.roleName,
|
|
371
|
+
}),
|
|
372
|
+
),
|
|
358
373
|
);
|
|
359
374
|
|
|
360
375
|
// Update assume role policy if it changed
|
|
361
376
|
if (role.Role?.AssumeRolePolicyDocument !== assumeRolePolicyDocument) {
|
|
362
|
-
await
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
377
|
+
await retry(() =>
|
|
378
|
+
client.send(
|
|
379
|
+
new UpdateAssumeRolePolicyCommand({
|
|
380
|
+
RoleName: props.roleName,
|
|
381
|
+
PolicyDocument: assumeRolePolicyDocument,
|
|
382
|
+
}),
|
|
383
|
+
),
|
|
367
384
|
);
|
|
368
385
|
}
|
|
369
386
|
|
|
@@ -372,12 +389,14 @@ export const Role = Resource(
|
|
|
372
389
|
role.Role?.Description !== props.description ||
|
|
373
390
|
role.Role?.MaxSessionDuration !== props.maxSessionDuration
|
|
374
391
|
) {
|
|
375
|
-
await
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
392
|
+
await retry(() =>
|
|
393
|
+
client.send(
|
|
394
|
+
new UpdateRoleCommand({
|
|
395
|
+
RoleName: props.roleName,
|
|
396
|
+
Description: props.description,
|
|
397
|
+
MaxSessionDuration: props.maxSessionDuration,
|
|
398
|
+
}),
|
|
399
|
+
),
|
|
381
400
|
);
|
|
382
401
|
}
|
|
383
402
|
|
|
@@ -391,11 +410,13 @@ export const Role = Resource(
|
|
|
391
410
|
Key,
|
|
392
411
|
Value,
|
|
393
412
|
}));
|
|
394
|
-
await
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
413
|
+
await retry(() =>
|
|
414
|
+
client.send(
|
|
415
|
+
new TagRoleCommand({
|
|
416
|
+
RoleName: props.roleName,
|
|
417
|
+
Tags: tags,
|
|
418
|
+
}),
|
|
419
|
+
),
|
|
399
420
|
);
|
|
400
421
|
|
|
401
422
|
// Handle policy changes
|
|
@@ -411,11 +432,13 @@ export const Role = Resource(
|
|
|
411
432
|
)
|
|
412
433
|
) {
|
|
413
434
|
await ignore(NoSuchEntityException.name, () =>
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
435
|
+
retry(() =>
|
|
436
|
+
client.send(
|
|
437
|
+
new DeleteRolePolicyCommand({
|
|
438
|
+
RoleName: props.roleName,
|
|
439
|
+
PolicyName: oldPolicy.policyName,
|
|
440
|
+
}),
|
|
441
|
+
),
|
|
419
442
|
),
|
|
420
443
|
);
|
|
421
444
|
}
|
|
@@ -431,22 +454,26 @@ export const Role = Resource(
|
|
|
431
454
|
JSON.stringify(oldPolicy.policyDocument) !==
|
|
432
455
|
JSON.stringify(policy.policyDocument)
|
|
433
456
|
) {
|
|
434
|
-
await
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
457
|
+
await retry(() =>
|
|
458
|
+
client.send(
|
|
459
|
+
new PutRolePolicyCommand({
|
|
460
|
+
RoleName: props.roleName,
|
|
461
|
+
PolicyName: policy.policyName,
|
|
462
|
+
PolicyDocument: JSON.stringify(policy.policyDocument),
|
|
463
|
+
}),
|
|
464
|
+
),
|
|
440
465
|
);
|
|
441
466
|
}
|
|
442
467
|
}
|
|
443
468
|
|
|
444
469
|
// Handle managed policy attachments
|
|
445
470
|
// Get currently attached policies
|
|
446
|
-
const attachedPoliciesResponse = await
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
471
|
+
const attachedPoliciesResponse = await retry(() =>
|
|
472
|
+
client.send(
|
|
473
|
+
new ListAttachedRolePoliciesCommand({
|
|
474
|
+
RoleName: props.roleName,
|
|
475
|
+
}),
|
|
476
|
+
),
|
|
450
477
|
);
|
|
451
478
|
|
|
452
479
|
const currentAttachedPolicies =
|
|
@@ -460,11 +487,13 @@ export const Role = Resource(
|
|
|
460
487
|
// Detach policies that are no longer needed
|
|
461
488
|
for (const policyArn of currentPolicyArns) {
|
|
462
489
|
if (!desiredPolicyArns.includes(policyArn)) {
|
|
463
|
-
await
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
490
|
+
await retry(() =>
|
|
491
|
+
client.send(
|
|
492
|
+
new DetachRolePolicyCommand({
|
|
493
|
+
RoleName: props.roleName,
|
|
494
|
+
PolicyArn: policyArn,
|
|
495
|
+
}),
|
|
496
|
+
),
|
|
468
497
|
);
|
|
469
498
|
}
|
|
470
499
|
}
|
|
@@ -472,11 +501,13 @@ export const Role = Resource(
|
|
|
472
501
|
// Attach new policies that weren't attached before
|
|
473
502
|
for (const policyArn of desiredPolicyArns) {
|
|
474
503
|
if (!currentPolicyArns.includes(policyArn)) {
|
|
475
|
-
await
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
504
|
+
await retry(() =>
|
|
505
|
+
client.send(
|
|
506
|
+
new AttachRolePolicyCommand({
|
|
507
|
+
RoleName: props.roleName,
|
|
508
|
+
PolicyArn: policyArn,
|
|
509
|
+
}),
|
|
510
|
+
),
|
|
480
511
|
);
|
|
481
512
|
}
|
|
482
513
|
}
|
package/src/aws/ses.ts
CHANGED
|
@@ -22,6 +22,7 @@ import {
|
|
|
22
22
|
import type { Context } from "../context.ts";
|
|
23
23
|
import { Resource } from "../resource.ts";
|
|
24
24
|
import { ignore } from "../util/ignore.ts";
|
|
25
|
+
import { retry } from "./retry.ts";
|
|
25
26
|
|
|
26
27
|
/**
|
|
27
28
|
* Properties for configuring AWS SES resources
|
|
@@ -177,10 +178,12 @@ export const SES = Resource(
|
|
|
177
178
|
// Delete configuration set if it exists
|
|
178
179
|
if (output?.configurationSetName) {
|
|
179
180
|
await ignore(NotFoundException.name, () =>
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
181
|
+
retry(() =>
|
|
182
|
+
client.send(
|
|
183
|
+
new DeleteConfigurationSetCommand({
|
|
184
|
+
ConfigurationSetName: output.configurationSetName,
|
|
185
|
+
}),
|
|
186
|
+
),
|
|
184
187
|
),
|
|
185
188
|
);
|
|
186
189
|
}
|
|
@@ -188,10 +191,12 @@ export const SES = Resource(
|
|
|
188
191
|
// Delete email identity if it exists
|
|
189
192
|
if (output?.emailIdentity) {
|
|
190
193
|
await ignore(NotFoundException.name, () =>
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
194
|
+
retry(() =>
|
|
195
|
+
client.send(
|
|
196
|
+
new DeleteEmailIdentityCommand({
|
|
197
|
+
EmailIdentity: output.emailIdentity,
|
|
198
|
+
}),
|
|
199
|
+
),
|
|
195
200
|
),
|
|
196
201
|
);
|
|
197
202
|
}
|
|
@@ -211,10 +216,12 @@ export const SES = Resource(
|
|
|
211
216
|
// Check if configuration set exists
|
|
212
217
|
let configSetExists = false;
|
|
213
218
|
try {
|
|
214
|
-
await
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
219
|
+
await retry(() =>
|
|
220
|
+
client.send(
|
|
221
|
+
new GetConfigurationSetCommand({
|
|
222
|
+
ConfigurationSetName: props.configurationSetName,
|
|
223
|
+
}),
|
|
224
|
+
),
|
|
218
225
|
);
|
|
219
226
|
configSetExists = true;
|
|
220
227
|
} catch (error) {
|
|
@@ -228,49 +235,60 @@ export const SES = Resource(
|
|
|
228
235
|
if (configSetExists) {
|
|
229
236
|
// Update existing configuration set using appropriate update commands
|
|
230
237
|
if (props.sendingOptions) {
|
|
231
|
-
await
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
238
|
+
await retry(() =>
|
|
239
|
+
client.send(
|
|
240
|
+
new PutConfigurationSetSendingOptionsCommand({
|
|
241
|
+
ConfigurationSetName: props.configurationSetName,
|
|
242
|
+
SendingEnabled: props.sendingOptions!.SendingEnabled,
|
|
243
|
+
}),
|
|
244
|
+
),
|
|
236
245
|
);
|
|
237
246
|
}
|
|
238
247
|
|
|
239
248
|
if (props.reputationOptions) {
|
|
240
|
-
await
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
249
|
+
await retry(() =>
|
|
250
|
+
client.send(
|
|
251
|
+
new PutConfigurationSetReputationOptionsCommand({
|
|
252
|
+
ConfigurationSetName: props.configurationSetName,
|
|
253
|
+
ReputationMetricsEnabled:
|
|
254
|
+
props.reputationOptions!.ReputationMetricsEnabled,
|
|
255
|
+
}),
|
|
256
|
+
),
|
|
246
257
|
);
|
|
247
258
|
}
|
|
248
259
|
|
|
249
260
|
if (props.trackingOptions) {
|
|
250
|
-
await
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
261
|
+
await retry(() =>
|
|
262
|
+
client.send(
|
|
263
|
+
new PutConfigurationSetTrackingOptionsCommand({
|
|
264
|
+
ConfigurationSetName: props.configurationSetName,
|
|
265
|
+
CustomRedirectDomain:
|
|
266
|
+
props.trackingOptions!.CustomRedirectDomain,
|
|
267
|
+
}),
|
|
268
|
+
),
|
|
255
269
|
);
|
|
256
270
|
}
|
|
257
271
|
|
|
258
272
|
if (props.suppressionOptions) {
|
|
259
|
-
await
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
273
|
+
await retry(() =>
|
|
274
|
+
client.send(
|
|
275
|
+
new PutConfigurationSetSuppressionOptionsCommand({
|
|
276
|
+
ConfigurationSetName: props.configurationSetName,
|
|
277
|
+
SuppressedReasons: props.suppressionOptions!.SuppressedReasons,
|
|
278
|
+
}),
|
|
279
|
+
),
|
|
264
280
|
);
|
|
265
281
|
}
|
|
266
282
|
|
|
267
283
|
if (props.deliveryOptions) {
|
|
268
|
-
await
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
284
|
+
await retry(() =>
|
|
285
|
+
client.send(
|
|
286
|
+
new PutConfigurationSetDeliveryOptionsCommand({
|
|
287
|
+
ConfigurationSetName: props.configurationSetName,
|
|
288
|
+
TlsPolicy: props.deliveryOptions!.TlsPolicy,
|
|
289
|
+
SendingPoolName: props.deliveryOptions!.SendingPoolName,
|
|
290
|
+
}),
|
|
291
|
+
),
|
|
274
292
|
);
|
|
275
293
|
}
|
|
276
294
|
|
|
@@ -278,19 +296,21 @@ export const SES = Resource(
|
|
|
278
296
|
configurationSetArn = `arn:aws:ses:${process.env.AWS_REGION}:${process.env.AWS_ACCOUNT_ID}:configuration-set/${props.configurationSetName}`;
|
|
279
297
|
} else {
|
|
280
298
|
// Create new configuration set
|
|
281
|
-
await
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
Key,
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
299
|
+
await retry(() =>
|
|
300
|
+
client.send(
|
|
301
|
+
new CreateConfigurationSetCommand({
|
|
302
|
+
ConfigurationSetName: props.configurationSetName,
|
|
303
|
+
SendingOptions: props.sendingOptions,
|
|
304
|
+
ReputationOptions: props.reputationOptions,
|
|
305
|
+
TrackingOptions: props.trackingOptions,
|
|
306
|
+
SuppressionOptions: props.suppressionOptions,
|
|
307
|
+
DeliveryOptions: props.deliveryOptions,
|
|
308
|
+
Tags: Object.entries(props.tags || {}).map(([Key, Value]) => ({
|
|
309
|
+
Key,
|
|
310
|
+
Value,
|
|
311
|
+
})),
|
|
312
|
+
}),
|
|
313
|
+
),
|
|
294
314
|
);
|
|
295
315
|
|
|
296
316
|
// In SESv2, the ARN isn't directly returned in the response
|
|
@@ -303,10 +323,12 @@ export const SES = Resource(
|
|
|
303
323
|
// Check if identity exists
|
|
304
324
|
let getIdentityResult;
|
|
305
325
|
try {
|
|
306
|
-
getIdentityResult = await
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
326
|
+
getIdentityResult = await retry(() =>
|
|
327
|
+
client.send(
|
|
328
|
+
new GetEmailIdentityCommand({
|
|
329
|
+
EmailIdentity: props.emailIdentity,
|
|
330
|
+
}),
|
|
331
|
+
),
|
|
310
332
|
);
|
|
311
333
|
} catch (error) {
|
|
312
334
|
if (error instanceof NotFoundException) {
|
|
@@ -318,14 +340,16 @@ export const SES = Resource(
|
|
|
318
340
|
|
|
319
341
|
if (!getIdentityResult) {
|
|
320
342
|
// Create new email identity
|
|
321
|
-
const createIdentityResult = await
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
Key,
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
343
|
+
const createIdentityResult = await retry(() =>
|
|
344
|
+
client.send(
|
|
345
|
+
new CreateEmailIdentityCommand({
|
|
346
|
+
EmailIdentity: props.emailIdentity,
|
|
347
|
+
Tags: Object.entries(props.tags || {}).map(([Key, Value]) => ({
|
|
348
|
+
Key,
|
|
349
|
+
Value,
|
|
350
|
+
})),
|
|
351
|
+
}),
|
|
352
|
+
),
|
|
329
353
|
);
|
|
330
354
|
|
|
331
355
|
// If it's an email address, we don't need to explicitly verify in v2
|
|
@@ -346,21 +370,25 @@ export const SES = Resource(
|
|
|
346
370
|
// Update DKIM settings if requested
|
|
347
371
|
if (props.enableDkim !== undefined) {
|
|
348
372
|
if (props.enableDkim) {
|
|
349
|
-
await
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
373
|
+
await retry(() =>
|
|
374
|
+
client.send(
|
|
375
|
+
new PutEmailIdentityDkimAttributesCommand({
|
|
376
|
+
EmailIdentity: props.emailIdentity,
|
|
377
|
+
SigningEnabled: true,
|
|
378
|
+
}),
|
|
379
|
+
),
|
|
354
380
|
);
|
|
355
381
|
|
|
356
382
|
// We can check the current status of DKIM
|
|
357
383
|
dkimVerificationStatus = "PENDING"; // Default to pending
|
|
358
384
|
|
|
359
385
|
// Get the updated identity to check DKIM status
|
|
360
|
-
const updatedIdentity = await
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
386
|
+
const updatedIdentity = await retry(() =>
|
|
387
|
+
client.send(
|
|
388
|
+
new GetEmailIdentityCommand({
|
|
389
|
+
EmailIdentity: props.emailIdentity,
|
|
390
|
+
}),
|
|
391
|
+
),
|
|
364
392
|
);
|
|
365
393
|
|
|
366
394
|
if (updatedIdentity.DkimAttributes?.Status) {
|