@fjall/components-infrastructure 0.41.1 → 0.43.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. package/dist/lib/app.d.ts +25 -2
  2. package/dist/lib/app.js +53 -6
  3. package/dist/lib/config/aws/cloudTrail.js +2 -7
  4. package/dist/lib/config/aws/ecrDefaultImage.js +2 -7
  5. package/dist/lib/patterns/aws/buildkite.js +2 -10
  6. package/dist/lib/patterns/aws/compute.d.ts +0 -2
  7. package/dist/lib/patterns/aws/compute.js +3 -5
  8. package/dist/lib/patterns/aws/database.js +4 -7
  9. package/dist/lib/patterns/aws/freeTierApp.d.ts +0 -2
  10. package/dist/lib/patterns/aws/freeTierApp.js +5 -15
  11. package/dist/lib/patterns/aws/hostedZone.js +2 -7
  12. package/dist/lib/patterns/aws/spotInstanceApp.d.ts +0 -2
  13. package/dist/lib/patterns/aws/spotInstanceApp.js +5 -15
  14. package/dist/lib/patterns/aws/storage.d.ts +0 -3
  15. package/dist/lib/patterns/aws/storage.js +4 -7
  16. package/dist/lib/resources/aws/compute/ec2.d.ts +0 -2
  17. package/dist/lib/resources/aws/compute/ec2.js +1 -4
  18. package/dist/lib/resources/aws/compute/ecs.d.ts +0 -1
  19. package/dist/lib/resources/aws/compute/ecs.js +1 -8
  20. package/dist/lib/resources/aws/compute/ecsFreeTier.d.ts +0 -1
  21. package/dist/lib/resources/aws/compute/ecsFreeTier.js +1 -10
  22. package/dist/lib/resources/aws/compute/ecsSpot.d.ts +0 -1
  23. package/dist/lib/resources/aws/compute/ecsSpot.js +1 -10
  24. package/dist/lib/resources/aws/compute/lambda.d.ts +1 -0
  25. package/dist/lib/resources/aws/compute/lambda.js +3 -7
  26. package/dist/lib/resources/aws/database/database.d.ts +0 -2
  27. package/dist/lib/resources/aws/database/database.js +3 -5
  28. package/dist/lib/resources/aws/database/databaseFreeTier.d.ts +0 -2
  29. package/dist/lib/resources/aws/database/databaseFreeTier.js +3 -5
  30. package/dist/lib/resources/aws/database/databaseInstance.d.ts +0 -2
  31. package/dist/lib/resources/aws/database/databaseInstance.js +3 -5
  32. package/dist/lib/resources/aws/database/rdsAurora.d.ts +0 -2
  33. package/dist/lib/resources/aws/database/rdsAurora.js +7 -13
  34. package/dist/lib/resources/aws/database/rdsFreeTier.d.ts +0 -2
  35. package/dist/lib/resources/aws/database/rdsFreeTier.js +4 -10
  36. package/dist/lib/resources/aws/database/rdsInstance.d.ts +0 -2
  37. package/dist/lib/resources/aws/database/rdsInstance.js +8 -18
  38. package/dist/lib/resources/aws/logging/cloudTrail.d.ts +0 -2
  39. package/dist/lib/resources/aws/logging/cloudTrail.js +2 -6
  40. package/dist/lib/resources/aws/networking/vpc.d.ts +0 -2
  41. package/dist/lib/resources/aws/networking/vpc.js +6 -3
  42. package/dist/lib/resources/aws/secrets/kms.d.ts +0 -2
  43. package/dist/lib/resources/aws/secrets/kms.js +1 -4
  44. package/dist/lib/resources/aws/secrets/parameter.js +2 -3
  45. package/dist/lib/resources/aws/secrets/secret.d.ts +0 -2
  46. package/dist/lib/resources/aws/secrets/secret.js +2 -5
  47. package/dist/lib/resources/aws/utilities/codeBuild.d.ts +0 -2
  48. package/dist/lib/resources/aws/utilities/codeBuild.js +1 -3
  49. package/dist/lib/utils/directTagging.d.ts +31 -0
  50. package/dist/lib/utils/directTagging.js +86 -0
  51. package/dist/lib/utils/fjallConstruct.d.ts +8 -0
  52. package/dist/lib/utils/fjallConstruct.js +18 -0
  53. package/dist/lib/utils/fjallStackSynthesizer.d.ts +9 -0
  54. package/dist/lib/utils/fjallStackSynthesizer.js +22 -0
  55. package/dist/lib/utils/getConfig.js +10 -1
  56. package/dist/lib/utils/standardTagsAspect.d.ts +6 -29
  57. package/dist/lib/utils/standardTagsAspect.js +72 -33
  58. package/dist/lib/utils/tagContext.d.ts +28 -0
  59. package/dist/lib/utils/tagContext.js +53 -0
  60. package/dist/lib/utils/tagResource.d.ts +5 -0
  61. package/dist/lib/utils/tagResource.js +8 -5
  62. package/dist/lib/utils/tagSynthesizer.d.ts +13 -0
  63. package/dist/lib/utils/tagSynthesizer.js +55 -0
  64. package/package.json +3 -3
@@ -4,7 +4,6 @@ exports.CodeBuildProjectStack = exports.CodeBuildProject = void 0;
4
4
  const aws_cdk_lib_1 = require("aws-cdk-lib");
5
5
  const aws_codebuild_1 = require("aws-cdk-lib/aws-codebuild");
6
6
  const constructs_1 = require("constructs");
7
- const tagResource_1 = require("../../../utils/tagResource");
8
7
  class CodeBuildProject extends constructs_1.Construct {
9
8
  constructor(scope, id, props) {
10
9
  super(scope, id);
@@ -12,7 +11,6 @@ class CodeBuildProject extends constructs_1.Construct {
12
11
  ...props,
13
12
  description: props.description || `Code build project for ${id}`
14
13
  });
15
- (0, tagResource_1.default)(this.project, props.tags);
16
14
  }
17
15
  }
18
16
  exports.CodeBuildProject = CodeBuildProject;
@@ -25,4 +23,4 @@ class CodeBuildProjectStack extends aws_cdk_lib_1.Stack {
25
23
  }
26
24
  }
27
25
  exports.CodeBuildProjectStack = CodeBuildProjectStack;
28
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29kZUJ1aWxkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vbGliL3Jlc291cmNlcy9hd3MvdXRpbGl0aWVzL2NvZGVCdWlsZC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSw2Q0FBb0M7QUFDcEMsNkRBQWtFO0FBQ2xFLDJDQUF1QztBQUN2Qyw0REFBcUQ7QUFPckQsTUFBYSxnQkFBaUIsU0FBUSxzQkFBUztJQUc3QyxZQUFZLEtBQWdCLEVBQUUsRUFBVSxFQUFFLEtBQXFCO1FBQzdELEtBQUssQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFFakIsSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLHVCQUFPLENBQUMsSUFBSSxFQUFFLEVBQUUsRUFBRTtZQUNuQyxHQUFHLEtBQUs7WUFDUixXQUFXLEVBQUUsS0FBSyxDQUFDLFdBQVcsSUFBSSwwQkFBMEIsRUFBRSxFQUFFO1NBQ2pFLENBQUMsQ0FBQztRQUNILElBQUEscUJBQVcsRUFBQyxJQUFJLENBQUMsT0FBTyxFQUFFLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUN4QyxDQUFDO0NBQ0Y7QUFaRCw0Q0FZQztBQUVELE1BQWEscUJBQXNCLFNBQVEsbUJBQUs7SUFDOUMsWUFBWSxLQUFnQixFQUFFLEVBQVUsRUFBRSxLQUFxQjtRQUM3RCxLQUFLLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBRWpCLElBQUksZ0JBQWdCLENBQUMsSUFBSSxFQUFFLEVBQUUsRUFBRTtZQUM3QixHQUFHLEtBQUs7U0FDVCxDQUFDLENBQUM7SUFDTCxDQUFDO0NBQ0Y7QUFSRCxzREFRQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFN0YWNrIH0gZnJvbSBcImF3cy1jZGstbGliXCI7XG5pbXBvcnQgeyBQcm9qZWN0LCBQcm9qZWN0UHJvcHMgfSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLWNvZGVidWlsZFwiO1xuaW1wb3J0IHsgQ29uc3RydWN0IH0gZnJvbSBcImNvbnN0cnVjdHNcIjtcbmltcG9ydCB0YWdSZXNvdXJjZSBmcm9tIFwiLi4vLi4vLi4vdXRpbHMvdGFnUmVzb3VyY2VcIjtcbmltcG9ydCB7IEtleVZhbHVlIH0gZnJvbSBcIi4uLy4uLy4uL3R5cGVzXCI7XG5cbmludGVyZmFjZSBDb2RlQnVpbGRQcm9wcyBleHRlbmRzIFByb2plY3RQcm9wcyB7XG4gIHRhZ3M6IEtleVZhbHVlO1xufVxuXG5leHBvcnQgY2xhc3MgQ29kZUJ1aWxkUHJvamVjdCBleHRlbmRzIENvbnN0cnVjdCB7XG4gIHB1YmxpYyByZWFkb25seSBwcm9qZWN0OiBQcm9qZWN0O1xuXG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzOiBDb2RlQnVpbGRQcm9wcykge1xuICAgIHN1cGVyKHNjb3BlLCBpZCk7XG5cbiAgICB0aGlzLnByb2plY3QgPSBuZXcgUHJvamVjdCh0aGlzLCBpZCwge1xuICAgICAgLi4ucHJvcHMsXG4gICAgICBkZXNjcmlwdGlvbjogcHJvcHMuZGVzY3JpcHRpb24gfHwgYENvZGUgYnVpbGQgcHJvamVjdCBmb3IgJHtpZH1gXG4gICAgfSk7XG4gICAgdGFnUmVzb3VyY2UodGhpcy5wcm9qZWN0LCBwcm9wcy50YWdzKTtcbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgQ29kZUJ1aWxkUHJvamVjdFN0YWNrIGV4dGVuZHMgU3RhY2sge1xuICBjb25zdHJ1Y3RvcihzY29wZTogQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wczogQ29kZUJ1aWxkUHJvcHMpIHtcbiAgICBzdXBlcihzY29wZSwgaWQpO1xuXG4gICAgbmV3IENvZGVCdWlsZFByb2plY3QodGhpcywgaWQsIHtcbiAgICAgIC4uLnByb3BzXG4gICAgfSk7XG4gIH1cbn1cbiJdfQ==
26
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29kZUJ1aWxkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vbGliL3Jlc291cmNlcy9hd3MvdXRpbGl0aWVzL2NvZGVCdWlsZC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSw2Q0FBb0M7QUFDcEMsNkRBQWtFO0FBQ2xFLDJDQUF1QztBQU12QyxNQUFhLGdCQUFpQixTQUFRLHNCQUFTO0lBRzdDLFlBQVksS0FBZ0IsRUFBRSxFQUFVLEVBQUUsS0FBcUI7UUFDN0QsS0FBSyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQztRQUVqQixJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksdUJBQU8sQ0FBQyxJQUFJLEVBQUUsRUFBRSxFQUFFO1lBQ25DLEdBQUcsS0FBSztZQUNSLFdBQVcsRUFBRSxLQUFLLENBQUMsV0FBVyxJQUFJLDBCQUEwQixFQUFFLEVBQUU7U0FDakUsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztDQUNGO0FBWEQsNENBV0M7QUFFRCxNQUFhLHFCQUFzQixTQUFRLG1CQUFLO0lBQzlDLFlBQVksS0FBZ0IsRUFBRSxFQUFVLEVBQUUsS0FBcUI7UUFDN0QsS0FBSyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQztRQUVqQixJQUFJLGdCQUFnQixDQUFDLElBQUksRUFBRSxFQUFFLEVBQUU7WUFDN0IsR0FBRyxLQUFLO1NBQ1QsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztDQUNGO0FBUkQsc0RBUUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBTdGFjayB9IGZyb20gXCJhd3MtY2RrLWxpYlwiO1xuaW1wb3J0IHsgUHJvamVjdCwgUHJvamVjdFByb3BzIH0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1jb2RlYnVpbGRcIjtcbmltcG9ydCB7IENvbnN0cnVjdCB9IGZyb20gXCJjb25zdHJ1Y3RzXCI7XG5pbXBvcnQgeyBLZXlWYWx1ZSB9IGZyb20gXCIuLi8uLi8uLi90eXBlc1wiO1xuXG5pbnRlcmZhY2UgQ29kZUJ1aWxkUHJvcHMgZXh0ZW5kcyBQcm9qZWN0UHJvcHMge1xufVxuXG5leHBvcnQgY2xhc3MgQ29kZUJ1aWxkUHJvamVjdCBleHRlbmRzIENvbnN0cnVjdCB7XG4gIHB1YmxpYyByZWFkb25seSBwcm9qZWN0OiBQcm9qZWN0O1xuXG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzOiBDb2RlQnVpbGRQcm9wcykge1xuICAgIHN1cGVyKHNjb3BlLCBpZCk7XG5cbiAgICB0aGlzLnByb2plY3QgPSBuZXcgUHJvamVjdCh0aGlzLCBpZCwge1xuICAgICAgLi4ucHJvcHMsXG4gICAgICBkZXNjcmlwdGlvbjogcHJvcHMuZGVzY3JpcHRpb24gfHwgYENvZGUgYnVpbGQgcHJvamVjdCBmb3IgJHtpZH1gXG4gICAgfSk7XG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIENvZGVCdWlsZFByb2plY3RTdGFjayBleHRlbmRzIFN0YWNrIHtcbiAgY29uc3RydWN0b3Ioc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM6IENvZGVCdWlsZFByb3BzKSB7XG4gICAgc3VwZXIoc2NvcGUsIGlkKTtcblxuICAgIG5ldyBDb2RlQnVpbGRQcm9qZWN0KHRoaXMsIGlkLCB7XG4gICAgICAuLi5wcm9wc1xuICAgIH0pO1xuICB9XG59XG4iXX0=
@@ -0,0 +1,31 @@
1
+ import { Stack, CfnResource } from "aws-cdk-lib";
2
+ import { IConstruct } from "constructs";
3
+ /**
4
+ * DirectTagging provides a way to apply tags to resources without using aspects.
5
+ * This approach works by directly manipulating CloudFormation resources during
6
+ * stack initialization, avoiding the infinite loop issue in CDK v2.206.0+
7
+ */
8
+ export declare class DirectTagging {
9
+ private static globalTags;
10
+ private static stackTags;
11
+ /**
12
+ * Set global tags that will be applied to all resources
13
+ */
14
+ static setGlobalTags(tags: {
15
+ [key: string]: string;
16
+ }): void;
17
+ /**
18
+ * Set tags for a specific stack
19
+ */
20
+ static setStackTags(stack: Stack, tags: {
21
+ [key: string]: string;
22
+ }): void;
23
+ /**
24
+ * Apply tags to a CloudFormation resource directly
25
+ */
26
+ static tagCfnResource(resource: CfnResource): void;
27
+ /**
28
+ * Process a construct tree and tag all CloudFormation resources
29
+ */
30
+ static processConstructTree(root: IConstruct): void;
31
+ }
@@ -0,0 +1,86 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DirectTagging = void 0;
4
+ const aws_cdk_lib_1 = require("aws-cdk-lib");
5
+ /**
6
+ * DirectTagging provides a way to apply tags to resources without using aspects.
7
+ * This approach works by directly manipulating CloudFormation resources during
8
+ * stack initialization, avoiding the infinite loop issue in CDK v2.206.0+
9
+ */
10
+ class DirectTagging {
11
+ /**
12
+ * Set global tags that will be applied to all resources
13
+ */
14
+ static setGlobalTags(tags) {
15
+ DirectTagging.globalTags = {
16
+ ...DirectTagging.globalTags,
17
+ ...tags
18
+ };
19
+ }
20
+ /**
21
+ * Set tags for a specific stack
22
+ */
23
+ static setStackTags(stack, tags) {
24
+ const existingTags = DirectTagging.stackTags.get(stack) || {};
25
+ DirectTagging.stackTags.set(stack, {
26
+ ...existingTags,
27
+ ...tags
28
+ });
29
+ }
30
+ /**
31
+ * Apply tags to a CloudFormation resource directly
32
+ */
33
+ static tagCfnResource(resource) {
34
+ const stack = aws_cdk_lib_1.Stack.of(resource);
35
+ const stackTags = DirectTagging.stackTags.get(stack) || {};
36
+ const allTags = {
37
+ ...DirectTagging.globalTags,
38
+ ...stackTags
39
+ };
40
+ if (Object.keys(allTags).length === 0) {
41
+ return;
42
+ }
43
+ // Check if resource supports tags
44
+ if (!('tags' in resource) || typeof resource.tags !== 'object') {
45
+ return;
46
+ }
47
+ // Get existing tags
48
+ const existingTags = resource.tags || [];
49
+ const tagMap = new Map();
50
+ // Add existing tags to map
51
+ if (Array.isArray(existingTags)) {
52
+ existingTags.forEach((tag) => {
53
+ if (tag.key && tag.value) {
54
+ tagMap.set(tag.key, tag.value);
55
+ }
56
+ });
57
+ }
58
+ // Add new tags (overwriting if they exist)
59
+ Object.entries(allTags).forEach(([key, value]) => {
60
+ tagMap.set(key, value);
61
+ });
62
+ // Convert back to array format
63
+ resource.tags = Array.from(tagMap.entries()).map(([key, value]) => ({
64
+ key,
65
+ value
66
+ }));
67
+ }
68
+ /**
69
+ * Process a construct tree and tag all CloudFormation resources
70
+ */
71
+ static processConstructTree(root) {
72
+ const processNode = (node) => {
73
+ // Check if this is a CloudFormation resource
74
+ if (aws_cdk_lib_1.CfnResource.isCfnResource(node)) {
75
+ DirectTagging.tagCfnResource(node);
76
+ }
77
+ // Process children
78
+ node.node.children.forEach(child => processNode(child));
79
+ };
80
+ processNode(root);
81
+ }
82
+ }
83
+ exports.DirectTagging = DirectTagging;
84
+ DirectTagging.globalTags = {};
85
+ DirectTagging.stackTags = new Map();
86
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGlyZWN0VGFnZ2luZy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL2xpYi91dGlscy9kaXJlY3RUYWdnaW5nLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLDZDQUFpRDtBQUdqRDs7OztHQUlHO0FBQ0gsTUFBYSxhQUFhO0lBSXhCOztPQUVHO0lBQ0ksTUFBTSxDQUFDLGFBQWEsQ0FBQyxJQUErQjtRQUN6RCxhQUFhLENBQUMsVUFBVSxHQUFHO1lBQ3pCLEdBQUcsYUFBYSxDQUFDLFVBQVU7WUFDM0IsR0FBRyxJQUFJO1NBQ1IsQ0FBQztJQUNKLENBQUM7SUFFRDs7T0FFRztJQUNJLE1BQU0sQ0FBQyxZQUFZLENBQUMsS0FBWSxFQUFFLElBQStCO1FBQ3RFLE1BQU0sWUFBWSxHQUFHLGFBQWEsQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUM5RCxhQUFhLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxLQUFLLEVBQUU7WUFDakMsR0FBRyxZQUFZO1lBQ2YsR0FBRyxJQUFJO1NBQ1IsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVEOztPQUVHO0lBQ0ksTUFBTSxDQUFDLGNBQWMsQ0FBQyxRQUFxQjtRQUNoRCxNQUFNLEtBQUssR0FBRyxtQkFBSyxDQUFDLEVBQUUsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUNqQyxNQUFNLFNBQVMsR0FBRyxhQUFhLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDM0QsTUFBTSxPQUFPLEdBQUc7WUFDZCxHQUFHLGFBQWEsQ0FBQyxVQUFVO1lBQzNCLEdBQUcsU0FBUztTQUNiLENBQUM7UUFFRixJQUFJLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQ3RDLE9BQU87UUFDVCxDQUFDO1FBRUQsa0NBQWtDO1FBQ2xDLElBQUksQ0FBQyxDQUFDLE1BQU0sSUFBSSxRQUFRLENBQUMsSUFBSSxPQUFPLFFBQVEsQ0FBQyxJQUFJLEtBQUssUUFBUSxFQUFFLENBQUM7WUFDL0QsT0FBTztRQUNULENBQUM7UUFFRCxvQkFBb0I7UUFDcEIsTUFBTSxZQUFZLEdBQUcsUUFBUSxDQUFDLElBQUksSUFBSSxFQUFFLENBQUM7UUFDekMsTUFBTSxNQUFNLEdBQUcsSUFBSSxHQUFHLEVBQWtCLENBQUM7UUFFekMsMkJBQTJCO1FBQzNCLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsRUFBRSxDQUFDO1lBQ2hDLFlBQVksQ0FBQyxPQUFPLENBQUMsQ0FBQyxHQUFRLEVBQUUsRUFBRTtnQkFDaEMsSUFBSSxHQUFHLENBQUMsR0FBRyxJQUFJLEdBQUcsQ0FBQyxLQUFLLEVBQUUsQ0FBQztvQkFDekIsTUFBTSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQztnQkFDakMsQ0FBQztZQUNILENBQUMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQztRQUVELDJDQUEyQztRQUMzQyxNQUFNLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxFQUFFLEVBQUU7WUFDL0MsTUFBTSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDekIsQ0FBQyxDQUFDLENBQUM7UUFFSCwrQkFBK0I7UUFDL0IsUUFBUSxDQUFDLElBQUksR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1lBQ2xFLEdBQUc7WUFDSCxLQUFLO1NBQ04sQ0FBQyxDQUFDLENBQUM7SUFDTixDQUFDO0lBRUQ7O09BRUc7SUFDSSxNQUFNLENBQUMsb0JBQW9CLENBQUMsSUFBZ0I7UUFDakQsTUFBTSxXQUFXLEdBQUcsQ0FBQyxJQUFnQixFQUFFLEVBQUU7WUFDdkMsNkNBQTZDO1lBQzdDLElBQUkseUJBQVcsQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQztnQkFDcEMsYUFBYSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUNyQyxDQUFDO1lBRUQsbUJBQW1CO1lBQ25CLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO1FBQzFELENBQUMsQ0FBQztRQUVGLFdBQVcsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUNwQixDQUFDOztBQXJGSCxzQ0FzRkM7QUFyRmdCLHdCQUFVLEdBQThCLEVBQUUsQ0FBQztBQUMzQyx1QkFBUyxHQUEwQyxJQUFJLEdBQUcsRUFBRSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgU3RhY2ssIENmblJlc291cmNlIH0gZnJvbSBcImF3cy1jZGstbGliXCI7XG5pbXBvcnQgeyBJQ29uc3RydWN0LCBOb2RlIH0gZnJvbSBcImNvbnN0cnVjdHNcIjtcblxuLyoqXG4gKiBEaXJlY3RUYWdnaW5nIHByb3ZpZGVzIGEgd2F5IHRvIGFwcGx5IHRhZ3MgdG8gcmVzb3VyY2VzIHdpdGhvdXQgdXNpbmcgYXNwZWN0cy5cbiAqIFRoaXMgYXBwcm9hY2ggd29ya3MgYnkgZGlyZWN0bHkgbWFuaXB1bGF0aW5nIENsb3VkRm9ybWF0aW9uIHJlc291cmNlcyBkdXJpbmdcbiAqIHN0YWNrIGluaXRpYWxpemF0aW9uLCBhdm9pZGluZyB0aGUgaW5maW5pdGUgbG9vcCBpc3N1ZSBpbiBDREsgdjIuMjA2LjArXG4gKi9cbmV4cG9ydCBjbGFzcyBEaXJlY3RUYWdnaW5nIHtcbiAgcHJpdmF0ZSBzdGF0aWMgZ2xvYmFsVGFnczogeyBba2V5OiBzdHJpbmddOiBzdHJpbmcgfSA9IHt9O1xuICBwcml2YXRlIHN0YXRpYyBzdGFja1RhZ3M6IE1hcDxTdGFjaywgeyBba2V5OiBzdHJpbmddOiBzdHJpbmcgfT4gPSBuZXcgTWFwKCk7XG4gIFxuICAvKipcbiAgICogU2V0IGdsb2JhbCB0YWdzIHRoYXQgd2lsbCBiZSBhcHBsaWVkIHRvIGFsbCByZXNvdXJjZXNcbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgc2V0R2xvYmFsVGFncyh0YWdzOiB7IFtrZXk6IHN0cmluZ106IHN0cmluZyB9KTogdm9pZCB7XG4gICAgRGlyZWN0VGFnZ2luZy5nbG9iYWxUYWdzID0ge1xuICAgICAgLi4uRGlyZWN0VGFnZ2luZy5nbG9iYWxUYWdzLFxuICAgICAgLi4udGFnc1xuICAgIH07XG4gIH1cbiAgXG4gIC8qKlxuICAgKiBTZXQgdGFncyBmb3IgYSBzcGVjaWZpYyBzdGFja1xuICAgKi9cbiAgcHVibGljIHN0YXRpYyBzZXRTdGFja1RhZ3Moc3RhY2s6IFN0YWNrLCB0YWdzOiB7IFtrZXk6IHN0cmluZ106IHN0cmluZyB9KTogdm9pZCB7XG4gICAgY29uc3QgZXhpc3RpbmdUYWdzID0gRGlyZWN0VGFnZ2luZy5zdGFja1RhZ3MuZ2V0KHN0YWNrKSB8fCB7fTtcbiAgICBEaXJlY3RUYWdnaW5nLnN0YWNrVGFncy5zZXQoc3RhY2ssIHtcbiAgICAgIC4uLmV4aXN0aW5nVGFncyxcbiAgICAgIC4uLnRhZ3NcbiAgICB9KTtcbiAgfVxuICBcbiAgLyoqXG4gICAqIEFwcGx5IHRhZ3MgdG8gYSBDbG91ZEZvcm1hdGlvbiByZXNvdXJjZSBkaXJlY3RseVxuICAgKi9cbiAgcHVibGljIHN0YXRpYyB0YWdDZm5SZXNvdXJjZShyZXNvdXJjZTogQ2ZuUmVzb3VyY2UpOiB2b2lkIHtcbiAgICBjb25zdCBzdGFjayA9IFN0YWNrLm9mKHJlc291cmNlKTtcbiAgICBjb25zdCBzdGFja1RhZ3MgPSBEaXJlY3RUYWdnaW5nLnN0YWNrVGFncy5nZXQoc3RhY2spIHx8IHt9O1xuICAgIGNvbnN0IGFsbFRhZ3MgPSB7XG4gICAgICAuLi5EaXJlY3RUYWdnaW5nLmdsb2JhbFRhZ3MsXG4gICAgICAuLi5zdGFja1RhZ3NcbiAgICB9O1xuICAgIFxuICAgIGlmIChPYmplY3Qua2V5cyhhbGxUYWdzKS5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgXG4gICAgLy8gQ2hlY2sgaWYgcmVzb3VyY2Ugc3VwcG9ydHMgdGFnc1xuICAgIGlmICghKCd0YWdzJyBpbiByZXNvdXJjZSkgfHwgdHlwZW9mIHJlc291cmNlLnRhZ3MgIT09ICdvYmplY3QnKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIFxuICAgIC8vIEdldCBleGlzdGluZyB0YWdzXG4gICAgY29uc3QgZXhpc3RpbmdUYWdzID0gcmVzb3VyY2UudGFncyB8fCBbXTtcbiAgICBjb25zdCB0YWdNYXAgPSBuZXcgTWFwPHN0cmluZywgc3RyaW5nPigpO1xuICAgIFxuICAgIC8vIEFkZCBleGlzdGluZyB0YWdzIHRvIG1hcFxuICAgIGlmIChBcnJheS5pc0FycmF5KGV4aXN0aW5nVGFncykpIHtcbiAgICAgIGV4aXN0aW5nVGFncy5mb3JFYWNoKCh0YWc6IGFueSkgPT4ge1xuICAgICAgICBpZiAodGFnLmtleSAmJiB0YWcudmFsdWUpIHtcbiAgICAgICAgICB0YWdNYXAuc2V0KHRhZy5rZXksIHRhZy52YWx1ZSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cbiAgICBcbiAgICAvLyBBZGQgbmV3IHRhZ3MgKG92ZXJ3cml0aW5nIGlmIHRoZXkgZXhpc3QpXG4gICAgT2JqZWN0LmVudHJpZXMoYWxsVGFncykuZm9yRWFjaCgoW2tleSwgdmFsdWVdKSA9PiB7XG4gICAgICB0YWdNYXAuc2V0KGtleSwgdmFsdWUpO1xuICAgIH0pO1xuICAgIFxuICAgIC8vIENvbnZlcnQgYmFjayB0byBhcnJheSBmb3JtYXRcbiAgICByZXNvdXJjZS50YWdzID0gQXJyYXkuZnJvbSh0YWdNYXAuZW50cmllcygpKS5tYXAoKFtrZXksIHZhbHVlXSkgPT4gKHtcbiAgICAgIGtleSxcbiAgICAgIHZhbHVlXG4gICAgfSkpO1xuICB9XG4gIFxuICAvKipcbiAgICogUHJvY2VzcyBhIGNvbnN0cnVjdCB0cmVlIGFuZCB0YWcgYWxsIENsb3VkRm9ybWF0aW9uIHJlc291cmNlc1xuICAgKi9cbiAgcHVibGljIHN0YXRpYyBwcm9jZXNzQ29uc3RydWN0VHJlZShyb290OiBJQ29uc3RydWN0KTogdm9pZCB7XG4gICAgY29uc3QgcHJvY2Vzc05vZGUgPSAobm9kZTogSUNvbnN0cnVjdCkgPT4ge1xuICAgICAgLy8gQ2hlY2sgaWYgdGhpcyBpcyBhIENsb3VkRm9ybWF0aW9uIHJlc291cmNlXG4gICAgICBpZiAoQ2ZuUmVzb3VyY2UuaXNDZm5SZXNvdXJjZShub2RlKSkge1xuICAgICAgICBEaXJlY3RUYWdnaW5nLnRhZ0NmblJlc291cmNlKG5vZGUpO1xuICAgICAgfVxuICAgICAgXG4gICAgICAvLyBQcm9jZXNzIGNoaWxkcmVuXG4gICAgICBub2RlLm5vZGUuY2hpbGRyZW4uZm9yRWFjaChjaGlsZCA9PiBwcm9jZXNzTm9kZShjaGlsZCkpO1xuICAgIH07XG4gICAgXG4gICAgcHJvY2Vzc05vZGUocm9vdCk7XG4gIH1cbn1cbiJdfQ==
@@ -0,0 +1,8 @@
1
+ import { Construct } from "constructs";
2
+ /**
3
+ * Base construct for Fjall resources that automatically
4
+ * applies tags from context during construction.
5
+ */
6
+ export declare class FjallConstruct extends Construct {
7
+ constructor(scope: Construct, id: string);
8
+ }
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FjallConstruct = void 0;
4
+ const constructs_1 = require("constructs");
5
+ const tagContext_1 = require("./tagContext");
6
+ /**
7
+ * Base construct for Fjall resources that automatically
8
+ * applies tags from context during construction.
9
+ */
10
+ class FjallConstruct extends constructs_1.Construct {
11
+ constructor(scope, id) {
12
+ super(scope, id);
13
+ // Apply tags from context during construction
14
+ tagContext_1.TagContext.applyTagsFromContext(this.node);
15
+ }
16
+ }
17
+ exports.FjallConstruct = FjallConstruct;
18
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmphbGxDb25zdHJ1Y3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9saWIvdXRpbHMvZmphbGxDb25zdHJ1Y3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsMkNBQXVDO0FBQ3ZDLDZDQUEwQztBQUUxQzs7O0dBR0c7QUFDSCxNQUFhLGNBQWUsU0FBUSxzQkFBUztJQUMzQyxZQUFZLEtBQWdCLEVBQUUsRUFBVTtRQUN0QyxLQUFLLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBRWpCLDhDQUE4QztRQUM5Qyx1QkFBVSxDQUFDLG9CQUFvQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUM3QyxDQUFDO0NBQ0Y7QUFQRCx3Q0FPQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbnN0cnVjdCB9IGZyb20gXCJjb25zdHJ1Y3RzXCI7XG5pbXBvcnQgeyBUYWdDb250ZXh0IH0gZnJvbSBcIi4vdGFnQ29udGV4dFwiO1xuXG4vKipcbiAqIEJhc2UgY29uc3RydWN0IGZvciBGamFsbCByZXNvdXJjZXMgdGhhdCBhdXRvbWF0aWNhbGx5XG4gKiBhcHBsaWVzIHRhZ3MgZnJvbSBjb250ZXh0IGR1cmluZyBjb25zdHJ1Y3Rpb24uXG4gKi9cbmV4cG9ydCBjbGFzcyBGamFsbENvbnN0cnVjdCBleHRlbmRzIENvbnN0cnVjdCB7XG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcpIHtcbiAgICBzdXBlcihzY29wZSwgaWQpO1xuICAgIFxuICAgIC8vIEFwcGx5IHRhZ3MgZnJvbSBjb250ZXh0IGR1cmluZyBjb25zdHJ1Y3Rpb25cbiAgICBUYWdDb250ZXh0LmFwcGx5VGFnc0Zyb21Db250ZXh0KHRoaXMubm9kZSk7XG4gIH1cbn1cbiJdfQ==
@@ -0,0 +1,9 @@
1
+ import { DefaultStackSynthesizer } from "aws-cdk-lib";
2
+ import { ISynthesisSession } from "aws-cdk-lib/core";
3
+ /**
4
+ * Custom stack synthesizer that applies tags during synthesis.
5
+ * This avoids the infinite loop issue with aspects in CDK v2.206.0+
6
+ */
7
+ export declare class FjallStackSynthesizer extends DefaultStackSynthesizer {
8
+ synthesize(session: ISynthesisSession): void;
9
+ }
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FjallStackSynthesizer = void 0;
4
+ const aws_cdk_lib_1 = require("aws-cdk-lib");
5
+ const directTagging_1 = require("./directTagging");
6
+ /**
7
+ * Custom stack synthesizer that applies tags during synthesis.
8
+ * This avoids the infinite loop issue with aspects in CDK v2.206.0+
9
+ */
10
+ class FjallStackSynthesizer extends aws_cdk_lib_1.DefaultStackSynthesizer {
11
+ synthesize(session) {
12
+ const stack = this.boundStack;
13
+ // Process the entire construct tree to apply tags
14
+ if (stack) {
15
+ directTagging_1.DirectTagging.processConstructTree(stack);
16
+ }
17
+ // Continue with normal synthesis
18
+ super.synthesize(session);
19
+ }
20
+ }
21
+ exports.FjallStackSynthesizer = FjallStackSynthesizer;
22
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmphbGxTdGFja1N5bnRoZXNpemVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vbGliL3V0aWxzL2ZqYWxsU3RhY2tTeW50aGVzaXplci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSw2Q0FBc0Q7QUFFdEQsbURBQWdEO0FBRWhEOzs7R0FHRztBQUNILE1BQWEscUJBQXNCLFNBQVEscUNBQXVCO0lBQ3pELFVBQVUsQ0FBQyxPQUEwQjtRQUMxQyxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDO1FBRTlCLGtEQUFrRDtRQUNsRCxJQUFJLEtBQUssRUFBRSxDQUFDO1lBQ1YsNkJBQWEsQ0FBQyxvQkFBb0IsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUM1QyxDQUFDO1FBRUQsaUNBQWlDO1FBQ2pDLEtBQUssQ0FBQyxVQUFVLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDNUIsQ0FBQztDQUNGO0FBWkQsc0RBWUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBEZWZhdWx0U3RhY2tTeW50aGVzaXplciB9IGZyb20gXCJhd3MtY2RrLWxpYlwiO1xuaW1wb3J0IHsgSVN5bnRoZXNpc1Nlc3Npb24gfSBmcm9tIFwiYXdzLWNkay1saWIvY29yZVwiO1xuaW1wb3J0IHsgRGlyZWN0VGFnZ2luZyB9IGZyb20gXCIuL2RpcmVjdFRhZ2dpbmdcIjtcblxuLyoqXG4gKiBDdXN0b20gc3RhY2sgc3ludGhlc2l6ZXIgdGhhdCBhcHBsaWVzIHRhZ3MgZHVyaW5nIHN5bnRoZXNpcy5cbiAqIFRoaXMgYXZvaWRzIHRoZSBpbmZpbml0ZSBsb29wIGlzc3VlIHdpdGggYXNwZWN0cyBpbiBDREsgdjIuMjA2LjArXG4gKi9cbmV4cG9ydCBjbGFzcyBGamFsbFN0YWNrU3ludGhlc2l6ZXIgZXh0ZW5kcyBEZWZhdWx0U3RhY2tTeW50aGVzaXplciB7XG4gIHB1YmxpYyBzeW50aGVzaXplKHNlc3Npb246IElTeW50aGVzaXNTZXNzaW9uKTogdm9pZCB7XG4gICAgY29uc3Qgc3RhY2sgPSB0aGlzLmJvdW5kU3RhY2s7XG4gICAgXG4gICAgLy8gUHJvY2VzcyB0aGUgZW50aXJlIGNvbnN0cnVjdCB0cmVlIHRvIGFwcGx5IHRhZ3NcbiAgICBpZiAoc3RhY2spIHtcbiAgICAgIERpcmVjdFRhZ2dpbmcucHJvY2Vzc0NvbnN0cnVjdFRyZWUoc3RhY2spO1xuICAgIH1cbiAgICBcbiAgICAvLyBDb250aW51ZSB3aXRoIG5vcm1hbCBzeW50aGVzaXNcbiAgICBzdXBlci5zeW50aGVzaXplKHNlc3Npb24pO1xuICB9XG59XG4iXX0=
@@ -44,7 +44,16 @@ function getConfig(accountName) {
44
44
  }
45
45
  }
46
46
  }
47
+ // Check for environment from context (highest priority)
48
+ const contextEnvironment = app.node.tryGetContext("environment");
49
+ if (contextEnvironment) {
50
+ config.environment = contextEnvironment;
51
+ }
52
+ else if (process.env.ENVIRONMENT && config.environment === "unknown") {
53
+ // Fall back to ENVIRONMENT variable if no other source found
54
+ config.environment = process.env.ENVIRONMENT;
55
+ }
47
56
  return config;
48
57
  }
49
58
  exports.default = getConfig;
50
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2V0Q29uZmlnLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vbGliL3V0aWxzL2dldENvbmZpZy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQWVBLDhCQWtEQztBQS9ERCxnQ0FBeUI7QUFDekIsc0NBQW9EO0FBWXBELFNBQWdCLFNBQVMsQ0FBQyxXQUFvQjtJQUM1QyxNQUFNLEdBQUcsR0FBRyxhQUFHLENBQUMsV0FBVyxFQUFFLENBQUM7SUFFOUIsTUFBTSxNQUFNLEdBQVc7UUFDckIsTUFBTSxFQUFFLE9BQU8sQ0FBQyxHQUFHLENBQUMsVUFBVSxJQUFJLFdBQVc7UUFDN0MsV0FBVyxFQUFFLFNBQVM7UUFDdEIsZ0JBQWdCLEVBQUUsRUFBRTtRQUNwQixrQkFBa0IsRUFBRSxFQUFFO0tBQ3ZCLENBQUM7SUFFRixJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxVQUFVO1FBQ3pCLE9BQU8sQ0FBQyxJQUFJLENBQUMsZ0RBQWdELENBQUMsQ0FBQztJQUVqRSwyQ0FBMkM7SUFDM0MsTUFBTSxXQUFXLEdBQUcsYUFBVyxDQUFDLFVBQVUsRUFBRSxDQUFDO0lBRTdDLHdCQUF3QjtJQUN4QixNQUFNLENBQUMsZ0JBQWdCLEdBQUcsV0FBVyxDQUFDLG1CQUFtQixFQUFFLENBQUM7SUFFNUQsMkJBQTJCO0lBQzNCLE1BQU0sQ0FBQyxrQkFBa0IsR0FBRyxXQUFXLENBQUMscUJBQXFCLEVBQUUsQ0FBQztJQUVoRSw2REFBNkQ7SUFDN0QsSUFBSSxDQUFDLFdBQVc7UUFBRSxXQUFXLEdBQUcsR0FBRyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsYUFBYSxDQUFDLENBQUM7SUFDdEUsb0VBQW9FO0lBQ3BFLElBQUksV0FBVyxFQUFFLENBQUM7UUFDaEIsTUFBTSxlQUFlLEdBQUcsV0FBVyxDQUFDLGtCQUFrQixDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBQ3BFLElBQUksQ0FBQyxDQUFDLGVBQWUsRUFBRSxDQUFDO1lBQ3RCLE1BQU0sQ0FBQyxTQUFTLEdBQUcsZUFBZSxDQUFDLEVBQUUsQ0FBQztZQUN0QyxNQUFNLENBQUMsV0FBVyxHQUFHLGVBQWUsQ0FBQyxJQUFJLENBQUM7WUFDMUMsTUFBTSxDQUFDLFdBQVcsR0FBRyxlQUFlLENBQUMsV0FBVyxDQUFDO1FBQ25ELENBQUM7SUFDSCxDQUFDO0lBRUQsa0ZBQWtGO0lBQ2xGLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDeEIsTUFBTSxTQUFTLEdBQUcsR0FBRyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsV0FBVyxDQUFDLENBQUM7UUFDdEQsd0VBQXdFO1FBQ3hFLElBQUksU0FBUyxFQUFFLENBQUM7WUFDZCxNQUFNLENBQUMsU0FBUyxHQUFHLFNBQVMsQ0FBQztZQUU3QixNQUFNLGVBQWUsR0FBRyxXQUFXLENBQUMsc0JBQXNCLENBQUMsU0FBUyxDQUFDLENBQUM7WUFDdEUsSUFBSSxDQUFDLENBQUMsZUFBZSxFQUFFLENBQUM7Z0JBQ3RCLE1BQU0sQ0FBQyxXQUFXLEdBQUcsZUFBZSxDQUFDLElBQUksQ0FBQztnQkFDMUMsTUFBTSxDQUFDLFdBQVcsR0FBRyxlQUFlLENBQUMsV0FBVyxDQUFDO1lBQ25ELENBQUM7UUFDSCxDQUFDO0lBQ0gsQ0FBQztJQUVELE9BQU8sTUFBTSxDQUFDO0FBQ2hCLENBQUM7QUFFRCxrQkFBZSxTQUFTLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBBY2NvdW50IH0gZnJvbSBcIkBhd3Mtc2RrL2NsaWVudC1vcmdhbml6YXRpb25zXCI7XG5cbmltcG9ydCBBcHAgZnJvbSBcIi4uL2FwcFwiO1xuaW1wb3J0IHsgQ29uZmlnIGFzIEZqYWxsQ29uZmlnIH0gZnJvbSBcIkBmamFsbC91dGlsXCI7XG5pbXBvcnQgeyBJQ29zdEFsbG9jYXRpb25UYWdzIH0gZnJvbSBcIi4uL2NvbmZpZy9hd3NcIjtcblxuaW50ZXJmYWNlIENvbmZpZyB7XG4gIHJlZ2lvbjogc3RyaW5nO1xuICBlbnZpcm9ubWVudDogc3RyaW5nO1xuICBleGlzdGluZ0FjY291bnRzOiBBY2NvdW50W107XG4gIGNvc3RBbGxvY2F0aW9uVGFnczogSUNvc3RBbGxvY2F0aW9uVGFnc1tdO1xuICBhY2NvdW50SWQ/OiBzdHJpbmc7XG4gIGFjY291bnROYW1lPzogc3RyaW5nO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0Q29uZmlnKGFjY291bnROYW1lPzogc3RyaW5nKTogQ29uZmlnIHtcbiAgY29uc3QgYXBwID0gQXBwLmdldEluc3RhbmNlKCk7XG5cbiAgY29uc3QgY29uZmlnOiBDb25maWcgPSB7XG4gICAgcmVnaW9uOiBwcm9jZXNzLmVudi5BV1NfUkVHSU9OIHx8IFwidXMtZWFzdC0xXCIsXG4gICAgZW52aXJvbm1lbnQ6IFwidW5rbm93blwiLFxuICAgIGV4aXN0aW5nQWNjb3VudHM6IFtdLFxuICAgIGNvc3RBbGxvY2F0aW9uVGFnczogW11cbiAgfTtcblxuICBpZiAoIXByb2Nlc3MuZW52LkFXU19SRUdJT04pXG4gICAgY29uc29sZS53YXJuKFwiQVdTX1JFR0lPTiBpcyBub3Qgc2V0LCBkZWZhdWx0aW5nIHRvIHVzLWVhc3QtMVwiKTtcblxuICAvLyBSZXRyaWV2ZSBhbnkgcHJlLWV4aXN0aW5nIGFjY291bnQgY29uZmlnXG4gIGNvbnN0IGZqYWxsQ29uZmlnID0gRmphbGxDb25maWcubG9hZENvbmZpZygpO1xuXG4gIC8vIEdldCBleGlzdGluZyBhY2NvdW50c1xuICBjb25maWcuZXhpc3RpbmdBY2NvdW50cyA9IGZqYWxsQ29uZmlnLmdldEV4aXN0aW5nQWNjb3VudHMoKTtcblxuICAvLyBHZXQgY29zdCBhbGxvY2F0aW9uIHRhZ3NcbiAgY29uZmlnLmNvc3RBbGxvY2F0aW9uVGFncyA9IGZqYWxsQ29uZmlnLmdldENvc3RBbGxvY2F0aW9uVGFncygpO1xuXG4gIC8vIElmIHVuc3BlY2lmaWVkIGFjY291bnQgbmFtZSAtIHRyeSB0byByZXRyaWV2ZSBmcm9tIGNvbnRleHRcbiAgaWYgKCFhY2NvdW50TmFtZSkgYWNjb3VudE5hbWUgPSBhcHAubm9kZS50cnlHZXRDb250ZXh0KFwiYWNjb3VudE5hbWVcIik7XG4gIC8vIElmIHdlIGhhdmUgYW4gYWNjb3VudCBuYW1lIC0gbG9vayBmb3IgYXNzb2NpYXRlZCBwcm92aWRlciBhY2NvdW50XG4gIGlmIChhY2NvdW50TmFtZSkge1xuICAgIGNvbnN0IHByb3ZpZGVyQWNjb3VudCA9IGZqYWxsQ29uZmlnLmdldFByb3ZpZGVyQWNjb3VudChhY2NvdW50TmFtZSk7XG4gICAgaWYgKCEhcHJvdmlkZXJBY2NvdW50KSB7XG4gICAgICBjb25maWcuYWNjb3VudElkID0gcHJvdmlkZXJBY2NvdW50LmlkO1xuICAgICAgY29uZmlnLmFjY291bnROYW1lID0gcHJvdmlkZXJBY2NvdW50Lm5hbWU7XG4gICAgICBjb25maWcuZW52aXJvbm1lbnQgPSBwcm92aWRlckFjY291bnQuZW52aXJvbm1lbnQ7XG4gICAgfVxuICB9XG5cbiAgLy8gSWYgd2Ugc3RpbGwgZG9uJ3QgaGF2ZSBhbiBhY2NvdW50IG5hbWUgLSB0cnkgdG8gcmV0cmlldmUgYWNjb3VudElkIGZyb20gY29udGV4dFxuICBpZiAoIWNvbmZpZy5hY2NvdW50TmFtZSkge1xuICAgIGNvbnN0IGFjY291bnRJZCA9IGFwcC5ub2RlLnRyeUdldENvbnRleHQoXCJhY2NvdW50SWRcIik7XG4gICAgLy8gSWYgd2UgZmluZCBhbiBhY2NvdW50SWQgLSByZXRyaWV2ZSB0aGUgYXNzb2NpYXRlZCBhY2NvdW50IGZyb20gY29uZmlnXG4gICAgaWYgKGFjY291bnRJZCkge1xuICAgICAgY29uZmlnLmFjY291bnRJZCA9IGFjY291bnRJZDtcblxuICAgICAgY29uc3QgcHJvdmlkZXJBY2NvdW50ID0gZmphbGxDb25maWcuZ2V0UHJvdmlkZXJBY2NvdW50QnlJZChhY2NvdW50SWQpO1xuICAgICAgaWYgKCEhcHJvdmlkZXJBY2NvdW50KSB7XG4gICAgICAgIGNvbmZpZy5hY2NvdW50TmFtZSA9IHByb3ZpZGVyQWNjb3VudC5uYW1lO1xuICAgICAgICBjb25maWcuZW52aXJvbm1lbnQgPSBwcm92aWRlckFjY291bnQuZW52aXJvbm1lbnQ7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGNvbmZpZztcbn1cblxuZXhwb3J0IGRlZmF1bHQgZ2V0Q29uZmlnO1xuIl19
59
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2V0Q29uZmlnLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vbGliL3V0aWxzL2dldENvbmZpZy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQWVBLDhCQTJEQztBQXhFRCxnQ0FBeUI7QUFDekIsc0NBQW9EO0FBWXBELFNBQWdCLFNBQVMsQ0FBQyxXQUFvQjtJQUM1QyxNQUFNLEdBQUcsR0FBRyxhQUFHLENBQUMsV0FBVyxFQUFFLENBQUM7SUFFOUIsTUFBTSxNQUFNLEdBQVc7UUFDckIsTUFBTSxFQUFFLE9BQU8sQ0FBQyxHQUFHLENBQUMsVUFBVSxJQUFJLFdBQVc7UUFDN0MsV0FBVyxFQUFFLFNBQVM7UUFDdEIsZ0JBQWdCLEVBQUUsRUFBRTtRQUNwQixrQkFBa0IsRUFBRSxFQUFFO0tBQ3ZCLENBQUM7SUFFRixJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxVQUFVO1FBQ3pCLE9BQU8sQ0FBQyxJQUFJLENBQUMsZ0RBQWdELENBQUMsQ0FBQztJQUVqRSwyQ0FBMkM7SUFDM0MsTUFBTSxXQUFXLEdBQUcsYUFBVyxDQUFDLFVBQVUsRUFBRSxDQUFDO0lBRTdDLHdCQUF3QjtJQUN4QixNQUFNLENBQUMsZ0JBQWdCLEdBQUcsV0FBVyxDQUFDLG1CQUFtQixFQUFFLENBQUM7SUFFNUQsMkJBQTJCO0lBQzNCLE1BQU0sQ0FBQyxrQkFBa0IsR0FBRyxXQUFXLENBQUMscUJBQXFCLEVBQUUsQ0FBQztJQUVoRSw2REFBNkQ7SUFDN0QsSUFBSSxDQUFDLFdBQVc7UUFBRSxXQUFXLEdBQUcsR0FBRyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsYUFBYSxDQUFDLENBQUM7SUFDdEUsb0VBQW9FO0lBQ3BFLElBQUksV0FBVyxFQUFFLENBQUM7UUFDaEIsTUFBTSxlQUFlLEdBQUcsV0FBVyxDQUFDLGtCQUFrQixDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBQ3BFLElBQUksQ0FBQyxDQUFDLGVBQWUsRUFBRSxDQUFDO1lBQ3RCLE1BQU0sQ0FBQyxTQUFTLEdBQUcsZUFBZSxDQUFDLEVBQUUsQ0FBQztZQUN0QyxNQUFNLENBQUMsV0FBVyxHQUFHLGVBQWUsQ0FBQyxJQUFJLENBQUM7WUFDMUMsTUFBTSxDQUFDLFdBQVcsR0FBRyxlQUFlLENBQUMsV0FBVyxDQUFDO1FBQ25ELENBQUM7SUFDSCxDQUFDO0lBRUQsa0ZBQWtGO0lBQ2xGLElBQUksQ0FBQyxNQUFNLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDeEIsTUFBTSxTQUFTLEdBQUcsR0FBRyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsV0FBVyxDQUFDLENBQUM7UUFDdEQsd0VBQXdFO1FBQ3hFLElBQUksU0FBUyxFQUFFLENBQUM7WUFDZCxNQUFNLENBQUMsU0FBUyxHQUFHLFNBQVMsQ0FBQztZQUU3QixNQUFNLGVBQWUsR0FBRyxXQUFXLENBQUMsc0JBQXNCLENBQUMsU0FBUyxDQUFDLENBQUM7WUFDdEUsSUFBSSxDQUFDLENBQUMsZUFBZSxFQUFFLENBQUM7Z0JBQ3RCLE1BQU0sQ0FBQyxXQUFXLEdBQUcsZUFBZSxDQUFDLElBQUksQ0FBQztnQkFDMUMsTUFBTSxDQUFDLFdBQVcsR0FBRyxlQUFlLENBQUMsV0FBVyxDQUFDO1lBQ25ELENBQUM7UUFDSCxDQUFDO0lBQ0gsQ0FBQztJQUVELHdEQUF3RDtJQUN4RCxNQUFNLGtCQUFrQixHQUFHLEdBQUcsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLGFBQWEsQ0FBQyxDQUFDO0lBQ2pFLElBQUksa0JBQWtCLEVBQUUsQ0FBQztRQUN2QixNQUFNLENBQUMsV0FBVyxHQUFHLGtCQUFrQixDQUFDO0lBQzFDLENBQUM7U0FBTSxJQUFJLE9BQU8sQ0FBQyxHQUFHLENBQUMsV0FBVyxJQUFJLE1BQU0sQ0FBQyxXQUFXLEtBQUssU0FBUyxFQUFFLENBQUM7UUFDdkUsNkRBQTZEO1FBQzdELE1BQU0sQ0FBQyxXQUFXLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxXQUFXLENBQUM7SUFDL0MsQ0FBQztJQUVELE9BQU8sTUFBTSxDQUFDO0FBQ2hCLENBQUM7QUFFRCxrQkFBZSxTQUFTLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBBY2NvdW50IH0gZnJvbSBcIkBhd3Mtc2RrL2NsaWVudC1vcmdhbml6YXRpb25zXCI7XG5cbmltcG9ydCBBcHAgZnJvbSBcIi4uL2FwcFwiO1xuaW1wb3J0IHsgQ29uZmlnIGFzIEZqYWxsQ29uZmlnIH0gZnJvbSBcIkBmamFsbC91dGlsXCI7XG5pbXBvcnQgeyBJQ29zdEFsbG9jYXRpb25UYWdzIH0gZnJvbSBcIi4uL2NvbmZpZy9hd3NcIjtcblxuaW50ZXJmYWNlIENvbmZpZyB7XG4gIHJlZ2lvbjogc3RyaW5nO1xuICBlbnZpcm9ubWVudDogc3RyaW5nO1xuICBleGlzdGluZ0FjY291bnRzOiBBY2NvdW50W107XG4gIGNvc3RBbGxvY2F0aW9uVGFnczogSUNvc3RBbGxvY2F0aW9uVGFnc1tdO1xuICBhY2NvdW50SWQ/OiBzdHJpbmc7XG4gIGFjY291bnROYW1lPzogc3RyaW5nO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0Q29uZmlnKGFjY291bnROYW1lPzogc3RyaW5nKTogQ29uZmlnIHtcbiAgY29uc3QgYXBwID0gQXBwLmdldEluc3RhbmNlKCk7XG5cbiAgY29uc3QgY29uZmlnOiBDb25maWcgPSB7XG4gICAgcmVnaW9uOiBwcm9jZXNzLmVudi5BV1NfUkVHSU9OIHx8IFwidXMtZWFzdC0xXCIsXG4gICAgZW52aXJvbm1lbnQ6IFwidW5rbm93blwiLFxuICAgIGV4aXN0aW5nQWNjb3VudHM6IFtdLFxuICAgIGNvc3RBbGxvY2F0aW9uVGFnczogW11cbiAgfTtcblxuICBpZiAoIXByb2Nlc3MuZW52LkFXU19SRUdJT04pXG4gICAgY29uc29sZS53YXJuKFwiQVdTX1JFR0lPTiBpcyBub3Qgc2V0LCBkZWZhdWx0aW5nIHRvIHVzLWVhc3QtMVwiKTtcblxuICAvLyBSZXRyaWV2ZSBhbnkgcHJlLWV4aXN0aW5nIGFjY291bnQgY29uZmlnXG4gIGNvbnN0IGZqYWxsQ29uZmlnID0gRmphbGxDb25maWcubG9hZENvbmZpZygpO1xuXG4gIC8vIEdldCBleGlzdGluZyBhY2NvdW50c1xuICBjb25maWcuZXhpc3RpbmdBY2NvdW50cyA9IGZqYWxsQ29uZmlnLmdldEV4aXN0aW5nQWNjb3VudHMoKTtcblxuICAvLyBHZXQgY29zdCBhbGxvY2F0aW9uIHRhZ3NcbiAgY29uZmlnLmNvc3RBbGxvY2F0aW9uVGFncyA9IGZqYWxsQ29uZmlnLmdldENvc3RBbGxvY2F0aW9uVGFncygpO1xuXG4gIC8vIElmIHVuc3BlY2lmaWVkIGFjY291bnQgbmFtZSAtIHRyeSB0byByZXRyaWV2ZSBmcm9tIGNvbnRleHRcbiAgaWYgKCFhY2NvdW50TmFtZSkgYWNjb3VudE5hbWUgPSBhcHAubm9kZS50cnlHZXRDb250ZXh0KFwiYWNjb3VudE5hbWVcIik7XG4gIC8vIElmIHdlIGhhdmUgYW4gYWNjb3VudCBuYW1lIC0gbG9vayBmb3IgYXNzb2NpYXRlZCBwcm92aWRlciBhY2NvdW50XG4gIGlmIChhY2NvdW50TmFtZSkge1xuICAgIGNvbnN0IHByb3ZpZGVyQWNjb3VudCA9IGZqYWxsQ29uZmlnLmdldFByb3ZpZGVyQWNjb3VudChhY2NvdW50TmFtZSk7XG4gICAgaWYgKCEhcHJvdmlkZXJBY2NvdW50KSB7XG4gICAgICBjb25maWcuYWNjb3VudElkID0gcHJvdmlkZXJBY2NvdW50LmlkO1xuICAgICAgY29uZmlnLmFjY291bnROYW1lID0gcHJvdmlkZXJBY2NvdW50Lm5hbWU7XG4gICAgICBjb25maWcuZW52aXJvbm1lbnQgPSBwcm92aWRlckFjY291bnQuZW52aXJvbm1lbnQ7XG4gICAgfVxuICB9XG5cbiAgLy8gSWYgd2Ugc3RpbGwgZG9uJ3QgaGF2ZSBhbiBhY2NvdW50IG5hbWUgLSB0cnkgdG8gcmV0cmlldmUgYWNjb3VudElkIGZyb20gY29udGV4dFxuICBpZiAoIWNvbmZpZy5hY2NvdW50TmFtZSkge1xuICAgIGNvbnN0IGFjY291bnRJZCA9IGFwcC5ub2RlLnRyeUdldENvbnRleHQoXCJhY2NvdW50SWRcIik7XG4gICAgLy8gSWYgd2UgZmluZCBhbiBhY2NvdW50SWQgLSByZXRyaWV2ZSB0aGUgYXNzb2NpYXRlZCBhY2NvdW50IGZyb20gY29uZmlnXG4gICAgaWYgKGFjY291bnRJZCkge1xuICAgICAgY29uZmlnLmFjY291bnRJZCA9IGFjY291bnRJZDtcblxuICAgICAgY29uc3QgcHJvdmlkZXJBY2NvdW50ID0gZmphbGxDb25maWcuZ2V0UHJvdmlkZXJBY2NvdW50QnlJZChhY2NvdW50SWQpO1xuICAgICAgaWYgKCEhcHJvdmlkZXJBY2NvdW50KSB7XG4gICAgICAgIGNvbmZpZy5hY2NvdW50TmFtZSA9IHByb3ZpZGVyQWNjb3VudC5uYW1lO1xuICAgICAgICBjb25maWcuZW52aXJvbm1lbnQgPSBwcm92aWRlckFjY291bnQuZW52aXJvbm1lbnQ7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLy8gQ2hlY2sgZm9yIGVudmlyb25tZW50IGZyb20gY29udGV4dCAoaGlnaGVzdCBwcmlvcml0eSlcbiAgY29uc3QgY29udGV4dEVudmlyb25tZW50ID0gYXBwLm5vZGUudHJ5R2V0Q29udGV4dChcImVudmlyb25tZW50XCIpO1xuICBpZiAoY29udGV4dEVudmlyb25tZW50KSB7XG4gICAgY29uZmlnLmVudmlyb25tZW50ID0gY29udGV4dEVudmlyb25tZW50O1xuICB9IGVsc2UgaWYgKHByb2Nlc3MuZW52LkVOVklST05NRU5UICYmIGNvbmZpZy5lbnZpcm9ubWVudCA9PT0gXCJ1bmtub3duXCIpIHtcbiAgICAvLyBGYWxsIGJhY2sgdG8gRU5WSVJPTk1FTlQgdmFyaWFibGUgaWYgbm8gb3RoZXIgc291cmNlIGZvdW5kXG4gICAgY29uZmlnLmVudmlyb25tZW50ID0gcHJvY2Vzcy5lbnYuRU5WSVJPTk1FTlQ7XG4gIH1cblxuICByZXR1cm4gY29uZmlnO1xufVxuXG5leHBvcnQgZGVmYXVsdCBnZXRDb25maWc7XG4iXX0=
@@ -3,40 +3,17 @@ import { IConstruct } from "constructs";
3
3
  /**
4
4
  * Aspect to enforce a standard set of tags on every tag-capable resource in a construct tree.
5
5
  *
6
- * Usage attach once near the root of your CDK app (or to an individual stack):
7
- * ```ts
8
- * import { App, Aspects } from "aws-cdk-lib";
9
- * import { StandardTagsAspect } from "./utils";
10
- *
11
- * const app = new App();
12
- *
13
- * // Define the required tags
14
- * const tags = {
15
- * "fjall:costAllocation:environment": "production",
16
- * "fjall:costAllocation:owner": "engineering"
17
- * };
18
- *
19
- * // Add the aspect – CDK will invoke it for every construct during synthesis
20
- * Aspects.of(app).add(new StandardTagsAspect(tags));
21
- *
22
- * // define stacks/constructs after the aspect is attached
23
- * new MyStack(app, "MyStack");
24
- *
25
- * app.synth();
26
- * ```
27
- *
28
- * How it works:
29
- * 1. CDK traverses every construct and calls `visit(node)`.
30
- * 2. For each required tag the aspect adds it to the construct via `Tags.of(node).add()`.
31
- * 3. Constructs that don't support tagging are silently ignored.
32
- * 4. The resulting CloudFormation template contains the enforced tags on all resources.
33
- *
34
- * If a tag already exists on a construct, CDK de-duplicates by key so no duplication occurs.
6
+ * Updated for CDK v2.206.0+ compatibility:
7
+ * - No longer uses Tags.of() during aspect visitation to avoid infinite loops
8
+ * - Directly manipulates CloudFormation resources instead
9
+ * - Maintains the same clean API and automatic tagging benefits
35
10
  */
36
11
  export declare class StandardTagsAspect implements IAspect {
37
12
  private readonly requiredTags;
13
+ private readonly taggedResources;
38
14
  constructor(requiredTags: {
39
15
  [key: string]: string;
40
16
  });
41
17
  visit(node: IConstruct): void;
18
+ private tagCfnResource;
42
19
  }
@@ -5,46 +5,85 @@ const aws_cdk_lib_1 = require("aws-cdk-lib");
5
5
  /**
6
6
  * Aspect to enforce a standard set of tags on every tag-capable resource in a construct tree.
7
7
  *
8
- * Usage attach once near the root of your CDK app (or to an individual stack):
9
- * ```ts
10
- * import { App, Aspects } from "aws-cdk-lib";
11
- * import { StandardTagsAspect } from "./utils";
12
- *
13
- * const app = new App();
14
- *
15
- * // Define the required tags
16
- * const tags = {
17
- * "fjall:costAllocation:environment": "production",
18
- * "fjall:costAllocation:owner": "engineering"
19
- * };
20
- *
21
- * // Add the aspect – CDK will invoke it for every construct during synthesis
22
- * Aspects.of(app).add(new StandardTagsAspect(tags));
23
- *
24
- * // define stacks/constructs after the aspect is attached
25
- * new MyStack(app, "MyStack");
26
- *
27
- * app.synth();
28
- * ```
29
- *
30
- * How it works:
31
- * 1. CDK traverses every construct and calls `visit(node)`.
32
- * 2. For each required tag the aspect adds it to the construct via `Tags.of(node).add()`.
33
- * 3. Constructs that don't support tagging are silently ignored.
34
- * 4. The resulting CloudFormation template contains the enforced tags on all resources.
35
- *
36
- * If a tag already exists on a construct, CDK de-duplicates by key so no duplication occurs.
8
+ * Updated for CDK v2.206.0+ compatibility:
9
+ * - No longer uses Tags.of() during aspect visitation to avoid infinite loops
10
+ * - Directly manipulates CloudFormation resources instead
11
+ * - Maintains the same clean API and automatic tagging benefits
37
12
  */
38
13
  class StandardTagsAspect {
39
14
  constructor(requiredTags) {
15
+ this.taggedResources = new WeakSet();
40
16
  this.requiredTags = requiredTags;
41
17
  }
42
18
  visit(node) {
43
- // Only attempt to tag constructs that support tagging
44
- for (const [key, value] of Object.entries(this.requiredTags)) {
45
- aws_cdk_lib_1.Tags.of(node).add(key, value);
19
+ // Skip if already processed
20
+ if (this.taggedResources.has(node)) {
21
+ return;
22
+ }
23
+ // Only process CfnResource nodes to avoid the Tags.of() issue
24
+ if (aws_cdk_lib_1.CfnResource.isCfnResource(node)) {
25
+ this.tagCfnResource(node);
26
+ this.taggedResources.add(node);
27
+ }
28
+ }
29
+ tagCfnResource(resource) {
30
+ // Check if resource supports tags
31
+ const cfnResourceType = resource.cfnResourceType;
32
+ // List of CloudFormation resource types that don't support tags
33
+ const unsupportedTypes = [
34
+ 'AWS::CloudFormation::WaitConditionHandle',
35
+ 'AWS::CloudFormation::WaitCondition',
36
+ 'AWS::Lambda::Permission',
37
+ 'AWS::IAM::Policy',
38
+ 'AWS::IAM::Role',
39
+ 'AWS::IAM::User',
40
+ 'AWS::IAM::Group',
41
+ 'AWS::Logs::LogGroup',
42
+ 'AWS::Logs::LogStream',
43
+ 'AWS::Events::Rule'
44
+ ];
45
+ if (unsupportedTypes.includes(cfnResourceType)) {
46
+ return;
47
+ }
48
+ // Get existing tags
49
+ let tags = resource.tags;
50
+ if (!tags) {
51
+ // Initialize tags if not present
52
+ resource.tags = [];
53
+ tags = resource.tags;
54
+ }
55
+ // Convert to map for easier manipulation
56
+ const tagMap = new Map();
57
+ // Add existing tags
58
+ if (Array.isArray(tags)) {
59
+ tags.forEach((tag) => {
60
+ if (tag && typeof tag === 'object' && 'key' in tag && 'value' in tag) {
61
+ tagMap.set(tag.key, tag.value);
62
+ }
63
+ });
46
64
  }
65
+ // Check for direct tags in metadata
66
+ const metadata = resource.node.metadata;
67
+ const directTagsMetadata = metadata.filter(m => m.type === 'fjall:direct-tags');
68
+ directTagsMetadata.forEach(m => {
69
+ if (m.data && typeof m.data === 'object') {
70
+ Object.entries(m.data).forEach(([key, value]) => {
71
+ if (typeof value === 'string') {
72
+ tagMap.set(key, value);
73
+ }
74
+ });
75
+ }
76
+ });
77
+ // Add required tags (overwriting if they exist)
78
+ Object.entries(this.requiredTags).forEach(([key, value]) => {
79
+ tagMap.set(key, value);
80
+ });
81
+ // Convert back to array format
82
+ resource.tags = Array.from(tagMap.entries()).map(([key, value]) => ({
83
+ key,
84
+ value
85
+ }));
47
86
  }
48
87
  }
49
88
  exports.StandardTagsAspect = StandardTagsAspect;
50
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhbmRhcmRUYWdzQXNwZWN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vbGliL3V0aWxzL3N0YW5kYXJkVGFnc0FzcGVjdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSw2Q0FBNEM7QUFHNUM7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBZ0NHO0FBQ0gsTUFBYSxrQkFBa0I7SUFHN0IsWUFBWSxZQUF1QztRQUNqRCxJQUFJLENBQUMsWUFBWSxHQUFHLFlBQVksQ0FBQztJQUNuQyxDQUFDO0lBRUQsS0FBSyxDQUFDLElBQWdCO1FBQ3BCLHNEQUFzRDtRQUN0RCxLQUFLLE1BQU0sQ0FBQyxHQUFHLEVBQUUsS0FBSyxDQUFDLElBQUksTUFBTSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLEVBQUUsQ0FBQztZQUM3RCxrQkFBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQ2hDLENBQUM7SUFDSCxDQUFDO0NBQ0Y7QUFiRCxnREFhQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IElBc3BlY3QsIFRhZ3MgfSBmcm9tIFwiYXdzLWNkay1saWJcIjtcbmltcG9ydCB7IElDb25zdHJ1Y3QgfSBmcm9tIFwiY29uc3RydWN0c1wiO1xuXG4vKipcbiAqIEFzcGVjdCB0byBlbmZvcmNlIGEgc3RhbmRhcmQgc2V0IG9mIHRhZ3Mgb24gZXZlcnkgdGFnLWNhcGFibGUgcmVzb3VyY2UgaW4gYSBjb25zdHJ1Y3QgdHJlZS5cbiAqXG4gKiBVc2FnZSDigJMgYXR0YWNoIG9uY2UgbmVhciB0aGUgcm9vdCBvZiB5b3VyIENESyBhcHAgKG9yIHRvIGFuIGluZGl2aWR1YWwgc3RhY2spOlxuICogYGBgdHNcbiAqIGltcG9ydCB7IEFwcCwgQXNwZWN0cyB9IGZyb20gXCJhd3MtY2RrLWxpYlwiO1xuICogaW1wb3J0IHsgU3RhbmRhcmRUYWdzQXNwZWN0IH0gZnJvbSBcIi4vdXRpbHNcIjtcbiAqXG4gKiBjb25zdCBhcHAgPSBuZXcgQXBwKCk7XG4gKlxuICogLy8gRGVmaW5lIHRoZSByZXF1aXJlZCB0YWdzXG4gKiBjb25zdCB0YWdzID0ge1xuICogICBcImZqYWxsOmNvc3RBbGxvY2F0aW9uOmVudmlyb25tZW50XCI6IFwicHJvZHVjdGlvblwiLFxuICogICBcImZqYWxsOmNvc3RBbGxvY2F0aW9uOm93bmVyXCI6IFwiZW5naW5lZXJpbmdcIlxuICogfTtcbiAqXG4gKiAvLyBBZGQgdGhlIGFzcGVjdCDigJMgQ0RLIHdpbGwgaW52b2tlIGl0IGZvciBldmVyeSBjb25zdHJ1Y3QgZHVyaW5nIHN5bnRoZXNpc1xuICogQXNwZWN0cy5vZihhcHApLmFkZChuZXcgU3RhbmRhcmRUYWdzQXNwZWN0KHRhZ3MpKTtcbiAqXG4gKiAvLyBkZWZpbmUgc3RhY2tzL2NvbnN0cnVjdHMgYWZ0ZXIgdGhlIGFzcGVjdCBpcyBhdHRhY2hlZFxuICogbmV3IE15U3RhY2soYXBwLCBcIk15U3RhY2tcIik7XG4gKlxuICogYXBwLnN5bnRoKCk7XG4gKiBgYGBcbiAqXG4gKiBIb3cgaXQgd29ya3M6XG4gKiAgIDEuIENESyB0cmF2ZXJzZXMgZXZlcnkgY29uc3RydWN0IGFuZCBjYWxscyBgdmlzaXQobm9kZSlgLlxuICogICAyLiBGb3IgZWFjaCByZXF1aXJlZCB0YWcgdGhlIGFzcGVjdCBhZGRzIGl0IHRvIHRoZSBjb25zdHJ1Y3QgdmlhIGBUYWdzLm9mKG5vZGUpLmFkZCgpYC5cbiAqICAgMy4gQ29uc3RydWN0cyB0aGF0IGRvbid0IHN1cHBvcnQgdGFnZ2luZyBhcmUgc2lsZW50bHkgaWdub3JlZC5cbiAqICAgNC4gVGhlIHJlc3VsdGluZyBDbG91ZEZvcm1hdGlvbiB0ZW1wbGF0ZSBjb250YWlucyB0aGUgZW5mb3JjZWQgdGFncyBvbiBhbGwgcmVzb3VyY2VzLlxuICpcbiAqIElmIGEgdGFnIGFscmVhZHkgZXhpc3RzIG9uIGEgY29uc3RydWN0LCBDREsgZGUtZHVwbGljYXRlcyBieSBrZXkgc28gbm8gZHVwbGljYXRpb24gb2NjdXJzLlxuICovXG5leHBvcnQgY2xhc3MgU3RhbmRhcmRUYWdzQXNwZWN0IGltcGxlbWVudHMgSUFzcGVjdCB7XG4gIHByaXZhdGUgcmVhZG9ubHkgcmVxdWlyZWRUYWdzOiB7IFtrZXk6IHN0cmluZ106IHN0cmluZyB9O1xuXG4gIGNvbnN0cnVjdG9yKHJlcXVpcmVkVGFnczogeyBba2V5OiBzdHJpbmddOiBzdHJpbmcgfSkge1xuICAgIHRoaXMucmVxdWlyZWRUYWdzID0gcmVxdWlyZWRUYWdzO1xuICB9XG5cbiAgdmlzaXQobm9kZTogSUNvbnN0cnVjdCk6IHZvaWQge1xuICAgIC8vIE9ubHkgYXR0ZW1wdCB0byB0YWcgY29uc3RydWN0cyB0aGF0IHN1cHBvcnQgdGFnZ2luZ1xuICAgIGZvciAoY29uc3QgW2tleSwgdmFsdWVdIG9mIE9iamVjdC5lbnRyaWVzKHRoaXMucmVxdWlyZWRUYWdzKSkge1xuICAgICAgVGFncy5vZihub2RlKS5hZGQoa2V5LCB2YWx1ZSk7XG4gICAgfVxuICB9XG59XG4iXX0=
89
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhbmRhcmRUYWdzQXNwZWN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vbGliL3V0aWxzL3N0YW5kYXJkVGFnc0FzcGVjdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSw2Q0FBMEQ7QUFHMUQ7Ozs7Ozs7R0FPRztBQUNILE1BQWEsa0JBQWtCO0lBSTdCLFlBQVksWUFBdUM7UUFGbEMsb0JBQWUsR0FBRyxJQUFJLE9BQU8sRUFBYyxDQUFDO1FBRzNELElBQUksQ0FBQyxZQUFZLEdBQUcsWUFBWSxDQUFDO0lBQ25DLENBQUM7SUFFRCxLQUFLLENBQUMsSUFBZ0I7UUFDcEIsNEJBQTRCO1FBQzVCLElBQUksSUFBSSxDQUFDLGVBQWUsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQztZQUNuQyxPQUFPO1FBQ1QsQ0FBQztRQUVELDhEQUE4RDtRQUM5RCxJQUFJLHlCQUFXLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUM7WUFDcEMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxJQUFtQixDQUFDLENBQUM7WUFDekMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDakMsQ0FBQztJQUNILENBQUM7SUFFTyxjQUFjLENBQUMsUUFBcUI7UUFDMUMsa0NBQWtDO1FBQ2xDLE1BQU0sZUFBZSxHQUFHLFFBQVEsQ0FBQyxlQUFlLENBQUM7UUFFakQsZ0VBQWdFO1FBQ2hFLE1BQU0sZ0JBQWdCLEdBQUc7WUFDdkIsMENBQTBDO1lBQzFDLG9DQUFvQztZQUNwQyx5QkFBeUI7WUFDekIsa0JBQWtCO1lBQ2xCLGdCQUFnQjtZQUNoQixnQkFBZ0I7WUFDaEIsaUJBQWlCO1lBQ2pCLHFCQUFxQjtZQUNyQixzQkFBc0I7WUFDdEIsbUJBQW1CO1NBQ3BCLENBQUM7UUFFRixJQUFJLGdCQUFnQixDQUFDLFFBQVEsQ0FBQyxlQUFlLENBQUMsRUFBRSxDQUFDO1lBQy9DLE9BQU87UUFDVCxDQUFDO1FBRUQsb0JBQW9CO1FBQ3BCLElBQUksSUFBSSxHQUFJLFFBQWdCLENBQUMsSUFBSSxDQUFDO1FBRWxDLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUNWLGlDQUFpQztZQUNoQyxRQUFnQixDQUFDLElBQUksR0FBRyxFQUFFLENBQUM7WUFDNUIsSUFBSSxHQUFJLFFBQWdCLENBQUMsSUFBSSxDQUFDO1FBQ2hDLENBQUM7UUFFRCx5Q0FBeUM7UUFDekMsTUFBTSxNQUFNLEdBQUcsSUFBSSxHQUFHLEVBQWtCLENBQUM7UUFFekMsb0JBQW9CO1FBQ3BCLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDO1lBQ3hCLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxHQUFRLEVBQUUsRUFBRTtnQkFDeEIsSUFBSSxHQUFHLElBQUksT0FBTyxHQUFHLEtBQUssUUFBUSxJQUFJLEtBQUssSUFBSSxHQUFHLElBQUksT0FBTyxJQUFJLEdBQUcsRUFBRSxDQUFDO29CQUNyRSxNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDO2dCQUNqQyxDQUFDO1lBQ0gsQ0FBQyxDQUFDLENBQUM7UUFDTCxDQUFDO1FBRUQsb0NBQW9DO1FBQ3BDLE1BQU0sUUFBUSxHQUFHLFFBQVEsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDO1FBQ3hDLE1BQU0sa0JBQWtCLEdBQUcsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLEtBQUssbUJBQW1CLENBQUMsQ0FBQztRQUNoRixrQkFBa0IsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUU7WUFDN0IsSUFBSSxDQUFDLENBQUMsSUFBSSxJQUFJLE9BQU8sQ0FBQyxDQUFDLElBQUksS0FBSyxRQUFRLEVBQUUsQ0FBQztnQkFDekMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsS0FBSyxDQUFDLEVBQUUsRUFBRTtvQkFDOUMsSUFBSSxPQUFPLEtBQUssS0FBSyxRQUFRLEVBQUUsQ0FBQzt3QkFDOUIsTUFBTSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsS0FBSyxDQUFDLENBQUM7b0JBQ3pCLENBQUM7Z0JBQ0gsQ0FBQyxDQUFDLENBQUM7WUFDTCxDQUFDO1FBQ0gsQ0FBQyxDQUFDLENBQUM7UUFFSCxnREFBZ0Q7UUFDaEQsTUFBTSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsS0FBSyxDQUFDLEVBQUUsRUFBRTtZQUN6RCxNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxLQUFLLENBQUMsQ0FBQztRQUN6QixDQUFDLENBQUMsQ0FBQztRQUVILCtCQUErQjtRQUM5QixRQUFnQixDQUFDLElBQUksR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1lBQzNFLEdBQUc7WUFDSCxLQUFLO1NBQ04sQ0FBQyxDQUFDLENBQUM7SUFDTixDQUFDO0NBQ0Y7QUF4RkQsZ0RBd0ZDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSUFzcGVjdCwgU3RhY2ssIENmblJlc291cmNlIH0gZnJvbSBcImF3cy1jZGstbGliXCI7XG5pbXBvcnQgeyBJQ29uc3RydWN0IH0gZnJvbSBcImNvbnN0cnVjdHNcIjtcblxuLyoqXG4gKiBBc3BlY3QgdG8gZW5mb3JjZSBhIHN0YW5kYXJkIHNldCBvZiB0YWdzIG9uIGV2ZXJ5IHRhZy1jYXBhYmxlIHJlc291cmNlIGluIGEgY29uc3RydWN0IHRyZWUuXG4gKiBcbiAqIFVwZGF0ZWQgZm9yIENESyB2Mi4yMDYuMCsgY29tcGF0aWJpbGl0eTpcbiAqIC0gTm8gbG9uZ2VyIHVzZXMgVGFncy5vZigpIGR1cmluZyBhc3BlY3QgdmlzaXRhdGlvbiB0byBhdm9pZCBpbmZpbml0ZSBsb29wc1xuICogLSBEaXJlY3RseSBtYW5pcHVsYXRlcyBDbG91ZEZvcm1hdGlvbiByZXNvdXJjZXMgaW5zdGVhZFxuICogLSBNYWludGFpbnMgdGhlIHNhbWUgY2xlYW4gQVBJIGFuZCBhdXRvbWF0aWMgdGFnZ2luZyBiZW5lZml0c1xuICovXG5leHBvcnQgY2xhc3MgU3RhbmRhcmRUYWdzQXNwZWN0IGltcGxlbWVudHMgSUFzcGVjdCB7XG4gIHByaXZhdGUgcmVhZG9ubHkgcmVxdWlyZWRUYWdzOiB7IFtrZXk6IHN0cmluZ106IHN0cmluZyB9O1xuICBwcml2YXRlIHJlYWRvbmx5IHRhZ2dlZFJlc291cmNlcyA9IG5ldyBXZWFrU2V0PElDb25zdHJ1Y3Q+KCk7XG5cbiAgY29uc3RydWN0b3IocmVxdWlyZWRUYWdzOiB7IFtrZXk6IHN0cmluZ106IHN0cmluZyB9KSB7XG4gICAgdGhpcy5yZXF1aXJlZFRhZ3MgPSByZXF1aXJlZFRhZ3M7XG4gIH1cblxuICB2aXNpdChub2RlOiBJQ29uc3RydWN0KTogdm9pZCB7XG4gICAgLy8gU2tpcCBpZiBhbHJlYWR5IHByb2Nlc3NlZFxuICAgIGlmICh0aGlzLnRhZ2dlZFJlc291cmNlcy5oYXMobm9kZSkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgXG4gICAgLy8gT25seSBwcm9jZXNzIENmblJlc291cmNlIG5vZGVzIHRvIGF2b2lkIHRoZSBUYWdzLm9mKCkgaXNzdWVcbiAgICBpZiAoQ2ZuUmVzb3VyY2UuaXNDZm5SZXNvdXJjZShub2RlKSkge1xuICAgICAgdGhpcy50YWdDZm5SZXNvdXJjZShub2RlIGFzIENmblJlc291cmNlKTtcbiAgICAgIHRoaXMudGFnZ2VkUmVzb3VyY2VzLmFkZChub2RlKTtcbiAgICB9XG4gIH1cbiAgXG4gIHByaXZhdGUgdGFnQ2ZuUmVzb3VyY2UocmVzb3VyY2U6IENmblJlc291cmNlKTogdm9pZCB7XG4gICAgLy8gQ2hlY2sgaWYgcmVzb3VyY2Ugc3VwcG9ydHMgdGFnc1xuICAgIGNvbnN0IGNmblJlc291cmNlVHlwZSA9IHJlc291cmNlLmNmblJlc291cmNlVHlwZTtcbiAgICBcbiAgICAvLyBMaXN0IG9mIENsb3VkRm9ybWF0aW9uIHJlc291cmNlIHR5cGVzIHRoYXQgZG9uJ3Qgc3VwcG9ydCB0YWdzXG4gICAgY29uc3QgdW5zdXBwb3J0ZWRUeXBlcyA9IFtcbiAgICAgICdBV1M6OkNsb3VkRm9ybWF0aW9uOjpXYWl0Q29uZGl0aW9uSGFuZGxlJyxcbiAgICAgICdBV1M6OkNsb3VkRm9ybWF0aW9uOjpXYWl0Q29uZGl0aW9uJyxcbiAgICAgICdBV1M6OkxhbWJkYTo6UGVybWlzc2lvbicsXG4gICAgICAnQVdTOjpJQU06OlBvbGljeScsXG4gICAgICAnQVdTOjpJQU06OlJvbGUnLFxuICAgICAgJ0FXUzo6SUFNOjpVc2VyJyxcbiAgICAgICdBV1M6OklBTTo6R3JvdXAnLFxuICAgICAgJ0FXUzo6TG9nczo6TG9nR3JvdXAnLFxuICAgICAgJ0FXUzo6TG9nczo6TG9nU3RyZWFtJyxcbiAgICAgICdBV1M6OkV2ZW50czo6UnVsZSdcbiAgICBdO1xuICAgIFxuICAgIGlmICh1bnN1cHBvcnRlZFR5cGVzLmluY2x1ZGVzKGNmblJlc291cmNlVHlwZSkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgXG4gICAgLy8gR2V0IGV4aXN0aW5nIHRhZ3NcbiAgICBsZXQgdGFncyA9IChyZXNvdXJjZSBhcyBhbnkpLnRhZ3M7XG4gICAgXG4gICAgaWYgKCF0YWdzKSB7XG4gICAgICAvLyBJbml0aWFsaXplIHRhZ3MgaWYgbm90IHByZXNlbnRcbiAgICAgIChyZXNvdXJjZSBhcyBhbnkpLnRhZ3MgPSBbXTtcbiAgICAgIHRhZ3MgPSAocmVzb3VyY2UgYXMgYW55KS50YWdzO1xuICAgIH1cbiAgICBcbiAgICAvLyBDb252ZXJ0IHRvIG1hcCBmb3IgZWFzaWVyIG1hbmlwdWxhdGlvblxuICAgIGNvbnN0IHRhZ01hcCA9IG5ldyBNYXA8c3RyaW5nLCBzdHJpbmc+KCk7XG4gICAgXG4gICAgLy8gQWRkIGV4aXN0aW5nIHRhZ3NcbiAgICBpZiAoQXJyYXkuaXNBcnJheSh0YWdzKSkge1xuICAgICAgdGFncy5mb3JFYWNoKCh0YWc6IGFueSkgPT4ge1xuICAgICAgICBpZiAodGFnICYmIHR5cGVvZiB0YWcgPT09ICdvYmplY3QnICYmICdrZXknIGluIHRhZyAmJiAndmFsdWUnIGluIHRhZykge1xuICAgICAgICAgIHRhZ01hcC5zZXQodGFnLmtleSwgdGFnLnZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuICAgIFxuICAgIC8vIENoZWNrIGZvciBkaXJlY3QgdGFncyBpbiBtZXRhZGF0YVxuICAgIGNvbnN0IG1ldGFkYXRhID0gcmVzb3VyY2Uubm9kZS5tZXRhZGF0YTtcbiAgICBjb25zdCBkaXJlY3RUYWdzTWV0YWRhdGEgPSBtZXRhZGF0YS5maWx0ZXIobSA9PiBtLnR5cGUgPT09ICdmamFsbDpkaXJlY3QtdGFncycpO1xuICAgIGRpcmVjdFRhZ3NNZXRhZGF0YS5mb3JFYWNoKG0gPT4ge1xuICAgICAgaWYgKG0uZGF0YSAmJiB0eXBlb2YgbS5kYXRhID09PSAnb2JqZWN0Jykge1xuICAgICAgICBPYmplY3QuZW50cmllcyhtLmRhdGEpLmZvckVhY2goKFtrZXksIHZhbHVlXSkgPT4ge1xuICAgICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICB0YWdNYXAuc2V0KGtleSwgdmFsdWUpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgXG4gICAgLy8gQWRkIHJlcXVpcmVkIHRhZ3MgKG92ZXJ3cml0aW5nIGlmIHRoZXkgZXhpc3QpXG4gICAgT2JqZWN0LmVudHJpZXModGhpcy5yZXF1aXJlZFRhZ3MpLmZvckVhY2goKFtrZXksIHZhbHVlXSkgPT4ge1xuICAgICAgdGFnTWFwLnNldChrZXksIHZhbHVlKTtcbiAgICB9KTtcbiAgICBcbiAgICAvLyBDb252ZXJ0IGJhY2sgdG8gYXJyYXkgZm9ybWF0XG4gICAgKHJlc291cmNlIGFzIGFueSkudGFncyA9IEFycmF5LmZyb20odGFnTWFwLmVudHJpZXMoKSkubWFwKChba2V5LCB2YWx1ZV0pID0+ICh7XG4gICAgICBrZXksXG4gICAgICB2YWx1ZVxuICAgIH0pKTtcbiAgfVxufVxuIl19
@@ -0,0 +1,28 @@
1
+ import { Node } from "constructs";
2
+ /**
3
+ * TagContext provides a CDK context-based approach for passing tags
4
+ * down the construct tree without using aspects.
5
+ *
6
+ * This avoids the infinite loop issue with Tags.of() creating aspects
7
+ * during the aspect visitation phase in CDK v2.206.0+
8
+ */
9
+ export declare class TagContext {
10
+ private static readonly TAG_CONTEXT_KEY;
11
+ /**
12
+ * Set tags in the context for a construct
13
+ */
14
+ static setTags(node: Node, tags: {
15
+ [key: string]: string;
16
+ }): void;
17
+ /**
18
+ * Get tags from the context, including inherited tags from parent constructs
19
+ */
20
+ static getTags(node: Node): {
21
+ [key: string]: string;
22
+ };
23
+ /**
24
+ * Apply tags from context to a construct using a safe approach
25
+ * This should be called during construction, not during synthesis
26
+ */
27
+ static applyTagsFromContext(node: Node): void;
28
+ }
@@ -0,0 +1,53 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TagContext = void 0;
4
+ const constructs_1 = require("constructs");
5
+ /**
6
+ * TagContext provides a CDK context-based approach for passing tags
7
+ * down the construct tree without using aspects.
8
+ *
9
+ * This avoids the infinite loop issue with Tags.of() creating aspects
10
+ * during the aspect visitation phase in CDK v2.206.0+
11
+ */
12
+ class TagContext {
13
+ /**
14
+ * Set tags in the context for a construct
15
+ */
16
+ static setTags(node, tags) {
17
+ const existingTags = this.getTags(node);
18
+ node.setContext(this.TAG_CONTEXT_KEY, {
19
+ ...existingTags,
20
+ ...tags
21
+ });
22
+ }
23
+ /**
24
+ * Get tags from the context, including inherited tags from parent constructs
25
+ */
26
+ static getTags(node) {
27
+ // Get tags from this node
28
+ const nodeTags = node.tryGetContext(this.TAG_CONTEXT_KEY) || {};
29
+ // Get inherited tags from parent
30
+ const parentTags = node.scope ? this.getTags(constructs_1.Node.of(node.scope)) : {};
31
+ // Node tags override parent tags
32
+ return {
33
+ ...parentTags,
34
+ ...nodeTags
35
+ };
36
+ }
37
+ /**
38
+ * Apply tags from context to a construct using a safe approach
39
+ * This should be called during construction, not during synthesis
40
+ */
41
+ static applyTagsFromContext(node) {
42
+ const tags = this.getTags(node);
43
+ if (Object.keys(tags).length === 0) {
44
+ return;
45
+ }
46
+ // Instead of using Tags.of() which creates aspects,
47
+ // we'll store tags as metadata that can be processed later
48
+ node.addMetadata('fjall:applied-tags', tags);
49
+ }
50
+ }
51
+ exports.TagContext = TagContext;
52
+ TagContext.TAG_CONTEXT_KEY = "fjall:tags";
53
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFnQ29udGV4dC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL2xpYi91dGlscy90YWdDb250ZXh0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLDJDQUFrQztBQUVsQzs7Ozs7O0dBTUc7QUFDSCxNQUFhLFVBQVU7SUFHckI7O09BRUc7SUFDSSxNQUFNLENBQUMsT0FBTyxDQUFDLElBQVUsRUFBRSxJQUErQjtRQUMvRCxNQUFNLFlBQVksR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3hDLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLGVBQWUsRUFBRTtZQUNwQyxHQUFHLFlBQVk7WUFDZixHQUFHLElBQUk7U0FDUixDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQ7O09BRUc7SUFDSSxNQUFNLENBQUMsT0FBTyxDQUFDLElBQVU7UUFDOUIsMEJBQTBCO1FBQzFCLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUVoRSxpQ0FBaUM7UUFDakMsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxpQkFBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1FBRXZFLGlDQUFpQztRQUNqQyxPQUFPO1lBQ0wsR0FBRyxVQUFVO1lBQ2IsR0FBRyxRQUFRO1NBQ1osQ0FBQztJQUNKLENBQUM7SUFFRDs7O09BR0c7SUFDSSxNQUFNLENBQUMsb0JBQW9CLENBQUMsSUFBVTtRQUMzQyxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBRWhDLElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDbkMsT0FBTztRQUNULENBQUM7UUFFRCxvREFBb0Q7UUFDcEQsMkRBQTJEO1FBQzNELElBQUksQ0FBQyxXQUFXLENBQUMsb0JBQW9CLEVBQUUsSUFBSSxDQUFDLENBQUM7SUFDL0MsQ0FBQzs7QUE3Q0gsZ0NBOENDO0FBN0N5QiwwQkFBZSxHQUFHLFlBQVksQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IE5vZGUgfSBmcm9tIFwiY29uc3RydWN0c1wiO1xuXG4vKipcbiAqIFRhZ0NvbnRleHQgcHJvdmlkZXMgYSBDREsgY29udGV4dC1iYXNlZCBhcHByb2FjaCBmb3IgcGFzc2luZyB0YWdzXG4gKiBkb3duIHRoZSBjb25zdHJ1Y3QgdHJlZSB3aXRob3V0IHVzaW5nIGFzcGVjdHMuXG4gKiBcbiAqIFRoaXMgYXZvaWRzIHRoZSBpbmZpbml0ZSBsb29wIGlzc3VlIHdpdGggVGFncy5vZigpIGNyZWF0aW5nIGFzcGVjdHNcbiAqIGR1cmluZyB0aGUgYXNwZWN0IHZpc2l0YXRpb24gcGhhc2UgaW4gQ0RLIHYyLjIwNi4wK1xuICovXG5leHBvcnQgY2xhc3MgVGFnQ29udGV4dCB7XG4gIHByaXZhdGUgc3RhdGljIHJlYWRvbmx5IFRBR19DT05URVhUX0tFWSA9IFwiZmphbGw6dGFnc1wiO1xuXG4gIC8qKlxuICAgKiBTZXQgdGFncyBpbiB0aGUgY29udGV4dCBmb3IgYSBjb25zdHJ1Y3RcbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgc2V0VGFncyhub2RlOiBOb2RlLCB0YWdzOiB7IFtrZXk6IHN0cmluZ106IHN0cmluZyB9KTogdm9pZCB7XG4gICAgY29uc3QgZXhpc3RpbmdUYWdzID0gdGhpcy5nZXRUYWdzKG5vZGUpO1xuICAgIG5vZGUuc2V0Q29udGV4dCh0aGlzLlRBR19DT05URVhUX0tFWSwge1xuICAgICAgLi4uZXhpc3RpbmdUYWdzLFxuICAgICAgLi4udGFnc1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCB0YWdzIGZyb20gdGhlIGNvbnRleHQsIGluY2x1ZGluZyBpbmhlcml0ZWQgdGFncyBmcm9tIHBhcmVudCBjb25zdHJ1Y3RzXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIGdldFRhZ3Mobm9kZTogTm9kZSk6IHsgW2tleTogc3RyaW5nXTogc3RyaW5nIH0ge1xuICAgIC8vIEdldCB0YWdzIGZyb20gdGhpcyBub2RlXG4gICAgY29uc3Qgbm9kZVRhZ3MgPSBub2RlLnRyeUdldENvbnRleHQodGhpcy5UQUdfQ09OVEVYVF9LRVkpIHx8IHt9O1xuICAgIFxuICAgIC8vIEdldCBpbmhlcml0ZWQgdGFncyBmcm9tIHBhcmVudFxuICAgIGNvbnN0IHBhcmVudFRhZ3MgPSBub2RlLnNjb3BlID8gdGhpcy5nZXRUYWdzKE5vZGUub2Yobm9kZS5zY29wZSkpIDoge307XG4gICAgXG4gICAgLy8gTm9kZSB0YWdzIG92ZXJyaWRlIHBhcmVudCB0YWdzXG4gICAgcmV0dXJuIHtcbiAgICAgIC4uLnBhcmVudFRhZ3MsXG4gICAgICAuLi5ub2RlVGFnc1xuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogQXBwbHkgdGFncyBmcm9tIGNvbnRleHQgdG8gYSBjb25zdHJ1Y3QgdXNpbmcgYSBzYWZlIGFwcHJvYWNoXG4gICAqIFRoaXMgc2hvdWxkIGJlIGNhbGxlZCBkdXJpbmcgY29uc3RydWN0aW9uLCBub3QgZHVyaW5nIHN5bnRoZXNpc1xuICAgKi9cbiAgcHVibGljIHN0YXRpYyBhcHBseVRhZ3NGcm9tQ29udGV4dChub2RlOiBOb2RlKTogdm9pZCB7XG4gICAgY29uc3QgdGFncyA9IHRoaXMuZ2V0VGFncyhub2RlKTtcbiAgICBcbiAgICBpZiAoT2JqZWN0LmtleXModGFncykubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gSW5zdGVhZCBvZiB1c2luZyBUYWdzLm9mKCkgd2hpY2ggY3JlYXRlcyBhc3BlY3RzLFxuICAgIC8vIHdlJ2xsIHN0b3JlIHRhZ3MgYXMgbWV0YWRhdGEgdGhhdCBjYW4gYmUgcHJvY2Vzc2VkIGxhdGVyXG4gICAgbm9kZS5hZGRNZXRhZGF0YSgnZmphbGw6YXBwbGllZC10YWdzJywgdGFncyk7XG4gIH1cbn1cbiJdfQ==
@@ -1,4 +1,9 @@
1
1
  import { IConstruct } from "constructs";
2
+ /**
3
+ * Tag a resource directly on the CloudFormation resource.
4
+ * This is used for resources that need tags at construction time,
5
+ * like VPC IPAM pool tags.
6
+ */
2
7
  export default function tagResource(resource: IConstruct, tags: {
3
8
  [key: string]: string;
4
9
  }): void;
@@ -1,10 +1,13 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.default = tagResource;
4
- const aws_cdk_lib_1 = require("aws-cdk-lib");
4
+ /**
5
+ * Tag a resource directly on the CloudFormation resource.
6
+ * This is used for resources that need tags at construction time,
7
+ * like VPC IPAM pool tags.
8
+ */
5
9
  function tagResource(resource, tags) {
6
- for (const tag in tags) {
7
- aws_cdk_lib_1.Tags.of(resource).add(tag, tags[tag]);
8
- }
10
+ // Add a metadata marker that will be processed by StandardTagsAspect
11
+ resource.node.addMetadata('fjall:direct-tags', tags);
9
12
  }
10
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFnUmVzb3VyY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9saWIvdXRpbHMvdGFnUmVzb3VyY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFHQSw4QkFPQztBQVZELDZDQUFtQztBQUduQyxTQUF3QixXQUFXLENBQ2pDLFFBQW9CLEVBQ3BCLElBQStCO0lBRS9CLEtBQUssTUFBTSxHQUFHLElBQUksSUFBSSxFQUFFLENBQUM7UUFDdkIsa0JBQUksQ0FBQyxFQUFFLENBQUMsUUFBUSxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztJQUN4QyxDQUFDO0FBQ0gsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFRhZ3MgfSBmcm9tIFwiYXdzLWNkay1saWJcIjtcbmltcG9ydCB7IElDb25zdHJ1Y3QgfSBmcm9tIFwiY29uc3RydWN0c1wiO1xuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiB0YWdSZXNvdXJjZShcbiAgcmVzb3VyY2U6IElDb25zdHJ1Y3QsXG4gIHRhZ3M6IHsgW2tleTogc3RyaW5nXTogc3RyaW5nIH1cbikge1xuICBmb3IgKGNvbnN0IHRhZyBpbiB0YWdzKSB7XG4gICAgVGFncy5vZihyZXNvdXJjZSkuYWRkKHRhZywgdGFnc1t0YWddKTtcbiAgfVxufVxuIl19
13
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFnUmVzb3VyY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9saWIvdXRpbHMvdGFnUmVzb3VyY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFRQSw4QkFNQztBQVhEOzs7O0dBSUc7QUFDSCxTQUF3QixXQUFXLENBQ2pDLFFBQW9CLEVBQ3BCLElBQStCO0lBRS9CLHFFQUFxRTtJQUNyRSxRQUFRLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxtQkFBbUIsRUFBRSxJQUFJLENBQUMsQ0FBQztBQUN2RCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSUNvbnN0cnVjdCB9IGZyb20gXCJjb25zdHJ1Y3RzXCI7XG5pbXBvcnQgeyBDZm5SZXNvdXJjZSB9IGZyb20gXCJhd3MtY2RrLWxpYlwiO1xuXG4vKipcbiAqIFRhZyBhIHJlc291cmNlIGRpcmVjdGx5IG9uIHRoZSBDbG91ZEZvcm1hdGlvbiByZXNvdXJjZS5cbiAqIFRoaXMgaXMgdXNlZCBmb3IgcmVzb3VyY2VzIHRoYXQgbmVlZCB0YWdzIGF0IGNvbnN0cnVjdGlvbiB0aW1lLFxuICogbGlrZSBWUEMgSVBBTSBwb29sIHRhZ3MuXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIHRhZ1Jlc291cmNlKFxuICByZXNvdXJjZTogSUNvbnN0cnVjdCxcbiAgdGFnczogeyBba2V5OiBzdHJpbmddOiBzdHJpbmcgfVxuKSB7XG4gIC8vIEFkZCBhIG1ldGFkYXRhIG1hcmtlciB0aGF0IHdpbGwgYmUgcHJvY2Vzc2VkIGJ5IFN0YW5kYXJkVGFnc0FzcGVjdFxuICByZXNvdXJjZS5ub2RlLmFkZE1ldGFkYXRhKCdmamFsbDpkaXJlY3QtdGFncycsIHRhZ3MpO1xufVxuIl19
@@ -0,0 +1,13 @@
1
+ import { IConstruct } from "constructs";
2
+ import { IAspect } from "aws-cdk-lib";
3
+ /**
4
+ * TagSynthesizer is a specialized aspect that runs during synthesis
5
+ * to apply tags stored in metadata to CloudFormation resources.
6
+ *
7
+ * This approach avoids creating new aspects during aspect visitation,
8
+ * which causes the infinite loop in CDK v2.206.0+
9
+ */
10
+ export declare class TagSynthesizer implements IAspect {
11
+ visit(node: IConstruct): void;
12
+ private collectTagsFromTree;
13
+ }