@jaypie/constructs 1.1.28 → 1.1.29

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.
@@ -1,18 +1,23 @@
1
1
  'use strict';
2
2
 
3
+ var constructs = require('constructs');
3
4
  var cdk$1 = require('aws-cdk-lib');
5
+ var acm = require('aws-cdk-lib/aws-certificatemanager');
6
+ var apiGateway = require('aws-cdk-lib/aws-apigateway');
7
+ var route53 = require('aws-cdk-lib/aws-route53');
8
+ var route53Targets = require('aws-cdk-lib/aws-route53-targets');
9
+ var cdk = require('@jaypie/cdk');
4
10
  var s3 = require('aws-cdk-lib/aws-s3');
5
11
  var s3n = require('aws-cdk-lib/aws-s3-notifications');
6
- var cdk = require('@jaypie/cdk');
7
- var constructs = require('constructs');
8
12
  var lambda = require('aws-cdk-lib/aws-lambda');
9
13
  var sqs = require('aws-cdk-lib/aws-sqs');
10
14
  var lambdaEventSources = require('aws-cdk-lib/aws-lambda-event-sources');
11
15
  var secretsmanager = require('aws-cdk-lib/aws-secretsmanager');
12
16
  var awsIam = require('aws-cdk-lib/aws-iam');
13
17
  var awsLogs = require('aws-cdk-lib/aws-logs');
14
- var awsRoute53 = require('aws-cdk-lib/aws-route53');
15
18
  var sso = require('aws-cdk-lib/aws-sso');
19
+ var cloudfront = require('aws-cdk-lib/aws-cloudfront');
20
+ var origins = require('aws-cdk-lib/aws-cloudfront-origins');
16
21
 
17
22
  function _interopNamespaceDefault(e) {
18
23
  var n = Object.create(null);
@@ -32,6 +37,10 @@ function _interopNamespaceDefault(e) {
32
37
  }
33
38
 
34
39
  var cdk__namespace = /*#__PURE__*/_interopNamespaceDefault(cdk$1);
40
+ var acm__namespace = /*#__PURE__*/_interopNamespaceDefault(acm);
41
+ var apiGateway__namespace = /*#__PURE__*/_interopNamespaceDefault(apiGateway);
42
+ var route53__namespace = /*#__PURE__*/_interopNamespaceDefault(route53);
43
+ var route53Targets__namespace = /*#__PURE__*/_interopNamespaceDefault(route53Targets);
35
44
  var s3__namespace = /*#__PURE__*/_interopNamespaceDefault(s3);
36
45
  var s3n__namespace = /*#__PURE__*/_interopNamespaceDefault(s3n);
37
46
  var lambda__namespace = /*#__PURE__*/_interopNamespaceDefault(lambda);
@@ -39,11 +48,264 @@ var sqs__namespace = /*#__PURE__*/_interopNamespaceDefault(sqs);
39
48
  var lambdaEventSources__namespace = /*#__PURE__*/_interopNamespaceDefault(lambdaEventSources);
40
49
  var secretsmanager__namespace = /*#__PURE__*/_interopNamespaceDefault(secretsmanager);
41
50
  var sso__namespace = /*#__PURE__*/_interopNamespaceDefault(sso);
51
+ var cloudfront__namespace = /*#__PURE__*/_interopNamespaceDefault(cloudfront);
52
+ var origins__namespace = /*#__PURE__*/_interopNamespaceDefault(origins);
53
+
54
+ function constructEnvName(name, opts) {
55
+ const env = opts?.env ?? process.env.PROJECT_ENV ?? "build";
56
+ const key = opts?.key ?? process.env.PROJECT_KEY ?? "project";
57
+ const nonce = opts?.nonce ?? process.env.PROJECT_NONCE ?? "cfe2";
58
+ return `${env}-${key}-${name}-${nonce}`;
59
+ }
60
+
61
+ function constructStackName(key) {
62
+ if (!key) {
63
+ return `cdk-${process.env.PROJECT_SPONSOR}-${process.env.PROJECT_KEY}-${process.env.PROJECT_ENV}-${process.env.PROJECT_NONCE}`;
64
+ }
65
+ else {
66
+ return `cdk-${process.env.PROJECT_SPONSOR}-${process.env.PROJECT_KEY}-${process.env.PROJECT_ENV}-${process.env.PROJECT_NONCE}-${key}`;
67
+ }
68
+ }
69
+
70
+ /**
71
+ * Check if the current environment matches the given environment
72
+ */
73
+ function isEnv(env) {
74
+ return process.env.PROJECT_ENV === env;
75
+ }
76
+ /**
77
+ * Check if the current environment is production
78
+ */
79
+ function isProductionEnv() {
80
+ return isEnv(cdk.CDK.ENV.PRODUCTION);
81
+ }
82
+ /**
83
+ * Check if the current environment is sandbox
84
+ */
85
+ function isSandboxEnv() {
86
+ return isEnv(cdk.CDK.ENV.SANDBOX);
87
+ }
88
+
89
+ const CDK$1 = {
90
+ CREATION: {
91
+ CDK: "cdk",
92
+ },
93
+ ROLE: {
94
+ STACK: "stack",
95
+ },
96
+ TAG: {
97
+ BUILD_DATE: "buildDate",
98
+ BUILD_HEX: "buildHex",
99
+ BUILD_TIME: "buildTime",
100
+ COMMIT: "commit",
101
+ CREATION: "creation",
102
+ ENV: "env",
103
+ NONCE: "nonce",
104
+ PROJECT: "project",
105
+ ROLE: "role",
106
+ SERVICE: "service",
107
+ SPONSOR: "sponsor",
108
+ STACK: "stack",
109
+ VERSION: "version",
110
+ },
111
+ };
112
+ function stackTagger(stack, { name } = {}) {
113
+ const stackName = name || constructStackName();
114
+ const version = process.env.npm_package_version || process.env.PROJECT_VERSION || null;
115
+ if (process.env.PROJECT_COMMIT && process.env.PROJECT_COMMIT.length > 8) {
116
+ cdk$1.Tags.of(stack).add(CDK$1.TAG.BUILD_HEX, process.env.PROJECT_COMMIT.slice(0, 8));
117
+ }
118
+ cdk$1.Tags.of(stack).add(CDK$1.TAG.BUILD_DATE, new Date().toISOString());
119
+ cdk$1.Tags.of(stack).add(CDK$1.TAG.BUILD_TIME, Date.now().toString());
120
+ if (process.env.PROJECT_COMMIT)
121
+ cdk$1.Tags.of(stack).add(CDK$1.TAG.COMMIT, process.env.PROJECT_COMMIT);
122
+ cdk$1.Tags.of(stack).add(CDK$1.TAG.CREATION, CDK$1.CREATION.CDK);
123
+ if (process.env.PROJECT_ENV)
124
+ cdk$1.Tags.of(stack).add(CDK$1.TAG.ENV, process.env.PROJECT_ENV);
125
+ if (process.env.PROJECT_NONCE)
126
+ cdk$1.Tags.of(stack).add(CDK$1.TAG.NONCE, process.env.PROJECT_NONCE);
127
+ if (process.env.PROJECT_KEY)
128
+ cdk$1.Tags.of(stack).add(CDK$1.TAG.PROJECT, process.env.PROJECT_KEY);
129
+ cdk$1.Tags.of(stack).add(CDK$1.TAG.ROLE, CDK$1.ROLE.STACK);
130
+ if (process.env.PROJECT_SERVICE)
131
+ cdk$1.Tags.of(stack).add(CDK$1.TAG.SERVICE, process.env.PROJECT_SERVICE);
132
+ if (process.env.PROJECT_SPONSOR)
133
+ cdk$1.Tags.of(stack).add(CDK$1.TAG.SPONSOR, process.env.PROJECT_SPONSOR);
134
+ if (stackName)
135
+ cdk$1.Tags.of(stack).add(CDK$1.TAG.STACK, stackName);
136
+ if (version)
137
+ cdk$1.Tags.of(stack).add(CDK$1.TAG.VERSION, version);
138
+ return true;
139
+ }
140
+
141
+ class JaypieApiGateway extends constructs.Construct {
142
+ constructor(scope, id, props) {
143
+ super(scope, id);
144
+ const { certificate = true, handler, host, name, roleTag = cdk.CDK.ROLE.API, zone, } = props;
145
+ const apiGatewayName = name || constructEnvName("ApiGateway");
146
+ const certificateName = constructEnvName("Certificate");
147
+ const apiDomainName = constructEnvName("ApiDomainName");
148
+ let hostedZone;
149
+ let certificateToUse;
150
+ if (host && zone) {
151
+ if (typeof zone === "string") {
152
+ hostedZone = route53__namespace.HostedZone.fromLookup(this, "HostedZone", {
153
+ domainName: zone,
154
+ });
155
+ }
156
+ else {
157
+ hostedZone = zone;
158
+ }
159
+ if (certificate === true) {
160
+ certificateToUse = new acm__namespace.Certificate(this, certificateName, {
161
+ domainName: host,
162
+ validation: acm__namespace.CertificateValidation.fromDns(hostedZone),
163
+ });
164
+ cdk$1.Tags.of(certificateToUse).add(cdk.CDK.TAG.ROLE, cdk.CDK.ROLE.HOSTING);
165
+ }
166
+ else if (typeof certificate === "object") {
167
+ certificateToUse = certificate;
168
+ }
169
+ this._certificate = certificateToUse;
170
+ this._host = host;
171
+ }
172
+ const {
173
+ // * `...lambdaRestApiProps` cannot be moved to the first const destructuring because it needs to exclude the custom properties first.
174
+ // Ignore the variables we already assigned to other properties
175
+ /* eslint-disable @typescript-eslint/no-unused-vars */
176
+ certificate: _certificate, host: _host, name: _name, roleTag: _roleTag, zone: _zone, handler: _handler,
177
+ /* eslint-enable @typescript-eslint/no-unused-vars */
178
+ ...lambdaRestApiProps } = props;
179
+ this._api = new apiGateway__namespace.LambdaRestApi(this, apiGatewayName, {
180
+ handler,
181
+ ...lambdaRestApiProps,
182
+ });
183
+ cdk$1.Tags.of(this._api).add(cdk.CDK.TAG.ROLE, roleTag);
184
+ if (host && certificateToUse && hostedZone) {
185
+ this._domainName = this._api.addDomainName(apiDomainName, {
186
+ domainName: host,
187
+ certificate: certificateToUse,
188
+ });
189
+ cdk$1.Tags.of(this._domainName).add(cdk.CDK.TAG.ROLE, roleTag);
190
+ const record = new route53__namespace.ARecord(this, "AliasRecord", {
191
+ recordName: host,
192
+ target: route53__namespace.RecordTarget.fromAlias(new route53Targets__namespace.ApiGatewayDomain(this._domainName)),
193
+ zone: hostedZone,
194
+ });
195
+ cdk$1.Tags.of(record).add(cdk.CDK.TAG.ROLE, cdk.CDK.ROLE.NETWORKING);
196
+ }
197
+ }
198
+ get api() {
199
+ return this._api;
200
+ }
201
+ get url() {
202
+ return this._api.url;
203
+ }
204
+ get certificateArn() {
205
+ return this._certificate?.certificateArn;
206
+ }
207
+ get domainName() {
208
+ return this._domainName?.domainName;
209
+ }
210
+ get host() {
211
+ return this._host;
212
+ }
213
+ get restApiId() {
214
+ return this._api.restApiId;
215
+ }
216
+ get restApiName() {
217
+ return this._api.restApiName;
218
+ }
219
+ get restApiRootResourceId() {
220
+ return this._api.restApiRootResourceId;
221
+ }
222
+ get deploymentStage() {
223
+ return this._api.deploymentStage;
224
+ }
225
+ get domainNameAliasDomainName() {
226
+ return this._domainName?.domainNameAliasDomainName;
227
+ }
228
+ get domainNameAliasHostedZoneId() {
229
+ return this._domainName?.domainNameAliasHostedZoneId;
230
+ }
231
+ get root() {
232
+ return this._api.root;
233
+ }
234
+ get env() {
235
+ return {
236
+ account: cdk$1.Stack.of(this).account,
237
+ region: cdk$1.Stack.of(this).region,
238
+ };
239
+ }
240
+ get stack() {
241
+ return this._api.stack;
242
+ }
243
+ arnForExecuteApi(method, path, stage) {
244
+ return this._api.arnForExecuteApi(method, path, stage);
245
+ }
246
+ metric(metricName, props) {
247
+ return this._api.metric(metricName, props);
248
+ }
249
+ metricCacheHitCount(props) {
250
+ return this._api.metricCacheHitCount(props);
251
+ }
252
+ metricCacheMissCount(props) {
253
+ return this._api.metricCacheMissCount(props);
254
+ }
255
+ metricClientError(props) {
256
+ return this._api.metricClientError(props);
257
+ }
258
+ metricCount(props) {
259
+ return this._api.metricCount(props);
260
+ }
261
+ metricIntegrationLatency(props) {
262
+ return this._api.metricIntegrationLatency(props);
263
+ }
264
+ metricLatency(props) {
265
+ return this._api.metricLatency(props);
266
+ }
267
+ metricServerError(props) {
268
+ return this._api.metricServerError(props);
269
+ }
270
+ applyRemovalPolicy(policy) {
271
+ this._api.applyRemovalPolicy(policy);
272
+ }
273
+ }
274
+
275
+ class JaypieStack extends cdk$1.Stack {
276
+ constructor(scope, id, props = {}) {
277
+ const { key, ...stackProps } = props;
278
+ // Handle stackName
279
+ if (!stackProps.stackName) {
280
+ stackProps.stackName = constructStackName(key);
281
+ }
282
+ // Handle env
283
+ stackProps.env = {
284
+ account: process.env.CDK_DEFAULT_ACCOUNT,
285
+ region: process.env.CDK_DEFAULT_REGION,
286
+ ...stackProps.env,
287
+ };
288
+ super(scope, id, stackProps);
289
+ // Apply tags
290
+ stackTagger(this, { name: stackProps.stackName });
291
+ }
292
+ }
293
+
294
+ class JaypieAppStack extends JaypieStack {
295
+ constructor(scope, id, props = {}) {
296
+ const { key = "app", ...stackProps } = props;
297
+ // Handle stackName
298
+ if (!stackProps.stackName) {
299
+ stackProps.stackName = constructStackName(key);
300
+ }
301
+ super(scope, id, { key, ...stackProps });
302
+ }
303
+ }
42
304
 
43
305
  class JaypieLambda extends constructs.Construct {
44
306
  constructor(scope, id, props) {
45
307
  super(scope, id);
46
- const { code, datadogApiKeyArn, environment: initialEnvironment = {}, envSecrets = {}, handler = "index.handler", layers = [], logRetention = cdk.CDK.LAMBDA.LOG_RETENTION, memorySize = cdk.CDK.LAMBDA.MEMORY_SIZE, paramsAndSecrets, paramsAndSecretsOptions, reservedConcurrentExecutions, roleTag, runtime = lambda__namespace.Runtime.NODEJS_22_X, secrets = [], timeout = cdk$1.Duration.seconds(cdk.CDK.DURATION.LAMBDA_WORKER), vendorTag, } = props;
308
+ const { code, datadogApiKeyArn, environment: initialEnvironment = {}, envSecrets = {}, handler = "index.handler", layers = [], logRetention = cdk.CDK.LAMBDA.LOG_RETENTION, memorySize = cdk.CDK.LAMBDA.MEMORY_SIZE, paramsAndSecrets, paramsAndSecretsOptions, reservedConcurrentExecutions, roleTag = cdk.CDK.ROLE.PROCESSING, runtime = lambda__namespace.Runtime.NODEJS_22_X, secrets = [], timeout = cdk$1.Duration.seconds(cdk.CDK.DURATION.LAMBDA_WORKER), vendorTag, } = props;
47
309
  // Create a mutable copy of the environment variables
48
310
  let environment = { ...initialEnvironment };
49
311
  // Default environment variables from process.env if present
@@ -845,7 +1107,7 @@ class JaypieHostedZone extends constructs.Construct {
845
1107
  });
846
1108
  }
847
1109
  // Create the hosted zone
848
- this.hostedZone = new awsRoute53.HostedZone(this, "HostedZone", {
1110
+ this.hostedZone = new route53.HostedZone(this, "HostedZone", {
849
1111
  queryLogsLogGroupArn: this.logGroup.logGroupArn,
850
1112
  zoneName,
851
1113
  });
@@ -858,6 +1120,26 @@ class JaypieHostedZone extends constructs.Construct {
858
1120
  }
859
1121
  }
860
1122
 
1123
+ const CDK = {
1124
+ TAG: {
1125
+ STACK_SHA: "stackSha",
1126
+ },
1127
+ };
1128
+ class JaypieInfrastructureStack extends JaypieStack {
1129
+ constructor(scope, id, props = {}) {
1130
+ const { key = "infra", ...stackProps } = props;
1131
+ // Handle stackName
1132
+ if (!stackProps.stackName) {
1133
+ stackProps.stackName = constructStackName(key);
1134
+ }
1135
+ super(scope, id, { key, ...stackProps });
1136
+ // Add infrastructure-specific tag
1137
+ if (process.env.CDK_ENV_INFRASTRUCTURE_STACK_SHA) {
1138
+ cdk$1.Tags.of(this).add(CDK.TAG.STACK_SHA, process.env.CDK_ENV_INFRASTRUCTURE_STACK_SHA);
1139
+ }
1140
+ }
1141
+ }
1142
+
861
1143
  class JaypieMongoDbSecret extends JaypieEnvSecret {
862
1144
  constructor(scope, id = "MongoConnectionString", props) {
863
1145
  const defaultProps = {
@@ -1168,15 +1450,271 @@ class JaypieTraceSigningKeySecret extends JaypieEnvSecret {
1168
1450
  }
1169
1451
  }
1170
1452
 
1453
+ class JaypieWebDeploymentBucket extends constructs.Construct {
1454
+ constructor(scope, id, props = {}) {
1455
+ super(scope, id);
1456
+ const roleTag = props.roleTag || cdk.CDK.ROLE.HOSTING;
1457
+ // Environment variable validation
1458
+ if (process.env.CDK_ENV_WEB_SUBDOMAIN &&
1459
+ !cdk.isValidSubdomain(process.env.CDK_ENV_WEB_SUBDOMAIN)) {
1460
+ throw new cdk.ConfigurationError("CDK_ENV_WEB_SUBDOMAIN is not a valid subdomain");
1461
+ }
1462
+ if (process.env.CDK_ENV_WEB_HOSTED_ZONE &&
1463
+ !cdk.isValidHostname(process.env.CDK_ENV_WEB_HOSTED_ZONE)) {
1464
+ throw new cdk.ConfigurationError("CDK_ENV_WEB_HOSTED_ZONE is not a valid hostname");
1465
+ }
1466
+ if (process.env.CDK_ENV_HOSTED_ZONE &&
1467
+ !cdk.isValidHostname(process.env.CDK_ENV_HOSTED_ZONE)) {
1468
+ throw new cdk.ConfigurationError("CDK_ENV_HOSTED_ZONE is not a valid hostname");
1469
+ }
1470
+ // Determine host from props or environment
1471
+ let host = props.host;
1472
+ if (!host) {
1473
+ try {
1474
+ host =
1475
+ process.env.CDK_ENV_WEB_HOST ||
1476
+ cdk.mergeDomain(process.env.CDK_ENV_WEB_SUBDOMAIN || "", process.env.CDK_ENV_WEB_HOSTED_ZONE ||
1477
+ process.env.CDK_ENV_HOSTED_ZONE ||
1478
+ "");
1479
+ }
1480
+ catch {
1481
+ host = undefined;
1482
+ }
1483
+ }
1484
+ if (host && !cdk.isValidHostname(host)) {
1485
+ throw new cdk.ConfigurationError("Host is not a valid hostname");
1486
+ }
1487
+ // Determine zone from props or environment
1488
+ const zone = props.zone ||
1489
+ process.env.CDK_ENV_WEB_HOSTED_ZONE ||
1490
+ process.env.CDK_ENV_HOSTED_ZONE;
1491
+ // Create the S3 bucket
1492
+ this.bucket = new s3__namespace.Bucket(this, "DestinationBucket", {
1493
+ accessControl: s3__namespace.BucketAccessControl.BUCKET_OWNER_FULL_CONTROL,
1494
+ autoDeleteObjects: true,
1495
+ blockPublicAccess: s3__namespace.BlockPublicAccess.BLOCK_ACLS,
1496
+ bucketName: props.name || constructEnvName("web"),
1497
+ publicReadAccess: true,
1498
+ removalPolicy: cdk$1.RemovalPolicy.DESTROY,
1499
+ versioned: false,
1500
+ websiteErrorDocument: "index.html",
1501
+ websiteIndexDocument: "index.html",
1502
+ ...props,
1503
+ });
1504
+ // Delegate IBucket properties to the bucket
1505
+ this.bucketArn = this.bucket.bucketArn;
1506
+ this.bucketDomainName = this.bucket.bucketDomainName;
1507
+ this.bucketDualStackDomainName = this.bucket.bucketDualStackDomainName;
1508
+ this.bucketName = this.bucket.bucketName;
1509
+ this.bucketRegionalDomainName = this.bucket.bucketRegionalDomainName;
1510
+ this.bucketWebsiteDomainName = this.bucket.bucketWebsiteDomainName;
1511
+ this.bucketWebsiteUrl = this.bucket.bucketWebsiteUrl;
1512
+ this.encryptionKey = this.bucket.encryptionKey;
1513
+ this.isWebsite = this.bucket.isWebsite;
1514
+ this.notificationsHandlerRole = undefined;
1515
+ this.policy = this.bucket.policy;
1516
+ cdk$1.Tags.of(this.bucket).add(cdk.CDK.TAG.ROLE, roleTag);
1517
+ // Create deployment role if repository is configured
1518
+ let repo;
1519
+ if (process.env.CDK_ENV_REPO) {
1520
+ repo = `repo:${process.env.CDK_ENV_REPO}:*`;
1521
+ }
1522
+ if (repo) {
1523
+ const bucketDeployRole = new awsIam.Role(this, "DestinationBucketDeployRole", {
1524
+ assumedBy: new awsIam.FederatedPrincipal(cdk$1.Fn.importValue(cdk.CDK.IMPORT.OIDC_PROVIDER), {
1525
+ StringLike: {
1526
+ "token.actions.githubusercontent.com:sub": repo,
1527
+ },
1528
+ }, "sts:AssumeRoleWithWebIdentity"),
1529
+ maxSessionDuration: cdk$1.Duration.hours(1),
1530
+ });
1531
+ cdk$1.Tags.of(bucketDeployRole).add(cdk.CDK.TAG.ROLE, cdk.CDK.ROLE.DEPLOY);
1532
+ // Allow the role to write to the bucket
1533
+ bucketDeployRole.addToPolicy(new awsIam.PolicyStatement({
1534
+ effect: awsIam.Effect.ALLOW,
1535
+ actions: [
1536
+ "s3:DeleteObject",
1537
+ "s3:GetObject",
1538
+ "s3:ListObjectsV2",
1539
+ "s3:PutObject",
1540
+ ],
1541
+ resources: [`${this.bucket.bucketArn}/*`],
1542
+ }));
1543
+ bucketDeployRole.addToPolicy(new awsIam.PolicyStatement({
1544
+ effect: awsIam.Effect.ALLOW,
1545
+ actions: ["s3:ListBucket"],
1546
+ resources: [this.bucket.bucketArn],
1547
+ }));
1548
+ // Allow the role to deploy CDK apps
1549
+ bucketDeployRole.addToPolicy(new awsIam.PolicyStatement({
1550
+ actions: ["cloudformation:DescribeStacks"],
1551
+ effect: awsIam.Effect.ALLOW,
1552
+ resources: ["*"], // TODO: restrict to this stack
1553
+ }));
1554
+ this.deployRoleArn = bucketDeployRole.roleArn;
1555
+ // Output the deploy role ARN
1556
+ new cdk$1.CfnOutput(this, "DestinationBucketDeployRoleArn", {
1557
+ value: bucketDeployRole.roleArn,
1558
+ });
1559
+ }
1560
+ // Create CloudFront distribution and certificate if host and zone are provided
1561
+ if (host && zone) {
1562
+ const hostedZone = typeof zone === "string"
1563
+ ? route53__namespace.HostedZone.fromLookup(this, "HostedZone", {
1564
+ domainName: zone,
1565
+ })
1566
+ : zone;
1567
+ // Create certificate if not provided
1568
+ if (props.certificate !== false) {
1569
+ this.certificate =
1570
+ typeof props.certificate === "object"
1571
+ ? props.certificate
1572
+ : new acm__namespace.Certificate(this, "Certificate", {
1573
+ domainName: host,
1574
+ validation: acm__namespace.CertificateValidation.fromDns(hostedZone),
1575
+ });
1576
+ new cdk$1.CfnOutput(this, "CertificateArn", {
1577
+ value: this.certificate.certificateArn,
1578
+ });
1579
+ cdk$1.Tags.of(this.certificate).add(cdk.CDK.TAG.ROLE, roleTag);
1580
+ }
1581
+ // Create CloudFront distribution
1582
+ this.distribution = new cloudfront__namespace.Distribution(this, "Distribution", {
1583
+ defaultBehavior: {
1584
+ cachePolicy: cloudfront__namespace.CachePolicy.CACHING_DISABLED,
1585
+ origin: new origins__namespace.S3Origin(this.bucket),
1586
+ viewerProtocolPolicy: cloudfront__namespace.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
1587
+ },
1588
+ certificate: this.certificate,
1589
+ domainNames: [host],
1590
+ });
1591
+ cdk$1.Tags.of(this.distribution).add(cdk.CDK.TAG.ROLE, roleTag);
1592
+ // If this is production, enable caching on everything but index.html
1593
+ if (isProductionEnv()) {
1594
+ this.distribution.addBehavior("/*", new origins__namespace.S3Origin(this.bucket), {
1595
+ viewerProtocolPolicy: cloudfront__namespace.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
1596
+ cachePolicy: cloudfront__namespace.CachePolicy.CACHING_OPTIMIZED,
1597
+ });
1598
+ }
1599
+ // Create DNS record
1600
+ const record = new route53__namespace.ARecord(this, "AliasRecord", {
1601
+ recordName: host,
1602
+ target: route53__namespace.RecordTarget.fromAlias(new route53Targets__namespace.CloudFrontTarget(this.distribution)),
1603
+ zone: hostedZone,
1604
+ });
1605
+ cdk$1.Tags.of(record).add(cdk.CDK.TAG.ROLE, cdk.CDK.ROLE.NETWORKING);
1606
+ this.distributionDomainName = this.distribution.distributionDomainName;
1607
+ }
1608
+ }
1609
+ // Implement remaining IBucket methods by delegating to the bucket
1610
+ addEventNotification(event, dest, ...filters) {
1611
+ this.bucket.addEventNotification(event, dest, ...filters);
1612
+ }
1613
+ addObjectCreatedNotification(dest, ...filters) {
1614
+ this.bucket.addObjectCreatedNotification(dest, ...filters);
1615
+ }
1616
+ addObjectRemovedNotification(dest, ...filters) {
1617
+ this.bucket.addObjectRemovedNotification(dest, ...filters);
1618
+ }
1619
+ addToResourcePolicy(permission) {
1620
+ return this.bucket.addToResourcePolicy(permission);
1621
+ }
1622
+ arnForObjects(keyPattern) {
1623
+ return this.bucket.arnForObjects(keyPattern);
1624
+ }
1625
+ grantDelete(identity, objectsKeyPattern) {
1626
+ return this.bucket.grantDelete(identity, objectsKeyPattern);
1627
+ }
1628
+ grantPublicAccess(allowedActions, keyPrefix) {
1629
+ return keyPrefix
1630
+ ? this.bucket.grantPublicAccess(allowedActions, keyPrefix)
1631
+ : this.bucket.grantPublicAccess(allowedActions);
1632
+ }
1633
+ grantPut(identity, objectsKeyPattern) {
1634
+ return this.bucket.grantPut(identity, objectsKeyPattern);
1635
+ }
1636
+ grantPutAcl(identity, objectsKeyPattern) {
1637
+ return this.bucket.grantPutAcl(identity, objectsKeyPattern);
1638
+ }
1639
+ grantRead(identity, objectsKeyPattern) {
1640
+ return this.bucket.grantRead(identity, objectsKeyPattern);
1641
+ }
1642
+ grantReadWrite(identity, objectsKeyPattern) {
1643
+ return this.bucket.grantReadWrite(identity, objectsKeyPattern);
1644
+ }
1645
+ grantWrite(identity, objectsKeyPattern) {
1646
+ return this.bucket.grantWrite(identity, objectsKeyPattern);
1647
+ }
1648
+ s3UrlForObject(key) {
1649
+ return this.bucket.s3UrlForObject(key);
1650
+ }
1651
+ urlForObject(key) {
1652
+ return this.bucket.urlForObject(key);
1653
+ }
1654
+ virtualHostedUrlForObject(key, options) {
1655
+ return this.bucket.virtualHostedUrlForObject(key, options);
1656
+ }
1657
+ transferAccelerationUrlForObject(key) {
1658
+ return this.bucket.transferAccelerationUrlForObject(key);
1659
+ }
1660
+ onCloudTrailEvent(id, options) {
1661
+ return this.bucket.onCloudTrailEvent(id, options);
1662
+ }
1663
+ onCloudTrailPutObject(id, options) {
1664
+ return this.bucket.onCloudTrailPutObject(id, options);
1665
+ }
1666
+ onCloudTrailWriteObject(id, options) {
1667
+ return this.bucket.onCloudTrailWriteObject(id, options);
1668
+ }
1669
+ addCorsRule(rule) {
1670
+ this.bucket.addCorsRule(rule);
1671
+ }
1672
+ addInventory(inventory) {
1673
+ this.bucket.addInventory(inventory);
1674
+ }
1675
+ addLifecycleRule(rule) {
1676
+ this.bucket.addLifecycleRule(rule);
1677
+ }
1678
+ addMetric(metric) {
1679
+ this.bucket.addMetric(metric);
1680
+ }
1681
+ enableEventBridgeNotification() {
1682
+ this.bucket.enableEventBridgeNotification();
1683
+ }
1684
+ addReplicationPolicy(policy) {
1685
+ this.bucket.addReplicationPolicy(policy);
1686
+ }
1687
+ get stack() {
1688
+ return this.bucket.stack;
1689
+ }
1690
+ get env() {
1691
+ return this.bucket.env;
1692
+ }
1693
+ applyRemovalPolicy(policy) {
1694
+ this.bucket.applyRemovalPolicy(policy);
1695
+ }
1696
+ }
1697
+
1698
+ exports.JaypieApiGateway = JaypieApiGateway;
1699
+ exports.JaypieAppStack = JaypieAppStack;
1171
1700
  exports.JaypieBucketQueuedLambda = JaypieBucketQueuedLambda;
1172
1701
  exports.JaypieDatadogSecret = JaypieDatadogSecret;
1173
1702
  exports.JaypieEnvSecret = JaypieEnvSecret;
1174
1703
  exports.JaypieExpressLambda = JaypieExpressLambda;
1175
1704
  exports.JaypieHostedZone = JaypieHostedZone;
1705
+ exports.JaypieInfrastructureStack = JaypieInfrastructureStack;
1176
1706
  exports.JaypieLambda = JaypieLambda;
1177
1707
  exports.JaypieMongoDbSecret = JaypieMongoDbSecret;
1178
1708
  exports.JaypieOpenAiSecret = JaypieOpenAiSecret;
1179
1709
  exports.JaypieQueuedLambda = JaypieQueuedLambda;
1180
1710
  exports.JaypieSsoGroups = JaypieSsoGroups;
1711
+ exports.JaypieStack = JaypieStack;
1181
1712
  exports.JaypieTraceSigningKeySecret = JaypieTraceSigningKeySecret;
1713
+ exports.JaypieWebDeploymentBucket = JaypieWebDeploymentBucket;
1714
+ exports.constructEnvName = constructEnvName;
1715
+ exports.constructStackName = constructStackName;
1716
+ exports.isEnv = isEnv;
1717
+ exports.isProductionEnv = isProductionEnv;
1718
+ exports.isSandboxEnv = isSandboxEnv;
1719
+ exports.stackTagger = stackTagger;
1182
1720
  //# sourceMappingURL=index.cjs.map