@jaypie/constructs 1.2.10 → 1.2.12

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.
@@ -5,8 +5,8 @@ import { Construct } from "constructs";
5
5
  export interface JaypieCertificateProps {
6
6
  /**
7
7
  * Import certificate from a provider stack instead of creating one.
8
- * Auto-detected from PROJECT_ENV (personal/ephemeral = consumer).
9
- * @default auto-detected from environment
8
+ * When true, imports the certificate ARN via CloudFormation export.
9
+ * @default false
10
10
  */
11
11
  consumer?: boolean;
12
12
  /**
@@ -16,19 +16,20 @@ export interface JaypieCertificateProps {
16
16
  domainName?: string;
17
17
  /**
18
18
  * Export name override for cross-stack sharing.
19
+ * Only used when provider is true.
19
20
  * @default Generated from environment and domain
20
21
  */
21
22
  export?: string;
22
23
  /**
23
24
  * Construct ID override. When not provided, ID is auto-generated from domain.
24
25
  * Use this to align with certificates created by other constructs.
25
- * @default Auto-generated as "Certificate-{sanitized-domain}"
26
+ * @default Auto-generated as "JaypieCert-{sanitized-domain}"
26
27
  */
27
28
  id?: string;
28
29
  /**
29
30
  * Export certificate ARN for other stacks to import.
30
- * Auto-detected from PROJECT_ENV (sandbox = provider).
31
- * @default auto-detected from environment
31
+ * When true, creates a CloudFormation export that consumer stacks can import.
32
+ * @default false
32
33
  */
33
34
  provider?: boolean;
34
35
  /**
@@ -83,11 +84,11 @@ export interface JaypieCertificateProps {
83
84
  * });
84
85
  *
85
86
  * @example
86
- * // Provider/consumer pattern for cross-stack sharing
87
- * // In sandbox stack:
87
+ * // Optional: Provider/consumer pattern for cross-stack sharing
88
+ * // In sandbox stack (explicitly export):
88
89
  * new JaypieCertificate(this, { provider: true });
89
90
  *
90
- * // In personal build:
91
+ * // In personal build (explicitly import):
91
92
  * new JaypieCertificate(this, { consumer: true });
92
93
  */
93
94
  export declare class JaypieCertificate extends Construct implements acm.ICertificate {
@@ -6,7 +6,7 @@ import * as route53 from "aws-cdk-lib/aws-route53";
6
6
  import * as s3 from "aws-cdk-lib/aws-s3";
7
7
  import { LambdaDestination } from "aws-cdk-lib/aws-s3-notifications";
8
8
  import { Construct } from "constructs";
9
- export interface JaypieDistributionProps extends Omit<cloudfront.DistributionProps, "certificate" | "defaultBehavior"> {
9
+ export interface JaypieDistributionProps extends Omit<cloudfront.DistributionProps, "certificate" | "defaultBehavior" | "logBucket"> {
10
10
  /**
11
11
  * SSL certificate for the CloudFront distribution
12
12
  * @default true (creates a new certificate)
@@ -20,10 +20,21 @@ export interface JaypieDistributionProps extends Omit<cloudfront.DistributionPro
20
20
  * Log destination configuration for CloudFront access logs
21
21
  * - LambdaDestination: Use a specific Lambda destination for S3 notifications
22
22
  * - true: Use Datadog forwarder for S3 notifications (default)
23
- * - false: Disable logging entirely
23
+ * - false: Disable S3 notifications (logging still occurs if logBucket is set)
24
24
  * @default true
25
25
  */
26
26
  destination?: LambdaDestination | boolean;
27
+ /**
28
+ * External log bucket for CloudFront access logs.
29
+ * - IBucket: Use existing bucket directly
30
+ * - string: Bucket name to import
31
+ * - { exportName: string }: CloudFormation export name to import
32
+ * - true: Use account logging bucket (CDK.IMPORT.LOG_BUCKET)
33
+ * @default undefined (creates new bucket if destination !== false)
34
+ */
35
+ logBucket?: s3.IBucket | string | {
36
+ exportName: string;
37
+ } | true;
27
38
  /**
28
39
  * The origin handler - can be an IOrigin, IFunctionUrl, or IFunction
29
40
  * If IFunction, a FunctionUrl will be created with auth NONE
@@ -74,6 +85,8 @@ export declare class JaypieDistribution extends Construct implements cloudfront.
74
85
  private isIFunctionUrl;
75
86
  private isIFunction;
76
87
  private hasInvokeMode;
88
+ private isExportNameObject;
89
+ private resolveLogBucket;
77
90
  get env(): {
78
91
  account: string;
79
92
  region: string;
@@ -2031,11 +2031,11 @@ function sanitizeDomain(domain) {
2031
2031
  * });
2032
2032
  *
2033
2033
  * @example
2034
- * // Provider/consumer pattern for cross-stack sharing
2035
- * // In sandbox stack:
2034
+ * // Optional: Provider/consumer pattern for cross-stack sharing
2035
+ * // In sandbox stack (explicitly export):
2036
2036
  * new JaypieCertificate(this, { provider: true });
2037
2037
  *
2038
- * // In personal build:
2038
+ * // In personal build (explicitly import):
2039
2039
  * new JaypieCertificate(this, { consumer: true });
2040
2040
  */
2041
2041
  class JaypieCertificate extends constructs.Construct {
@@ -2072,7 +2072,7 @@ class JaypieCertificate extends constructs.Construct {
2072
2072
  }
2073
2073
  }
2074
2074
  super(scope, id);
2075
- const { consumer = checkEnvIsConsumer(), domainName: propsDomainName, export: exportParam, provider = checkEnvIsProvider(), roleTag = CDK$2.ROLE.API, zone: propsZone, } = props;
2075
+ const { consumer = false, domainName: propsDomainName, export: exportParam, provider = false, roleTag = CDK$2.ROLE.API, zone: propsZone, } = props;
2076
2076
  // Validate environment variables
2077
2077
  if (process.env.CDK_ENV_API_SUBDOMAIN &&
2078
2078
  !isValidSubdomain(process.env.CDK_ENV_API_SUBDOMAIN)) {
@@ -2357,7 +2357,7 @@ class JaypieDatadogSecret extends JaypieEnvSecret {
2357
2357
  class JaypieDistribution extends constructs.Construct {
2358
2358
  constructor(scope, id, props) {
2359
2359
  super(scope, id);
2360
- const { certificate: certificateProp = true, defaultBehavior: propsDefaultBehavior, destination: destinationProp = true, handler, host: propsHost, invokeMode = lambda__namespace.InvokeMode.BUFFERED, originReadTimeout = cdk.Duration.seconds(CDK$2.DURATION.CLOUDFRONT_API), roleTag = CDK$2.ROLE.API, zone: propsZone, ...distributionProps } = props;
2360
+ const { certificate: certificateProp = true, defaultBehavior: propsDefaultBehavior, destination: destinationProp = true, handler, host: propsHost, invokeMode = lambda__namespace.InvokeMode.BUFFERED, logBucket: logBucketProp, originReadTimeout = cdk.Duration.seconds(CDK$2.DURATION.CLOUDFRONT_API), roleTag = CDK$2.ROLE.API, zone: propsZone, ...distributionProps } = props;
2361
2361
  // Validate environment variables
2362
2362
  if (process.env.CDK_ENV_API_SUBDOMAIN &&
2363
2363
  !isValidSubdomain(process.env.CDK_ENV_API_SUBDOMAIN)) {
@@ -2459,12 +2459,16 @@ class JaypieDistribution extends constructs.Construct {
2459
2459
  });
2460
2460
  this.certificate = certificateToUse;
2461
2461
  }
2462
- // Create log bucket if logging is enabled
2462
+ // Resolve or create log bucket
2463
2463
  let logBucket;
2464
- if (destinationProp !== false) {
2465
- logBucket = new s3__namespace.Bucket(this, constructEnvName("LogBucket"), {
2466
- objectOwnership: s3__namespace.ObjectOwnership.OBJECT_WRITER,
2467
- removalPolicy: cdk.RemovalPolicy.DESTROY,
2464
+ const isExternalBucket = logBucketProp !== undefined;
2465
+ if (logBucketProp !== undefined) {
2466
+ // Use external bucket
2467
+ logBucket = this.resolveLogBucket(logBucketProp);
2468
+ }
2469
+ else if (destinationProp !== false) {
2470
+ // Create new bucket (original behavior)
2471
+ const createdBucket = new s3__namespace.Bucket(this, constructEnvName("LogBucket"), {
2468
2472
  autoDeleteObjects: true,
2469
2473
  lifecycleRules: [
2470
2474
  {
@@ -2477,15 +2481,21 @@ class JaypieDistribution extends constructs.Construct {
2477
2481
  ],
2478
2482
  },
2479
2483
  ],
2484
+ objectOwnership: s3__namespace.ObjectOwnership.OBJECT_WRITER,
2485
+ removalPolicy: cdk.RemovalPolicy.DESTROY,
2480
2486
  });
2481
- cdk.Tags.of(logBucket).add(CDK$2.TAG.ROLE, CDK$2.ROLE.STORAGE);
2482
- // Add S3 notification to Datadog forwarder
2487
+ cdk.Tags.of(createdBucket).add(CDK$2.TAG.ROLE, CDK$2.ROLE.STORAGE);
2488
+ logBucket = createdBucket;
2489
+ }
2490
+ // Add S3 notifications if we have a bucket and destination is not false
2491
+ if (logBucket && destinationProp !== false && !isExternalBucket) {
2492
+ // Only add notifications to buckets we created (not external buckets)
2483
2493
  const lambdaDestination = destinationProp === true
2484
2494
  ? new s3n.LambdaDestination(resolveDatadogForwarderFunction(this))
2485
2495
  : destinationProp;
2486
2496
  logBucket.addEventNotification(s3__namespace.EventType.OBJECT_CREATED, lambdaDestination);
2487
- this.logBucket = logBucket;
2488
2497
  }
2498
+ this.logBucket = logBucket;
2489
2499
  // Create the CloudFront distribution
2490
2500
  this.distribution = new cloudfront__namespace.Distribution(this, constructEnvName("Distribution"), {
2491
2501
  defaultBehavior,
@@ -2556,6 +2566,30 @@ class JaypieDistribution extends constructs.Construct {
2556
2566
  "invokeMode" in handler &&
2557
2567
  typeof handler.invokeMode === "string");
2558
2568
  }
2569
+ isExportNameObject(value) {
2570
+ return (typeof value === "object" &&
2571
+ value !== null &&
2572
+ "exportName" in value &&
2573
+ typeof value.exportName === "string");
2574
+ }
2575
+ resolveLogBucket(logBucketProp) {
2576
+ // true = use account logging bucket
2577
+ if (logBucketProp === true) {
2578
+ const bucketName = cdk.Fn.importValue(CDK$2.IMPORT.LOG_BUCKET);
2579
+ return s3__namespace.Bucket.fromBucketName(this, "ImportedLogBucket", bucketName);
2580
+ }
2581
+ // { exportName: string } = import from CloudFormation export
2582
+ if (this.isExportNameObject(logBucketProp)) {
2583
+ const bucketName = cdk.Fn.importValue(logBucketProp.exportName);
2584
+ return s3__namespace.Bucket.fromBucketName(this, "ImportedLogBucket", bucketName);
2585
+ }
2586
+ // string = bucket name
2587
+ if (typeof logBucketProp === "string") {
2588
+ return s3__namespace.Bucket.fromBucketName(this, "ImportedLogBucket", logBucketProp);
2589
+ }
2590
+ // IBucket = use directly
2591
+ return logBucketProp;
2592
+ }
2559
2593
  // Implement IDistribution interface
2560
2594
  get env() {
2561
2595
  return {