@ingeno/pipedream-services 1.0.77 → 1.0.78

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 (88) hide show
  1. package/dist/aws/apn/zoho-crm/analytics-to-zoho-sync.d.ts +27 -0
  2. package/dist/aws/apn/zoho-crm/analytics-to-zoho-sync.d.ts.map +1 -0
  3. package/dist/aws/apn/zoho-crm/analytics-to-zoho-sync.js +89 -0
  4. package/dist/aws/apn/zoho-crm/analytics-to-zoho-sync.js.map +1 -0
  5. package/dist/aws/apn/zoho-crm/index.d.ts +1 -0
  6. package/dist/aws/apn/zoho-crm/index.d.ts.map +1 -1
  7. package/dist/aws/apn/zoho-crm/index.js +1 -0
  8. package/dist/aws/apn/zoho-crm/index.js.map +1 -1
  9. package/dist/aws/cost/cost-schema.d.ts +4 -0
  10. package/dist/aws/cost/cost-schema.d.ts.map +1 -0
  11. package/dist/aws/cost/cost-schema.js +19 -0
  12. package/dist/aws/cost/cost-schema.js.map +1 -0
  13. package/dist/aws/cost/index.d.ts +8 -0
  14. package/dist/aws/cost/index.d.ts.map +1 -0
  15. package/dist/aws/cost/index.js +8 -0
  16. package/dist/aws/cost/index.js.map +1 -0
  17. package/dist/aws/cost/metrics.d.ts +18 -0
  18. package/dist/aws/cost/metrics.d.ts.map +1 -0
  19. package/dist/aws/cost/metrics.js +41 -0
  20. package/dist/aws/cost/metrics.js.map +1 -0
  21. package/dist/aws/cost/orchestrator.d.ts +30 -0
  22. package/dist/aws/cost/orchestrator.d.ts.map +1 -0
  23. package/dist/aws/cost/orchestrator.js +52 -0
  24. package/dist/aws/cost/orchestrator.js.map +1 -0
  25. package/dist/aws/cost/steps/account-fetcher-step.d.ts +16 -0
  26. package/dist/aws/cost/steps/account-fetcher-step.d.ts.map +1 -0
  27. package/dist/aws/cost/steps/account-fetcher-step.js +23 -0
  28. package/dist/aws/cost/steps/account-fetcher-step.js.map +1 -0
  29. package/dist/aws/cost/steps/cost-explorer-step.d.ts +27 -0
  30. package/dist/aws/cost/steps/cost-explorer-step.d.ts.map +1 -0
  31. package/dist/aws/cost/steps/cost-explorer-step.js +100 -0
  32. package/dist/aws/cost/steps/cost-explorer-step.js.map +1 -0
  33. package/dist/aws/execute-as.d.ts +14 -0
  34. package/dist/aws/execute-as.d.ts.map +1 -1
  35. package/dist/aws/execute-as.js +22 -0
  36. package/dist/aws/execute-as.js.map +1 -1
  37. package/dist/aws/index.d.ts +1 -1
  38. package/dist/aws/index.d.ts.map +1 -1
  39. package/dist/aws/index.js +1 -1
  40. package/dist/aws/index.js.map +1 -1
  41. package/dist/collections/types.d.ts +1 -1
  42. package/dist/collections/types.d.ts.map +1 -1
  43. package/dist/index.d.ts +1 -0
  44. package/dist/index.d.ts.map +1 -1
  45. package/dist/index.js +1 -0
  46. package/dist/index.js.map +1 -1
  47. package/dist/pipeline/database-operations.d.ts +26 -0
  48. package/dist/pipeline/database-operations.d.ts.map +1 -0
  49. package/dist/pipeline/database-operations.js +84 -0
  50. package/dist/pipeline/database-operations.js.map +1 -0
  51. package/dist/pipeline/index.d.ts +5 -0
  52. package/dist/pipeline/index.d.ts.map +1 -0
  53. package/dist/pipeline/index.js +4 -0
  54. package/dist/pipeline/index.js.map +1 -0
  55. package/dist/pipeline/pipeline-builder.d.ts +15 -0
  56. package/dist/pipeline/pipeline-builder.d.ts.map +1 -0
  57. package/dist/pipeline/pipeline-builder.js +24 -0
  58. package/dist/pipeline/pipeline-builder.js.map +1 -0
  59. package/dist/postgres/index.d.ts +1 -0
  60. package/dist/postgres/index.d.ts.map +1 -1
  61. package/dist/postgres/index.js +1 -0
  62. package/dist/postgres/index.js.map +1 -1
  63. package/dist/postgres/postgres.d.ts +3 -1
  64. package/dist/postgres/postgres.d.ts.map +1 -1
  65. package/dist/postgres/postgres.js +31 -1
  66. package/dist/postgres/postgres.js.map +1 -1
  67. package/dist/postgres/query-executor.d.ts +13 -0
  68. package/dist/postgres/query-executor.d.ts.map +1 -0
  69. package/dist/postgres/query-executor.js +52 -0
  70. package/dist/postgres/query-executor.js.map +1 -0
  71. package/dist/slack/example.d.ts.map +1 -1
  72. package/dist/slack/example.js.map +1 -1
  73. package/dist/slack/slack-service.d.ts +1 -1
  74. package/dist/slack/slack-service.d.ts.map +1 -1
  75. package/dist/slack/slack-service.js +8 -8
  76. package/dist/slack/slack-service.js.map +1 -1
  77. package/dist/zoho-crm/zoho-crm-client.js +2 -2
  78. package/dist/zoho-crm/zoho-crm-fetcher.d.ts.map +1 -1
  79. package/dist/zoho-crm/zoho-crm-fetcher.js +3 -3
  80. package/dist/zoho-crm/zoho-crm-fetcher.js.map +1 -1
  81. package/dist/zoho-crm/zoho-crm-to-database-collection-converter.d.ts.map +1 -1
  82. package/dist/zoho-crm/zoho-crm-to-database-collection-converter.js +7 -7
  83. package/dist/zoho-crm/zoho-crm-to-database-collection-converter.js.map +1 -1
  84. package/package.json +1 -1
  85. package/dist/aws/aws-cost.d.ts +0 -33
  86. package/dist/aws/aws-cost.d.ts.map +0 -1
  87. package/dist/aws/aws-cost.js +0 -98
  88. package/dist/aws/aws-cost.js.map +0 -1
@@ -0,0 +1,27 @@
1
+ import { ZohoCRMConfig } from '../../../zoho-crm/zoho-crm-client.js';
2
+ import { PostgresAuth } from '../../../postgres/postgres.js';
3
+ export interface AwsAnalyticsRecord {
4
+ opportunity_id: string;
5
+ customer_type: string | null;
6
+ geo: string | null;
7
+ is_greenfield: boolean | null;
8
+ segment: string | null;
9
+ aws_stage: string | null;
10
+ }
11
+ export interface AnalyticsSyncConfig {
12
+ zoho: ZohoCRMConfig;
13
+ postgres: PostgresAuth;
14
+ }
15
+ export interface AnalyticsSyncResult {
16
+ totalProcessed: number;
17
+ updated: number;
18
+ notFoundInZoho: number;
19
+ skipped: number;
20
+ errors: number;
21
+ errorDetails: Array<{
22
+ opportunityId: string;
23
+ error: string;
24
+ }>;
25
+ }
26
+ export declare function syncAwsAnalyticsToZoho(config: AnalyticsSyncConfig): Promise<AnalyticsSyncResult>;
27
+ //# sourceMappingURL=analytics-to-zoho-sync.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analytics-to-zoho-sync.d.ts","sourceRoot":"","sources":["../../../../src/aws/apn/zoho-crm/analytics-to-zoho-sync.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,aAAa,EAAE,MAAM,sCAAsC,CAAA;AACnF,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAA;AAK5D,MAAM,WAAW,kBAAkB;IACjC,cAAc,EAAE,MAAM,CAAA;IACtB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;IAClB,aAAa,EAAE,OAAO,GAAG,IAAI,CAAA;IAC7B,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;IACtB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;CACzB;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,aAAa,CAAA;IACnB,QAAQ,EAAE,YAAY,CAAA;CACvB;AAED,MAAM,WAAW,mBAAmB;IAClC,cAAc,EAAE,MAAM,CAAA;IACtB,OAAO,EAAE,MAAM,CAAA;IACf,cAAc,EAAE,MAAM,CAAA;IACtB,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,MAAM,CAAA;IACd,YAAY,EAAE,KAAK,CAAC;QAClB,aAAa,EAAE,MAAM,CAAA;QACrB,KAAK,EAAE,MAAM,CAAA;KACd,CAAC,CAAA;CACH;AAED,wBAAsB,sBAAsB,CAAC,MAAM,EAAE,mBAAmB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CA4GtG"}
@@ -0,0 +1,89 @@
1
+ import { ZohoCRMClient } from '../../../zoho-crm/zoho-crm-client.js';
2
+ import pg from 'pg';
3
+ const { Pool } = pg;
4
+ export async function syncAwsAnalyticsToZoho(config) {
5
+ const zohoCrmClient = new ZohoCRMClient(config.zoho);
6
+ const pool = new Pool({
7
+ ...config.postgres,
8
+ max: 5,
9
+ // Allow process to exit when pool is idle - prevents hanging processes
10
+ allowExitOnIdle: true,
11
+ });
12
+ try {
13
+ console.log('🚀 Starting AWS analytics to Zoho sync');
14
+ // Fetch all AWS analytics data
15
+ const awsAnalyticsResult = await pool.query('SELECT opportunity_id, customer_type, geo, is_greenfield, segment, aws_stage FROM aws_opportunities_analytics WHERE opportunity_id IS NOT NULL');
16
+ const awsAnalytics = awsAnalyticsResult.rows;
17
+ console.log(`Found ${awsAnalytics.length} AWS analytics records`);
18
+ const result = {
19
+ totalProcessed: awsAnalytics.length,
20
+ updated: 0,
21
+ notFoundInZoho: 0,
22
+ skipped: 0,
23
+ errors: 0,
24
+ errorDetails: []
25
+ };
26
+ for (const analytics of awsAnalytics) {
27
+ try {
28
+ // Find matching Zoho APN Opportunity
29
+ const zohoResult = await pool.query('SELECT id, opportunity_id, aws_customer_type, aws_geo, aws_is_greenfield, aws_segment, aws_stage FROM zoho_crm_apn_opportunities WHERE opportunity_id = $1', [analytics.opportunity_id]);
30
+ if (zohoResult.rows.length === 0) {
31
+ result.notFoundInZoho++;
32
+ console.log(`No Zoho APN opportunity found for ${analytics.opportunity_id}`);
33
+ continue;
34
+ }
35
+ const zohoOpp = zohoResult.rows[0];
36
+ // Check if update is needed
37
+ const greenfieldValue = analytics.is_greenfield === true ? 'Greenfield' : 'Not Greenfield';
38
+ const needsUpdate = zohoOpp.aws_customer_type !== analytics.customer_type ||
39
+ zohoOpp.aws_geo !== analytics.geo ||
40
+ zohoOpp.aws_is_greenfield !== greenfieldValue ||
41
+ zohoOpp.aws_segment !== analytics.segment ||
42
+ zohoOpp.aws_stage !== analytics.aws_stage;
43
+ if (!needsUpdate) {
44
+ result.skipped++;
45
+ console.log(`No updates needed for ${analytics.opportunity_id}`);
46
+ continue;
47
+ }
48
+ // Update Zoho CRM via API
49
+ const updateData = {
50
+ AWS_Customer_Type: analytics.customer_type,
51
+ AWS_Geo: analytics.geo,
52
+ AWS_Is_Greenfield: greenfieldValue,
53
+ AWS_Segment: analytics.segment,
54
+ AWS_Stage: analytics.aws_stage,
55
+ };
56
+ await zohoCrmClient.updateRecord('APN_Opportunities', zohoOpp.id, updateData);
57
+ result.updated++;
58
+ console.log(`✅ Updated Zoho opportunity ${analytics.opportunity_id}`);
59
+ // Update our local database copy
60
+ await pool.query(`UPDATE zoho_crm_apn_opportunities
61
+ SET aws_customer_type = $1, aws_geo = $2, aws_is_greenfield = $3, aws_segment = $4, aws_stage = $5
62
+ WHERE id = $6`, [
63
+ analytics.customer_type,
64
+ analytics.geo,
65
+ greenfieldValue,
66
+ analytics.segment,
67
+ analytics.aws_stage,
68
+ zohoOpp.id
69
+ ]);
70
+ }
71
+ catch (error) {
72
+ result.errors++;
73
+ const errorMessage = error instanceof Error ? error.message : String(error);
74
+ result.errorDetails.push({
75
+ opportunityId: analytics.opportunity_id,
76
+ error: errorMessage
77
+ });
78
+ console.error(`❌ Failed to update ${analytics.opportunity_id}:`, errorMessage);
79
+ }
80
+ }
81
+ console.log('✅ AWS analytics sync completed');
82
+ console.log(`Results: Processed ${result.totalProcessed}, Updated ${result.updated}, Not found ${result.notFoundInZoho}, Skipped ${result.skipped}, Errors ${result.errors}`);
83
+ return result;
84
+ }
85
+ finally {
86
+ await pool.end();
87
+ }
88
+ }
89
+ //# sourceMappingURL=analytics-to-zoho-sync.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analytics-to-zoho-sync.js","sourceRoot":"","sources":["../../../../src/aws/apn/zoho-crm/analytics-to-zoho-sync.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,6 @@
1
1
  export * from './apn-opportunities-sync.js';
2
2
  export * from './apn-opportunities-sync-step.js';
3
+ export * from './analytics-to-zoho-sync.js';
3
4
  export * from './types.js';
4
5
  export * from './opportunity-transformer.js';
5
6
  export * from './opportunity-matcher.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/aws/apn/zoho-crm/index.ts"],"names":[],"mappings":"AAAA,cAAc,6BAA6B,CAAA;AAC3C,cAAc,kCAAkC,CAAA;AAChD,cAAc,YAAY,CAAA;AAC1B,cAAc,8BAA8B,CAAA;AAC5C,cAAc,0BAA0B,CAAA;AACxC,cAAc,wBAAwB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/aws/apn/zoho-crm/index.ts"],"names":[],"mappings":"AAAA,cAAc,6BAA6B,CAAA;AAC3C,cAAc,kCAAkC,CAAA;AAChD,cAAc,6BAA6B,CAAA;AAC3C,cAAc,YAAY,CAAA;AAC1B,cAAc,8BAA8B,CAAA;AAC5C,cAAc,0BAA0B,CAAA;AACxC,cAAc,wBAAwB,CAAA"}
@@ -1,5 +1,6 @@
1
1
  export * from './apn-opportunities-sync.js';
2
2
  export * from './apn-opportunities-sync-step.js';
3
+ export * from './analytics-to-zoho-sync.js';
3
4
  export * from './types.js';
4
5
  export * from './opportunity-transformer.js';
5
6
  export * from './opportunity-matcher.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/aws/apn/zoho-crm/index.ts"],"names":[],"mappings":"AAAA,cAAc,6BAA6B,CAAA;AAC3C,cAAc,kCAAkC,CAAA;AAChD,cAAc,YAAY,CAAA;AAC1B,cAAc,8BAA8B,CAAA;AAC5C,cAAc,0BAA0B,CAAA;AACxC,cAAc,wBAAwB,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/aws/apn/zoho-crm/index.ts"],"names":[],"mappings":"AAAA,cAAc,6BAA6B,CAAA;AAC3C,cAAc,kCAAkC,CAAA;AAChD,cAAc,6BAA6B,CAAA;AAC3C,cAAc,YAAY,CAAA;AAC1B,cAAc,8BAA8B,CAAA;AAC5C,cAAc,0BAA0B,CAAA;AACxC,cAAc,wBAAwB,CAAA"}
@@ -0,0 +1,4 @@
1
+ import type { CollectionSchema } from '../../collections/types.js';
2
+ import type { DateRange } from '../../date/date-range.js';
3
+ export declare function createCostDataSchema(dateRange: DateRange): CollectionSchema;
4
+ //# sourceMappingURL=cost-schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cost-schema.d.ts","sourceRoot":"","sources":["../../../src/aws/cost/cost-schema.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAA;AAClE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAA;AAEzD,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,SAAS,GAAG,gBAAgB,CAiB3E"}
@@ -0,0 +1,19 @@
1
+ import { CostMetrics } from '../cost/metrics.js';
2
+ export function createCostDataSchema(dateRange) {
3
+ const metrics = new CostMetrics();
4
+ return {
5
+ name: 'cost_and_usage',
6
+ prepareMode: `date >= '${dateRange.startDate}' and date < '${dateRange.endDate}'`,
7
+ columns: [
8
+ { name: 'id', type: 'id' },
9
+ { name: 'date', type: 'date' },
10
+ { name: 'account_id' },
11
+ { name: 'service' },
12
+ ...metrics.getSnakeCaseNames().map((name) => ({
13
+ name,
14
+ type: 'currency',
15
+ })),
16
+ ],
17
+ };
18
+ }
19
+ //# sourceMappingURL=cost-schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cost-schema.js","sourceRoot":"","sources":["../../../src/aws/cost/cost-schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAIhD,MAAM,UAAU,oBAAoB,CAAC,SAAoB;IACvD,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAA;IAEjC,OAAO;QACL,IAAI,EAAE,gBAAgB;QACtB,WAAW,EAAE,YAAY,SAAS,CAAC,SAAS,iBAAiB,SAAS,CAAC,OAAO,GAAG;QACjF,OAAO,EAAE;YACP,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE;YAC1B,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE;YAC9B,EAAE,IAAI,EAAE,YAAY,EAAE;YACtB,EAAE,IAAI,EAAE,SAAS,EAAE;YACnB,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC,GAAG,CAAC,CAAC,IAAY,EAAE,EAAE,CAAC,CAAC;gBACpD,IAAI;gBACJ,IAAI,EAAE,UAAmB;aAC1B,CAAC,CAAC;SACJ;KACF,CAAA;AACH,CAAC"}
@@ -0,0 +1,8 @@
1
+ export { AwsCostStreamingOrchestrator } from './orchestrator.js';
2
+ export { AccountFetcherStep } from './steps/account-fetcher-step.js';
3
+ export { CostExplorerStep } from './steps/cost-explorer-step.js';
4
+ export { createCostDataSchema } from './cost-schema.js';
5
+ export type { StreamingOrchestratorOptions, StreamingOrchestratorResult } from './orchestrator.js';
6
+ export type { AwsAccount as StreamingAwsAccount } from './steps/account-fetcher-step.js';
7
+ export type { CostData as StreamingCostData } from './steps/cost-explorer-step.js';
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/aws/cost/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,4BAA4B,EAAE,MAAM,mBAAmB,CAAA;AAGhE,OAAO,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAA;AACpE,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAA;AAGhE,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAA;AAGvD,YAAY,EACV,4BAA4B,EAC5B,2BAA2B,EAC5B,MAAM,mBAAmB,CAAA;AAG1B,YAAY,EAAE,UAAU,IAAI,mBAAmB,EAAE,MAAM,iCAAiC,CAAA;AACxF,YAAY,EAAE,QAAQ,IAAI,iBAAiB,EAAE,MAAM,+BAA+B,CAAA"}
@@ -0,0 +1,8 @@
1
+ // Main orchestrator
2
+ export { AwsCostStreamingOrchestrator } from './orchestrator.js';
3
+ // AWS-specific pipeline steps
4
+ export { AccountFetcherStep } from './steps/account-fetcher-step.js';
5
+ export { CostExplorerStep } from './steps/cost-explorer-step.js';
6
+ // Schema factory
7
+ export { createCostDataSchema } from './cost-schema.js';
8
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/aws/cost/index.ts"],"names":[],"mappings":"AAAA,oBAAoB;AACpB,OAAO,EAAE,4BAA4B,EAAE,MAAM,mBAAmB,CAAA;AAEhE,8BAA8B;AAC9B,OAAO,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAA;AACpE,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAA;AAEhE,iBAAiB;AACjB,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAA"}
@@ -0,0 +1,18 @@
1
+ export interface CostMetric {
2
+ readonly name: string;
3
+ readonly snakeCaseName: string;
4
+ readonly upperCaseName: string;
5
+ }
6
+ export declare class CostMetrics {
7
+ private readonly metrics;
8
+ constructor();
9
+ getAllMetrics(): readonly CostMetric[];
10
+ getMetricNames(): readonly string[];
11
+ getUpperCaseNames(): readonly string[];
12
+ getSnakeCaseNames(): readonly string[];
13
+ createMetricRecord(groupMetrics: Record<string, {
14
+ Amount?: string;
15
+ }>): Record<string, string>;
16
+ private toSnakeCase;
17
+ }
18
+ //# sourceMappingURL=metrics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metrics.d.ts","sourceRoot":"","sources":["../../../src/aws/cost/metrics.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;IAC9B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;CAC/B;AAED,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAc;;IAoBtC,aAAa,IAAI,SAAS,UAAU,EAAE;IAItC,cAAc,IAAI,SAAS,MAAM,EAAE;IAInC,iBAAiB,IAAI,SAAS,MAAM,EAAE;IAItC,iBAAiB,IAAI,SAAS,MAAM,EAAE;IAItC,kBAAkB,CAAC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IAU7F,OAAO,CAAC,WAAW;CAGpB"}
@@ -0,0 +1,41 @@
1
+ export class CostMetrics {
2
+ metrics;
3
+ constructor() {
4
+ const metricNames = [
5
+ 'BlendedCost',
6
+ 'UnblendedCost',
7
+ 'UsageQuantity',
8
+ 'NormalizedUsageAmount',
9
+ 'AmortizedCost',
10
+ 'NetUnblendedCost',
11
+ 'NetAmortizedCost',
12
+ ];
13
+ this.metrics = metricNames.map(name => ({
14
+ name,
15
+ snakeCaseName: this.toSnakeCase(name),
16
+ upperCaseName: this.toSnakeCase(name).toUpperCase(),
17
+ }));
18
+ }
19
+ getAllMetrics() {
20
+ return this.metrics;
21
+ }
22
+ getMetricNames() {
23
+ return this.metrics.map(m => m.name);
24
+ }
25
+ getUpperCaseNames() {
26
+ return this.metrics.map(m => m.upperCaseName);
27
+ }
28
+ getSnakeCaseNames() {
29
+ return this.metrics.map(m => m.snakeCaseName);
30
+ }
31
+ createMetricRecord(groupMetrics) {
32
+ return this.metrics.reduce((acc, metric) => ({
33
+ ...acc,
34
+ [metric.snakeCaseName]: groupMetrics[metric.name]?.Amount ?? '0',
35
+ }), {});
36
+ }
37
+ toSnakeCase(value) {
38
+ return value.replace(/([a-z])([A-Z])/g, '$1_$2').toLowerCase();
39
+ }
40
+ }
41
+ //# sourceMappingURL=metrics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metrics.js","sourceRoot":"","sources":["../../../src/aws/cost/metrics.ts"],"names":[],"mappings":"AAMA,MAAM,OAAO,WAAW;IACL,OAAO,CAAc;IAEtC;QACE,MAAM,WAAW,GAAG;YAClB,aAAa;YACb,eAAe;YACf,eAAe;YACf,uBAAuB;YACvB,eAAe;YACf,kBAAkB;YAClB,kBAAkB;SACnB,CAAA;QAED,IAAI,CAAC,OAAO,GAAG,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACtC,IAAI;YACJ,aAAa,EAAE,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC;YACrC,aAAa,EAAE,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE;SACpD,CAAC,CAAC,CAAA;IACL,CAAC;IAED,aAAa;QACX,OAAO,IAAI,CAAC,OAAO,CAAA;IACrB,CAAC;IAED,cAAc;QACZ,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAA;IACtC,CAAC;IAED,iBAAiB;QACf,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAA;IAC/C,CAAC;IAED,iBAAiB;QACf,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAA;IAC/C,CAAC;IAED,kBAAkB,CAAC,YAAiD;QAClE,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CACxB,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC;YAChB,GAAG,GAAG;YACN,CAAC,MAAM,CAAC,aAAa,CAAC,EAAE,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,MAAM,IAAI,GAAG;SACjE,CAAC,EACF,EAAE,CACH,CAAA;IACH,CAAC;IAEO,WAAW,CAAC,KAAa;QAC/B,OAAO,KAAK,CAAC,OAAO,CAAC,iBAAiB,EAAE,OAAO,CAAC,CAAC,WAAW,EAAE,CAAA;IAChE,CAAC;CACF"}
@@ -0,0 +1,30 @@
1
+ import type { PostgresAuth } from '../../postgres/postgres.js';
2
+ import type { DateRange } from '../../date/date-range.js';
3
+ import type { AwsCredentialIdentity } from '@aws-sdk/types';
4
+ export interface StreamingOrchestratorOptions {
5
+ readonly postgresAuth: PostgresAuth;
6
+ readonly awsCredentials: AwsCredentialIdentity;
7
+ readonly dateRange?: DateRange;
8
+ readonly tablesPrefix?: string;
9
+ readonly roleName?: string;
10
+ }
11
+ export interface StreamingOrchestratorResult {
12
+ readonly success: boolean;
13
+ readonly tableName: string;
14
+ readonly recordCount: number;
15
+ }
16
+ interface AwsCostPipelineContext {
17
+ readonly auth: PostgresAuth;
18
+ readonly awsCredentials: AwsCredentialIdentity;
19
+ readonly dateRange: DateRange;
20
+ readonly tablesPrefix: string;
21
+ readonly roleName: string;
22
+ }
23
+ export declare class AwsCostStreamingOrchestrator {
24
+ private readonly context;
25
+ constructor(options: StreamingOrchestratorOptions);
26
+ execute(): Promise<StreamingOrchestratorResult>;
27
+ getContext(): AwsCostPipelineContext;
28
+ }
29
+ export {};
30
+ //# sourceMappingURL=orchestrator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"orchestrator.d.ts","sourceRoot":"","sources":["../../../src/aws/cost/orchestrator.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAA;AAC9D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAA;AACzD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAA;AAI3D,MAAM,WAAW,4BAA4B;IAC3C,QAAQ,CAAC,YAAY,EAAE,YAAY,CAAA;IACnC,QAAQ,CAAC,cAAc,EAAE,qBAAqB,CAAA;IAC9C,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,CAAA;IAC9B,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAA;IAC9B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAC3B;AAED,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;IACzB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;CAC7B;AAED,UAAU,sBAAsB;IAC9B,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAA;IAC3B,QAAQ,CAAC,cAAc,EAAE,qBAAqB,CAAA;IAC9C,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAA;IAC7B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;IAC7B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;CAC1B;AAED,qBAAa,4BAA4B;IACvC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAwB;gBAEpC,OAAO,EAAE,4BAA4B;IAU3C,OAAO,IAAI,OAAO,CAAC,2BAA2B,CAAC;IAiCrD,UAAU,IAAI,sBAAsB;CAGrC"}
@@ -0,0 +1,52 @@
1
+ import { firstValueFrom } from 'rxjs';
2
+ import { monthsAgo } from '../../date/date-range.js';
3
+ import { createPipeline } from '../../pipeline/pipeline-builder.js';
4
+ import { DatabaseSaver } from '../../pipeline/database-operations.js';
5
+ import { AccountFetcherStep } from './steps/account-fetcher-step.js';
6
+ import { CostExplorerStep } from './steps/cost-explorer-step.js';
7
+ import { createCostDataSchema } from './cost-schema.js';
8
+ export class AwsCostStreamingOrchestrator {
9
+ context;
10
+ constructor(options) {
11
+ this.context = {
12
+ auth: options.postgresAuth,
13
+ awsCredentials: options.awsCredentials,
14
+ dateRange: options.dateRange ?? monthsAgo(1),
15
+ tablesPrefix: options.tablesPrefix ?? 'aws_cost_',
16
+ roleName: options.roleName ?? 'IngenoCrossAccountReadOnlyAccessRole',
17
+ };
18
+ }
19
+ async execute() {
20
+ try {
21
+ console.log('Starting AWS cost streaming orchestration...');
22
+ console.log(`Date range: ${this.context.dateRange.startDate} to ${this.context.dateRange.endDate}`);
23
+ console.log(`Table prefix: ${this.context.tablesPrefix}`);
24
+ // Build the streaming pipeline using dependency injection
25
+ const pipeline = createPipeline()
26
+ .pipe(new AccountFetcherStep(this.context.auth))
27
+ .pipe(new CostExplorerStep(this.context.awsCredentials, this.context.dateRange, this.context.roleName))
28
+ .pipe(new DatabaseSaver({
29
+ auth: this.context.auth,
30
+ tablesPrefix: this.context.tablesPrefix,
31
+ schema: createCostDataSchema(this.context.dateRange)
32
+ }));
33
+ // Execute the pipeline (automatically creates void observable for void input)
34
+ const result$ = pipeline.execute();
35
+ const saveResult = await firstValueFrom(result$);
36
+ console.log('AWS cost streaming orchestration completed successfully!');
37
+ return {
38
+ success: saveResult.success,
39
+ tableName: saveResult.tableName,
40
+ recordCount: saveResult.recordCount,
41
+ };
42
+ }
43
+ catch (error) {
44
+ console.error('AWS cost streaming orchestration failed:', error);
45
+ throw error;
46
+ }
47
+ }
48
+ getContext() {
49
+ return { ...this.context };
50
+ }
51
+ }
52
+ //# sourceMappingURL=orchestrator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"orchestrator.js","sourceRoot":"","sources":["../../../src/aws/cost/orchestrator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAmB,MAAM,MAAM,CAAA;AACtD,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAA;AAEpD,OAAO,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAA;AACnE,OAAO,EAAE,aAAa,EAAE,MAAM,uCAAuC,CAAA;AACrE,OAAO,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAA;AACpE,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAA;AAChE,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAA;AA8BvD,MAAM,OAAO,4BAA4B;IACtB,OAAO,CAAwB;IAEhD,YAAY,OAAqC;QAC/C,IAAI,CAAC,OAAO,GAAG;YACb,IAAI,EAAE,OAAO,CAAC,YAAY;YAC1B,cAAc,EAAE,OAAO,CAAC,cAAc;YACtC,SAAS,EAAE,OAAO,CAAC,SAAS,IAAI,SAAS,CAAC,CAAC,CAAC;YAC5C,YAAY,EAAE,OAAO,CAAC,YAAY,IAAI,WAAW;YACjD,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,sCAAsC;SACrE,CAAA;IACH,CAAC;IAED,KAAK,CAAC,OAAO;QACX,IAAI,CAAC;YACH,OAAO,CAAC,GAAG,CAAC,8CAA8C,CAAC,CAAA;YAC3D,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,SAAS,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC,CAAA;YACnG,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,CAAC,CAAA;YAEzD,0DAA0D;YAC1D,MAAM,QAAQ,GAAG,cAAc,EAAQ;iBACpC,IAAI,CAAC,IAAI,kBAAkB,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;iBAC/C,IAAI,CAAC,IAAI,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;iBACtG,IAAI,CAAC,IAAI,aAAa,CAAW;gBAChC,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI;gBACvB,YAAY,EAAE,IAAI,CAAC,OAAO,CAAC,YAAY;gBACvC,MAAM,EAAE,oBAAoB,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC;aACrD,CAAC,CAAC,CAAA;YAEL,8EAA8E;YAC9E,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,EAAoC,CAAA;YACpE,MAAM,UAAU,GAAG,MAAM,cAAc,CAAC,OAAO,CAAC,CAAA;YAEhD,OAAO,CAAC,GAAG,CAAC,0DAA0D,CAAC,CAAA;YAEvE,OAAO;gBACL,OAAO,EAAE,UAAU,CAAC,OAAO;gBAC3B,SAAS,EAAE,UAAU,CAAC,SAAS;gBAC/B,WAAW,EAAE,UAAU,CAAC,WAAW;aACpC,CAAA;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,0CAA0C,EAAE,KAAK,CAAC,CAAA;YAChE,MAAM,KAAK,CAAA;QACb,CAAC;IACH,CAAC;IAED,UAAU;QACR,OAAO,EAAE,GAAG,IAAI,CAAC,OAAO,EAAE,CAAA;IAC5B,CAAC;CACF"}
@@ -0,0 +1,16 @@
1
+ import type { PipelineStep } from '../../../pipeline/pipeline-builder.js';
2
+ import type { Observable } from 'rxjs';
3
+ import type { PostgresAuth } from '../../../postgres/postgres.js';
4
+ export interface AwsAccount {
5
+ readonly account_id: string;
6
+ readonly account_name?: string;
7
+ readonly active: boolean;
8
+ }
9
+ export declare class AccountFetcherStep implements PipelineStep<void, AwsAccount> {
10
+ private readonly auth;
11
+ readonly name = "AccountFetcher";
12
+ constructor(auth: PostgresAuth);
13
+ transform(input$: Observable<void>): Observable<AwsAccount>;
14
+ private fetchActiveAccounts;
15
+ }
16
+ //# sourceMappingURL=account-fetcher-step.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"account-fetcher-step.d.ts","sourceRoot":"","sources":["../../../../src/aws/cost/steps/account-fetcher-step.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uCAAuC,CAAA;AAEzE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,MAAM,CAAA;AACtC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAA;AAEjE,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAA;IAC9B,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAA;CACzB;AAED,qBAAa,kBAAmB,YAAW,YAAY,CAAC,IAAI,EAAE,UAAU,CAAC;IAG3D,OAAO,CAAC,QAAQ,CAAC,IAAI;IAFjC,QAAQ,CAAC,IAAI,oBAAmB;gBAEH,IAAI,EAAE,YAAY;IAE/C,SAAS,CAAC,MAAM,EAAE,UAAU,CAAC,IAAI,CAAC,GAAG,UAAU,CAAC,UAAU,CAAC;YAa7C,mBAAmB;CAQlC"}
@@ -0,0 +1,23 @@
1
+ import { from, switchMap, mergeMap } from 'rxjs';
2
+ import { executeSQLQuery } from '../../../postgres/query-executor.js';
3
+ export class AccountFetcherStep {
4
+ auth;
5
+ name = 'AccountFetcher';
6
+ constructor(auth) {
7
+ this.auth = auth;
8
+ }
9
+ transform(input$) {
10
+ return input$.pipe(switchMap(() => {
11
+ console.log('Fetching active AWS accounts from database...');
12
+ return from(this.fetchActiveAccounts());
13
+ }), mergeMap((accounts) => {
14
+ console.log(`Found ${accounts.length} active AWS accounts`);
15
+ return from(accounts);
16
+ }));
17
+ }
18
+ async fetchActiveAccounts() {
19
+ const result = await executeSQLQuery(this.auth, 'SELECT account_id, account_name, active FROM aws_ingeno_accounts WHERE active = true');
20
+ return result.rows;
21
+ }
22
+ }
23
+ //# sourceMappingURL=account-fetcher-step.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"account-fetcher-step.js","sourceRoot":"","sources":["../../../../src/aws/cost/steps/account-fetcher-step.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,MAAM,CAAA;AAChD,OAAO,EAAE,eAAe,EAAE,MAAM,qCAAqC,CAAA;AAYrE,MAAM,OAAO,kBAAkB;IAGA;IAFpB,IAAI,GAAG,gBAAgB,CAAA;IAEhC,YAA6B,IAAkB;QAAlB,SAAI,GAAJ,IAAI,CAAc;IAAG,CAAC;IAEnD,SAAS,CAAC,MAAwB;QAChC,OAAO,MAAM,CAAC,IAAI,CAChB,SAAS,CAAC,GAAG,EAAE;YACb,OAAO,CAAC,GAAG,CAAC,+CAA+C,CAAC,CAAA;YAC5D,OAAO,IAAI,CAAC,IAAI,CAAC,mBAAmB,EAAE,CAAC,CAAA;QACzC,CAAC,CAAC,EACF,QAAQ,CAAC,CAAC,QAA+B,EAAE,EAAE;YAC3C,OAAO,CAAC,GAAG,CAAC,SAAS,QAAQ,CAAC,MAAM,sBAAsB,CAAC,CAAA;YAC3D,OAAO,IAAI,CAAC,QAAQ,CAAC,CAAA;QACvB,CAAC,CAAC,CACH,CAAA;IACH,CAAC;IAEO,KAAK,CAAC,mBAAmB;QAC/B,MAAM,MAAM,GAAG,MAAM,eAAe,CAClC,IAAI,CAAC,IAAI,EACT,sFAAsF,CACvF,CAAA;QAED,OAAO,MAAM,CAAC,IAAI,CAAA;IACpB,CAAC;CACF"}
@@ -0,0 +1,27 @@
1
+ import type { PipelineStep } from '../../../pipeline/pipeline-builder.js';
2
+ import type { Observable } from 'rxjs';
3
+ import type { AwsAccount } from './account-fetcher-step.js';
4
+ import type { AwsCredentialIdentity } from '@aws-sdk/types';
5
+ import type { DateRange } from '../../../date/date-range.js';
6
+ export interface CostData {
7
+ readonly date: string;
8
+ readonly account_id: string;
9
+ readonly service: string;
10
+ readonly [metricName: string]: string;
11
+ }
12
+ export declare class CostExplorerStep implements PipelineStep<AwsAccount, CostData> {
13
+ private readonly awsCredentials;
14
+ private readonly dateRange;
15
+ private readonly roleName;
16
+ readonly name = "CostExplorer";
17
+ private readonly metrics;
18
+ private mainAccountId;
19
+ constructor(awsCredentials: AwsCredentialIdentity, dateRange: DateRange, roleName: string);
20
+ transform(accounts$: Observable<AwsAccount>): Observable<CostData>;
21
+ private createCostDataStream;
22
+ private getMainAccountId;
23
+ private getCredentialsForAccount;
24
+ private fetchCostAndUsagePage;
25
+ private transformResultToCostData;
26
+ }
27
+ //# sourceMappingURL=cost-explorer-step.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cost-explorer-step.d.ts","sourceRoot":"","sources":["../../../../src/aws/cost/steps/cost-explorer-step.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uCAAuC,CAAA;AAEzE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,MAAM,CAAA;AACtC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAA;AAC3D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAA;AAC3D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAA;AAG5D,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAAA;CACtC;AAaD,qBAAa,gBAAiB,YAAW,YAAY,CAAC,UAAU,EAAE,QAAQ,CAAC;IAMvE,OAAO,CAAC,QAAQ,CAAC,cAAc;IAC/B,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAP3B,QAAQ,CAAC,IAAI,kBAAiB;IAC9B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAa;IACrC,OAAO,CAAC,aAAa,CAAsB;gBAGxB,cAAc,EAAE,qBAAqB,EACrC,SAAS,EAAE,SAAS,EACpB,QAAQ,EAAE,MAAM;IAKnC,SAAS,CAAC,SAAS,EAAE,UAAU,CAAC,UAAU,CAAC,GAAG,UAAU,CAAC,QAAQ,CAAC;IASlE,OAAO,CAAC,oBAAoB;YAYd,gBAAgB;YAQhB,wBAAwB;YA4BxB,qBAAqB;IA+BnC,OAAO,CAAC,yBAAyB;CAgBlC"}
@@ -0,0 +1,100 @@
1
+ import { mergeMap, from } from 'rxjs';
2
+ import { CostExplorerClient, GetCostAndUsageCommand } from '@aws-sdk/client-cost-explorer';
3
+ import { createPaginatedStream } from '../../../streams/list-stream.js';
4
+ import { CostMetrics } from '../../cost/metrics.js';
5
+ import { assumeRoleCredentialsProvider, getCurrentAccountId } from '../../execute-as.js';
6
+ export class CostExplorerStep {
7
+ awsCredentials;
8
+ dateRange;
9
+ roleName;
10
+ name = 'CostExplorer';
11
+ metrics;
12
+ mainAccountId = null;
13
+ constructor(awsCredentials, dateRange, roleName) {
14
+ this.awsCredentials = awsCredentials;
15
+ this.dateRange = dateRange;
16
+ this.roleName = roleName;
17
+ this.metrics = new CostMetrics();
18
+ }
19
+ transform(accounts$) {
20
+ return accounts$.pipe(mergeMap((account) => {
21
+ console.log(`Fetching cost data for account: ${account.account_id}`);
22
+ return this.createCostDataStream(account);
23
+ }, 3) // Limit concurrent account processing
24
+ );
25
+ }
26
+ createCostDataStream(account) {
27
+ return from(this.getCredentialsForAccount(account)).pipe(mergeMap((credentials) => createPaginatedStream((options) => this.fetchCostAndUsagePage(credentials, options), { pageSize: 100 })), mergeMap((result) => from(this.transformResultToCostData(result))));
28
+ }
29
+ async getMainAccountId() {
30
+ if (!this.mainAccountId) {
31
+ this.mainAccountId = await getCurrentAccountId(this.awsCredentials);
32
+ console.log(`Determined main account ID: ${this.mainAccountId}`);
33
+ }
34
+ return this.mainAccountId;
35
+ }
36
+ async getCredentialsForAccount(account) {
37
+ const mainAccountId = await this.getMainAccountId();
38
+ // For main account, use main credentials
39
+ if (account.account_id === mainAccountId) {
40
+ console.log(`Using main credentials for account: ${account.account_id}`);
41
+ return this.awsCredentials;
42
+ }
43
+ // For other accounts, assume role
44
+ console.log(`Assuming role ${this.roleName} for account: ${account.account_id}`);
45
+ try {
46
+ const credentialsProvider = assumeRoleCredentialsProvider({
47
+ accountId: account.account_id,
48
+ roleName: this.roleName,
49
+ mainCredentials: this.awsCredentials,
50
+ region: 'us-east-1'
51
+ });
52
+ const credentials = await credentialsProvider();
53
+ console.log(`Successfully assumed role for account: ${account.account_id}`);
54
+ return credentials;
55
+ }
56
+ catch (error) {
57
+ console.error(`Failed to assume role ${this.roleName} for account ${account.account_id}:`, error);
58
+ throw error;
59
+ }
60
+ }
61
+ async fetchCostAndUsagePage(credentials, options) {
62
+ const client = new CostExplorerClient({
63
+ credentials,
64
+ region: 'us-east-1',
65
+ });
66
+ const command = new GetCostAndUsageCommand({
67
+ TimePeriod: {
68
+ Start: this.dateRange.startDate,
69
+ End: this.dateRange.endDate,
70
+ },
71
+ Granularity: 'DAILY',
72
+ Metrics: [...this.metrics.getUpperCaseNames()],
73
+ GroupBy: [
74
+ { Type: 'DIMENSION', Key: 'LINKED_ACCOUNT' },
75
+ { Type: 'DIMENSION', Key: 'SERVICE' },
76
+ ],
77
+ NextPageToken: options.nextPageToken,
78
+ });
79
+ const response = await client.send(command);
80
+ return {
81
+ items: response.ResultsByTime ?? [],
82
+ nextPageToken: response.NextPageToken,
83
+ };
84
+ }
85
+ transformResultToCostData(result) {
86
+ const date = result.TimePeriod?.Start ?? '';
87
+ return (result.Groups ?? []).map(group => {
88
+ const account_id = group.Keys?.[0] ?? '';
89
+ const service = group.Keys?.[1] ?? '';
90
+ const metricData = this.metrics.createMetricRecord(group.Metrics ?? {});
91
+ return {
92
+ date,
93
+ account_id,
94
+ service,
95
+ ...metricData,
96
+ };
97
+ });
98
+ }
99
+ }
100
+ //# sourceMappingURL=cost-explorer-step.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cost-explorer-step.js","sourceRoot":"","sources":["../../../../src/aws/cost/steps/cost-explorer-step.ts"],"names":[],"mappings":"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"}
@@ -39,4 +39,18 @@ export declare const allExecutionContexts: (options: AllExecutionContextsOptions
39
39
  */
40
40
  export declare function executeAs<T>(options: ExecutionContext, fn: (accountId: string, credentials: AwsCredentialIdentity) => Promise<T>): Promise<T>;
41
41
  export declare const executeAllAs: <T>(options: ExecutionContext[], fn: (accountId: string, credentials: AwsCredentialIdentity) => Promise<T>) => Promise<T[]>;
42
+ /**
43
+ * Get the AWS account ID for the provided credentials using STS GetCallerIdentity
44
+ *
45
+ * @param credentials - AWS credentials to determine the account ID for
46
+ * @param region - AWS region to use for the STS call (defaults to 'us-east-1')
47
+ * @returns Promise that resolves to the account ID string
48
+ *
49
+ * @example
50
+ * ```typescript
51
+ * const accountId = await getCurrentAccountId(awsCredentials);
52
+ * console.log(`Current account: ${accountId}`);
53
+ * ```
54
+ */
55
+ export declare function getCurrentAccountId(credentials: AwsCredentialIdentity, region?: string): Promise<string>;
42
56
  //# sourceMappingURL=execute-as.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"execute-as.d.ts","sourceRoot":"","sources":["../../src/aws/execute-as.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,qBAAqB,EAAE,6BAA6B,EAAE,MAAM,gBAAgB,CAAA;AAE1F,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,MAAM,GAAG,CAAC,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC,CAAA;IAC3C,WAAW,EAAE,qBAAqB,GAAG,CAAC,MAAM,OAAO,CAAC,qBAAqB,CAAC,CAAC,CAAA;CAC5E;AAED,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,EAAE,MAAM,CAAA;IAChB,eAAe,EAAE,qBAAqB,CAAA;IACtC,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,eAAO,MAAM,6BAA6B,GAAI,SAAS,iBAAiB,KAAG,6BAc1E,CAAA;AAED,eAAO,MAAM,0BAA0B,GAAI,SAAS,iBAAiB,KAAG,gBAUvE,CAAA;AAED,MAAM,WAAW,2BAA2B;IAC1C,aAAa,EAAE,MAAM,CAAA;IACrB,eAAe,EAAE,qBAAqB,CAAA;IACtC,kCAAkC,CAAC,EAAE,OAAO,CAAA;IAC5C,UAAU,EAAE,MAAM,EAAE,CAAA;IACpB,gBAAgB,EAAE,MAAM,CAAA;CACzB;AAED,eAAO,MAAM,oBAAoB,GAAI,SAAS,2BAA2B,KAAG,gBAAgB,EAiC3F,CAAA;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,SAAS,CAAC,CAAC,EAC/B,OAAO,EAAE,gBAAgB,EACzB,EAAE,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,qBAAqB,KAAK,OAAO,CAAC,CAAC,CAAC,GACxE,OAAO,CAAC,CAAC,CAAC,CAWZ;AAED,eAAO,MAAM,YAAY,GAAU,CAAC,EAClC,SAAS,gBAAgB,EAAE,EAC3B,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,qBAAqB,KAAK,OAAO,CAAC,CAAC,CAAC,KACxE,OAAO,CAAC,CAAC,EAAE,CAA4E,CAAA"}
1
+ {"version":3,"file":"execute-as.d.ts","sourceRoot":"","sources":["../../src/aws/execute-as.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,qBAAqB,EAAE,6BAA6B,EAAE,MAAM,gBAAgB,CAAA;AAE1F,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,MAAM,GAAG,CAAC,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC,CAAA;IAC3C,WAAW,EAAE,qBAAqB,GAAG,CAAC,MAAM,OAAO,CAAC,qBAAqB,CAAC,CAAC,CAAA;CAC5E;AAED,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,EAAE,MAAM,CAAA;IAChB,eAAe,EAAE,qBAAqB,CAAA;IACtC,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,eAAO,MAAM,6BAA6B,GAAI,SAAS,iBAAiB,KAAG,6BAc1E,CAAA;AAED,eAAO,MAAM,0BAA0B,GAAI,SAAS,iBAAiB,KAAG,gBAUvE,CAAA;AAED,MAAM,WAAW,2BAA2B;IAC1C,aAAa,EAAE,MAAM,CAAA;IACrB,eAAe,EAAE,qBAAqB,CAAA;IACtC,kCAAkC,CAAC,EAAE,OAAO,CAAA;IAC5C,UAAU,EAAE,MAAM,EAAE,CAAA;IACpB,gBAAgB,EAAE,MAAM,CAAA;CACzB;AAED,eAAO,MAAM,oBAAoB,GAAI,SAAS,2BAA2B,KAAG,gBAAgB,EAiC3F,CAAA;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,SAAS,CAAC,CAAC,EAC/B,OAAO,EAAE,gBAAgB,EACzB,EAAE,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,qBAAqB,KAAK,OAAO,CAAC,CAAC,CAAC,GACxE,OAAO,CAAC,CAAC,CAAC,CAWZ;AAED,eAAO,MAAM,YAAY,GAAU,CAAC,EAClC,SAAS,gBAAgB,EAAE,EAC3B,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,qBAAqB,KAAK,OAAO,CAAC,CAAC,CAAC,KACxE,OAAO,CAAC,CAAC,EAAE,CAA4E,CAAA;AAE1F;;;;;;;;;;;;GAYG;AACH,wBAAsB,mBAAmB,CACvC,WAAW,EAAE,qBAAqB,EAClC,MAAM,SAAc,GACnB,OAAO,CAAC,MAAM,CAAC,CASjB"}