@jaypie/constructs 1.2.52 → 1.2.53

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,4 +1,4 @@
1
- import { RemovalPolicy } from "aws-cdk-lib";
1
+ import { CfnOutput, RemovalPolicy } from "aws-cdk-lib";
2
2
  import * as acm from "aws-cdk-lib/aws-certificatemanager";
3
3
  import * as cloudfront from "aws-cdk-lib/aws-cloudfront";
4
4
  import { AddToResourcePolicyResult, PolicyStatement } from "aws-cdk-lib/aws-iam";
@@ -123,6 +123,23 @@ export declare class JaypieWebDeploymentBucket extends Construct implements s3.I
123
123
  readonly wafLogBucket?: s3.IBucket;
124
124
  readonly webAcl?: wafv2.CfnWebACL;
125
125
  constructor(scope: Construct, id: string, props?: JaypieWebDeploymentBucketProps);
126
+ /**
127
+ * Emit stack-level CfnOutputs with stable, hash-free logical IDs so they can
128
+ * be read directly from `cdk-outputs.json` without prefix-matching. Skips
129
+ * outputs whose underlying resource is absent.
130
+ *
131
+ * Logical IDs (with optional `prefix`):
132
+ * - `${prefix}DestinationBucketName`
133
+ * - `${prefix}DestinationBucketDeployRoleArn` (when a deploy role exists)
134
+ * - `${prefix}DistributionId` (when a distribution exists)
135
+ * - `${prefix}CertificateArn` (when a certificate exists)
136
+ *
137
+ * @returns map of created outputs keyed by their logical ID
138
+ */
139
+ exportOutputs(options?: {
140
+ prefix?: string;
141
+ scope?: Construct;
142
+ }): Record<string, CfnOutput>;
126
143
  private resolveWafConfig;
127
144
  private isExportNameObject;
128
145
  private resolveLogBucket;
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Build a WAF log bucket name shaped like
3
+ * `aws-waf-logs-${env}-${key}-${name}-waf-${nonce}` (or `-waf-` only when
4
+ * `name` is empty). The `aws-waf-logs-` prefix is required by AWS WAF, and
5
+ * `-${PROJECT_NONCE}` is preserved verbatim for uniqueness; the middle is
6
+ * truncated when needed to fit S3's 63-char limit.
7
+ */
8
+ export declare function constructWafLogBucketName(name?: string): string;
@@ -2,6 +2,7 @@ export { addDatadogLayers } from "./addDatadogLayers";
2
2
  export { constructEnvName } from "./constructEnvName";
3
3
  export { constructStackName } from "./constructStackName";
4
4
  export { constructTagger } from "./constructTagger";
5
+ export { constructWafLogBucketName } from "./constructWafLogBucketName";
5
6
  export { envHostname, HostConfig } from "./envHostname";
6
7
  export { extendDatadogRole, ExtendDatadogRoleOptions, } from "./extendDatadogRole";
7
8
  export { clearAllCertificateCaches, clearCertificateCache, resolveCertificate, ResolveCertificateOptions, } from "./resolveCertificate";
@@ -401,6 +401,29 @@ function constructTagger(construct, { name } = {}) {
401
401
  return true;
402
402
  }
403
403
 
404
+ const AWS_WAF_LOGS_PREFIX = "aws-waf-logs-";
405
+ const S3_BUCKET_NAME_MAX_LENGTH = 63;
406
+ /**
407
+ * Build a WAF log bucket name shaped like
408
+ * `aws-waf-logs-${env}-${key}-${name}-waf-${nonce}` (or `-waf-` only when
409
+ * `name` is empty). The `aws-waf-logs-` prefix is required by AWS WAF, and
410
+ * `-${PROJECT_NONCE}` is preserved verbatim for uniqueness; the middle is
411
+ * truncated when needed to fit S3's 63-char limit.
412
+ */
413
+ function constructWafLogBucketName(name) {
414
+ const nonce = (process.env.PROJECT_NONCE ?? "cfe2").toLowerCase();
415
+ const nonceSuffix = `-${nonce}`;
416
+ const innerName = name ? `${name}-waf` : "waf";
417
+ const middle = constructEnvName(innerName)
418
+ .toLowerCase()
419
+ .slice(0, -nonceSuffix.length);
420
+ const maxMiddleLength = S3_BUCKET_NAME_MAX_LENGTH - AWS_WAF_LOGS_PREFIX.length - nonceSuffix.length;
421
+ const truncated = middle.length > maxMiddleLength
422
+ ? middle.slice(0, maxMiddleLength).replace(/-+$/, "")
423
+ : middle;
424
+ return `${AWS_WAF_LOGS_PREFIX}${truncated}${nonceSuffix}`;
425
+ }
426
+
404
427
  function envHostname({ component, domain, env, subdomain, } = {}) {
405
428
  const resolvedDomain = domain || process.env.CDK_ENV_DOMAIN || process.env.CDK_ENV_HOSTED_ZONE;
406
429
  if (!resolvedDomain) {
@@ -2765,9 +2788,7 @@ class JaypieDistribution extends constructs.Construct {
2765
2788
  const wafLogBucketId = wafConfig.name
2766
2789
  ? constructEnvName(`${wafConfig.name}-WafLogBucket`)
2767
2790
  : constructEnvName("WafLogBucket");
2768
- const wafLogBucketName = wafConfig.name
2769
- ? `aws-waf-logs-${constructEnvName(`${wafConfig.name}-waf`).toLowerCase()}`
2770
- : `aws-waf-logs-${constructEnvName("waf").toLowerCase()}`;
2791
+ const wafLogBucketName = constructWafLogBucketName(wafConfig.name);
2771
2792
  const createdBucket = new s3__namespace.Bucket(this, wafLogBucketId, {
2772
2793
  bucketName: wafLogBucketName,
2773
2794
  lifecycleRules: [
@@ -4622,7 +4643,7 @@ class JaypieWebDeploymentBucket extends constructs.Construct {
4622
4643
  let wafLogBucket;
4623
4644
  if (wafLogBucketProp === true) {
4624
4645
  const wafLogBucketId = constructEnvName(`${wafConfig.name}-WafLogBucket`);
4625
- const wafLogBucketName = `aws-waf-logs-${constructEnvName(`${wafConfig.name}-waf`).toLowerCase()}`;
4646
+ const wafLogBucketName = constructWafLogBucketName(wafConfig.name);
4626
4647
  const createdBucket = new s3__namespace.Bucket(this, wafLogBucketId, {
4627
4648
  bucketName: wafLogBucketName,
4628
4649
  lifecycleRules: [
@@ -4661,6 +4682,41 @@ class JaypieWebDeploymentBucket extends constructs.Construct {
4661
4682
  }
4662
4683
  }
4663
4684
  }
4685
+ /**
4686
+ * Emit stack-level CfnOutputs with stable, hash-free logical IDs so they can
4687
+ * be read directly from `cdk-outputs.json` without prefix-matching. Skips
4688
+ * outputs whose underlying resource is absent.
4689
+ *
4690
+ * Logical IDs (with optional `prefix`):
4691
+ * - `${prefix}DestinationBucketName`
4692
+ * - `${prefix}DestinationBucketDeployRoleArn` (when a deploy role exists)
4693
+ * - `${prefix}DistributionId` (when a distribution exists)
4694
+ * - `${prefix}CertificateArn` (when a certificate exists)
4695
+ *
4696
+ * @returns map of created outputs keyed by their logical ID
4697
+ */
4698
+ exportOutputs(options = {}) {
4699
+ const { prefix = "", scope = cdk.Stack.of(this) } = options;
4700
+ const outputs = {};
4701
+ const create = (id, value) => {
4702
+ const logicalId = `${prefix}${id}`;
4703
+ const output = new cdk.CfnOutput(scope, `${logicalId}Export`, { value });
4704
+ output.overrideLogicalId(logicalId);
4705
+ outputs[logicalId] = output;
4706
+ return output;
4707
+ };
4708
+ create("DestinationBucketName", this.bucket.bucketName);
4709
+ if (this.deployRoleArn) {
4710
+ create("DestinationBucketDeployRoleArn", this.deployRoleArn);
4711
+ }
4712
+ if (this.distribution) {
4713
+ create("DistributionId", this.distribution.distributionId);
4714
+ }
4715
+ if (this.certificate) {
4716
+ create("CertificateArn", this.certificate.certificateArn);
4717
+ }
4718
+ return outputs;
4719
+ }
4664
4720
  resolveWafConfig(wafProp, defaultName) {
4665
4721
  if (wafProp === false)
4666
4722
  return undefined;
@@ -5238,6 +5294,7 @@ exports.clearSecretsCache = clearSecretsCache;
5238
5294
  exports.constructEnvName = constructEnvName;
5239
5295
  exports.constructStackName = constructStackName;
5240
5296
  exports.constructTagger = constructTagger;
5297
+ exports.constructWafLogBucketName = constructWafLogBucketName;
5241
5298
  exports.ensureRoute53QueryLoggingPolicy = ensureRoute53QueryLoggingPolicy;
5242
5299
  exports.envHostname = envHostname;
5243
5300
  exports.extendDatadogRole = extendDatadogRole;