@fjall/components-infrastructure 0.86.1 → 0.87.3

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 (112) hide show
  1. package/README.md +3 -3
  2. package/dist/lib/app.d.ts +166 -6
  3. package/dist/lib/app.js +212 -20
  4. package/dist/lib/aspects/resourceInventory.d.ts +4 -4
  5. package/dist/lib/aspects/resourceInventory.js +3 -3
  6. package/dist/lib/config/aws/backupGlobalSettings.js +1 -2
  7. package/dist/lib/config/aws/identityCenter.js +1 -5
  8. package/dist/lib/config/aws/organisation.js +1 -4
  9. package/dist/lib/index.d.ts +1 -0
  10. package/dist/lib/index.js +7 -1
  11. package/dist/lib/patterns/aws/buildkite.js +3 -2
  12. package/dist/lib/patterns/aws/cdn.d.ts +164 -0
  13. package/dist/lib/patterns/aws/cdn.js +264 -0
  14. package/dist/lib/patterns/aws/compute.d.ts +278 -59
  15. package/dist/lib/patterns/aws/compute.js +384 -188
  16. package/dist/lib/patterns/aws/connections.d.ts +46 -0
  17. package/dist/lib/patterns/aws/connections.js +159 -0
  18. package/dist/lib/patterns/aws/database.d.ts +124 -11
  19. package/dist/lib/patterns/aws/database.js +188 -66
  20. package/dist/lib/patterns/aws/hostedZone.js +1 -1
  21. package/dist/lib/patterns/aws/index.d.ts +3 -0
  22. package/dist/lib/patterns/aws/index.js +4 -1
  23. package/dist/lib/patterns/aws/interfaces/compute.d.ts +121 -0
  24. package/dist/lib/patterns/aws/interfaces/compute.js +48 -0
  25. package/dist/lib/patterns/aws/interfaces/connector.d.ts +183 -0
  26. package/dist/lib/patterns/aws/interfaces/connector.js +117 -0
  27. package/dist/lib/patterns/aws/interfaces/database.d.ts +136 -0
  28. package/dist/lib/patterns/aws/interfaces/database.js +65 -0
  29. package/dist/lib/patterns/aws/interfaces/index.d.ts +12 -0
  30. package/dist/lib/patterns/aws/interfaces/index.js +49 -0
  31. package/dist/lib/patterns/aws/interfaces/messaging.d.ts +146 -0
  32. package/dist/lib/patterns/aws/interfaces/messaging.js +56 -0
  33. package/dist/lib/patterns/aws/interfaces/pattern.d.ts +403 -0
  34. package/dist/lib/patterns/aws/interfaces/pattern.js +36 -0
  35. package/dist/lib/patterns/aws/interfaces/storage.d.ts +136 -0
  36. package/dist/lib/patterns/aws/interfaces/storage.js +48 -0
  37. package/dist/lib/patterns/aws/messaging.d.ts +183 -0
  38. package/dist/lib/patterns/aws/messaging.js +239 -0
  39. package/dist/lib/patterns/aws/network.js +4 -4
  40. package/dist/lib/patterns/aws/pattern.d.ts +67 -0
  41. package/dist/lib/patterns/aws/pattern.js +69 -0
  42. package/dist/lib/patterns/aws/payload.d.ts +87 -0
  43. package/dist/lib/patterns/aws/payload.js +526 -0
  44. package/dist/lib/patterns/aws/storage.d.ts +127 -15
  45. package/dist/lib/patterns/aws/storage.js +234 -38
  46. package/dist/lib/resources/aws/backup/backupPlan.js +1 -6
  47. package/dist/lib/resources/aws/backup/backupVault.js +1 -2
  48. package/dist/lib/resources/aws/base/awsStack.d.ts +0 -2
  49. package/dist/lib/resources/aws/base/awsStack.js +1 -7
  50. package/dist/lib/resources/aws/cdn/cloudFront.d.ts +71 -0
  51. package/dist/lib/resources/aws/cdn/cloudFront.js +176 -0
  52. package/dist/lib/resources/aws/cdn/index.d.ts +1 -0
  53. package/dist/lib/resources/aws/cdn/index.js +18 -0
  54. package/dist/lib/resources/aws/compute/ec2.d.ts +5 -0
  55. package/dist/lib/resources/aws/compute/ec2.js +33 -6
  56. package/dist/lib/resources/aws/compute/ecs.d.ts +32 -25
  57. package/dist/lib/resources/aws/compute/ecs.js +31 -115
  58. package/dist/lib/resources/aws/compute/lambda.d.ts +94 -5
  59. package/dist/lib/resources/aws/compute/lambda.js +209 -32
  60. package/dist/lib/resources/aws/database/database.js +1 -1
  61. package/dist/lib/resources/aws/database/dynamodb.d.ts +70 -0
  62. package/dist/lib/resources/aws/database/dynamodb.js +181 -0
  63. package/dist/lib/resources/aws/database/index.d.ts +1 -0
  64. package/dist/lib/resources/aws/database/index.js +2 -1
  65. package/dist/lib/resources/aws/database/migrationLambda.d.ts +80 -0
  66. package/dist/lib/resources/aws/database/migrationLambda.js +119 -0
  67. package/dist/lib/resources/aws/database/rdsAurora.d.ts +15 -0
  68. package/dist/lib/resources/aws/database/rdsAurora.js +41 -18
  69. package/dist/lib/resources/aws/database/rdsAuroraGlobal.js +12 -8
  70. package/dist/lib/resources/aws/database/rdsInstance.js +2 -2
  71. package/dist/lib/resources/aws/index.d.ts +2 -0
  72. package/dist/lib/resources/aws/index.js +3 -1
  73. package/dist/lib/resources/aws/messaging/eventbridge.d.ts +28 -0
  74. package/dist/lib/resources/aws/messaging/eventbridge.js +53 -0
  75. package/dist/lib/resources/aws/messaging/index.d.ts +3 -0
  76. package/dist/lib/resources/aws/messaging/index.js +20 -0
  77. package/dist/lib/resources/aws/messaging/sns.d.ts +35 -0
  78. package/dist/lib/resources/aws/messaging/sns.js +70 -0
  79. package/dist/lib/resources/aws/messaging/sqs.d.ts +105 -0
  80. package/dist/lib/resources/aws/messaging/sqs.js +231 -0
  81. package/dist/lib/resources/aws/messaging/utils.d.ts +3 -0
  82. package/dist/lib/resources/aws/messaging/utils.js +7 -0
  83. package/dist/lib/resources/aws/networking/ipam.js +1 -2
  84. package/dist/lib/resources/aws/networking/ipamPool.js +3 -2
  85. package/dist/lib/resources/aws/networking/vpc.js +1 -2
  86. package/dist/lib/resources/aws/storage/ecr.js +8 -5
  87. package/dist/lib/resources/aws/storage/s3.js +1 -2
  88. package/dist/lib/resources/aws/utilities/awsCustomResource.js +1 -1
  89. package/dist/lib/resources/aws/utilities/customResource.js +1 -1
  90. package/dist/lib/utils/getConfig.js +3 -2
  91. package/dist/lib/utils/index.d.ts +1 -0
  92. package/dist/lib/utils/index.js +2 -1
  93. package/dist/lib/utils/manifestWriter.d.ts +174 -0
  94. package/dist/lib/utils/manifestWriter.js +233 -0
  95. package/dist/lib/utils/standardTagsAspect.js +1 -8
  96. package/dist/lib/utils/validationLogger.d.ts +34 -0
  97. package/dist/lib/utils/validationLogger.js +83 -0
  98. package/package.json +3 -3
  99. package/dist/lib/__tests__/setup.d.ts +0 -48
  100. package/dist/lib/__tests__/setup.js +0 -1
  101. package/dist/lib/patterns/aws/cicdRole.d.ts +0 -67
  102. package/dist/lib/patterns/aws/cicdRole.js +0 -68
  103. package/dist/lib/resources/aws/cicd/cicdRole.d.ts +0 -65
  104. package/dist/lib/resources/aws/cicd/cicdRole.js +0 -191
  105. package/dist/lib/resources/aws/compute/ecsFreeTier.d.ts +0 -75
  106. package/dist/lib/resources/aws/compute/ecsFreeTier.js +0 -1
  107. package/dist/lib/resources/aws/compute/ecsSpot.d.ts +0 -75
  108. package/dist/lib/resources/aws/compute/ecsSpot.js +0 -1
  109. package/dist/lib/resources/aws/compute/utilities/capacityProviderDrainWaiter.d.ts +0 -20
  110. package/dist/lib/resources/aws/compute/utilities/capacityProviderDrainWaiter.js +0 -1
  111. package/dist/lib/resources/aws/utilities/cfnOutput.d.ts +0 -5
  112. package/dist/lib/resources/aws/utilities/cfnOutput.js +0 -1
@@ -0,0 +1,233 @@
1
+ "use strict";
2
+ /**
3
+ * Fjall Manifest Writer.
4
+ *
5
+ * Writes a manifest file during CDK synthesis that contains resolved service
6
+ * configuration, pattern details, and template hashes. This replaces fragile
7
+ * AST parsing of infrastructure.ts in the CLI.
8
+ *
9
+ * The manifest is written to cdk.out/fjall-manifest.json after synthesis.
10
+ *
11
+ * NOTE: This file uses synchronous file operations (writeFileSync, readFileSync, etc.)
12
+ * because CDK synthesis is inherently synchronous. The synth() method blocks until
13
+ * complete, so async operations would provide no benefit and add complexity.
14
+ *
15
+ * TYPE DUPLICATION NOTE: The interfaces below (ManifestService, ManifestPattern, etc.)
16
+ * are mirrored by Zod schemas in cli/src/types/FjallManifest.ts. The CLI schemas are
17
+ * the authoritative source for validation. If you modify these interfaces, update
18
+ * the Zod schemas to match. Future work: extract to shared @fjall/types package.
19
+ */
20
+ Object.defineProperty(exports, "__esModule", { value: true });
21
+ exports.ManifestCollector = void 0;
22
+ exports.writeManifest = writeManifest;
23
+ exports.readExistingManifest = readExistingManifest;
24
+ exports.getManifestCollector = getManifestCollector;
25
+ exports.getCurrentCollector = getCurrentCollector;
26
+ exports.resetManifestCollector = resetManifestCollector;
27
+ const fs_1 = require("fs");
28
+ const path_1 = require("path");
29
+ const crypto_1 = require("crypto");
30
+ const validationLogger_js_1 = require("./validationLogger.js");
31
+ /** Current manifest schema version. Must match MANIFEST_SCHEMA_VERSION in CLI's FjallManifest.ts */
32
+ const MANIFEST_SCHEMA_VERSION = 1;
33
+ /** Manifest file name */
34
+ const MANIFEST_FILE_NAME = "fjall-manifest.json";
35
+ /**
36
+ * Collected manifest data during synthesis.
37
+ * Stores all data that will be written to the manifest file.
38
+ */
39
+ class ManifestCollector {
40
+ constructor(appName) {
41
+ this.services = [];
42
+ this.lambdas = [];
43
+ this.appName = appName;
44
+ }
45
+ /**
46
+ * Add a service configuration.
47
+ */
48
+ addService(service) {
49
+ if (!this.services.some((s) => s.name === service.name)) {
50
+ this.services.push(service);
51
+ }
52
+ }
53
+ /**
54
+ * Add a Lambda function configuration.
55
+ */
56
+ addLambda(lambda) {
57
+ if (!this.lambdas.some((l) => l.name === lambda.name)) {
58
+ this.lambdas.push(lambda);
59
+ }
60
+ }
61
+ /**
62
+ * Set the pattern configuration.
63
+ */
64
+ setPattern(pattern) {
65
+ this.pattern = pattern;
66
+ }
67
+ /**
68
+ * Set the ECR repository configuration.
69
+ */
70
+ setEcr(ecr) {
71
+ this.ecr = ecr;
72
+ }
73
+ /**
74
+ * Get collected services.
75
+ */
76
+ getServices() {
77
+ return this.services;
78
+ }
79
+ /**
80
+ * Get collected Lambda functions.
81
+ */
82
+ getLambdas() {
83
+ return this.lambdas;
84
+ }
85
+ /**
86
+ * Get pattern configuration.
87
+ */
88
+ getPattern() {
89
+ return this.pattern;
90
+ }
91
+ /**
92
+ * Get ECR configuration.
93
+ */
94
+ getEcr() {
95
+ return this.ecr;
96
+ }
97
+ /**
98
+ * Get the application name.
99
+ */
100
+ getAppName() {
101
+ return this.appName;
102
+ }
103
+ }
104
+ exports.ManifestCollector = ManifestCollector;
105
+ /**
106
+ * Compute SHA-256 hash of a CloudFormation template file.
107
+ * Normalises JSON to ensure consistent hashes.
108
+ */
109
+ function computeTemplateHash(templatePath) {
110
+ try {
111
+ const content = (0, fs_1.readFileSync)(templatePath, "utf-8");
112
+ const normalised = JSON.stringify(JSON.parse(content));
113
+ return (0, crypto_1.createHash)("sha256").update(normalised).digest("hex");
114
+ }
115
+ catch (error) {
116
+ const errorMessage = error instanceof Error ? error.message : String(error);
117
+ validationLogger_js_1.FjallLogger.warn(`Failed to compute hash for ${templatePath}: ${errorMessage}`);
118
+ return null;
119
+ }
120
+ }
121
+ /**
122
+ * Find all template files in cdk.out and compute their hashes.
123
+ */
124
+ function computeStackHashes(cdkOutPath) {
125
+ const stacks = {};
126
+ const synthTimestamp = new Date().toISOString();
127
+ try {
128
+ const files = (0, fs_1.readdirSync)(cdkOutPath);
129
+ const templateFiles = files.filter((f) => f.endsWith(".template.json"));
130
+ for (const templateFile of templateFiles) {
131
+ const templatePath = (0, path_1.join)(cdkOutPath, templateFile);
132
+ const stackName = (0, path_1.basename)(templateFile, ".template.json");
133
+ const hash = computeTemplateHash(templatePath);
134
+ if (hash) {
135
+ stacks[stackName] = {
136
+ templateHash: hash,
137
+ synthTimestamp
138
+ };
139
+ }
140
+ }
141
+ }
142
+ catch (error) {
143
+ const errorMessage = error instanceof Error ? error.message : String(error);
144
+ validationLogger_js_1.FjallLogger.warn(`Failed to read cdk.out for hash computation: ${errorMessage}`);
145
+ }
146
+ return stacks;
147
+ }
148
+ /**
149
+ * Write the manifest file to cdk.out.
150
+ *
151
+ * @param assembly - The CloudAssembly from synth
152
+ * @param collector - The manifest collector with service data
153
+ */
154
+ function writeManifest(assembly, collector) {
155
+ const cdkOutPath = assembly.directory;
156
+ const manifestPath = (0, path_1.join)(cdkOutPath, MANIFEST_FILE_NAME);
157
+ const stacks = computeStackHashes(cdkOutPath);
158
+ const manifest = {
159
+ version: MANIFEST_SCHEMA_VERSION,
160
+ generatedAt: new Date().toISOString(),
161
+ appName: collector.getAppName(),
162
+ services: collector.getServices(),
163
+ lambdas: collector.getLambdas(),
164
+ stacks
165
+ };
166
+ const pattern = collector.getPattern();
167
+ if (pattern) {
168
+ manifest.pattern = pattern;
169
+ }
170
+ const ecr = collector.getEcr();
171
+ if (ecr) {
172
+ manifest.ecr = ecr;
173
+ }
174
+ try {
175
+ (0, fs_1.writeFileSync)(manifestPath, JSON.stringify(manifest, null, 2), "utf-8");
176
+ validationLogger_js_1.FjallLogger.info(`Fjall manifest written to ${manifestPath}`);
177
+ }
178
+ catch (error) {
179
+ const errorMessage = error instanceof Error ? error.message : String(error);
180
+ validationLogger_js_1.FjallLogger.warn(`Failed to write Fjall manifest: ${errorMessage}`);
181
+ }
182
+ }
183
+ /**
184
+ * Read an existing manifest file (for preserving deployment history).
185
+ */
186
+ function readExistingManifest(cdkOutPath) {
187
+ const manifestPath = (0, path_1.join)(cdkOutPath, MANIFEST_FILE_NAME);
188
+ if (!(0, fs_1.existsSync)(manifestPath)) {
189
+ return null;
190
+ }
191
+ try {
192
+ const content = (0, fs_1.readFileSync)(manifestPath, "utf-8");
193
+ return JSON.parse(content);
194
+ }
195
+ catch (error) {
196
+ const message = error instanceof Error ? error.message : String(error);
197
+ validationLogger_js_1.FjallLogger.warn(`Failed to parse existing manifest: ${message}`);
198
+ return null;
199
+ }
200
+ }
201
+ /**
202
+ * Global manifest collector instance.
203
+ *
204
+ * CDK's architecture guarantees one App per process, so a global singleton is safe here.
205
+ * The collector is created when App is constructed and used throughout synthesis.
206
+ * resetManifestCollector() is provided for testing scenarios where multiple Apps
207
+ * may be created in the same process.
208
+ */
209
+ let globalCollector = null;
210
+ /**
211
+ * Get or create the global manifest collector.
212
+ * Called by App during construction to initialise the collector.
213
+ */
214
+ function getManifestCollector(appName) {
215
+ if (!globalCollector || globalCollector.getAppName() !== appName) {
216
+ globalCollector = new ManifestCollector(appName);
217
+ }
218
+ return globalCollector;
219
+ }
220
+ /**
221
+ * Get the current global manifest collector.
222
+ * Returns null if not initialised.
223
+ */
224
+ function getCurrentCollector() {
225
+ return globalCollector;
226
+ }
227
+ /**
228
+ * Reset the global collector (for testing).
229
+ */
230
+ function resetManifestCollector() {
231
+ globalCollector = null;
232
+ }
233
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFuaWZlc3RXcml0ZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9saWIvdXRpbHMvbWFuaWZlc3RXcml0ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7Ozs7Ozs7Ozs7Ozs7OztHQWlCRzs7O0FBa1BILHNDQW1DQztBQUtELG9EQWVDO0FBZ0JELG9EQUtDO0FBTUQsa0RBRUM7QUFLRCx3REFFQztBQTNVRCwyQkFBMEU7QUFDMUUsK0JBQXNDO0FBQ3RDLG1DQUFvQztBQUdwQywrREFBb0Q7QUFFcEQsb0dBQW9HO0FBQ3BHLE1BQU0sdUJBQXVCLEdBQUcsQ0FBVSxDQUFDO0FBdUYzQyx5QkFBeUI7QUFDekIsTUFBTSxrQkFBa0IsR0FBRyxxQkFBcUIsQ0FBQztBQUVqRDs7O0dBR0c7QUFDSCxNQUFhLGlCQUFpQjtJQU81QixZQUFZLE9BQWU7UUFObkIsYUFBUSxHQUFzQixFQUFFLENBQUM7UUFDakMsWUFBTyxHQUFxQixFQUFFLENBQUM7UUFNckMsSUFBSSxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUM7SUFDekIsQ0FBQztJQUVEOztPQUVHO0lBQ0gsVUFBVSxDQUFDLE9BQXdCO1FBQ2pDLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksS0FBSyxPQUFPLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQztZQUN4RCxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUM5QixDQUFDO0lBQ0gsQ0FBQztJQUVEOztPQUVHO0lBQ0gsU0FBUyxDQUFDLE1BQXNCO1FBQzlCLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksS0FBSyxNQUFNLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQztZQUN0RCxJQUFJ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Ozs7R0FHRztBQUNILFNBQWdCLG9CQUFvQixDQUFDLE9BQWU7SUFDbEQsSUFBSSxDQUFDLGVBQWUsSUFBSSxlQUFlLENBQUMsVUFBVSxFQUFFLEtBQUssT0FBTyxFQUFFLENBQUM7UUFDakUsZUFBZSxHQUFHLElBQUksaUJBQWlCLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDbkQsQ0FBQztJQUNELE9BQU8sZUFBZSxDQUFDO0FBQ3pCLENBQUM7QUFFRDs7O0dBR0c7QUFDSCxTQUFnQixtQkFBbUI7SUFDakMsT0FBTyxlQUFlLENBQUM7QUFDekIsQ0FBQztBQUVEOztHQUVHO0FBQ0gsU0FBZ0Isc0JBQXNCO0lBQ3BDLGVBQWUsR0FBRyxJQUFJLENBQUM7QUFDekIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogRmphbGwgTWFuaWZlc3QgV3JpdGVyLlxuICpcbiAqIFdyaXRlcyBhIG1hbmlmZXN0IGZpbGUgZHVyaW5nIENESyBzeW50aGVzaXMgdGhhdCBjb250YWlucyByZXNvbHZlZCBzZXJ2aWNlXG4gKiBjb25maWd1cmF0aW9uLCBwYXR0ZXJuIGRldGFpbHMsIGFuZCB0ZW1wbGF0ZSBoYXNoZXMuIFRoaXMgcmVwbGFjZXMgZnJhZ2lsZVxuICogQVNUIHBhcnNpbmcgb2YgaW5mcmFzdHJ1Y3R1cmUudHMgaW4gdGhlIENMSS5cbiAqXG4gKiBUaGUgbWFuaWZlc3QgaXMgd3JpdHRlbiB0byBjZGsub3V0L2ZqYWxsLW1hbmlmZXN0Lmpzb24gYWZ0ZXIgc3ludGhlc2lzLlxuICpcbiAqIE5PVEU6IFRoaXMgZmlsZSB1c2VzIHN5bmNocm9ub3VzIGZpbGUgb3BlcmF0aW9ucyAod3JpdGVGaWxlU3luYywgcmVhZEZpbGVTeW5jLCBldGMuKVxuICogYmVjYXVzZSBDREsgc3ludGhlc2lzIGlzIGluaGVyZW50bHkgc3luY2hyb25vdXMuIFRoZSBzeW50aCgpIG1ldGhvZCBibG9ja3MgdW50aWxcbiAqIGNvbXBsZXRlLCBzbyBhc3luYyBvcGVyYXRpb25zIHdvdWxkIHByb3ZpZGUgbm8gYmVuZWZpdCBhbmQgYWRkIGNvbXBsZXhpdHkuXG4gKlxuICogVFlQRSBEVVBMSUNBVElPTiBOT1RFOiBUaGUgaW50ZXJmYWNlcyBiZWxvdyAoTWFuaWZlc3RTZXJ2aWNlLCBNYW5pZmVzdFBhdHRlcm4sIGV0Yy4pXG4gKiBhcmUgbWlycm9yZWQgYnkgWm9kIHNjaGVtYXMgaW4gY2xpL3NyYy90eXBlcy9GamFsbE1hbmlmZXN0LnRzLiBUaGUgQ0xJIHNjaGVtYXMgYXJlXG4gKiB0aGUgYXV0aG9yaXRhdGl2ZSBzb3VyY2UgZm9yIHZhbGlkYXRpb24uIElmIHlvdSBtb2RpZnkgdGhlc2UgaW50ZXJmYWNlcywgdXBkYXRlXG4gKiB0aGUgWm9kIHNjaGVtYXMgdG8gbWF0Y2guIEZ1dHVyZSB3b3JrOiBleHRyYWN0IHRvIHNoYXJlZCBAZmphbGwvdHlwZXMgcGFja2FnZS5cbiAqL1xuXG5pbXBvcnQgeyB3cml0ZUZpbGVTeW5jLCByZWFkRmlsZVN5bmMsIGV4aXN0c1N5bmMsIHJlYWRkaXJTeW5jIH0gZnJvbSBcImZzXCI7XG5pbXBvcnQgeyBqb2luLCBiYXNlbmFtZSB9IGZyb20gXCJwYXRoXCI7XG5pbXBvcnQgeyBjcmVhdGVIYXNoIH0gZnJvbSBcImNyeXB0b1wiO1xuaW1wb3J0IHR5cGUgeyBDbG91ZEFzc2VtYmx5IH0gZnJvbSBcImF3cy1jZGstbGliL2N4LWFwaVwiO1xuXG5pbXBvcnQgeyBGamFsbExvZ2dlciB9IGZyb20gXCIuL3ZhbGlkYXRpb25Mb2dnZXIuanNcIjtcblxuLyoqIEN1cnJlbnQgbWFuaWZlc3Qgc2NoZW1hIHZlcnNpb24uIE11c3QgbWF0Y2ggTUFOSUZFU1RfU0NIRU1BX1ZFUlNJT04gaW4gQ0xJJ3MgRmphbGxNYW5pZmVzdC50cyAqL1xuY29uc3QgTUFOSUZFU1RfU0NIRU1BX1ZFUlNJT04gPSAxIGFzIGNvbnN0O1xuXG4vKipcbiAqIFNlcnZpY2UgY29uZmlndXJhdGlvbiBleHRyYWN0ZWQgZnJvbSBFQ1Mgc2VydmljZXMuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgTWFuaWZlc3RTZXJ2aWNlIHtcbiAgLyoqIFNlcnZpY2UgbmFtZSAobXVzdCBtYXRjaCBFQ1Mgc2VydmljZSBuYW1lKSAqL1xuICBuYW1lOiBzdHJpbmc7XG4gIC8qKiBDbHVzdGVyIG5hbWUgdGhpcyBzZXJ2aWNlIGJlbG9uZ3MgdG8gKi9cbiAgY2x1c3Rlck5hbWU/OiBzdHJpbmc7XG4gIC8qKiBQYXRoIHRvIERvY2tlcmZpbGUgcmVsYXRpdmUgdG8gYXBwIHJvb3QgKi9cbiAgZG9ja2VyZmlsZVBhdGg/OiBzdHJpbmc7XG4gIC8qKiBEb2NrZXIgYnVpbGQgdGFyZ2V0IGZvciBtdWx0aS1zdGFnZSBidWlsZHMgKi9cbiAgZG9ja2VyVGFyZ2V0Pzogc3RyaW5nO1xuICAvKiogQ29udGFpbmVyIHBvcnQgKi9cbiAgY29udGFpbmVyUG9ydD86IG51bWJlcjtcbiAgLyoqIFNTTSBzZWNyZXRzIGNvbmZpZ3VyZWQgZm9yIHRoaXMgc2VydmljZSAoYWdncmVnYXRlZCBmcm9tIGFsbCBjb250YWluZXJzKSAqL1xuICBzZWNyZXRzPzogc3RyaW5nW107XG4gIC8qKiBTU00gc2VjcmV0cyBwYXRoIChkZXJpdmVkIG9yIGV4cGxpY2l0KSAqL1xuICBzc21TZWNyZXRzUGF0aD86IHN0cmluZztcbn1cblxuLyoqXG4gKiBQYXR0ZXJuIGNvbmZpZ3VyYXRpb24gZXh0cmFjdGVkIGZyb20gUGF0dGVybkZhY3RvcnkuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgTWFuaWZlc3RQYXR0ZXJuIHtcbiAgLyoqIFBhdHRlcm4gdHlwZSAqL1xuICB0eXBlOiBcInBheWxvYWRcIjtcbiAgLyoqIFBhdHRlcm4gbmFtZSAoQ01TIG5hbWUpICovXG4gIG5hbWU6IHN0cmluZztcbiAgLyoqIFNvdXJjZSBkaXJlY3RvcnkgY29udGFpbmluZyBidWlsZCBvdXRwdXQgKi9cbiAgc291cmNlOiBzdHJpbmc7XG59XG5cbi8qKlxuICogRUNSIGNvbmZpZ3VyYXRpb24uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgTWFuaWZlc3RFY3Ige1xuICAvKiogRUNSIHJlcG9zaXRvcnkgbmFtZSAqL1xuICByZXBvc2l0b3J5TmFtZTogc3RyaW5nO1xufVxuXG4vKipcbiAqIExhbWJkYSBmdW5jdGlvbiBjb25maWd1cmF0aW9uIGV4dHJhY3RlZCBmcm9tIExhbWJkYSBjb21wdXRlLlxuICogRW5hYmxlcyBDTEkgZGlzY292ZXJ5IG9mIExhbWJkYSBmdW5jdGlvbnMgZm9yIHNlY3JldHMgbWFuYWdlbWVudC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBNYW5pZmVzdExhbWJkYSB7XG4gIC8qKiBMYW1iZGEgZnVuY3Rpb24gbmFtZSAoY29uc3RydWN0IElEKSAqL1xuICBuYW1lOiBzdHJpbmc7XG4gIC8qKiBTU00gc2VjcmV0cyBjb25maWd1cmVkIGZvciB0aGlzIExhbWJkYSAqL1xuICBzZWNyZXRzPzogc3RyaW5nW107XG4gIC8qKiBTU00gc2VjcmV0cyBwYXRoIChkZXJpdmVkIG9yIGV4cGxpY2l0KSAqL1xuICBzc21TZWNyZXRzUGF0aD86IHN0cmluZztcbn1cblxuLyoqXG4gKiBTdGFjayBoYXNoIGVudHJ5IGNvbXB1dGVkIGZyb20gc3ludGhlc2lzZWQgdGVtcGxhdGUuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgTWFuaWZlc3RTdGFja0hhc2gge1xuICAvKiogU0hBLTI1NiBoYXNoIG9mIHRoZSBzeW50aGVzaXNlZCB0ZW1wbGF0ZSAqL1xuICB0ZW1wbGF0ZUhhc2g6IHN0cmluZztcbiAgLyoqIElTTyB0aW1lc3RhbXAgd2hlbiBzeW50aCBjb21wbGV0ZWQgKi9cbiAgc3ludGhUaW1lc3RhbXA6IHN0cmluZztcbn1cblxuLyoqXG4gKiBGamFsbCBtYW5pZmVzdCAtIGdlbmVyYXRlZCBkdXJpbmcgQ0RLIHN5bnRoLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEZqYWxsTWFuaWZlc3Qge1xuICAvKiogU2NoZW1hIHZlcnNpb24gZm9yIGZ1dHVyZSBjb21wYXRpYmlsaXR5ICovXG4gIHZlcnNpb246IHR5cGVvZiBNQU5JRkVTVF9TQ0hFTUFfVkVSU0lPTjtcbiAgLyoqIElTTyB0aW1lc3RhbXAgd2hlbiBtYW5pZmVzdCB3YXMgZ2VuZXJhdGVkICovXG4gIGdlbmVyYXRlZEF0OiBzdHJpbmc7XG4gIC8qKiBBcHBsaWNhdGlvbiBuYW1lICovXG4gIGFwcE5hbWU6IHN0cmluZztcbiAgLyoqIFJlc29sdmVkIHNlcnZpY2UgY29uZmlndXJhdGlvbnMgKi9cbiAgc2VydmljZXM6IE1hbmlmZXN0U2VydmljZVtdO1xuICAvKiogTGFtYmRhIGZ1bmN0aW9uIGNvbmZpZ3VyYXRpb25zICovXG4gIGxhbWJkYXM6IE1hbmlmZXN0TGFtYmRhW107XG4gIC8qKiBQYXR0ZXJuIGNvbmZpZ3VyYXRpb24gKGlmIHVzaW5nIFBhdHRlcm5GYWN0b3J5KSAqL1xuICBwYXR0ZXJuPzogTWFuaWZlc3RQYXR0ZXJuO1xuICAvKiogRUNSIGNvbmZpZ3VyYXRpb24gKi9cbiAgZWNyPzogTWFuaWZlc3RFY3I7XG4gIC8qKiBUZW1wbGF0ZSBoYXNoZXMgYnkgc3RhY2sgbmFtZSAqL1xuICBzdGFja3M6IFJlY29yZDxzdHJpbmcsIE1hbmlmZXN0U3RhY2tIYXNoPjtcbn1cblxuLyoqIE1hbmlmZXN0IGZpbGUgbmFtZSAqL1xuY29uc3QgTUFOSUZFU1RfRklMRV9OQU1FID0gXCJmamFsbC1tYW5pZmVzdC5qc29uXCI7XG5cbi8qKlxuICogQ29sbGVjdGVkIG1hbmlmZXN0IGRhdGEgZHVyaW5nIHN5bnRoZXNpcy5cbiAqIFN0b3JlcyBhbGwgZGF0YSB0aGF0IHdpbGwgYmUgd3JpdHRlbiB0byB0aGUgbWFuaWZlc3QgZmlsZS5cbiAqL1xuZXhwb3J0IGNsYXNzIE1hbmlmZXN0Q29sbGVjdG9yIHtcbiAgcHJpdmF0ZSBzZXJ2aWNlczogTWFuaWZlc3RTZXJ2aWNlW10gPSBbXTtcbiAgcHJpdmF0ZSBsYW1iZGFzOiBNYW5pZmVzdExhbWJkYVtdID0gW107XG4gIHByaXZhdGUgcGF0dGVybj86IE1hbmlmZXN0UGF0dGVybjtcbiAgcHJpdmF0ZSBlY3I/OiBNYW5pZmVzdEVjcjtcbiAgcHJpdmF0ZSBhcHBOYW1lOiBzdHJpbmc7XG5cbiAgY29uc3RydWN0b3IoYXBwTmFtZTogc3RyaW5nKSB7XG4gICAgdGhpcy5hcHBOYW1lID0gYXBwTmFtZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBZGQgYSBzZXJ2aWNlIGNvbmZpZ3VyYXRpb24uXG4gICAqL1xuICBhZGRTZXJ2aWNlKHNlcnZpY2U6IE1hbmlmZXN0U2VydmljZSk6IHZvaWQge1xuICAgIGlmICghdGhpcy5zZXJ2aWNlcy5zb21lKChzKSA9PiBzLm5hbWUgPT09IHNlcnZpY2UubmFtZSkpIHtcbiAgICAgIHRoaXMuc2VydmljZXMucHVzaChzZXJ2aWNlKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQWRkIGEgTGFtYmRhIGZ1bmN0aW9uIGNvbmZpZ3VyYXRpb24uXG4gICAqL1xuICBhZGRMYW1iZGEobGFtYmRhOiBNYW5pZmVzdExhbWJkYSk6IHZvaWQge1xuICAgIGlmICghdGhpcy5sYW1iZGFzLnNvbWUoKGwpID0+IGwubmFtZSA9PT0gbGFtYmRhLm5hbWUpKSB7XG4gICAgICB0aGlzLmxhbWJkYXMucHVzaChsYW1iZGEpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBTZXQgdGhlIHBhdHRlcm4gY29uZmlndXJhdGlvbi5cbiAgICovXG4gIHNldFBhdHRlcm4ocGF0dGVybjogTWFuaWZlc3RQYXR0ZXJuKTogdm9pZCB7XG4gICAgdGhpcy5wYXR0ZXJuID0gcGF0dGVybjtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZXQgdGhlIEVDUiByZXBvc2l0b3J5IGNvbmZpZ3VyYXRpb24uXG4gICAqL1xuICBzZXRFY3IoZWNyOiBNYW5pZmVzdEVjcik6IHZvaWQge1xuICAgIHRoaXMuZWNyID0gZWNyO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBjb2xsZWN0ZWQgc2VydmljZXMuXG4gICAqL1xuICBnZXRTZXJ2aWNlcygpOiBNYW5pZmVzdFNlcnZpY2VbXSB7XG4gICAgcmV0dXJuIHRoaXMuc2VydmljZXM7XG4gIH1cblxuICAvKipcbiAgICogR2V0IGNvbGxlY3RlZCBMYW1iZGEgZnVuY3Rpb25zLlxuICAgKi9cbiAgZ2V0TGFtYmRhcygpOiBNYW5pZmVzdExhbWJkYVtdIHtcbiAgICByZXR1cm4gdGhpcy5sYW1iZGFzO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBwYXR0ZXJuIGNvbmZpZ3VyYXRpb24uXG4gICAqL1xuICBnZXRQYXR0ZXJuKCk6IE1hbmlmZXN0UGF0dGVybiB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHRoaXMucGF0dGVybjtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgRUNSIGNvbmZpZ3VyYXRpb24uXG4gICAqL1xuICBnZXRFY3IoKTogTWFuaWZlc3RFY3IgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLmVjcjtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgdGhlIGFwcGxpY2F0aW9uIG5hbWUuXG4gICAqL1xuICBnZXRBcHBOYW1lKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuYXBwTmFtZTtcbiAgfVxufVxuXG4vKipcbiAqIENvbXB1dGUgU0hBLTI1NiBoYXNoIG9mIGEgQ2xvdWRGb3JtYXRpb24gdGVtcGxhdGUgZmlsZS5cbiAqIE5vcm1hbGlzZXMgSlNPTiB0byBlbnN1cmUgY29uc2lzdGVudCBoYXNoZXMuXG4gKi9cbmZ1bmN0aW9uIGNvbXB1dGVUZW1wbGF0ZUhhc2godGVtcGxhdGVQYXRoOiBzdHJpbmcpOiBzdHJpbmcgfCBudWxsIHtcbiAgdHJ5IHtcbiAgICBjb25zdCBjb250ZW50ID0gcmVhZEZpbGVTeW5jKHRlbXBsYXRlUGF0aCwgXCJ1dGYtOFwiKTtcbiAgICBjb25zdCBub3JtYWxpc2VkID0gSlNPTi5zdHJpbmdpZnkoSlNPTi5wYXJzZShjb250ZW50KSk7XG4gICAgcmV0dXJuIGNyZWF0ZUhhc2goXCJzaGEyNTZcIikudXBkYXRlKG5vcm1hbGlzZWQpLmRpZ2VzdChcImhleFwiKTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICBjb25zdCBlcnJvck1lc3NhZ2UgPSBlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IubWVzc2FnZSA6IFN0cmluZyhlcnJvcik7XG4gICAgRmphbGxMb2dnZXIud2FybihcbiAgICAgIGBGYWlsZWQgdG8gY29tcHV0ZSBoYXNoIGZvciAke3RlbXBsYXRlUGF0aH06ICR7ZXJyb3JNZXNzYWdlfWBcbiAgICApO1xuICAgIHJldHVybiBudWxsO1xuICB9XG59XG5cbi8qKlxuICogRmluZCBhbGwgdGVtcGxhdGUgZmlsZXMgaW4gY2RrLm91dCBhbmQgY29tcHV0ZSB0aGVpciBoYXNoZXMuXG4gKi9cbmZ1bmN0aW9uIGNvbXB1dGVTdGFja0hhc2hlcyhcbiAgY2RrT3V0UGF0aDogc3RyaW5nXG4pOiBSZWNvcmQ8c3RyaW5nLCBNYW5pZmVzdFN0YWNrSGFzaD4ge1xuICBjb25zdCBzdGFja3M6IFJlY29yZDxzdHJpbmcsIE1hbmlmZXN0U3RhY2tIYXNoPiA9IHt9O1xuICBjb25zdCBzeW50aFRpbWVzdGFtcCA9IG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKTtcblxuICB0cnkge1xuICAgIGNvbnN0IGZpbGVzID0gcmVhZGRpclN5bmMoY2RrT3V0UGF0aCk7XG4gICAgY29uc3QgdGVtcGxhdGVGaWxlcyA9IGZpbGVzLmZpbHRlcigoZikgPT4gZi5lbmRzV2l0aChcIi50ZW1wbGF0ZS5qc29uXCIpKTtcblxuICAgIGZvciAoY29uc3QgdGVtcGxhdGVGaWxlIG9mIHRlbXBsYXRlRmlsZXMpIHtcbiAgICAgIGNvbnN0IHRlbXBsYXRlUGF0aCA9IGpvaW4oY2RrT3V0UGF0aCwgdGVtcGxhdGVGaWxlKTtcbiAgICAgIGNvbnN0IHN0YWNrTmFtZSA9IGJhc2VuYW1lKHRlbXBsYXRlRmlsZSwgXCIudGVtcGxhdGUuanNvblwiKTtcbiAgICAgIGNvbnN0IGhhc2ggPSBjb21wdXRlVGVtcGxhdGVIYXNoKHRlbXBsYXRlUGF0aCk7XG5cbiAgICAgIGlmIChoYXNoKSB7XG4gICAgICAgIHN0YWNrc1tzdGFja05hbWVdID0ge1xuICAgICAgICAgIHRlbXBsYXRlSGFzaDogaGFzaCxcbiAgICAgICAgICBzeW50aFRpbWVzdGFtcFxuICAgICAgICB9O1xuICAgICAgfVxuICAgIH1cbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICBjb25zdCBlcnJvck1lc3NhZ2UgPSBlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IubWVzc2FnZSA6IFN0cmluZyhlcnJvcik7XG4gICAgRmphbGxMb2dnZXIud2FybihcbiAgICAgIGBGYWlsZWQgdG8gcmVhZCBjZGsub3V0IGZvciBoYXNoIGNvbXB1dGF0aW9uOiAke2Vycm9yTWVzc2FnZX1gXG4gICAgKTtcbiAgfVxuXG4gIHJldHVybiBzdGFja3M7XG59XG5cbi8qKlxuICogV3JpdGUgdGhlIG1hbmlmZXN0IGZpbGUgdG8gY2RrLm91dC5cbiAqXG4gKiBAcGFyYW0gYXNzZW1ibHkgLSBUaGUgQ2xvdWRBc3NlbWJseSBmcm9tIHN5bnRoXG4gKiBAcGFyYW0gY29sbGVjdG9yIC0gVGhlIG1hbmlmZXN0IGNvbGxlY3RvciB3aXRoIHNlcnZpY2UgZGF0YVxuICovXG5leHBvcnQgZnVuY3Rpb24gd3JpdGVNYW5pZmVzdChcbiAgYXNzZW1ibHk6IENsb3VkQXNzZW1ibHksXG4gIGNvbGxlY3RvcjogTWFuaWZlc3RDb2xsZWN0b3Jcbik6IHZvaWQge1xuICBjb25zdCBjZGtPdXRQYXRoID0gYXNzZW1ibHkuZGlyZWN0b3J5O1xuICBjb25zdCBtYW5pZmVzdFBhdGggPSBqb2luKGNka091dFBhdGgsIE1BTklGRVNUX0ZJTEVfTkFNRSk7XG5cbiAgY29uc3Qgc3RhY2tzID0gY29tcHV0ZVN0YWNrSGFzaGVzKGNka091dFBhdGgpO1xuXG4gIGNvbnN0IG1hbmlmZXN0OiBGamFsbE1hbmlmZXN0ID0ge1xuICAgIHZlcnNpb246IE1BTklGRVNUX1NDSEVNQV9WRVJTSU9OLFxuICAgIGdlbmVyYXRlZEF0OiBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCksXG4gICAgYXBwTmFtZTogY29sbGVjdG9yLmdldEFwcE5hbWUoKSxcbiAgICBzZXJ2aWNlczogY29sbGVjdG9yLmdldFNlcnZpY2VzKCksXG4gICAgbGFtYmRhczogY29sbGVjdG9yLmdldExhbWJkYXMoKSxcbiAgICBzdGFja3NcbiAgfTtcblxuICBjb25zdCBwYXR0ZXJuID0gY29sbGVjdG9yLmdldFBhdHRlcm4oKTtcbiAgaWYgKHBhdHRlcm4pIHtcbiAgICBtYW5pZmVzdC5wYXR0ZXJuID0gcGF0dGVybjtcbiAgfVxuXG4gIGNvbnN0IGVjciA9IGNvbGxlY3Rvci5nZXRFY3IoKTtcbiAgaWYgKGVjcikge1xuICAgIG1hbmlmZXN0LmVjciA9IGVjcjtcbiAgfVxuXG4gIHRyeSB7XG4gICAgd3JpdGVGaWxlU3luYyhtYW5pZmVzdFBhdGgsIEpTT04uc3RyaW5naWZ5KG1hbmlmZXN0LCBudWxsLCAyKSwgXCJ1dGYtOFwiKTtcbiAgICBGamFsbExvZ2dlci5pbmZvKGBGamFsbCBtYW5pZmVzdCB3cml0dGVuIHRvICR7bWFuaWZlc3RQYXRofWApO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIGNvbnN0IGVycm9yTWVzc2FnZSA9IGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5tZXNzYWdlIDogU3RyaW5nKGVycm9yKTtcbiAgICBGamFsbExvZ2dlci53YXJuKGBGYWlsZWQgdG8gd3JpdGUgRmphbGwgbWFuaWZlc3Q6ICR7ZXJyb3JNZXNzYWdlfWApO1xuICB9XG59XG5cbi8qKlxuICogUmVhZCBhbiBleGlzdGluZyBtYW5pZmVzdCBmaWxlIChmb3IgcHJlc2VydmluZyBkZXBsb3ltZW50IGhpc3RvcnkpLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVhZEV4aXN0aW5nTWFuaWZlc3QoY2RrT3V0UGF0aDogc3RyaW5nKTogRmphbGxNYW5pZmVzdCB8IG51bGwge1xuICBjb25zdCBtYW5pZmVzdFBhdGggPSBqb2luKGNka091dFBhdGgsIE1BTklGRVNUX0ZJTEVfTkFNRSk7XG5cbiAgaWYgKCFleGlzdHNTeW5jKG1hbmlmZXN0UGF0aCkpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHRyeSB7XG4gICAgY29uc3QgY29udGVudCA9IHJlYWRGaWxlU3luYyhtYW5pZmVzdFBhdGgsIFwidXRmLThcIik7XG4gICAgcmV0dXJuIEpTT04ucGFyc2UoY29udGVudCkgYXMgRmphbGxNYW5pZmVzdDtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICBjb25zdCBtZXNzYWdlID0gZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiBTdHJpbmcoZXJyb3IpO1xuICAgIEZqYWxsTG9nZ2VyLndhcm4oYEZhaWxlZCB0byBwYXJzZSBleGlzdGluZyBtYW5pZmVzdDogJHttZXNzYWdlfWApO1xuICAgIHJldHVybiBudWxsO1xuICB9XG59XG5cbi8qKlxuICogR2xvYmFsIG1hbmlmZXN0IGNvbGxlY3RvciBpbnN0YW5jZS5cbiAqXG4gKiBDREsncyBhcmNoaXRlY3R1cmUgZ3VhcmFudGVlcyBvbmUgQXBwIHBlciBwcm9jZXNzLCBzbyBhIGdsb2JhbCBzaW5nbGV0b24gaXMgc2FmZSBoZXJlLlxuICogVGhlIGNvbGxlY3RvciBpcyBjcmVhdGVkIHdoZW4gQXBwIGlzIGNvbnN0cnVjdGVkIGFuZCB1c2VkIHRocm91Z2hvdXQgc3ludGhlc2lzLlxuICogcmVzZXRNYW5pZmVzdENvbGxlY3RvcigpIGlzIHByb3ZpZGVkIGZvciB0ZXN0aW5nIHNjZW5hcmlvcyB3aGVyZSBtdWx0aXBsZSBBcHBzXG4gKiBtYXkgYmUgY3JlYXRlZCBpbiB0aGUgc2FtZSBwcm9jZXNzLlxuICovXG5sZXQgZ2xvYmFsQ29sbGVjdG9yOiBNYW5pZmVzdENvbGxlY3RvciB8IG51bGwgPSBudWxsO1xuXG4vKipcbiAqIEdldCBvciBjcmVhdGUgdGhlIGdsb2JhbCBtYW5pZmVzdCBjb2xsZWN0b3IuXG4gKiBDYWxsZWQgYnkgQXBwIGR1cmluZyBjb25zdHJ1Y3Rpb24gdG8gaW5pdGlhbGlzZSB0aGUgY29sbGVjdG9yLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0TWFuaWZlc3RDb2xsZWN0b3IoYXBwTmFtZTogc3RyaW5nKTogTWFuaWZlc3RDb2xsZWN0b3Ige1xuICBpZiAoIWdsb2JhbENvbGxlY3RvciB8fCBnbG9iYWxDb2xsZWN0b3IuZ2V0QXBwTmFtZSgpICE9PSBhcHBOYW1lKSB7XG4gICAgZ2xvYmFsQ29sbGVjdG9yID0gbmV3IE1hbmlmZXN0Q29sbGVjdG9yKGFwcE5hbWUpO1xuICB9XG4gIHJldHVybiBnbG9iYWxDb2xsZWN0b3I7XG59XG5cbi8qKlxuICogR2V0IHRoZSBjdXJyZW50IGdsb2JhbCBtYW5pZmVzdCBjb2xsZWN0b3IuXG4gKiBSZXR1cm5zIG51bGwgaWYgbm90IGluaXRpYWxpc2VkLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0Q3VycmVudENvbGxlY3RvcigpOiBNYW5pZmVzdENvbGxlY3RvciB8IG51bGwge1xuICByZXR1cm4gZ2xvYmFsQ29sbGVjdG9yO1xufVxuXG4vKipcbiAqIFJlc2V0IHRoZSBnbG9iYWwgY29sbGVjdG9yIChmb3IgdGVzdGluZykuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXNldE1hbmlmZXN0Q29sbGVjdG9yKCk6IHZvaWQge1xuICBnbG9iYWxDb2xsZWN0b3IgPSBudWxsO1xufVxuIl19
@@ -20,25 +20,20 @@ class StandardTagsAspect {
20
20
  this.processedResources = new WeakSet();
21
21
  }
22
22
  visit(node) {
23
- // Skip if already processed
24
23
  if (this.processedResources.has(node)) {
25
24
  return;
26
25
  }
27
- // Process L1 (CFN) resources only
28
26
  if (!aws_cdk_lib_1.CfnResource.isCfnResource(node)) {
29
27
  return;
30
28
  }
31
29
  const resource = node;
32
30
  this.processedResources.add(node);
33
- // Skip SecretRotation resources as they create nested stacks
34
31
  if (resource.node.path.includes("SecretRotation")) {
35
32
  return;
36
33
  }
37
- // Add IPAM pool tag for VPCs with IPAM configuration
38
34
  if (resource.cfnResourceType === "AWS::EC2::VPC") {
39
35
  this.addIpamPoolTag(resource);
40
36
  }
41
- // Add disaster recovery tier tag for S3 buckets with backupVaultTier
42
37
  if (resource.cfnResourceType === "AWS::S3::Bucket") {
43
38
  this.addBackupTierTag(resource);
44
39
  }
@@ -71,10 +66,8 @@ class StandardTagsAspect {
71
66
  * - enterprise -> "enterprise"
72
67
  */
73
68
  addBackupTierTag(resource) {
74
- // Walk up the construct tree to find the L2 S3Bucket construct
75
69
  let construct = resource;
76
70
  while (construct) {
77
- // Check if this is our custom S3Bucket class with backupVaultTier property
78
71
  const backupConstruct = construct;
79
72
  if (backupConstruct.backupVaultTier) {
80
73
  const tier = backupConstruct.backupVaultTier;
@@ -92,4 +85,4 @@ class StandardTagsAspect {
92
85
  }
93
86
  }
94
87
  exports.StandardTagsAspect = StandardTagsAspect;
95
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhbmRhcmRUYWdzQXNwZWN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vbGliL3V0aWxzL3N0YW5kYXJkVGFnc0FzcGVjdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSw2Q0FBcUU7QUFTckU7Ozs7Ozs7Ozs7OztHQVlHO0FBQ0gsTUFBYSxrQkFBa0I7SUFBL0I7UUFDbUIsdUJBQWtCLEdBQUcsSUFBSSxPQUFPLEVBQWMsQ0FBQztJQXNGbEUsQ0FBQztJQXBGQyxLQUFLLENBQUMsSUFBZ0I7UUFDcEIsNEJBQTRCO1FBQzVCLElBQUksSUFBSSxDQUFDLGtCQUFrQixDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDO1lBQ3RDLE9BQU87UUFDVCxDQUFDO1FBRUQsa0NBQWtDO1FBQ2xDLElBQUksQ0FBQyx5QkFBVyxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDO1lBQ3JDLE9BQU87UUFDVCxDQUFDO1FBRUQsTUFBTSxRQUFRLEdBQUcsSUFBbUIsQ0FBQztRQUNyQyxJQUFJLENBQUMsa0JBQWtCLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBRWxDLDZEQUE2RDtRQUM3RCxJQUFJLFFBQVEsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxnQkFBZ0IsQ0FBQyxFQUFFLENBQUM7WUFDbEQsT0FBTztRQUNULENBQUM7UUFFRCxxREFBcUQ7UUFDckQsSUFBSSxRQUFRLENBQUMsZUFBZSxLQUFLLGVBQWUsRUFBRSxDQUFDO1lBQ2pELElBQUksQ0FBQyxjQUFjLENBQUMsUUFBa0IsQ0FBQyxDQUFDO1FBQzFDLENBQUM7UUFFRCxxRUFBcUU7UUFDckUsSUFBSSxRQUFRLENBQUMsZUFBZSxLQUFLLGlCQUFpQixFQUFFLENBQUM7WUFDbkQsSUFBSSxDQUFDLGdCQUFnQixDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQ2xDLENBQUM7SUFDSCxDQUFDO0lBRUQ7OztPQUdHO0lBQ0ssY0FBYyxDQUFDLEdBQVc7UUFDaEMsTUFBTSxVQUFVLEdBQUcsR0FBRyxDQUFDLGNBQWMsQ0FBQztRQUV0QyxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7WUFDaEIsT0FBTztRQUNULENBQUM7UUFFRCxNQUFNLEtBQUssR0FBRyxtQkFBSyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUM1QixNQUFNLFNBQVMsR0FDYixLQUFLLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxXQUFXLENBQUM7WUFDckMsS0FBSyxDQUFDLE9BQU87WUFDYixPQUFPLENBQUMsR0FBRyxDQUFDLG1CQUFtQixDQUFDO1FBQ2xDLE1BQU0sTUFBTSxHQUFHLEtBQUssQ0FBQyxNQUFNLElBQUksT0FBTyxDQUFDLEdBQUcsQ0FBQyxrQkFBa0IsQ0FBQztRQUU5RCxJQUFJLFNBQVMsSUFBSSxNQUFNLEVBQUUsQ0FBQztZQUN4QixrQkFBSSxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsdUJBQXVCLEVBQUUsR0FBRyxTQUFTLElBQUksTUFBTSxFQUFFLENBQUMsQ0FBQztRQUN0RSxDQUFDO0lBQ0gsQ0FBQztJQUVEOzs7Ozs7OztPQVFHO0lBQ0ssZ0JBQWdCLENBQUMsUUFBcUI7UUFDNUMsK0RBQStEO1FBQy9ELElBQUksU0FBUyxHQUEyQixRQUFRLENBQUM7UUFDakQsT0FBTyxTQUFTLEVBQUUsQ0FBQztZQUNqQiwyRUFBMkU7WUFDM0UsTUFBTSxlQUFlLEdBQUcsU0FBaUMsQ0FBQztZQUMxRCxJQUFJLGVBQWUsQ0FBQyxlQUFlLEVBQUUsQ0FBQztnQkFDcEMsTUFBTSxJQUFJLEdBQUcsZUFBZSxDQUFDLGVBQWUsQ0FBQztnQkFFN0MsTUFBTSxPQUFPLEdBQTJCO29CQUN0QyxRQUFRLEVBQUUsU0FBUztvQkFDbkIsU0FBUyxFQUFFLFdBQVc7b0JBQ3RCLFVBQVUsRUFBRSxZQUFZO2lCQUN6QixDQUFDO2dCQUVGLE1BQU0sUUFBUSxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxJQUFJLENBQUM7Z0JBQ3ZDLGtCQUFJLENBQUMsRUFBRSxDQUFDLFFBQVEsQ0FBQyxDQUFDLEdBQUcsQ0FBQyw2QkFBNkIsRUFBRSxRQUFRLENBQUMsQ0FBQztnQkFDL0QsTUFBTTtZQUNSLENBQUM7WUFDRCxTQUFTLEdBQUcsU0FBUyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUM7UUFDbkMsQ0FBQztJQUNILENBQUM7Q0FDRjtBQXZGRCxnREF1RkMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyB0eXBlIElBc3BlY3QsIENmblJlc291cmNlLCBTdGFjaywgVGFncyB9IGZyb20gXCJhd3MtY2RrLWxpYlwiO1xuaW1wb3J0IHsgdHlwZSBDZm5WUEMgfSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLWVjMlwiO1xuaW1wb3J0IHsgdHlwZSBJQ29uc3RydWN0IH0gZnJvbSBcImNvbnN0cnVjdHNcIjtcblxuLyoqIENvbnN0cnVjdCB3aXRoIG9wdGlvbmFsIGJhY2t1cFZhdWx0VGllciBwcm9wZXJ0eSAqL1xuaW50ZXJmYWNlIElCYWNrdXBUaWVyQ29uc3RydWN0IGV4dGVuZHMgSUNvbnN0cnVjdCB7XG4gIGJhY2t1cFZhdWx0VGllcj86IHN0cmluZztcbn1cblxuLyoqXG4gKiBBc3BlY3QgdG8gYXBwbHkgc3BlY2lhbCBGamFsbCB0YWdzIHRvIHNwZWNpZmljIHJlc291cmNlIHR5cGVzLlxuICpcbiAqIFRoaXMgYXNwZWN0IGhhbmRsZXMgdGFncyB0aGF0IGRlcGVuZCBvbiByZXNvdXJjZS1zcGVjaWZpYyBwcm9wZXJ0aWVzOlxuICogLSBmamFsbDpvcGVyYXRpb25zOnBvb2wgb24gVlBDcyB3aXRoIElQQU0gY29uZmlndXJhdGlvblxuICogLSBmamFsbDpkaXNhc3RlclJlY292ZXJ5OnRpZXIgb24gUzMgYnVja2V0cyB3aXRoIGJhY2t1cCBjb25maWd1cmF0aW9uXG4gKlxuICogU3RhbmRhcmQgRmphbGwgdGFncyAoY29zdEFsbG9jYXRpb246ZW52aXJvbm1lbnQsIGNvc3RBbGxvY2F0aW9uOnNlcnZpY2UsIGV0Yy4pXG4gKiBhcmUgYXBwbGllZCB2aWEgVGFncy5vZihhcHApLmFkZCgpIGluIHRoZSBBcHAgY2xhc3MsIHdoaWNoIHByb3Blcmx5IG1lcmdlc1xuICogd2l0aCBleGlzdGluZyB0YWdzIGZyb20gTDIgY29uc3RydWN0cy5cbiAqXG4gKiBUaGlzIGFzcGVjdCB1c2VzIFRhZ3Mub2Yobm9kZSkuYWRkKCkgdG8gcHJvcGVybHkgbWVyZ2Ugd2l0aCBleGlzdGluZyB0YWdzXG4gKi9cbmV4cG9ydCBjbGFzcyBTdGFuZGFyZFRhZ3NBc3BlY3QgaW1wbGVtZW50cyBJQXNwZWN0IHtcbiAgcHJpdmF0ZSByZWFkb25seSBwcm9jZXNzZWRSZXNvdXJjZXMgPSBuZXcgV2Vha1NldDxJQ29uc3RydWN0PigpO1xuXG4gIHZpc2l0KG5vZGU6IElDb25zdHJ1Y3QpOiB2b2lkIHtcbiAgICAvLyBTa2lwIGlmIGFscmVhZHkgcHJvY2Vzc2VkXG4gICAgaWYgKHRoaXMucHJvY2Vzc2VkUmVzb3VyY2VzLmhhcyhub2RlKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIFByb2Nlc3MgTDEgKENGTikgcmVzb3VyY2VzIG9ubHlcbiAgICBpZiAoIUNmblJlc291cmNlLmlzQ2ZuUmVzb3VyY2Uobm9kZSkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCByZXNvdXJjZSA9IG5vZGUgYXMgQ2ZuUmVzb3VyY2U7XG4gICAgdGhpcy5wcm9jZXNzZWRSZXNvdXJjZXMuYWRkKG5vZGUpO1xuXG4gICAgLy8gU2tpcCBTZWNyZXRSb3RhdGlvbiByZXNvdXJjZXMgYXMgdGhleSBjcmVhdGUgbmVzdGVkIHN0YWNrc1xuICAgIGlmIChyZXNvdXJjZS5ub2RlLnBhdGguaW5jbHVkZXMoXCJTZWNyZXRSb3RhdGlvblwiKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIEFkZCBJUEFNIHBvb2wgdGFnIGZvciBWUENzIHdpdGggSVBBTSBjb25maWd1cmF0aW9uXG4gICAgaWYgKHJlc291cmNlLmNmblJlc291cmNlVHlwZSA9PT0gXCJBV1M6OkVDMjo6VlBDXCIpIHtcbiAgICAgIHRoaXMuYWRkSXBhbVBvb2xUYWcocmVzb3VyY2UgYXMgQ2ZuVlBDKTtcbiAgICB9XG5cbiAgICAvLyBBZGQgZGlzYXN0ZXIgcmVjb3ZlcnkgdGllciB0YWcgZm9yIFMzIGJ1Y2tldHMgd2l0aCBiYWNrdXBWYXVsdFRpZXJcbiAgICBpZiAocmVzb3VyY2UuY2ZuUmVzb3VyY2VUeXBlID09PSBcIkFXUzo6UzM6OkJ1Y2tldFwiKSB7XG4gICAgICB0aGlzLmFkZEJhY2t1cFRpZXJUYWcocmVzb3VyY2UpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBBZGQgSVBBTSBwb29sIHRhZyB0byBWUENzIHRoYXQgdXNlIElQQU0gZm9yIElQIGFkZHJlc3MgYWxsb2NhdGlvbi5cbiAgICogVGFnIGZvcm1hdDogZmphbGw6b3BlcmF0aW9uczpwb29sID0gXCJ7YWNjb3VudElkfS17cmVnaW9ufVwiXG4gICAqL1xuICBwcml2YXRlIGFkZElwYW1Qb29sVGFnKHZwYzogQ2ZuVlBDKTogdm9pZCB7XG4gICAgY29uc3QgaXBhbVBvb2xJZCA9IHZwYy5pcHY0SXBhbVBvb2xJZDtcblxuICAgIGlmICghaXBhbVBvb2xJZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHN0YWNrID0gU3RhY2sub2YodnBjKTtcbiAgICBjb25zdCBhY2NvdW50SWQgPVxuICAgICAgc3RhY2subm9kZS50cnlHZXRDb250ZXh0KFwiYWNjb3VudElkXCIpIHx8XG4gICAgICBzdGFjay5hY2NvdW50IHx8XG4gICAgICBwcm9jZXNzLmVudi5DREtfREVGQVVMVF9BQ0NPVU5UO1xuICAgIGNvbnN0IHJlZ2lvbiA9IHN0YWNrLnJlZ2lvbiB8fCBwcm9jZXNzLmVudi5DREtfREVGQVVMVF9SRUdJT047XG5cbiAgICBpZiAoYWNjb3VudElkICYmIHJlZ2lvbikge1xuICAgICAgVGFncy5vZih2cGMpLmFkZChcImZqYWxsOm9wZXJhdGlvbnM6cG9vbFwiLCBgJHthY2NvdW50SWR9LSR7cmVnaW9ufWApO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBBZGQgZGlzYXN0ZXIgcmVjb3ZlcnkgdGllciB0YWcgdG8gUzMgYnVja2V0cyB3aXRoIGJhY2t1cFZhdWx0VGllciBwcm9wZXJ0eS5cbiAgICogVGFnIGZvcm1hdDogZmphbGw6ZGlzYXN0ZXJSZWNvdmVyeTp0aWVyID0gXCJ7dGllcn1cIlxuICAgKlxuICAgKiBUaWVyIG1hcHBpbmc6XG4gICAqIC0gc3RhbmRhcmQgLT4gXCJkZWZhdWx0XCIgKG1hdGNoZXMgZXhpc3RpbmcgYmFja3VwIHBsYW5zKVxuICAgKiAtIHJlc2lsaWVudCAtPiBcInJlc2lsaWVudFwiXG4gICAqIC0gZW50ZXJwcmlzZSAtPiBcImVudGVycHJpc2VcIlxuICAgKi9cbiAgcHJpdmF0ZSBhZGRCYWNrdXBUaWVyVGFnKHJlc291cmNlOiBDZm5SZXNvdXJjZSk6IHZvaWQge1xuICAgIC8vIFdhbGsgdXAgdGhlIGNvbnN0cnVjdCB0cmVlIHRvIGZpbmQgdGhlIEwyIFMzQnVja2V0IGNvbnN0cnVjdFxuICAgIGxldCBjb25zdHJ1Y3Q6IElDb25zdHJ1Y3QgfCB1bmRlZmluZWQgPSByZXNvdXJjZTtcbiAgICB3aGlsZSAoY29uc3RydWN0KSB7XG4gICAgICAvLyBDaGVjayBpZiB0aGlzIGlzIG91ciBjdXN0b20gUzNCdWNrZXQgY2xhc3Mgd2l0aCBiYWNrdXBWYXVsdFRpZXIgcHJvcGVydHlcbiAgICAgIGNvbnN0IGJhY2t1cENvbnN0cnVjdCA9IGNvbnN0cnVjdCBhcyBJQmFja3VwVGllckNvbnN0cnVjdDtcbiAgICAgIGlmIChiYWNrdXBDb25zdHJ1Y3QuYmFja3VwVmF1bHRUaWVyKSB7XG4gICAgICAgIGNvbnN0IHRpZXIgPSBiYWNrdXBDb25zdHJ1Y3QuYmFja3VwVmF1bHRUaWVyO1xuXG4gICAgICAgIGNvbnN0IHRpZXJNYXA6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7XG4gICAgICAgICAgc3RhbmRhcmQ6IFwiZGVmYXVsdFwiLFxuICAgICAgICAgIHJlc2lsaWVudDogXCJyZXNpbGllbnRcIixcbiAgICAgICAgICBlbnRlcnByaXNlOiBcImVudGVycHJpc2VcIlxuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IHRhZ1ZhbHVlID0gdGllck1hcFt0aWVyXSB8fCB0aWVyO1xuICAgICAgICBUYWdzLm9mKHJlc291cmNlKS5hZGQoXCJmamFsbDpkaXNhc3RlclJlY292ZXJ5OnRpZXJcIiwgdGFnVmFsdWUpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGNvbnN0cnVjdCA9IGNvbnN0cnVjdC5ub2RlLnNjb3BlO1xuICAgIH1cbiAgfVxufVxuIl19
88
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhbmRhcmRUYWdzQXNwZWN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vbGliL3V0aWxzL3N0YW5kYXJkVGFnc0FzcGVjdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSw2Q0FBcUU7QUFTckU7Ozs7Ozs7Ozs7OztHQVlHO0FBQ0gsTUFBYSxrQkFBa0I7SUFBL0I7UUFDbUIsdUJBQWtCLEdBQUcsSUFBSSxPQUFPLEVBQWMsQ0FBQztJQStFbEUsQ0FBQztJQTdFQyxLQUFLLENBQUMsSUFBZ0I7UUFDcEIsSUFBSSxJQUFJLENBQUMsa0JBQWtCLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUM7WUFDdEMsT0FBTztRQUNULENBQUM7UUFFRCxJQUFJLENBQUMseUJBQVcsQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQztZQUNyQyxPQUFPO1FBQ1QsQ0FBQztRQUVELE1BQU0sUUFBUSxHQUFHLElBQW1CLENBQUM7UUFDckMsSUFBSSxDQUFDLGtCQUFrQixDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUVsQyxJQUFJLFFBQVEsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxnQkFBZ0IsQ0FBQyxFQUFFLENBQUM7WUFDbEQsT0FBTztRQUNULENBQUM7UUFFRCxJQUFJLFFBQVEsQ0FBQyxlQUFlLEtBQUssZUFBZSxFQUFFLENBQUM7WUFDakQsSUFBSSxDQUFDLGNBQWMsQ0FBQyxRQUFrQixDQUFDLENBQUM7UUFDMUMsQ0FBQztRQUVELElBQUksUUFBUSxDQUFDLGVBQWUsS0FBSyxpQkFBaUIsRUFBRSxDQUFDO1lBQ25ELElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUNsQyxDQUFDO0lBQ0gsQ0FBQztJQUVEOzs7T0FHRztJQUNLLGNBQWMsQ0FBQyxHQUFXO1FBQ2hDLE1BQU0sVUFBVSxHQUFHLEdBQUcsQ0FBQyxjQUFjLENBQUM7UUFFdEMsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO1lBQ2hCLE9BQU87UUFDVCxDQUFDO1FBRUQsTUFBTSxLQUFLLEdBQUcsbUJBQUssQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDNUIsTUFBTSxTQUFTLEdBQ2IsS0FBSyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsV0FBVyxDQUFDO1lBQ3JDLEtBQUssQ0FBQyxPQUFPO1lBQ2IsT0FBTyxDQUFDLEdBQUcsQ0FBQyxtQkFBbUIsQ0FBQztRQUNsQyxNQUFNLE1BQU0sR0FBRyxLQUFLLENBQUMsTUFBTSxJQUFJLE9BQU8sQ0FBQyxHQUFHLENBQUMsa0JBQWtCLENBQUM7UUFFOUQsSUFBSSxTQUFTLElBQUksTUFBTSxFQUFFLENBQUM7WUFDeEIsa0JBQUksQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLHVCQUF1QixFQUFFLEdBQUcsU0FBUyxJQUFJLE1BQU0sRUFBRSxDQUFDLENBQUM7UUFDdEUsQ0FBQztJQUNILENBQUM7SUFFRDs7Ozs7Ozs7T0FRRztJQUNLLGdCQUFnQixDQUFDLFFBQXFCO1FBQzVDLElBQUksU0FBUyxHQUEyQixRQUFRLENBQUM7UUFDakQsT0FBTyxTQUFTLEVBQUUsQ0FBQztZQUNqQixNQUFNLGVBQWUsR0FBRyxTQUFpQyxDQUFDO1lBQzFELElBQUksZUFBZSxDQUFDLGVBQWUsRUFBRSxDQUFDO2dCQUNwQyxNQUFNLElBQUksR0FBRyxlQUFlLENBQUMsZUFBZSxDQUFDO2dCQUU3QyxNQUFNLE9BQU8sR0FBMkI7b0JBQ3RDLFFBQVEsRUFBRSxTQUFTO29CQUNuQixTQUFTLEVBQUUsV0FBVztvQkFDdEIsVUFBVSxFQUFFLFlBQVk7aUJBQ3pCLENBQUM7Z0JBRUYsTUFBTSxRQUFRLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLElBQUksQ0FBQztnQkFDdkMsa0JBQUksQ0FBQyxFQUFFLENBQUMsUUFBUSxDQUFDLENBQUMsR0FBRyxDQUFDLDZCQUE2QixFQUFFLFFBQVEsQ0FBQyxDQUFDO2dCQUMvRCxNQUFNO1lBQ1IsQ0FBQztZQUNELFNBQVMsR0FBRyxTQUFTLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQztRQUNuQyxDQUFDO0lBQ0gsQ0FBQztDQUNGO0FBaEZELGdEQWdGQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IHR5cGUgSUFzcGVjdCwgQ2ZuUmVzb3VyY2UsIFN0YWNrLCBUYWdzIH0gZnJvbSBcImF3cy1jZGstbGliXCI7XG5pbXBvcnQgeyB0eXBlIENmblZQQyB9IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtZWMyXCI7XG5pbXBvcnQgeyB0eXBlIElDb25zdHJ1Y3QgfSBmcm9tIFwiY29uc3RydWN0c1wiO1xuXG4vKiogQ29uc3RydWN0IHdpdGggb3B0aW9uYWwgYmFja3VwVmF1bHRUaWVyIHByb3BlcnR5ICovXG5pbnRlcmZhY2UgSUJhY2t1cFRpZXJDb25zdHJ1Y3QgZXh0ZW5kcyBJQ29uc3RydWN0IHtcbiAgYmFja3VwVmF1bHRUaWVyPzogc3RyaW5nO1xufVxuXG4vKipcbiAqIEFzcGVjdCB0byBhcHBseSBzcGVjaWFsIEZqYWxsIHRhZ3MgdG8gc3BlY2lmaWMgcmVzb3VyY2UgdHlwZXMuXG4gKlxuICogVGhpcyBhc3BlY3QgaGFuZGxlcyB0YWdzIHRoYXQgZGVwZW5kIG9uIHJlc291cmNlLXNwZWNpZmljIHByb3BlcnRpZXM6XG4gKiAtIGZqYWxsOm9wZXJhdGlvbnM6cG9vbCBvbiBWUENzIHdpdGggSVBBTSBjb25maWd1cmF0aW9uXG4gKiAtIGZqYWxsOmRpc2FzdGVyUmVjb3Zlcnk6dGllciBvbiBTMyBidWNrZXRzIHdpdGggYmFja3VwIGNvbmZpZ3VyYXRpb25cbiAqXG4gKiBTdGFuZGFyZCBGamFsbCB0YWdzIChjb3N0QWxsb2NhdGlvbjplbnZpcm9ubWVudCwgY29zdEFsbG9jYXRpb246c2VydmljZSwgZXRjLilcbiAqIGFyZSBhcHBsaWVkIHZpYSBUYWdzLm9mKGFwcCkuYWRkKCkgaW4gdGhlIEFwcCBjbGFzcywgd2hpY2ggcHJvcGVybHkgbWVyZ2VzXG4gKiB3aXRoIGV4aXN0aW5nIHRhZ3MgZnJvbSBMMiBjb25zdHJ1Y3RzLlxuICpcbiAqIFRoaXMgYXNwZWN0IHVzZXMgVGFncy5vZihub2RlKS5hZGQoKSB0byBwcm9wZXJseSBtZXJnZSB3aXRoIGV4aXN0aW5nIHRhZ3NcbiAqL1xuZXhwb3J0IGNsYXNzIFN0YW5kYXJkVGFnc0FzcGVjdCBpbXBsZW1lbnRzIElBc3BlY3Qge1xuICBwcml2YXRlIHJlYWRvbmx5IHByb2Nlc3NlZFJlc291cmNlcyA9IG5ldyBXZWFrU2V0PElDb25zdHJ1Y3Q+KCk7XG5cbiAgdmlzaXQobm9kZTogSUNvbnN0cnVjdCk6IHZvaWQge1xuICAgIGlmICh0aGlzLnByb2Nlc3NlZFJlc291cmNlcy5oYXMobm9kZSkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoIUNmblJlc291cmNlLmlzQ2ZuUmVzb3VyY2Uobm9kZSkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCByZXNvdXJjZSA9IG5vZGUgYXMgQ2ZuUmVzb3VyY2U7XG4gICAgdGhpcy5wcm9jZXNzZWRSZXNvdXJjZXMuYWRkKG5vZGUpO1xuXG4gICAgaWYgKHJlc291cmNlLm5vZGUucGF0aC5pbmNsdWRlcyhcIlNlY3JldFJvdGF0aW9uXCIpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKHJlc291cmNlLmNmblJlc291cmNlVHlwZSA9PT0gXCJBV1M6OkVDMjo6VlBDXCIpIHtcbiAgICAgIHRoaXMuYWRkSXBhbVBvb2xUYWcocmVzb3VyY2UgYXMgQ2ZuVlBDKTtcbiAgICB9XG5cbiAgICBpZiAocmVzb3VyY2UuY2ZuUmVzb3VyY2VUeXBlID09PSBcIkFXUzo6UzM6OkJ1Y2tldFwiKSB7XG4gICAgICB0aGlzLmFkZEJhY2t1cFRpZXJUYWcocmVzb3VyY2UpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBBZGQgSVBBTSBwb29sIHRhZyB0byBWUENzIHRoYXQgdXNlIElQQU0gZm9yIElQIGFkZHJlc3MgYWxsb2NhdGlvbi5cbiAgICogVGFnIGZvcm1hdDogZmphbGw6b3BlcmF0aW9uczpwb29sID0gXCJ7YWNjb3VudElkfS17cmVnaW9ufVwiXG4gICAqL1xuICBwcml2YXRlIGFkZElwYW1Qb29sVGFnKHZwYzogQ2ZuVlBDKTogdm9pZCB7XG4gICAgY29uc3QgaXBhbVBvb2xJZCA9IHZwYy5pcHY0SXBhbVBvb2xJZDtcblxuICAgIGlmICghaXBhbVBvb2xJZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHN0YWNrID0gU3RhY2sub2YodnBjKTtcbiAgICBjb25zdCBhY2NvdW50SWQgPVxuICAgICAgc3RhY2subm9kZS50cnlHZXRDb250ZXh0KFwiYWNjb3VudElkXCIpIHx8XG4gICAgICBzdGFjay5hY2NvdW50IHx8XG4gICAgICBwcm9jZXNzLmVudi5DREtfREVGQVVMVF9BQ0NPVU5UO1xuICAgIGNvbnN0IHJlZ2lvbiA9IHN0YWNrLnJlZ2lvbiB8fCBwcm9jZXNzLmVudi5DREtfREVGQVVMVF9SRUdJT047XG5cbiAgICBpZiAoYWNjb3VudElkICYmIHJlZ2lvbikge1xuICAgICAgVGFncy5vZih2cGMpLmFkZChcImZqYWxsOm9wZXJhdGlvbnM6cG9vbFwiLCBgJHthY2NvdW50SWR9LSR7cmVnaW9ufWApO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBBZGQgZGlzYXN0ZXIgcmVjb3ZlcnkgdGllciB0YWcgdG8gUzMgYnVja2V0cyB3aXRoIGJhY2t1cFZhdWx0VGllciBwcm9wZXJ0eS5cbiAgICogVGFnIGZvcm1hdDogZmphbGw6ZGlzYXN0ZXJSZWNvdmVyeTp0aWVyID0gXCJ7dGllcn1cIlxuICAgKlxuICAgKiBUaWVyIG1hcHBpbmc6XG4gICAqIC0gc3RhbmRhcmQgLT4gXCJkZWZhdWx0XCIgKG1hdGNoZXMgZXhpc3RpbmcgYmFja3VwIHBsYW5zKVxuICAgKiAtIHJlc2lsaWVudCAtPiBcInJlc2lsaWVudFwiXG4gICAqIC0gZW50ZXJwcmlzZSAtPiBcImVudGVycHJpc2VcIlxuICAgKi9cbiAgcHJpdmF0ZSBhZGRCYWNrdXBUaWVyVGFnKHJlc291cmNlOiBDZm5SZXNvdXJjZSk6IHZvaWQge1xuICAgIGxldCBjb25zdHJ1Y3Q6IElDb25zdHJ1Y3QgfCB1bmRlZmluZWQgPSByZXNvdXJjZTtcbiAgICB3aGlsZSAoY29uc3RydWN0KSB7XG4gICAgICBjb25zdCBiYWNrdXBDb25zdHJ1Y3QgPSBjb25zdHJ1Y3QgYXMgSUJhY2t1cFRpZXJDb25zdHJ1Y3Q7XG4gICAgICBpZiAoYmFja3VwQ29uc3RydWN0LmJhY2t1cFZhdWx0VGllcikge1xuICAgICAgICBjb25zdCB0aWVyID0gYmFja3VwQ29uc3RydWN0LmJhY2t1cFZhdWx0VGllcjtcblxuICAgICAgICBjb25zdCB0aWVyTWFwOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge1xuICAgICAgICAgIHN0YW5kYXJkOiBcImRlZmF1bHRcIixcbiAgICAgICAgICByZXNpbGllbnQ6IFwicmVzaWxpZW50XCIsXG4gICAgICAgICAgZW50ZXJwcmlzZTogXCJlbnRlcnByaXNlXCJcbiAgICAgICAgfTtcblxuICAgICAgICBjb25zdCB0YWdWYWx1ZSA9IHRpZXJNYXBbdGllcl0gfHwgdGllcjtcbiAgICAgICAgVGFncy5vZihyZXNvdXJjZSkuYWRkKFwiZmphbGw6ZGlzYXN0ZXJSZWNvdmVyeTp0aWVyXCIsIHRhZ1ZhbHVlKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBjb25zdHJ1Y3QgPSBjb25zdHJ1Y3Qubm9kZS5zY29wZTtcbiAgICB9XG4gIH1cbn1cbiJdfQ==
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Fjall validation logging utilities.
3
+ * Centralises warning and info messages for consistent formatting.
4
+ * Also writes to JSONL file for debugging and support.
5
+ */
6
+ export declare const FjallLogger: {
7
+ /**
8
+ * Log a warning message with Fjall prefix.
9
+ */
10
+ readonly warn: (message: string) => void;
11
+ /**
12
+ * Log an info message with Fjall prefix.
13
+ */
14
+ readonly info: (message: string) => void;
15
+ };
16
+ /**
17
+ * Warn if a property is set but will be ignored for the given type.
18
+ * Used across factories to alert users about type-specific properties.
19
+ *
20
+ * @param props - The props object with a `type` discriminator
21
+ * @param property - The property name to check
22
+ * @param applicableType - The type(s) where this property is used
23
+ * @param typeName - Human-readable type name for the message
24
+ */
25
+ export declare function warnIfPropertyIgnored<T extends {
26
+ type: string;
27
+ }>(props: T, property: string, applicableType: string | string[], typeName: string): void;
28
+ /**
29
+ * Warn if any of the specified properties are set but will be ignored.
30
+ * Convenience wrapper for checking multiple properties at once.
31
+ */
32
+ export declare function warnIfPropertiesIgnored<T extends {
33
+ type: string;
34
+ }>(props: T, properties: string[], applicableType: string | string[], typeName: string): void;
@@ -0,0 +1,83 @@
1
+ "use strict";
2
+ /**
3
+ * Fjall validation logging utilities.
4
+ * Centralises warning and info messages for consistent formatting.
5
+ * Also writes to JSONL file for debugging and support.
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.FjallLogger = void 0;
9
+ exports.warnIfPropertyIgnored = warnIfPropertyIgnored;
10
+ exports.warnIfPropertiesIgnored = warnIfPropertiesIgnored;
11
+ const fs_1 = require("fs");
12
+ const os_1 = require("os");
13
+ const path_1 = require("path");
14
+ const LOG_DIR = process.env.FJALL_LOG_DIR ?? (0, path_1.join)((0, os_1.homedir)(), ".fjall", "logs");
15
+ const LOG_FILE = (0, path_1.join)(LOG_DIR, "infrastructure.jsonl");
16
+ /**
17
+ * Write a log entry to the infrastructure JSONL file
18
+ */
19
+ function writeToLog(level, message) {
20
+ try {
21
+ if (!(0, fs_1.existsSync)(LOG_DIR)) {
22
+ (0, fs_1.mkdirSync)(LOG_DIR, { recursive: true });
23
+ }
24
+ const entry = JSON.stringify({
25
+ timestamp: new Date().toISOString(),
26
+ level,
27
+ component: "Infrastructure",
28
+ message,
29
+ source: "cdk-subprocess"
30
+ });
31
+ (0, fs_1.appendFileSync)(LOG_FILE, entry + "\n");
32
+ }
33
+ catch {
34
+ // Never crash CDK on logging failure
35
+ }
36
+ }
37
+ exports.FjallLogger = {
38
+ /**
39
+ * Log a warning message with Fjall prefix.
40
+ */
41
+ warn: (message) => {
42
+ console.warn(`[Fjall] Warning: ${message}`);
43
+ writeToLog("warn", message);
44
+ },
45
+ /**
46
+ * Log an info message with Fjall prefix.
47
+ */
48
+ info: (message) => {
49
+ console.info(`[Fjall] Note: ${message}`);
50
+ writeToLog("info", message);
51
+ }
52
+ };
53
+ /**
54
+ * Warn if a property is set but will be ignored for the given type.
55
+ * Used across factories to alert users about type-specific properties.
56
+ *
57
+ * @param props - The props object with a `type` discriminator
58
+ * @param property - The property name to check
59
+ * @param applicableType - The type(s) where this property is used
60
+ * @param typeName - Human-readable type name for the message
61
+ */
62
+ function warnIfPropertyIgnored(props, property, applicableType, typeName) {
63
+ const propsRecord = props;
64
+ const types = Array.isArray(applicableType)
65
+ ? applicableType
66
+ : [applicableType];
67
+ if (!types.includes(props.type) &&
68
+ property in propsRecord &&
69
+ propsRecord[property] !== undefined) {
70
+ exports.FjallLogger.warn(`'${property}' is only used for ${typeName} type. ` +
71
+ `It will be ignored for type '${props.type}'.`);
72
+ }
73
+ }
74
+ /**
75
+ * Warn if any of the specified properties are set but will be ignored.
76
+ * Convenience wrapper for checking multiple properties at once.
77
+ */
78
+ function warnIfPropertiesIgnored(props, properties, applicableType, typeName) {
79
+ for (const property of properties) {
80
+ warnIfPropertyIgnored(props, property, applicableType, typeName);
81
+ }
82
+ }
83
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmFsaWRhdGlvbkxvZ2dlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL2xpYi91dGlscy92YWxpZGF0aW9uTG9nZ2VyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTs7OztHQUlHOzs7QUF5REgsc0RBcUJDO0FBTUQsMERBU0M7QUEzRkQsMkJBQTJEO0FBQzNELDJCQUE2QjtBQUM3QiwrQkFBNEI7QUFFNUIsTUFBTSxPQUFPLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxhQUFhLElBQUksSUFBQSxXQUFJLEVBQUMsSUFBQSxZQUFPLEdBQUUsRUFBRSxRQUFRLEVBQUUsTUFBTSxDQUFDLENBQUM7QUFDL0UsTUFBTSxRQUFRLEdBQUcsSUFBQSxXQUFJLEVBQUMsT0FBTyxFQUFFLHNCQUFzQixDQUFDLENBQUM7QUFFdkQ7O0dBRUc7QUFDSCxTQUFTLFVBQVUsQ0FBQyxLQUFhLEVBQUUsT0FBZTtJQUNoRCxJQUFJLENBQUM7UUFDSCxJQUFJLENBQUMsSUFBQSxlQUFVLEVBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztZQUN6QixJQUFBLGNBQVMsRUFBQyxPQUFPLEVBQUUsRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztRQUMxQyxDQUFDO1FBQ0QsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQztZQUMzQixTQUFTLEVBQUUsSUFBSSxJQUFJLEVBQUUsQ0FBQyxXQUFXLEVBQUU7WUFDbkMsS0FBSztZQUNMLFNBQVMsRUFBRSxnQkFBZ0I7WUFDM0IsT0FBTztZQUNQLE1BQU0sRUFBRSxnQkFBZ0I7U0FDekIsQ0FBQyxDQUFDO1FBQ0gsSUFBQSxtQkFBYyxFQUFDLFFBQVEsRUFBRSxLQUFLLEdBQUcsSUFBSSxDQUFDLENBQUM7SUFDekMsQ0FBQztJQUFDLE1BQU0sQ0FBQztRQUNQLHFDQUFxQztJQUN2QyxDQUFDO0FBQ0gsQ0FBQztBQUVZLFFBQUEsV0FBVyxHQUFHO0lBQ3pCOztPQUVHO0lBQ0gsSUFBSSxFQUFFLENBQUMsT0FBZSxFQUFRLEVBQUU7UUFDOUIsT0FBTyxDQUFDLElBQUksQ0FBQyxvQkFBb0IsT0FBTyxFQUFFLENBQUMsQ0FBQztRQUM1QyxVQUFVLENBQUMsTUFBTSxFQUFFLE9BQU8sQ0FBQyxDQUFDO0lBQzlCLENBQUM7SUFFRDs7T0FFRztJQUNILElBQUksRUFBRSxDQUFDLE9BQWUsRUFBUSxFQUFFO1FBQzlCLE9BQU8sQ0FBQyxJQUFJLENBQUMsaUJBQWlCLE9BQU8sRUFBRSxDQUFDLENBQUM7UUFDekMsVUFBVSxDQUFDLE1BQU0sRUFBRSxPQUFPLENBQUMsQ0FBQztJQUM5QixDQUFDO0NBQ08sQ0FBQztBQUVYOzs7Ozs7OztHQVFHO0FBQ0gsU0FBZ0IscUJBQXFCLENBQ25DLEtBQVEsRUFDUixRQUFnQixFQUNoQixjQUFpQyxFQUNqQyxRQUFnQjtJQUVoQixNQUFNLFdBQVcsR0FBRyxLQUEyQyxDQUFDO0lBQ2hFLE1BQU0sS0FBSyxHQUFHLEtBQUssQ0FBQyxPQUFPLENBQUMsY0FBYyxDQUFDO1FBQ3pDLENBQUMsQ0FBQyxjQUFjO1FBQ2hCLENBQUMsQ0FBQyxDQUFDLGNBQWMsQ0FBQyxDQUFDO0lBRXJCLElBQ0UsQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUM7UUFDM0IsUUFBUSxJQUFJLFdBQVc7UUFDdkIsV0FBVyxDQUFDLFFBQVEsQ0FBQyxLQUFLLFNBQVMsRUFDbkMsQ0FBQztRQUNELG1CQUFXLENBQUMsSUFBSSxDQUNkLElBQUksUUFBUSxzQkFBc0IsUUFBUSxTQUFTO1lBQ2pELGdDQUFnQyxLQUFLLENBQUMsSUFBSSxJQUFJLENBQ2pELENBQUM7SUFDSixDQUFDO0FBQ0gsQ0FBQztBQUVEOzs7R0FHRztBQUNILFNBQWdCLHVCQUF1QixDQUNyQyxLQUFRLEVBQ1IsVUFBb0IsRUFDcEIsY0FBaUMsRUFDakMsUUFBZ0I7SUFFaEIsS0FBSyxNQUFNLFFBQVEsSUFBSSxVQUFVLEVBQUUsQ0FBQztRQUNsQyxxQkFBcUIsQ0FBQyxLQUFLLEVBQUUsUUFBUSxFQUFFLGNBQWMsRUFBRSxRQUFRLENBQUMsQ0FBQztJQUNuRSxDQUFDO0FBQ0gsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogRmphbGwgdmFsaWRhdGlvbiBsb2dnaW5nIHV0aWxpdGllcy5cbiAqIENlbnRyYWxpc2VzIHdhcm5pbmcgYW5kIGluZm8gbWVzc2FnZXMgZm9yIGNvbnNpc3RlbnQgZm9ybWF0dGluZy5cbiAqIEFsc28gd3JpdGVzIHRvIEpTT05MIGZpbGUgZm9yIGRlYnVnZ2luZyBhbmQgc3VwcG9ydC5cbiAqL1xuXG5pbXBvcnQgeyBhcHBlbmRGaWxlU3luYywgZXhpc3RzU3luYywgbWtkaXJTeW5jIH0gZnJvbSBcImZzXCI7XG5pbXBvcnQgeyBob21lZGlyIH0gZnJvbSBcIm9zXCI7XG5pbXBvcnQgeyBqb2luIH0gZnJvbSBcInBhdGhcIjtcblxuY29uc3QgTE9HX0RJUiA9IHByb2Nlc3MuZW52LkZKQUxMX0xPR19ESVIgPz8gam9pbihob21lZGlyKCksIFwiLmZqYWxsXCIsIFwibG9nc1wiKTtcbmNvbnN0IExPR19GSUxFID0gam9pbihMT0dfRElSLCBcImluZnJhc3RydWN0dXJlLmpzb25sXCIpO1xuXG4vKipcbiAqIFdyaXRlIGEgbG9nIGVudHJ5IHRvIHRoZSBpbmZyYXN0cnVjdHVyZSBKU09OTCBmaWxlXG4gKi9cbmZ1bmN0aW9uIHdyaXRlVG9Mb2cobGV2ZWw6IHN0cmluZywgbWVzc2FnZTogc3RyaW5nKTogdm9pZCB7XG4gIHRyeSB7XG4gICAgaWYgKCFleGlzdHNTeW5jKExPR19ESVIpKSB7XG4gICAgICBta2RpclN5bmMoTE9HX0RJUiwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG4gICAgfVxuICAgIGNvbnN0IGVudHJ5ID0gSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgdGltZXN0YW1wOiBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCksXG4gICAgICBsZXZlbCxcbiAgICAgIGNvbXBvbmVudDogXCJJbmZyYXN0cnVjdHVyZVwiLFxuICAgICAgbWVzc2FnZSxcbiAgICAgIHNvdXJjZTogXCJjZGstc3VicHJvY2Vzc1wiXG4gICAgfSk7XG4gICAgYXBwZW5kRmlsZVN5bmMoTE9HX0ZJTEUsIGVudHJ5ICsgXCJcXG5cIik7XG4gIH0gY2F0Y2gge1xuICAgIC8vIE5ldmVyIGNyYXNoIENESyBvbiBsb2dnaW5nIGZhaWx1cmVcbiAgfVxufVxuXG5leHBvcnQgY29uc3QgRmphbGxMb2dnZXIgPSB7XG4gIC8qKlxuICAgKiBMb2cgYSB3YXJuaW5nIG1lc3NhZ2Ugd2l0aCBGamFsbCBwcmVmaXguXG4gICAqL1xuICB3YXJuOiAobWVzc2FnZTogc3RyaW5nKTogdm9pZCA9PiB7XG4gICAgY29uc29sZS53YXJuKGBbRmphbGxdIFdhcm5pbmc6ICR7bWVzc2FnZX1gKTtcbiAgICB3cml0ZVRvTG9nKFwid2FyblwiLCBtZXNzYWdlKTtcbiAgfSxcblxuICAvKipcbiAgICogTG9nIGFuIGluZm8gbWVzc2FnZSB3aXRoIEZqYWxsIHByZWZpeC5cbiAgICovXG4gIGluZm86IChtZXNzYWdlOiBzdHJpbmcpOiB2b2lkID0+IHtcbiAgICBjb25zb2xlLmluZm8oYFtGamFsbF0gTm90ZTogJHttZXNzYWdlfWApO1xuICAgIHdyaXRlVG9Mb2coXCJpbmZvXCIsIG1lc3NhZ2UpO1xuICB9XG59IGFzIGNvbnN0O1xuXG4vKipcbiAqIFdhcm4gaWYgYSBwcm9wZXJ0eSBpcyBzZXQgYnV0IHdpbGwgYmUgaWdub3JlZCBmb3IgdGhlIGdpdmVuIHR5cGUuXG4gKiBVc2VkIGFjcm9zcyBmYWN0b3JpZXMgdG8gYWxlcnQgdXNlcnMgYWJvdXQgdHlwZS1zcGVjaWZpYyBwcm9wZXJ0aWVzLlxuICpcbiAqIEBwYXJhbSBwcm9wcyAtIFRoZSBwcm9wcyBvYmplY3Qgd2l0aCBhIGB0eXBlYCBkaXNjcmltaW5hdG9yXG4gKiBAcGFyYW0gcHJvcGVydHkgLSBUaGUgcHJvcGVydHkgbmFtZSB0byBjaGVja1xuICogQHBhcmFtIGFwcGxpY2FibGVUeXBlIC0gVGhlIHR5cGUocykgd2hlcmUgdGhpcyBwcm9wZXJ0eSBpcyB1c2VkXG4gKiBAcGFyYW0gdHlwZU5hbWUgLSBIdW1hbi1yZWFkYWJsZSB0eXBlIG5hbWUgZm9yIHRoZSBtZXNzYWdlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB3YXJuSWZQcm9wZXJ0eUlnbm9yZWQ8VCBleHRlbmRzIHsgdHlwZTogc3RyaW5nIH0+KFxuICBwcm9wczogVCxcbiAgcHJvcGVydHk6IHN0cmluZyxcbiAgYXBwbGljYWJsZVR5cGU6IHN0cmluZyB8IHN0cmluZ1tdLFxuICB0eXBlTmFtZTogc3RyaW5nXG4pOiB2b2lkIHtcbiAgY29uc3QgcHJvcHNSZWNvcmQgPSBwcm9wcyBhcyB1bmtub3duIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xuICBjb25zdCB0eXBlcyA9IEFycmF5LmlzQXJyYXkoYXBwbGljYWJsZVR5cGUpXG4gICAgPyBhcHBsaWNhYmxlVHlwZVxuICAgIDogW2FwcGxpY2FibGVUeXBlXTtcblxuICBpZiAoXG4gICAgIXR5cGVzLmluY2x1ZGVzKHByb3BzLnR5cGUpICYmXG4gICAgcHJvcGVydHkgaW4gcHJvcHNSZWNvcmQgJiZcbiAgICBwcm9wc1JlY29yZFtwcm9wZXJ0eV0gIT09IHVuZGVmaW5lZFxuICApIHtcbiAgICBGamFsbExvZ2dlci53YXJuKFxuICAgICAgYCcke3Byb3BlcnR5fScgaXMgb25seSB1c2VkIGZvciAke3R5cGVOYW1lfSB0eXBlLiBgICtcbiAgICAgICAgYEl0IHdpbGwgYmUgaWdub3JlZCBmb3IgdHlwZSAnJHtwcm9wcy50eXBlfScuYFxuICAgICk7XG4gIH1cbn1cblxuLyoqXG4gKiBXYXJuIGlmIGFueSBvZiB0aGUgc3BlY2lmaWVkIHByb3BlcnRpZXMgYXJlIHNldCBidXQgd2lsbCBiZSBpZ25vcmVkLlxuICogQ29udmVuaWVuY2Ugd3JhcHBlciBmb3IgY2hlY2tpbmcgbXVsdGlwbGUgcHJvcGVydGllcyBhdCBvbmNlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gd2FybklmUHJvcGVydGllc0lnbm9yZWQ8VCBleHRlbmRzIHsgdHlwZTogc3RyaW5nIH0+KFxuICBwcm9wczogVCxcbiAgcHJvcGVydGllczogc3RyaW5nW10sXG4gIGFwcGxpY2FibGVUeXBlOiBzdHJpbmcgfCBzdHJpbmdbXSxcbiAgdHlwZU5hbWU6IHN0cmluZ1xuKTogdm9pZCB7XG4gIGZvciAoY29uc3QgcHJvcGVydHkgb2YgcHJvcGVydGllcykge1xuICAgIHdhcm5JZlByb3BlcnR5SWdub3JlZChwcm9wcywgcHJvcGVydHksIGFwcGxpY2FibGVUeXBlLCB0eXBlTmFtZSk7XG4gIH1cbn1cbiJdfQ==
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fjall/components-infrastructure",
3
- "version": "0.86.1",
3
+ "version": "0.87.3",
4
4
  "bin": {
5
5
  "infrastructure": "bin/infrastructure.js"
6
6
  },
@@ -36,7 +36,7 @@
36
36
  },
37
37
  "dependencies": {
38
38
  "@aws-sdk/client-organizations": "^3.716.0",
39
- "@fjall/util": "^0.86.1",
39
+ "@fjall/util": "^0.87.3",
40
40
  "@pepperize/cdk-organizations": "^0.7.135",
41
41
  "cdk-time-sleep": "^1.0.0",
42
42
  "constructs": "^10.0.0",
@@ -45,7 +45,7 @@
45
45
  "overrides": {
46
46
  "@smithy/core": "2.5.5"
47
47
  },
48
- "gitHead": "18fcab64c8b43a0507191d418592f3cda68fe6c6",
48
+ "gitHead": "be3b6f5bee0c9d1fe50e0be4816ffd87eb07e4c4",
49
49
  "peerDependencies": {
50
50
  "aws-cdk": "^2.206.0",
51
51
  "aws-cdk-lib": "^2.206.0",
@@ -1,48 +0,0 @@
1
- import { App } from "aws-cdk-lib";
2
- import { Template } from "aws-cdk-lib/assertions";
3
- import { Stack } from "aws-cdk-lib";
4
- /**
5
- * Test utilities for CDK infrastructure testing
6
- */
7
- export declare class TestUtils {
8
- /**
9
- * Create a test app with proper environment settings
10
- */
11
- static createTestApp(): App;
12
- /**
13
- * Create a test stack within a test app
14
- */
15
- static createTestStack(app?: App): Stack;
16
- /**
17
- * Get CloudFormation template from a stack for assertions
18
- */
19
- static getTemplate(stack: Stack): Template;
20
- /**
21
- * Generate consistent snapshot from CDK stack
22
- */
23
- static getSnapshotTemplate(stack: Stack): any;
24
- /**
25
- * Clean up template for consistent snapshots by removing random IDs
26
- */
27
- static sanitiseTemplate(template: any): any;
28
- }
29
- /**
30
- * Common test data for infrastructure patterns
31
- */
32
- export declare const TestData: {
33
- defaultTags: {
34
- "fjall:costAllocation:environment": string;
35
- "fjall:costAllocation:owner": string;
36
- };
37
- defaultAccountId: string;
38
- defaultRegion: string;
39
- vpc: {
40
- vpcId: string;
41
- };
42
- basicApp: {
43
- serviceName: string;
44
- environment: string;
45
- containerPort: number;
46
- owner: string;
47
- };
48
- };