cdk-cost-analyzer 0.1.1

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 (228) hide show
  1. package/.cdk-cost-analyzer-cache/metadata.json +12 -0
  2. package/.gitlab-ci.yml +214 -0
  3. package/.husky/pre-commit +12 -0
  4. package/.kiro/hooks/accessibility-audit.kiro.hook +18 -0
  5. package/.kiro/hooks/api-schema-validation.kiro.hook +21 -0
  6. package/.kiro/hooks/auto-test-on-save.kiro.hook +19 -0
  7. package/.kiro/hooks/cdk-synth-on-change.kiro.hook +20 -0
  8. package/.kiro/hooks/code-coverage-check.kiro.hook +14 -0
  9. package/.kiro/hooks/commit-message-helper.kiro.hook +14 -0
  10. package/.kiro/hooks/dependency-update-check.kiro.hook +14 -0
  11. package/.kiro/hooks/env-file-validation.kiro.hook +18 -0
  12. package/.kiro/hooks/lint-and-format-on-save.kiro.hook +21 -0
  13. package/.kiro/hooks/mcp-config-validation.kiro.hook +17 -0
  14. package/.kiro/hooks/mcp-server-test.kiro.hook +14 -0
  15. package/.kiro/hooks/performance-analysis.kiro.hook +14 -0
  16. package/.kiro/hooks/readme-spell-check.kiro.hook +14 -0
  17. package/.kiro/hooks/security-scan-on-dependency-change.kiro.hook +21 -0
  18. package/.kiro/hooks/translation-update.kiro.hook +18 -0
  19. package/.kiro/hooks/update-documentation.kiro.hook +18 -0
  20. package/.kiro/settings/mcp.json +20 -0
  21. package/.kiro/specs/cdk-cost-analyzer/design.md +620 -0
  22. package/.kiro/specs/cdk-cost-analyzer/requirements.md +183 -0
  23. package/.kiro/specs/cdk-cost-analyzer/tasks.md +357 -0
  24. package/.kiro/specs/github-actions-ci/design.md +281 -0
  25. package/.kiro/specs/github-actions-ci/requirements.md +86 -0
  26. package/.kiro/specs/github-actions-ci/tasks.md +115 -0
  27. package/.kiro/specs/nlb-calculator-test-coverage/design.md +190 -0
  28. package/.kiro/specs/nlb-calculator-test-coverage/requirements.md +84 -0
  29. package/.kiro/specs/nlb-calculator-test-coverage/tasks.md +150 -0
  30. package/.kiro/specs/production-readiness/design.md +1213 -0
  31. package/.kiro/specs/production-readiness/requirements.md +312 -0
  32. package/.kiro/specs/production-readiness/tasks.md +269 -0
  33. package/.kiro/specs/repository-cleanup/design.md +283 -0
  34. package/.kiro/specs/repository-cleanup/requirements.md +74 -0
  35. package/.kiro/specs/repository-cleanup/tasks.md +64 -0
  36. package/.kiro/steering/aws-cli-best-practices.md +41 -0
  37. package/.kiro/steering/cdk-best-practices.md +49 -0
  38. package/.kiro/steering/development-standards.md +54 -0
  39. package/.kiro/steering/docker-best-practices.md +34 -0
  40. package/.kiro/steering/documentation-style.md +151 -0
  41. package/.kiro/steering/git-best-practices.md +37 -0
  42. package/.kiro/steering/mcp-best-practices.md +95 -0
  43. package/.kiro/steering/python-best-practices.md +48 -0
  44. package/.kiro/steering/react-best-practices.md +44 -0
  45. package/.kiro/steering/security-best-practices.md +41 -0
  46. package/.kiro/steering/testing-best-practices.md +59 -0
  47. package/.kiro/steering/typescript-best-practices.md +40 -0
  48. package/CHANGELOG.md +49 -0
  49. package/CONTRIBUTING.md +258 -0
  50. package/LICENSE +19 -0
  51. package/README.md +480 -0
  52. package/SECURITY.md +117 -0
  53. package/dist/api/index.d.ts +11 -0
  54. package/dist/api/index.js +65 -0
  55. package/dist/api/types.d.ts +15 -0
  56. package/dist/api/types.js +3 -0
  57. package/dist/cli/index.d.ts +2 -0
  58. package/dist/cli/index.js +262 -0
  59. package/dist/config/ConfigManager.d.ts +40 -0
  60. package/dist/config/ConfigManager.js +238 -0
  61. package/dist/config/index.d.ts +2 -0
  62. package/dist/config/index.js +19 -0
  63. package/dist/config/types.d.ts +72 -0
  64. package/dist/config/types.js +15 -0
  65. package/dist/diff/DiffEngine.d.ts +7 -0
  66. package/dist/diff/DiffEngine.js +73 -0
  67. package/dist/diff/index.d.ts +2 -0
  68. package/dist/diff/index.js +21 -0
  69. package/dist/diff/types.d.ts +20 -0
  70. package/dist/diff/types.js +3 -0
  71. package/dist/integrations/GitLabIntegration.d.ts +7 -0
  72. package/dist/integrations/GitLabIntegration.js +45 -0
  73. package/dist/integrations/index.d.ts +2 -0
  74. package/dist/integrations/index.js +21 -0
  75. package/dist/integrations/types.d.ts +11 -0
  76. package/dist/integrations/types.js +13 -0
  77. package/dist/parser/TemplateParser.d.ts +8 -0
  78. package/dist/parser/TemplateParser.js +75 -0
  79. package/dist/parser/index.d.ts +2 -0
  80. package/dist/parser/index.js +22 -0
  81. package/dist/parser/types.d.ts +30 -0
  82. package/dist/parser/types.js +3 -0
  83. package/dist/pipeline/PipelineOrchestrator.d.ts +23 -0
  84. package/dist/pipeline/PipelineOrchestrator.js +191 -0
  85. package/dist/pipeline/index.d.ts +2 -0
  86. package/dist/pipeline/index.js +19 -0
  87. package/dist/pipeline/types.d.ts +41 -0
  88. package/dist/pipeline/types.js +13 -0
  89. package/dist/pricing/CacheManager.d.ts +75 -0
  90. package/dist/pricing/CacheManager.js +195 -0
  91. package/dist/pricing/PricingClient.d.ts +17 -0
  92. package/dist/pricing/PricingClient.js +122 -0
  93. package/dist/pricing/PricingService.d.ts +16 -0
  94. package/dist/pricing/PricingService.js +149 -0
  95. package/dist/pricing/calculators/ALBCalculator.d.ts +16 -0
  96. package/dist/pricing/calculators/ALBCalculator.js +163 -0
  97. package/dist/pricing/calculators/APIGatewayCalculator.d.ts +10 -0
  98. package/dist/pricing/calculators/APIGatewayCalculator.js +177 -0
  99. package/dist/pricing/calculators/CloudFrontCalculator.d.ts +59 -0
  100. package/dist/pricing/calculators/CloudFrontCalculator.js +151 -0
  101. package/dist/pricing/calculators/DynamoDBCalculator.d.ts +9 -0
  102. package/dist/pricing/calculators/DynamoDBCalculator.js +146 -0
  103. package/dist/pricing/calculators/EC2Calculator.d.ts +7 -0
  104. package/dist/pricing/calculators/EC2Calculator.js +80 -0
  105. package/dist/pricing/calculators/ECSCalculator.d.ts +9 -0
  106. package/dist/pricing/calculators/ECSCalculator.js +116 -0
  107. package/dist/pricing/calculators/ElastiCacheCalculator.d.ts +8 -0
  108. package/dist/pricing/calculators/ElastiCacheCalculator.js +106 -0
  109. package/dist/pricing/calculators/LambdaCalculator.d.ts +13 -0
  110. package/dist/pricing/calculators/LambdaCalculator.js +111 -0
  111. package/dist/pricing/calculators/NLBCalculator.d.ts +16 -0
  112. package/dist/pricing/calculators/NLBCalculator.js +138 -0
  113. package/dist/pricing/calculators/NatGatewayCalculator.d.ts +12 -0
  114. package/dist/pricing/calculators/NatGatewayCalculator.js +116 -0
  115. package/dist/pricing/calculators/RDSCalculator.d.ts +9 -0
  116. package/dist/pricing/calculators/RDSCalculator.js +103 -0
  117. package/dist/pricing/calculators/S3Calculator.d.ts +8 -0
  118. package/dist/pricing/calculators/S3Calculator.js +68 -0
  119. package/dist/pricing/calculators/VPCEndpointCalculator.d.ts +12 -0
  120. package/dist/pricing/calculators/VPCEndpointCalculator.js +129 -0
  121. package/dist/pricing/index.d.ts +10 -0
  122. package/dist/pricing/index.js +37 -0
  123. package/dist/pricing/types.d.ts +53 -0
  124. package/dist/pricing/types.js +22 -0
  125. package/dist/releasetag.txt +1 -0
  126. package/dist/reporter/Reporter.d.ts +18 -0
  127. package/dist/reporter/Reporter.js +412 -0
  128. package/dist/reporter/index.d.ts +2 -0
  129. package/dist/reporter/index.js +21 -0
  130. package/dist/reporter/types.d.ts +72 -0
  131. package/dist/reporter/types.js +3 -0
  132. package/dist/synthesis/SynthesisOrchestrator.d.ts +26 -0
  133. package/dist/synthesis/SynthesisOrchestrator.js +243 -0
  134. package/dist/synthesis/index.d.ts +2 -0
  135. package/dist/synthesis/index.js +19 -0
  136. package/dist/synthesis/types.d.ts +17 -0
  137. package/dist/synthesis/types.js +13 -0
  138. package/dist/threshold/ThresholdEnforcer.d.ts +29 -0
  139. package/dist/threshold/ThresholdEnforcer.js +143 -0
  140. package/dist/threshold/index.d.ts +2 -0
  141. package/dist/threshold/index.js +19 -0
  142. package/dist/threshold/types.d.ts +15 -0
  143. package/dist/threshold/types.js +17 -0
  144. package/docs/CALCULATORS.md +820 -0
  145. package/docs/CI_CD.md +608 -0
  146. package/docs/CONFIGURATION.md +407 -0
  147. package/docs/DEVELOPMENT.md +387 -0
  148. package/docs/RELEASE.md +223 -0
  149. package/docs/TROUBLESHOOTING.md +847 -0
  150. package/examples/.cdk-cost-analyzer.yml +85 -0
  151. package/examples/.gitlab-ci.yml +125 -0
  152. package/examples/api-usage.js +26 -0
  153. package/examples/complex/base.json +16 -0
  154. package/examples/complex/target.json +29 -0
  155. package/examples/monorepo/.gitlab-ci.yml +251 -0
  156. package/examples/monorepo/README.md +341 -0
  157. package/examples/monorepo/package.json +27 -0
  158. package/examples/monorepo/packages/backend-infra/.cdk-cost-analyzer.yml +34 -0
  159. package/examples/monorepo/packages/backend-infra/bin/app.ts +16 -0
  160. package/examples/monorepo/packages/backend-infra/cdk.json +7 -0
  161. package/examples/monorepo/packages/backend-infra/lib/backend-stack.ts +128 -0
  162. package/examples/monorepo/packages/backend-infra/package.json +30 -0
  163. package/examples/monorepo/packages/backend-infra/tsconfig.json +11 -0
  164. package/examples/monorepo/packages/data-infra/.cdk-cost-analyzer.yml +38 -0
  165. package/examples/monorepo/packages/data-infra/bin/app.ts +16 -0
  166. package/examples/monorepo/packages/data-infra/cdk.json +7 -0
  167. package/examples/monorepo/packages/data-infra/lib/data-stack.ts +121 -0
  168. package/examples/monorepo/packages/data-infra/package.json +30 -0
  169. package/examples/monorepo/packages/data-infra/tsconfig.json +11 -0
  170. package/examples/monorepo/packages/frontend-infra/.cdk-cost-analyzer.yml +31 -0
  171. package/examples/monorepo/packages/frontend-infra/bin/app.ts +16 -0
  172. package/examples/monorepo/packages/frontend-infra/cdk.json +7 -0
  173. package/examples/monorepo/packages/frontend-infra/lib/frontend-stack.ts +60 -0
  174. package/examples/monorepo/packages/frontend-infra/package.json +30 -0
  175. package/examples/monorepo/packages/frontend-infra/tsconfig.json +11 -0
  176. package/examples/monorepo/tsconfig.json +35 -0
  177. package/examples/multi-stack/.cdk-cost-analyzer.yml +72 -0
  178. package/examples/multi-stack/.gitlab-ci.yml +184 -0
  179. package/examples/multi-stack/README.md +279 -0
  180. package/examples/multi-stack/bin/app.ts +36 -0
  181. package/examples/multi-stack/cdk.json +72 -0
  182. package/examples/multi-stack/lib/compute-stack.ts +128 -0
  183. package/examples/multi-stack/lib/networking-stack.ts +69 -0
  184. package/examples/multi-stack/lib/storage-stack.ts +141 -0
  185. package/examples/multi-stack/package-lock.json +4437 -0
  186. package/examples/multi-stack/package.json +42 -0
  187. package/examples/multi-stack/tsconfig.json +34 -0
  188. package/examples/simple/base.json +8 -0
  189. package/examples/simple/target.json +14 -0
  190. package/examples/single-stack/.NVP +0 -0
  191. package/examples/single-stack/.cdk-cost-analyzer.yml +52 -0
  192. package/examples/single-stack/.gitlab-ci.yml +126 -0
  193. package/examples/single-stack/README.md +184 -0
  194. package/examples/single-stack/UeK +0 -0
  195. package/examples/single-stack/bin/app.ts +16 -0
  196. package/examples/single-stack/cdk.json +72 -0
  197. package/examples/single-stack/lib/infrastructure-stack.ts +119 -0
  198. package/examples/single-stack/package-lock.json +4443 -0
  199. package/examples/single-stack/package.json +38 -0
  200. package/examples/single-stack/tsconfig.json +34 -0
  201. package/package.json +139 -0
  202. package/test-cdk-project/README-COMPUTE.md +141 -0
  203. package/test-cdk-project/README.md +95 -0
  204. package/test-cdk-project/app-with-compute.js +102 -0
  205. package/test-cdk-project/app.js +81 -0
  206. package/test-cdk-project/cdk-compute.json +3 -0
  207. package/test-cdk-project/cdk.context.json +7 -0
  208. package/test-cdk-project/cdk.json +3 -0
  209. package/test-cdk-project/cdk.out/TestStack.assets.json +21 -0
  210. package/test-cdk-project/cdk.out/TestStack.template.json +115 -0
  211. package/test-cdk-project/cdk.out/cdk.out +1 -0
  212. package/test-cdk-project/cdk.out/manifest.json +503 -0
  213. package/test-cdk-project/cdk.out/tree.json +1 -0
  214. package/test-cdk-project/cdk.out.base/TestStack.assets.json +21 -0
  215. package/test-cdk-project/cdk.out.base/TestStack.template.json +115 -0
  216. package/test-cdk-project/cdk.out.base/cdk.out +1 -0
  217. package/test-cdk-project/cdk.out.base/manifest.json +503 -0
  218. package/test-cdk-project/cdk.out.base/tree.json +1 -0
  219. package/test-cdk-project/cdk.out.target/TestStack.assets.json +21 -0
  220. package/test-cdk-project/cdk.out.target/TestStack.template.json +183 -0
  221. package/test-cdk-project/cdk.out.target/cdk.out +1 -0
  222. package/test-cdk-project/cdk.out.target/manifest.json +521 -0
  223. package/test-cdk-project/cdk.out.target/tree.json +1 -0
  224. package/test-cdk-project/package-lock.json +422 -0
  225. package/test-cdk-project/package.json +17 -0
  226. package/tools/workflows/README.md +102 -0
  227. package/tools/workflows/validate-workflows.js +109 -0
  228. package/tools/workflows/workflow-utils.ts +181 -0
@@ -0,0 +1,191 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.PipelineOrchestrator = void 0;
37
+ const fs = __importStar(require("fs/promises"));
38
+ const types_1 = require("./types");
39
+ const ConfigManager_1 = require("../config/ConfigManager");
40
+ const DiffEngine_1 = require("../diff/DiffEngine");
41
+ const TemplateParser_1 = require("../parser/TemplateParser");
42
+ const PricingService_1 = require("../pricing/PricingService");
43
+ const Reporter_1 = require("../reporter/Reporter");
44
+ const SynthesisOrchestrator_1 = require("../synthesis/SynthesisOrchestrator");
45
+ const ThresholdEnforcer_1 = require("../threshold/ThresholdEnforcer");
46
+ class PipelineOrchestrator {
47
+ configManager;
48
+ synthesisOrchestrator;
49
+ thresholdEnforcer;
50
+ constructor() {
51
+ this.configManager = new ConfigManager_1.ConfigManager();
52
+ this.synthesisOrchestrator = new SynthesisOrchestrator_1.SynthesisOrchestrator();
53
+ this.thresholdEnforcer = new ThresholdEnforcer_1.ThresholdEnforcer();
54
+ }
55
+ /**
56
+ * Run complete pipeline analysis
57
+ */
58
+ async runPipelineAnalysis(options) {
59
+ try {
60
+ // 1. Load configuration
61
+ const config = await this.configManager.loadConfig(options.configPath);
62
+ // 2. Determine template paths
63
+ let baseTemplatePath;
64
+ let targetTemplatePath;
65
+ let synthesisInfo;
66
+ if (options.synthesize && options.cdkAppPath) {
67
+ // Synthesize both branches
68
+ const synthResult = await this.synthesizeBothBranches(options.cdkAppPath, config, options.outputPath);
69
+ baseTemplatePath = synthResult.baseTemplatePath;
70
+ targetTemplatePath = synthResult.targetTemplatePath;
71
+ synthesisInfo = synthResult.synthesisInfo;
72
+ }
73
+ else {
74
+ // Use provided template paths
75
+ if (!options.baseTemplate || !options.targetTemplate) {
76
+ throw new types_1.PipelineError('Either provide template paths or enable synthesis with cdkAppPath', 'configuration');
77
+ }
78
+ baseTemplatePath = options.baseTemplate;
79
+ targetTemplatePath = options.targetTemplate;
80
+ }
81
+ // 3. Analyze costs
82
+ const region = options.region || config.synthesis?.context?.region || 'eu-central-1';
83
+ const costAnalysis = await this.analyzeCosts(baseTemplatePath, targetTemplatePath, region, config);
84
+ // 4. Evaluate thresholds
85
+ const thresholdStatus = this.thresholdEnforcer.evaluateThreshold(costAnalysis.totalDelta, costAnalysis.addedResources, costAnalysis.modifiedResources, config.thresholds, options.environment);
86
+ // 5. Build config summary
87
+ const configSummary = this.buildConfigSummary(config, options);
88
+ return {
89
+ costAnalysis,
90
+ thresholdStatus,
91
+ synthesisInfo,
92
+ configUsed: configSummary,
93
+ };
94
+ }
95
+ catch (error) {
96
+ if (error instanceof types_1.PipelineError) {
97
+ throw error;
98
+ }
99
+ throw new types_1.PipelineError(`Pipeline failed: ${error instanceof Error ? error.message : String(error)}`, 'unknown');
100
+ }
101
+ }
102
+ /**
103
+ * Synthesize both base and target branches
104
+ */
105
+ async synthesizeBothBranches(cdkAppPath, config, outputPath) {
106
+ // For now, just synthesize the current branch
107
+ // In a full implementation, this would checkout branches and synthesize each
108
+ const result = await this.synthesisOrchestrator.synthesize({
109
+ cdkAppPath,
110
+ outputPath: outputPath || config.synthesis?.outputPath,
111
+ context: config.synthesis?.context,
112
+ customCommand: config.synthesis?.customCommand,
113
+ });
114
+ if (!result.success) {
115
+ throw new types_1.PipelineError(`CDK synthesis failed: ${result.error}`, 'synthesis');
116
+ }
117
+ // For simplicity, use the first template for both base and target
118
+ // In production, you'd synthesize different branches
119
+ return {
120
+ baseTemplatePath: result.templatePaths[0],
121
+ targetTemplatePath: result.templatePaths[0],
122
+ synthesisInfo: {
123
+ baseStackCount: result.stackNames.length,
124
+ targetStackCount: result.stackNames.length,
125
+ baseSynthesisTime: result.duration,
126
+ targetSynthesisTime: result.duration,
127
+ },
128
+ };
129
+ }
130
+ /**
131
+ * Analyze costs between two templates
132
+ */
133
+ async analyzeCosts(baseTemplatePath, targetTemplatePath, region, config) {
134
+ const parser = new TemplateParser_1.TemplateParser();
135
+ const diffEngine = new DiffEngine_1.DiffEngine();
136
+ const pricingService = new PricingService_1.PricingService(region, config.usageAssumptions, config.exclusions?.resourceTypes, config.cache);
137
+ const reporter = new Reporter_1.Reporter();
138
+ // Read templates
139
+ const baseTemplateContent = await fs.readFile(baseTemplatePath, 'utf-8');
140
+ const targetTemplateContent = await fs.readFile(targetTemplatePath, 'utf-8');
141
+ // Parse templates
142
+ const baseTemplateObj = parser.parse(baseTemplateContent);
143
+ const targetTemplateObj = parser.parse(targetTemplateContent);
144
+ // Diff templates
145
+ const diff = diffEngine.diff(baseTemplateObj, targetTemplateObj);
146
+ // Calculate cost delta
147
+ const costDelta = await pricingService.getCostDelta(diff, region);
148
+ // Generate report
149
+ const summary = reporter.generateReport(costDelta, 'text');
150
+ return {
151
+ totalDelta: costDelta.totalDelta,
152
+ currency: costDelta.currency,
153
+ addedResources: costDelta.addedCosts,
154
+ removedResources: costDelta.removedCosts,
155
+ modifiedResources: costDelta.modifiedCosts,
156
+ summary,
157
+ };
158
+ }
159
+ /**
160
+ * Build configuration summary
161
+ */
162
+ buildConfigSummary(config, options) {
163
+ const summary = {
164
+ synthesisEnabled: !!options.synthesize,
165
+ };
166
+ if (options.configPath) {
167
+ summary.configPath = options.configPath;
168
+ }
169
+ if (config.thresholds) {
170
+ const thresholds = options.environment && config.thresholds.environments?.[options.environment]
171
+ ? config.thresholds.environments[options.environment]
172
+ : config.thresholds.default;
173
+ if (thresholds) {
174
+ summary.thresholds = {
175
+ warning: thresholds.warning,
176
+ error: thresholds.error,
177
+ environment: options.environment,
178
+ };
179
+ }
180
+ }
181
+ if (config.usageAssumptions) {
182
+ summary.usageAssumptions = config.usageAssumptions;
183
+ }
184
+ if (config.exclusions?.resourceTypes) {
185
+ summary.excludedResourceTypes = config.exclusions.resourceTypes;
186
+ }
187
+ return summary;
188
+ }
189
+ }
190
+ exports.PipelineOrchestrator = PipelineOrchestrator;
191
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUGlwZWxpbmVPcmNoZXN0cmF0b3IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcGlwZWxpbmUvUGlwZWxpbmVPcmNoZXN0cmF0b3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsZ0RBQWtDO0FBQ2xDLG1DQUF3RjtBQUN4RiwyREFBd0Q7QUFDeEQsbURBQWdEO0FBQ2hELDZEQUEwRDtBQUMxRCw4REFBMkQ7QUFDM0QsbURBQWdEO0FBQ2hELDhFQUEyRTtBQUMzRSxzRUFBbUU7QUFFbkUsTUFBYSxvQkFBb0I7SUFDdkIsYUFBYSxDQUFnQjtJQUM3QixxQkFBcUIsQ0FBd0I7SUFDN0MsaUJBQWlCLENBQW9CO0lBRTdDO1FBQ0UsSUFBSSxDQUFDLGFBQWEsR0FBRyxJQUFJLDZCQUFhLEVBQUUsQ0FBQztRQUN6QyxJQUFJLENBQUMscUJBQXFCLEdBQUcsSUFBSSw2Q0FBcUIsRUFBRSxDQUFDO1FBQ3pELElBQUksQ0FBQyxpQkFBaUIsR0FBRyxJQUFJLHFDQUFpQixFQUFFLENBQUM7SUFDbkQsQ0FBQztJQUVEOztPQUVHO0lBQ0gsS0FBSyxDQUFDLG1CQUFtQixDQUFDLE9BQXdCO1FBQ2hELElBQUksQ0FBQztZQUNILHdCQUF3QjtZQUN4QixNQUFNLE1BQU0sR0FBRyxNQUFNLElBQUksQ0FBQyxhQUFhLENBQUMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUMsQ0FBQztZQUV2RSw4QkFBOEI7WUFDOUIsSUFBSSxnQkFBd0IsQ0FBQztZQUM3QixJQUFJLGtCQUEwQixDQUFDO1lBQy9CLElBQUksYUFBYSxDQUFDO1lBRWxCLElBQUksT0FBTyxDQUFDLFVBQVUsSUFBSSxPQUFPLENBQUMsVUFBVSxFQUFFLENBQUM7Z0JBQzdDLDJCQUEyQjtnQkFDM0IsTUFBTSxXQUFXLEdBQUcsTUFBTSxJQUFJLENBQUMsc0JBQXNCLENBQ25ELE9BQU8sQ0FBQyxVQUFVLEVB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QUFFLFVBQVUsQ0FBQyxLQUFLO29CQUN2QixXQUFXLEVBQUUsT0FBTyxDQUFDLFdBQVc7aUJBQ2pDLENBQUM7WUFDSixDQUFDO1FBQ0gsQ0FBQztRQUVELElBQUksTUFBTSxDQUFDLGdCQUFnQixFQUFFLENBQUM7WUFDNUIsT0FBTyxDQUFDLGdCQUFnQixHQUFHLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQztRQUNyRCxDQUFDO1FBRUQsSUFBSSxNQUFNLENBQUMsVUFBVSxFQUFFLGFBQWEsRUFBRSxDQUFDO1lBQ3JDLE9BQU8sQ0FBQyxxQkFBcUIsR0FBRyxNQUFNLENBQUMsVUFBVSxDQUFDLGFBQWEsQ0FBQztRQUNsRSxDQUFDO1FBRUQsT0FBTyxPQUFPLENBQUM7SUFDakIsQ0FBQztDQUNGO0FBaE5ELG9EQWdOQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIGZzIGZyb20gJ2ZzL3Byb21pc2VzJztcbmltcG9ydCB7IFBpcGVsaW5lT3B0aW9ucywgUGlwZWxpbmVSZXN1bHQsIFBpcGVsaW5lRXJyb3IsIENvbmZpZ1N1bW1hcnkgfSBmcm9tICcuL3R5cGVzJztcbmltcG9ydCB7IENvbmZpZ01hbmFnZXIgfSBmcm9tICcuLi9jb25maWcvQ29uZmlnTWFuYWdlcic7XG5pbXBvcnQgeyBEaWZmRW5naW5lIH0gZnJvbSAnLi4vZGlmZi9EaWZmRW5naW5lJztcbmltcG9ydCB7IFRlbXBsYXRlUGFyc2VyIH0gZnJvbSAnLi4vcGFyc2VyL1RlbXBsYXRlUGFyc2VyJztcbmltcG9ydCB7IFByaWNpbmdTZXJ2aWNlIH0gZnJvbSAnLi4vcHJpY2luZy9QcmljaW5nU2VydmljZSc7XG5pbXBvcnQgeyBSZXBvcnRlciB9IGZyb20gJy4uL3JlcG9ydGVyL1JlcG9ydGVyJztcbmltcG9ydCB7IFN5bnRoZXNpc09yY2hlc3RyYXRvciB9IGZyb20gJy4uL3N5bnRoZXNpcy9TeW50aGVzaXNPcmNoZXN0cmF0b3InO1xuaW1wb3J0IHsgVGhyZXNob2xkRW5mb3JjZXIgfSBmcm9tICcuLi90aHJlc2hvbGQvVGhyZXNob2xkRW5mb3JjZXInO1xuXG5leHBvcnQgY2xhc3MgUGlwZWxpbmVPcmNoZXN0cmF0b3Ige1xuICBwcml2YXRlIGNvbmZpZ01hbmFnZXI6IENvbmZpZ01hbmFnZXI7XG4gIHByaXZhdGUgc3ludGhlc2lzT3JjaGVzdHJhdG9yOiBTeW50aGVzaXNPcmNoZXN0cmF0b3I7XG4gIHByaXZhdGUgdGhyZXNob2xkRW5mb3JjZXI6IFRocmVzaG9sZEVuZm9yY2VyO1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHRoaXMuY29uZmlnTWFuYWdlciA9IG5ldyBDb25maWdNYW5hZ2VyKCk7XG4gICAgdGhpcy5zeW50aGVzaXNPcmNoZXN0cmF0b3IgPSBuZXcgU3ludGhlc2lzT3JjaGVzdHJhdG9yKCk7XG4gICAgdGhpcy50aHJlc2hvbGRFbmZvcmNlciA9IG5ldyBUaHJlc2hvbGRFbmZvcmNlcigpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJ1biBjb21wbGV0ZSBwaXBlbGluZSBhbmFseXNpc1xuICAgKi9cbiAgYXN5bmMgcnVuUGlwZWxpbmVBbmFseXNpcyhvcHRpb25zOiBQaXBlbGluZU9wdGlvbnMpOiBQcm9taXNlPFBpcGVsaW5lUmVzdWx0PiB7XG4gICAgdHJ5IHtcbiAgICAgIC8vIDEuIExvYWQgY29uZmlndXJhdGlvblxuICAgICAgY29uc3QgY29uZmlnID0gYXdhaXQgdGhpcy5jb25maWdNYW5hZ2VyLmxvYWRDb25maWcob3B0aW9ucy5jb25maWdQYXRoKTtcblxuICAgICAgLy8gMi4gRGV0ZXJtaW5lIHRlbXBsYXRlIHBhdGhzXG4gICAgICBsZXQgYmFzZVRlbXBsYXRlUGF0aDogc3RyaW5nO1xuICAgICAgbGV0IHRhcmdldFRlbXBsYXRlUGF0aDogc3RyaW5nO1xuICAgICAgbGV0IHN5bnRoZXNpc0luZm87XG5cbiAgICAgIGlmIChvcHRpb25zLnN5bnRoZXNpemUgJiYgb3B0aW9ucy5jZGtBcHBQYXRoKSB7XG4gICAgICAgIC8vIFN5bnRoZXNpemUgYm90aCBicmFuY2hlc1xuICAgICAgICBjb25zdCBzeW50aFJlc3VsdCA9IGF3YWl0IHRoaXMuc3ludGhlc2l6ZUJvdGhCcmFuY2hlcyhcbiAgICAgICAgICBvcHRpb25zLmNka0FwcFBhdGgsXG4gICAgICAgICAgY29uZmlnLFxuICAgICAgICAgIG9wdGlvbnMub3V0cHV0UGF0aCxcbiAgICAgICAgKTtcbiAgICAgICAgYmFzZVRlbXBsYXRlUGF0aCA9IHN5bnRoUmVzdWx0LmJhc2VUZW1wbGF0ZVBhdGg7XG4gICAgICAgIHRhcmdldFRlbXBsYXRlUGF0aCA9IHN5bnRoUmVzdWx0LnRhcmdldFRlbXBsYXRlUGF0aDtcbiAgICAgICAgc3ludGhlc2lzSW5mbyA9IHN5bnRoUmVzdWx0LnN5bnRoZXNpc0luZm87XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBVc2UgcHJvdmlkZWQgdGVtcGxhdGUgcGF0aHNcbiAgICAgICAgaWYgKCFvcHRpb25zLmJhc2VUZW1wbGF0ZSB8fCAhb3B0aW9ucy50YXJnZXRUZW1wbGF0ZSkge1xuICAgICAgICAgIHRocm93IG5ldyBQaXBlbGluZUVycm9yKFxuICAgICAgICAgICAgJ0VpdGhlciBwcm92aWRlIHRlbXBsYXRlIHBhdGhzIG9yIGVuYWJsZSBzeW50aGVzaXMgd2l0aCBjZGtBcHBQYXRoJyxcbiAgICAgICAgICAgICdjb25maWd1cmF0aW9uJyxcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICAgIGJhc2VUZW1wbGF0ZVBhdGggPSBvcHRpb25zLmJhc2VUZW1wbGF0ZTtcbiAgICAgICAgdGFyZ2V0VGVtcGxhdGVQYXRoID0gb3B0aW9ucy50YXJnZXRUZW1wbGF0ZTtcbiAgICAgIH1cblxuICAgICAgLy8gMy4gQW5hbHl6ZSBjb3N0c1xuICAgICAgY29uc3QgcmVnaW9uID0gb3B0aW9ucy5yZWdpb24gfHwgY29uZmlnLnN5bnRoZXNpcz8uY29udGV4dD8ucmVnaW9uIHx8ICdldS1jZW50cmFsLTEnO1xuICAgICAgY29uc3QgY29zdEFuYWx5c2lzID0gYXdhaXQgdGhpcy5hbmFseXplQ29zdHMoXG4gICAgICAgIGJhc2VUZW1wbGF0ZVBhdGgsXG4gICAgICAgIHRhcmdldFRlbXBsYXRlUGF0aCxcbiAgICAgICAgcmVnaW9uLFxuICAgICAgICBjb25maWcsXG4gICAgICApO1xuXG4gICAgICAvLyA0LiBFdmFsdWF0ZSB0aHJlc2hvbGRzXG4gICAgICBjb25zdCB0aHJlc2hvbGRTdGF0dXMgPSB0aGlzLnRocmVzaG9sZEVuZm9yY2VyLmV2YWx1YXRlVGhyZXNob2xkKFxuICAgICAgICBjb3N0QW5hbHlzaXMudG90YWxEZWx0YSxcbiAgICAgICAgY29zdEFuYWx5c2lzLmFkZGVkUmVzb3VyY2VzLFxuICAgICAgICBjb3N0QW5hbHlzaXMubW9kaWZpZWRSZXNvdXJjZXMsXG4gICAgICAgIGNvbmZpZy50aHJlc2hvbGRzLFxuICAgICAgICBvcHRpb25zLmVudmlyb25tZW50LFxuICAgICAgKTtcblxuICAgICAgLy8gNS4gQnVpbGQgY29uZmlnIHN1bW1hcnlcbiAgICAgIGNvbnN0IGNvbmZpZ1N1bW1hcnkgPSB0aGlzLmJ1aWxkQ29uZmlnU3VtbWFyeShjb25maWcsIG9wdGlvbnMpO1xuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBjb3N0QW5hbHlzaXMsXG4gICAgICAgIHRocmVzaG9sZFN0YXR1cyxcbiAgICAgICAgc3ludGhlc2lzSW5mbyxcbiAgICAgICAgY29uZmlnVXNlZDogY29uZmlnU3VtbWFyeSxcbiAgICAgIH07XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIFBpcGVsaW5lRXJyb3IpIHtcbiAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICB9XG4gICAgICB0aHJvdyBuZXcgUGlwZWxpbmVFcnJvcihcbiAgICAgICAgYFBpcGVsaW5lIGZhaWxlZDogJHtlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IubWVzc2FnZSA6IFN0cmluZyhlcnJvcil9YCxcbiAgICAgICAgJ3Vua25vd24nLFxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogU3ludGhlc2l6ZSBib3RoIGJhc2UgYW5kIHRhcmdldCBicmFuY2hlc1xuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBzeW50aGVzaXplQm90aEJyYW5jaGVzKFxuICAgIGNka0FwcFBhdGg6IHN0cmluZyxcbiAgICBjb25maWc6IGFueSxcbiAgICBvdXRwdXRQYXRoPzogc3RyaW5nLFxuICApOiBQcm9taXNlPHtcbiAgICAgIGJhc2VUZW1wbGF0ZVBhdGg6IHN0cmluZztcbiAgICAgIHRhcmdldFRlbXBsYXRlUGF0aDogc3RyaW5nO1xuICAgICAgc3ludGhlc2lzSW5mbzogYW55O1xuICAgIH0+IHtcbiAgICAvLyBGb3Igbm93LCBqdXN0IHN5bnRoZXNpemUgdGhlIGN1cnJlbnQgYnJhbmNoXG4gICAgLy8gSW4gYSBmdWxsIGltcGxlbWVudGF0aW9uLCB0aGlzIHdvdWxkIGNoZWNrb3V0IGJyYW5jaGVzIGFuZCBzeW50aGVzaXplIGVhY2hcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB0aGlzLnN5bnRoZXNpc09yY2hlc3RyYXRvci5zeW50aGVzaXplKHtcbiAgICAgIGNka0FwcFBhdGgsXG4gICAgICBvdXRwdXRQYXRoOiBvdXRwdXRQYXRoIHx8IGNvbmZpZy5zeW50aGVzaXM/Lm91dHB1dFBhdGgsXG4gICAgICBjb250ZXh0OiBjb25maWcuc3ludGhlc2lzPy5jb250ZXh0LFxuICAgICAgY3VzdG9tQ29tbWFuZDogY29uZmlnLnN5bnRoZXNpcz8uY3VzdG9tQ29tbWFuZCxcbiAgICB9KTtcblxuICAgIGlmICghcmVzdWx0LnN1Y2Nlc3MpIHtcbiAgICAgIHRocm93IG5ldyBQaXBlbGluZUVycm9yKFxuICAgICAgICBgQ0RLIHN5bnRoZXNpcyBmYWlsZWQ6ICR7cmVzdWx0LmVycm9yfWAsXG4gICAgICAgICdzeW50aGVzaXMnLFxuICAgICAgKTtcbiAgICB9XG5cbiAgICAvLyBGb3Igc2ltcGxpY2l0eSwgdXNlIHRoZSBmaXJzdCB0ZW1wbGF0ZSBmb3IgYm90aCBiYXNlIGFuZCB0YXJnZXRcbiAgICAvLyBJbiBwcm9kdWN0aW9uLCB5b3UnZCBzeW50aGVzaXplIGRpZmZlcmVudCBicmFuY2hlc1xuICAgIHJldHVybiB7XG4gICAgICBiYXNlVGVtcGxhdGVQYXRoOiByZXN1bHQudGVtcGxhdGVQYXRoc1swXSxcbiAgICAgIHRhcmdldFRlbXBsYXRlUGF0aDogcmVzdWx0LnRlbXBsYXRlUGF0aHNbMF0sXG4gICAgICBzeW50aGVzaXNJbmZvOiB7XG4gICAgICAgIGJhc2VTdGFja0NvdW50OiByZXN1bHQuc3RhY2tOYW1lcy5sZW5ndGgsXG4gICAgICAgIHRhcmdldFN0YWNrQ291bnQ6IHJlc3VsdC5zdGFja05hbWVzLmxlbmd0aCxcbiAgICAgICAgYmFzZVN5bnRoZXNpc1RpbWU6IHJlc3VsdC5kdXJhdGlvbixcbiAgICAgICAgdGFyZ2V0U3ludGhlc2lzVGltZTogcmVzdWx0LmR1cmF0aW9uLFxuICAgICAgfSxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIEFuYWx5emUgY29zdHMgYmV0d2VlbiB0d28gdGVtcGxhdGVzXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGFuYWx5emVDb3N0cyhcbiAgICBiYXNlVGVtcGxhdGVQYXRoOiBzdHJpbmcsXG4gICAgdGFyZ2V0VGVtcGxhdGVQYXRoOiBzdHJpbmcsXG4gICAgcmVnaW9uOiBzdHJpbmcsXG4gICAgY29uZmlnOiBhbnksXG4gICk6IFByb21pc2U8YW55PiB7XG4gICAgY29uc3QgcGFyc2VyID0gbmV3IFRlbXBsYXRlUGFyc2VyKCk7XG4gICAgY29uc3QgZGlmZkVuZ2luZSA9IG5ldyBEaWZmRW5naW5lKCk7XG4gICAgY29uc3QgcHJpY2luZ1NlcnZpY2UgPSBuZXcgUHJpY2luZ1NlcnZpY2UoXG4gICAgICByZWdpb24sXG4gICAgICBjb25maWcudXNhZ2VBc3N1bXB0aW9ucyxcbiAgICAgIGNvbmZpZy5leGNsdXNpb25zPy5yZXNvdXJjZVR5cGVzLFxuICAgICAgY29uZmlnLmNhY2hlLFxuICAgICk7XG4gICAgY29uc3QgcmVwb3J0ZXIgPSBuZXcgUmVwb3J0ZXIoKTtcblxuICAgIC8vIFJlYWQgdGVtcGxhdGVzXG4gICAgY29uc3QgYmFzZVRlbXBsYXRlQ29udGVudCA9IGF3YWl0IGZzLnJlYWRGaWxlKGJhc2VUZW1wbGF0ZVBhdGgsICd1dGYtOCcpO1xuICAgIGNvbnN0IHRhcmdldFRlbXBsYXRlQ29udGVudCA9IGF3YWl0IGZzLnJlYWRGaWxlKHRhcmdldFRlbXBsYXRlUGF0aCwgJ3V0Zi04Jyk7XG5cbiAgICAvLyBQYXJzZSB0ZW1wbGF0ZXNcbiAgICBjb25zdCBiYXNlVGVtcGxhdGVPYmogPSBwYXJzZXIucGFyc2UoYmFzZVRlbXBsYXRlQ29udGVudCk7XG4gICAgY29uc3QgdGFyZ2V0VGVtcGxhdGVPYmogPSBwYXJzZXIucGFyc2UodGFyZ2V0VGVtcGxhdGVDb250ZW50KTtcblxuICAgIC8vIERpZmYgdGVtcGxhdGVzXG4gICAgY29uc3QgZGlmZiA9IGRpZmZFbmdpbmUuZGlmZihiYXNlVGVtcGxhdGVPYmosIHRhcmdldFRlbXBsYXRlT2JqKTtcblxuICAgIC8vIENhbGN1bGF0ZSBjb3N0IGRlbHRhXG4gICAgY29uc3QgY29zdERlbHRhID0gYXdhaXQgcHJpY2luZ1NlcnZpY2UuZ2V0Q29zdERlbHRhKGRpZmYsIHJlZ2lvbik7XG5cbiAgICAvLyBHZW5lcmF0ZSByZXBvcnRcbiAgICBjb25zdCBzdW1tYXJ5ID0gcmVwb3J0ZXIuZ2VuZXJhdGVSZXBvcnQoY29zdERlbHRhLCAndGV4dCcpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIHRvdGFsRGVsdGE6IGNvc3REZWx0YS50b3RhbERlbHRhLFxuICAgICAgY3VycmVuY3k6IGNvc3REZWx0YS5jdXJyZW5jeSxcbiAgICAgIGFkZGVkUmVzb3VyY2VzOiBjb3N0RGVsdGEuYWRkZWRDb3N0cyxcbiAgICAgIHJlbW92ZWRSZXNvdXJjZXM6IGNvc3REZWx0YS5yZW1vdmVkQ29zdHMsXG4gICAgICBtb2RpZmllZFJlc291cmNlczogY29zdERlbHRhLm1vZGlmaWVkQ29zdHMsXG4gICAgICBzdW1tYXJ5LFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogQnVpbGQgY29uZmlndXJhdGlvbiBzdW1tYXJ5XG4gICAqL1xuICBwcml2YXRlIGJ1aWxkQ29uZmlnU3VtbWFyeShjb25maWc6IGFueSwgb3B0aW9uczogUGlwZWxpbmVPcHRpb25zKTogQ29uZmlnU3VtbWFyeSB7XG4gICAgY29uc3Qgc3VtbWFyeTogQ29uZmlnU3VtbWFyeSA9IHtcbiAgICAgIHN5bnRoZXNpc0VuYWJsZWQ6ICEhb3B0aW9ucy5zeW50aGVzaXplLFxuICAgIH07XG5cbiAgICBpZiAob3B0aW9ucy5jb25maWdQYXRoKSB7XG4gICAgICBzdW1tYXJ5LmNvbmZpZ1BhdGggPSBvcHRpb25zLmNvbmZpZ1BhdGg7XG4gICAgfVxuXG4gICAgaWYgKGNvbmZpZy50aHJlc2hvbGRzKSB7XG4gICAgICBjb25zdCB0aHJlc2hvbGRzID0gb3B0aW9ucy5lbnZpcm9ubWVudCAmJiBjb25maWcudGhyZXNob2xkcy5lbnZpcm9ubWVudHM/LltvcHRpb25zLmVudmlyb25tZW50XVxuICAgICAgICA/IGNvbmZpZy50aHJlc2hvbGRzLmVudmlyb25tZW50c1tvcHRpb25zLmVudmlyb25tZW50XVxuICAgICAgICA6IGNvbmZpZy50aHJlc2hvbGRzLmRlZmF1bHQ7XG5cbiAgICAgIGlmICh0aHJlc2hvbGRzKSB7XG4gICAgICAgIHN1bW1hcnkudGhyZXNob2xkcyA9IHtcbiAgICAgICAgICB3YXJuaW5nOiB0aHJlc2hvbGRzLndhcm5pbmcsXG4gICAgICAgICAgZXJyb3I6IHRocmVzaG9sZHMuZXJyb3IsXG4gICAgICAgICAgZW52aXJvbm1lbnQ6IG9wdGlvbnMuZW52aXJvbm1lbnQsXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGNvbmZpZy51c2FnZUFzc3VtcHRpb25zKSB7XG4gICAgICBzdW1tYXJ5LnVzYWdlQXNzdW1wdGlvbnMgPSBjb25maWcudXNhZ2VBc3N1bXB0aW9ucztcbiAgICB9XG5cbiAgICBpZiAoY29uZmlnLmV4Y2x1c2lvbnM/LnJlc291cmNlVHlwZXMpIHtcbiAgICAgIHN1bW1hcnkuZXhjbHVkZWRSZXNvdXJjZVR5cGVzID0gY29uZmlnLmV4Y2x1c2lvbnMucmVzb3VyY2VUeXBlcztcbiAgICB9XG5cbiAgICByZXR1cm4gc3VtbWFyeTtcbiAgfVxufVxuIl19
@@ -0,0 +1,2 @@
1
+ export * from './PipelineOrchestrator';
2
+ export * from './types';
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./PipelineOrchestrator"), exports);
18
+ __exportStar(require("./types"), exports);
19
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcGlwZWxpbmUvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLHlEQUF1QztBQUN2QywwQ0FBd0IiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgKiBmcm9tICcuL1BpcGVsaW5lT3JjaGVzdHJhdG9yJztcbmV4cG9ydCAqIGZyb20gJy4vdHlwZXMnO1xuIl19
@@ -0,0 +1,41 @@
1
+ import { CostAnalysisResult } from '../api/types';
2
+ import { ThresholdEvaluation } from '../threshold/types';
3
+ export interface PipelineOptions {
4
+ baseTemplate?: string;
5
+ targetTemplate?: string;
6
+ baseBranch?: string;
7
+ targetBranch?: string;
8
+ cdkAppPath?: string;
9
+ outputPath?: string;
10
+ configPath?: string;
11
+ region?: string;
12
+ synthesize?: boolean;
13
+ environment?: string;
14
+ }
15
+ export interface PipelineResult {
16
+ costAnalysis: CostAnalysisResult;
17
+ thresholdStatus: ThresholdEvaluation;
18
+ synthesisInfo?: SynthesisInfo;
19
+ configUsed: ConfigSummary;
20
+ }
21
+ export interface SynthesisInfo {
22
+ baseStackCount: number;
23
+ targetStackCount: number;
24
+ baseSynthesisTime: number;
25
+ targetSynthesisTime: number;
26
+ }
27
+ export interface ConfigSummary {
28
+ configPath?: string;
29
+ thresholds?: {
30
+ warning?: number;
31
+ error?: number;
32
+ environment?: string;
33
+ };
34
+ usageAssumptions?: Record<string, unknown>;
35
+ excludedResourceTypes?: string[];
36
+ synthesisEnabled: boolean;
37
+ }
38
+ export declare class PipelineError extends Error {
39
+ stage: string;
40
+ constructor(message: string, stage: string);
41
+ }
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PipelineError = void 0;
4
+ class PipelineError extends Error {
5
+ stage;
6
+ constructor(message, stage) {
7
+ super(message);
8
+ this.stage = stage;
9
+ this.name = 'PipelineError';
10
+ }
11
+ }
12
+ exports.PipelineError = PipelineError;
13
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcGlwZWxpbmUvdHlwZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBMENBLE1BQWEsYUFBYyxTQUFRLEtBQUs7SUFDRjtJQUFwQyxZQUFZLE9BQWUsRUFBUyxLQUFhO1FBQy9DLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQztRQURtQixVQUFLLEdBQUwsS0FBSyxDQUFRO1FBRS9DLElBQUksQ0FBQyxJQUFJLEdBQUcsZUFBZSxDQUFDO0lBQzlCLENBQUM7Q0FDRjtBQUxELHNDQUtDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29zdEFuYWx5c2lzUmVzdWx0IH0gZnJvbSAnLi4vYXBpL3R5cGVzJztcbmltcG9ydCB7IFRocmVzaG9sZEV2YWx1YXRpb24gfSBmcm9tICcuLi90aHJlc2hvbGQvdHlwZXMnO1xuXG5leHBvcnQgaW50ZXJmYWNlIFBpcGVsaW5lT3B0aW9ucyB7XG4gIGJhc2VUZW1wbGF0ZT86IHN0cmluZztcbiAgdGFyZ2V0VGVtcGxhdGU/OiBzdHJpbmc7XG4gIGJhc2VCcmFuY2g/OiBzdHJpbmc7XG4gIHRhcmdldEJyYW5jaD86IHN0cmluZztcbiAgY2RrQXBwUGF0aD86IHN0cmluZztcbiAgb3V0cHV0UGF0aD86IHN0cmluZztcbiAgY29uZmlnUGF0aD86IHN0cmluZztcbiAgcmVnaW9uPzogc3RyaW5nO1xuICBzeW50aGVzaXplPzogYm9vbGVhbjtcbiAgZW52aXJvbm1lbnQ/OiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUGlwZWxpbmVSZXN1bHQge1xuICBjb3N0QW5hbHlzaXM6IENvc3RBbmFseXNpc1Jlc3VsdDtcbiAgdGhyZXNob2xkU3RhdHVzOiBUaHJlc2hvbGRFdmFsdWF0aW9uO1xuICBzeW50aGVzaXNJbmZvPzogU3ludGhlc2lzSW5mbztcbiAgY29uZmlnVXNlZDogQ29uZmlnU3VtbWFyeTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBTeW50aGVzaXNJbmZvIHtcbiAgYmFzZVN0YWNrQ291bnQ6IG51bWJlcjtcbiAgdGFyZ2V0U3RhY2tDb3VudDogbnVtYmVyO1xuICBiYXNlU3ludGhlc2lzVGltZTogbnVtYmVyO1xuICB0YXJnZXRTeW50aGVzaXNUaW1lOiBudW1iZXI7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ29uZmlnU3VtbWFyeSB7XG4gIGNvbmZpZ1BhdGg/OiBzdHJpbmc7XG4gIHRocmVzaG9sZHM/OiB7XG4gICAgd2FybmluZz86IG51bWJlcjtcbiAgICBlcnJvcj86IG51bWJlcjtcbiAgICBlbnZpcm9ubWVudD86IHN0cmluZztcbiAgfTtcbiAgdXNhZ2VBc3N1bXB0aW9ucz86IFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xuICBleGNsdWRlZFJlc291cmNlVHlwZXM/OiBzdHJpbmdbXTtcbiAgc3ludGhlc2lzRW5hYmxlZDogYm9vbGVhbjtcbn1cblxuZXhwb3J0IGNsYXNzIFBpcGVsaW5lRXJyb3IgZXh0ZW5kcyBFcnJvciB7XG4gIGNvbnN0cnVjdG9yKG1lc3NhZ2U6IHN0cmluZywgcHVibGljIHN0YWdlOiBzdHJpbmcpIHtcbiAgICBzdXBlcihtZXNzYWdlKTtcbiAgICB0aGlzLm5hbWUgPSAnUGlwZWxpbmVFcnJvcic7XG4gIH1cbn1cbiJdfQ==
@@ -0,0 +1,75 @@
1
+ import { PriceQueryParams } from './types';
2
+ export interface CachedPriceEntry {
3
+ price: number;
4
+ timestamp: number;
5
+ }
6
+ export interface CacheMetadata {
7
+ entries: Record<string, CachedPriceEntry>;
8
+ }
9
+ /**
10
+ * Manages persistent caching of pricing data to reduce AWS API calls
11
+ * and improve performance across pipeline runs.
12
+ */
13
+ export declare class CacheManager {
14
+ private cacheDir;
15
+ private cacheDurationMs;
16
+ private metadata;
17
+ private metadataPath;
18
+ /**
19
+ * Creates a new CacheManager instance
20
+ * @param cacheDir Directory to store cache files (default: .cdk-cost-analyzer-cache)
21
+ * @param cacheDurationHours Duration in hours before cache entries expire (default: 24)
22
+ */
23
+ constructor(cacheDir?: string, cacheDurationHours?: number);
24
+ /**
25
+ * Retrieves a cached price if it exists and is still fresh
26
+ * @param params Price query parameters
27
+ * @returns Cached price or null if not found or expired
28
+ */
29
+ getCachedPrice(params: PriceQueryParams): number | null;
30
+ /**
31
+ * Stores a price in the cache with current timestamp
32
+ * @param params Price query parameters
33
+ * @param price Price value to cache
34
+ */
35
+ setCachedPrice(params: PriceQueryParams, price: number): void;
36
+ /**
37
+ * Checks if a cached price exists and is still fresh
38
+ * @param params Price query parameters
39
+ * @returns true if fresh cache entry exists
40
+ */
41
+ hasFreshCache(params: PriceQueryParams): boolean;
42
+ /**
43
+ * Clears all cached entries
44
+ */
45
+ clearCache(): void;
46
+ /**
47
+ * Gets cache statistics
48
+ * @returns Object with cache statistics
49
+ */
50
+ getCacheStats(): {
51
+ totalEntries: number;
52
+ freshEntries: number;
53
+ staleEntries: number;
54
+ };
55
+ /**
56
+ * Removes stale cache entries
57
+ */
58
+ pruneStaleEntries(): void;
59
+ /**
60
+ * Generates a cache key from price query parameters
61
+ */
62
+ private getCacheKey;
63
+ /**
64
+ * Ensures the cache directory exists
65
+ */
66
+ private ensureCacheDirectory;
67
+ /**
68
+ * Loads cache metadata from disk
69
+ */
70
+ private loadMetadata;
71
+ /**
72
+ * Saves cache metadata to disk
73
+ */
74
+ private saveMetadata;
75
+ }
@@ -0,0 +1,195 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.CacheManager = void 0;
37
+ const fs = __importStar(require("fs"));
38
+ const path = __importStar(require("path"));
39
+ /**
40
+ * Manages persistent caching of pricing data to reduce AWS API calls
41
+ * and improve performance across pipeline runs.
42
+ */
43
+ class CacheManager {
44
+ cacheDir;
45
+ cacheDurationMs;
46
+ metadata;
47
+ metadataPath;
48
+ /**
49
+ * Creates a new CacheManager instance
50
+ * @param cacheDir Directory to store cache files (default: .cdk-cost-analyzer-cache)
51
+ * @param cacheDurationHours Duration in hours before cache entries expire (default: 24)
52
+ */
53
+ constructor(cacheDir = '.cdk-cost-analyzer-cache', cacheDurationHours = 24) {
54
+ this.cacheDir = cacheDir;
55
+ this.cacheDurationMs = cacheDurationHours * 60 * 60 * 1000;
56
+ this.metadataPath = path.join(this.cacheDir, 'metadata.json');
57
+ this.metadata = { entries: {} };
58
+ this.ensureCacheDirectory();
59
+ this.loadMetadata();
60
+ }
61
+ /**
62
+ * Retrieves a cached price if it exists and is still fresh
63
+ * @param params Price query parameters
64
+ * @returns Cached price or null if not found or expired
65
+ */
66
+ getCachedPrice(params) {
67
+ const cacheKey = this.getCacheKey(params);
68
+ const entry = this.metadata.entries[cacheKey];
69
+ if (!entry) {
70
+ return null;
71
+ }
72
+ const now = Date.now();
73
+ const age = now - entry.timestamp;
74
+ if (age > this.cacheDurationMs) {
75
+ // Cache entry is stale
76
+ delete this.metadata.entries[cacheKey];
77
+ this.saveMetadata();
78
+ return null;
79
+ }
80
+ return entry.price;
81
+ }
82
+ /**
83
+ * Stores a price in the cache with current timestamp
84
+ * @param params Price query parameters
85
+ * @param price Price value to cache
86
+ */
87
+ setCachedPrice(params, price) {
88
+ const cacheKey = this.getCacheKey(params);
89
+ this.metadata.entries[cacheKey] = {
90
+ price,
91
+ timestamp: Date.now(),
92
+ };
93
+ this.saveMetadata();
94
+ }
95
+ /**
96
+ * Checks if a cached price exists and is still fresh
97
+ * @param params Price query parameters
98
+ * @returns true if fresh cache entry exists
99
+ */
100
+ hasFreshCache(params) {
101
+ return this.getCachedPrice(params) !== null;
102
+ }
103
+ /**
104
+ * Clears all cached entries
105
+ */
106
+ clearCache() {
107
+ this.metadata = { entries: {} };
108
+ this.saveMetadata();
109
+ }
110
+ /**
111
+ * Gets cache statistics
112
+ * @returns Object with cache statistics
113
+ */
114
+ getCacheStats() {
115
+ const now = Date.now();
116
+ let freshEntries = 0;
117
+ let staleEntries = 0;
118
+ for (const entry of Object.values(this.metadata.entries)) {
119
+ const age = now - entry.timestamp;
120
+ if (age <= this.cacheDurationMs) {
121
+ freshEntries++;
122
+ }
123
+ else {
124
+ staleEntries++;
125
+ }
126
+ }
127
+ return {
128
+ totalEntries: Object.keys(this.metadata.entries).length,
129
+ freshEntries,
130
+ staleEntries,
131
+ };
132
+ }
133
+ /**
134
+ * Removes stale cache entries
135
+ */
136
+ pruneStaleEntries() {
137
+ const now = Date.now();
138
+ const freshEntries = {};
139
+ for (const [key, entry] of Object.entries(this.metadata.entries)) {
140
+ const age = now - entry.timestamp;
141
+ if (age <= this.cacheDurationMs) {
142
+ freshEntries[key] = entry;
143
+ }
144
+ }
145
+ this.metadata.entries = freshEntries;
146
+ this.saveMetadata();
147
+ }
148
+ /**
149
+ * Generates a cache key from price query parameters
150
+ */
151
+ getCacheKey(params) {
152
+ const filterStr = params.filters
153
+ .map((f) => `${f.field}:${f.value}`)
154
+ .sort()
155
+ .join('|');
156
+ return `${params.serviceCode}:${params.region}:${filterStr}`;
157
+ }
158
+ /**
159
+ * Ensures the cache directory exists
160
+ */
161
+ ensureCacheDirectory() {
162
+ if (!fs.existsSync(this.cacheDir)) {
163
+ fs.mkdirSync(this.cacheDir, { recursive: true });
164
+ }
165
+ }
166
+ /**
167
+ * Loads cache metadata from disk
168
+ */
169
+ loadMetadata() {
170
+ try {
171
+ if (fs.existsSync(this.metadataPath)) {
172
+ const data = fs.readFileSync(this.metadataPath, 'utf-8');
173
+ this.metadata = JSON.parse(data);
174
+ }
175
+ }
176
+ catch (error) {
177
+ // If metadata is corrupted, start fresh
178
+ this.metadata = { entries: {} };
179
+ }
180
+ }
181
+ /**
182
+ * Saves cache metadata to disk
183
+ */
184
+ saveMetadata() {
185
+ try {
186
+ fs.writeFileSync(this.metadataPath, JSON.stringify(this.metadata, null, 2), 'utf-8');
187
+ }
188
+ catch (error) {
189
+ // Silently fail if we can't write cache - not critical
190
+ console.warn(`Failed to save cache metadata: ${error instanceof Error ? error.message : String(error)}`);
191
+ }
192
+ }
193
+ }
194
+ exports.CacheManager = CacheManager;
195
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQ2FjaGVNYW5hZ2VyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3ByaWNpbmcvQ2FjaGVNYW5hZ2VyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLHVDQUF5QjtBQUN6QiwyQ0FBNkI7QUFZN0I7OztHQUdHO0FBQ0gsTUFBYSxZQUFZO0lBQ2YsUUFBUSxDQUFTO0lBQ2pCLGVBQWUsQ0FBUztJQUN4QixRQUFRLENBQWdCO0lBQ3hCLFlBQVksQ0FBUztJQUU3Qjs7OztPQUlHO0lBQ0gsWUFDRSxXQUFtQiwwQkFBMEIsRUFDN0MscUJBQTZCLEVBQUU7UUFFL0IsSUFBSSxDQUFDLFFBQVEsR0FBRyxRQUFRLENBQUM7UUFDekIsSUFBSSxDQUFDLGVBQWUsR0FBRyxrQkFBa0IsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQztRQUMzRCxJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxlQUFlLENBQUMsQ0FBQztRQUM5RCxJQUFJLENBQUMsUUFBUSxHQUFHLEVBQUUsT0FBTyxFQUFFLEVBQUUsRUFBRSxDQUFDO1FBQ2hDLElBQUksQ0FBQyxvQkFBb0IsRUFBRSxDQUFDO1FBQzVCLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztJQUN0QixDQUFDO0lBRUQ7Ozs7T0FJRztJQUNILGNBQWMsQ0FBQyxNQUF3QjtRQUNyQyxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQzFDLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBRTlDLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUNYLE9BQU8sSUFBSSxDQUFDO1FBQ2QsQ0FBQztRQUVELE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQztRQUN2QixNQUFNLEdBQUcsR0FBRyxHQUFHLEdBQUcsS0FBSyxDQUFDLFNBQVMsQ0FBQztRQUVsQyxJQUFJLEdBQUcsR0FBRyxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7WUFDL0IsdUJBQXVCO1lBQ3ZCLE9BQU8sSUFBSSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDdkMsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1lBQ3BCLE9BQU8sSUFBSSxDQUFDO1FBQ2QsQ0FBQztRQUVELE9BQU8sS0FBSyxDQUFDLEtBQUssQ0FBQztJQUNyQixDQUFDO0lBRUQ7Ozs7T0FJRztJQUNILGNBQWMsQ0FBQyxNQUF3QixFQUFFLEtBQWE7UUFDcEQsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUMxQyxJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsR0FBRztZQUNoQyxLQUFLO1lBQ0wsU0FBUyxFQUFFLElBQUksQ0FBQyxHQUFHLEVBQUU7U0FDdEIsQ0FBQztRQUNGLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztJQUN0QixDQUFDO0lBRUQ7Ozs7T0FJRztJQUNILGFBQWEsQ0FBQyxNQUF3QjtRQUNwQyxPQUFPLElBQUksQ0FBQyxjQUFjLENBQUMsTUFBTSxDQUFDLEtBQUssSUFBSSxDQUFDO0lBQzlDLENBQUM7SUFFRDs7T0FFRztJQUNILFVBQVU7UUFDUixJQUFJLENBQUMsUUFBUSxHQUFHLEVBQUUsT0FBTyxFQUFFLEVBQUUsRUFBRSxDQUFDO1FBQ2hDLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztJQUN0QixDQUFDO0lBRUQ7OztPQUdHO0lBQ0gsYUFBYTtRQUtYLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQztRQUN2QixJQUFJLFlBQVksR0FBRyxDQUFDLENBQUM7UUFDckIsSUFBSSxZQUFZLEdBQUcsQ0FBQyxDQUFDO1FBRXJCLEtBQUssTUFBTSxLQUFLLElBQUksTUFBTSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7WUFDekQsTUFBTSxHQUFHLEdBQUcsR0FBRyxHQUFHLEtBQUssQ0FBQyxTQUFTLENBQUM7WUFDbEMsSUFBSSxHQUFHLElBQUksSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDO2dCQUNoQyxZQUFZLEVBQUUsQ0FBQztZQUNqQixDQUFDO2lCQUFNLENBQUM7Z0JBQ04sWUFBWSxFQUFFLENBQUM7WUFDakIsQ0FBQztRQUNILENBQUM7UUFFRCxPQUFPO1lBQ0wsWUFBWSxFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxNQUFNO1lBQ3ZELFlBQVk7WUFDWixZQUFZO1NBQ2IsQ0FBQztJQUNKLENBQUM7SUFFRDs7T0FFRztJQUNILGlCQUFpQjtRQUNmLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQztRQUN2QixNQUFNLFlBQVksR0FBcUMsRUFBRSxDQUFDO1FBRTFELEtBQUssTUFBTSxDQUFDLEdBQUcsRUFBRSxLQUFLLENBQUMsSUFBSSxNQUFNLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztZQUNqRSxNQUFNLEdBQUcsR0FBRyxHQUFHLEdBQUcsS0FBSyxDQUFDLFNBQVMsQ0FBQztZQUNsQyxJQUFJLEdBQUcsSUFBSSxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7Z0JBQ2hDLFlBQVksQ0FBQyxHQUFHLENBQUMsR0FBRyxLQUFLLENBQUM7WUFDNUIsQ0FBQztRQUNILENBQUM7UUFFRCxJQUFJLENBQUMsUUFBUSxDQUFDLE9BQU8sR0FBRyxZQUFZLENBQUM7UUFDckMsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO0lBQ3RCLENBQUM7SUFFRDs7T0FFRztJQUNLLFdBQVcsQ0FBQyxNQUF3QjtRQUMxQyxNQUFNLFNBQVMsR0FBRyxNQUFNLENBQUMsT0FBTzthQUM3QixHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEtBQUssSUFBSSxDQUFDLENBQUMsS0FBSyxFQUFFLENBQUM7YUFDbkMsSUFBSSxFQUFFO2FBQ04sSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ2IsT0FBTyxHQUFHLE1BQU0sQ0FBQyxXQUFXLElBQUksTUFBTSxDQUFDLE1BQU0sSUFBSSxTQUFTLEVBQUUsQ0FBQztJQUMvRCxDQUFDO0lBRUQ7O09BRUc7SUFDSyxvQkFBb0I7UUFDMUIsSUFBSSxDQUFDLEVBQUUsQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUM7WUFDbEMsRUFBRSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7UUFDbkQsQ0FBQztJQUNILENBQUM7SUFFRDs7T0FFRztJQUNLLFlBQVk7UUFDbEIsSUFBSSxDQUFDO1lBQ0gsSUFBSSxFQUFFLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsRUFBRSxDQUFDO2dCQUNyQyxNQUFNLElBQUksR0FBRyxFQUFFLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxZQUFZLEVBQUUsT0FBTyxDQUFDLENBQUM7Z0JBQ3pELElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUNuQyxDQUFDO1FBQ0gsQ0FBQztRQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7WUFDZix3Q0FBd0M7WUFDeEMsSUFBSSxDQUFDLFFBQVEsR0FBRyxFQUFFLE9BQU8sRUFBRSxFQUFFLEVBQUUsQ0FBQztRQUNsQyxDQUFDO0lBQ0gsQ0FBQztJQUVEOztPQUVHO0lBQ0ssWUFBWTtRQUNsQixJQUFJLENBQUM7WUFDSCxFQUFFLENBQUMsYUFBYSxDQUNkLElBQUksQ0FBQyxZQUFZLEVBQ2pCLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDLEVBQ3RDLE9BQU8sQ0FDUixDQUFDO1FBQ0osQ0FBQztRQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7WUFDZix1REFBdUQ7WUFDdkQsT0FBTyxDQUFDLElBQUksQ0FDVixrQ0FBa0MsS0FBSyxZQUFZLEtBQUssQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQzNGLENBQUM7UUFDSixDQUFDO0lBQ0gsQ0FBQztDQUNGO0FBbkxELG9DQW1MQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIGZzIGZyb20gJ2ZzJztcbmltcG9ydCAqIGFzIHBhdGggZnJvbSAncGF0aCc7XG5pbXBvcnQgeyBQcmljZVF1ZXJ5UGFyYW1zIH0gZnJvbSAnLi90eXBlcyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ2FjaGVkUHJpY2VFbnRyeSB7XG4gIHByaWNlOiBudW1iZXI7XG4gIHRpbWVzdGFtcDogbnVtYmVyO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIENhY2hlTWV0YWRhdGEge1xuICBlbnRyaWVzOiBSZWNvcmQ8c3RyaW5nLCBDYWNoZWRQcmljZUVudHJ5Pjtcbn1cblxuLyoqXG4gKiBNYW5hZ2VzIHBlcnNpc3RlbnQgY2FjaGluZyBvZiBwcmljaW5nIGRhdGEgdG8gcmVkdWNlIEFXUyBBUEkgY2FsbHNcbiAqIGFuZCBpbXByb3ZlIHBlcmZvcm1hbmNlIGFjcm9zcyBwaXBlbGluZSBydW5zLlxuICovXG5leHBvcnQgY2xhc3MgQ2FjaGVNYW5hZ2VyIHtcbiAgcHJpdmF0ZSBjYWNoZURpcjogc3RyaW5nO1xuICBwcml2YXRlIGNhY2hlRHVyYXRpb25NczogbnVtYmVyO1xuICBwcml2YXRlIG1ldGFkYXRhOiBDYWNoZU1ldGFkYXRhO1xuICBwcml2YXRlIG1ldGFkYXRhUGF0aDogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBDcmVhdGVzIGEgbmV3IENhY2hlTWFuYWdlciBpbnN0YW5jZVxuICAgKiBAcGFyYW0gY2FjaGVEaXIgRGlyZWN0b3J5IHRvIHN0b3JlIGNhY2hlIGZpbGVzIChkZWZhdWx0OiAuY2RrLWNvc3QtYW5hbHl6ZXItY2FjaGUpXG4gICAqIEBwYXJhbSBjYWNoZUR1cmF0aW9uSG91cnMgRHVyYXRpb24gaW4gaG91cnMgYmVmb3JlIGNhY2hlIGVudHJpZXMgZXhwaXJlIChkZWZhdWx0OiAyNClcbiAgICovXG4gIGNvbnN0cnVjdG9yKFxuICAgIGNhY2hlRGlyOiBzdHJpbmcgPSAnLmNkay1jb3N0LWFuYWx5emVyLWNhY2hlJyxcbiAgICBjYWNoZUR1cmF0aW9uSG91cnM6IG51bWJlciA9IDI0LFxuICApIHtcbiAgICB0aGlzLmNhY2hlRGlyID0gY2FjaGVEaXI7XG4gICAgdGhpcy5jYWNoZUR1cmF0aW9uTXMgPSBjYWNoZUR1cmF0aW9uSG91cnMgKiA2MCAqIDYwICogMTAwMDtcbiAgICB0aGlzLm1ldGFkYXRhUGF0aCA9IHBhdGguam9pbih0aGlzLmNhY2hlRGlyLCAnbWV0YWRhdGEuanNvbicpO1xuICAgIHRoaXMubWV0YWRhdGEgPSB7IGVudHJpZXM6IHt9IH07XG4gICAgdGhpcy5lbnN1cmVDYWNoZURpcmVjdG9yeSgpO1xuICAgIHRoaXMubG9hZE1ldGFkYXRhKCk7XG4gIH1cblxuICAvKipcbiAgICogUmV0cmlldmVzIGEgY2FjaGVkIHByaWNlIGlmIGl0IGV4aXN0cyBhbmQgaXMgc3RpbGwgZnJlc2hcbiAgICogQHBhcmFtIHBhcmFtcyBQcmljZSBxdWVyeSBwYXJhbWV0ZXJzXG4gICAqIEByZXR1cm5zIENhY2hlZCBwcmljZSBvciBudWxsIGlmIG5vdCBmb3VuZCBvciBleHBpcmVkXG4gICAqL1xuICBnZXRDYWNoZWRQcmljZShwYXJhbXM6IFByaWNlUXVlcnlQYXJhbXMpOiBudW1iZXIgfCBudWxsIHtcbiAgICBjb25zdCBjYWNoZUtleSA9IHRoaXMuZ2V0Q2FjaGVLZXkocGFyYW1zKTtcbiAgICBjb25zdCBlbnRyeSA9IHRoaXMubWV0YWRhdGEuZW50cmllc1tjYWNoZUtleV07XG5cbiAgICBpZiAoIWVudHJ5KSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBjb25zdCBub3cgPSBEYXRlLm5vdygpO1xuICAgIGNvbnN0IGFnZSA9IG5vdyAtIGVudHJ5LnRpbWVzdGFtcDtcblxuICAgIGlmIChhZ2UgPiB0aGlzLmNhY2hlRHVyYXRpb25Ncykge1xuICAgICAgLy8gQ2FjaGUgZW50cnkgaXMgc3RhbGVcbiAgICAgIGRlbGV0ZSB0aGlzLm1ldGFkYXRhLmVudHJpZXNbY2FjaGVLZXldO1xuICAgICAgdGhpcy5zYXZlTWV0YWRhdGEoKTtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIHJldHVybiBlbnRyeS5wcmljZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTdG9yZXMgYSBwcmljZSBpbiB0aGUgY2FjaGUgd2l0aCBjdXJyZW50IHRpbWVzdGFtcFxuICAgKiBAcGFyYW0gcGFyYW1zIFByaWNlIHF1ZXJ5IHBhcmFtZXRlcnNcbiAgICogQHBhcmFtIHByaWNlIFByaWNlIHZhbHVlIHRvIGNhY2hlXG4gICAqL1xuICBzZXRDYWNoZWRQcmljZShwYXJhbXM6IFByaWNlUXVlcnlQYXJhbXMsIHByaWNlOiBudW1iZXIpOiB2b2lkIHtcbiAgICBjb25zdCBjYWNoZUtleSA9IHRoaXMuZ2V0Q2FjaGVLZXkocGFyYW1zKTtcbiAgICB0aGlzLm1ldGFkYXRhLmVudHJpZXNbY2FjaGVLZXldID0ge1xuICAgICAgcHJpY2UsXG4gICAgICB0aW1lc3RhbXA6IERhdGUubm93KCksXG4gICAgfTtcbiAgICB0aGlzLnNhdmVNZXRhZGF0YSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIENoZWNrcyBpZiBhIGNhY2hlZCBwcmljZSBleGlzdHMgYW5kIGlzIHN0aWxsIGZyZXNoXG4gICAqIEBwYXJhbSBwYXJhbXMgUHJpY2UgcXVlcnkgcGFyYW1ldGVyc1xuICAgKiBAcmV0dXJucyB0cnVlIGlmIGZyZXNoIGNhY2hlIGVudHJ5IGV4aXN0c1xuICAgKi9cbiAgaGFzRnJlc2hDYWNoZShwYXJhbXM6IFByaWNlUXVlcnlQYXJhbXMpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5nZXRDYWNoZWRQcmljZShwYXJhbXMpICE9PSBudWxsO1xuICB9XG5cbiAgLyoqXG4gICAqIENsZWFycyBhbGwgY2FjaGVkIGVudHJpZXNcbiAgICovXG4gIGNsZWFyQ2FjaGUoKTogdm9pZCB7XG4gICAgdGhpcy5tZXRhZGF0YSA9IHsgZW50cmllczoge30gfTtcbiAgICB0aGlzLnNhdmVNZXRhZGF0YSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldHMgY2FjaGUgc3RhdGlzdGljc1xuICAgKiBAcmV0dXJucyBPYmplY3Qgd2l0aCBjYWNoZSBzdGF0aXN0aWNzXG4gICAqL1xuICBnZXRDYWNoZVN0YXRzKCk6IHtcbiAgICB0b3RhbEVudHJpZXM6IG51bWJlcjtcbiAgICBmcmVzaEVudHJpZXM6IG51bWJlcjtcbiAgICBzdGFsZUVudHJpZXM6IG51bWJlcjtcbiAgfSB7XG4gICAgY29uc3Qgbm93ID0gRGF0ZS5ub3coKTtcbiAgICBsZXQgZnJlc2hFbnRyaWVzID0gMDtcbiAgICBsZXQgc3RhbGVFbnRyaWVzID0gMDtcblxuICAgIGZvciAoY29uc3QgZW50cnkgb2YgT2JqZWN0LnZhbHVlcyh0aGlzLm1ldGFkYXRhLmVudHJpZXMpKSB7XG4gICAgICBjb25zdCBhZ2UgPSBub3cgLSBlbnRyeS50aW1lc3RhbXA7XG4gICAgICBpZiAoYWdlIDw9IHRoaXMuY2FjaGVEdXJhdGlvbk1zKSB7XG4gICAgICAgIGZyZXNoRW50cmllcysrO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc3RhbGVFbnRyaWVzKys7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIHRvdGFsRW50cmllczogT2JqZWN0LmtleXModGhpcy5tZXRhZGF0YS5lbnRyaWVzKS5sZW5ndGgsXG4gICAgICBmcmVzaEVudHJpZXMsXG4gICAgICBzdGFsZUVudHJpZXMsXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZW1vdmVzIHN0YWxlIGNhY2hlIGVudHJpZXNcbiAgICovXG4gIHBydW5lU3RhbGVFbnRyaWVzKCk6IHZvaWQge1xuICAgIGNvbnN0IG5vdyA9IERhdGUubm93KCk7XG4gICAgY29uc3QgZnJlc2hFbnRyaWVzOiBSZWNvcmQ8c3RyaW5nLCBDYWNoZWRQcmljZUVudHJ5PiA9IHt9O1xuXG4gICAgZm9yIChjb25zdCBba2V5LCBlbnRyeV0gb2YgT2JqZWN0LmVudHJpZXModGhpcy5tZXRhZGF0YS5lbnRyaWVzKSkge1xuICAgICAgY29uc3QgYWdlID0gbm93IC0gZW50cnkudGltZXN0YW1wO1xuICAgICAgaWYgKGFnZSA8PSB0aGlzLmNhY2hlRHVyYXRpb25Ncykge1xuICAgICAgICBmcmVzaEVudHJpZXNba2V5XSA9IGVudHJ5O1xuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMubWV0YWRhdGEuZW50cmllcyA9IGZyZXNoRW50cmllcztcbiAgICB0aGlzLnNhdmVNZXRhZGF0YSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdlbmVyYXRlcyBhIGNhY2hlIGtleSBmcm9tIHByaWNlIHF1ZXJ5IHBhcmFtZXRlcnNcbiAgICovXG4gIHByaXZhdGUgZ2V0Q2FjaGVLZXkocGFyYW1zOiBQcmljZVF1ZXJ5UGFyYW1zKTogc3RyaW5nIHtcbiAgICBjb25zdCBmaWx0ZXJTdHIgPSBwYXJhbXMuZmlsdGVyc1xuICAgICAgLm1hcCgoZikgPT4gYCR7Zi5maWVsZH06JHtmLnZhbHVlfWApXG4gICAgICAuc29ydCgpXG4gICAgICAuam9pbignfCcpO1xuICAgIHJldHVybiBgJHtwYXJhbXMuc2VydmljZUNvZGV9OiR7cGFyYW1zLnJlZ2lvbn06JHtmaWx0ZXJTdHJ9YDtcbiAgfVxuXG4gIC8qKlxuICAgKiBFbnN1cmVzIHRoZSBjYWNoZSBkaXJlY3RvcnkgZXhpc3RzXG4gICAqL1xuICBwcml2YXRlIGVuc3VyZUNhY2hlRGlyZWN0b3J5KCk6IHZvaWQge1xuICAgIGlmICghZnMuZXhpc3RzU3luYyh0aGlzLmNhY2hlRGlyKSkge1xuICAgICAgZnMubWtkaXJTeW5jKHRoaXMuY2FjaGVEaXIsIHsgcmVjdXJzaXZlOiB0cnVlIH0pO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBMb2FkcyBjYWNoZSBtZXRhZGF0YSBmcm9tIGRpc2tcbiAgICovXG4gIHByaXZhdGUgbG9hZE1ldGFkYXRhKCk6IHZvaWQge1xuICAgIHRyeSB7XG4gICAgICBpZiAoZnMuZXhpc3RzU3luYyh0aGlzLm1ldGFkYXRhUGF0aCkpIHtcbiAgICAgICAgY29uc3QgZGF0YSA9IGZzLnJlYWRGaWxlU3luYyh0aGlzLm1ldGFkYXRhUGF0aCwgJ3V0Zi04Jyk7XG4gICAgICAgIHRoaXMubWV0YWRhdGEgPSBKU09OLnBhcnNlKGRhdGEpO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAvLyBJZiBtZXRhZGF0YSBpcyBjb3JydXB0ZWQsIHN0YXJ0IGZyZXNoXG4gICAgICB0aGlzLm1ldGFkYXRhID0geyBlbnRyaWVzOiB7fSB9O1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBTYXZlcyBjYWNoZSBtZXRhZGF0YSB0byBkaXNrXG4gICAqL1xuICBwcml2YXRlIHNhdmVNZXRhZGF0YSgpOiB2b2lkIHtcbiAgICB0cnkge1xuICAgICAgZnMud3JpdGVGaWxlU3luYyhcbiAgICAgICAgdGhpcy5tZXRhZGF0YVBhdGgsXG4gICAgICAgIEpTT04uc3RyaW5naWZ5KHRoaXMubWV0YWRhdGEsIG51bGwsIDIpLFxuICAgICAgICAndXRmLTgnLFxuICAgICAgKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgLy8gU2lsZW50bHkgZmFpbCBpZiB3ZSBjYW4ndCB3cml0ZSBjYWNoZSAtIG5vdCBjcml0aWNhbFxuICAgICAgY29uc29sZS53YXJuKFxuICAgICAgICBgRmFpbGVkIHRvIHNhdmUgY2FjaGUgbWV0YWRhdGE6ICR7ZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiBTdHJpbmcoZXJyb3IpfWAsXG4gICAgICApO1xuICAgIH1cbiAgfVxufVxuIl19
@@ -0,0 +1,17 @@
1
+ import { PricingClient as AWSPricingClient } from '@aws-sdk/client-pricing';
2
+ import { CacheManager } from './CacheManager';
3
+ import { PricingClient as IPricingClient, PriceQueryParams } from './types';
4
+ export declare class PricingClient implements IPricingClient {
5
+ private cache;
6
+ private client;
7
+ private cacheManager?;
8
+ constructor(region?: string, cacheManager?: CacheManager, awsClient?: AWSPricingClient);
9
+ /**
10
+ * Clean up resources and connections
11
+ */
12
+ destroy(): void;
13
+ getPrice(params: PriceQueryParams): Promise<number | null>;
14
+ private fetchPriceWithRetry;
15
+ private fetchPrice;
16
+ private getCacheKey;
17
+ }