@wraps.dev/cli 2.11.7 → 2.11.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/dist/cli.js
CHANGED
|
@@ -95,7 +95,7 @@ async function stateBucketExists(accountId, region) {
|
|
|
95
95
|
await client.send(new HeadBucketCommand({ Bucket: bucketName }));
|
|
96
96
|
return true;
|
|
97
97
|
} catch (error) {
|
|
98
|
-
if (error.name === "NotFound" || error.name === "NoSuchBucket" || error.$metadata?.httpStatusCode === 404) {
|
|
98
|
+
if (error instanceof Error && (error.name === "NotFound" || error.name === "NoSuchBucket" || error.$metadata?.httpStatusCode === 404)) {
|
|
99
99
|
return false;
|
|
100
100
|
}
|
|
101
101
|
throw error;
|
|
@@ -117,7 +117,8 @@ async function ensureStateBucket(accountId, region) {
|
|
|
117
117
|
await client.send(new HeadBucketCommand({ Bucket: bucketName }));
|
|
118
118
|
return bucketName;
|
|
119
119
|
} catch (error) {
|
|
120
|
-
|
|
120
|
+
const isNotFound = error instanceof Error && (error.name === "NotFound" || error.name === "NoSuchBucket" || error.$metadata?.httpStatusCode === 404);
|
|
121
|
+
if (!isNotFound) {
|
|
121
122
|
throw error;
|
|
122
123
|
}
|
|
123
124
|
}
|
|
@@ -204,7 +205,7 @@ async function downloadMetadata(bucketName, accountId, region) {
|
|
|
204
205
|
}
|
|
205
206
|
return JSON.parse(body);
|
|
206
207
|
} catch (error) {
|
|
207
|
-
if (error.name === "NoSuchKey" || error.$metadata?.httpStatusCode === 404) {
|
|
208
|
+
if (error instanceof Error && (error.name === "NoSuchKey" || error.$metadata?.httpStatusCode === 404)) {
|
|
208
209
|
return null;
|
|
209
210
|
}
|
|
210
211
|
throw error;
|
|
@@ -277,7 +278,7 @@ async function migrateLocalPulumiState(localPulumiDir, bucketName, accountId, re
|
|
|
277
278
|
await s3Stack.importStack(state);
|
|
278
279
|
} catch (error) {
|
|
279
280
|
console.error(
|
|
280
|
-
`Warning: Failed to migrate stack ${stackName}: ${error.message}`
|
|
281
|
+
`Warning: Failed to migrate stack ${stackName}: ${error instanceof Error ? error.message : error}`
|
|
281
282
|
);
|
|
282
283
|
}
|
|
283
284
|
}
|
|
@@ -351,7 +352,7 @@ async function ensurePulumiWorkDir(options) {
|
|
|
351
352
|
} catch (error) {
|
|
352
353
|
const clack47 = await import("@clack/prompts");
|
|
353
354
|
clack47.log.warn(
|
|
354
|
-
`S3 state backend unavailable (${error.message}). Using local state.`
|
|
355
|
+
`S3 state backend unavailable (${error instanceof Error ? error.message : error}). Using local state.`
|
|
355
356
|
);
|
|
356
357
|
}
|
|
357
358
|
}
|
|
@@ -825,8 +826,8 @@ async function isAWSCLIInstalled() {
|
|
|
825
826
|
}
|
|
826
827
|
async function getAWSCLIVersion() {
|
|
827
828
|
try {
|
|
828
|
-
const
|
|
829
|
-
const match =
|
|
829
|
+
const output3 = execSync("aws --version", { encoding: "utf-8" });
|
|
830
|
+
const match = output3.match(/aws-cli\/(\d+\.\d+\.\d+)/);
|
|
830
831
|
return match ? match[1] : null;
|
|
831
832
|
} catch {
|
|
832
833
|
return null;
|
|
@@ -1815,7 +1816,7 @@ async function isSESSandbox(region) {
|
|
|
1815
1816
|
);
|
|
1816
1817
|
return false;
|
|
1817
1818
|
} catch (error) {
|
|
1818
|
-
if (error.name === "InvalidParameterValue") {
|
|
1819
|
+
if (error instanceof Error && error.name === "InvalidParameterValue") {
|
|
1819
1820
|
return true;
|
|
1820
1821
|
}
|
|
1821
1822
|
throw error;
|
|
@@ -4057,7 +4058,10 @@ async function loadConnectionMetadata(accountId, region) {
|
|
|
4057
4058
|
localData = data;
|
|
4058
4059
|
}
|
|
4059
4060
|
} catch (error) {
|
|
4060
|
-
console.error(
|
|
4061
|
+
console.error(
|
|
4062
|
+
"Error loading connection metadata:",
|
|
4063
|
+
error instanceof Error ? error.message : error
|
|
4064
|
+
);
|
|
4061
4065
|
}
|
|
4062
4066
|
}
|
|
4063
4067
|
if (process.env.WRAPS_LOCAL_ONLY !== "1") {
|
|
@@ -4115,7 +4119,10 @@ async function saveConnectionMetadata(metadata) {
|
|
|
4115
4119
|
const content = JSON.stringify(metadata, null, 2);
|
|
4116
4120
|
await writeFile3(metadataPath, content, "utf-8");
|
|
4117
4121
|
} catch (error) {
|
|
4118
|
-
console.error(
|
|
4122
|
+
console.error(
|
|
4123
|
+
"Error saving connection metadata:",
|
|
4124
|
+
error instanceof Error ? error.message : error
|
|
4125
|
+
);
|
|
4119
4126
|
throw error;
|
|
4120
4127
|
}
|
|
4121
4128
|
if (process.env.WRAPS_LOCAL_ONLY !== "1") {
|
|
@@ -4165,7 +4172,10 @@ async function listConnections() {
|
|
|
4165
4172
|
}
|
|
4166
4173
|
return connections;
|
|
4167
4174
|
} catch (error) {
|
|
4168
|
-
console.error(
|
|
4175
|
+
console.error(
|
|
4176
|
+
"Error listing connections:",
|
|
4177
|
+
error instanceof Error ? error.message : error
|
|
4178
|
+
);
|
|
4169
4179
|
return [];
|
|
4170
4180
|
}
|
|
4171
4181
|
}
|
|
@@ -4467,10 +4477,10 @@ var init_metadata = __esm({
|
|
|
4467
4477
|
async function roleExists(roleName) {
|
|
4468
4478
|
try {
|
|
4469
4479
|
const { IAMClient: IAMClient4, GetRoleCommand: GetRoleCommand3 } = await import("@aws-sdk/client-iam");
|
|
4470
|
-
const
|
|
4480
|
+
const iam9 = new IAMClient4({
|
|
4471
4481
|
region: process.env.AWS_REGION || "us-east-1"
|
|
4472
4482
|
});
|
|
4473
|
-
await
|
|
4483
|
+
await iam9.send(new GetRoleCommand3({ RoleName: roleName }));
|
|
4474
4484
|
return true;
|
|
4475
4485
|
} catch (error) {
|
|
4476
4486
|
if (error instanceof Error && (error.name === "NoSuchEntityException" || error.Code === "NoSuchEntity" || error.Error?.Code === "NoSuchEntity")) {
|
|
@@ -4760,7 +4770,7 @@ import { builtinModules } from "module";
|
|
|
4760
4770
|
import { tmpdir } from "os";
|
|
4761
4771
|
import { dirname as dirname2, join as join7 } from "path";
|
|
4762
4772
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
4763
|
-
import * as
|
|
4773
|
+
import * as aws7 from "@pulumi/aws";
|
|
4764
4774
|
import * as pulumi11 from "@pulumi/pulumi";
|
|
4765
4775
|
import { build } from "esbuild";
|
|
4766
4776
|
function getPackageRoot() {
|
|
@@ -4835,7 +4845,7 @@ Try running: pnpm build`
|
|
|
4835
4845
|
}
|
|
4836
4846
|
async function deployLambdaFunctions(config2) {
|
|
4837
4847
|
const eventProcessorCode = await getLambdaCode("event-processor");
|
|
4838
|
-
const lambdaRole = new
|
|
4848
|
+
const lambdaRole = new aws7.iam.Role("wraps-email-lambda-role", {
|
|
4839
4849
|
assumeRolePolicy: JSON.stringify({
|
|
4840
4850
|
Version: "2012-10-17",
|
|
4841
4851
|
Statement: [
|
|
@@ -4850,11 +4860,11 @@ async function deployLambdaFunctions(config2) {
|
|
|
4850
4860
|
ManagedBy: "wraps-cli"
|
|
4851
4861
|
}
|
|
4852
4862
|
});
|
|
4853
|
-
new
|
|
4863
|
+
new aws7.iam.RolePolicyAttachment("wraps-email-lambda-basic-execution", {
|
|
4854
4864
|
role: lambdaRole.name,
|
|
4855
4865
|
policyArn: "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
|
|
4856
4866
|
});
|
|
4857
|
-
new
|
|
4867
|
+
new aws7.iam.RolePolicy("wraps-email-lambda-policy", {
|
|
4858
4868
|
role: lambdaRole.name,
|
|
4859
4869
|
policy: pulumi11.all([config2.tableName, config2.queueArn]).apply(
|
|
4860
4870
|
([tableName, queueArn]) => JSON.stringify({
|
|
@@ -4898,7 +4908,7 @@ async function deployLambdaFunctions(config2) {
|
|
|
4898
4908
|
RETENTION_DAYS: config2.retentionDays.toString()
|
|
4899
4909
|
}
|
|
4900
4910
|
};
|
|
4901
|
-
const eventProcessor = exists ? new
|
|
4911
|
+
const eventProcessor = exists ? new aws7.lambda.Function(
|
|
4902
4912
|
functionName,
|
|
4903
4913
|
{
|
|
4904
4914
|
name: functionName,
|
|
@@ -4919,7 +4929,7 @@ async function deployLambdaFunctions(config2) {
|
|
|
4919
4929
|
import: functionName
|
|
4920
4930
|
// Import existing function
|
|
4921
4931
|
}
|
|
4922
|
-
) : new
|
|
4932
|
+
) : new aws7.lambda.Function(functionName, {
|
|
4923
4933
|
name: functionName,
|
|
4924
4934
|
runtime: "nodejs24.x",
|
|
4925
4935
|
handler: "index.handler",
|
|
@@ -4949,14 +4959,14 @@ async function deployLambdaFunctions(config2) {
|
|
|
4949
4959
|
functionResponseTypes: ["ReportBatchItemFailures"]
|
|
4950
4960
|
// Enable partial batch responses
|
|
4951
4961
|
};
|
|
4952
|
-
const eventSourceMapping = existingMappingUuid ? new
|
|
4962
|
+
const eventSourceMapping = existingMappingUuid ? new aws7.lambda.EventSourceMapping(
|
|
4953
4963
|
"wraps-email-event-source-mapping",
|
|
4954
4964
|
mappingConfig,
|
|
4955
4965
|
{
|
|
4956
4966
|
import: existingMappingUuid
|
|
4957
4967
|
// Import with the UUID
|
|
4958
4968
|
}
|
|
4959
|
-
) : new
|
|
4969
|
+
) : new aws7.lambda.EventSourceMapping(
|
|
4960
4970
|
"wraps-email-event-source-mapping",
|
|
4961
4971
|
mappingConfig
|
|
4962
4972
|
);
|
|
@@ -4982,7 +4992,7 @@ __export(acm_exports, {
|
|
|
4982
4992
|
createACMCertificate: () => createACMCertificate
|
|
4983
4993
|
});
|
|
4984
4994
|
import { ACMClient as ACMClient2, DescribeCertificateCommand as DescribeCertificateCommand2 } from "@aws-sdk/client-acm";
|
|
4985
|
-
import * as
|
|
4995
|
+
import * as aws11 from "@pulumi/aws";
|
|
4986
4996
|
async function checkCertificateValidation(domain) {
|
|
4987
4997
|
try {
|
|
4988
4998
|
const acm3 = new ACMClient2({ region: "us-east-1" });
|
|
@@ -5009,10 +5019,10 @@ async function checkCertificateValidation(domain) {
|
|
|
5009
5019
|
}
|
|
5010
5020
|
}
|
|
5011
5021
|
async function createACMCertificate(config2) {
|
|
5012
|
-
const usEast1Provider = new
|
|
5022
|
+
const usEast1Provider = new aws11.Provider("acm-us-east-1", {
|
|
5013
5023
|
region: "us-east-1"
|
|
5014
5024
|
});
|
|
5015
|
-
const certificate = new
|
|
5025
|
+
const certificate = new aws11.acm.Certificate(
|
|
5016
5026
|
"wraps-email-tracking-cert",
|
|
5017
5027
|
{
|
|
5018
5028
|
domainName: config2.domain,
|
|
@@ -5035,7 +5045,7 @@ async function createACMCertificate(config2) {
|
|
|
5035
5045
|
);
|
|
5036
5046
|
let certificateValidation;
|
|
5037
5047
|
if (config2.hostedZoneId) {
|
|
5038
|
-
const validationRecord = new
|
|
5048
|
+
const validationRecord = new aws11.route53.Record(
|
|
5039
5049
|
"wraps-email-tracking-cert-validation",
|
|
5040
5050
|
{
|
|
5041
5051
|
zoneId: config2.hostedZoneId,
|
|
@@ -5045,7 +5055,7 @@ async function createACMCertificate(config2) {
|
|
|
5045
5055
|
ttl: 60
|
|
5046
5056
|
}
|
|
5047
5057
|
);
|
|
5048
|
-
certificateValidation = new
|
|
5058
|
+
certificateValidation = new aws11.acm.CertificateValidation(
|
|
5049
5059
|
"wraps-email-tracking-cert-validation-waiter",
|
|
5050
5060
|
{
|
|
5051
5061
|
certificateArn: certificate.arn,
|
|
@@ -5074,7 +5084,7 @@ var cloudfront_exports = {};
|
|
|
5074
5084
|
__export(cloudfront_exports, {
|
|
5075
5085
|
createCloudFrontTracking: () => createCloudFrontTracking
|
|
5076
5086
|
});
|
|
5077
|
-
import * as
|
|
5087
|
+
import * as aws12 from "@pulumi/aws";
|
|
5078
5088
|
async function findDistributionByAlias(alias) {
|
|
5079
5089
|
try {
|
|
5080
5090
|
const { CloudFrontClient, ListDistributionsCommand } = await import("@aws-sdk/client-cloudfront");
|
|
@@ -5090,10 +5100,10 @@ async function findDistributionByAlias(alias) {
|
|
|
5090
5100
|
}
|
|
5091
5101
|
}
|
|
5092
5102
|
async function createWAFWebACL() {
|
|
5093
|
-
const usEast1Provider = new
|
|
5103
|
+
const usEast1Provider = new aws12.Provider("waf-us-east-1", {
|
|
5094
5104
|
region: "us-east-1"
|
|
5095
5105
|
});
|
|
5096
|
-
const webAcl = new
|
|
5106
|
+
const webAcl = new aws12.wafv2.WebAcl(
|
|
5097
5107
|
"wraps-email-tracking-waf",
|
|
5098
5108
|
{
|
|
5099
5109
|
scope: "CLOUDFRONT",
|
|
@@ -5208,14 +5218,14 @@ async function createCloudFrontTracking(config2) {
|
|
|
5208
5218
|
Description: "Wraps email tracking CloudFront distribution"
|
|
5209
5219
|
}
|
|
5210
5220
|
};
|
|
5211
|
-
const distribution = existingDistributionId ? new
|
|
5221
|
+
const distribution = existingDistributionId ? new aws12.cloudfront.Distribution(
|
|
5212
5222
|
"wraps-email-tracking-cdn",
|
|
5213
5223
|
distributionConfig,
|
|
5214
5224
|
{
|
|
5215
5225
|
import: existingDistributionId
|
|
5216
5226
|
// Import existing distribution
|
|
5217
5227
|
}
|
|
5218
|
-
) : new
|
|
5228
|
+
) : new aws12.cloudfront.Distribution(
|
|
5219
5229
|
"wraps-email-tracking-cdn",
|
|
5220
5230
|
distributionConfig
|
|
5221
5231
|
);
|
|
@@ -5396,10 +5406,10 @@ var s3_inbound_exports = {};
|
|
|
5396
5406
|
__export(s3_inbound_exports, {
|
|
5397
5407
|
createS3InboundResources: () => createS3InboundResources
|
|
5398
5408
|
});
|
|
5399
|
-
import * as
|
|
5409
|
+
import * as aws13 from "@pulumi/aws";
|
|
5400
5410
|
async function createS3InboundResources(config2) {
|
|
5401
5411
|
const bucketName = `wraps-inbound-${config2.accountId}-${config2.region}`;
|
|
5402
|
-
const bucket = new
|
|
5412
|
+
const bucket = new aws13.s3.BucketV2("wraps-inbound-bucket", {
|
|
5403
5413
|
bucket: bucketName,
|
|
5404
5414
|
forceDestroy: true,
|
|
5405
5415
|
tags: {
|
|
@@ -5407,14 +5417,14 @@ async function createS3InboundResources(config2) {
|
|
|
5407
5417
|
Service: "email-inbound"
|
|
5408
5418
|
}
|
|
5409
5419
|
});
|
|
5410
|
-
new
|
|
5420
|
+
new aws13.s3.BucketPublicAccessBlock("wraps-inbound-public-access-block", {
|
|
5411
5421
|
bucket: bucket.id,
|
|
5412
5422
|
blockPublicAcls: true,
|
|
5413
5423
|
blockPublicPolicy: true,
|
|
5414
5424
|
ignorePublicAcls: true,
|
|
5415
5425
|
restrictPublicBuckets: true
|
|
5416
5426
|
});
|
|
5417
|
-
new
|
|
5427
|
+
new aws13.s3.BucketServerSideEncryptionConfigurationV2(
|
|
5418
5428
|
"wraps-inbound-encryption",
|
|
5419
5429
|
{
|
|
5420
5430
|
bucket: bucket.id,
|
|
@@ -5430,7 +5440,7 @@ async function createS3InboundResources(config2) {
|
|
|
5430
5440
|
if (config2.retention) {
|
|
5431
5441
|
const retentionDays = retentionToDays2(config2.retention);
|
|
5432
5442
|
if (retentionDays > 0) {
|
|
5433
|
-
new
|
|
5443
|
+
new aws13.s3.BucketLifecycleConfigurationV2("wraps-inbound-lifecycle", {
|
|
5434
5444
|
bucket: bucket.id,
|
|
5435
5445
|
rules: [
|
|
5436
5446
|
{
|
|
@@ -5444,8 +5454,8 @@ async function createS3InboundResources(config2) {
|
|
|
5444
5454
|
});
|
|
5445
5455
|
}
|
|
5446
5456
|
}
|
|
5447
|
-
const identity = await
|
|
5448
|
-
new
|
|
5457
|
+
const identity = await aws13.getCallerIdentity();
|
|
5458
|
+
new aws13.s3.BucketPolicy("wraps-inbound-bucket-policy", {
|
|
5449
5459
|
bucket: bucket.id,
|
|
5450
5460
|
policy: bucket.arn.apply(
|
|
5451
5461
|
(arn) => JSON.stringify({
|
|
@@ -5487,9 +5497,9 @@ var sqs_inbound_exports = {};
|
|
|
5487
5497
|
__export(sqs_inbound_exports, {
|
|
5488
5498
|
createSQSInboundResources: () => createSQSInboundResources
|
|
5489
5499
|
});
|
|
5490
|
-
import * as
|
|
5500
|
+
import * as aws14 from "@pulumi/aws";
|
|
5491
5501
|
function createSQSInboundResources() {
|
|
5492
|
-
const dlq = new
|
|
5502
|
+
const dlq = new aws14.sqs.Queue("wraps-inbound-events-dlq", {
|
|
5493
5503
|
name: "wraps-inbound-events-dlq",
|
|
5494
5504
|
messageRetentionSeconds: 1209600,
|
|
5495
5505
|
// 14 days
|
|
@@ -5499,7 +5509,7 @@ function createSQSInboundResources() {
|
|
|
5499
5509
|
Description: "Dead letter queue for failed inbound email processing"
|
|
5500
5510
|
}
|
|
5501
5511
|
});
|
|
5502
|
-
const queue = new
|
|
5512
|
+
const queue = new aws14.sqs.Queue("wraps-inbound-events", {
|
|
5503
5513
|
name: "wraps-inbound-events",
|
|
5504
5514
|
visibilityTimeoutSeconds: 300,
|
|
5505
5515
|
// Must be >= Lambda timeout (120s) * 2 + buffer
|
|
@@ -5536,11 +5546,11 @@ var lambda_inbound_exports = {};
|
|
|
5536
5546
|
__export(lambda_inbound_exports, {
|
|
5537
5547
|
deployInboundLambda: () => deployInboundLambda
|
|
5538
5548
|
});
|
|
5539
|
-
import * as
|
|
5549
|
+
import * as aws15 from "@pulumi/aws";
|
|
5540
5550
|
import * as pulumi12 from "@pulumi/pulumi";
|
|
5541
5551
|
async function deployInboundLambda(config2) {
|
|
5542
5552
|
const inboundProcessorCode = await getLambdaCode("inbound-processor");
|
|
5543
|
-
const lambdaRole = new
|
|
5553
|
+
const lambdaRole = new aws15.iam.Role("wraps-inbound-lambda-role", {
|
|
5544
5554
|
name: "wraps-inbound-lambda-role",
|
|
5545
5555
|
assumeRolePolicy: JSON.stringify({
|
|
5546
5556
|
Version: "2012-10-17",
|
|
@@ -5557,11 +5567,11 @@ async function deployInboundLambda(config2) {
|
|
|
5557
5567
|
Service: "email-inbound"
|
|
5558
5568
|
}
|
|
5559
5569
|
});
|
|
5560
|
-
new
|
|
5570
|
+
new aws15.iam.RolePolicyAttachment("wraps-inbound-lambda-basic-execution", {
|
|
5561
5571
|
role: lambdaRole.name,
|
|
5562
5572
|
policyArn: "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
|
|
5563
5573
|
});
|
|
5564
|
-
new
|
|
5574
|
+
new aws15.iam.RolePolicy("wraps-inbound-lambda-policy", {
|
|
5565
5575
|
role: lambdaRole.name,
|
|
5566
5576
|
policy: pulumi12.all([config2.bucketArn, config2.dlqArn]).apply(
|
|
5567
5577
|
([bucketArn, dlqArn]) => JSON.stringify({
|
|
@@ -5590,7 +5600,7 @@ async function deployInboundLambda(config2) {
|
|
|
5590
5600
|
)
|
|
5591
5601
|
});
|
|
5592
5602
|
const functionName = "wraps-inbound-email-processor";
|
|
5593
|
-
const lambdaFunction = new
|
|
5603
|
+
const lambdaFunction = new aws15.lambda.Function(functionName, {
|
|
5594
5604
|
name: functionName,
|
|
5595
5605
|
runtime: "nodejs20.x",
|
|
5596
5606
|
handler: "index.handler",
|
|
@@ -5612,7 +5622,7 @@ async function deployInboundLambda(config2) {
|
|
|
5612
5622
|
Service: "email-inbound"
|
|
5613
5623
|
}
|
|
5614
5624
|
});
|
|
5615
|
-
const s3InvokePermission = new
|
|
5625
|
+
const s3InvokePermission = new aws15.lambda.Permission(
|
|
5616
5626
|
"wraps-inbound-s3-invoke",
|
|
5617
5627
|
{
|
|
5618
5628
|
action: "lambda:InvokeFunction",
|
|
@@ -5640,9 +5650,9 @@ var eventbridge_inbound_exports = {};
|
|
|
5640
5650
|
__export(eventbridge_inbound_exports, {
|
|
5641
5651
|
createEventBridgeInboundResources: () => createEventBridgeInboundResources
|
|
5642
5652
|
});
|
|
5643
|
-
import * as
|
|
5653
|
+
import * as aws16 from "@pulumi/aws";
|
|
5644
5654
|
function createEventBridgeInboundResources(config2) {
|
|
5645
|
-
const rule = new
|
|
5655
|
+
const rule = new aws16.cloudwatch.EventRule("wraps-inbound-events-rule", {
|
|
5646
5656
|
name: "wraps-inbound-events-to-webhook",
|
|
5647
5657
|
description: "Route inbound email events to webhook",
|
|
5648
5658
|
eventBusName: "default",
|
|
@@ -5659,7 +5669,7 @@ function createEventBridgeInboundResources(config2) {
|
|
|
5659
5669
|
let webhookApiDestination;
|
|
5660
5670
|
let webhookTarget;
|
|
5661
5671
|
if (config2.webhookUrl && config2.webhookSecret) {
|
|
5662
|
-
webhookConnection = new
|
|
5672
|
+
webhookConnection = new aws16.cloudwatch.EventConnection(
|
|
5663
5673
|
"wraps-inbound-webhook-connection",
|
|
5664
5674
|
{
|
|
5665
5675
|
name: "wraps-inbound-webhook-connection",
|
|
@@ -5673,7 +5683,7 @@ function createEventBridgeInboundResources(config2) {
|
|
|
5673
5683
|
}
|
|
5674
5684
|
}
|
|
5675
5685
|
);
|
|
5676
|
-
webhookApiDestination = new
|
|
5686
|
+
webhookApiDestination = new aws16.cloudwatch.EventApiDestination(
|
|
5677
5687
|
"wraps-inbound-webhook-destination",
|
|
5678
5688
|
{
|
|
5679
5689
|
name: "wraps-inbound-webhook-destination",
|
|
@@ -5684,7 +5694,7 @@ function createEventBridgeInboundResources(config2) {
|
|
|
5684
5694
|
invocationRateLimitPerSecond: 100
|
|
5685
5695
|
}
|
|
5686
5696
|
);
|
|
5687
|
-
const webhookRole = new
|
|
5697
|
+
const webhookRole = new aws16.iam.Role("wraps-inbound-webhook-role", {
|
|
5688
5698
|
name: "wraps-inbound-eventbridge-webhook-role",
|
|
5689
5699
|
assumeRolePolicy: JSON.stringify({
|
|
5690
5700
|
Version: "2012-10-17",
|
|
@@ -5703,7 +5713,7 @@ function createEventBridgeInboundResources(config2) {
|
|
|
5703
5713
|
Service: "email-inbound"
|
|
5704
5714
|
}
|
|
5705
5715
|
});
|
|
5706
|
-
new
|
|
5716
|
+
new aws16.iam.RolePolicy("wraps-inbound-webhook-policy", {
|
|
5707
5717
|
role: webhookRole.name,
|
|
5708
5718
|
policy: webhookApiDestination.arn.apply(
|
|
5709
5719
|
(destArn) => JSON.stringify({
|
|
@@ -5718,7 +5728,7 @@ function createEventBridgeInboundResources(config2) {
|
|
|
5718
5728
|
})
|
|
5719
5729
|
)
|
|
5720
5730
|
});
|
|
5721
|
-
webhookTarget = new
|
|
5731
|
+
webhookTarget = new aws16.cloudwatch.EventTarget(
|
|
5722
5732
|
"wraps-inbound-webhook-target",
|
|
5723
5733
|
{
|
|
5724
5734
|
rule: rule.name,
|
|
@@ -9419,13 +9429,12 @@ async function deleteCdnDNSRecords(hostedZoneId, customDomain) {
|
|
|
9419
9429
|
// src/commands/cdn/init.ts
|
|
9420
9430
|
init_esm_shims();
|
|
9421
9431
|
import * as clack10 from "@clack/prompts";
|
|
9422
|
-
import * as
|
|
9432
|
+
import * as pulumi5 from "@pulumi/pulumi";
|
|
9423
9433
|
import pc11 from "picocolors";
|
|
9424
9434
|
|
|
9425
9435
|
// src/infrastructure/cdn-stack.ts
|
|
9426
9436
|
init_esm_shims();
|
|
9427
|
-
import * as
|
|
9428
|
-
import * as pulumi3 from "@pulumi/pulumi";
|
|
9437
|
+
import * as pulumi4 from "@pulumi/pulumi";
|
|
9429
9438
|
|
|
9430
9439
|
// src/infrastructure/resources/s3-cdn.ts
|
|
9431
9440
|
init_esm_shims();
|
|
@@ -9749,19 +9758,133 @@ async function createCdnACMCertificate(config2) {
|
|
|
9749
9758
|
};
|
|
9750
9759
|
}
|
|
9751
9760
|
|
|
9752
|
-
// src/infrastructure/
|
|
9761
|
+
// src/infrastructure/shared/iam.ts
|
|
9762
|
+
init_esm_shims();
|
|
9753
9763
|
init_resource_checks();
|
|
9764
|
+
import * as aws2 from "@pulumi/aws";
|
|
9765
|
+
import * as pulumi3 from "@pulumi/pulumi";
|
|
9766
|
+
async function createServiceIAMRole(config2) {
|
|
9767
|
+
let assumeRolePolicy;
|
|
9768
|
+
if (config2.provider === "vercel" && config2.oidcProvider) {
|
|
9769
|
+
const hasAdditionalPrincipals = config2.additionalVercelPrincipals && config2.additionalVercelPrincipals.length > 0;
|
|
9770
|
+
if (hasAdditionalPrincipals) {
|
|
9771
|
+
const serviceStatement = JSON.stringify({
|
|
9772
|
+
Effect: "Allow",
|
|
9773
|
+
Principal: {
|
|
9774
|
+
Service: config2.additionalVercelPrincipals.length === 1 ? config2.additionalVercelPrincipals[0] : config2.additionalVercelPrincipals
|
|
9775
|
+
},
|
|
9776
|
+
Action: "sts:AssumeRole"
|
|
9777
|
+
});
|
|
9778
|
+
assumeRolePolicy = pulumi3.interpolate`{
|
|
9779
|
+
"Version": "2012-10-17",
|
|
9780
|
+
"Statement": [
|
|
9781
|
+
{
|
|
9782
|
+
"Effect": "Allow",
|
|
9783
|
+
"Principal": {
|
|
9784
|
+
"Federated": "${config2.oidcProvider.arn}"
|
|
9785
|
+
},
|
|
9786
|
+
"Action": "sts:AssumeRoleWithWebIdentity",
|
|
9787
|
+
"Condition": {
|
|
9788
|
+
"StringEquals": {
|
|
9789
|
+
"oidc.vercel.com/${config2.vercelTeamSlug}:aud": "https://vercel.com/${config2.vercelTeamSlug}"
|
|
9790
|
+
},
|
|
9791
|
+
"StringLike": {
|
|
9792
|
+
"oidc.vercel.com/${config2.vercelTeamSlug}:sub": "owner:${config2.vercelTeamSlug}:project:${config2.vercelProjectName}:environment:*"
|
|
9793
|
+
}
|
|
9794
|
+
}
|
|
9795
|
+
},
|
|
9796
|
+
${serviceStatement}
|
|
9797
|
+
]
|
|
9798
|
+
}`;
|
|
9799
|
+
} else {
|
|
9800
|
+
assumeRolePolicy = pulumi3.interpolate`{
|
|
9801
|
+
"Version": "2012-10-17",
|
|
9802
|
+
"Statement": [{
|
|
9803
|
+
"Effect": "Allow",
|
|
9804
|
+
"Principal": {
|
|
9805
|
+
"Federated": "${config2.oidcProvider.arn}"
|
|
9806
|
+
},
|
|
9807
|
+
"Action": "sts:AssumeRoleWithWebIdentity",
|
|
9808
|
+
"Condition": {
|
|
9809
|
+
"StringEquals": {
|
|
9810
|
+
"oidc.vercel.com/${config2.vercelTeamSlug}:aud": "https://vercel.com/${config2.vercelTeamSlug}"
|
|
9811
|
+
},
|
|
9812
|
+
"StringLike": {
|
|
9813
|
+
"oidc.vercel.com/${config2.vercelTeamSlug}:sub": "owner:${config2.vercelTeamSlug}:project:${config2.vercelProjectName}:environment:*"
|
|
9814
|
+
}
|
|
9815
|
+
}
|
|
9816
|
+
}]
|
|
9817
|
+
}`;
|
|
9818
|
+
}
|
|
9819
|
+
} else if (config2.provider === "aws") {
|
|
9820
|
+
assumeRolePolicy = pulumi3.output(`{
|
|
9821
|
+
"Version": "2012-10-17",
|
|
9822
|
+
"Statement": [{
|
|
9823
|
+
"Effect": "Allow",
|
|
9824
|
+
"Principal": {
|
|
9825
|
+
"Service": ["lambda.amazonaws.com", "ec2.amazonaws.com", "ecs-tasks.amazonaws.com"]
|
|
9826
|
+
},
|
|
9827
|
+
"Action": "sts:AssumeRole"
|
|
9828
|
+
}]
|
|
9829
|
+
}`);
|
|
9830
|
+
} else {
|
|
9831
|
+
throw new Error("Other providers not yet implemented");
|
|
9832
|
+
}
|
|
9833
|
+
const roleName = `wraps-${config2.serviceName}-role`;
|
|
9834
|
+
const exists = await roleExists(roleName);
|
|
9835
|
+
const tags = {
|
|
9836
|
+
ManagedBy: "wraps-cli",
|
|
9837
|
+
Provider: config2.provider,
|
|
9838
|
+
...config2.extraTags
|
|
9839
|
+
};
|
|
9840
|
+
const role = exists ? new aws2.iam.Role(
|
|
9841
|
+
roleName,
|
|
9842
|
+
{ name: roleName, assumeRolePolicy, tags },
|
|
9843
|
+
{
|
|
9844
|
+
import: roleName,
|
|
9845
|
+
...config2.customTimeouts && {
|
|
9846
|
+
customTimeouts: config2.customTimeouts
|
|
9847
|
+
}
|
|
9848
|
+
}
|
|
9849
|
+
) : new aws2.iam.Role(
|
|
9850
|
+
roleName,
|
|
9851
|
+
{ name: roleName, assumeRolePolicy, tags },
|
|
9852
|
+
config2.customTimeouts ? { customTimeouts: config2.customTimeouts } : void 0
|
|
9853
|
+
);
|
|
9854
|
+
const policyName = `wraps-${config2.serviceName}-policy`;
|
|
9855
|
+
const isOutputStatements = pulumi3.Output.isInstance(config2.policyStatements);
|
|
9856
|
+
if (isOutputStatements) {
|
|
9857
|
+
new aws2.iam.RolePolicy(policyName, {
|
|
9858
|
+
role: role.name,
|
|
9859
|
+
policy: config2.policyStatements.apply(
|
|
9860
|
+
(stmts) => JSON.stringify({
|
|
9861
|
+
Version: "2012-10-17",
|
|
9862
|
+
Statement: stmts
|
|
9863
|
+
})
|
|
9864
|
+
)
|
|
9865
|
+
});
|
|
9866
|
+
} else {
|
|
9867
|
+
new aws2.iam.RolePolicy(policyName, {
|
|
9868
|
+
role: role.name,
|
|
9869
|
+
policy: JSON.stringify({
|
|
9870
|
+
Version: "2012-10-17",
|
|
9871
|
+
Statement: config2.policyStatements
|
|
9872
|
+
})
|
|
9873
|
+
});
|
|
9874
|
+
}
|
|
9875
|
+
return role;
|
|
9876
|
+
}
|
|
9754
9877
|
|
|
9755
9878
|
// src/infrastructure/vercel-oidc.ts
|
|
9756
9879
|
init_esm_shims();
|
|
9757
|
-
import * as
|
|
9880
|
+
import * as aws3 from "@pulumi/aws";
|
|
9758
9881
|
async function getExistingOIDCProviderArn(url) {
|
|
9759
9882
|
try {
|
|
9760
9883
|
const { IAMClient: IAMClient4, ListOpenIDConnectProvidersCommand } = await import("@aws-sdk/client-iam");
|
|
9761
|
-
const
|
|
9884
|
+
const iam9 = new IAMClient4({
|
|
9762
9885
|
region: process.env.AWS_REGION || "us-east-1"
|
|
9763
9886
|
});
|
|
9764
|
-
const response = await
|
|
9887
|
+
const response = await iam9.send(new ListOpenIDConnectProvidersCommand({}));
|
|
9765
9888
|
const expectedArnSuffix = url.replace("https://", "");
|
|
9766
9889
|
const provider = response.OpenIDConnectProviderList?.find(
|
|
9767
9890
|
(p) => p.Arn?.endsWith(expectedArnSuffix)
|
|
@@ -9776,7 +9899,7 @@ async function createVercelOIDC(config2) {
|
|
|
9776
9899
|
const url = `https://oidc.vercel.com/${config2.teamSlug}`;
|
|
9777
9900
|
const existingArn = await getExistingOIDCProviderArn(url);
|
|
9778
9901
|
if (existingArn) {
|
|
9779
|
-
return new
|
|
9902
|
+
return new aws3.iam.OpenIdConnectProvider(
|
|
9780
9903
|
"wraps-vercel-oidc",
|
|
9781
9904
|
{
|
|
9782
9905
|
url,
|
|
@@ -9797,7 +9920,7 @@ async function createVercelOIDC(config2) {
|
|
|
9797
9920
|
}
|
|
9798
9921
|
);
|
|
9799
9922
|
}
|
|
9800
|
-
return new
|
|
9923
|
+
return new aws3.iam.OpenIdConnectProvider("wraps-vercel-oidc", {
|
|
9801
9924
|
url,
|
|
9802
9925
|
clientIdLists: [`https://vercel.com/${config2.teamSlug}`],
|
|
9803
9926
|
thumbprintLists: [
|
|
@@ -9814,104 +9937,46 @@ async function createVercelOIDC(config2) {
|
|
|
9814
9937
|
|
|
9815
9938
|
// src/infrastructure/cdn-stack.ts
|
|
9816
9939
|
async function createCdnIAMRole(config2) {
|
|
9817
|
-
|
|
9818
|
-
|
|
9819
|
-
|
|
9820
|
-
|
|
9821
|
-
|
|
9822
|
-
|
|
9823
|
-
|
|
9824
|
-
"
|
|
9825
|
-
|
|
9826
|
-
|
|
9827
|
-
|
|
9828
|
-
"
|
|
9829
|
-
|
|
9830
|
-
|
|
9831
|
-
|
|
9832
|
-
"oidc.vercel.com/${config2.vercelTeamSlug}:sub": "owner:${config2.vercelTeamSlug}:project:${config2.vercelProjectName}:environment:*"
|
|
9833
|
-
}
|
|
9834
|
-
}
|
|
9835
|
-
}]
|
|
9836
|
-
}`;
|
|
9837
|
-
} else if (config2.provider === "aws") {
|
|
9838
|
-
assumeRolePolicy = pulumi3.output(`{
|
|
9839
|
-
"Version": "2012-10-17",
|
|
9840
|
-
"Statement": [{
|
|
9841
|
-
"Effect": "Allow",
|
|
9842
|
-
"Principal": {
|
|
9843
|
-
"Service": ["lambda.amazonaws.com", "ec2.amazonaws.com", "ecs-tasks.amazonaws.com"]
|
|
9844
|
-
},
|
|
9845
|
-
"Action": "sts:AssumeRole"
|
|
9846
|
-
}]
|
|
9847
|
-
}`);
|
|
9848
|
-
} else {
|
|
9849
|
-
throw new Error("Other providers not yet implemented");
|
|
9850
|
-
}
|
|
9851
|
-
const roleName = "wraps-cdn-role";
|
|
9852
|
-
const exists = await roleExists(roleName);
|
|
9853
|
-
const role = exists ? new aws3.iam.Role(
|
|
9854
|
-
roleName,
|
|
9855
|
-
{
|
|
9856
|
-
name: roleName,
|
|
9857
|
-
assumeRolePolicy,
|
|
9858
|
-
tags: {
|
|
9859
|
-
ManagedBy: "wraps-cli",
|
|
9860
|
-
Service: "cdn",
|
|
9861
|
-
Provider: config2.provider
|
|
9940
|
+
const resolvedStatements = pulumi4.all([config2.bucketArn, config2.distributionArn]).apply(([bucketArn, distributionArn]) => {
|
|
9941
|
+
const statements = [
|
|
9942
|
+
{
|
|
9943
|
+
Sid: "StorageBucketAccess",
|
|
9944
|
+
Effect: "Allow",
|
|
9945
|
+
Action: [
|
|
9946
|
+
"s3:PutObject",
|
|
9947
|
+
"s3:GetObject",
|
|
9948
|
+
"s3:DeleteObject",
|
|
9949
|
+
"s3:ListBucket",
|
|
9950
|
+
"s3:GetBucketLocation",
|
|
9951
|
+
"s3:GetObjectTagging",
|
|
9952
|
+
"s3:PutObjectTagging"
|
|
9953
|
+
],
|
|
9954
|
+
Resource: [bucketArn, `${bucketArn}/*`]
|
|
9862
9955
|
}
|
|
9863
|
-
|
|
9864
|
-
{
|
|
9865
|
-
|
|
9866
|
-
|
|
9867
|
-
|
|
9868
|
-
|
|
9869
|
-
|
|
9870
|
-
|
|
9871
|
-
|
|
9872
|
-
|
|
9873
|
-
|
|
9956
|
+
];
|
|
9957
|
+
if (distributionArn) {
|
|
9958
|
+
statements.push({
|
|
9959
|
+
Sid: "CloudFrontInvalidation",
|
|
9960
|
+
Effect: "Allow",
|
|
9961
|
+
Action: [
|
|
9962
|
+
"cloudfront:CreateInvalidation",
|
|
9963
|
+
"cloudfront:GetInvalidation",
|
|
9964
|
+
"cloudfront:ListInvalidations"
|
|
9965
|
+
],
|
|
9966
|
+
Resource: distributionArn
|
|
9967
|
+
});
|
|
9874
9968
|
}
|
|
9969
|
+
return statements;
|
|
9875
9970
|
});
|
|
9876
|
-
|
|
9877
|
-
|
|
9878
|
-
|
|
9879
|
-
|
|
9880
|
-
|
|
9881
|
-
|
|
9882
|
-
|
|
9883
|
-
|
|
9884
|
-
"s3:DeleteObject",
|
|
9885
|
-
"s3:ListBucket",
|
|
9886
|
-
"s3:GetBucketLocation",
|
|
9887
|
-
"s3:GetObjectTagging",
|
|
9888
|
-
"s3:PutObjectTagging"
|
|
9889
|
-
],
|
|
9890
|
-
Resource: [config2.bucketArn, pulumi3.interpolate`${config2.bucketArn}/*`]
|
|
9891
|
-
}
|
|
9892
|
-
];
|
|
9893
|
-
if (config2.distributionArn) {
|
|
9894
|
-
statements.push({
|
|
9895
|
-
Sid: "CloudFrontInvalidation",
|
|
9896
|
-
Effect: "Allow",
|
|
9897
|
-
Action: [
|
|
9898
|
-
"cloudfront:CreateInvalidation",
|
|
9899
|
-
"cloudfront:GetInvalidation",
|
|
9900
|
-
"cloudfront:ListInvalidations"
|
|
9901
|
-
],
|
|
9902
|
-
Resource: config2.distributionArn
|
|
9903
|
-
});
|
|
9904
|
-
}
|
|
9905
|
-
new aws3.iam.RolePolicy("wraps-cdn-policy", {
|
|
9906
|
-
role: role.name,
|
|
9907
|
-
policy: pulumi3.all([statements]).apply(
|
|
9908
|
-
([stmts]) => JSON.stringify({
|
|
9909
|
-
Version: "2012-10-17",
|
|
9910
|
-
Statement: stmts
|
|
9911
|
-
})
|
|
9912
|
-
)
|
|
9971
|
+
return createServiceIAMRole({
|
|
9972
|
+
serviceName: "cdn",
|
|
9973
|
+
provider: config2.provider,
|
|
9974
|
+
oidcProvider: config2.oidcProvider,
|
|
9975
|
+
vercelTeamSlug: config2.vercelTeamSlug,
|
|
9976
|
+
vercelProjectName: config2.vercelProjectName,
|
|
9977
|
+
policyStatements: resolvedStatements,
|
|
9978
|
+
extraTags: { Service: "cdn" }
|
|
9913
9979
|
});
|
|
9914
|
-
return role;
|
|
9915
9980
|
}
|
|
9916
9981
|
async function deployCdnStack(config2) {
|
|
9917
9982
|
const accountId = config2.accountId;
|
|
@@ -9943,7 +10008,7 @@ async function deployCdnStack(config2) {
|
|
|
9943
10008
|
if (config2.cdnConfig.cdn.enabled) {
|
|
9944
10009
|
const hasAutoValidation2 = acmResources?.certificateValidation;
|
|
9945
10010
|
const useCertFromUpgrade = config2.certValidated && config2.existingCertArn;
|
|
9946
|
-
const certificateArn = useCertFromUpgrade ?
|
|
10011
|
+
const certificateArn = useCertFromUpgrade ? pulumi4.output(config2.existingCertArn) : hasAutoValidation2 ? acmResources?.certificateValidation?.certificateArn : void 0;
|
|
9947
10012
|
const customDomainForCdn = useCertFromUpgrade || hasAutoValidation2 ? config2.cdnConfig.cdn.customDomain : void 0;
|
|
9948
10013
|
cdnResources = await createCdnDistribution({
|
|
9949
10014
|
bucket: bucketResources.bucket,
|
|
@@ -10529,7 +10594,7 @@ ${pc11.yellow(pc11.bold("Configuration Notes:"))}`);
|
|
|
10529
10594
|
"Generating infrastructure preview",
|
|
10530
10595
|
async () => {
|
|
10531
10596
|
await ensurePulumiWorkDir({ accountId: identity.accountId, region });
|
|
10532
|
-
const stack = await
|
|
10597
|
+
const stack = await pulumi5.automation.LocalWorkspace.createOrSelectStack(
|
|
10533
10598
|
{
|
|
10534
10599
|
stackName: `wraps-cdn-${identity.accountId}-${region}`,
|
|
10535
10600
|
projectName: "wraps-cdn",
|
|
@@ -10594,7 +10659,7 @@ ${pc11.yellow(pc11.bold("Configuration Notes:"))}`);
|
|
|
10594
10659
|
"Deploying CDN infrastructure (this may take 2-3 minutes)",
|
|
10595
10660
|
async () => {
|
|
10596
10661
|
await ensurePulumiWorkDir({ accountId: identity.accountId, region });
|
|
10597
|
-
const stack = await
|
|
10662
|
+
const stack = await pulumi5.automation.LocalWorkspace.createOrSelectStack(
|
|
10598
10663
|
{
|
|
10599
10664
|
stackName: `wraps-cdn-${identity.accountId}-${region}`,
|
|
10600
10665
|
projectName: "wraps-cdn",
|
|
@@ -10929,7 +10994,7 @@ init_aws();
|
|
|
10929
10994
|
init_fs();
|
|
10930
10995
|
init_metadata();
|
|
10931
10996
|
import * as clack11 from "@clack/prompts";
|
|
10932
|
-
import * as
|
|
10997
|
+
import * as pulumi6 from "@pulumi/pulumi";
|
|
10933
10998
|
import pc12 from "picocolors";
|
|
10934
10999
|
async function cdnStatus(options) {
|
|
10935
11000
|
const startTime = Date.now();
|
|
@@ -10965,7 +11030,7 @@ async function cdnStatus(options) {
|
|
|
10965
11030
|
let stackOutputs = {};
|
|
10966
11031
|
try {
|
|
10967
11032
|
await ensurePulumiWorkDir({ accountId: identity.accountId, region });
|
|
10968
|
-
const stack = await
|
|
11033
|
+
const stack = await pulumi6.automation.LocalWorkspace.selectStack({
|
|
10969
11034
|
stackName: `wraps-cdn-${identity.accountId}-${region}`,
|
|
10970
11035
|
workDir: getPulumiWorkDir()
|
|
10971
11036
|
});
|
|
@@ -11087,7 +11152,7 @@ ${pc12.bold("Commands:")}`);
|
|
|
11087
11152
|
// src/commands/cdn/sync.ts
|
|
11088
11153
|
init_esm_shims();
|
|
11089
11154
|
import * as clack12 from "@clack/prompts";
|
|
11090
|
-
import * as
|
|
11155
|
+
import * as pulumi7 from "@pulumi/pulumi";
|
|
11091
11156
|
import pc13 from "picocolors";
|
|
11092
11157
|
init_client();
|
|
11093
11158
|
init_events();
|
|
@@ -11143,7 +11208,7 @@ async function cdnSync(options) {
|
|
|
11143
11208
|
if (cdnConfig.cdn.customDomain) {
|
|
11144
11209
|
try {
|
|
11145
11210
|
await ensurePulumiWorkDir({ accountId: identity.accountId, region });
|
|
11146
|
-
const checkStack = await
|
|
11211
|
+
const checkStack = await pulumi7.automation.LocalWorkspace.selectStack({
|
|
11147
11212
|
stackName: `wraps-cdn-${identity.accountId}-${region}`,
|
|
11148
11213
|
workDir: getPulumiWorkDir()
|
|
11149
11214
|
});
|
|
@@ -11180,7 +11245,7 @@ async function cdnSync(options) {
|
|
|
11180
11245
|
try {
|
|
11181
11246
|
await progress.execute("Syncing CDN infrastructure", async () => {
|
|
11182
11247
|
await ensurePulumiWorkDir({ accountId: identity.accountId, region });
|
|
11183
|
-
const stack = await
|
|
11248
|
+
const stack = await pulumi7.automation.LocalWorkspace.createOrSelectStack(
|
|
11184
11249
|
{
|
|
11185
11250
|
stackName: `wraps-cdn-${identity.accountId}-${region}`,
|
|
11186
11251
|
projectName: "wraps-cdn",
|
|
@@ -11242,7 +11307,7 @@ async function cdnSync(options) {
|
|
|
11242
11307
|
// src/commands/cdn/upgrade.ts
|
|
11243
11308
|
init_esm_shims();
|
|
11244
11309
|
import * as clack13 from "@clack/prompts";
|
|
11245
|
-
import * as
|
|
11310
|
+
import * as pulumi8 from "@pulumi/pulumi";
|
|
11246
11311
|
import pc14 from "picocolors";
|
|
11247
11312
|
init_client();
|
|
11248
11313
|
init_events();
|
|
@@ -11298,7 +11363,7 @@ async function cdnUpgrade(options) {
|
|
|
11298
11363
|
let stackOutputs = {};
|
|
11299
11364
|
try {
|
|
11300
11365
|
await ensurePulumiWorkDir({ accountId: identity.accountId, region });
|
|
11301
|
-
const stack = await
|
|
11366
|
+
const stack = await pulumi8.automation.LocalWorkspace.selectStack({
|
|
11302
11367
|
stackName: `wraps-cdn-${identity.accountId}-${region}`,
|
|
11303
11368
|
workDir: getPulumiWorkDir()
|
|
11304
11369
|
});
|
|
@@ -11436,7 +11501,7 @@ Ready to add custom domain: ${pc14.cyan(pendingDomain)}`);
|
|
|
11436
11501
|
"Updating CloudFront distribution (this may take 2-3 minutes)",
|
|
11437
11502
|
async () => {
|
|
11438
11503
|
await ensurePulumiWorkDir({ accountId: identity.accountId, region });
|
|
11439
|
-
const stack = await
|
|
11504
|
+
const stack = await pulumi8.automation.LocalWorkspace.createOrSelectStack(
|
|
11440
11505
|
{
|
|
11441
11506
|
stackName: `wraps-cdn-${identity.accountId}-${region}`,
|
|
11442
11507
|
projectName: "wraps-cdn",
|
|
@@ -11524,7 +11589,7 @@ init_aws();
|
|
|
11524
11589
|
init_fs();
|
|
11525
11590
|
init_metadata();
|
|
11526
11591
|
import * as clack14 from "@clack/prompts";
|
|
11527
|
-
import * as
|
|
11592
|
+
import * as pulumi9 from "@pulumi/pulumi";
|
|
11528
11593
|
import pc15 from "picocolors";
|
|
11529
11594
|
async function checkDNSRecord(hostname, expectedValue) {
|
|
11530
11595
|
try {
|
|
@@ -11607,7 +11672,7 @@ async function cdnVerify(options) {
|
|
|
11607
11672
|
let stackOutputs = {};
|
|
11608
11673
|
try {
|
|
11609
11674
|
await ensurePulumiWorkDir({ accountId: identity.accountId, region });
|
|
11610
|
-
const stack = await
|
|
11675
|
+
const stack = await pulumi9.automation.LocalWorkspace.selectStack({
|
|
11611
11676
|
stackName: `wraps-cdn-${identity.accountId}-${region}`,
|
|
11612
11677
|
workDir: getPulumiWorkDir()
|
|
11613
11678
|
});
|
|
@@ -14754,7 +14819,7 @@ import pc17 from "picocolors";
|
|
|
14754
14819
|
// src/infrastructure/email-stack.ts
|
|
14755
14820
|
init_esm_shims();
|
|
14756
14821
|
init_dist();
|
|
14757
|
-
import * as
|
|
14822
|
+
import * as aws17 from "@pulumi/aws";
|
|
14758
14823
|
|
|
14759
14824
|
// src/infrastructure/resources/alerting.ts
|
|
14760
14825
|
init_esm_shims();
|
|
@@ -15022,7 +15087,7 @@ async function createDynamoDBTables(_config) {
|
|
|
15022
15087
|
// src/infrastructure/resources/eventbridge.ts
|
|
15023
15088
|
init_esm_shims();
|
|
15024
15089
|
import * as aws6 from "@pulumi/aws";
|
|
15025
|
-
import * as
|
|
15090
|
+
import * as pulumi10 from "@pulumi/pulumi";
|
|
15026
15091
|
async function createEventBridgeResources(config2) {
|
|
15027
15092
|
const eventBusName = config2.eventBusArn.apply((arn) => arn.split("/").pop());
|
|
15028
15093
|
const rule = new aws6.cloudwatch.EventRule("wraps-email-events-rule", {
|
|
@@ -15040,7 +15105,7 @@ async function createEventBridgeResources(config2) {
|
|
|
15040
15105
|
});
|
|
15041
15106
|
new aws6.sqs.QueuePolicy("wraps-email-events-queue-policy", {
|
|
15042
15107
|
queueUrl: config2.queueUrl,
|
|
15043
|
-
policy:
|
|
15108
|
+
policy: pulumi10.all([config2.queueArn, rule.arn]).apply(
|
|
15044
15109
|
([queueArn, ruleArn]) => JSON.stringify({
|
|
15045
15110
|
Version: "2012-10-17",
|
|
15046
15111
|
Statement: [
|
|
@@ -15149,68 +15214,7 @@ async function createEventBridgeResources(config2) {
|
|
|
15149
15214
|
|
|
15150
15215
|
// src/infrastructure/resources/iam.ts
|
|
15151
15216
|
init_esm_shims();
|
|
15152
|
-
init_resource_checks();
|
|
15153
|
-
import * as aws7 from "@pulumi/aws";
|
|
15154
|
-
import * as pulumi10 from "@pulumi/pulumi";
|
|
15155
15217
|
async function createIAMRole(config2) {
|
|
15156
|
-
let assumeRolePolicy;
|
|
15157
|
-
if (config2.provider === "vercel" && config2.oidcProvider) {
|
|
15158
|
-
assumeRolePolicy = pulumi10.interpolate`{
|
|
15159
|
-
"Version": "2012-10-17",
|
|
15160
|
-
"Statement": [{
|
|
15161
|
-
"Effect": "Allow",
|
|
15162
|
-
"Principal": {
|
|
15163
|
-
"Federated": "${config2.oidcProvider.arn}"
|
|
15164
|
-
},
|
|
15165
|
-
"Action": "sts:AssumeRoleWithWebIdentity",
|
|
15166
|
-
"Condition": {
|
|
15167
|
-
"StringEquals": {
|
|
15168
|
-
"oidc.vercel.com/${config2.vercelTeamSlug}:aud": "https://vercel.com/${config2.vercelTeamSlug}"
|
|
15169
|
-
},
|
|
15170
|
-
"StringLike": {
|
|
15171
|
-
"oidc.vercel.com/${config2.vercelTeamSlug}:sub": "owner:${config2.vercelTeamSlug}:project:${config2.vercelProjectName}:environment:*"
|
|
15172
|
-
}
|
|
15173
|
-
}
|
|
15174
|
-
}]
|
|
15175
|
-
}`;
|
|
15176
|
-
} else if (config2.provider === "aws") {
|
|
15177
|
-
assumeRolePolicy = pulumi10.output(`{
|
|
15178
|
-
"Version": "2012-10-17",
|
|
15179
|
-
"Statement": [{
|
|
15180
|
-
"Effect": "Allow",
|
|
15181
|
-
"Principal": {
|
|
15182
|
-
"Service": ["lambda.amazonaws.com", "ec2.amazonaws.com", "ecs-tasks.amazonaws.com"]
|
|
15183
|
-
},
|
|
15184
|
-
"Action": "sts:AssumeRole"
|
|
15185
|
-
}]
|
|
15186
|
-
}`);
|
|
15187
|
-
} else {
|
|
15188
|
-
throw new Error("Other providers not yet implemented");
|
|
15189
|
-
}
|
|
15190
|
-
const roleName = "wraps-email-role";
|
|
15191
|
-
const exists = await roleExists(roleName);
|
|
15192
|
-
const role = exists ? new aws7.iam.Role(
|
|
15193
|
-
roleName,
|
|
15194
|
-
{
|
|
15195
|
-
name: roleName,
|
|
15196
|
-
assumeRolePolicy,
|
|
15197
|
-
tags: {
|
|
15198
|
-
ManagedBy: "wraps-cli",
|
|
15199
|
-
Provider: config2.provider
|
|
15200
|
-
}
|
|
15201
|
-
},
|
|
15202
|
-
{
|
|
15203
|
-
import: roleName
|
|
15204
|
-
// Import existing role (use role name, not ARN)
|
|
15205
|
-
}
|
|
15206
|
-
) : new aws7.iam.Role(roleName, {
|
|
15207
|
-
name: roleName,
|
|
15208
|
-
assumeRolePolicy,
|
|
15209
|
-
tags: {
|
|
15210
|
-
ManagedBy: "wraps-cli",
|
|
15211
|
-
Provider: config2.provider
|
|
15212
|
-
}
|
|
15213
|
-
});
|
|
15214
15218
|
const statements = [];
|
|
15215
15219
|
statements.push({
|
|
15216
15220
|
Effect: "Allow",
|
|
@@ -15316,14 +15320,14 @@ async function createIAMRole(config2) {
|
|
|
15316
15320
|
Resource: "arn:aws:ses:*:*:mailmanager-archive/*"
|
|
15317
15321
|
});
|
|
15318
15322
|
}
|
|
15319
|
-
|
|
15320
|
-
|
|
15321
|
-
|
|
15322
|
-
|
|
15323
|
-
|
|
15324
|
-
|
|
15323
|
+
return createServiceIAMRole({
|
|
15324
|
+
serviceName: "email",
|
|
15325
|
+
provider: config2.provider,
|
|
15326
|
+
oidcProvider: config2.oidcProvider,
|
|
15327
|
+
vercelTeamSlug: config2.vercelTeamSlug,
|
|
15328
|
+
vercelProjectName: config2.vercelProjectName,
|
|
15329
|
+
policyStatements: statements
|
|
15325
15330
|
});
|
|
15326
|
-
return role;
|
|
15327
15331
|
}
|
|
15328
15332
|
|
|
15329
15333
|
// src/infrastructure/email-stack.ts
|
|
@@ -15331,7 +15335,7 @@ init_lambda();
|
|
|
15331
15335
|
|
|
15332
15336
|
// src/infrastructure/resources/ses.ts
|
|
15333
15337
|
init_esm_shims();
|
|
15334
|
-
import * as
|
|
15338
|
+
import * as aws8 from "@pulumi/aws";
|
|
15335
15339
|
async function configurationSetExists(configSetName, region) {
|
|
15336
15340
|
try {
|
|
15337
15341
|
const { SESv2Client: SESv2Client6, GetConfigurationSetCommand: GetConfigurationSetCommand2 } = await import("@aws-sdk/client-sesv2");
|
|
@@ -15341,7 +15345,7 @@ async function configurationSetExists(configSetName, region) {
|
|
|
15341
15345
|
);
|
|
15342
15346
|
return true;
|
|
15343
15347
|
} catch (error) {
|
|
15344
|
-
if (error.name === "NotFoundException") {
|
|
15348
|
+
if (error instanceof Error && error.name === "NotFoundException") {
|
|
15345
15349
|
return false;
|
|
15346
15350
|
}
|
|
15347
15351
|
console.error("Error checking for existing configuration set:", error);
|
|
@@ -15359,7 +15363,7 @@ async function eventDestinationExists(configSetName, eventDestName, region) {
|
|
|
15359
15363
|
);
|
|
15360
15364
|
return response.EventDestinations?.some((dest) => dest.Name === eventDestName) ?? false;
|
|
15361
15365
|
} catch (error) {
|
|
15362
|
-
if (error.name === "NotFoundException") {
|
|
15366
|
+
if (error instanceof Error && error.name === "NotFoundException") {
|
|
15363
15367
|
return false;
|
|
15364
15368
|
}
|
|
15365
15369
|
return false;
|
|
@@ -15374,7 +15378,7 @@ async function emailIdentityExists(emailIdentity, region) {
|
|
|
15374
15378
|
);
|
|
15375
15379
|
return true;
|
|
15376
15380
|
} catch (error) {
|
|
15377
|
-
if (error.name === "NotFoundException") {
|
|
15381
|
+
if (error instanceof Error && error.name === "NotFoundException") {
|
|
15378
15382
|
return false;
|
|
15379
15383
|
}
|
|
15380
15384
|
console.error("Error checking for existing email identity:", error);
|
|
@@ -15409,16 +15413,16 @@ async function createSESResources(config2) {
|
|
|
15409
15413
|
}
|
|
15410
15414
|
const configSetName = "wraps-email-tracking";
|
|
15411
15415
|
const exists = await configurationSetExists(configSetName, config2.region);
|
|
15412
|
-
const configSet = exists ? new
|
|
15416
|
+
const configSet = exists ? new aws8.sesv2.ConfigurationSet(configSetName, configSetOptions, {
|
|
15413
15417
|
import: configSetName
|
|
15414
15418
|
// Import existing configuration set
|
|
15415
|
-
}) : new
|
|
15416
|
-
const defaultEventBus =
|
|
15419
|
+
}) : new aws8.sesv2.ConfigurationSet(configSetName, configSetOptions);
|
|
15420
|
+
const defaultEventBus = aws8.cloudwatch.getEventBusOutput({
|
|
15417
15421
|
name: "default"
|
|
15418
15422
|
});
|
|
15419
15423
|
if (config2.eventTrackingEnabled) {
|
|
15420
15424
|
const eventDestName = "wraps-email-eventbridge";
|
|
15421
|
-
new
|
|
15425
|
+
new aws8.sesv2.ConfigurationSetEventDestination(
|
|
15422
15426
|
"wraps-email-all-events",
|
|
15423
15427
|
{
|
|
15424
15428
|
configurationSetName: configSet.configurationSetName,
|
|
@@ -15458,7 +15462,7 @@ async function createSESResources(config2) {
|
|
|
15458
15462
|
config2.domain,
|
|
15459
15463
|
config2.region
|
|
15460
15464
|
);
|
|
15461
|
-
domainIdentity = identityExists ? new
|
|
15465
|
+
domainIdentity = identityExists ? new aws8.sesv2.EmailIdentity(
|
|
15462
15466
|
"wraps-email-domain",
|
|
15463
15467
|
{
|
|
15464
15468
|
emailIdentity: config2.domain,
|
|
@@ -15475,7 +15479,7 @@ async function createSESResources(config2) {
|
|
|
15475
15479
|
import: config2.domain
|
|
15476
15480
|
// Import existing identity
|
|
15477
15481
|
}
|
|
15478
|
-
) : new
|
|
15482
|
+
) : new aws8.sesv2.EmailIdentity("wraps-email-domain", {
|
|
15479
15483
|
emailIdentity: config2.domain,
|
|
15480
15484
|
configurationSetName: configSet.configurationSetName,
|
|
15481
15485
|
// Link configuration set to domain
|
|
@@ -15491,7 +15495,7 @@ async function createSESResources(config2) {
|
|
|
15491
15495
|
);
|
|
15492
15496
|
if (config2.mailFromDomain) {
|
|
15493
15497
|
mailFromDomain = config2.mailFromDomain;
|
|
15494
|
-
new
|
|
15498
|
+
new aws8.sesv2.EmailIdentityMailFromAttributes(
|
|
15495
15499
|
"wraps-email-mail-from",
|
|
15496
15500
|
{
|
|
15497
15501
|
emailIdentity: config2.domain,
|
|
@@ -15522,7 +15526,7 @@ async function createSESResources(config2) {
|
|
|
15522
15526
|
// src/infrastructure/resources/smtp-credentials.ts
|
|
15523
15527
|
init_esm_shims();
|
|
15524
15528
|
import { createHmac as createHmac2 } from "crypto";
|
|
15525
|
-
import * as
|
|
15529
|
+
import * as aws9 from "@pulumi/aws";
|
|
15526
15530
|
function convertToSMTPPassword2(secretAccessKey, region) {
|
|
15527
15531
|
const DATE = "11111111";
|
|
15528
15532
|
const SERVICE = "ses";
|
|
@@ -15543,13 +15547,13 @@ function convertToSMTPPassword2(secretAccessKey, region) {
|
|
|
15543
15547
|
async function userExists(userName) {
|
|
15544
15548
|
try {
|
|
15545
15549
|
const { IAMClient: IAMClient4, GetUserCommand } = await import("@aws-sdk/client-iam");
|
|
15546
|
-
const
|
|
15550
|
+
const iam9 = new IAMClient4({
|
|
15547
15551
|
region: process.env.AWS_REGION || "us-east-1"
|
|
15548
15552
|
});
|
|
15549
|
-
await
|
|
15553
|
+
await iam9.send(new GetUserCommand({ UserName: userName }));
|
|
15550
15554
|
return true;
|
|
15551
15555
|
} catch (error) {
|
|
15552
|
-
if (error.name === "NoSuchEntityException" || error.Code === "NoSuchEntity") {
|
|
15556
|
+
if (error instanceof Error && (error.name === "NoSuchEntityException" || error.Code === "NoSuchEntity")) {
|
|
15553
15557
|
return false;
|
|
15554
15558
|
}
|
|
15555
15559
|
return false;
|
|
@@ -15558,7 +15562,7 @@ async function userExists(userName) {
|
|
|
15558
15562
|
async function createSMTPCredentials(config2) {
|
|
15559
15563
|
const userName = "wraps-email-smtp-user";
|
|
15560
15564
|
const userAlreadyExists = await userExists(userName);
|
|
15561
|
-
const iamUser = userAlreadyExists ? new
|
|
15565
|
+
const iamUser = userAlreadyExists ? new aws9.iam.User(
|
|
15562
15566
|
userName,
|
|
15563
15567
|
{
|
|
15564
15568
|
name: userName,
|
|
@@ -15568,14 +15572,14 @@ async function createSMTPCredentials(config2) {
|
|
|
15568
15572
|
}
|
|
15569
15573
|
},
|
|
15570
15574
|
{ import: userName }
|
|
15571
|
-
) : new
|
|
15575
|
+
) : new aws9.iam.User(userName, {
|
|
15572
15576
|
name: userName,
|
|
15573
15577
|
tags: {
|
|
15574
15578
|
ManagedBy: "wraps-cli",
|
|
15575
15579
|
Purpose: "SES SMTP Authentication"
|
|
15576
15580
|
}
|
|
15577
15581
|
});
|
|
15578
|
-
new
|
|
15582
|
+
new aws9.iam.UserPolicy("wraps-email-smtp-policy", {
|
|
15579
15583
|
user: iamUser.name,
|
|
15580
15584
|
policy: JSON.stringify({
|
|
15581
15585
|
Version: "2012-10-17",
|
|
@@ -15593,7 +15597,7 @@ async function createSMTPCredentials(config2) {
|
|
|
15593
15597
|
]
|
|
15594
15598
|
})
|
|
15595
15599
|
});
|
|
15596
|
-
const accessKey = new
|
|
15600
|
+
const accessKey = new aws9.iam.AccessKey("wraps-email-smtp-key", {
|
|
15597
15601
|
user: iamUser.name
|
|
15598
15602
|
});
|
|
15599
15603
|
const smtpPassword = accessKey.secret.apply(
|
|
@@ -15608,9 +15612,9 @@ async function createSMTPCredentials(config2) {
|
|
|
15608
15612
|
|
|
15609
15613
|
// src/infrastructure/resources/sqs.ts
|
|
15610
15614
|
init_esm_shims();
|
|
15611
|
-
import * as
|
|
15615
|
+
import * as aws10 from "@pulumi/aws";
|
|
15612
15616
|
async function createSQSResources() {
|
|
15613
|
-
const dlq = new
|
|
15617
|
+
const dlq = new aws10.sqs.Queue("wraps-email-events-dlq", {
|
|
15614
15618
|
name: "wraps-email-events-dlq",
|
|
15615
15619
|
messageRetentionSeconds: 1209600,
|
|
15616
15620
|
// 14 days
|
|
@@ -15619,7 +15623,7 @@ async function createSQSResources() {
|
|
|
15619
15623
|
Description: "Dead letter queue for failed SES event processing"
|
|
15620
15624
|
}
|
|
15621
15625
|
});
|
|
15622
|
-
const queue = new
|
|
15626
|
+
const queue = new aws10.sqs.Queue("wraps-email-events", {
|
|
15623
15627
|
name: "wraps-email-events",
|
|
15624
15628
|
visibilityTimeoutSeconds: 60,
|
|
15625
15629
|
// Must be >= Lambda timeout
|
|
@@ -15647,7 +15651,7 @@ async function createSQSResources() {
|
|
|
15647
15651
|
|
|
15648
15652
|
// src/infrastructure/email-stack.ts
|
|
15649
15653
|
async function deployEmailStack(config2) {
|
|
15650
|
-
const identity = await
|
|
15654
|
+
const identity = await aws17.getCallerIdentity();
|
|
15651
15655
|
const accountId = identity.accountId;
|
|
15652
15656
|
let oidcProvider;
|
|
15653
15657
|
if (config2.provider === "vercel" && config2.vercel) {
|
|
@@ -15810,7 +15814,7 @@ async function deployEmailStack(config2) {
|
|
|
15810
15814
|
region: config2.region,
|
|
15811
15815
|
dlqArn: sqsInbound.dlq.arn
|
|
15812
15816
|
});
|
|
15813
|
-
new
|
|
15817
|
+
new aws17.s3.BucketNotification(
|
|
15814
15818
|
"wraps-inbound-s3-notification",
|
|
15815
15819
|
{
|
|
15816
15820
|
bucket: s3Inbound.bucket.id,
|
|
@@ -16200,7 +16204,10 @@ async function scanSESIdentities(region) {
|
|
|
16200
16204
|
}
|
|
16201
16205
|
return identities;
|
|
16202
16206
|
} catch (error) {
|
|
16203
|
-
console.error(
|
|
16207
|
+
console.error(
|
|
16208
|
+
"Error scanning SES identities:",
|
|
16209
|
+
error instanceof Error ? error.message : error
|
|
16210
|
+
);
|
|
16204
16211
|
return [];
|
|
16205
16212
|
}
|
|
16206
16213
|
}
|
|
@@ -16227,12 +16234,18 @@ async function scanSESConfigurationSets(region) {
|
|
|
16227
16234
|
eventDestinations
|
|
16228
16235
|
});
|
|
16229
16236
|
} catch (error) {
|
|
16230
|
-
console.error(
|
|
16237
|
+
console.error(
|
|
16238
|
+
`Error describing config set ${name}:`,
|
|
16239
|
+
error instanceof Error ? error.message : error
|
|
16240
|
+
);
|
|
16231
16241
|
}
|
|
16232
16242
|
}
|
|
16233
16243
|
return configSets;
|
|
16234
16244
|
} catch (error) {
|
|
16235
|
-
console.error(
|
|
16245
|
+
console.error(
|
|
16246
|
+
"Error scanning SES configuration sets:",
|
|
16247
|
+
error instanceof Error ? error.message : error
|
|
16248
|
+
);
|
|
16236
16249
|
return [];
|
|
16237
16250
|
}
|
|
16238
16251
|
}
|
|
@@ -16260,13 +16273,16 @@ async function scanSNSTopics(region) {
|
|
|
16260
16273
|
} catch (error) {
|
|
16261
16274
|
console.error(
|
|
16262
16275
|
`Error getting topic attributes for ${arn}:`,
|
|
16263
|
-
error.message
|
|
16276
|
+
error instanceof Error ? error.message : error
|
|
16264
16277
|
);
|
|
16265
16278
|
}
|
|
16266
16279
|
}
|
|
16267
16280
|
return topics;
|
|
16268
16281
|
} catch (error) {
|
|
16269
|
-
console.error(
|
|
16282
|
+
console.error(
|
|
16283
|
+
"Error scanning SNS topics:",
|
|
16284
|
+
error instanceof Error ? error.message : error
|
|
16285
|
+
);
|
|
16270
16286
|
return [];
|
|
16271
16287
|
}
|
|
16272
16288
|
}
|
|
@@ -16291,12 +16307,18 @@ async function scanDynamoTables(region) {
|
|
|
16291
16307
|
});
|
|
16292
16308
|
}
|
|
16293
16309
|
} catch (error) {
|
|
16294
|
-
console.error(
|
|
16310
|
+
console.error(
|
|
16311
|
+
`Error describing table ${name}:`,
|
|
16312
|
+
error instanceof Error ? error.message : error
|
|
16313
|
+
);
|
|
16295
16314
|
}
|
|
16296
16315
|
}
|
|
16297
16316
|
return tables;
|
|
16298
16317
|
} catch (error) {
|
|
16299
|
-
console.error(
|
|
16318
|
+
console.error(
|
|
16319
|
+
"Error scanning DynamoDB tables:",
|
|
16320
|
+
error instanceof Error ? error.message : error
|
|
16321
|
+
);
|
|
16300
16322
|
return [];
|
|
16301
16323
|
}
|
|
16302
16324
|
}
|
|
@@ -16318,18 +16340,21 @@ async function scanLambdaFunctions(region) {
|
|
|
16318
16340
|
}
|
|
16319
16341
|
return functions;
|
|
16320
16342
|
} catch (error) {
|
|
16321
|
-
console.error(
|
|
16343
|
+
console.error(
|
|
16344
|
+
"Error scanning Lambda functions:",
|
|
16345
|
+
error instanceof Error ? error.message : error
|
|
16346
|
+
);
|
|
16322
16347
|
return [];
|
|
16323
16348
|
}
|
|
16324
16349
|
}
|
|
16325
16350
|
async function scanIAMRoles(region) {
|
|
16326
|
-
const
|
|
16351
|
+
const iam9 = new IAMClient({ region });
|
|
16327
16352
|
const roles = [];
|
|
16328
16353
|
try {
|
|
16329
16354
|
let marker;
|
|
16330
16355
|
let hasMore = true;
|
|
16331
16356
|
while (hasMore) {
|
|
16332
|
-
const listResponse = await
|
|
16357
|
+
const listResponse = await iam9.send(
|
|
16333
16358
|
new ListRolesCommand({
|
|
16334
16359
|
Marker: marker,
|
|
16335
16360
|
MaxItems: 100
|
|
@@ -16350,7 +16375,10 @@ async function scanIAMRoles(region) {
|
|
|
16350
16375
|
}
|
|
16351
16376
|
return roles;
|
|
16352
16377
|
} catch (error) {
|
|
16353
|
-
console.error(
|
|
16378
|
+
console.error(
|
|
16379
|
+
"Error scanning IAM roles:",
|
|
16380
|
+
error instanceof Error ? error.message : error
|
|
16381
|
+
);
|
|
16354
16382
|
return [];
|
|
16355
16383
|
}
|
|
16356
16384
|
}
|
|
@@ -16757,7 +16785,7 @@ async function getEmailIdentityInfo(domain, region) {
|
|
|
16757
16785
|
mailFromDomain: response.MailFromAttributes?.MailFromDomain
|
|
16758
16786
|
};
|
|
16759
16787
|
} catch (error) {
|
|
16760
|
-
if (
|
|
16788
|
+
if (isAWSNotFoundError(error)) {
|
|
16761
16789
|
return { dkimTokens: [] };
|
|
16762
16790
|
}
|
|
16763
16791
|
throw error;
|
|
@@ -17549,11 +17577,11 @@ Run ${pc20.cyan("wraps email domains add")} to add a domain.
|
|
|
17549
17577
|
verified: details.VerifiedForSendingStatus,
|
|
17550
17578
|
dkimStatus: details.DkimAttributes?.Status || "PENDING"
|
|
17551
17579
|
};
|
|
17552
|
-
} catch {
|
|
17580
|
+
} catch (error) {
|
|
17553
17581
|
return {
|
|
17554
17582
|
name: domain.IdentityName,
|
|
17555
17583
|
verified: false,
|
|
17556
|
-
dkimStatus: "UNKNOWN"
|
|
17584
|
+
dkimStatus: isAWSNotFoundError(error) ? "UNKNOWN" : "ERROR"
|
|
17557
17585
|
};
|
|
17558
17586
|
}
|
|
17559
17587
|
})
|
|
@@ -19415,7 +19443,7 @@ Run ${pc24.cyan("wraps email init")} to deploy email infrastructure.
|
|
|
19415
19443
|
purpose: tracked?.purpose
|
|
19416
19444
|
};
|
|
19417
19445
|
} catch (error) {
|
|
19418
|
-
if (
|
|
19446
|
+
if (isAWSNotFoundError(error)) {
|
|
19419
19447
|
return {
|
|
19420
19448
|
domain: d.domain,
|
|
19421
19449
|
status: d.verified ? "verified" : "pending",
|
|
@@ -22459,9 +22487,9 @@ ${pc28.green("\u2713")} ${pc28.bold("Upgrade complete!")}
|
|
|
22459
22487
|
iamUserArn: outputs.smtpUserArn,
|
|
22460
22488
|
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
22461
22489
|
};
|
|
22462
|
-
await saveConnectionMetadata(metadata);
|
|
22463
22490
|
}
|
|
22464
22491
|
}
|
|
22492
|
+
await saveConnectionMetadata(metadata);
|
|
22465
22493
|
const enabledFeatures = [];
|
|
22466
22494
|
if (updatedConfig.tracking?.enabled) {
|
|
22467
22495
|
enabledFeatures.push("tracking");
|
|
@@ -24574,10 +24602,10 @@ async function deployEventBridge(metadata, region, identity, webhookSecret, prog
|
|
|
24574
24602
|
var WRAPS_PLATFORM_ACCOUNT_ID = "905130073023";
|
|
24575
24603
|
async function updatePlatformRole(metadata, progress, externalId) {
|
|
24576
24604
|
const roleName = "wraps-console-access-role";
|
|
24577
|
-
const
|
|
24605
|
+
const iam9 = new IAMClient2({ region: "us-east-1" });
|
|
24578
24606
|
let roleExists2 = false;
|
|
24579
24607
|
try {
|
|
24580
|
-
await
|
|
24608
|
+
await iam9.send(new GetRoleCommand({ RoleName: roleName }));
|
|
24581
24609
|
roleExists2 = true;
|
|
24582
24610
|
} catch (error) {
|
|
24583
24611
|
const isNotFound = error instanceof Error && (error.name === "NoSuchEntityException" || error.name === "NoSuchEntity" || error.message.includes("NoSuchEntity"));
|
|
@@ -24590,7 +24618,7 @@ async function updatePlatformRole(metadata, progress, externalId) {
|
|
|
24590
24618
|
const policy = buildConsolePolicyDocument(emailConfig, smsConfig);
|
|
24591
24619
|
if (roleExists2) {
|
|
24592
24620
|
await progress.execute("Updating platform access role", async () => {
|
|
24593
|
-
await
|
|
24621
|
+
await iam9.send(
|
|
24594
24622
|
new PutRolePolicyCommand({
|
|
24595
24623
|
RoleName: roleName,
|
|
24596
24624
|
PolicyName: "wraps-console-access-policy",
|
|
@@ -24618,7 +24646,7 @@ async function updatePlatformRole(metadata, progress, externalId) {
|
|
|
24618
24646
|
}
|
|
24619
24647
|
]
|
|
24620
24648
|
};
|
|
24621
|
-
await
|
|
24649
|
+
await iam9.send(
|
|
24622
24650
|
new CreateRoleCommand({
|
|
24623
24651
|
RoleName: roleName,
|
|
24624
24652
|
Description: "Allows Wraps dashboard to access CloudWatch metrics and SES data",
|
|
@@ -24629,7 +24657,7 @@ async function updatePlatformRole(metadata, progress, externalId) {
|
|
|
24629
24657
|
]
|
|
24630
24658
|
})
|
|
24631
24659
|
);
|
|
24632
|
-
await
|
|
24660
|
+
await iam9.send(
|
|
24633
24661
|
new PutRolePolicyCommand({
|
|
24634
24662
|
RoleName: roleName,
|
|
24635
24663
|
PolicyName: "wraps-console-access-policy",
|
|
@@ -25045,10 +25073,10 @@ Run ${pc33.cyan("wraps email init")} or ${pc33.cyan("wraps sms init")} first.
|
|
|
25045
25073
|
progress.succeed("Event streaming already configured");
|
|
25046
25074
|
}
|
|
25047
25075
|
const roleName = "wraps-console-access-role";
|
|
25048
|
-
const
|
|
25076
|
+
const iam9 = new IAMClient2({ region: "us-east-1" });
|
|
25049
25077
|
let roleExists2 = false;
|
|
25050
25078
|
try {
|
|
25051
|
-
await
|
|
25079
|
+
await iam9.send(new GetRoleCommand({ RoleName: roleName }));
|
|
25052
25080
|
roleExists2 = true;
|
|
25053
25081
|
} catch (error) {
|
|
25054
25082
|
const isNotFound = error instanceof Error && (error.name === "NoSuchEntityException" || error.name === "NoSuchEntity" || error.message.includes("NoSuchEntity"));
|
|
@@ -25061,7 +25089,7 @@ Run ${pc33.cyan("wraps email init")} or ${pc33.cyan("wraps sms init")} first.
|
|
|
25061
25089
|
const smsConfig = metadata.services.sms?.config;
|
|
25062
25090
|
const policy = buildConsolePolicyDocument(emailConfig, smsConfig);
|
|
25063
25091
|
await progress.execute("Updating platform access role", async () => {
|
|
25064
|
-
await
|
|
25092
|
+
await iam9.send(
|
|
25065
25093
|
new PutRolePolicyCommand({
|
|
25066
25094
|
RoleName: roleName,
|
|
25067
25095
|
PolicyName: "wraps-console-access-policy",
|
|
@@ -25212,10 +25240,10 @@ Run ${pc35.cyan("wraps email init")} to deploy infrastructure first.
|
|
|
25212
25240
|
process.exit(1);
|
|
25213
25241
|
}
|
|
25214
25242
|
const roleName = "wraps-console-access-role";
|
|
25215
|
-
const
|
|
25243
|
+
const iam9 = new IAMClient3({ region: "us-east-1" });
|
|
25216
25244
|
let roleExists2 = false;
|
|
25217
25245
|
try {
|
|
25218
|
-
await
|
|
25246
|
+
await iam9.send(new GetRoleCommand2({ RoleName: roleName }));
|
|
25219
25247
|
roleExists2 = true;
|
|
25220
25248
|
} catch (error) {
|
|
25221
25249
|
const isNotFound = error instanceof Error && (error.name === "NoSuchEntityException" || error.name === "NoSuchEntity" || error.message.includes("NoSuchEntity"));
|
|
@@ -25284,7 +25312,7 @@ Run ${pc35.cyan("wraps email init")} to deploy infrastructure first.
|
|
|
25284
25312
|
}
|
|
25285
25313
|
]
|
|
25286
25314
|
};
|
|
25287
|
-
await
|
|
25315
|
+
await iam9.send(
|
|
25288
25316
|
new CreateRoleCommand2({
|
|
25289
25317
|
RoleName: roleName,
|
|
25290
25318
|
Description: "Allows Wraps dashboard to access CloudWatch metrics and SES data",
|
|
@@ -25296,7 +25324,7 @@ Run ${pc35.cyan("wraps email init")} to deploy infrastructure first.
|
|
|
25296
25324
|
})
|
|
25297
25325
|
);
|
|
25298
25326
|
const { PutRolePolicyCommand: PutRolePolicyCommand2 } = await import("@aws-sdk/client-iam");
|
|
25299
|
-
await
|
|
25327
|
+
await iam9.send(
|
|
25300
25328
|
new PutRolePolicyCommand2({
|
|
25301
25329
|
RoleName: roleName,
|
|
25302
25330
|
PolicyName: "wraps-console-access-policy",
|
|
@@ -25307,7 +25335,7 @@ Run ${pc35.cyan("wraps email init")} to deploy infrastructure first.
|
|
|
25307
25335
|
} else {
|
|
25308
25336
|
await progress.execute("Updating IAM role permissions", async () => {
|
|
25309
25337
|
const { PutRolePolicyCommand: PutRolePolicyCommand2 } = await import("@aws-sdk/client-iam");
|
|
25310
|
-
await
|
|
25338
|
+
await iam9.send(
|
|
25311
25339
|
new PutRolePolicyCommand2({
|
|
25312
25340
|
RoleName: roleName,
|
|
25313
25341
|
PolicyName: "wraps-console-access-policy",
|
|
@@ -27041,7 +27069,7 @@ function createSettingsRouter(config2) {
|
|
|
27041
27069
|
});
|
|
27042
27070
|
} catch (error) {
|
|
27043
27071
|
console.error("[Verify] Error verifying tracking domain:", error);
|
|
27044
|
-
if (error.code === "ENODATA" || error.code === "ENOTFOUND") {
|
|
27072
|
+
if (error instanceof Error && (error.code === "ENODATA" || error.code === "ENOTFOUND")) {
|
|
27045
27073
|
return res.json({
|
|
27046
27074
|
verified: false,
|
|
27047
27075
|
error: "No CNAME record found for this domain"
|
|
@@ -27075,7 +27103,7 @@ function createSettingsRouter(config2) {
|
|
|
27075
27103
|
});
|
|
27076
27104
|
} catch (error) {
|
|
27077
27105
|
console.error("[Verify] Error verifying DMARC:", error);
|
|
27078
|
-
if (error.code === "ENODATA" || error.code === "ENOTFOUND") {
|
|
27106
|
+
if (error instanceof Error && (error.code === "ENODATA" || error.code === "ENOTFOUND")) {
|
|
27079
27107
|
return res.json({
|
|
27080
27108
|
verified: false,
|
|
27081
27109
|
error: "No DMARC record found for this domain"
|
|
@@ -28501,85 +28529,10 @@ import pc39 from "picocolors";
|
|
|
28501
28529
|
|
|
28502
28530
|
// src/infrastructure/sms-stack.ts
|
|
28503
28531
|
init_esm_shims();
|
|
28504
|
-
|
|
28505
|
-
import * as aws19 from "@pulumi/aws";
|
|
28532
|
+
import * as aws18 from "@pulumi/aws";
|
|
28506
28533
|
import * as pulumi24 from "@pulumi/pulumi";
|
|
28534
|
+
init_resource_checks();
|
|
28507
28535
|
async function createSMSIAMRole(config2) {
|
|
28508
|
-
let assumeRolePolicy;
|
|
28509
|
-
if (config2.provider === "vercel" && config2.oidcProvider) {
|
|
28510
|
-
assumeRolePolicy = pulumi24.interpolate`{
|
|
28511
|
-
"Version": "2012-10-17",
|
|
28512
|
-
"Statement": [
|
|
28513
|
-
{
|
|
28514
|
-
"Effect": "Allow",
|
|
28515
|
-
"Principal": {
|
|
28516
|
-
"Federated": "${config2.oidcProvider.arn}"
|
|
28517
|
-
},
|
|
28518
|
-
"Action": "sts:AssumeRoleWithWebIdentity",
|
|
28519
|
-
"Condition": {
|
|
28520
|
-
"StringEquals": {
|
|
28521
|
-
"oidc.vercel.com/${config2.vercelTeamSlug}:aud": "https://vercel.com/${config2.vercelTeamSlug}"
|
|
28522
|
-
},
|
|
28523
|
-
"StringLike": {
|
|
28524
|
-
"oidc.vercel.com/${config2.vercelTeamSlug}:sub": "owner:${config2.vercelTeamSlug}:project:${config2.vercelProjectName}:environment:*"
|
|
28525
|
-
}
|
|
28526
|
-
}
|
|
28527
|
-
},
|
|
28528
|
-
{
|
|
28529
|
-
"Effect": "Allow",
|
|
28530
|
-
"Principal": {
|
|
28531
|
-
"Service": "lambda.amazonaws.com"
|
|
28532
|
-
},
|
|
28533
|
-
"Action": "sts:AssumeRole"
|
|
28534
|
-
}
|
|
28535
|
-
]
|
|
28536
|
-
}`;
|
|
28537
|
-
} else if (config2.provider === "aws") {
|
|
28538
|
-
assumeRolePolicy = pulumi24.output(`{
|
|
28539
|
-
"Version": "2012-10-17",
|
|
28540
|
-
"Statement": [{
|
|
28541
|
-
"Effect": "Allow",
|
|
28542
|
-
"Principal": {
|
|
28543
|
-
"Service": ["lambda.amazonaws.com", "ec2.amazonaws.com", "ecs-tasks.amazonaws.com"]
|
|
28544
|
-
},
|
|
28545
|
-
"Action": "sts:AssumeRole"
|
|
28546
|
-
}]
|
|
28547
|
-
}`);
|
|
28548
|
-
} else {
|
|
28549
|
-
throw new Error("Other providers not yet implemented");
|
|
28550
|
-
}
|
|
28551
|
-
const roleName = "wraps-sms-role";
|
|
28552
|
-
const exists = await roleExists(roleName);
|
|
28553
|
-
const role = exists ? new aws19.iam.Role(
|
|
28554
|
-
roleName,
|
|
28555
|
-
{
|
|
28556
|
-
name: roleName,
|
|
28557
|
-
assumeRolePolicy,
|
|
28558
|
-
tags: {
|
|
28559
|
-
ManagedBy: "wraps-cli",
|
|
28560
|
-
Service: "sms",
|
|
28561
|
-
Provider: config2.provider
|
|
28562
|
-
}
|
|
28563
|
-
},
|
|
28564
|
-
{
|
|
28565
|
-
import: roleName,
|
|
28566
|
-
customTimeouts: { create: "2m", update: "2m", delete: "2m" }
|
|
28567
|
-
}
|
|
28568
|
-
) : new aws19.iam.Role(
|
|
28569
|
-
roleName,
|
|
28570
|
-
{
|
|
28571
|
-
name: roleName,
|
|
28572
|
-
assumeRolePolicy,
|
|
28573
|
-
tags: {
|
|
28574
|
-
ManagedBy: "wraps-cli",
|
|
28575
|
-
Service: "sms",
|
|
28576
|
-
Provider: config2.provider
|
|
28577
|
-
}
|
|
28578
|
-
},
|
|
28579
|
-
{
|
|
28580
|
-
customTimeouts: { create: "2m", update: "2m", delete: "2m" }
|
|
28581
|
-
}
|
|
28582
|
-
);
|
|
28583
28536
|
const statements = [];
|
|
28584
28537
|
statements.push({
|
|
28585
28538
|
Effect: "Allow",
|
|
@@ -28660,17 +28613,20 @@ async function createSMSIAMRole(config2) {
|
|
|
28660
28613
|
Resource: "arn:aws:logs:*:*:log-group:/aws/lambda/wraps-sms-*"
|
|
28661
28614
|
});
|
|
28662
28615
|
}
|
|
28663
|
-
|
|
28664
|
-
|
|
28665
|
-
|
|
28666
|
-
|
|
28667
|
-
|
|
28668
|
-
|
|
28616
|
+
return createServiceIAMRole({
|
|
28617
|
+
serviceName: "sms",
|
|
28618
|
+
provider: config2.provider,
|
|
28619
|
+
oidcProvider: config2.oidcProvider,
|
|
28620
|
+
vercelTeamSlug: config2.vercelTeamSlug,
|
|
28621
|
+
vercelProjectName: config2.vercelProjectName,
|
|
28622
|
+
additionalVercelPrincipals: ["lambda.amazonaws.com"],
|
|
28623
|
+
policyStatements: statements,
|
|
28624
|
+
extraTags: { Service: "sms" },
|
|
28625
|
+
customTimeouts: { create: "2m", update: "2m", delete: "2m" }
|
|
28669
28626
|
});
|
|
28670
|
-
return role;
|
|
28671
28627
|
}
|
|
28672
28628
|
function createSMSConfigurationSet() {
|
|
28673
|
-
return new
|
|
28629
|
+
return new aws18.pinpoint.Smsvoicev2ConfigurationSet("wraps-sms-config", {
|
|
28674
28630
|
name: "wraps-sms-config",
|
|
28675
28631
|
defaultMessageType: "TRANSACTIONAL",
|
|
28676
28632
|
tags: {
|
|
@@ -28680,7 +28636,7 @@ function createSMSConfigurationSet() {
|
|
|
28680
28636
|
});
|
|
28681
28637
|
}
|
|
28682
28638
|
function createSMSOptOutList() {
|
|
28683
|
-
return new
|
|
28639
|
+
return new aws18.pinpoint.Smsvoicev2OptOutList("wraps-sms-optouts", {
|
|
28684
28640
|
name: "wraps-sms-optouts",
|
|
28685
28641
|
tags: {
|
|
28686
28642
|
ManagedBy: "wraps-cli",
|
|
@@ -28744,7 +28700,7 @@ async function createSMSPhoneNumber(phoneNumberType, optOutList) {
|
|
|
28744
28700
|
}
|
|
28745
28701
|
};
|
|
28746
28702
|
if (existingArn) {
|
|
28747
|
-
return new
|
|
28703
|
+
return new aws18.pinpoint.Smsvoicev2PhoneNumber(
|
|
28748
28704
|
"wraps-sms-number",
|
|
28749
28705
|
phoneConfig,
|
|
28750
28706
|
{
|
|
@@ -28753,7 +28709,7 @@ async function createSMSPhoneNumber(phoneNumberType, optOutList) {
|
|
|
28753
28709
|
}
|
|
28754
28710
|
);
|
|
28755
28711
|
}
|
|
28756
|
-
return new
|
|
28712
|
+
return new aws18.pinpoint.Smsvoicev2PhoneNumber(
|
|
28757
28713
|
"wraps-sms-number",
|
|
28758
28714
|
phoneConfig,
|
|
28759
28715
|
{
|
|
@@ -28782,10 +28738,10 @@ async function createSMSSQSResources() {
|
|
|
28782
28738
|
Description: "Dead letter queue for failed SMS event processing"
|
|
28783
28739
|
}
|
|
28784
28740
|
};
|
|
28785
|
-
const dlq = dlqUrl ? new
|
|
28741
|
+
const dlq = dlqUrl ? new aws18.sqs.Queue(dlqName, dlqConfig, {
|
|
28786
28742
|
import: dlqUrl,
|
|
28787
28743
|
customTimeouts: { create: "2m", update: "2m", delete: "2m" }
|
|
28788
|
-
}) : new
|
|
28744
|
+
}) : new aws18.sqs.Queue(dlqName, dlqConfig, {
|
|
28789
28745
|
customTimeouts: { create: "2m", update: "2m", delete: "2m" }
|
|
28790
28746
|
});
|
|
28791
28747
|
const queueConfig = {
|
|
@@ -28808,10 +28764,10 @@ async function createSMSSQSResources() {
|
|
|
28808
28764
|
Description: "Queue for SMS events from SNS"
|
|
28809
28765
|
}
|
|
28810
28766
|
};
|
|
28811
|
-
const queue = queueUrl ? new
|
|
28767
|
+
const queue = queueUrl ? new aws18.sqs.Queue(queueName, queueConfig, {
|
|
28812
28768
|
import: queueUrl,
|
|
28813
28769
|
customTimeouts: { create: "2m", update: "2m", delete: "2m" }
|
|
28814
|
-
}) : new
|
|
28770
|
+
}) : new aws18.sqs.Queue(queueName, queueConfig, {
|
|
28815
28771
|
customTimeouts: { create: "2m", update: "2m", delete: "2m" }
|
|
28816
28772
|
});
|
|
28817
28773
|
return { queue, dlq };
|
|
@@ -28827,13 +28783,13 @@ async function createSMSSNSResources(config2) {
|
|
|
28827
28783
|
Description: "SNS topic for SMS delivery events"
|
|
28828
28784
|
}
|
|
28829
28785
|
};
|
|
28830
|
-
const topic = topicArn ? new
|
|
28786
|
+
const topic = topicArn ? new aws18.sns.Topic("wraps-sms-events-topic", topicConfig, {
|
|
28831
28787
|
import: topicArn,
|
|
28832
28788
|
customTimeouts: { create: "2m", update: "2m", delete: "2m" }
|
|
28833
|
-
}) : new
|
|
28789
|
+
}) : new aws18.sns.Topic("wraps-sms-events-topic", topicConfig, {
|
|
28834
28790
|
customTimeouts: { create: "2m", update: "2m", delete: "2m" }
|
|
28835
28791
|
});
|
|
28836
|
-
new
|
|
28792
|
+
new aws18.sns.TopicPolicy("wraps-sms-events-topic-policy", {
|
|
28837
28793
|
arn: topic.arn,
|
|
28838
28794
|
policy: topic.arn.apply(
|
|
28839
28795
|
(topicArn2) => JSON.stringify({
|
|
@@ -28850,7 +28806,7 @@ async function createSMSSNSResources(config2) {
|
|
|
28850
28806
|
})
|
|
28851
28807
|
)
|
|
28852
28808
|
});
|
|
28853
|
-
new
|
|
28809
|
+
new aws18.sqs.QueuePolicy("wraps-sms-events-queue-policy", {
|
|
28854
28810
|
queueUrl: config2.queueUrl,
|
|
28855
28811
|
policy: pulumi24.all([config2.queueArn, topic.arn]).apply(
|
|
28856
28812
|
([queueArn, topicArn2]) => JSON.stringify({
|
|
@@ -28869,7 +28825,7 @@ async function createSMSSNSResources(config2) {
|
|
|
28869
28825
|
})
|
|
28870
28826
|
)
|
|
28871
28827
|
});
|
|
28872
|
-
const subscription = new
|
|
28828
|
+
const subscription = new aws18.sns.TopicSubscription(
|
|
28873
28829
|
"wraps-sms-events-subscription",
|
|
28874
28830
|
{
|
|
28875
28831
|
topic: topic.arn,
|
|
@@ -28918,17 +28874,17 @@ async function createSMSDynamoDBTable() {
|
|
|
28918
28874
|
Service: "sms"
|
|
28919
28875
|
}
|
|
28920
28876
|
};
|
|
28921
|
-
return exists ? new
|
|
28877
|
+
return exists ? new aws18.dynamodb.Table(tableName, tableConfig, {
|
|
28922
28878
|
import: tableName,
|
|
28923
28879
|
customTimeouts: { create: "5m", update: "5m", delete: "5m" }
|
|
28924
|
-
}) : new
|
|
28880
|
+
}) : new aws18.dynamodb.Table(tableName, tableConfig, {
|
|
28925
28881
|
customTimeouts: { create: "5m", update: "5m", delete: "5m" }
|
|
28926
28882
|
});
|
|
28927
28883
|
}
|
|
28928
28884
|
async function deploySMSLambdaFunction(config2) {
|
|
28929
28885
|
const { getLambdaCode: getLambdaCode2 } = await Promise.resolve().then(() => (init_lambda(), lambda_exports));
|
|
28930
28886
|
const codeDir = await getLambdaCode2("sms-event-processor");
|
|
28931
|
-
const lambdaRole = new
|
|
28887
|
+
const lambdaRole = new aws18.iam.Role("wraps-sms-lambda-role", {
|
|
28932
28888
|
name: "wraps-sms-lambda-role",
|
|
28933
28889
|
assumeRolePolicy: JSON.stringify({
|
|
28934
28890
|
Version: "2012-10-17",
|
|
@@ -28945,11 +28901,11 @@ async function deploySMSLambdaFunction(config2) {
|
|
|
28945
28901
|
Service: "sms"
|
|
28946
28902
|
}
|
|
28947
28903
|
});
|
|
28948
|
-
new
|
|
28904
|
+
new aws18.iam.RolePolicyAttachment("wraps-sms-lambda-basic-execution", {
|
|
28949
28905
|
role: lambdaRole.name,
|
|
28950
28906
|
policyArn: "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
|
|
28951
28907
|
});
|
|
28952
|
-
new
|
|
28908
|
+
new aws18.iam.RolePolicy("wraps-sms-lambda-policy", {
|
|
28953
28909
|
role: lambdaRole.name,
|
|
28954
28910
|
policy: pulumi24.all([config2.tableName, config2.queueArn]).apply(
|
|
28955
28911
|
([tableName, queueArn]) => JSON.stringify({
|
|
@@ -28981,7 +28937,7 @@ async function deploySMSLambdaFunction(config2) {
|
|
|
28981
28937
|
})
|
|
28982
28938
|
)
|
|
28983
28939
|
});
|
|
28984
|
-
const eventProcessor = new
|
|
28940
|
+
const eventProcessor = new aws18.lambda.Function(
|
|
28985
28941
|
"wraps-sms-event-processor",
|
|
28986
28942
|
{
|
|
28987
28943
|
name: "wraps-sms-event-processor",
|
|
@@ -29009,7 +28965,7 @@ async function deploySMSLambdaFunction(config2) {
|
|
|
29009
28965
|
customTimeouts: { create: "5m", update: "5m", delete: "2m" }
|
|
29010
28966
|
}
|
|
29011
28967
|
);
|
|
29012
|
-
new
|
|
28968
|
+
new aws18.lambda.EventSourceMapping(
|
|
29013
28969
|
"wraps-sms-event-source-mapping",
|
|
29014
28970
|
{
|
|
29015
28971
|
eventSourceArn: config2.queueArn,
|
|
@@ -29025,7 +28981,7 @@ async function deploySMSLambdaFunction(config2) {
|
|
|
29025
28981
|
return eventProcessor;
|
|
29026
28982
|
}
|
|
29027
28983
|
async function deploySMSStack(config2) {
|
|
29028
|
-
const identity = await
|
|
28984
|
+
const identity = await aws18.getCallerIdentity();
|
|
29029
28985
|
const accountId = identity.accountId;
|
|
29030
28986
|
let oidcProvider;
|
|
29031
28987
|
if (config2.provider === "vercel" && config2.vercel) {
|