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.
- package/.cdk-cost-analyzer-cache/metadata.json +12 -0
- package/.gitlab-ci.yml +214 -0
- package/.husky/pre-commit +12 -0
- package/.kiro/hooks/accessibility-audit.kiro.hook +18 -0
- package/.kiro/hooks/api-schema-validation.kiro.hook +21 -0
- package/.kiro/hooks/auto-test-on-save.kiro.hook +19 -0
- package/.kiro/hooks/cdk-synth-on-change.kiro.hook +20 -0
- package/.kiro/hooks/code-coverage-check.kiro.hook +14 -0
- package/.kiro/hooks/commit-message-helper.kiro.hook +14 -0
- package/.kiro/hooks/dependency-update-check.kiro.hook +14 -0
- package/.kiro/hooks/env-file-validation.kiro.hook +18 -0
- package/.kiro/hooks/lint-and-format-on-save.kiro.hook +21 -0
- package/.kiro/hooks/mcp-config-validation.kiro.hook +17 -0
- package/.kiro/hooks/mcp-server-test.kiro.hook +14 -0
- package/.kiro/hooks/performance-analysis.kiro.hook +14 -0
- package/.kiro/hooks/readme-spell-check.kiro.hook +14 -0
- package/.kiro/hooks/security-scan-on-dependency-change.kiro.hook +21 -0
- package/.kiro/hooks/translation-update.kiro.hook +18 -0
- package/.kiro/hooks/update-documentation.kiro.hook +18 -0
- package/.kiro/settings/mcp.json +20 -0
- package/.kiro/specs/cdk-cost-analyzer/design.md +620 -0
- package/.kiro/specs/cdk-cost-analyzer/requirements.md +183 -0
- package/.kiro/specs/cdk-cost-analyzer/tasks.md +357 -0
- package/.kiro/specs/github-actions-ci/design.md +281 -0
- package/.kiro/specs/github-actions-ci/requirements.md +86 -0
- package/.kiro/specs/github-actions-ci/tasks.md +115 -0
- package/.kiro/specs/nlb-calculator-test-coverage/design.md +190 -0
- package/.kiro/specs/nlb-calculator-test-coverage/requirements.md +84 -0
- package/.kiro/specs/nlb-calculator-test-coverage/tasks.md +150 -0
- package/.kiro/specs/production-readiness/design.md +1213 -0
- package/.kiro/specs/production-readiness/requirements.md +312 -0
- package/.kiro/specs/production-readiness/tasks.md +269 -0
- package/.kiro/specs/repository-cleanup/design.md +283 -0
- package/.kiro/specs/repository-cleanup/requirements.md +74 -0
- package/.kiro/specs/repository-cleanup/tasks.md +64 -0
- package/.kiro/steering/aws-cli-best-practices.md +41 -0
- package/.kiro/steering/cdk-best-practices.md +49 -0
- package/.kiro/steering/development-standards.md +54 -0
- package/.kiro/steering/docker-best-practices.md +34 -0
- package/.kiro/steering/documentation-style.md +151 -0
- package/.kiro/steering/git-best-practices.md +37 -0
- package/.kiro/steering/mcp-best-practices.md +95 -0
- package/.kiro/steering/python-best-practices.md +48 -0
- package/.kiro/steering/react-best-practices.md +44 -0
- package/.kiro/steering/security-best-practices.md +41 -0
- package/.kiro/steering/testing-best-practices.md +59 -0
- package/.kiro/steering/typescript-best-practices.md +40 -0
- package/CHANGELOG.md +49 -0
- package/CONTRIBUTING.md +258 -0
- package/LICENSE +19 -0
- package/README.md +480 -0
- package/SECURITY.md +117 -0
- package/dist/api/index.d.ts +11 -0
- package/dist/api/index.js +65 -0
- package/dist/api/types.d.ts +15 -0
- package/dist/api/types.js +3 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.js +262 -0
- package/dist/config/ConfigManager.d.ts +40 -0
- package/dist/config/ConfigManager.js +238 -0
- package/dist/config/index.d.ts +2 -0
- package/dist/config/index.js +19 -0
- package/dist/config/types.d.ts +72 -0
- package/dist/config/types.js +15 -0
- package/dist/diff/DiffEngine.d.ts +7 -0
- package/dist/diff/DiffEngine.js +73 -0
- package/dist/diff/index.d.ts +2 -0
- package/dist/diff/index.js +21 -0
- package/dist/diff/types.d.ts +20 -0
- package/dist/diff/types.js +3 -0
- package/dist/integrations/GitLabIntegration.d.ts +7 -0
- package/dist/integrations/GitLabIntegration.js +45 -0
- package/dist/integrations/index.d.ts +2 -0
- package/dist/integrations/index.js +21 -0
- package/dist/integrations/types.d.ts +11 -0
- package/dist/integrations/types.js +13 -0
- package/dist/parser/TemplateParser.d.ts +8 -0
- package/dist/parser/TemplateParser.js +75 -0
- package/dist/parser/index.d.ts +2 -0
- package/dist/parser/index.js +22 -0
- package/dist/parser/types.d.ts +30 -0
- package/dist/parser/types.js +3 -0
- package/dist/pipeline/PipelineOrchestrator.d.ts +23 -0
- package/dist/pipeline/PipelineOrchestrator.js +191 -0
- package/dist/pipeline/index.d.ts +2 -0
- package/dist/pipeline/index.js +19 -0
- package/dist/pipeline/types.d.ts +41 -0
- package/dist/pipeline/types.js +13 -0
- package/dist/pricing/CacheManager.d.ts +75 -0
- package/dist/pricing/CacheManager.js +195 -0
- package/dist/pricing/PricingClient.d.ts +17 -0
- package/dist/pricing/PricingClient.js +122 -0
- package/dist/pricing/PricingService.d.ts +16 -0
- package/dist/pricing/PricingService.js +149 -0
- package/dist/pricing/calculators/ALBCalculator.d.ts +16 -0
- package/dist/pricing/calculators/ALBCalculator.js +163 -0
- package/dist/pricing/calculators/APIGatewayCalculator.d.ts +10 -0
- package/dist/pricing/calculators/APIGatewayCalculator.js +177 -0
- package/dist/pricing/calculators/CloudFrontCalculator.d.ts +59 -0
- package/dist/pricing/calculators/CloudFrontCalculator.js +151 -0
- package/dist/pricing/calculators/DynamoDBCalculator.d.ts +9 -0
- package/dist/pricing/calculators/DynamoDBCalculator.js +146 -0
- package/dist/pricing/calculators/EC2Calculator.d.ts +7 -0
- package/dist/pricing/calculators/EC2Calculator.js +80 -0
- package/dist/pricing/calculators/ECSCalculator.d.ts +9 -0
- package/dist/pricing/calculators/ECSCalculator.js +116 -0
- package/dist/pricing/calculators/ElastiCacheCalculator.d.ts +8 -0
- package/dist/pricing/calculators/ElastiCacheCalculator.js +106 -0
- package/dist/pricing/calculators/LambdaCalculator.d.ts +13 -0
- package/dist/pricing/calculators/LambdaCalculator.js +111 -0
- package/dist/pricing/calculators/NLBCalculator.d.ts +16 -0
- package/dist/pricing/calculators/NLBCalculator.js +138 -0
- package/dist/pricing/calculators/NatGatewayCalculator.d.ts +12 -0
- package/dist/pricing/calculators/NatGatewayCalculator.js +116 -0
- package/dist/pricing/calculators/RDSCalculator.d.ts +9 -0
- package/dist/pricing/calculators/RDSCalculator.js +103 -0
- package/dist/pricing/calculators/S3Calculator.d.ts +8 -0
- package/dist/pricing/calculators/S3Calculator.js +68 -0
- package/dist/pricing/calculators/VPCEndpointCalculator.d.ts +12 -0
- package/dist/pricing/calculators/VPCEndpointCalculator.js +129 -0
- package/dist/pricing/index.d.ts +10 -0
- package/dist/pricing/index.js +37 -0
- package/dist/pricing/types.d.ts +53 -0
- package/dist/pricing/types.js +22 -0
- package/dist/releasetag.txt +1 -0
- package/dist/reporter/Reporter.d.ts +18 -0
- package/dist/reporter/Reporter.js +412 -0
- package/dist/reporter/index.d.ts +2 -0
- package/dist/reporter/index.js +21 -0
- package/dist/reporter/types.d.ts +72 -0
- package/dist/reporter/types.js +3 -0
- package/dist/synthesis/SynthesisOrchestrator.d.ts +26 -0
- package/dist/synthesis/SynthesisOrchestrator.js +243 -0
- package/dist/synthesis/index.d.ts +2 -0
- package/dist/synthesis/index.js +19 -0
- package/dist/synthesis/types.d.ts +17 -0
- package/dist/synthesis/types.js +13 -0
- package/dist/threshold/ThresholdEnforcer.d.ts +29 -0
- package/dist/threshold/ThresholdEnforcer.js +143 -0
- package/dist/threshold/index.d.ts +2 -0
- package/dist/threshold/index.js +19 -0
- package/dist/threshold/types.d.ts +15 -0
- package/dist/threshold/types.js +17 -0
- package/docs/CALCULATORS.md +820 -0
- package/docs/CI_CD.md +608 -0
- package/docs/CONFIGURATION.md +407 -0
- package/docs/DEVELOPMENT.md +387 -0
- package/docs/RELEASE.md +223 -0
- package/docs/TROUBLESHOOTING.md +847 -0
- package/examples/.cdk-cost-analyzer.yml +85 -0
- package/examples/.gitlab-ci.yml +125 -0
- package/examples/api-usage.js +26 -0
- package/examples/complex/base.json +16 -0
- package/examples/complex/target.json +29 -0
- package/examples/monorepo/.gitlab-ci.yml +251 -0
- package/examples/monorepo/README.md +341 -0
- package/examples/monorepo/package.json +27 -0
- package/examples/monorepo/packages/backend-infra/.cdk-cost-analyzer.yml +34 -0
- package/examples/monorepo/packages/backend-infra/bin/app.ts +16 -0
- package/examples/monorepo/packages/backend-infra/cdk.json +7 -0
- package/examples/monorepo/packages/backend-infra/lib/backend-stack.ts +128 -0
- package/examples/monorepo/packages/backend-infra/package.json +30 -0
- package/examples/monorepo/packages/backend-infra/tsconfig.json +11 -0
- package/examples/monorepo/packages/data-infra/.cdk-cost-analyzer.yml +38 -0
- package/examples/monorepo/packages/data-infra/bin/app.ts +16 -0
- package/examples/monorepo/packages/data-infra/cdk.json +7 -0
- package/examples/monorepo/packages/data-infra/lib/data-stack.ts +121 -0
- package/examples/monorepo/packages/data-infra/package.json +30 -0
- package/examples/monorepo/packages/data-infra/tsconfig.json +11 -0
- package/examples/monorepo/packages/frontend-infra/.cdk-cost-analyzer.yml +31 -0
- package/examples/monorepo/packages/frontend-infra/bin/app.ts +16 -0
- package/examples/monorepo/packages/frontend-infra/cdk.json +7 -0
- package/examples/monorepo/packages/frontend-infra/lib/frontend-stack.ts +60 -0
- package/examples/monorepo/packages/frontend-infra/package.json +30 -0
- package/examples/monorepo/packages/frontend-infra/tsconfig.json +11 -0
- package/examples/monorepo/tsconfig.json +35 -0
- package/examples/multi-stack/.cdk-cost-analyzer.yml +72 -0
- package/examples/multi-stack/.gitlab-ci.yml +184 -0
- package/examples/multi-stack/README.md +279 -0
- package/examples/multi-stack/bin/app.ts +36 -0
- package/examples/multi-stack/cdk.json +72 -0
- package/examples/multi-stack/lib/compute-stack.ts +128 -0
- package/examples/multi-stack/lib/networking-stack.ts +69 -0
- package/examples/multi-stack/lib/storage-stack.ts +141 -0
- package/examples/multi-stack/package-lock.json +4437 -0
- package/examples/multi-stack/package.json +42 -0
- package/examples/multi-stack/tsconfig.json +34 -0
- package/examples/simple/base.json +8 -0
- package/examples/simple/target.json +14 -0
- package/examples/single-stack/.NVP +0 -0
- package/examples/single-stack/.cdk-cost-analyzer.yml +52 -0
- package/examples/single-stack/.gitlab-ci.yml +126 -0
- package/examples/single-stack/README.md +184 -0
- package/examples/single-stack/UeK +0 -0
- package/examples/single-stack/bin/app.ts +16 -0
- package/examples/single-stack/cdk.json +72 -0
- package/examples/single-stack/lib/infrastructure-stack.ts +119 -0
- package/examples/single-stack/package-lock.json +4443 -0
- package/examples/single-stack/package.json +38 -0
- package/examples/single-stack/tsconfig.json +34 -0
- package/package.json +139 -0
- package/test-cdk-project/README-COMPUTE.md +141 -0
- package/test-cdk-project/README.md +95 -0
- package/test-cdk-project/app-with-compute.js +102 -0
- package/test-cdk-project/app.js +81 -0
- package/test-cdk-project/cdk-compute.json +3 -0
- package/test-cdk-project/cdk.context.json +7 -0
- package/test-cdk-project/cdk.json +3 -0
- package/test-cdk-project/cdk.out/TestStack.assets.json +21 -0
- package/test-cdk-project/cdk.out/TestStack.template.json +115 -0
- package/test-cdk-project/cdk.out/cdk.out +1 -0
- package/test-cdk-project/cdk.out/manifest.json +503 -0
- package/test-cdk-project/cdk.out/tree.json +1 -0
- package/test-cdk-project/cdk.out.base/TestStack.assets.json +21 -0
- package/test-cdk-project/cdk.out.base/TestStack.template.json +115 -0
- package/test-cdk-project/cdk.out.base/cdk.out +1 -0
- package/test-cdk-project/cdk.out.base/manifest.json +503 -0
- package/test-cdk-project/cdk.out.base/tree.json +1 -0
- package/test-cdk-project/cdk.out.target/TestStack.assets.json +21 -0
- package/test-cdk-project/cdk.out.target/TestStack.template.json +183 -0
- package/test-cdk-project/cdk.out.target/cdk.out +1 -0
- package/test-cdk-project/cdk.out.target/manifest.json +521 -0
- package/test-cdk-project/cdk.out.target/tree.json +1 -0
- package/test-cdk-project/package-lock.json +422 -0
- package/test-cdk-project/package.json +17 -0
- package/tools/workflows/README.md +102 -0
- package/tools/workflows/validate-workflows.js +109 -0
- package/tools/workflows/workflow-utils.ts +181 -0
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PricingClient = void 0;
|
|
4
|
+
const client_pricing_1 = require("@aws-sdk/client-pricing");
|
|
5
|
+
const types_1 = require("./types");
|
|
6
|
+
class PricingClient {
|
|
7
|
+
cache = new Map();
|
|
8
|
+
client;
|
|
9
|
+
cacheManager;
|
|
10
|
+
constructor(region = 'us-east-1', cacheManager, awsClient) {
|
|
11
|
+
this.client = awsClient || new client_pricing_1.PricingClient({ region });
|
|
12
|
+
this.cacheManager = cacheManager;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Clean up resources and connections
|
|
16
|
+
*/
|
|
17
|
+
destroy() {
|
|
18
|
+
this.cache.clear();
|
|
19
|
+
// AWS SDK v3 clients automatically clean up their connections
|
|
20
|
+
// but we can help by clearing references
|
|
21
|
+
if (this.client && typeof this.client.destroy === 'function') {
|
|
22
|
+
this.client.destroy();
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
async getPrice(params) {
|
|
26
|
+
const cacheKey = this.getCacheKey(params);
|
|
27
|
+
// Check in-memory cache first
|
|
28
|
+
if (this.cache.has(cacheKey)) {
|
|
29
|
+
return this.cache.get(cacheKey);
|
|
30
|
+
}
|
|
31
|
+
// Check persistent cache if cache manager is available
|
|
32
|
+
if (this.cacheManager) {
|
|
33
|
+
const cachedPrice = this.cacheManager.getCachedPrice(params);
|
|
34
|
+
if (cachedPrice !== null) {
|
|
35
|
+
// Store in memory cache for faster subsequent access
|
|
36
|
+
this.cache.set(cacheKey, cachedPrice);
|
|
37
|
+
return cachedPrice;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
try {
|
|
41
|
+
const price = await this.fetchPriceWithRetry(params);
|
|
42
|
+
if (price !== null) {
|
|
43
|
+
// Store in both memory and persistent cache
|
|
44
|
+
this.cache.set(cacheKey, price);
|
|
45
|
+
if (this.cacheManager) {
|
|
46
|
+
this.cacheManager.setCachedPrice(params, price);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return price;
|
|
50
|
+
}
|
|
51
|
+
catch (error) {
|
|
52
|
+
// On API failure, try to use cached data even if stale
|
|
53
|
+
if (this.cache.has(cacheKey)) {
|
|
54
|
+
return this.cache.get(cacheKey);
|
|
55
|
+
}
|
|
56
|
+
if (this.cacheManager) {
|
|
57
|
+
const cachedPrice = this.cacheManager.getCachedPrice(params);
|
|
58
|
+
if (cachedPrice !== null) {
|
|
59
|
+
return cachedPrice;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
async fetchPriceWithRetry(params, maxRetries = 3) {
|
|
66
|
+
let lastError = null;
|
|
67
|
+
for (let attempt = 0; attempt < maxRetries; attempt++) {
|
|
68
|
+
try {
|
|
69
|
+
return await this.fetchPrice(params);
|
|
70
|
+
}
|
|
71
|
+
catch (error) {
|
|
72
|
+
lastError = error;
|
|
73
|
+
if (attempt < maxRetries - 1) {
|
|
74
|
+
const delay = Math.pow(2, attempt) * 1000;
|
|
75
|
+
await new Promise(resolve => setTimeout(resolve, delay));
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
throw new types_1.PricingAPIError(`Failed to fetch pricing after ${maxRetries} attempts: ${lastError?.message}`, false);
|
|
80
|
+
}
|
|
81
|
+
async fetchPrice(params) {
|
|
82
|
+
const filters = params.filters.map(f => ({
|
|
83
|
+
Type: f.type || 'TERM_MATCH',
|
|
84
|
+
Field: f.field,
|
|
85
|
+
Value: f.value,
|
|
86
|
+
}));
|
|
87
|
+
const command = new client_pricing_1.GetProductsCommand({
|
|
88
|
+
ServiceCode: params.serviceCode,
|
|
89
|
+
Filters: filters,
|
|
90
|
+
MaxResults: 1,
|
|
91
|
+
});
|
|
92
|
+
const response = await this.client.send(command);
|
|
93
|
+
if (!response.PriceList || response.PriceList.length === 0) {
|
|
94
|
+
return null;
|
|
95
|
+
}
|
|
96
|
+
const priceItem = JSON.parse(response.PriceList[0]);
|
|
97
|
+
const onDemand = priceItem?.terms?.OnDemand;
|
|
98
|
+
if (!onDemand) {
|
|
99
|
+
return null;
|
|
100
|
+
}
|
|
101
|
+
const termKey = Object.keys(onDemand)[0];
|
|
102
|
+
const priceDimensions = onDemand[termKey]?.priceDimensions;
|
|
103
|
+
if (!priceDimensions) {
|
|
104
|
+
return null;
|
|
105
|
+
}
|
|
106
|
+
const dimensionKey = Object.keys(priceDimensions)[0];
|
|
107
|
+
const pricePerUnit = priceDimensions[dimensionKey]?.pricePerUnit?.USD;
|
|
108
|
+
if (!pricePerUnit) {
|
|
109
|
+
return null;
|
|
110
|
+
}
|
|
111
|
+
return parseFloat(pricePerUnit);
|
|
112
|
+
}
|
|
113
|
+
getCacheKey(params) {
|
|
114
|
+
const filterStr = params.filters
|
|
115
|
+
.map(f => `${f.field}:${f.value}`)
|
|
116
|
+
.sort()
|
|
117
|
+
.join('|');
|
|
118
|
+
return `${params.serviceCode}:${params.region}:${filterStr}`;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
exports.PricingClient = PricingClient;
|
|
122
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUHJpY2luZ0NsaWVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9wcmljaW5nL1ByaWNpbmdDbGllbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsNERBQWdHO0FBRWhHLG1DQUE2RjtBQUU3RixNQUFhLGFBQWE7SUFDaEIsS0FBSyxHQUF3QixJQUFJLEdBQUcsRUFBRSxDQUFDO0lBQ3ZDLE1BQU0sQ0FBbUI7SUFDekIsWUFBWSxDQUFnQjtJQUVwQyxZQUNFLFNBQWlCLFdBQVcsRUFDNUIsWUFBMkIsRUFDM0IsU0FBNEI7UUFFNUIsSUFBSSxDQUFDLE1BQU0sR0FBRyxTQUFTLElBQUksSUFBSSw4QkFBZ0IsQ0FBQyxFQUFFLE1BQU0sRUFBRSxDQUFDLENBQUM7UUFDNUQsSUFBSSxDQUFDLFlBQVksR0FBRyxZQUFZLENBQUM7SUFDbkMsQ0FBQztJQUVEOztPQUVHO0lBQ0gsT0FBTztRQUNMLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDbkIsOERBQThEO1FBQzlELHlDQUF5QztRQUN6QyxJQUFJLElBQUksQ0FBQyxNQUFNLElBQUksT0FBUSxJQUFJLENBQUMsTUFBYyxDQUFDLE9BQU8sS0FBSyxVQUFVLEVBQUUsQ0FBQztZQUNyRSxJQUFJLENBQUMsTUFBYyxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ2pDLENBQUM7SUFDSCxDQUFDO0lBRUQsS0FBSyxDQUFDLFFBQVEsQ0FBQyxNQUF3QjtRQUNyQyxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBRTFDLDhCQUE4QjtRQUM5QixJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUM7WUFDN0IsT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUUsQ0FBQztRQUNuQyxDQUFDO1FBRUQsdURBQXVEO1FBQ3ZELElBQUksSUFBSSxD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ZCxDQUFDO1FBRUQsT0FBTyxVQUFVLENBQUMsWUFBWSxDQUFDLENBQUM7SUFDbEMsQ0FBQztJQUVPLFdBQVcsQ0FBQyxNQUF3QjtRQUMxQyxNQUFNLFNBQVMsR0FBRyxNQUFNLENBQUMsT0FBTzthQUM3QixHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxLQUFLLElBQUksQ0FBQyxDQUFDLEtBQUssRUFBRSxDQUFDO2FBQ2pDLElBQUksRUFBRTthQUNOLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUNiLE9BQU8sR0FBRyxNQUFNLENBQUMsV0FBVyxJQUFJLE1BQU0sQ0FBQyxNQUFNLElBQUksU0FBUyxFQUFFLENBQUM7SUFDL0QsQ0FBQztDQUNGO0FBNUlELHNDQTRJQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFByaWNpbmdDbGllbnQgYXMgQVdTUHJpY2luZ0NsaWVudCwgR2V0UHJvZHVjdHNDb21tYW5kIH0gZnJvbSAnQGF3cy1zZGsvY2xpZW50LXByaWNpbmcnO1xuaW1wb3J0IHsgQ2FjaGVNYW5hZ2VyIH0gZnJvbSAnLi9DYWNoZU1hbmFnZXInO1xuaW1wb3J0IHsgUHJpY2luZ0NsaWVudCBhcyBJUHJpY2luZ0NsaWVudCwgUHJpY2VRdWVyeVBhcmFtcywgUHJpY2luZ0FQSUVycm9yIH0gZnJvbSAnLi90eXBlcyc7XG5cbmV4cG9ydCBjbGFzcyBQcmljaW5nQ2xpZW50IGltcGxlbWVudHMgSVByaWNpbmdDbGllbnQge1xuICBwcml2YXRlIGNhY2hlOiBNYXA8c3RyaW5nLCBudW1iZXI+ID0gbmV3IE1hcCgpO1xuICBwcml2YXRlIGNsaWVudDogQVdTUHJpY2luZ0NsaWVudDtcbiAgcHJpdmF0ZSBjYWNoZU1hbmFnZXI/OiBDYWNoZU1hbmFnZXI7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcmVnaW9uOiBzdHJpbmcgPSAndXMtZWFzdC0xJyxcbiAgICBjYWNoZU1hbmFnZXI/OiBDYWNoZU1hbmFnZXIsXG4gICAgYXdzQ2xpZW50PzogQVdTUHJpY2luZ0NsaWVudCxcbiAgKSB7XG4gICAgdGhpcy5jbGllbnQgPSBhd3NDbGllbnQgfHwgbmV3IEFXU1ByaWNpbmdDbGllbnQoeyByZWdpb24gfSk7XG4gICAgdGhpcy5jYWNoZU1hbmFnZXIgPSBjYWNoZU1hbmFnZXI7XG4gIH1cblxuICAvKipcbiAgICogQ2xlYW4gdXAgcmVzb3VyY2VzIGFuZCBjb25uZWN0aW9uc1xuICAgKi9cbiAgZGVzdHJveSgpOiB2b2lkIHtcbiAgICB0aGlzLmNhY2hlLmNsZWFyKCk7XG4gICAgLy8gQVdTIFNESyB2MyBjbGllbnRzIGF1dG9tYXRpY2FsbHkgY2xlYW4gdXAgdGhlaXIgY29ubmVjdGlvbnNcbiAgICAvLyBidXQgd2UgY2FuIGhlbHAgYnkgY2xlYXJpbmcgcmVmZXJlbmNlc1xuICAgIGlmICh0aGlzLmNsaWVudCAmJiB0eXBlb2YgKHRoaXMuY2xpZW50IGFzIGFueSkuZGVzdHJveSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgKHRoaXMuY2xpZW50IGFzIGFueSkuZGVzdHJveSgpO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIGdldFByaWNlKHBhcmFtczogUHJpY2VRdWVyeVBhcmFtcyk6IFByb21pc2U8bnVtYmVyIHwgbnVsbD4ge1xuICAgIGNvbnN0IGNhY2hlS2V5ID0gdGhpcy5nZXRDYWNoZUtleShwYXJhbXMpO1xuXG4gICAgLy8gQ2hlY2sgaW4tbWVtb3J5IGNhY2hlIGZpcnN0XG4gICAgaWYgKHRoaXMuY2FjaGUuaGFzKGNhY2hlS2V5KSkge1xuICAgICAgcmV0dXJuIHRoaXMuY2FjaGUuZ2V0KGNhY2hlS2V5KSE7XG4gICAgfVxuXG4gICAgLy8gQ2hlY2sgcGVyc2lzdGVudCBjYWNoZSBpZiBjYWNoZSBtYW5hZ2VyIGlzIGF2YWlsYWJsZVxuICAgIGlmICh0aGlzLmNhY2hlTWFuYWdlcikge1xuICAgICAgY29uc3QgY2FjaGVkUHJpY2UgPSB0aGlzLmNhY2hlTWFuYWdlci5nZXRDYWNoZWRQcmljZShwYXJhbXMpO1xuICAgICAgaWYgKGNhY2hlZFByaWNlICE9PSBudWxsKSB7XG4gICAgICAgIC8vIFN0b3JlIGluIG1lbW9yeSBjYWNoZSBmb3IgZmFzdGVyIHN1YnNlcXVlbnQgYWNjZXNzXG4gICAgICAgIHRoaXMuY2FjaGUuc2V0KGNhY2hlS2V5LCBjYWNoZWRQcmljZSk7XG4gICAgICAgIHJldHVybiBjYWNoZWRQcmljZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgcHJpY2UgPSBhd2FpdCB0aGlzLmZldGNoUHJpY2VXaXRoUmV0cnkocGFyYW1zKTtcbiAgICAgIGlmIChwcmljZSAhPT0gbnVsbCkge1xuICAgICAgICAvLyBTdG9yZSBpbiBib3RoIG1lbW9yeSBhbmQgcGVyc2lzdGVudCBjYWNoZVxuICAgICAgICB0aGlzLmNhY2hlLnNldChjYWNoZUtleSwgcHJpY2UpO1xuICAgICAgICBpZiAodGhpcy5jYWNoZU1hbmFnZXIpIHtcbiAgICAgICAgICB0aGlzLmNhY2hlTWFuYWdlci5zZXRDYWNoZWRQcmljZShwYXJhbXMsIHByaWNlKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIHByaWNlO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAvLyBPbiBBUEkgZmFpbHVyZSwgdHJ5IHRvIHVzZSBjYWNoZWQgZGF0YSBldmVuIGlmIHN0YWxlXG4gICAgICBpZiAodGhpcy5jYWNoZS5oYXMoY2FjaGVLZXkpKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNhY2hlLmdldChjYWNoZUtleSkhO1xuICAgICAgfVxuICAgICAgaWYgKHRoaXMuY2FjaGVNYW5hZ2VyKSB7XG4gICAgICAgIGNvbnN0IGNhY2hlZFByaWNlID0gdGhpcy5jYWNoZU1hbmFnZXIuZ2V0Q2FjaGVkUHJpY2UocGFyYW1zKTtcbiAgICAgICAgaWYgKGNhY2hlZFByaWNlICE9PSBudWxsKSB7XG4gICAgICAgICAgcmV0dXJuIGNhY2hlZFByaWNlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGZldGNoUHJpY2VXaXRoUmV0cnkocGFyYW1zOiBQcmljZVF1ZXJ5UGFyYW1zLCBtYXhSZXRyaWVzOiBudW1iZXIgPSAzKTogUHJvbWlzZTxudW1iZXIgfCBudWxsPiB7XG4gICAgbGV0IGxhc3RFcnJvcjogRXJyb3IgfCBudWxsID0gbnVsbDtcblxuICAgIGZvciAobGV0IGF0dGVtcHQgPSAwOyBhdHRlbXB0IDwgbWF4UmV0cmllczsgYXR0ZW1wdCsrKSB7XG4gICAgICB0cnkge1xuICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5mZXRjaFByaWNlKHBhcmFtcyk7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBsYXN0RXJyb3IgPSBlcnJvciBhcyBFcnJvcjtcbiAgICAgICAgaWYgKGF0dGVtcHQgPCBtYXhSZXRyaWVzIC0gMSkge1xuICAgICAgICAgIGNvbnN0IGRlbGF5ID0gTWF0aC5wb3coMiwgYXR0ZW1wdCkgKiAxMDAwO1xuICAgICAgICAgIGF3YWl0IG5ldyBQcm9taXNlKHJlc29sdmUgPT4gc2V0VGltZW91dChyZXNvbHZlLCBkZWxheSkpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhyb3cgbmV3IFByaWNpbmdBUElFcnJvcihcbiAgICAgIGBGYWlsZWQgdG8gZmV0Y2ggcHJpY2luZyBhZnRlciAke21heFJldHJpZXN9IGF0dGVtcHRzOiAke2xhc3RFcnJvcj8ubWVzc2FnZX1gLFxuICAgICAgZmFsc2UsXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgZmV0Y2hQcmljZShwYXJhbXM6IFByaWNlUXVlcnlQYXJhbXMpOiBQcm9taXNlPG51bWJlciB8IG51bGw+IHtcbiAgICBjb25zdCBmaWx0ZXJzID0gcGFyYW1zLmZpbHRlcnMubWFwKGYgPT4gKHtcbiAgICAgIFR5cGU6IGYudHlwZSB8fCAnVEVSTV9NQVRDSCcsXG4gICAgICBGaWVsZDogZi5maWVsZCxcbiAgICAgIFZhbHVlOiBmLnZhbHVlLFxuICAgIH0pKTtcblxuICAgIGNvbnN0IGNvbW1hbmQgPSBuZXcgR2V0UHJvZHVjdHNDb21tYW5kKHtcbiAgICAgIFNlcnZpY2VDb2RlOiBwYXJhbXMuc2VydmljZUNvZGUsXG4gICAgICBGaWx0ZXJzOiBmaWx0ZXJzLFxuICAgICAgTWF4UmVzdWx0czogMSxcbiAgICB9KTtcblxuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgdGhpcy5jbGllbnQuc2VuZChjb21tYW5kKTtcblxuICAgIGlmICghcmVzcG9uc2UuUHJpY2VMaXN0IHx8IHJlc3BvbnNlLlByaWNlTGlzdC5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIGNvbnN0IHByaWNlSXRlbSA9IEpTT04ucGFyc2UocmVzcG9uc2UuUHJpY2VMaXN0WzBdKTtcbiAgICBjb25zdCBvbkRlbWFuZCA9IHByaWNlSXRlbT8udGVybXM/Lk9uRGVtYW5kO1xuXG4gICAgaWYgKCFvbkRlbWFuZCkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgY29uc3QgdGVybUtleSA9IE9iamVjdC5rZXlzKG9uRGVtYW5kKVswXTtcbiAgICBjb25zdCBwcmljZURpbWVuc2lvbnMgPSBvbkRlbWFuZFt0ZXJtS2V5XT8ucHJpY2VEaW1lbnNpb25zO1xuXG4gICAgaWYgKCFwcmljZURpbWVuc2lvbnMpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIGNvbnN0IGRpbWVuc2lvbktleSA9IE9iamVjdC5rZXlzKHByaWNlRGltZW5zaW9ucylbMF07XG4gICAgY29uc3QgcHJpY2VQZXJVbml0ID0gcHJpY2VEaW1lbnNpb25zW2RpbWVuc2lvbktleV0/LnByaWNlUGVyVW5pdD8uVVNEO1xuXG4gICAgaWYgKCFwcmljZVBlclVuaXQpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIHJldHVybiBwYXJzZUZsb2F0KHByaWNlUGVyVW5pdCk7XG4gIH1cblxuICBwcml2YXRlIGdldENhY2hlS2V5KHBhcmFtczogUHJpY2VRdWVyeVBhcmFtcyk6IHN0cmluZyB7XG4gICAgY29uc3QgZmlsdGVyU3RyID0gcGFyYW1zLmZpbHRlcnNcbiAgICAgIC5tYXAoZiA9PiBgJHtmLmZpZWxkfToke2YudmFsdWV9YClcbiAgICAgIC5zb3J0KClcbiAgICAgIC5qb2luKCd8Jyk7XG4gICAgcmV0dXJuIGAke3BhcmFtcy5zZXJ2aWNlQ29kZX06JHtwYXJhbXMucmVnaW9ufToke2ZpbHRlclN0cn1gO1xuICB9XG59XG4iXX0=
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { PricingClient } from './PricingClient';
|
|
2
|
+
import { PricingService as IPricingService, MonthlyCost, CostDelta } from './types';
|
|
3
|
+
import { UsageAssumptionsConfig, CacheConfig } from '../config/types';
|
|
4
|
+
import { ResourceWithId, ResourceDiff } from '../diff/types';
|
|
5
|
+
export declare class PricingService implements IPricingService {
|
|
6
|
+
private calculators;
|
|
7
|
+
private pricingClient;
|
|
8
|
+
private excludedResourceTypes;
|
|
9
|
+
constructor(region?: string, usageAssumptions?: UsageAssumptionsConfig, excludedResourceTypes?: string[], cacheConfig?: CacheConfig, pricingClient?: PricingClient);
|
|
10
|
+
getResourceCost(resource: ResourceWithId, region: string): Promise<MonthlyCost>;
|
|
11
|
+
getCostDelta(diff: ResourceDiff, region: string): Promise<CostDelta>;
|
|
12
|
+
/**
|
|
13
|
+
* Clean up resources and connections
|
|
14
|
+
*/
|
|
15
|
+
destroy(): void;
|
|
16
|
+
}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PricingService = void 0;
|
|
4
|
+
const CacheManager_1 = require("./CacheManager");
|
|
5
|
+
const ALBCalculator_1 = require("./calculators/ALBCalculator");
|
|
6
|
+
const APIGatewayCalculator_1 = require("./calculators/APIGatewayCalculator");
|
|
7
|
+
const CloudFrontCalculator_1 = require("./calculators/CloudFrontCalculator");
|
|
8
|
+
const DynamoDBCalculator_1 = require("./calculators/DynamoDBCalculator");
|
|
9
|
+
const EC2Calculator_1 = require("./calculators/EC2Calculator");
|
|
10
|
+
const ECSCalculator_1 = require("./calculators/ECSCalculator");
|
|
11
|
+
const ElastiCacheCalculator_1 = require("./calculators/ElastiCacheCalculator");
|
|
12
|
+
const LambdaCalculator_1 = require("./calculators/LambdaCalculator");
|
|
13
|
+
const NatGatewayCalculator_1 = require("./calculators/NatGatewayCalculator");
|
|
14
|
+
const NLBCalculator_1 = require("./calculators/NLBCalculator");
|
|
15
|
+
const RDSCalculator_1 = require("./calculators/RDSCalculator");
|
|
16
|
+
const S3Calculator_1 = require("./calculators/S3Calculator");
|
|
17
|
+
const VPCEndpointCalculator_1 = require("./calculators/VPCEndpointCalculator");
|
|
18
|
+
const PricingClient_1 = require("./PricingClient");
|
|
19
|
+
class PricingService {
|
|
20
|
+
calculators;
|
|
21
|
+
pricingClient;
|
|
22
|
+
excludedResourceTypes;
|
|
23
|
+
constructor(region = 'us-east-1', usageAssumptions, excludedResourceTypes, cacheConfig, pricingClient) {
|
|
24
|
+
// Use provided pricing client or create a new one
|
|
25
|
+
if (pricingClient) {
|
|
26
|
+
this.pricingClient = pricingClient;
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
// Initialize cache manager if caching is enabled
|
|
30
|
+
let cacheManager;
|
|
31
|
+
if (cacheConfig?.enabled !== false) {
|
|
32
|
+
const cacheDuration = cacheConfig?.durationHours ?? 24;
|
|
33
|
+
cacheManager = new CacheManager_1.CacheManager('.cdk-cost-analyzer-cache', cacheDuration);
|
|
34
|
+
}
|
|
35
|
+
this.pricingClient = new PricingClient_1.PricingClient(region, cacheManager);
|
|
36
|
+
}
|
|
37
|
+
this.excludedResourceTypes = new Set(excludedResourceTypes || []);
|
|
38
|
+
this.calculators = [
|
|
39
|
+
new EC2Calculator_1.EC2Calculator(),
|
|
40
|
+
new S3Calculator_1.S3Calculator(),
|
|
41
|
+
new LambdaCalculator_1.LambdaCalculator(usageAssumptions?.lambda?.invocationsPerMonth, usageAssumptions?.lambda?.averageDurationMs),
|
|
42
|
+
new RDSCalculator_1.RDSCalculator(),
|
|
43
|
+
new DynamoDBCalculator_1.DynamoDBCalculator(),
|
|
44
|
+
new ECSCalculator_1.ECSCalculator(),
|
|
45
|
+
new APIGatewayCalculator_1.APIGatewayCalculator(),
|
|
46
|
+
new NatGatewayCalculator_1.NatGatewayCalculator(usageAssumptions?.natGateway?.dataProcessedGB),
|
|
47
|
+
new ALBCalculator_1.ALBCalculator(usageAssumptions?.alb?.newConnectionsPerSecond, usageAssumptions?.alb?.activeConnectionsPerMinute, usageAssumptions?.alb?.processedBytesGB),
|
|
48
|
+
new NLBCalculator_1.NLBCalculator(usageAssumptions?.nlb?.newConnectionsPerSecond, usageAssumptions?.nlb?.activeConnectionsPerMinute, usageAssumptions?.nlb?.processedBytesGB),
|
|
49
|
+
new VPCEndpointCalculator_1.VPCEndpointCalculator(usageAssumptions?.vpcEndpoint?.dataProcessedGB),
|
|
50
|
+
new CloudFrontCalculator_1.CloudFrontCalculator(usageAssumptions?.cloudfront?.dataTransferGB, usageAssumptions?.cloudfront?.requests),
|
|
51
|
+
new ElastiCacheCalculator_1.ElastiCacheCalculator(),
|
|
52
|
+
];
|
|
53
|
+
}
|
|
54
|
+
async getResourceCost(resource, region) {
|
|
55
|
+
// Check if resource type is excluded
|
|
56
|
+
if (this.excludedResourceTypes.has(resource.type)) {
|
|
57
|
+
return {
|
|
58
|
+
amount: 0,
|
|
59
|
+
currency: 'USD',
|
|
60
|
+
confidence: 'high',
|
|
61
|
+
assumptions: [`Resource type ${resource.type} is excluded from cost analysis`],
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
const calculator = this.calculators.find(calc => calc.supports(resource.type));
|
|
65
|
+
if (!calculator) {
|
|
66
|
+
return {
|
|
67
|
+
amount: 0,
|
|
68
|
+
currency: 'USD',
|
|
69
|
+
confidence: 'unknown',
|
|
70
|
+
assumptions: [`Resource type ${resource.type} is not supported`],
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
try {
|
|
74
|
+
return await calculator.calculateCost(resource, region, this.pricingClient);
|
|
75
|
+
}
|
|
76
|
+
catch (error) {
|
|
77
|
+
return {
|
|
78
|
+
amount: 0,
|
|
79
|
+
currency: 'USD',
|
|
80
|
+
confidence: 'unknown',
|
|
81
|
+
assumptions: [`Failed to calculate cost: ${error instanceof Error ? error.message : String(error)}`],
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
async getCostDelta(diff, region) {
|
|
86
|
+
// Filter out excluded resources before processing
|
|
87
|
+
const filteredAdded = diff.added.filter(r => !this.excludedResourceTypes.has(r.type));
|
|
88
|
+
const filteredRemoved = diff.removed.filter(r => !this.excludedResourceTypes.has(r.type));
|
|
89
|
+
const filteredModified = diff.modified.filter(r => !this.excludedResourceTypes.has(r.type));
|
|
90
|
+
const addedCosts = await Promise.all(filteredAdded.map(async (resource) => {
|
|
91
|
+
const monthlyCost = await this.getResourceCost(resource, region);
|
|
92
|
+
return {
|
|
93
|
+
logicalId: resource.logicalId,
|
|
94
|
+
type: resource.type,
|
|
95
|
+
monthlyCost,
|
|
96
|
+
};
|
|
97
|
+
}));
|
|
98
|
+
const removedCosts = await Promise.all(filteredRemoved.map(async (resource) => {
|
|
99
|
+
const monthlyCost = await this.getResourceCost(resource, region);
|
|
100
|
+
return {
|
|
101
|
+
logicalId: resource.logicalId,
|
|
102
|
+
type: resource.type,
|
|
103
|
+
monthlyCost,
|
|
104
|
+
};
|
|
105
|
+
}));
|
|
106
|
+
const modifiedCosts = await Promise.all(filteredModified.map(async (resource) => {
|
|
107
|
+
const oldResource = {
|
|
108
|
+
logicalId: resource.logicalId,
|
|
109
|
+
type: resource.type,
|
|
110
|
+
properties: resource.oldProperties,
|
|
111
|
+
};
|
|
112
|
+
const newResource = {
|
|
113
|
+
logicalId: resource.logicalId,
|
|
114
|
+
type: resource.type,
|
|
115
|
+
properties: resource.newProperties,
|
|
116
|
+
};
|
|
117
|
+
const oldMonthlyCost = await this.getResourceCost(oldResource, region);
|
|
118
|
+
const newMonthlyCost = await this.getResourceCost(newResource, region);
|
|
119
|
+
const costDelta = newMonthlyCost.amount - oldMonthlyCost.amount;
|
|
120
|
+
return {
|
|
121
|
+
logicalId: resource.logicalId,
|
|
122
|
+
type: resource.type,
|
|
123
|
+
monthlyCost: newMonthlyCost,
|
|
124
|
+
oldMonthlyCost,
|
|
125
|
+
newMonthlyCost,
|
|
126
|
+
costDelta,
|
|
127
|
+
};
|
|
128
|
+
}));
|
|
129
|
+
const totalAddedCost = addedCosts.reduce((sum, r) => sum + r.monthlyCost.amount, 0);
|
|
130
|
+
const totalRemovedCost = removedCosts.reduce((sum, r) => sum + r.monthlyCost.amount, 0);
|
|
131
|
+
const totalModifiedDelta = modifiedCosts.reduce((sum, r) => sum + r.costDelta, 0);
|
|
132
|
+
const totalDelta = totalAddedCost - totalRemovedCost + totalModifiedDelta;
|
|
133
|
+
return {
|
|
134
|
+
totalDelta,
|
|
135
|
+
currency: 'USD',
|
|
136
|
+
addedCosts,
|
|
137
|
+
removedCosts,
|
|
138
|
+
modifiedCosts,
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Clean up resources and connections
|
|
143
|
+
*/
|
|
144
|
+
destroy() {
|
|
145
|
+
this.pricingClient.destroy();
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
exports.PricingService = PricingService;
|
|
149
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUHJpY2luZ1NlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcHJpY2luZy9QcmljaW5nU2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSxpREFBOEM7QUFDOUMsK0RBQTREO0FBQzVELDZFQUEwRTtBQUMxRSw2RUFBMEU7QUFDMUUseUVBQXNFO0FBQ3RFLCtEQUE0RDtBQUM1RCwrREFBNEQ7QUFDNUQsK0VBQTRFO0FBQzVFLHFFQUFrRTtBQUNsRSw2RUFBMEU7QUFDMUUsK0RBQTREO0FBQzVELCtEQUE0RDtBQUM1RCw2REFBMEQ7QUFDMUQsK0VBQTRFO0FBQzVFLG1EQUFnRDtBQVVoRCxNQUFhLGNBQWM7SUFDakIsV0FBVyxDQUEyQjtJQUN0QyxhQUFhLENBQWdCO0lBQzdCLHFCQUFxQixDQUFjO0lBRTNDLFlBQ0UsU0FBaUIsV0FBVyxFQUM1QixnQkFBeUMsRUFDekMscUJBQWdDLEVBQ2hDLFdBQXlCLEVBQ3pCLGFBQTZCO1FBRTdCLGtEQUFrRDtRQUNsRCxJQUFJLGFBQWEsRUFBRSxDQUFDO1lBQ2xCLElBQUksQ0FBQyxhQUFhLEdBQUcsYUFBYSxDQUFDO1FBQ3JDLENBQUM7YUFBTSxDQUFDO1lBQ04saURBQWlEO1lBQ2pELElBQUksWUFBc0MsQ0FBQztZQUMzQyxJQUFJLFdBQVcsRUFBRSxPQUFPLEtBQUssS0FBSyxFQUFFLENBQUM7Z0JBQ25DLE1BQU0sYUFBYSxHQUFHLFdBQVcsRUFBRSxhQUFhLElBQUksRUFBRSxDQUFDO2dCQUN2RCxZQUFZLEdBQUcsSUFBSSwyQkFBWSxDQUFDLDBCQUEwQixFQUFFLGFBQWEsQ0FBQyxDQUFDO1lBQzdFLENBQUM7WUFFRCxJQUFJLENBQUMsYUFBYSxHQUFHLElBQUksNkJBQWEsQ0FBQyxNQUFNLEVBQUUsWUFBWSxDQUFDLENBQUM7UUFDL0QsQ0FBQztRQUNELElBQUksQ0FBQyxxQkFBcUIsR0FBRyxJQUFJLEdBQUcsQ0FBQyxxQkFBcUIsSUFBSSxFQUFFLENBQUMsQ0FBQztRQUNsRSxJQUFJLENBQUMsV0FBVyxHQUFHO1lBQ2pCLElBQUksNkJBQWEsRUFBRTtZQUNuQixJQUFJLDJCQUFZLEVBQUU7WUFDbEIsSUFBSSxtQ0FBZ0IsQ0FDbEIsZ0JBQWdCLEVBQUUsTUFBTSxFQUFFLG1CQUFtQixFQUM3QyxnQkFBZ0IsRUFBRSxNQUFNLEVBQUUsaUJBQWlCLENBQzVDO1lBQ0QsSUFBSSw2QkFBYSxFQUFFO1lBQ25CLElBQUksdUNBQWtCLEVBQUU7WUFDeEIsSUFBSSw2QkFBYSxFQUFFO1lBQ25CLElBQUksMkNBQW9CLEVBQUU7WUFDMUIsSUFBSSwyQ0FBb0IsQ0FBQyxnQkFBZ0IsRUFBRSxVQUFVLEVBQUUsZUFBZSxDQUFDO1lBQ3ZFLElBQUksNkJBQWEsQ0FDZixnQkFBZ0IsRUFBRSxHQUFHLEVBQUUsdUJBQXVCLEVBQzlDLGdCQUFnQixFQUFFLEdBQUcsRUFBRSwwQkFBMEIsRUFDakQsZ0JBQWdCLEVBQUUsR0FBRyxFQUFFLGdCQUFnQixDQUN4QztZQUNELElBQUksNkJBQWEsQ0FDZixnQkFBZ0IsRUFBRSxHQUFHLEVBQUUsdUJBQXVCLEVBQzlDLGdCQUFnQixFQUFFLEdBQUcsRUFBRSwwQkFBMEIsRUFDakQsZ0JBQWdCLEVBQUUsR0FBRyxFQUFFLGdCQUFnQixDQUN4QztZQUNELElBQUksNkNBQXFCLENBQUMsZ0JBQWdCLEVBQUUsV0FBVyxFQUFFLGVBQWUsQ0FBQztZQUN6RSxJQUFJLDJDQUFvQixDQUN0QixnQkFBZ0IsRUFBRSxVQUFVLEVBQUUsY0FBYyxFQUM1QyxnQkFBZ0IsRUFBRSxVQUFVLEVBQUUsUUFBUSxDQUN2QztZQUNELElBQUksNkNBQXFCLEVBQUU7U0FDNUIsQ0FBQztJQUNKLENBQUM7SUFFRCxLQUFLLENBQUMsZUFBZSxDQUFDLFFBQXdCLEVBQUUsTUFBYztRQUM1RCxxQ0FBcUM7UUFDckMsSUFBSSxJQUFJLENBQUMscUJBQXFCLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDO1lBQ2xELE9BQU87Z0JBQ0wsTUFBTSxFQUFFLENBQUM7Z0JBQ1QsUUFBUSxFQUFFLEtBQUs7Z0JBQ2YsVUFBVSxFQUFFLE1BQU07Z0JBQ2xCLFdBQVcsRUFBRSxDQUFDLGlCQUFpQixRQUFRLENBQUMsSUFBSSxpQ0FBaUMsQ0FBQzthQUMvRSxDQUFDO1FBQ0osQ0FBQztRQUVELE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztRQUUvRSxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7WUFDaEIsT0FBTztnQkFDTCxNQUFNLEVBQUUsQ0FBQztnQkFDVCxRQUFRLEVBQUUsS0FBSztnQkFDZixVQUFVLEVBQUUsU0FBUztnQkFDckIsV0FBVyxFQUFFLENBQUMsaUJBQWlCLFFBQVEsQ0FBQyxJQUFJLG1CQUFtQixDQUFDO2FBQ2pFLENBQUM7UUFDSixDQUFDO1FBRUQsSUFBSSxDQUFDO1lBQ0gsT0FBTyxNQUFNLFVBQVUsQ0FBQyxhQUFhLENBQUMsUUFBUSxFQUFFLE1BQU0sRUFBRSxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUM7UUFDOUUsQ0FBQztRQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7WUFDZixPQUFPO2dCQUNMLE1BQU0sRUFBRSxDQUFDO2dCQUNULFFBQVEsRUFBRSxLQUFLO2dCQUNmLFVBQVUsRUFBRSxTQUFTO2dCQUNyQixXQUFXLEVBQUUsQ0FBQyw2QkFBNkIsS0FBSyxZQUFZLEtBQUssQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUM7YUFDckcsQ0FBQztRQUNKLENBQUM7SUFDSCxDQUFDO0lBRUQsS0FBSyxDQUFDLFlBQVksQ0FBQyxJQUFrQixFQUFFLE1BQWM7UUFDbkQsa0RBQWtEO1FBQ2xELE1BQU0sYUFBYSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMscUJBQXFCLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO1FBQ3RGLE1BQU0sZUFBZSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMscUJBQXFCLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO1FBQzFGLE1BQU0sZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7UUFFNUYsTUFBTSxVQUFVLEdBQUcsTUFBTSxPQUFPLENBQUMsR0FBRyxDQUNsQyxhQUFhLENBQUMsR0FBRyxDQUFDLEtBQUssRUFBRSxRQUFRLEVBQUUsRUFBRTtZQUNuQyxNQUFNLFdBQVcsR0FBRyxNQUFNLElBQUksQ0FBQyxlQUFlLENBQUMsUUFBUSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1lBQ2pFLE9BQU87Z0JBQ0wsU0FBUyxFQUFFLFFBQVEsQ0FBQyxTQUFTO2dCQUM3QixJQUFJLEVBQUUsUUFBUSxDQUFDLElBQUk7Z0JBQ25CLFdBQVc7YUFDWixDQUFDO1FBQ0osQ0FBQyxDQUFDLENBQ0gsQ0FBQztRQUVGLE1BQU0sWUFBWSxHQUFHLE1BQU0sT0FBTyxDQUFDLEdBQUcsQ0FDcEMsZUFBZSxDQUFDLEdBQUcsQ0FBQyxLQUFLLEVBQUUsUUFBUSxFQUFFLEVBQUU7WUFDckMsTUFBTSxXQUFXLEdBQUcsTUFBTSxJQUFJLENBQUMsZUFBZSxDQUFDLFFBQVEsRUFBRSxNQUFNLENBQUMsQ0FBQztZQUNqRSxPQUFPO2dCQUNMLFNBQVMsRUFBRSxRQUFRLENBQUMsU0FBUztnQkFDN0IsSUFBSSxFQUFFLFFBQVEsQ0FBQyxJQUFJO2dCQUNuQixXQUFXO2FBQ1osQ0FBQztRQUNKLENBQUMsQ0FBQyxDQUNILENBQUM7UUFFRixNQUFNLGFBQWEsR0FBRyxNQUFNLE9BQU8sQ0FBQyxHQUFHLENBQ3JDLGdCQUFnQixDQUFDLEdBQUcsQ0FBQyxLQUFLLEVBQUUsUUFBUSxFQUFFLEVBQUU7WUFDdEMsTUFBTSxXQUFXLEdBQW1CO2dCQUNsQyxTQUFTLEVBQUUsUUFBUSxDQUFDLFNBQVM7Z0JBQzdCLElBQUksRUFBRSxRQUFRLENBQUMsSUFBSTtnQkFDbkIsVUFBVSxFQUFFLFFBQVEsQ0FBQyxhQUFhO2FBQ25DLENBQUM7WUFDRixNQUFNLFdBQVcsR0FBbUI7Z0JBQ2xDLFNBQVMsRUFBRSxRQUFRLENBQUMsU0FBUztnQkFDN0IsSUFBSSxFQUFFLFFBQVEsQ0FBQyxJQUFJO2dCQUNuQixVQUFVLEVBQUUsUUFBUSxDQUFDLGFBQWE7YUFDbkMsQ0FBQztZQUVGLE1BQU0sY0FBYyxHQUFHLE1BQU0sSUFBSSxDQUFDLGVBQWUsQ0FBQyxXQUFXLEVBQUUsTUFBTSxDQUFDLENBQUM7WUFDdkUsTUFBTSxjQUFjLEdBQUcsTUFBTSxJQUFJLENBQUMsZUFBZSxDQUFDLFdBQVcsRUFBRSxNQUFNLENBQUMsQ0FBQztZQUN2RSxNQUFNLFNBQVMsR0FBRyxjQUFjLENBQUMsTUFBTSxHQUFHLGNBQWMsQ0FBQyxNQUFNLENBQUM7WUFFaEUsT0FBTztnQkFDTCxTQUFTLEVBQUUsUUFBUSxDQUFDLFNBQVM7Z0JBQzdCLElBQUksRUFBRSxRQUFRLENBQUMsSUFBSTtnQkFDbkIsV0FBVyxFQUFFLGNBQWM7Z0JBQzNCLGNBQWM7Z0JBQ2QsY0FBYztnQkFDZCxTQUFTO2FBQ1YsQ0FBQztRQUNKLENBQUMsQ0FBQyxDQUNILENBQUM7UUFFRixNQUFNLGNBQWMsR0FBRyxVQUFVLENBQUMsTUFBTSxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQyxXQUFXLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQ3BGLE1BQU0sZ0JBQWdCLEdBQUcsWUFBWSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLEdBQUcsR0FBRyxDQUFDLENBQUMsV0FBVyxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsQ0FBQztRQUN4RixNQUFNLGtCQUFrQixHQUFHLGFBQWEsQ0FBQyxNQUFNLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxDQUFDLFNBQVMsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUVsRixNQUFNLFVBQVUsR0FBRyxjQUFjLEdBQUcsZ0JBQWdCLEdBQUcsa0JBQWtCLENBQUM7UUFFMUUsT0FBTztZQUNMLFVBQVU7WUFDVixRQUFRLEVBQUUsS0FBSztZQUNmLFVBQVU7WUFDVixZQUFZO1lBQ1osYUFBYTtTQUNkLENBQUM7SUFDSixDQUFDO0lBRUQ7O09BRUc7SUFDSCxPQUFPO1FBQ0wsSUFBSSxDQUFDLGFBQWEsQ0FBQyxPQUFPLEVBQUUsQ0FBQztJQUMvQixDQUFDO0NBQ0Y7QUF4S0Qsd0NBd0tDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ2FjaGVNYW5hZ2VyIH0gZnJvbSAnLi9DYWNoZU1hbmFnZXInO1xuaW1wb3J0IHsgQUxCQ2FsY3VsYXRvciB9IGZyb20gJy4vY2FsY3VsYXRvcnMvQUxCQ2FsY3VsYXRvcic7XG5pbXBvcnQgeyBBUElHYXRld2F5Q2FsY3VsYXRvciB9IGZyb20gJy4vY2FsY3VsYXRvcnMvQVBJR2F0ZXdheUNhbGN1bGF0b3InO1xuaW1wb3J0IHsgQ2xvdWRGcm9udENhbGN1bGF0b3IgfSBmcm9tICcuL2NhbGN1bGF0b3JzL0Nsb3VkRnJvbnRDYWxjdWxhdG9yJztcbmltcG9ydCB7IER5bmFtb0RCQ2FsY3VsYXRvciB9IGZyb20gJy4vY2FsY3VsYXRvcnMvRHluYW1vREJDYWxjdWxhdG9yJztcbmltcG9ydCB7IEVDMkNhbGN1bGF0b3IgfSBmcm9tICcuL2NhbGN1bGF0b3JzL0VDMkNhbGN1bGF0b3InO1xuaW1wb3J0IHsgRUNTQ2FsY3VsYXRvciB9IGZyb20gJy4vY2FsY3VsYXRvcnMvRUNTQ2FsY3VsYXRvcic7XG5pbXBvcnQgeyBFbGFzdGlDYWNoZUNhbGN1bGF0b3IgfSBmcm9tICcuL2NhbGN1bGF0b3JzL0VsYXN0aUNhY2hlQ2FsY3VsYXRvcic7XG5pbXBvcnQgeyBMYW1iZGFDYWxjdWxhdG9yIH0gZnJvbSAnLi9jYWxjdWxhdG9ycy9MYW1iZGFDYWxjdWxhdG9yJztcbmltcG9ydCB7IE5hdEdhdGV3YXlDYWxjdWxhdG9yIH0gZnJvbSAnLi9jYWxjdWxhdG9ycy9OYXRHYXRld2F5Q2FsY3VsYXRvcic7XG5pbXBvcnQgeyBOTEJDYWxjdWxhdG9yIH0gZnJvbSAnLi9jYWxjdWxhdG9ycy9OTEJDYWxjdWxhdG9yJztcbmltcG9ydCB7IFJEU0NhbGN1bGF0b3IgfSBmcm9tICcuL2NhbGN1bGF0b3JzL1JEU0NhbGN1bGF0b3InO1xuaW1wb3J0IHsgUzNDYWxjdWxhdG9yIH0gZnJvbSAnLi9jYWxjdWxhdG9ycy9TM0NhbGN1bGF0b3InO1xuaW1wb3J0IHsgVlBDRW5kcG9pbnRDYWxjdWxhdG9yIH0gZnJvbSAnLi9jYWxjdWxhdG9ycy9WUENFbmRwb2ludENhbGN1bGF0b3InO1xuaW1wb3J0IHsgUHJpY2luZ0NsaWVudCB9IGZyb20gJy4vUHJpY2luZ0NsaWVudCc7XG5pbXBvcnQge1xuICBQcmljaW5nU2VydmljZSBhcyBJUHJpY2luZ1NlcnZpY2UsXG4gIE1vbnRobHlDb3N0LFxuICBDb3N0RGVsdGEsXG4gIFJlc291cmNlQ29zdENhbGN1bGF0b3IsXG59IGZyb20gJy4vdHlwZXMnO1xuaW1wb3J0IHsgVXNhZ2VBc3N1bXB0aW9uc0NvbmZpZywgQ2FjaGVDb25maWcgfSBmcm9tICcuLi9jb25maWcvdHlwZXMnO1xuaW1wb3J0IHsgUmVzb3VyY2VXaXRoSWQsIFJlc291cmNlRGlmZiB9IGZyb20gJy4uL2RpZmYvdHlwZXMnO1xuXG5leHBvcnQgY2xhc3MgUHJpY2luZ1NlcnZpY2UgaW1wbGVtZW50cyBJUHJpY2luZ1NlcnZpY2Uge1xuICBwcml2YXRlIGNhbGN1bGF0b3JzOiBSZXNvdXJjZUNvc3RDYWxjdWxhdG9yW107XG4gIHByaXZhdGUgcHJpY2luZ0NsaWVudDogUHJpY2luZ0NsaWVudDtcbiAgcHJpdmF0ZSBleGNsdWRlZFJlc291cmNlVHlwZXM6IFNldDxzdHJpbmc+O1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHJlZ2lvbjogc3RyaW5nID0gJ3VzLWVhc3QtMScsXG4gICAgdXNhZ2VBc3N1bXB0aW9ucz86IFVzYWdlQXNzdW1wdGlvbnNDb25maWcsXG4gICAgZXhjbHVkZWRSZXNvdXJjZVR5cGVzPzogc3RyaW5nW10sXG4gICAgY2FjaGVDb25maWc/OiBDYWNoZUNvbmZpZyxcbiAgICBwcmljaW5nQ2xpZW50PzogUHJpY2luZ0NsaWVudCxcbiAgKSB7XG4gICAgLy8gVXNlIHByb3ZpZGVkIHByaWNpbmcgY2xpZW50IG9yIGNyZWF0ZSBhIG5ldyBvbmVcbiAgICBpZiAocHJpY2luZ0NsaWVudCkge1xuICAgICAgdGhpcy5wcmljaW5nQ2xpZW50ID0gcHJpY2luZ0NsaWVudDtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gSW5pdGlhbGl6ZSBjYWNoZSBtYW5hZ2VyIGlmIGNhY2hpbmcgaXMgZW5hYmxlZFxuICAgICAgbGV0IGNhY2hlTWFuYWdlcjogQ2FjaGVNYW5hZ2VyIHwgdW5kZWZpbmVkO1xuICAgICAgaWYgKGNhY2hlQ29uZmlnPy5lbmFibGVkICE9PSBmYWxzZSkge1xuICAgICAgICBjb25zdCBjYWNoZUR1cmF0aW9uID0gY2FjaGVDb25maWc/LmR1cmF0aW9uSG91cnMgPz8gMjQ7XG4gICAgICAgIGNhY2hlTWFuYWdlciA9IG5ldyBDYWNoZU1hbmFnZXIoJy5jZGstY29zdC1hbmFseXplci1jYWNoZScsIGNhY2hlRHVyYXRpb24pO1xuICAgICAgfVxuXG4gICAgICB0aGlzLnByaWNpbmdDbGllbnQgPSBuZXcgUHJpY2luZ0NsaWVudChyZWdpb24sIGNhY2hlTWFuYWdlcik7XG4gICAgfVxuICAgIHRoaXMuZXhjbHVkZWRSZXNvdXJjZVR5cGVzID0gbmV3IFNldChleGNsdWRlZFJlc291cmNlVHlwZXMgfHwgW10pO1xuICAgIHRoaXMuY2FsY3VsYXRvcnMgPSBbXG4gICAgICBuZXcgRUMyQ2FsY3VsYXRvcigpLFxuICAgICAgbmV3IFMzQ2FsY3VsYXRvcigpLFxuICAgICAgbmV3IExhbWJkYUNhbGN1bGF0b3IoXG4gICAgICAgIHVzYWdlQXNzdW1wdGlvbnM/LmxhbWJkYT8uaW52b2NhdGlvbnNQZXJNb250aCxcbiAgICAgICAgdXNhZ2VBc3N1bXB0aW9ucz8ubGFtYmRhPy5hdmVyYWdlRHVyYXRpb25NcyxcbiAgICAgICksXG4gICAgICBuZXcgUkRTQ2FsY3VsYXRvcigpLFxuICAgICAgbmV3IER5bmFtb0RCQ2FsY3VsYXRvcigpLFxuICAgICAgbmV3IEVDU0NhbGN1bGF0b3IoKSxcbiAgICAgIG5ldyBBUElHYXRld2F5Q2FsY3VsYXRvcigpLFxuICAgICAgbmV3IE5hdEdhdGV3YXlDYWxjdWxhdG9yKHVzYWdlQXNzdW1wdGlvbnM/Lm5hdEdhdGV3YXk/LmRhdGFQcm9jZXNzZWRHQiksXG4gICAgICBuZXcgQUxCQ2FsY3VsYXRvcihcbiAgICAgICAgdXNhZ2VBc3N1bXB0aW9ucz8uYWxiPy5uZXdDb25uZWN0aW9uc1BlclNlY29uZCxcbiAgICAgICAgdXNhZ2VBc3N1bXB0aW9ucz8uYWxiPy5hY3RpdmVDb25uZWN0aW9uc1Blck1pbnV0ZSxcbiAgICAgICAgdXNhZ2VBc3N1bXB0aW9ucz8uYWxiPy5wcm9jZXNzZWRCeXRlc0dCLFxuICAgICAgKSxcbiAgICAgIG5ldyBOTEJDYWxjdWxhdG9yKFxuICAgICAgICB1c2FnZUFzc3VtcHRpb25zPy5ubGI/Lm5ld0Nvbm5lY3Rpb25zUGVyU2Vjb25kLFxuICAgICAgICB1c2FnZUFzc3VtcHRpb25zPy5ubGI/LmFjdGl2ZUNvbm5lY3Rpb25zUGVyTWludXRlLFxuICAgICAgICB1c2FnZUFzc3VtcHRpb25zPy5ubGI/LnByb2Nlc3NlZEJ5dGVzR0IsXG4gICAgICApLFxuICAgICAgbmV3IFZQQ0VuZHBvaW50Q2FsY3VsYXRvcih1c2FnZUFzc3VtcHRpb25zPy52cGNFbmRwb2ludD8uZGF0YVByb2Nlc3NlZEdCKSxcbiAgICAgIG5ldyBDbG91ZEZyb250Q2FsY3VsYXRvcihcbiAgICAgICAgdXNhZ2VBc3N1bXB0aW9ucz8uY2xvdWRmcm9udD8uZGF0YVRyYW5zZmVyR0IsXG4gICAgICAgIHVzYWdlQXNzdW1wdGlvbnM/LmNsb3VkZnJvbnQ/LnJlcXVlc3RzLFxuICAgICAgKSxcbiAgICAgIG5ldyBFbGFzdGlDYWNoZUNhbGN1bGF0b3IoKSxcbiAgICBdO1xuICB9XG5cbiAgYXN5bmMgZ2V0UmVzb3VyY2VDb3N0KHJlc291cmNlOiBSZXNvdXJjZVdpdGhJZCwgcmVnaW9uOiBzdHJpbmcpOiBQcm9taXNlPE1vbnRobHlDb3N0PiB7XG4gICAgLy8gQ2hlY2sgaWYgcmVzb3VyY2UgdHlwZSBpcyBleGNsdWRlZFxuICAgIGlmICh0aGlzLmV4Y2x1ZGVkUmVzb3VyY2VUeXBlcy5oYXMocmVzb3VyY2UudHlwZSkpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGFtb3VudDogMCxcbiAgICAgICAgY3VycmVuY3k6ICdVU0QnLFxuICAgICAgICBjb25maWRlbmNlOiAnaGlnaCcsXG4gICAgICAgIGFzc3VtcHRpb25zOiBbYFJlc291cmNlIHR5cGUgJHtyZXNvdXJjZS50eXBlfSBpcyBleGNsdWRlZCBmcm9tIGNvc3QgYW5hbHlzaXNgXSxcbiAgICAgIH07XG4gICAgfVxuXG4gICAgY29uc3QgY2FsY3VsYXRvciA9IHRoaXMuY2FsY3VsYXRvcnMuZmluZChjYWxjID0+IGNhbGMuc3VwcG9ydHMocmVzb3VyY2UudHlwZSkpO1xuXG4gICAgaWYgKCFjYWxjdWxhdG9yKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBhbW91bnQ6IDAsXG4gICAgICAgIGN1cnJlbmN5OiAnVVNEJyxcbiAgICAgICAgY29uZmlkZW5jZTogJ3Vua25vd24nLFxuICAgICAgICBhc3N1bXB0aW9uczogW2BSZXNvdXJjZSB0eXBlICR7cmVzb3VyY2UudHlwZX0gaXMgbm90IHN1cHBvcnRlZGBdLFxuICAgICAgfTtcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgcmV0dXJuIGF3YWl0IGNhbGN1bGF0b3IuY2FsY3VsYXRlQ29zdChyZXNvdXJjZSwgcmVnaW9uLCB0aGlzLnByaWNpbmdDbGllbnQpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBhbW91bnQ6IDAsXG4gICAgICAgIGN1cnJlbmN5OiAnVVNEJyxcbiAgICAgICAgY29uZmlkZW5jZTogJ3Vua25vd24nLFxuICAgICAgICBhc3N1bXB0aW9uczogW2BGYWlsZWQgdG8gY2FsY3VsYXRlIGNvc3Q6ICR7ZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiBTdHJpbmcoZXJyb3IpfWBdLFxuICAgICAgfTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBnZXRDb3N0RGVsdGEoZGlmZjogUmVzb3VyY2VEaWZmLCByZWdpb246IHN0cmluZyk6IFByb21pc2U8Q29zdERlbHRhPiB7XG4gICAgLy8gRmlsdGVyIG91dCBleGNsdWRlZCByZXNvdXJjZXMgYmVmb3JlIHByb2Nlc3NpbmdcbiAgICBjb25zdCBmaWx0ZXJlZEFkZGVkID0gZGlmZi5hZGRlZC5maWx0ZXIociA9PiAhdGhpcy5leGNsdWRlZFJlc291cmNlVHlwZXMuaGFzKHIudHlwZSkpO1xuICAgIGNvbnN0IGZpbHRlcmVkUmVtb3ZlZCA9IGRpZmYucmVtb3ZlZC5maWx0ZXIociA9PiAhdGhpcy5leGNsdWRlZFJlc291cmNlVHlwZXMuaGFzKHIudHlwZSkpO1xuICAgIGNvbnN0IGZpbHRlcmVkTW9kaWZpZWQgPSBkaWZmLm1vZGlmaWVkLmZpbHRlcihyID0+ICF0aGlzLmV4Y2x1ZGVkUmVzb3VyY2VUeXBlcy5oYXMoci50eXBlKSk7XG5cbiAgICBjb25zdCBhZGRlZENvc3RzID0gYXdhaXQgUHJvbWlzZS5hbGwoXG4gICAgICBmaWx0ZXJlZEFkZGVkLm1hcChhc3luYyAocmVzb3VyY2UpID0+IHtcbiAgICAgICAgY29uc3QgbW9udGhseUNvc3QgPSBhd2FpdCB0aGlzLmdldFJlc291cmNlQ29zdChyZXNvdXJjZSwgcmVnaW9uKTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBsb2dpY2FsSWQ6IHJlc291cmNlLmxvZ2ljYWxJZCxcbiAgICAgICAgICB0eXBlOiByZXNvdXJjZS50eXBlLFxuICAgICAgICAgIG1vbnRobHlDb3N0LFxuICAgICAgICB9O1xuICAgICAgfSksXG4gICAgKTtcblxuICAgIGNvbnN0IHJlbW92ZWRDb3N0cyA9IGF3YWl0IFByb21pc2UuYWxsKFxuICAgICAgZmlsdGVyZWRSZW1vdmVkLm1hcChhc3luYyAocmVzb3VyY2UpID0+IHtcbiAgICAgICAgY29uc3QgbW9udGhseUNvc3QgPSBhd2FpdCB0aGlzLmdldFJlc291cmNlQ29zdChyZXNvdXJjZSwgcmVnaW9uKTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBsb2dpY2FsSWQ6IHJlc291cmNlLmxvZ2ljYWxJZCxcbiAgICAgICAgICB0eXBlOiByZXNvdXJjZS50eXBlLFxuICAgICAgICAgIG1vbnRobHlDb3N0LFxuICAgICAgICB9O1xuICAgICAgfSksXG4gICAgKTtcblxuICAgIGNvbnN0IG1vZGlmaWVkQ29zdHMgPSBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgIGZpbHRlcmVkTW9kaWZpZWQubWFwKGFzeW5jIChyZXNvdXJjZSkgPT4ge1xuICAgICAgICBjb25zdCBvbGRSZXNvdXJjZTogUmVzb3VyY2VXaXRoSWQgPSB7XG4gICAgICAgICAgbG9naWNhbElkOiByZXNvdXJjZS5sb2dpY2FsSWQsXG4gICAgICAgICAgdHlwZTogcmVzb3VyY2UudHlwZSxcbiAgICAgICAgICBwcm9wZXJ0aWVzOiByZXNvdXJjZS5vbGRQcm9wZXJ0aWVzLFxuICAgICAgICB9O1xuICAgICAgICBjb25zdCBuZXdSZXNvdXJjZTogUmVzb3VyY2VXaXRoSWQgPSB7XG4gICAgICAgICAgbG9naWNhbElkOiByZXNvdXJjZS5sb2dpY2FsSWQsXG4gICAgICAgICAgdHlwZTogcmVzb3VyY2UudHlwZSxcbiAgICAgICAgICBwcm9wZXJ0aWVzOiByZXNvdXJjZS5uZXdQcm9wZXJ0aWVzLFxuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IG9sZE1vbnRobHlDb3N0ID0gYXdhaXQgdGhpcy5nZXRSZXNvdXJjZUNvc3Qob2xkUmVzb3VyY2UsIHJlZ2lvbik7XG4gICAgICAgIGNvbnN0IG5ld01vbnRobHlDb3N0ID0gYXdhaXQgdGhpcy5nZXRSZXNvdXJjZUNvc3QobmV3UmVzb3VyY2UsIHJlZ2lvbik7XG4gICAgICAgIGNvbnN0IGNvc3REZWx0YSA9IG5ld01vbnRobHlDb3N0LmFtb3VudCAtIG9sZE1vbnRobHlDb3N0LmFtb3VudDtcblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIGxvZ2ljYWxJZDogcmVzb3VyY2UubG9naWNhbElkLFxuICAgICAgICAgIHR5cGU6IHJlc291cmNlLnR5cGUsXG4gICAgICAgICAgbW9udGhseUNvc3Q6IG5ld01vbnRobHlDb3N0LFxuICAgICAgICAgIG9sZE1vbnRobHlDb3N0LFxuICAgICAgICAgIG5ld01vbnRobHlDb3N0LFxuICAgICAgICAgIGNvc3REZWx0YSxcbiAgICAgICAgfTtcbiAgICAgIH0pLFxuICAgICk7XG5cbiAgICBjb25zdCB0b3RhbEFkZGVkQ29zdCA9IGFkZGVkQ29zdHMucmVkdWNlKChzdW0sIHIpID0+IHN1bSArIHIubW9udGhseUNvc3QuYW1vdW50LCAwKTtcbiAgICBjb25zdCB0b3RhbFJlbW92ZWRDb3N0ID0gcmVtb3ZlZENvc3RzLnJlZHVjZSgoc3VtLCByKSA9PiBzdW0gKyByLm1vbnRobHlDb3N0LmFtb3VudCwgMCk7XG4gICAgY29uc3QgdG90YWxNb2RpZmllZERlbHRhID0gbW9kaWZpZWRDb3N0cy5yZWR1Y2UoKHN1bSwgcikgPT4gc3VtICsgci5jb3N0RGVsdGEsIDApO1xuXG4gICAgY29uc3QgdG90YWxEZWx0YSA9IHRvdGFsQWRkZWRDb3N0IC0gdG90YWxSZW1vdmVkQ29zdCArIHRvdGFsTW9kaWZpZWREZWx0YTtcblxuICAgIHJldHVybiB7XG4gICAgICB0b3RhbERlbHRhLFxuICAgICAgY3VycmVuY3k6ICdVU0QnLFxuICAgICAgYWRkZWRDb3N0cyxcbiAgICAgIHJlbW92ZWRDb3N0cyxcbiAgICAgIG1vZGlmaWVkQ29zdHMsXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDbGVhbiB1cCByZXNvdXJjZXMgYW5kIGNvbm5lY3Rpb25zXG4gICAqL1xuICBkZXN0cm95KCk6IHZvaWQge1xuICAgIHRoaXMucHJpY2luZ0NsaWVudC5kZXN0cm95KCk7XG4gIH1cbn1cbiJdfQ==
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { ResourceWithId } from '../../diff/types';
|
|
2
|
+
import { ResourceCostCalculator, MonthlyCost, PricingClient } from '../types';
|
|
3
|
+
export declare class ALBCalculator implements ResourceCostCalculator {
|
|
4
|
+
private customNewConnectionsPerSecond?;
|
|
5
|
+
private customActiveConnectionsPerMinute?;
|
|
6
|
+
private customProcessedBytesGB?;
|
|
7
|
+
private readonly DEFAULT_NEW_CONNECTIONS_PER_SECOND;
|
|
8
|
+
private readonly DEFAULT_ACTIVE_CONNECTIONS_PER_MINUTE;
|
|
9
|
+
private readonly DEFAULT_PROCESSED_BYTES_GB;
|
|
10
|
+
private readonly HOURS_PER_MONTH;
|
|
11
|
+
constructor(customNewConnectionsPerSecond?: number | undefined, customActiveConnectionsPerMinute?: number | undefined, customProcessedBytesGB?: number | undefined);
|
|
12
|
+
supports(resourceType: string): boolean;
|
|
13
|
+
calculateCost(resource: ResourceWithId, region: string, pricingClient: PricingClient): Promise<MonthlyCost>;
|
|
14
|
+
private normalizeRegion;
|
|
15
|
+
private getRegionPrefix;
|
|
16
|
+
}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ALBCalculator = void 0;
|
|
4
|
+
class ALBCalculator {
|
|
5
|
+
customNewConnectionsPerSecond;
|
|
6
|
+
customActiveConnectionsPerMinute;
|
|
7
|
+
customProcessedBytesGB;
|
|
8
|
+
DEFAULT_NEW_CONNECTIONS_PER_SECOND = 25;
|
|
9
|
+
DEFAULT_ACTIVE_CONNECTIONS_PER_MINUTE = 3000;
|
|
10
|
+
DEFAULT_PROCESSED_BYTES_GB = 100;
|
|
11
|
+
HOURS_PER_MONTH = 730;
|
|
12
|
+
constructor(customNewConnectionsPerSecond, customActiveConnectionsPerMinute, customProcessedBytesGB) {
|
|
13
|
+
this.customNewConnectionsPerSecond = customNewConnectionsPerSecond;
|
|
14
|
+
this.customActiveConnectionsPerMinute = customActiveConnectionsPerMinute;
|
|
15
|
+
this.customProcessedBytesGB = customProcessedBytesGB;
|
|
16
|
+
}
|
|
17
|
+
supports(resourceType) {
|
|
18
|
+
return resourceType === 'AWS::ElasticLoadBalancingV2::LoadBalancer';
|
|
19
|
+
}
|
|
20
|
+
async calculateCost(resource, region, pricingClient) {
|
|
21
|
+
// Check if this is an Application Load Balancer (not Network Load Balancer)
|
|
22
|
+
const loadBalancerType = resource.properties?.Type;
|
|
23
|
+
if (loadBalancerType && loadBalancerType !== 'application') {
|
|
24
|
+
return {
|
|
25
|
+
amount: 0,
|
|
26
|
+
currency: 'USD',
|
|
27
|
+
confidence: 'unknown',
|
|
28
|
+
assumptions: ['This calculator only supports Application Load Balancers'],
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
try {
|
|
32
|
+
// Get hourly rate
|
|
33
|
+
const hourlyRate = await pricingClient.getPrice({
|
|
34
|
+
serviceCode: 'AWSELB',
|
|
35
|
+
region: this.normalizeRegion(region),
|
|
36
|
+
filters: [
|
|
37
|
+
{ field: 'productFamily', value: 'Load Balancer-Application' },
|
|
38
|
+
{ field: 'usagetype', value: `${this.getRegionPrefix(region)}LoadBalancerUsage` },
|
|
39
|
+
],
|
|
40
|
+
});
|
|
41
|
+
// Get LCU rate
|
|
42
|
+
const lcuRate = await pricingClient.getPrice({
|
|
43
|
+
serviceCode: 'AWSELB',
|
|
44
|
+
region: this.normalizeRegion(region),
|
|
45
|
+
filters: [
|
|
46
|
+
{ field: 'productFamily', value: 'Load Balancer-Application' },
|
|
47
|
+
{ field: 'usagetype', value: `${this.getRegionPrefix(region)}LCUUsage` },
|
|
48
|
+
],
|
|
49
|
+
});
|
|
50
|
+
const newConnectionsPerSecond = this.customNewConnectionsPerSecond || this.DEFAULT_NEW_CONNECTIONS_PER_SECOND;
|
|
51
|
+
const activeConnectionsPerMinute = this.customActiveConnectionsPerMinute || this.DEFAULT_ACTIVE_CONNECTIONS_PER_MINUTE;
|
|
52
|
+
const processedBytesGB = this.customProcessedBytesGB || this.DEFAULT_PROCESSED_BYTES_GB;
|
|
53
|
+
if (hourlyRate === null || lcuRate === null) {
|
|
54
|
+
// Calculate LCU consumption for assumptions even when pricing fails
|
|
55
|
+
const lcuFromNewConnections = newConnectionsPerSecond / 25;
|
|
56
|
+
const lcuFromActiveConnections = activeConnectionsPerMinute / 3000;
|
|
57
|
+
const gbPerHour = processedBytesGB / this.HOURS_PER_MONTH;
|
|
58
|
+
const lcuFromProcessedBytes = gbPerHour;
|
|
59
|
+
const lcuPerHour = Math.max(lcuFromNewConnections, lcuFromActiveConnections, lcuFromProcessedBytes);
|
|
60
|
+
return {
|
|
61
|
+
amount: 0,
|
|
62
|
+
currency: 'USD',
|
|
63
|
+
confidence: 'unknown',
|
|
64
|
+
assumptions: [
|
|
65
|
+
`Pricing data not available for Application Load Balancer in region ${region}`,
|
|
66
|
+
`Would use LCU consumption: ${lcuPerHour.toFixed(2)} LCU/hour based on:`,
|
|
67
|
+
` - New connections: ${newConnectionsPerSecond}/sec → ${lcuFromNewConnections.toFixed(2)} LCU`,
|
|
68
|
+
` - Active connections: ${activeConnectionsPerMinute}/min → ${lcuFromActiveConnections.toFixed(2)} LCU`,
|
|
69
|
+
` - Processed data: ${processedBytesGB} GB/month → ${lcuFromProcessedBytes.toFixed(2)} LCU`,
|
|
70
|
+
],
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
// Calculate LCU consumption
|
|
74
|
+
// 1 LCU provides: 25 new connections/sec, 3000 active connections/min, 1 GB processed/hour, 1000 rule evaluations/sec
|
|
75
|
+
const lcuFromNewConnections = newConnectionsPerSecond / 25;
|
|
76
|
+
const lcuFromActiveConnections = activeConnectionsPerMinute / 3000;
|
|
77
|
+
const gbPerHour = processedBytesGB / this.HOURS_PER_MONTH;
|
|
78
|
+
const lcuFromProcessedBytes = gbPerHour;
|
|
79
|
+
// Use the highest LCU consumption
|
|
80
|
+
const lcuPerHour = Math.max(lcuFromNewConnections, lcuFromActiveConnections, lcuFromProcessedBytes);
|
|
81
|
+
const hourlyCost = hourlyRate * this.HOURS_PER_MONTH;
|
|
82
|
+
const lcuCost = lcuRate * lcuPerHour * this.HOURS_PER_MONTH;
|
|
83
|
+
const totalCost = hourlyCost + lcuCost;
|
|
84
|
+
return {
|
|
85
|
+
amount: totalCost,
|
|
86
|
+
currency: 'USD',
|
|
87
|
+
confidence: 'medium',
|
|
88
|
+
assumptions: [
|
|
89
|
+
`Hourly rate: $${hourlyRate.toFixed(4)}/hour × ${this.HOURS_PER_MONTH} hours = $${hourlyCost.toFixed(2)}/month`,
|
|
90
|
+
`LCU consumption: ${lcuPerHour.toFixed(2)} LCU/hour based on:`,
|
|
91
|
+
` - New connections: ${newConnectionsPerSecond}/sec → ${lcuFromNewConnections.toFixed(2)} LCU`,
|
|
92
|
+
` - Active connections: ${activeConnectionsPerMinute}/min → ${lcuFromActiveConnections.toFixed(2)} LCU`,
|
|
93
|
+
` - Processed data: ${processedBytesGB} GB/month → ${lcuFromProcessedBytes.toFixed(2)} LCU`,
|
|
94
|
+
`LCU cost: $${lcuRate.toFixed(4)}/LCU/hour × ${lcuPerHour.toFixed(2)} LCU × ${this.HOURS_PER_MONTH} hours = $${lcuCost.toFixed(2)}/month`,
|
|
95
|
+
`Total: $${totalCost.toFixed(2)}/month`,
|
|
96
|
+
],
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
catch (error) {
|
|
100
|
+
const newConnectionsPerSecond = this.customNewConnectionsPerSecond || this.DEFAULT_NEW_CONNECTIONS_PER_SECOND;
|
|
101
|
+
const activeConnectionsPerMinute = this.customActiveConnectionsPerMinute || this.DEFAULT_ACTIVE_CONNECTIONS_PER_MINUTE;
|
|
102
|
+
const processedBytesGB = this.customProcessedBytesGB || this.DEFAULT_PROCESSED_BYTES_GB;
|
|
103
|
+
// Calculate LCU consumption for assumptions even when error occurs
|
|
104
|
+
const lcuFromNewConnections = newConnectionsPerSecond / 25;
|
|
105
|
+
const lcuFromActiveConnections = activeConnectionsPerMinute / 3000;
|
|
106
|
+
const gbPerHour = processedBytesGB / this.HOURS_PER_MONTH;
|
|
107
|
+
const lcuFromProcessedBytes = gbPerHour;
|
|
108
|
+
const lcuPerHour = Math.max(lcuFromNewConnections, lcuFromActiveConnections, lcuFromProcessedBytes);
|
|
109
|
+
return {
|
|
110
|
+
amount: 0,
|
|
111
|
+
currency: 'USD',
|
|
112
|
+
confidence: 'unknown',
|
|
113
|
+
assumptions: [
|
|
114
|
+
`Failed to fetch pricing: ${error instanceof Error ? error.message : String(error)}`,
|
|
115
|
+
`Would use LCU consumption: ${lcuPerHour.toFixed(2)} LCU/hour based on:`,
|
|
116
|
+
` - New connections: ${newConnectionsPerSecond}/sec → ${lcuFromNewConnections.toFixed(2)} LCU`,
|
|
117
|
+
` - Active connections: ${activeConnectionsPerMinute}/min → ${lcuFromActiveConnections.toFixed(2)} LCU`,
|
|
118
|
+
` - Processed data: ${processedBytesGB} GB/month → ${lcuFromProcessedBytes.toFixed(2)} LCU`,
|
|
119
|
+
],
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
normalizeRegion(region) {
|
|
124
|
+
const regionMap = {
|
|
125
|
+
'us-east-1': 'US East (N. Virginia)',
|
|
126
|
+
'us-east-2': 'US East (Ohio)',
|
|
127
|
+
'us-west-1': 'US West (N. California)',
|
|
128
|
+
'us-west-2': 'US West (Oregon)',
|
|
129
|
+
'eu-west-1': 'EU (Ireland)',
|
|
130
|
+
'eu-west-2': 'EU (London)',
|
|
131
|
+
'eu-west-3': 'EU (Paris)',
|
|
132
|
+
'eu-central-1': 'EU (Frankfurt)',
|
|
133
|
+
'eu-north-1': 'EU (Stockholm)',
|
|
134
|
+
'ap-south-1': 'Asia Pacific (Mumbai)',
|
|
135
|
+
'ap-southeast-1': 'Asia Pacific (Singapore)',
|
|
136
|
+
'ap-southeast-2': 'Asia Pacific (Sydney)',
|
|
137
|
+
'ap-northeast-1': 'Asia Pacific (Tokyo)',
|
|
138
|
+
'ap-northeast-2': 'Asia Pacific (Seoul)',
|
|
139
|
+
};
|
|
140
|
+
return regionMap[region] || region;
|
|
141
|
+
}
|
|
142
|
+
getRegionPrefix(region) {
|
|
143
|
+
const prefixMap = {
|
|
144
|
+
'us-east-1': 'USE1',
|
|
145
|
+
'us-east-2': 'USE2',
|
|
146
|
+
'us-west-1': 'USW1',
|
|
147
|
+
'us-west-2': 'USW2',
|
|
148
|
+
'eu-west-1': 'EUW1',
|
|
149
|
+
'eu-west-2': 'EUW2',
|
|
150
|
+
'eu-west-3': 'EUW3',
|
|
151
|
+
'eu-central-1': 'EUC1',
|
|
152
|
+
'eu-north-1': 'EUN1',
|
|
153
|
+
'ap-south-1': 'APS1',
|
|
154
|
+
'ap-southeast-1': 'APS2',
|
|
155
|
+
'ap-southeast-2': 'APS3',
|
|
156
|
+
'ap-northeast-1': 'APN1',
|
|
157
|
+
'ap-northeast-2': 'APN2',
|
|
158
|
+
};
|
|
159
|
+
return prefixMap[region] || '';
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
exports.ALBCalculator = ALBCalculator;
|
|
163
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQUxCQ2FsY3VsYXRvci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9wcmljaW5nL2NhbGN1bGF0b3JzL0FMQkNhbGN1bGF0b3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBR0EsTUFBYSxhQUFhO0lBT2Q7SUFDQTtJQUNBO0lBUk8sa0NBQWtDLEdBQUcsRUFBRSxDQUFDO0lBQ3hDLHFDQUFxQyxHQUFHLElBQUksQ0FBQztJQUM3QywwQkFBMEIsR0FBRyxHQUFHLENBQUM7SUFDakMsZUFBZSxHQUFHLEdBQUcsQ0FBQztJQUV2QyxZQUNVLDZCQUFzQyxFQUN0QyxnQ0FBeUMsRUFDekMsc0JBQStCO1FBRi9CLGtDQUE2QixHQUE3Qiw2QkFBNkIsQ0FBUztRQUN0QyxxQ0FBZ0MsR0FBaEMsZ0NBQWdDLENBQVM7UUFDekMsMkJBQXNCLEdBQXRCLHNCQUFzQixDQUFTO0lBQ3RDLENBQUM7SUFFSixRQUFRLENBQUMsWUFBb0I7UUFDM0IsT0FBTyxZQUFZLEtBQUssMkNBQTJDLENBQUM7SUFDdEUsQ0FBQztJQUVELEtBQUssQ0FBQyxhQUFhLENBQ2pCLFFBQXdCLEVBQ3hCLE1BQWMsRUFDZCxhQUE0QjtRQUU1Qiw0RUFBNEU7UUFDNUUsTUFBTSxnQkFBZ0IsR0FBRyxRQUFRLENBQUMsVUFBVSxFQUFFLElBQUksQ0FBQztRQUNuRCxJQUFJLGdCQUFnQixJQUFJLGdCQUFnQixLQUFLLGFBQWEsRUFBRSxDQUFDO1lBQzNELE9BQU87Z0JBQ0wsTUFBTSxFQUFFLENBQUM7Z0JBQ1QsUUFBUSxFQUFFLEtBQUs7Z0JBQ2YsVUFBVSxFQUFFLFNBQVM7Z0JBQ3JCLFdBQVcsRUFBRSxDQUFDLDBEQUEwRCxDQUFDO2FBQzFFLENBQUM7UUFDSixDQUFDO1FBRUQsSUFBSSxDQUFDO1lBQ0gsa0JBQWtCO1lBQ2xCLE1BQU0sVUFBVSxHQUFHLE1BQU0sYUFBYSxDQUFDLFFBQVEsQ0FBQztnQkFDOUMsV0FBVyxFQUFFLFFBQVE7Z0JBQ3JCLE1B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QzdCLFdBQVcsRUFBRSx5QkFBeUI7WUFDdEMsV0FBVyxFQUFFLGtCQUFrQjtZQUMvQixXQUFXLEVBQUUsY0FBYztZQUMzQixXQUFXLEVBQUUsYUFBYTtZQUMxQixXQUFXLEVBQUUsWUFBWTtZQUN6QixjQUFjLEVBQUUsZ0JBQWdCO1lBQ2hDLFlBQVksRUFBRSxnQkFBZ0I7WUFDOUIsWUFBWSxFQUFFLHVCQUF1QjtZQUNyQyxnQkFBZ0IsRUFBRSwwQkFBMEI7WUFDNUMsZ0JBQWdCLEVBQUUsdUJBQXVCO1lBQ3pDLGdCQUFnQixFQUFFLHNCQUFzQjtZQUN4QyxnQkFBZ0IsRUFBRSxzQkFBc0I7U0FDekMsQ0FBQztRQUVGLE9BQU8sU0FBUyxDQUFDLE1BQU0sQ0FBQyxJQUFJLE1BQU0sQ0FBQztJQUNyQyxDQUFDO0lBRU8sZUFBZSxDQUFDLE1BQWM7UUFDcEMsTUFBTSxTQUFTLEdBQTJCO1lBQ3hDLFdBQVcsRUFBRSxNQUFNO1lBQ25CLFdBQVcsRUFBRSxNQUFNO1lBQ25CLFdBQVcsRUFBRSxNQUFNO1lBQ25CLFdBQVcsRUFBRSxNQUFNO1lBQ25CLFdBQVcsRUFBRSxNQUFNO1lBQ25CLFdBQVcsRUFBRSxNQUFNO1lBQ25CLFdBQVcsRUFBRSxNQUFNO1lBQ25CLGNBQWMsRUFBRSxNQUFNO1lBQ3RCLFlBQVksRUFBRSxNQUFNO1lBQ3BCLFlBQVksRUFBRSxNQUFNO1lBQ3BCLGdCQUFnQixFQUFFLE1BQU07WUFDeEIsZ0JBQWdCLEVBQUUsTUFBTTtZQUN4QixnQkFBZ0IsRUFBRSxNQUFNO1lBQ3hCLGdCQUFnQixFQUFFLE1BQU07U0FDekIsQ0FBQztRQUVGLE9BQU8sU0FBUyxDQUFDLE1BQU0sQ0FBQyxJQUFJLEVBQUUsQ0FBQztJQUNqQyxDQUFDO0NBQ0Y7QUFqTUQsc0NBaU1DIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgUmVzb3VyY2VXaXRoSWQgfSBmcm9tICcuLi8uLi9kaWZmL3R5cGVzJztcbmltcG9ydCB7IFJlc291cmNlQ29zdENhbGN1bGF0b3IsIE1vbnRobHlDb3N0LCBQcmljaW5nQ2xpZW50IH0gZnJvbSAnLi4vdHlwZXMnO1xuXG5leHBvcnQgY2xhc3MgQUxCQ2FsY3VsYXRvciBpbXBsZW1lbnRzIFJlc291cmNlQ29zdENhbGN1bGF0b3Ige1xuICBwcml2YXRlIHJlYWRvbmx5IERFRkFVTFRfTkVXX0NPTk5FQ1RJT05TX1BFUl9TRUNPTkQgPSAyNTtcbiAgcHJpdmF0ZSByZWFkb25seSBERUZBVUxUX0FDVElWRV9DT05ORUNUSU9OU19QRVJfTUlOVVRFID0gMzAwMDtcbiAgcHJpdmF0ZSByZWFkb25seSBERUZBVUxUX1BST0NFU1NFRF9CWVRFU19HQiA9IDEwMDtcbiAgcHJpdmF0ZSByZWFkb25seSBIT1VSU19QRVJfTU9OVEggPSA3MzA7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBjdXN0b21OZXdDb25uZWN0aW9uc1BlclNlY29uZD86IG51bWJlcixcbiAgICBwcml2YXRlIGN1c3RvbUFjdGl2ZUNvbm5lY3Rpb25zUGVyTWludXRlPzogbnVtYmVyLFxuICAgIHByaXZhdGUgY3VzdG9tUHJvY2Vzc2VkQnl0ZXNHQj86IG51bWJlcixcbiAgKSB7fVxuXG4gIHN1cHBvcnRzKHJlc291cmNlVHlwZTogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHJlc291cmNlVHlwZSA9PT0gJ0FXUzo6RWxhc3RpY0xvYWRCYWxhbmNpbmdWMjo6TG9hZEJhbGFuY2VyJztcbiAgfVxuXG4gIGFzeW5jIGNhbGN1bGF0ZUNvc3QoXG4gICAgcmVzb3VyY2U6IFJlc291cmNlV2l0aElkLFxuICAgIHJlZ2lvbjogc3RyaW5nLFxuICAgIHByaWNpbmdDbGllbnQ6IFByaWNpbmdDbGllbnQsXG4gICk6IFByb21pc2U8TW9udGhseUNvc3Q+IHtcbiAgICAvLyBDaGVjayBpZiB0aGlzIGlzIGFuIEFwcGxpY2F0aW9uIExvYWQgQmFsYW5jZXIgKG5vdCBOZXR3b3JrIExvYWQgQmFsYW5jZXIpXG4gICAgY29uc3QgbG9hZEJhbGFuY2VyVHlwZSA9IHJlc291cmNlLnByb3BlcnRpZXM/LlR5cGU7XG4gICAgaWYgKGxvYWRCYWxhbmNlclR5cGUgJiYgbG9hZEJhbGFuY2VyVHlwZSAhPT0gJ2FwcGxpY2F0aW9uJykge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgYW1vdW50OiAwLFxuICAgICAgICBjdXJyZW5jeTogJ1VTRCcsXG4gICAgICAgIGNvbmZpZGVuY2U6ICd1bmtub3duJyxcbiAgICAgICAgYXNzdW1wdGlvbnM6IFsnVGhpcyBjYWxjdWxhdG9yIG9ubHkgc3VwcG9ydHMgQXBwbGljYXRpb24gTG9hZCBCYWxhbmNlcnMnXSxcbiAgICAgIH07XG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgIC8vIEdldCBob3VybHkgcmF0ZVxuICAgICAgY29uc3QgaG91cmx5UmF0ZSA9IGF3YWl0IHByaWNpbmdDbGllbnQuZ2V0UHJpY2Uoe1xuICAgICAgICBzZXJ2aWNlQ29kZTogJ0FXU0VMQicsXG4gICAgICAgIHJlZ2lvbjogdGhpcy5ub3JtYWxpemVSZWdpb24ocmVnaW9uKSxcbiAgICAgICAgZmlsdGVyczogW1xuICAgICAgICAgIHsgZmllbGQ6ICdwcm9kdWN0RmFtaWx5JywgdmFsdWU6ICdMb2FkIEJhbGFuY2VyLUFwcGxpY2F0aW9uJyB9LFxuICAgICAgICAgIHsgZmllbGQ6ICd1c2FnZXR5cGUnLCB2YWx1ZTogYCR7dGhpcy5nZXRSZWdpb25QcmVmaXgocmVnaW9uKX1Mb2FkQmFsYW5jZXJVc2FnZWAgfSxcbiAgICAgICAgXSxcbiAgICAgIH0pO1xuXG4gICAgICAvLyBHZXQgTENVIHJhdGVcbiAgICAgIGNvbnN0IGxjdVJhdGUgPSBhd2FpdCBwcmljaW5nQ2xpZW50LmdldFByaWNlKHtcbiAgICAgICAgc2VydmljZUNvZGU6ICdBV1NFTEInLFxuICAgICAgICByZWdpb246IHRoaXMubm9ybWFsaXplUmVnaW9uKHJlZ2lvbiksXG4gICAgICAgIGZpbHRlcnM6IFtcbiAgICAgICAgICB7IGZpZWxkOiAncHJvZHVjdEZhbWlseScsIHZhbHVlOiAnTG9hZCBCYWxhbmNlci1BcHBsaWNhdGlvbicgfSxcbiAgICAgICAgICB7IGZpZWxkOiAndXNhZ2V0eXBlJywgdmFsdWU6IGAke3RoaXMuZ2V0UmVnaW9uUHJlZml4KHJlZ2lvbil9TENVVXNhZ2VgIH0sXG4gICAgICAgIF0sXG4gICAgICB9KTtcblxuICAgICAgY29uc3QgbmV3Q29ubmVjdGlvbnNQZXJTZWNvbmQgPVxuICAgICAgICB0aGlzLmN1c3RvbU5ld0Nvbm5lY3Rpb25zUGVyU2Vjb25kIHx8IHRoaXMuREVGQVVMVF9ORVdfQ09OTkVDVElPTlNfUEVSX1NFQ09ORDtcbiAgICAgIGNvbnN0IGFjdGl2ZUNvbm5lY3Rpb25zUGVyTWludXRlID1cbiAgICAgICAgdGhpcy5jdXN0b21BY3RpdmVDb25uZWN0aW9uc1Blck1pbnV0ZSB8fCB0aGlzLkRFRkFVTFRfQUNUSVZFX0NPTk5FQ1RJT05TX1BFUl9NSU5VVEU7XG4gICAgICBjb25zdCBwcm9jZXNzZWRCeXRlc0dCID1cbiAgICAgICAgdGhpcy5jdXN0b21Qcm9jZXNzZWRCeXRlc0dCIHx8IHRoaXMuREVGQVVMVF9QUk9DRVNTRURfQllURVNfR0I7XG5cbiAgICAgIGlmIChob3VybHlSYXRlID09PSBudWxsIHx8IGxjdVJhdGUgPT09IG51bGwpIHtcbiAgICAgICAgLy8gQ2FsY3VsYXRlIExDVSBjb25zdW1wdGlvbiBmb3IgYXNzdW1wdGlvbnMgZXZlbiB3aGVuIHByaWNpbmcgZmFpbHNcbiAgICAgICAgY29uc3QgbGN1RnJvbU5ld0Nvbm5lY3Rpb25zID0gbmV3Q29ubmVjdGlvbnNQZXJTZWNvbmQgLyAyNTtcbiAgICAgICAgY29uc3QgbGN1RnJvbUFjdGl2ZUNvbm5lY3Rpb25zID0gYWN0aXZlQ29ubmVjdGlvbnNQZXJNaW51dGUgLyAzMDAwO1xuICAgICAgICBjb25zdCBnYlBlckhvdXIgPSBwcm9jZXNzZWRCeXRlc0dCIC8gdGhpcy5IT1VSU19QRVJfTU9OVEg7XG4gICAgICAgIGNvbnN0IGxjdUZyb21Qcm9jZXNzZWRCeXRlcyA9IGdiUGVySG91cjtcbiAgICAgICAgY29uc3QgbGN1UGVySG91ciA9IE1hdGgubWF4KFxuICAgICAgICAgIGxjdUZyb21OZXdDb25uZWN0aW9ucyxcbiAgICAgICAgICBsY3VGcm9tQWN0aXZlQ29ubmVjdGlvbnMsXG4gICAgICAgICAgbGN1RnJvbVByb2Nlc3NlZEJ5dGVzLFxuICAgICAgICApO1xuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgYW1vdW50OiAwLFxuICAgICAgICAgIGN1cnJlbmN5OiAnVVNEJyxcbiAgICAgICAgICBjb25maWRlbmNlOiAndW5rbm93bicsXG4gICAgICAgICAgYXNzdW1wdGlvbnM6IFtcbiAgICAgICAgICAgIGBQcmljaW5nIGRhdGEgbm90IGF2YWlsYWJsZSBmb3IgQXBwbGljYXRpb24gTG9hZCBCYWxhbmNlciBpbiByZWdpb24gJHtyZWdpb259YCxcbiAgICAgICAgICAgIGBXb3VsZCB1c2UgTENVIGNvbnN1bXB0aW9uOiAke2xjdVBlckhvdXIudG9GaXhlZCgyKX0gTENVL2hvdXIgYmFzZWQgb246YCxcbiAgICAgICAgICAgIGAgIC0gTmV3IGNvbm5lY3Rpb25zOiAke25ld0Nvbm5lY3Rpb25zUGVyU2Vjb25kfS9zZWMg4oaSICR7bGN1RnJvbU5ld0Nvbm5lY3Rpb25zLnRvRml4ZWQoMil9IExDVWAsXG4gICAgICAgICAgICBgICAtIEFjdGl2ZSBjb25uZWN0aW9uczogJHthY3RpdmVDb25uZWN0aW9uc1Blck1pbnV0ZX0vbWluIOKGkiAke2xjdUZyb21BY3RpdmVDb25uZWN0aW9ucy50b0ZpeGVkKDIpfSBMQ1VgLFxuICAgICAgICAgICAgYCAgLSBQcm9jZXNzZWQgZGF0YTogJHtwcm9jZXNzZWRCeXRlc0dCfSBHQi9tb250aCDihpIgJHtsY3VGcm9tUHJvY2Vzc2VkQnl0ZXMudG9GaXhlZCgyKX0gTENVYCxcbiAgICAgICAgICBdLFxuICAgICAgICB9O1xuICAgICAgfVxuXG4gICAgICAvLyBDYWxjdWxhdGUgTENVIGNvbnN1bXB0aW9uXG4gICAgICAvLyAxIExDVSBwcm92aWRlczogMjUgbmV3IGNvbm5lY3Rpb25zL3NlYywgMzAwMCBhY3RpdmUgY29ubmVjdGlvbnMvbWluLCAxIEdCIHByb2Nlc3NlZC9ob3VyLCAxMDAwIHJ1bGUgZXZhbHVhdGlvbnMvc2VjXG4gICAgICBjb25zdCBsY3VGcm9tTmV3Q29ubmVjdGlvbnMgPSBuZXdDb25uZWN0aW9uc1BlclNlY29uZCAvIDI1O1xuICAgICAgY29uc3QgbGN1RnJvbUFjdGl2ZUNvbm5lY3Rpb25zID0gYWN0aXZlQ29ubmVjdGlvbnNQZXJNaW51dGUgLyAzMDAwO1xuICAgICAgY29uc3QgZ2JQZXJIb3VyID0gcHJvY2Vzc2VkQnl0ZXNHQiAvIHRoaXMuSE9VUlNfUEVSX01PTlRIO1xuICAgICAgY29uc3QgbGN1RnJvbVByb2Nlc3NlZEJ5dGVzID0gZ2JQZXJIb3VyO1xuXG4gICAgICAvLyBVc2UgdGhlIGhpZ2hlc3QgTENVIGNvbnN1bXB0aW9uXG4gICAgICBjb25zdCBsY3VQZXJIb3VyID0gTWF0aC5tYXgoXG4gICAgICAgIGxjdUZyb21OZXdDb25uZWN0aW9ucyxcbiAgICAgICAgbGN1RnJvbUFjdGl2ZUNvbm5lY3Rpb25zLFxuICAgICAgICBsY3VGcm9tUHJvY2Vzc2VkQnl0ZXMsXG4gICAgICApO1xuXG4gICAgICBjb25zdCBob3VybHlDb3N0ID0gaG91cmx5UmF0ZSAqIHRoaXMuSE9VUlNfUEVSX01PTlRIO1xuICAgICAgY29uc3QgbGN1Q29zdCA9IGxjdVJhdGUgKiBsY3VQZXJIb3VyICogdGhpcy5IT1VSU19QRVJfTU9OVEg7XG4gICAgICBjb25zdCB0b3RhbENvc3QgPSBob3VybHlDb3N0ICsgbGN1Q29zdDtcblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgYW1vdW50OiB0b3RhbENvc3QsXG4gICAgICAgIGN1cnJlbmN5OiAnVVNEJyxcbiAgICAgICAgY29uZmlkZW5jZTogJ21lZGl1bScsXG4gICAgICAgIGFzc3VtcHRpb25zOiBbXG4gICAgICAgICAgYEhvdXJseSByYXRlOiAkJHtob3VybHlSYXRlLnRvRml4ZWQoNCl9L2hvdXIgw5cgJHt0aGlzLkhPVVJTX1BFUl9NT05USH0gaG91cnMgPSAkJHtob3VybHlDb3N0LnRvRml4ZWQoMil9L21vbnRoYCxcbiAgICAgICAgICBgTENVIGNvbnN1bXB0aW9uOiAke2xjdVBlckhvdXIudG9GaXhlZCgyKX0gTENVL2hvdXIgYmFzZWQgb246YCxcbiAgICAgICAgICBgICAtIE5ldyBjb25uZWN0aW9uczogJHtuZXdDb25uZWN0aW9uc1BlclNlY29uZH0vc2VjIOKGkiAke2xjdUZyb21OZXdDb25uZWN0aW9ucy50b0ZpeGVkKDIpfSBMQ1VgLFxuICAgICAgICAgIGAgIC0gQWN0aXZlIGNvbm5lY3Rpb25zOiAke2FjdGl2ZUNvbm5lY3Rpb25zUGVyTWludXRlfS9taW4g4oaSICR7bGN1RnJvbUFjdGl2ZUNvbm5lY3Rpb25zLnRvRml4ZWQoMil9IExDVWAsXG4gICAgICAgICAgYCAgLSBQcm9jZXNzZWQgZGF0YTogJHtwcm9jZXNzZWRCeXRlc0dCfSBHQi9tb250aCDihpIgJHtsY3VGcm9tUHJvY2Vzc2VkQnl0ZXMudG9GaXhlZCgyKX0gTENVYCxcbiAgICAgICAgICBgTENVIGNvc3Q6ICQke2xjdVJhdGUudG9GaXhlZCg0KX0vTENVL2hvdXIgw5cgJHtsY3VQZXJIb3VyLnRvRml4ZWQoMil9IExDVSDDlyAke3RoaXMuSE9VUlNfUEVSX01PTlRIfSBob3VycyA9ICQke2xjdUNvc3QudG9GaXhlZCgyKX0vbW9udGhgLFxuICAgICAgICAgIGBUb3RhbDogJCR7dG90YWxDb3N0LnRvRml4ZWQoMil9L21vbnRoYCxcbiAgICAgICAgXSxcbiAgICAgIH07XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGNvbnN0IG5ld0Nvbm5lY3Rpb25zUGVyU2Vjb25kID1cbiAgICAgICAgdGhpcy5jdXN0b21OZXdDb25uZWN0aW9uc1BlclNlY29uZCB8fCB0aGlzLkRFRkFVTFRfTkVXX0NPTk5FQ1RJT05TX1BFUl9TRUNPTkQ7XG4gICAgICBjb25zdCBhY3RpdmVDb25uZWN0aW9uc1Blck1pbnV0ZSA9XG4gICAgICAgIHRoaXMuY3VzdG9tQWN0aXZlQ29ubmVjdGlvbnNQZXJNaW51dGUgfHwgdGhpcy5ERUZBVUxUX0FDVElWRV9DT05ORUNUSU9OU19QRVJfTUlOVVRFO1xuICAgICAgY29uc3QgcHJvY2Vzc2VkQnl0ZXNHQiA9XG4gICAgICAgIHRoaXMuY3VzdG9tUHJvY2Vzc2VkQnl0ZXNHQiB8fCB0aGlzLkRFRkFVTFRfUFJPQ0VTU0VEX0JZVEVTX0dCO1xuXG4gICAgICAvLyBDYWxjdWxhdGUgTENVIGNvbnN1bXB0aW9uIGZvciBhc3N1bXB0aW9ucyBldmVuIHdoZW4gZXJyb3Igb2NjdXJzXG4gICAgICBjb25zdCBsY3VGcm9tTmV3Q29ubmVjdGlvbnMgPSBuZXdDb25uZWN0aW9uc1BlclNlY29uZCAvIDI1O1xuICAgICAgY29uc3QgbGN1RnJvbUFjdGl2ZUNvbm5lY3Rpb25zID0gYWN0aXZlQ29ubmVjdGlvbnNQZXJNaW51dGUgLyAzMDAwO1xuICAgICAgY29uc3QgZ2JQZXJIb3VyID0gcHJvY2Vzc2VkQnl0ZXNHQiAvIHRoaXMuSE9VUlNfUEVSX01PTlRIO1xuICAgICAgY29uc3QgbGN1RnJvbVByb2Nlc3NlZEJ5dGVzID0gZ2JQZXJIb3VyO1xuICAgICAgY29uc3QgbGN1UGVySG91ciA9IE1hdGgubWF4KFxuICAgICAgICBsY3VGcm9tTmV3Q29ubmVjdGlvbnMsXG4gICAgICAgIGxjdUZyb21BY3RpdmVDb25uZWN0aW9ucyxcbiAgICAgICAgbGN1RnJvbVByb2Nlc3NlZEJ5dGVzLFxuICAgICAgKTtcblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgYW1vdW50OiAwLFxuICAgICAgICBjdXJyZW5jeTogJ1VTRCcsXG4gICAgICAgIGNvbmZpZGVuY2U6ICd1bmtub3duJyxcbiAgICAgICAgYXNzdW1wdGlvbnM6IFtcbiAgICAgICAgICBgRmFpbGVkIHRvIGZldGNoIHByaWNpbmc6ICR7ZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiBTdHJpbmcoZXJyb3IpfWAsXG4gICAgICAgICAgYFdvdWxkIHVzZSBMQ1UgY29uc3VtcHRpb246ICR7bGN1UGVySG91ci50b0ZpeGVkKDIpfSBMQ1UvaG91ciBiYXNlZCBvbjpgLFxuICAgICAgICAgIGAgIC0gTmV3IGNvbm5lY3Rpb25zOiAke25ld0Nvbm5lY3Rpb25zUGVyU2Vjb25kfS9zZWMg4oaSICR7bGN1RnJvbU5ld0Nvbm5lY3Rpb25zLnRvRml4ZWQoMil9IExDVWAsXG4gICAgICAgICAgYCAgLSBBY3RpdmUgY29ubmVjdGlvbnM6ICR7YWN0aXZlQ29ubmVjdGlvbnNQZXJNaW51dGV9L21pbiDihpIgJHtsY3VGcm9tQWN0aXZlQ29ubmVjdGlvbnMudG9GaXhlZCgyKX0gTENVYCxcbiAgICAgICAgICBgICAtIFByb2Nlc3NlZCBkYXRhOiAke3Byb2Nlc3NlZEJ5dGVzR0J9IEdCL21vbnRoIOKGkiAke2xjdUZyb21Qcm9jZXNzZWRCeXRlcy50b0ZpeGVkKDIpfSBMQ1VgLFxuICAgICAgICBdLFxuICAgICAgfTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIG5vcm1hbGl6ZVJlZ2lvbihyZWdpb246IHN0cmluZyk6IHN0cmluZyB7XG4gICAgY29uc3QgcmVnaW9uTWFwOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge1xuICAgICAgJ3VzLWVhc3QtMSc6ICdVUyBFYXN0IChOLiBWaXJnaW5pYSknLFxuICAgICAgJ3VzLWVhc3QtMic6ICdVUyBFYXN0IChPaGlvKScsXG4gICAgICAndXMtd2VzdC0xJzogJ1VTIFdlc3QgKE4uIENhbGlmb3JuaWEpJyxcbiAgICAgICd1cy13ZXN0LTInOiAnVVMgV2VzdCAoT3JlZ29uKScsXG4gICAgICAnZXUtd2VzdC0xJzogJ0VVIChJcmVsYW5kKScsXG4gICAgICAnZXUtd2VzdC0yJzogJ0VVIChMb25kb24pJyxcbiAgICAgICdldS13ZXN0LTMnOiAnRVUgKFBhcmlzKScsXG4gICAgICAnZXUtY2VudHJhbC0xJzogJ0VVIChGcmFua2Z1cnQpJyxcbiAgICAgICdldS1ub3J0aC0xJzogJ0VVIChTdG9ja2hvbG0pJyxcbiAgICAgICdhcC1zb3V0aC0xJzogJ0FzaWEgUGFjaWZpYyAoTXVtYmFpKScsXG4gICAgICAnYXAtc291dGhlYXN0LTEnOiAnQXNpYSBQYWNpZmljIChTaW5nYXBvcmUpJyxcbiAgICAgICdhcC1zb3V0aGVhc3QtMic6ICdBc2lhIFBhY2lmaWMgKFN5ZG5leSknLFxuICAgICAgJ2FwLW5vcnRoZWFzdC0xJzogJ0FzaWEgUGFjaWZpYyAoVG9reW8pJyxcbiAgICAgICdhcC1ub3J0aGVhc3QtMic6ICdBc2lhIFBhY2lmaWMgKFNlb3VsKScsXG4gICAgfTtcblxuICAgIHJldHVybiByZWdpb25NYXBbcmVnaW9uXSB8fCByZWdpb247XG4gIH1cblxuICBwcml2YXRlIGdldFJlZ2lvblByZWZpeChyZWdpb246IHN0cmluZyk6IHN0cmluZyB7XG4gICAgY29uc3QgcHJlZml4TWFwOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge1xuICAgICAgJ3VzLWVhc3QtMSc6ICdVU0UxJyxcbiAgICAgICd1cy1lYXN0LTInOiAnVVNFMicsXG4gICAgICAndXMtd2VzdC0xJzogJ1VTVzEnLFxuICAgICAgJ3VzLXdlc3QtMic6ICdVU1cyJyxcbiAgICAgICdldS13ZXN0LTEnOiAnRVVXMScsXG4gICAgICAnZXUtd2VzdC0yJzogJ0VVVzInLFxuICAgICAgJ2V1LXdlc3QtMyc6ICdFVVczJyxcbiAgICAgICdldS1jZW50cmFsLTEnOiAnRVVDMScsXG4gICAgICAnZXUtbm9ydGgtMSc6ICdFVU4xJyxcbiAgICAgICdhcC1zb3V0aC0xJzogJ0FQUzEnLFxuICAgICAgJ2FwLXNvdXRoZWFzdC0xJzogJ0FQUzInLFxuICAgICAgJ2FwLXNvdXRoZWFzdC0yJzogJ0FQUzMnLFxuICAgICAgJ2FwLW5vcnRoZWFzdC0xJzogJ0FQTjEnLFxuICAgICAgJ2FwLW5vcnRoZWFzdC0yJzogJ0FQTjInLFxuICAgIH07XG5cbiAgICByZXR1cm4gcHJlZml4TWFwW3JlZ2lvbl0gfHwgJyc7XG4gIH1cbn1cbiJdfQ==
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { ResourceWithId } from '../../diff/types';
|
|
2
|
+
import { ResourceCostCalculator, MonthlyCost, PricingClient } from '../types';
|
|
3
|
+
export declare class APIGatewayCalculator implements ResourceCostCalculator {
|
|
4
|
+
supports(resourceType: string): boolean;
|
|
5
|
+
calculateCost(resource: ResourceWithId, region: string, pricingClient: PricingClient): Promise<MonthlyCost>;
|
|
6
|
+
private calculateRestApiCost;
|
|
7
|
+
private calculateHttpApiCost;
|
|
8
|
+
private calculateWebSocketCost;
|
|
9
|
+
private normalizeRegion;
|
|
10
|
+
}
|