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,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYXBpL3R5cGVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBSZXNvdXJjZUNvc3QsIE1vZGlmaWVkUmVzb3VyY2VDb3N0IH0gZnJvbSAnLi4vcHJpY2luZy90eXBlcyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgQW5hbHl6ZU9wdGlvbnMge1xuICBiYXNlVGVtcGxhdGU6IHN0cmluZztcbiAgdGFyZ2V0VGVtcGxhdGU6IHN0cmluZztcbiAgcmVnaW9uPzogc3RyaW5nO1xuICBmb3JtYXQ/OiAndGV4dCcgfCAnanNvbicgfCAnbWFya2Rvd24nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIENvc3RBbmFseXNpc1Jlc3VsdCB7XG4gIHRvdGFsRGVsdGE6IG51bWJlcjtcbiAgY3VycmVuY3k6IHN0cmluZztcbiAgYWRkZWRSZXNvdXJjZXM6IFJlc291cmNlQ29zdFtdO1xuICByZW1vdmVkUmVzb3VyY2VzOiBSZXNvdXJjZUNvc3RbXTtcbiAgbW9kaWZpZWRSZXNvdXJjZXM6IE1vZGlmaWVkUmVzb3VyY2VDb3N0W107XG4gIHN1bW1hcnk6IHN0cmluZztcbn1cbiJdfQ==
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
@@ -0,0 +1,262 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
+ if (k2 === undefined) k2 = k;
5
+ var desc = Object.getOwnPropertyDescriptor(m, k);
6
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
+ desc = { enumerable: true, get: function() { return m[k]; } };
8
+ }
9
+ Object.defineProperty(o, k2, desc);
10
+ }) : (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ o[k2] = m[k];
13
+ }));
14
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
15
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
16
+ }) : function(o, v) {
17
+ o["default"] = v;
18
+ });
19
+ var __importStar = (this && this.__importStar) || (function () {
20
+ var ownKeys = function(o) {
21
+ ownKeys = Object.getOwnPropertyNames || function (o) {
22
+ var ar = [];
23
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
24
+ return ar;
25
+ };
26
+ return ownKeys(o);
27
+ };
28
+ return function (mod) {
29
+ if (mod && mod.__esModule) return mod;
30
+ var result = {};
31
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
32
+ __setModuleDefault(result, mod);
33
+ return result;
34
+ };
35
+ })();
36
+ Object.defineProperty(exports, "__esModule", { value: true });
37
+ const fs = __importStar(require("fs"));
38
+ const commander_1 = require("commander");
39
+ const api_1 = require("../api");
40
+ const GitLabIntegration_1 = require("../integrations/GitLabIntegration");
41
+ const PipelineOrchestrator_1 = require("../pipeline/PipelineOrchestrator");
42
+ const program = new commander_1.Command();
43
+ program
44
+ .name('cdk-cost-analyzer')
45
+ .description('Analyze AWS CDK infrastructure changes and provide cost impact summaries')
46
+ .version('1.0.0');
47
+ // Original command for direct template comparison
48
+ program
49
+ .command('compare')
50
+ .description('Compare two CloudFormation templates')
51
+ .argument('<base>', 'Path to base CloudFormation template')
52
+ .argument('<target>', 'Path to target CloudFormation template')
53
+ .option('--region <region>', 'AWS region', 'eu-central-1')
54
+ .option('--format <format>', 'Output format: text|json|markdown', 'text')
55
+ .option('--config <path>', 'Path to configuration file')
56
+ .action(async (basePath, targetPath, options) => {
57
+ try {
58
+ if (!fs.existsSync(basePath)) {
59
+ console.error(`Error: Base template file not found: ${basePath}`);
60
+ process.exit(1);
61
+ }
62
+ if (!fs.existsSync(targetPath)) {
63
+ console.error(`Error: Target template file not found: ${targetPath}`);
64
+ process.exit(1);
65
+ }
66
+ const baseTemplate = fs.readFileSync(basePath, 'utf-8');
67
+ const targetTemplate = fs.readFileSync(targetPath, 'utf-8');
68
+ const result = await (0, api_1.analyzeCosts)({
69
+ baseTemplate,
70
+ targetTemplate,
71
+ region: options.region,
72
+ format: options.format,
73
+ });
74
+ if (options.format === 'json') {
75
+ console.log(JSON.stringify(result, null, 2));
76
+ }
77
+ else {
78
+ console.log(result.summary);
79
+ }
80
+ process.exit(0);
81
+ }
82
+ catch (error) {
83
+ if (error instanceof Error) {
84
+ console.error(`Error: ${error.message}`);
85
+ }
86
+ else {
87
+ console.error(`Error: ${String(error)}`);
88
+ }
89
+ process.exit(1);
90
+ }
91
+ });
92
+ // New pipeline command for CI/CD integration with synthesis
93
+ program
94
+ .command('pipeline')
95
+ .description('Run cost analysis in CI/CD pipeline with automatic synthesis')
96
+ .option('--base <path>', 'Path to base template (if not using synthesis)')
97
+ .option('--target <path>', 'Path to target template (if not using synthesis)')
98
+ .option('--synth', 'Enable automatic CDK synthesis')
99
+ .option('--cdk-app-path <path>', 'Path to CDK application directory')
100
+ .option('--region <region>', 'AWS region', 'eu-central-1')
101
+ .option('--config <path>', 'Path to configuration file')
102
+ .option('--environment <env>', 'Environment name for threshold selection')
103
+ .option('--format <format>', 'Output format: text|json|markdown', 'text')
104
+ .option('--post-to-gitlab', 'Post results to GitLab merge request')
105
+ .action(async (options) => {
106
+ try {
107
+ // Check AWS credentials
108
+ if (!process.env.AWS_ACCESS_KEY_ID && !process.env.AWS_PROFILE) {
109
+ console.error('Error: AWS credentials not configured');
110
+ console.error('');
111
+ console.error('Please set AWS credentials using one of:');
112
+ console.error(' - AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment variables');
113
+ console.error(' - AWS_PROFILE environment variable');
114
+ console.error(' - AWS credentials file (~/.aws/credentials)');
115
+ console.error('');
116
+ console.error('For GitLab CI, configure AWS credentials in CI/CD variables:');
117
+ console.error(' Settings > CI/CD > Variables');
118
+ console.error(' Add: AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_REGION');
119
+ process.exit(1);
120
+ }
121
+ const orchestrator = new PipelineOrchestrator_1.PipelineOrchestrator();
122
+ const result = await orchestrator.runPipelineAnalysis({
123
+ baseTemplate: options.base,
124
+ targetTemplate: options.target,
125
+ synthesize: options.synth,
126
+ cdkAppPath: options.cdkAppPath,
127
+ region: options.region,
128
+ configPath: options.config,
129
+ environment: options.environment,
130
+ });
131
+ // Display results
132
+ if (options.format === 'json') {
133
+ console.log(JSON.stringify(result, null, 2));
134
+ }
135
+ else {
136
+ console.log(result.costAnalysis.summary);
137
+ console.log('');
138
+ // Display threshold status
139
+ if (result.thresholdStatus.level !== 'none') {
140
+ console.log('='.repeat(80));
141
+ console.log('THRESHOLD STATUS');
142
+ console.log('='.repeat(80));
143
+ console.log(result.thresholdStatus.message);
144
+ console.log('');
145
+ if (result.thresholdStatus.recommendations.length > 0) {
146
+ console.log('Recommendations:');
147
+ result.thresholdStatus.recommendations.forEach((rec, i) => {
148
+ console.log(`${i + 1}. ${rec}`);
149
+ });
150
+ console.log('');
151
+ }
152
+ }
153
+ // Display config summary
154
+ if (result.configUsed.configPath || result.configUsed.thresholds) {
155
+ console.log('='.repeat(80));
156
+ console.log('CONFIGURATION');
157
+ console.log('='.repeat(80));
158
+ if (result.configUsed.configPath) {
159
+ console.log(`Config file: ${result.configUsed.configPath}`);
160
+ }
161
+ if (result.configUsed.thresholds) {
162
+ console.log(`Thresholds: warning=$${result.configUsed.thresholds.warning || 'none'}, error=$${result.configUsed.thresholds.error || 'none'}`);
163
+ if (result.configUsed.thresholds.environment) {
164
+ console.log(`Environment: ${result.configUsed.thresholds.environment}`);
165
+ }
166
+ }
167
+ if (result.configUsed.excludedResourceTypes?.length) {
168
+ console.log(`Excluded resources: ${result.configUsed.excludedResourceTypes.join(', ')}`);
169
+ }
170
+ console.log('');
171
+ }
172
+ }
173
+ // Post to GitLab if requested
174
+ if (options.postToGitlab) {
175
+ const gitlabToken = process.env.GITLAB_TOKEN || process.env.CI_JOB_TOKEN;
176
+ const projectId = process.env.CI_PROJECT_ID;
177
+ const mergeRequestIid = process.env.CI_MERGE_REQUEST_IID;
178
+ const gitlabUrl = process.env.CI_SERVER_URL;
179
+ if (!gitlabToken || !projectId || !mergeRequestIid || !gitlabUrl) {
180
+ console.error('Warning: GitLab environment variables not found. Skipping GitLab post.');
181
+ console.error('Required: CI_JOB_TOKEN, CI_PROJECT_ID, CI_MERGE_REQUEST_IID, CI_SERVER_URL');
182
+ }
183
+ else {
184
+ try {
185
+ const gitlab = new GitLabIntegration_1.GitLabIntegration({
186
+ token: gitlabToken,
187
+ apiUrl: gitlabUrl,
188
+ });
189
+ await gitlab.postMergeRequestComment(projectId, mergeRequestIid, result.costAnalysis.summary);
190
+ console.log('Results posted to GitLab merge request');
191
+ }
192
+ catch (error) {
193
+ console.error(`Warning: Failed to post to GitLab: ${error instanceof Error ? error.message : String(error)}`);
194
+ }
195
+ }
196
+ }
197
+ // Exit with appropriate code based on threshold
198
+ if (result.thresholdStatus.level === 'error' && !result.thresholdStatus.passed) {
199
+ console.error('Pipeline failed: Cost threshold exceeded');
200
+ process.exit(2);
201
+ }
202
+ process.exit(0);
203
+ }
204
+ catch (error) {
205
+ if (error instanceof Error) {
206
+ console.error(`Error: ${error.message}`);
207
+ }
208
+ else {
209
+ console.error(`Error: ${String(error)}`);
210
+ }
211
+ process.exit(1);
212
+ }
213
+ });
214
+ // Default to compare command for backward compatibility
215
+ program
216
+ .argument('[base]', 'Path to base CloudFormation template')
217
+ .argument('[target]', 'Path to target CloudFormation template')
218
+ .option('--region <region>', 'AWS region', 'eu-central-1')
219
+ .option('--format <format>', 'Output format: text|json|markdown', 'text')
220
+ .option('--config <path>', 'Path to configuration file')
221
+ .action(async (basePath, targetPath, options) => {
222
+ if (!basePath || !targetPath) {
223
+ program.help();
224
+ return;
225
+ }
226
+ try {
227
+ if (!fs.existsSync(basePath)) {
228
+ console.error(`Error: Base template file not found: ${basePath}`);
229
+ process.exit(1);
230
+ }
231
+ if (!fs.existsSync(targetPath)) {
232
+ console.error(`Error: Target template file not found: ${targetPath}`);
233
+ process.exit(1);
234
+ }
235
+ const baseTemplate = fs.readFileSync(basePath, 'utf-8');
236
+ const targetTemplate = fs.readFileSync(targetPath, 'utf-8');
237
+ const result = await (0, api_1.analyzeCosts)({
238
+ baseTemplate,
239
+ targetTemplate,
240
+ region: options?.region || 'eu-central-1',
241
+ format: options?.format || 'text',
242
+ });
243
+ if (options?.format === 'json') {
244
+ console.log(JSON.stringify(result, null, 2));
245
+ }
246
+ else {
247
+ console.log(result.summary);
248
+ }
249
+ process.exit(0);
250
+ }
251
+ catch (error) {
252
+ if (error instanceof Error) {
253
+ console.error(`Error: ${error.message}`);
254
+ }
255
+ else {
256
+ console.error(`Error: ${String(error)}`);
257
+ }
258
+ process.exit(1);
259
+ }
260
+ });
261
+ program.parse();
262
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvY2xpL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUVBLHVDQUF5QjtBQUN6Qix5Q0FBb0M7QUFDcEMsZ0NBQXNDO0FBQ3RDLHlFQUFzRTtBQUN0RSwyRUFBd0U7QUFFeEUsTUFBTSxPQUFPLEdBQUcsSUFBSSxtQkFBTyxFQUFFLENBQUM7QUFFOUIsT0FBTztLQUNKLElBQUksQ0FBQyxtQkFBbUIsQ0FBQztLQUN6QixXQUFXLENBQUMsMEVBQTBFLENBQUM7S0FDdkYsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDO0FBRXBCLGtEQUFrRDtBQUNsRCxPQUFPO0tBQ0osT0FBTyxDQUFDLFNBQVMsQ0FBQztLQUNsQixXQUFXLENBQUMsc0NBQXNDLENBQUM7S0FDbkQsUUFBUSxDQUFDLFFBQVEsRUFBRSxzQ0FBc0MsQ0FBQztLQUMxRCxRQUFRLENBQUMsVUFBVSxFQUFFLHdDQUF3QyxDQUFDO0tBQzlELE1BQU0sQ0FBQyxtQkFBbUIsRUFBRSxZQUFZLEVBQUUsY0FBYyxDQUFDO0tBQ3pELE1BQU0sQ0FBQyxtQkFBbUIsRUFBRSxtQ0FBbUMsRUFBRSxNQUFNLENBQUM7S0FDeEUsTUFBTSxDQUFDLGlCQUFpQixFQUFFLDRCQUE0QixDQUFDO0tBQ3ZELE1BQU0sQ0FBQyxLQUFLLEVBQUUsUUFBZ0IsRUFBRSxVQUFrQixFQUFFLE9BQTRELEVBQUUsRUFBRTtJQUNuSCxJQUFJLENBQUM7UUFDSCxJQUFJLENBQUMsRUFBRSxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDO1lBQzdCLE9BQU8sQ0FBQyxLQUFLLENBQUMsd0NBQXdDLFFBQVEsRUFBRSxDQUFDLENBQUM7WUFDbEUsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNsQixDQUFDO1FBRUQsSUFBSSxDQUFDLEVBQUUsQ0FB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QUNOLE9BQU8sQ0FBQyxLQUFLLENBQUMsVUFBVSxNQUFNLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQzNDLENBQUM7UUFDRCxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ2xCLENBQUM7QUFDSCxDQUFDLENBQUMsQ0FBQztBQUVMLE9BQU8sQ0FBQyxLQUFLLEVBQUUsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIiMhL3Vzci9iaW4vZW52IG5vZGVcblxuaW1wb3J0ICogYXMgZnMgZnJvbSAnZnMnO1xuaW1wb3J0IHsgQ29tbWFuZCB9IGZyb20gJ2NvbW1hbmRlcic7XG5pbXBvcnQgeyBhbmFseXplQ29zdHMgfSBmcm9tICcuLi9hcGknO1xuaW1wb3J0IHsgR2l0TGFiSW50ZWdyYXRpb24gfSBmcm9tICcuLi9pbnRlZ3JhdGlvbnMvR2l0TGFiSW50ZWdyYXRpb24nO1xuaW1wb3J0IHsgUGlwZWxpbmVPcmNoZXN0cmF0b3IgfSBmcm9tICcuLi9waXBlbGluZS9QaXBlbGluZU9yY2hlc3RyYXRvcic7XG5cbmNvbnN0IHByb2dyYW0gPSBuZXcgQ29tbWFuZCgpO1xuXG5wcm9ncmFtXG4gIC5uYW1lKCdjZGstY29zdC1hbmFseXplcicpXG4gIC5kZXNjcmlwdGlvbignQW5hbHl6ZSBBV1MgQ0RLIGluZnJhc3RydWN0dXJlIGNoYW5nZXMgYW5kIHByb3ZpZGUgY29zdCBpbXBhY3Qgc3VtbWFyaWVzJylcbiAgLnZlcnNpb24oJzEuMC4wJyk7XG5cbi8vIE9yaWdpbmFsIGNvbW1hbmQgZm9yIGRpcmVjdCB0ZW1wbGF0ZSBjb21wYXJpc29uXG5wcm9ncmFtXG4gIC5jb21tYW5kKCdjb21wYXJlJylcbiAgLmRlc2NyaXB0aW9uKCdDb21wYXJlIHR3byBDbG91ZEZvcm1hdGlvbiB0ZW1wbGF0ZXMnKVxuICAuYXJndW1lbnQoJzxiYXNlPicsICdQYXRoIHRvIGJhc2UgQ2xvdWRGb3JtYXRpb24gdGVtcGxhdGUnKVxuICAuYXJndW1lbnQoJzx0YXJnZXQ+JywgJ1BhdGggdG8gdGFyZ2V0IENsb3VkRm9ybWF0aW9uIHRlbXBsYXRlJylcbiAgLm9wdGlvbignLS1yZWdpb24gPHJlZ2lvbj4nLCAnQVdTIHJlZ2lvbicsICdldS1jZW50cmFsLTEnKVxuICAub3B0aW9uKCctLWZvcm1hdCA8Zm9ybWF0PicsICdPdXRwdXQgZm9ybWF0OiB0ZXh0fGpzb258bWFya2Rvd24nLCAndGV4dCcpXG4gIC5vcHRpb24oJy0tY29uZmlnIDxwYXRoPicsICdQYXRoIHRvIGNvbmZpZ3VyYXRpb24gZmlsZScpXG4gIC5hY3Rpb24oYXN5bmMgKGJhc2VQYXRoOiBzdHJpbmcsIHRhcmdldFBhdGg6IHN0cmluZywgb3B0aW9uczogeyByZWdpb246IHN0cmluZzsgZm9ybWF0OiBzdHJpbmc7IGNvbmZpZz86IHN0cmluZyB9KSA9PiB7XG4gICAgdHJ5IHtcbiAgICAgIGlmICghZnMuZXhpc3RzU3luYyhiYXNlUGF0aCkpIHtcbiAgICAgICAgY29uc29sZS5lcnJvcihgRXJyb3I6IEJhc2UgdGVtcGxhdGUgZmlsZSBub3QgZm91bmQ6ICR7YmFzZVBhdGh9YCk7XG4gICAgICAgIHByb2Nlc3MuZXhpdCgxKTtcbiAgICAgIH1cblxuICAgICAgaWYgKCFmcy5leGlzdHNTeW5jKHRhcmdldFBhdGgpKSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoYEVycm9yOiBUYXJnZXQgdGVtcGxhdGUgZmlsZSBub3QgZm91bmQ6ICR7dGFyZ2V0UGF0aH1gKTtcbiAgICAgICAgcHJvY2Vzcy5leGl0KDEpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBiYXNlVGVtcGxhdGUgPSBmcy5yZWFkRmlsZVN5bmMoYmFzZVBhdGgsICd1dGYtOCcpO1xuICAgICAgY29uc3QgdGFyZ2V0VGVtcGxhdGUgPSBmcy5yZWFkRmlsZVN5bmModGFyZ2V0UGF0aCwgJ3V0Zi04Jyk7XG5cbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGFuYWx5emVDb3N0cyh7XG4gICAgICAgIGJhc2VUZW1wbGF0ZSxcbiAgICAgICAgdGFyZ2V0VGVtcGxhdGUsXG4gICAgICAgIHJlZ2lvbjogb3B0aW9ucy5yZWdpb24sXG4gICAgICAgIGZvcm1hdDogb3B0aW9ucy5mb3JtYXQgYXMgJ3RleHQnIHwgJ2pzb24nIHwgJ21hcmtkb3duJyxcbiAgICAgIH0pO1xuXG4gICAgICBpZiAob3B0aW9ucy5mb3JtYXQgPT09ICdqc29uJykge1xuICAgICAgICBjb25zb2xlLmxvZyhKU09OLnN0cmluZ2lmeShyZXN1bHQsIG51bGwsIDIpKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnNvbGUubG9nKHJlc3VsdC5zdW1tYXJ5KTtcbiAgICAgIH1cblxuICAgICAgcHJvY2Vzcy5leGl0KDApO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICBjb25zb2xlLmVycm9yKGBFcnJvcjogJHtlcnJvci5tZXNzYWdlfWApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc29sZS5lcnJvcihgRXJyb3I6ICR7U3RyaW5nKGVycm9yKX1gKTtcbiAgICAgIH1cbiAgICAgIHByb2Nlc3MuZXhpdCgxKTtcbiAgICB9XG4gIH0pO1xuXG4vLyBOZXcgcGlwZWxpbmUgY29tbWFuZCBmb3IgQ0kvQ0QgaW50ZWdyYXRpb24gd2l0aCBzeW50aGVzaXNcbnByb2dyYW1cbiAgLmNvbW1hbmQoJ3BpcGVsaW5lJylcbiAgLmRlc2NyaXB0aW9uKCdSdW4gY29zdCBhbmFseXNpcyBpbiBDSS9DRCBwaXBlbGluZSB3aXRoIGF1dG9tYXRpYyBzeW50aGVzaXMnKVxuICAub3B0aW9uKCctLWJhc2UgPHBhdGg+JywgJ1BhdGggdG8gYmFzZSB0ZW1wbGF0ZSAoaWYgbm90IHVzaW5nIHN5bnRoZXNpcyknKVxuICAub3B0aW9uKCctLXRhcmdldCA8cGF0aD4nLCAnUGF0aCB0byB0YXJnZXQgdGVtcGxhdGUgKGlmIG5vdCB1c2luZyBzeW50aGVzaXMpJylcbiAgLm9wdGlvbignLS1zeW50aCcsICdFbmFibGUgYXV0b21hdGljIENESyBzeW50aGVzaXMnKVxuICAub3B0aW9uKCctLWNkay1hcHAtcGF0aCA8cGF0aD4nLCAnUGF0aCB0byBDREsgYXBwbGljYXRpb24gZGlyZWN0b3J5JylcbiAgLm9wdGlvbignLS1yZWdpb24gPHJlZ2lvbj4nLCAnQVdTIHJlZ2lvbicsICdldS1jZW50cmFsLTEnKVxuICAub3B0aW9uKCctLWNvbmZpZyA8cGF0aD4nLCAnUGF0aCB0byBjb25maWd1cmF0aW9uIGZpbGUnKVxuICAub3B0aW9uKCctLWVudmlyb25tZW50IDxlbnY+JywgJ0Vudmlyb25tZW50IG5hbWUgZm9yIHRocmVzaG9sZCBzZWxlY3Rpb24nKVxuICAub3B0aW9uKCctLWZvcm1hdCA8Zm9ybWF0PicsICdPdXRwdXQgZm9ybWF0OiB0ZXh0fGpzb258bWFya2Rvd24nLCAndGV4dCcpXG4gIC5vcHRpb24oJy0tcG9zdC10by1naXRsYWInLCAnUG9zdCByZXN1bHRzIHRvIEdpdExhYiBtZXJnZSByZXF1ZXN0JylcbiAgLmFjdGlvbihhc3luYyAob3B0aW9uczoge1xuICAgIGJhc2U/OiBzdHJpbmc7XG4gICAgdGFyZ2V0Pzogc3RyaW5nO1xuICAgIHN5bnRoPzogYm9vbGVhbjtcbiAgICBjZGtBcHBQYXRoPzogc3RyaW5nO1xuICAgIHJlZ2lvbjogc3RyaW5nO1xuICAgIGNvbmZpZz86IHN0cmluZztcbiAgICBlbnZpcm9ubWVudD86IHN0cmluZztcbiAgICBmb3JtYXQ6IHN0cmluZztcbiAgICBwb3N0VG9HaXRsYWI/OiBib29sZWFuO1xuICB9KSA9PiB7XG4gICAgdHJ5IHtcbiAgICAgIC8vIENoZWNrIEFXUyBjcmVkZW50aWFsc1xuICAgICAgaWYgKCFwcm9jZXNzLmVudi5BV1NfQUNDRVNTX0tFWV9JRCAmJiAhcHJvY2Vzcy5lbnYuQVdTX1BST0ZJTEUpIHtcbiAgICAgICAgY29uc29sZS5lcnJvcignRXJyb3I6IEFXUyBjcmVkZW50aWFscyBub3QgY29uZmlndXJlZCcpO1xuICAgICAgICBjb25zb2xlLmVycm9yKCcnKTtcbiAgICAgICAgY29uc29sZS5lcnJvcignUGxlYXNlIHNldCBBV1MgY3JlZGVudGlhbHMgdXNpbmcgb25lIG9mOicpO1xuICAgICAgICBjb25zb2xlLmVycm9yKCcgIC0gQVdTX0FDQ0VTU19LRVlfSUQgYW5kIEFXU19TRUNSRVRfQUNDRVNTX0tFWSBlbnZpcm9ubWVudCB2YXJpYWJsZXMnKTtcbiAgICAgICAgY29uc29sZS5lcnJvcignICAtIEFXU19QUk9GSUxFIGVudmlyb25tZW50IHZhcmlhYmxlJyk7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoJyAgLSBBV1MgY3JlZGVudGlhbHMgZmlsZSAofi8uYXdzL2NyZWRlbnRpYWxzKScpO1xuICAgICAgICBjb25zb2xlLmVycm9yKCcnKTtcbiAgICAgICAgY29uc29sZS5lcnJvcignRm9yIEdpdExhYiBDSSwgY29uZmlndXJlIEFXUyBjcmVkZW50aWFscyBpbiBDSS9DRCB2YXJpYWJsZXM6Jyk7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoJyAgU2V0dGluZ3MgPiBDSS9DRCA+IFZhcmlhYmxlcycpO1xuICAgICAgICBjb25zb2xlLmVycm9yKCcgIEFkZDogQVdTX0FDQ0VTU19LRVlfSUQsIEFXU19TRUNSRVRfQUNDRVNTX0tFWSwgQVdTX1JFR0lPTicpO1xuICAgICAgICBwcm9jZXNzLmV4aXQoMSk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IG9yY2hlc3RyYXRvciA9IG5ldyBQaXBlbGluZU9yY2hlc3RyYXRvcigpO1xuXG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBvcmNoZXN0cmF0b3IucnVuUGlwZWxpbmVBbmFseXNpcyh7XG4gICAgICAgIGJhc2VUZW1wbGF0ZTogb3B0aW9ucy5iYXNlLFxuICAgICAgICB0YXJnZXRUZW1wbGF0ZTogb3B0aW9ucy50YXJnZXQsXG4gICAgICAgIHN5bnRoZXNpemU6IG9wdGlvbnMuc3ludGgsXG4gICAgICAgIGNka0FwcFBhdGg6IG9wdGlvbnMuY2RrQXBwUGF0aCxcbiAgICAgICAgcmVnaW9uOiBvcHRpb25zLnJlZ2lvbixcbiAgICAgICAgY29uZmlnUGF0aDogb3B0aW9ucy5jb25maWcsXG4gICAgICAgIGVudmlyb25tZW50OiBvcHRpb25zLmVudmlyb25tZW50LFxuICAgICAgfSk7XG5cbiAgICAgIC8vIERpc3BsYXkgcmVzdWx0c1xuICAgICAgaWYgKG9wdGlvbnMuZm9ybWF0ID09PSAnanNvbicpIHtcbiAgICAgICAgY29uc29sZS5sb2coSlNPTi5zdHJpbmdpZnkocmVzdWx0LCBudWxsLCAyKSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zb2xlLmxvZyhyZXN1bHQuY29zdEFuYWx5c2lzLnN1bW1hcnkpO1xuICAgICAgICBjb25zb2xlLmxvZygnJyk7XG5cbiAgICAgICAgLy8gRGlzcGxheSB0aHJlc2hvbGQgc3RhdHVzXG4gICAgICAgIGlmIChyZXN1bHQudGhyZXNob2xkU3RhdHVzLmxldmVsICE9PSAnbm9uZScpIHtcbiAgICAgICAgICBjb25zb2xlLmxvZygnPScucmVwZWF0KDgwKSk7XG4gICAgICAgICAgY29uc29sZS5sb2coJ1RIUkVTSE9MRCBTVEFUVVMnKTtcbiAgICAgICAgICBjb25zb2xlLmxvZygnPScucmVwZWF0KDgwKSk7XG4gICAgICAgICAgY29uc29sZS5sb2cocmVzdWx0LnRocmVzaG9sZFN0YXR1cy5tZXNzYWdlKTtcbiAgICAgICAgICBjb25zb2xlLmxvZygnJyk7XG5cbiAgICAgICAgICBpZiAocmVzdWx0LnRocmVzaG9sZFN0YXR1cy5yZWNvbW1lbmRhdGlvbnMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgY29uc29sZS5sb2coJ1JlY29tbWVuZGF0aW9uczonKTtcbiAgICAgICAgICAgIHJlc3VsdC50aHJlc2hvbGRTdGF0dXMucmVjb21tZW5kYXRpb25zLmZvckVhY2goKHJlYywgaSkgPT4ge1xuICAgICAgICAgICAgICBjb25zb2xlLmxvZyhgJHtpICsgMX0uICR7cmVjfWApO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBjb25zb2xlLmxvZygnJyk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gRGlzcGxheSBjb25maWcgc3VtbWFyeVxuICAgICAgICBpZiAocmVzdWx0LmNvbmZpZ1VzZWQuY29uZmlnUGF0aCB8fCByZXN1bHQuY29uZmlnVXNlZC50aHJlc2hvbGRzKSB7XG4gICAgICAgICAgY29uc29sZS5sb2coJz0nLnJlcGVhdCg4MCkpO1xuICAgICAgICAgIGNvbnNvbGUubG9nKCdDT05GSUdVUkFUSU9OJyk7XG4gICAgICAgICAgY29uc29sZS5sb2coJz0nLnJlcGVhdCg4MCkpO1xuICAgICAgICAgIGlmIChyZXN1bHQuY29uZmlnVXNlZC5jb25maWdQYXRoKSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyhgQ29uZmlnIGZpbGU6ICR7cmVzdWx0LmNvbmZpZ1VzZWQuY29uZmlnUGF0aH1gKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKHJlc3VsdC5jb25maWdVc2VkLnRocmVzaG9sZHMpIHtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKGBUaHJlc2hvbGRzOiB3YXJuaW5nPSQke3Jlc3VsdC5jb25maWdVc2VkLnRocmVzaG9sZHMud2FybmluZyB8fCAnbm9uZSd9LCBlcnJvcj0kJHtyZXN1bHQuY29uZmlnVXNlZC50aHJlc2hvbGRzLmVycm9yIHx8ICdub25lJ31gKTtcbiAgICAgICAgICAgIGlmIChyZXN1bHQuY29uZmlnVXNlZC50aHJlc2hvbGRzLmVudmlyb25tZW50KSB7XG4gICAgICAgICAgICAgIGNvbnNvbGUubG9nKGBFbnZpcm9ubWVudDogJHtyZXN1bHQuY29uZmlnVXNlZC50aHJlc2hvbGRzLmVudmlyb25tZW50fWApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAocmVzdWx0LmNvbmZpZ1VzZWQuZXhjbHVkZWRSZXNvdXJjZVR5cGVzPy5sZW5ndGgpIHtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKGBFeGNsdWRlZCByZXNvdXJjZXM6ICR7cmVzdWx0LmNvbmZpZ1VzZWQuZXhjbHVkZWRSZXNvdXJjZVR5cGVzLmpvaW4oJywgJyl9YCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNvbnNvbGUubG9nKCcnKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBQb3N0IHRvIEdpdExhYiBpZiByZXF1ZXN0ZWRcbiAgICAgIGlmIChvcHRpb25zLnBvc3RUb0dpdGxhYikge1xuICAgICAgICBjb25zdCBnaXRsYWJUb2tlbiA9IHByb2Nlc3MuZW52LkdJVExBQl9UT0tFTiB8fCBwcm9jZXNzLmVudi5DSV9KT0JfVE9LRU47XG4gICAgICAgIGNvbnN0IHByb2plY3RJZCA9IHByb2Nlc3MuZW52LkNJX1BST0pFQ1RfSUQ7XG4gICAgICAgIGNvbnN0IG1lcmdlUmVxdWVzdElpZCA9IHByb2Nlc3MuZW52LkNJX01FUkdFX1JFUVVFU1RfSUlEO1xuICAgICAgICBjb25zdCBnaXRsYWJVcmwgPSBwcm9jZXNzLmVudi5DSV9TRVJWRVJfVVJMO1xuXG4gICAgICAgIGlmICghZ2l0bGFiVG9rZW4gfHwgIXByb2plY3RJZCB8fCAhbWVyZ2VSZXF1ZXN0SWlkIHx8ICFnaXRsYWJVcmwpIHtcbiAgICAgICAgICBjb25zb2xlLmVycm9yKCdXYXJuaW5nOiBHaXRMYWIgZW52aXJvbm1lbnQgdmFyaWFibGVzIG5vdCBmb3VuZC4gU2tpcHBpbmcgR2l0TGFiIHBvc3QuJyk7XG4gICAgICAgICAgY29uc29sZS5lcnJvcignUmVxdWlyZWQ6IENJX0pPQl9UT0tFTiwgQ0lfUFJPSkVDVF9JRCwgQ0lfTUVSR0VfUkVRVUVTVF9JSUQsIENJX1NFUlZFUl9VUkwnKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3QgZ2l0bGFiID0gbmV3IEdpdExhYkludGVncmF0aW9uKHtcbiAgICAgICAgICAgICAgdG9rZW46IGdpdGxhYlRva2VuLFxuICAgICAgICAgICAgICBhcGlVcmw6IGdpdGxhYlVybCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgYXdhaXQgZ2l0bGFiLnBvc3RNZXJnZVJlcXVlc3RDb21tZW50KFxuICAgICAgICAgICAgICBwcm9qZWN0SWQsXG4gICAgICAgICAgICAgIG1lcmdlUmVxdWVzdElpZCxcbiAgICAgICAgICAgICAgcmVzdWx0LmNvc3RBbmFseXNpcy5zdW1tYXJ5LFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKCdSZXN1bHRzIHBvc3RlZCB0byBHaXRMYWIgbWVyZ2UgcmVxdWVzdCcpO1xuICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKGBXYXJuaW5nOiBGYWlsZWQgdG8gcG9zdCB0byBHaXRMYWI6ICR7ZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiBTdHJpbmcoZXJyb3IpfWApO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBFeGl0IHdpdGggYXBwcm9wcmlhdGUgY29kZSBiYXNlZCBvbiB0aHJlc2hvbGRcbiAgICAgIGlmIChyZXN1bHQudGhyZXNob2xkU3RhdHVzLmxldmVsID09PSAnZXJyb3InICYmICFyZXN1bHQudGhyZXNob2xkU3RhdHVzLnBhc3NlZCkge1xuICAgICAgICBjb25zb2xlLmVycm9yKCdQaXBlbGluZSBmYWlsZWQ6IENvc3QgdGhyZXNob2xkIGV4Y2VlZGVkJyk7XG4gICAgICAgIHByb2Nlc3MuZXhpdCgyKTtcbiAgICAgIH1cblxuICAgICAgcHJvY2Vzcy5leGl0KDApO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICBjb25zb2xlLmVycm9yKGBFcnJvcjogJHtlcnJvci5tZXNzYWdlfWApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc29sZS5lcnJvcihgRXJyb3I6ICR7U3RyaW5nKGVycm9yKX1gKTtcbiAgICAgIH1cbiAgICAgIHByb2Nlc3MuZXhpdCgxKTtcbiAgICB9XG4gIH0pO1xuXG4vLyBEZWZhdWx0IHRvIGNvbXBhcmUgY29tbWFuZCBmb3IgYmFja3dhcmQgY29tcGF0aWJpbGl0eVxucHJvZ3JhbVxuICAuYXJndW1lbnQoJ1tiYXNlXScsICdQYXRoIHRvIGJhc2UgQ2xvdWRGb3JtYXRpb24gdGVtcGxhdGUnKVxuICAuYXJndW1lbnQoJ1t0YXJnZXRdJywgJ1BhdGggdG8gdGFyZ2V0IENsb3VkRm9ybWF0aW9uIHRlbXBsYXRlJylcbiAgLm9wdGlvbignLS1yZWdpb24gPHJlZ2lvbj4nLCAnQVdTIHJlZ2lvbicsICdldS1jZW50cmFsLTEnKVxuICAub3B0aW9uKCctLWZvcm1hdCA8Zm9ybWF0PicsICdPdXRwdXQgZm9ybWF0OiB0ZXh0fGpzb258bWFya2Rvd24nLCAndGV4dCcpXG4gIC5vcHRpb24oJy0tY29uZmlnIDxwYXRoPicsICdQYXRoIHRvIGNvbmZpZ3VyYXRpb24gZmlsZScpXG4gIC5hY3Rpb24oYXN5bmMgKGJhc2VQYXRoPzogc3RyaW5nLCB0YXJnZXRQYXRoPzogc3RyaW5nLCBvcHRpb25zPzogeyByZWdpb246IHN0cmluZzsgZm9ybWF0OiBzdHJpbmc7IGNvbmZpZz86IHN0cmluZyB9KSA9PiB7XG4gICAgaWYgKCFiYXNlUGF0aCB8fCAhdGFyZ2V0UGF0aCkge1xuICAgICAgcHJvZ3JhbS5oZWxwKCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgIGlmICghZnMuZXhpc3RzU3luYyhiYXNlUGF0aCkpIHtcbiAgICAgICAgY29uc29sZS5lcnJvcihgRXJyb3I6IEJhc2UgdGVtcGxhdGUgZmlsZSBub3QgZm91bmQ6ICR7YmFzZVBhdGh9YCk7XG4gICAgICAgIHByb2Nlc3MuZXhpdCgxKTtcbiAgICAgIH1cblxuICAgICAgaWYgKCFmcy5leGlzdHNTeW5jKHRhcmdldFBhdGgpKSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoYEVycm9yOiBUYXJnZXQgdGVtcGxhdGUgZmlsZSBub3QgZm91bmQ6ICR7dGFyZ2V0UGF0aH1gKTtcbiAgICAgICAgcHJvY2Vzcy5leGl0KDEpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBiYXNlVGVtcGxhdGUgPSBmcy5yZWFkRmlsZVN5bmMoYmFzZVBhdGgsICd1dGYtOCcpO1xuICAgICAgY29uc3QgdGFyZ2V0VGVtcGxhdGUgPSBmcy5yZWFkRmlsZVN5bmModGFyZ2V0UGF0aCwgJ3V0Zi04Jyk7XG5cbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGFuYWx5emVDb3N0cyh7XG4gICAgICAgIGJhc2VUZW1wbGF0ZSxcbiAgICAgICAgdGFyZ2V0VGVtcGxhdGUsXG4gICAgICAgIHJlZ2lvbjogb3B0aW9ucz8ucmVnaW9uIHx8ICdldS1jZW50cmFsLTEnLFxuICAgICAgICBmb3JtYXQ6IChvcHRpb25zPy5mb3JtYXQgYXMgJ3RleHQnIHwgJ2pzb24nIHwgJ21hcmtkb3duJykgfHwgJ3RleHQnLFxuICAgICAgfSk7XG5cbiAgICAgIGlmIChvcHRpb25zPy5mb3JtYXQgPT09ICdqc29uJykge1xuICAgICAgICBjb25zb2xlLmxvZyhKU09OLnN0cmluZ2lmeShyZXN1bHQsIG51bGwsIDIpKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnNvbGUubG9nKHJlc3VsdC5zdW1tYXJ5KTtcbiAgICAgIH1cblxuICAgICAgcHJvY2Vzcy5leGl0KDApO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICBjb25zb2xlLmVycm9yKGBFcnJvcjogJHtlcnJvci5tZXNzYWdlfWApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc29sZS5lcnJvcihgRXJyb3I6ICR7U3RyaW5nKGVycm9yKX1gKTtcbiAgICAgIH1cbiAgICAgIHByb2Nlc3MuZXhpdCgxKTtcbiAgICB9XG4gIH0pO1xuXG5wcm9ncmFtLnBhcnNlKCk7XG4iXX0=
@@ -0,0 +1,40 @@
1
+ import { CostAnalyzerConfig, ValidationResult } from './types';
2
+ export declare class ConfigManager {
3
+ private static readonly CONFIG_FILE_NAMES;
4
+ /**
5
+ * Load configuration from file or return default configuration
6
+ */
7
+ loadConfig(configPath?: string): Promise<CostAnalyzerConfig>;
8
+ /**
9
+ * Validate configuration structure and values
10
+ */
11
+ validateConfig(config: CostAnalyzerConfig): ValidationResult;
12
+ /**
13
+ * Resolve configuration file path using search order
14
+ */
15
+ private resolveConfigPath;
16
+ /**
17
+ * Read and parse configuration file (YAML or JSON)
18
+ */
19
+ private readConfigFile;
20
+ /**
21
+ * Check if file exists
22
+ */
23
+ private fileExists;
24
+ /**
25
+ * Validate threshold configuration
26
+ */
27
+ private validateThresholds;
28
+ /**
29
+ * Validate usage assumptions
30
+ */
31
+ private validateUsageAssumptions;
32
+ /**
33
+ * Get default configuration
34
+ */
35
+ private getDefaultConfig;
36
+ /**
37
+ * Merge user configuration with defaults
38
+ */
39
+ private mergeWithDefaults;
40
+ }
@@ -0,0 +1,238 @@
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.ConfigManager = void 0;
37
+ const fs = __importStar(require("fs/promises"));
38
+ const path = __importStar(require("path"));
39
+ const yaml = __importStar(require("js-yaml"));
40
+ const types_1 = require("./types");
41
+ class ConfigManager {
42
+ static CONFIG_FILE_NAMES = [
43
+ '.cdk-cost-analyzer.yml',
44
+ '.cdk-cost-analyzer.yaml',
45
+ '.cdk-cost-analyzer.json',
46
+ ];
47
+ /**
48
+ * Load configuration from file or return default configuration
49
+ */
50
+ async loadConfig(configPath) {
51
+ try {
52
+ const resolvedPath = await this.resolveConfigPath(configPath);
53
+ if (!resolvedPath) {
54
+ return this.getDefaultConfig();
55
+ }
56
+ const config = await this.readConfigFile(resolvedPath);
57
+ const validation = this.validateConfig(config);
58
+ if (!validation.valid) {
59
+ throw new types_1.ConfigurationError('Invalid configuration', resolvedPath, validation.errors);
60
+ }
61
+ return this.mergeWithDefaults(config);
62
+ }
63
+ catch (error) {
64
+ if (error instanceof types_1.ConfigurationError) {
65
+ throw error;
66
+ }
67
+ throw new types_1.ConfigurationError(`Failed to load configuration: ${error instanceof Error ? error.message : String(error)}`, configPath || 'unknown', []);
68
+ }
69
+ }
70
+ /**
71
+ * Validate configuration structure and values
72
+ */
73
+ validateConfig(config) {
74
+ const errors = [];
75
+ const warnings = [];
76
+ if (config.thresholds) {
77
+ this.validateThresholds(config.thresholds, errors, warnings);
78
+ }
79
+ if (config.usageAssumptions) {
80
+ this.validateUsageAssumptions(config.usageAssumptions, errors);
81
+ }
82
+ if (config.cache?.durationHours !== undefined) {
83
+ if (config.cache.durationHours <= 0) {
84
+ errors.push('cache.durationHours must be positive');
85
+ }
86
+ }
87
+ return {
88
+ valid: errors.length === 0,
89
+ errors,
90
+ warnings,
91
+ };
92
+ }
93
+ /**
94
+ * Resolve configuration file path using search order
95
+ */
96
+ async resolveConfigPath(configPath) {
97
+ if (configPath) {
98
+ const exists = await this.fileExists(configPath);
99
+ if (!exists) {
100
+ throw new Error(`Configuration file not found: ${configPath}`);
101
+ }
102
+ return configPath;
103
+ }
104
+ // Search in current directory
105
+ for (const fileName of ConfigManager.CONFIG_FILE_NAMES) {
106
+ const filePath = path.join(process.cwd(), fileName);
107
+ if (await this.fileExists(filePath)) {
108
+ return filePath;
109
+ }
110
+ }
111
+ return null;
112
+ }
113
+ /**
114
+ * Read and parse configuration file (YAML or JSON)
115
+ */
116
+ async readConfigFile(filePath) {
117
+ const content = await fs.readFile(filePath, 'utf-8');
118
+ const ext = path.extname(filePath).toLowerCase();
119
+ try {
120
+ if (ext === '.json') {
121
+ return JSON.parse(content);
122
+ }
123
+ else {
124
+ return yaml.load(content);
125
+ }
126
+ }
127
+ catch (error) {
128
+ throw new Error(`Failed to parse configuration file: ${error instanceof Error ? error.message : String(error)}`);
129
+ }
130
+ }
131
+ /**
132
+ * Check if file exists
133
+ */
134
+ async fileExists(filePath) {
135
+ try {
136
+ await fs.access(filePath);
137
+ return true;
138
+ }
139
+ catch {
140
+ return false;
141
+ }
142
+ }
143
+ /**
144
+ * Validate threshold configuration
145
+ */
146
+ validateThresholds(thresholds, errors, warnings) {
147
+ const validateLevels = (levels, prefix) => {
148
+ if (levels.warning !== undefined && levels.warning < 0) {
149
+ errors.push(`${prefix}.warning must be non-negative`);
150
+ }
151
+ if (levels.error !== undefined && levels.error < 0) {
152
+ errors.push(`${prefix}.error must be non-negative`);
153
+ }
154
+ if (levels.warning !== undefined &&
155
+ levels.error !== undefined &&
156
+ levels.warning > levels.error) {
157
+ warnings.push(`${prefix}.warning (${levels.warning}) is greater than ${prefix}.error (${levels.error})`);
158
+ }
159
+ };
160
+ if (thresholds.default) {
161
+ validateLevels(thresholds.default, 'thresholds.default');
162
+ }
163
+ if (thresholds.environments) {
164
+ for (const [env, levels] of Object.entries(thresholds.environments)) {
165
+ validateLevels(levels, `thresholds.environments.${env}`);
166
+ }
167
+ }
168
+ }
169
+ /**
170
+ * Validate usage assumptions
171
+ */
172
+ validateUsageAssumptions(assumptions, errors) {
173
+ const validatePositive = (value, configPath) => {
174
+ if (value !== undefined && value < 0) {
175
+ errors.push(`${configPath} must be non-negative`);
176
+ }
177
+ };
178
+ if (assumptions.s3) {
179
+ validatePositive(assumptions.s3.storageGB, 'usageAssumptions.s3.storageGB');
180
+ validatePositive(assumptions.s3.getRequests, 'usageAssumptions.s3.getRequests');
181
+ validatePositive(assumptions.s3.putRequests, 'usageAssumptions.s3.putRequests');
182
+ }
183
+ if (assumptions.lambda) {
184
+ validatePositive(assumptions.lambda.invocationsPerMonth, 'usageAssumptions.lambda.invocationsPerMonth');
185
+ validatePositive(assumptions.lambda.averageDurationMs, 'usageAssumptions.lambda.averageDurationMs');
186
+ }
187
+ if (assumptions.natGateway) {
188
+ validatePositive(assumptions.natGateway.dataProcessedGB, 'usageAssumptions.natGateway.dataProcessedGB');
189
+ }
190
+ if (assumptions.alb) {
191
+ validatePositive(assumptions.alb.newConnectionsPerSecond, 'usageAssumptions.alb.newConnectionsPerSecond');
192
+ validatePositive(assumptions.alb.activeConnectionsPerMinute, 'usageAssumptions.alb.activeConnectionsPerMinute');
193
+ validatePositive(assumptions.alb.processedBytesGB, 'usageAssumptions.alb.processedBytesGB');
194
+ }
195
+ if (assumptions.nlb) {
196
+ validatePositive(assumptions.nlb.newConnectionsPerSecond, 'usageAssumptions.nlb.newConnectionsPerSecond');
197
+ validatePositive(assumptions.nlb.activeConnectionsPerMinute, 'usageAssumptions.nlb.activeConnectionsPerMinute');
198
+ validatePositive(assumptions.nlb.processedBytesGB, 'usageAssumptions.nlb.processedBytesGB');
199
+ }
200
+ if (assumptions.cloudfront) {
201
+ validatePositive(assumptions.cloudfront.dataTransferGB, 'usageAssumptions.cloudfront.dataTransferGB');
202
+ validatePositive(assumptions.cloudfront.requests, 'usageAssumptions.cloudfront.requests');
203
+ }
204
+ if (assumptions.apiGateway) {
205
+ validatePositive(assumptions.apiGateway.requestsPerMonth, 'usageAssumptions.apiGateway.requestsPerMonth');
206
+ }
207
+ if (assumptions.vpcEndpoint) {
208
+ validatePositive(assumptions.vpcEndpoint.dataProcessedGB, 'usageAssumptions.vpcEndpoint.dataProcessedGB');
209
+ }
210
+ }
211
+ /**
212
+ * Get default configuration
213
+ */
214
+ getDefaultConfig() {
215
+ return {
216
+ cache: {
217
+ enabled: true,
218
+ durationHours: 24,
219
+ },
220
+ };
221
+ }
222
+ /**
223
+ * Merge user configuration with defaults
224
+ */
225
+ mergeWithDefaults(config) {
226
+ const defaults = this.getDefaultConfig();
227
+ return {
228
+ ...defaults,
229
+ ...config,
230
+ cache: {
231
+ ...defaults.cache,
232
+ ...config.cache,
233
+ },
234
+ };
235
+ }
236
+ }
237
+ exports.ConfigManager = ConfigManager;
238
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQ29uZmlnTWFuYWdlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jb25maWcvQ29uZmlnTWFuYWdlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSxnREFBa0M7QUFDbEMsMkNBQTZCO0FBQzdCLDhDQUFnQztBQUNoQyxtQ0FLaUI7QUFFakIsTUFBYSxhQUFhO0lBQ2hCLE1BQU0sQ0FBVSxpQkFBaUIsR0FBRztRQUMxQyx3QkFBd0I7UUFDeEIseUJBQXlCO1FBQ3pCLHlCQUF5QjtLQUMxQixDQUFDO0lBRUY7O09BRUc7SUFDSCxLQUFLLENBQUMsVUFBVSxDQUFDLFVBQW1CO1FBQ2xDLElBQUksQ0FBQztZQUNILE1BQU0sWUFBWSxHQUFHLE1BQU0sSUFBSSxDQUFDLGlCQUFpQixDQUFDLFVBQVUsQ0FBQyxDQUFDO1lBRTlELElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztnQkFDbEIsT0FBTyxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztZQUNqQyxDQUFDO1lBRUQsTUFBTSxNQUFNLEdBQUcsTUFBTSxJQUFJLENBQUMsY0FBYyxDQUFDLFlBQVksQ0FBQyxDQUFDO1lBQ3ZELE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxjQUFjLENBQUMsTUFBTSxDQUFDLENBQUM7WUFFL0MsSUFBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLEVBQUUsQ0FBQztnQkFDdEIsTUFBTSxJQUFJLDBCQUFrQixDQUMxQix1QkFBdUIsRUFDdkIsWUFBWSxFQUNaLFVBQVUsQ0FBQyxNQUFNLENBQ2xCLENBQUM7WUFDSixDQUFDO1lBRUQsT0FBTyxJQUFJLENBQUMsaUJBQWlCLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDeEMsQ0FBQztRQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7WUFDZixJQUFJLEtBQUssWUFBWSwwQkFBa0IsRUFBRSxDQUFDO2dCQUN4QyxNQUFNLEtBQUssQ0FBQztZQUNk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QixDQUNkLFdBQVcsQ0FBQyxVQUFVLENBQUMsZ0JBQWdCLEVBQ3ZDLDhDQUE4QyxDQUMvQyxDQUFDO1FBQ0osQ0FBQztRQUVELElBQUksV0FBVyxDQUFDLFdBQVcsRUFBRSxDQUFDO1lBQzVCLGdCQUFnQixDQUNkLFdBQVcsQ0FBQyxXQUFXLENBQUMsZUFBZSxFQUN2Qyw4Q0FBOEMsQ0FDL0MsQ0FBQztRQUNKLENBQUM7SUFDSCxDQUFDO0lBRUQ7O09BRUc7SUFDSyxnQkFBZ0I7UUFDdEIsT0FBTztZQUNMLEtBQUssRUFBRTtnQkFDTCxPQUFPLEVBQUUsSUFBSTtnQkFDYixhQUFhLEVBQUUsRUFBRTthQUNsQjtTQUNGLENBQUM7SUFDSixDQUFDO0lBRUQ7O09BRUc7SUFDSyxpQkFBaUIsQ0FBQyxNQUEwQjtRQUNsRCxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztRQUN6QyxPQUFPO1lBQ0wsR0FBRyxRQUFRO1lBQ1gsR0FBRyxNQUFNO1lBQ1QsS0FBSyxFQUFFO2dCQUNMLEdBQUcsUUFBUSxDQUFDLEtBQUs7Z0JBQ2pCLEdBQUcsTUFBTSxDQUFDLEtBQUs7YUFDaEI7U0FDRixDQUFDO0lBQ0osQ0FBQzs7QUF4Ukgsc0NBeVJDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgZnMgZnJvbSAnZnMvcHJvbWlzZXMnO1xuaW1wb3J0ICogYXMgcGF0aCBmcm9tICdwYXRoJztcbmltcG9ydCAqIGFzIHlhbWwgZnJvbSAnanMteWFtbCc7XG5pbXBvcnQge1xuICBDb3N0QW5hbHl6ZXJDb25maWcsXG4gIFZhbGlkYXRpb25SZXN1bHQsXG4gIENvbmZpZ3VyYXRpb25FcnJvcixcbiAgVGhyZXNob2xkTGV2ZWxzLFxufSBmcm9tICcuL3R5cGVzJztcblxuZXhwb3J0IGNsYXNzIENvbmZpZ01hbmFnZXIge1xuICBwcml2YXRlIHN0YXRpYyByZWFkb25seSBDT05GSUdfRklMRV9OQU1FUyA9IFtcbiAgICAnLmNkay1jb3N0LWFuYWx5emVyLnltbCcsXG4gICAgJy5jZGstY29zdC1hbmFseXplci55YW1sJyxcbiAgICAnLmNkay1jb3N0LWFuYWx5emVyLmpzb24nLFxuICBdO1xuXG4gIC8qKlxuICAgKiBMb2FkIGNvbmZpZ3VyYXRpb24gZnJvbSBmaWxlIG9yIHJldHVybiBkZWZhdWx0IGNvbmZpZ3VyYXRpb25cbiAgICovXG4gIGFzeW5jIGxvYWRDb25maWcoY29uZmlnUGF0aD86IHN0cmluZyk6IFByb21pc2U8Q29zdEFuYWx5emVyQ29uZmlnPiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJlc29sdmVkUGF0aCA9IGF3YWl0IHRoaXMucmVzb2x2ZUNvbmZpZ1BhdGgoY29uZmlnUGF0aCk7XG5cbiAgICAgIGlmICghcmVzb2x2ZWRQYXRoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldERlZmF1bHRDb25maWcoKTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgY29uZmlnID0gYXdhaXQgdGhpcy5yZWFkQ29uZmlnRmlsZShyZXNvbHZlZFBhdGgpO1xuICAgICAgY29uc3QgdmFsaWRhdGlvbiA9IHRoaXMudmFsaWRhdGVDb25maWcoY29uZmlnKTtcblxuICAgICAgaWYgKCF2YWxpZGF0aW9uLnZhbGlkKSB7XG4gICAgICAgIHRocm93IG5ldyBDb25maWd1cmF0aW9uRXJyb3IoXG4gICAgICAgICAgJ0ludmFsaWQgY29uZmlndXJhdGlvbicsXG4gICAgICAgICAgcmVzb2x2ZWRQYXRoLFxuICAgICAgICAgIHZhbGlkYXRpb24uZXJyb3JzLFxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gdGhpcy5tZXJnZVdpdGhEZWZhdWx0cyhjb25maWcpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBDb25maWd1cmF0aW9uRXJyb3IpIHtcbiAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICB9XG4gICAgICB0aHJvdyBuZXcgQ29uZmlndXJhdGlvbkVycm9yKFxuICAgICAgICBgRmFpbGVkIHRvIGxvYWQgY29uZmlndXJhdGlvbjogJHtlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IubWVzc2FnZSA6IFN0cmluZyhlcnJvcil9YCxcbiAgICAgICAgY29uZmlnUGF0aCB8fCAndW5rbm93bicsXG4gICAgICAgIFtdLFxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogVmFsaWRhdGUgY29uZmlndXJhdGlvbiBzdHJ1Y3R1cmUgYW5kIHZhbHVlc1xuICAgKi9cbiAgdmFsaWRhdGVDb25maWcoY29uZmlnOiBDb3N0QW5hbHl6ZXJDb25maWcpOiBWYWxpZGF0aW9uUmVzdWx0IHtcbiAgICBjb25zdCBlcnJvcnM6IHN0cmluZ1tdID0gW107XG4gICAgY29uc3Qgd2FybmluZ3M6IHN0cmluZ1tdID0gW107XG5cbiAgICBpZiAoY29uZmlnLnRocmVzaG9sZHMpIHtcbiAgICAgIHRoaXMudmFsaWRhdGVUaHJlc2hvbGRzKGNvbmZpZy50aHJlc2hvbGRzLCBlcnJvcnMsIHdhcm5pbmdzKTtcbiAgICB9XG5cbiAgICBpZiAoY29uZmlnLnVzYWdlQXNzdW1wdGlvbnMpIHtcbiAgICAgIHRoaXMudmFsaWRhdGVVc2FnZUFzc3VtcHRpb25zKGNvbmZpZy51c2FnZUFzc3VtcHRpb25zLCBlcnJvcnMpO1xuICAgIH1cblxuICAgIGlmIChjb25maWcuY2FjaGU/LmR1cmF0aW9uSG91cnMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgaWYgKGNvbmZpZy5jYWNoZS5kdXJhdGlvbkhvdXJzIDw9IDApIHtcbiAgICAgICAgZXJyb3JzLnB1c2goJ2NhY2hlLmR1cmF0aW9uSG91cnMgbXVzdCBiZSBwb3NpdGl2ZScpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICB2YWxpZDogZXJyb3JzLmxlbmd0aCA9PT0gMCxcbiAgICAgIGVycm9ycyxcbiAgICAgIHdhcm5pbmdzLFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogUmVzb2x2ZSBjb25maWd1cmF0aW9uIGZpbGUgcGF0aCB1c2luZyBzZWFyY2ggb3JkZXJcbiAgICovXG4gIHByaXZhdGUgYXN5bmMgcmVzb2x2ZUNvbmZpZ1BhdGgoY29uZmlnUGF0aD86IHN0cmluZyk6IFByb21pc2U8c3RyaW5nIHwgbnVsbD4ge1xuICAgIGlmIChjb25maWdQYXRoKSB7XG4gICAgICBjb25zdCBleGlzdHMgPSBhd2FpdCB0aGlzLmZpbGVFeGlzdHMoY29uZmlnUGF0aCk7XG4gICAgICBpZiAoIWV4aXN0cykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYENvbmZpZ3VyYXRpb24gZmlsZSBub3QgZm91bmQ6ICR7Y29uZmlnUGF0aH1gKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBjb25maWdQYXRoO1xuICAgIH1cblxuICAgIC8vIFNlYXJjaCBpbiBjdXJyZW50IGRpcmVjdG9yeVxuICAgIGZvciAoY29uc3QgZmlsZU5hbWUgb2YgQ29uZmlnTWFuYWdlci5DT05GSUdfRklMRV9OQU1FUykge1xuICAgICAgY29uc3QgZmlsZVBhdGggPSBwYXRoLmpvaW4ocHJvY2Vzcy5jd2QoKSwgZmlsZU5hbWUpO1xuICAgICAgaWYgKGF3YWl0IHRoaXMuZmlsZUV4aXN0cyhmaWxlUGF0aCkpIHtcbiAgICAgICAgcmV0dXJuIGZpbGVQYXRoO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlYWQgYW5kIHBhcnNlIGNvbmZpZ3VyYXRpb24gZmlsZSAoWUFNTCBvciBKU09OKVxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyByZWFkQ29uZmlnRmlsZShmaWxlUGF0aDogc3RyaW5nKTogUHJvbWlzZTxDb3N0QW5hbHl6ZXJDb25maWc+IHtcbiAgICBjb25zdCBjb250ZW50ID0gYXdhaXQgZnMucmVhZEZpbGUoZmlsZVBhdGgsICd1dGYtOCcpO1xuICAgIGNvbnN0IGV4dCA9IHBhdGguZXh0bmFtZShmaWxlUGF0aCkudG9Mb3dlckNhc2UoKTtcblxuICAgIHRyeSB7XG4gICAgICBpZiAoZXh0ID09PSAnLmpzb24nKSB7XG4gICAgICAgIHJldHVybiBKU09OLnBhcnNlKGNvbnRlbnQpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIHlhbWwubG9hZChjb250ZW50KSBhcyBDb3N0QW5hbHl6ZXJDb25maWc7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgYEZhaWxlZCB0byBwYXJzZSBjb25maWd1cmF0aW9uIGZpbGU6ICR7ZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiBTdHJpbmcoZXJyb3IpfWAsXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVjayBpZiBmaWxlIGV4aXN0c1xuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBmaWxlRXhpc3RzKGZpbGVQYXRoOiBzdHJpbmcpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgZnMuYWNjZXNzKGZpbGVQYXRoKTtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH0gY2F0Y2gge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBWYWxpZGF0ZSB0aHJlc2hvbGQgY29uZmlndXJhdGlvblxuICAgKi9cbiAgcHJpdmF0ZSB2YWxpZGF0ZVRocmVzaG9sZHMoXG4gICAgdGhyZXNob2xkczogTm9uTnVsbGFibGU8Q29zdEFuYWx5emVyQ29uZmlnWyd0aHJlc2hvbGRzJ10+LFxuICAgIGVycm9yczogc3RyaW5nW10sXG4gICAgd2FybmluZ3M6IHN0cmluZ1tdLFxuICApOiB2b2lkIHtcbiAgICBjb25zdCB2YWxpZGF0ZUxldmVscyA9IChsZXZlbHM6IFRocmVzaG9sZExldmVscywgcHJlZml4OiBzdHJpbmcpID0+IHtcbiAgICAgIGlmIChsZXZlbHMud2FybmluZyAhPT0gdW5kZWZpbmVkICYmIGxldmVscy53YXJuaW5nIDwgMCkge1xuICAgICAgICBlcnJvcnMucHVzaChgJHtwcmVmaXh9Lndhcm5pbmcgbXVzdCBiZSBub24tbmVnYXRpdmVgKTtcbiAgICAgIH1cbiAgICAgIGlmIChsZXZlbHMuZXJyb3IgIT09IHVuZGVmaW5lZCAmJiBsZXZlbHMuZXJyb3IgPCAwKSB7XG4gICAgICAgIGVycm9ycy5wdXNoKGAke3ByZWZpeH0uZXJyb3IgbXVzdCBiZSBub24tbmVnYXRpdmVgKTtcbiAgICAgIH1cbiAgICAgIGlmIChcbiAgICAgICAgbGV2ZWxzLndhcm5pbmcgIT09IHVuZGVmaW5lZCAmJlxuICAgICAgICBsZXZlbHMuZXJyb3IgIT09IHVuZGVmaW5lZCAmJlxuICAgICAgICBsZXZlbHMud2FybmluZyA+IGxldmVscy5lcnJvclxuICAgICAgKSB7XG4gICAgICAgIHdhcm5pbmdzLnB1c2goXG4gICAgICAgICAgYCR7cHJlZml4fS53YXJuaW5nICgke2xldmVscy53YXJuaW5nfSkgaXMgZ3JlYXRlciB0aGFuICR7cHJlZml4fS5lcnJvciAoJHtsZXZlbHMuZXJyb3J9KWAsXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIGlmICh0aHJlc2hvbGRzLmRlZmF1bHQpIHtcbiAgICAgIHZhbGlkYXRlTGV2ZWxzKHRocmVzaG9sZHMuZGVmYXVsdCwgJ3RocmVzaG9sZHMuZGVmYXVsdCcpO1xuICAgIH1cblxuICAgIGlmICh0aHJlc2hvbGRzLmVudmlyb25tZW50cykge1xuICAgICAgZm9yIChjb25zdCBbZW52LCBsZXZlbHNdIG9mIE9iamVjdC5lbnRyaWVzKHRocmVzaG9sZHMuZW52aXJvbm1lbnRzKSkge1xuICAgICAgICB2YWxpZGF0ZUxldmVscyhsZXZlbHMsIGB0aHJlc2hvbGRzLmVudmlyb25tZW50cy4ke2Vudn1gKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogVmFsaWRhdGUgdXNhZ2UgYXNzdW1wdGlvbnNcbiAgICovXG4gIHByaXZhdGUgdmFsaWRhdGVVc2FnZUFzc3VtcHRpb25zKFxuICAgIGFzc3VtcHRpb25zOiBOb25OdWxsYWJsZTxDb3N0QW5hbHl6ZXJDb25maWdbJ3VzYWdlQXNzdW1wdGlvbnMnXT4sXG4gICAgZXJyb3JzOiBzdHJpbmdbXSxcbiAgKTogdm9pZCB7XG4gICAgY29uc3QgdmFsaWRhdGVQb3NpdGl2ZSA9ICh2YWx1ZTogbnVtYmVyIHwgdW5kZWZpbmVkLCBjb25maWdQYXRoOiBzdHJpbmcpID0+IHtcbiAgICAgIGlmICh2YWx1ZSAhPT0gdW5kZWZpbmVkICYmIHZhbHVlIDwgMCkge1xuICAgICAgICBlcnJvcnMucHVzaChgJHtjb25maWdQYXRofSBtdXN0IGJlIG5vbi1uZWdhdGl2ZWApO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBpZiAoYXNzdW1wdGlvbnMuczMpIHtcbiAgICAgIHZhbGlkYXRlUG9zaXRpdmUoYXNzdW1wdGlvbnMuczMuc3RvcmFnZUdCLCAndXNhZ2VBc3N1bXB0aW9ucy5zMy5zdG9yYWdlR0InKTtcbiAgICAgIHZhbGlkYXRlUG9zaXRpdmUoYXNzdW1wdGlvbnMuczMuZ2V0UmVxdWVzdHMsICd1c2FnZUFzc3VtcHRpb25zLnMzLmdldFJlcXVlc3RzJyk7XG4gICAgICB2YWxpZGF0ZVBvc2l0aXZlKGFzc3VtcHRpb25zLnMzLnB1dFJlcXVlc3RzLCAndXNhZ2VBc3N1bXB0aW9ucy5zMy5wdXRSZXF1ZXN0cycpO1xuICAgIH1cblxuICAgIGlmIChhc3N1bXB0aW9ucy5sYW1iZGEpIHtcbiAgICAgIHZhbGlkYXRlUG9zaXRpdmUoXG4gICAgICAgIGFzc3VtcHRpb25zLmxhbWJkYS5pbnZvY2F0aW9uc1Blck1vbnRoLFxuICAgICAgICAndXNhZ2VBc3N1bXB0aW9ucy5sYW1iZGEuaW52b2NhdGlvbnNQZXJNb250aCcsXG4gICAgICApO1xuICAgICAgdmFsaWRhdGVQb3NpdGl2ZShcbiAgICAgICAgYXNzdW1wdGlvbnMubGFtYmRhLmF2ZXJhZ2VEdXJhdGlvbk1zLFxuICAgICAgICAndXNhZ2VBc3N1bXB0aW9ucy5sYW1iZGEuYXZlcmFnZUR1cmF0aW9uTXMnLFxuICAgICAgKTtcbiAgICB9XG5cbiAgICBpZiAoYXNzdW1wdGlvbnMubmF0R2F0ZXdheSkge1xuICAgICAgdmFsaWRhdGVQb3NpdGl2ZShcbiAgICAgICAgYXNzdW1wdGlvbnMubmF0R2F0ZXdheS5kYXRhUHJvY2Vzc2VkR0IsXG4gICAgICAgICd1c2FnZUFzc3VtcHRpb25zLm5hdEdhdGV3YXkuZGF0YVByb2Nlc3NlZEdCJyxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgaWYgKGFzc3VtcHRpb25zLmFsYikge1xuICAgICAgdmFsaWRhdGVQb3NpdGl2ZShcbiAgICAgICAgYXNzdW1wdGlvbnMuYWxiLm5ld0Nvbm5lY3Rpb25zUGVyU2Vjb25kLFxuICAgICAgICAndXNhZ2VBc3N1bXB0aW9ucy5hbGIubmV3Q29ubmVjdGlvbnNQZXJTZWNvbmQnLFxuICAgICAgKTtcbiAgICAgIHZhbGlkYXRlUG9zaXRpdmUoXG4gICAgICAgIGFzc3VtcHRpb25zLmFsYi5hY3RpdmVDb25uZWN0aW9uc1Blck1pbnV0ZSxcbiAgICAgICAgJ3VzYWdlQXNzdW1wdGlvbnMuYWxiLmFjdGl2ZUNvbm5lY3Rpb25zUGVyTWludXRlJyxcbiAgICAgICk7XG4gICAgICB2YWxpZGF0ZVBvc2l0aXZlKFxuICAgICAgICBhc3N1bXB0aW9ucy5hbGIucHJvY2Vzc2VkQnl0ZXNHQixcbiAgICAgICAgJ3VzYWdlQXNzdW1wdGlvbnMuYWxiLnByb2Nlc3NlZEJ5dGVzR0InLFxuICAgICAgKTtcbiAgICB9XG5cbiAgICBpZiAoYXNzdW1wdGlvbnMubmxiKSB7XG4gICAgICB2YWxpZGF0ZVBvc2l0aXZlKFxuICAgICAgICBhc3N1bXB0aW9ucy5ubGIubmV3Q29ubmVjdGlvbnNQZXJTZWNvbmQsXG4gICAgICAgICd1c2FnZUFzc3VtcHRpb25zLm5sYi5uZXdDb25uZWN0aW9uc1BlclNlY29uZCcsXG4gICAgICApO1xuICAgICAgdmFsaWRhdGVQb3NpdGl2ZShcbiAgICAgICAgYXNzdW1wdGlvbnMubmxiLmFjdGl2ZUNvbm5lY3Rpb25zUGVyTWludXRlLFxuICAgICAgICAndXNhZ2VBc3N1bXB0aW9ucy5ubGIuYWN0aXZlQ29ubmVjdGlvbnNQZXJNaW51dGUnLFxuICAgICAgKTtcbiAgICAgIHZhbGlkYXRlUG9zaXRpdmUoXG4gICAgICAgIGFzc3VtcHRpb25zLm5sYi5wcm9jZXNzZWRCeXRlc0dCLFxuICAgICAgICAndXNhZ2VBc3N1bXB0aW9ucy5ubGIucHJvY2Vzc2VkQnl0ZXNHQicsXG4gICAgICApO1xuICAgIH1cblxuICAgIGlmIChhc3N1bXB0aW9ucy5jbG91ZGZyb250KSB7XG4gICAgICB2YWxpZGF0ZVBvc2l0aXZlKFxuICAgICAgICBhc3N1bXB0aW9ucy5jbG91ZGZyb250LmRhdGFUcmFuc2ZlckdCLFxuICAgICAgICAndXNhZ2VBc3N1bXB0aW9ucy5jbG91ZGZyb250LmRhdGFUcmFuc2ZlckdCJyxcbiAgICAgICk7XG4gICAgICB2YWxpZGF0ZVBvc2l0aXZlKFxuICAgICAgICBhc3N1bXB0aW9ucy5jbG91ZGZyb250LnJlcXVlc3RzLFxuICAgICAgICAndXNhZ2VBc3N1bXB0aW9ucy5jbG91ZGZyb250LnJlcXVlc3RzJyxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgaWYgKGFzc3VtcHRpb25zLmFwaUdhdGV3YXkpIHtcbiAgICAgIHZhbGlkYXRlUG9zaXRpdmUoXG4gICAgICAgIGFzc3VtcHRpb25zLmFwaUdhdGV3YXkucmVxdWVzdHNQZXJNb250aCxcbiAgICAgICAgJ3VzYWdlQXNzdW1wdGlvbnMuYXBpR2F0ZXdheS5yZXF1ZXN0c1Blck1vbnRoJyxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgaWYgKGFzc3VtcHRpb25zLnZwY0VuZHBvaW50KSB7XG4gICAgICB2YWxpZGF0ZVBvc2l0aXZlKFxuICAgICAgICBhc3N1bXB0aW9ucy52cGNFbmRwb2ludC5kYXRhUHJvY2Vzc2VkR0IsXG4gICAgICAgICd1c2FnZUFzc3VtcHRpb25zLnZwY0VuZHBvaW50LmRhdGFQcm9jZXNzZWRHQicsXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgZGVmYXVsdCBjb25maWd1cmF0aW9uXG4gICAqL1xuICBwcml2YXRlIGdldERlZmF1bHRDb25maWcoKTogQ29zdEFuYWx5emVyQ29uZmlnIHtcbiAgICByZXR1cm4ge1xuICAgICAgY2FjaGU6IHtcbiAgICAgICAgZW5hYmxlZDogdHJ1ZSxcbiAgICAgICAgZHVyYXRpb25Ib3VyczogMjQsXG4gICAgICB9LFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogTWVyZ2UgdXNlciBjb25maWd1cmF0aW9uIHdpdGggZGVmYXVsdHNcbiAgICovXG4gIHByaXZhdGUgbWVyZ2VXaXRoRGVmYXVsdHMoY29uZmlnOiBDb3N0QW5hbHl6ZXJDb25maWcpOiBDb3N0QW5hbHl6ZXJDb25maWcge1xuICAgIGNvbnN0IGRlZmF1bHRzID0gdGhpcy5nZXREZWZhdWx0Q29uZmlnKCk7XG4gICAgcmV0dXJuIHtcbiAgICAgIC4uLmRlZmF1bHRzLFxuICAgICAgLi4uY29uZmlnLFxuICAgICAgY2FjaGU6IHtcbiAgICAgICAgLi4uZGVmYXVsdHMuY2FjaGUsXG4gICAgICAgIC4uLmNvbmZpZy5jYWNoZSxcbiAgICAgIH0sXG4gICAgfTtcbiAgfVxufVxuIl19
@@ -0,0 +1,2 @@
1
+ export * from './ConfigManager';
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("./ConfigManager"), exports);
18
+ __exportStar(require("./types"), exports);
19
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvY29uZmlnL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSxrREFBZ0M7QUFDaEMsMENBQXdCIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0ICogZnJvbSAnLi9Db25maWdNYW5hZ2VyJztcbmV4cG9ydCAqIGZyb20gJy4vdHlwZXMnO1xuIl19