@pagopa/dx-savemoney 0.3.3 → 0.5.0

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 (174) hide show
  1. package/README.md +12 -0
  2. package/dist/__tests__/finding.test.js +22 -0
  3. package/dist/__tests__/finding.test.js.map +1 -1
  4. package/dist/azure/__tests__/analyzer-tags.test.js +28 -1
  5. package/dist/azure/__tests__/analyzer-tags.test.js.map +1 -1
  6. package/dist/azure/__tests__/config.test.js +31 -1
  7. package/dist/azure/__tests__/config.test.js.map +1 -1
  8. package/dist/azure/__tests__/report.test.js +71 -0
  9. package/dist/azure/__tests__/report.test.js.map +1 -1
  10. package/dist/azure/analyzer.d.ts +8 -1
  11. package/dist/azure/analyzer.d.ts.map +1 -1
  12. package/dist/azure/analyzer.js +57 -41
  13. package/dist/azure/analyzer.js.map +1 -1
  14. package/dist/azure/analyzers/registry.d.ts.map +1 -1
  15. package/dist/azure/analyzers/registry.js +4 -4
  16. package/dist/azure/analyzers/registry.js.map +1 -1
  17. package/dist/azure/analyzers/types.d.ts +6 -0
  18. package/dist/azure/analyzers/types.d.ts.map +1 -1
  19. package/dist/azure/config.d.ts.map +1 -1
  20. package/dist/azure/config.js +1 -5
  21. package/dist/azure/config.js.map +1 -1
  22. package/dist/azure/pricing/__tests__/cache.test.d.ts +8 -0
  23. package/dist/azure/pricing/__tests__/cache.test.d.ts.map +1 -0
  24. package/dist/azure/pricing/__tests__/cache.test.js +56 -0
  25. package/dist/azure/pricing/__tests__/cache.test.js.map +1 -0
  26. package/dist/azure/pricing/__tests__/client.test.d.ts +9 -0
  27. package/dist/azure/pricing/__tests__/client.test.d.ts.map +1 -0
  28. package/dist/azure/pricing/__tests__/client.test.js +181 -0
  29. package/dist/azure/pricing/__tests__/client.test.js.map +1 -0
  30. package/dist/azure/pricing/__tests__/pricing-service.test.d.ts +6 -0
  31. package/dist/azure/pricing/__tests__/pricing-service.test.d.ts.map +1 -0
  32. package/dist/azure/pricing/__tests__/pricing-service.test.js +283 -0
  33. package/dist/azure/pricing/__tests__/pricing-service.test.js.map +1 -0
  34. package/dist/azure/pricing/cache.d.ts +45 -0
  35. package/dist/azure/pricing/cache.d.ts.map +1 -0
  36. package/dist/azure/pricing/cache.js +79 -0
  37. package/dist/azure/pricing/cache.js.map +1 -0
  38. package/dist/azure/pricing/client.d.ts +67 -0
  39. package/dist/azure/pricing/client.d.ts.map +1 -0
  40. package/dist/azure/pricing/client.js +96 -0
  41. package/dist/azure/pricing/client.js.map +1 -0
  42. package/dist/azure/pricing/index.d.ts +6 -0
  43. package/dist/azure/pricing/index.d.ts.map +1 -0
  44. package/dist/azure/pricing/index.js +6 -0
  45. package/dist/azure/pricing/index.js.map +1 -0
  46. package/dist/azure/pricing/pricing-service.d.ts +46 -0
  47. package/dist/azure/pricing/pricing-service.d.ts.map +1 -0
  48. package/dist/azure/pricing/pricing-service.js +84 -0
  49. package/dist/azure/pricing/pricing-service.js.map +1 -0
  50. package/dist/azure/pricing/resolvers/__tests__/app-service.test.d.ts +5 -0
  51. package/dist/azure/pricing/resolvers/__tests__/app-service.test.d.ts.map +1 -0
  52. package/dist/azure/pricing/resolvers/__tests__/app-service.test.js +137 -0
  53. package/dist/azure/pricing/resolvers/__tests__/app-service.test.js.map +1 -0
  54. package/dist/azure/pricing/resolvers/__tests__/disk.test.d.ts +5 -0
  55. package/dist/azure/pricing/resolvers/__tests__/disk.test.d.ts.map +1 -0
  56. package/dist/azure/pricing/resolvers/__tests__/disk.test.js +160 -0
  57. package/dist/azure/pricing/resolvers/__tests__/disk.test.js.map +1 -0
  58. package/dist/azure/pricing/resolvers/__tests__/public-ip.test.d.ts +5 -0
  59. package/dist/azure/pricing/resolvers/__tests__/public-ip.test.d.ts.map +1 -0
  60. package/dist/azure/pricing/resolvers/__tests__/public-ip.test.js +113 -0
  61. package/dist/azure/pricing/resolvers/__tests__/public-ip.test.js.map +1 -0
  62. package/dist/azure/pricing/resolvers/__tests__/vm.test.d.ts +9 -0
  63. package/dist/azure/pricing/resolvers/__tests__/vm.test.d.ts.map +1 -0
  64. package/dist/azure/pricing/resolvers/__tests__/vm.test.js +204 -0
  65. package/dist/azure/pricing/resolvers/__tests__/vm.test.js.map +1 -0
  66. package/dist/azure/pricing/resolvers/app-service.d.ts +27 -0
  67. package/dist/azure/pricing/resolvers/app-service.d.ts.map +1 -0
  68. package/dist/azure/pricing/resolvers/app-service.js +67 -0
  69. package/dist/azure/pricing/resolvers/app-service.js.map +1 -0
  70. package/dist/azure/pricing/resolvers/disk.d.ts +59 -0
  71. package/dist/azure/pricing/resolvers/disk.d.ts.map +1 -0
  72. package/dist/azure/pricing/resolvers/disk.js +140 -0
  73. package/dist/azure/pricing/resolvers/disk.js.map +1 -0
  74. package/dist/azure/pricing/resolvers/index.d.ts +12 -0
  75. package/dist/azure/pricing/resolvers/index.d.ts.map +1 -0
  76. package/dist/azure/pricing/resolvers/index.js +8 -0
  77. package/dist/azure/pricing/resolvers/index.js.map +1 -0
  78. package/dist/azure/pricing/resolvers/public-ip.d.ts +32 -0
  79. package/dist/azure/pricing/resolvers/public-ip.d.ts.map +1 -0
  80. package/dist/azure/pricing/resolvers/public-ip.js +56 -0
  81. package/dist/azure/pricing/resolvers/public-ip.js.map +1 -0
  82. package/dist/azure/pricing/resolvers/vm.d.ts +51 -0
  83. package/dist/azure/pricing/resolvers/vm.d.ts.map +1 -0
  84. package/dist/azure/pricing/resolvers/vm.js +89 -0
  85. package/dist/azure/pricing/resolvers/vm.js.map +1 -0
  86. package/dist/azure/pricing/schema.d.ts +88 -0
  87. package/dist/azure/pricing/schema.d.ts.map +1 -0
  88. package/dist/azure/pricing/schema.js +64 -0
  89. package/dist/azure/pricing/schema.js.map +1 -0
  90. package/dist/azure/pricing/test-cache-dir.d.ts +3 -0
  91. package/dist/azure/pricing/test-cache-dir.d.ts.map +1 -0
  92. package/dist/azure/pricing/test-cache-dir.js +17 -0
  93. package/dist/azure/pricing/test-cache-dir.js.map +1 -0
  94. package/dist/azure/report.d.ts.map +1 -1
  95. package/dist/azure/report.js +57 -18
  96. package/dist/azure/report.js.map +1 -1
  97. package/dist/azure/resources/__tests__/app-service.test.d.ts +5 -0
  98. package/dist/azure/resources/__tests__/app-service.test.d.ts.map +1 -0
  99. package/dist/azure/resources/__tests__/app-service.test.js +105 -0
  100. package/dist/azure/resources/__tests__/app-service.test.js.map +1 -0
  101. package/dist/azure/resources/app-service.d.ts +8 -3
  102. package/dist/azure/resources/app-service.d.ts.map +1 -1
  103. package/dist/azure/resources/app-service.js +35 -2
  104. package/dist/azure/resources/app-service.js.map +1 -1
  105. package/dist/azure/resources/disk.d.ts +3 -1
  106. package/dist/azure/resources/disk.d.ts.map +1 -1
  107. package/dist/azure/resources/disk.js +35 -3
  108. package/dist/azure/resources/disk.js.map +1 -1
  109. package/dist/azure/resources/public-ip.d.ts +3 -1
  110. package/dist/azure/resources/public-ip.d.ts.map +1 -1
  111. package/dist/azure/resources/public-ip.js +41 -3
  112. package/dist/azure/resources/public-ip.js.map +1 -1
  113. package/dist/azure/resources/vm.d.ts +4 -1
  114. package/dist/azure/resources/vm.d.ts.map +1 -1
  115. package/dist/azure/resources/vm.js +49 -6
  116. package/dist/azure/resources/vm.js.map +1 -1
  117. package/dist/azure/types.d.ts +18 -3
  118. package/dist/azure/types.d.ts.map +1 -1
  119. package/dist/finding.d.ts +3 -3
  120. package/dist/finding.d.ts.map +1 -1
  121. package/dist/finding.js +7 -0
  122. package/dist/finding.js.map +1 -1
  123. package/dist/index.d.ts +3 -2
  124. package/dist/index.d.ts.map +1 -1
  125. package/dist/index.js +1 -0
  126. package/dist/index.js.map +1 -1
  127. package/dist/schema.d.ts +5 -1
  128. package/dist/schema.d.ts.map +1 -1
  129. package/dist/schema.js +5 -3
  130. package/dist/schema.js.map +1 -1
  131. package/dist/types.d.ts +8 -0
  132. package/dist/types.d.ts.map +1 -1
  133. package/dist/types.js +2 -0
  134. package/dist/types.js.map +1 -1
  135. package/package.json +1 -1
  136. package/src/__tests__/finding.test.ts +24 -0
  137. package/src/azure/__tests__/analyzer-tags.test.ts +36 -1
  138. package/src/azure/__tests__/config.test.ts +43 -1
  139. package/src/azure/__tests__/fixtures/full-override.yaml +2 -0
  140. package/src/azure/__tests__/report.test.ts +78 -0
  141. package/src/azure/analyzer.ts +70 -52
  142. package/src/azure/analyzers/registry.ts +8 -2
  143. package/src/azure/analyzers/types.ts +6 -0
  144. package/src/azure/config.ts +1 -5
  145. package/src/azure/pricing/__tests__/cache.test.ts +67 -0
  146. package/src/azure/pricing/__tests__/client.test.ts +212 -0
  147. package/src/azure/pricing/__tests__/fixtures/vm-b2s-westeurope.json +51 -0
  148. package/src/azure/pricing/__tests__/pricing-service.test.ts +315 -0
  149. package/src/azure/pricing/cache.ts +92 -0
  150. package/src/azure/pricing/client.ts +137 -0
  151. package/src/azure/pricing/index.ts +6 -0
  152. package/src/azure/pricing/pricing-service.ts +125 -0
  153. package/src/azure/pricing/resolvers/__tests__/app-service.test.ts +154 -0
  154. package/src/azure/pricing/resolvers/__tests__/disk.test.ts +189 -0
  155. package/src/azure/pricing/resolvers/__tests__/public-ip.test.ts +130 -0
  156. package/src/azure/pricing/resolvers/__tests__/vm.test.ts +232 -0
  157. package/src/azure/pricing/resolvers/app-service.ts +102 -0
  158. package/src/azure/pricing/resolvers/disk.ts +170 -0
  159. package/src/azure/pricing/resolvers/index.ts +31 -0
  160. package/src/azure/pricing/resolvers/public-ip.ts +87 -0
  161. package/src/azure/pricing/resolvers/vm.ts +125 -0
  162. package/src/azure/pricing/schema.ts +69 -0
  163. package/src/azure/pricing/test-cache-dir.ts +26 -0
  164. package/src/azure/report.ts +86 -21
  165. package/src/azure/resources/__tests__/app-service.test.ts +165 -0
  166. package/src/azure/resources/app-service.ts +65 -4
  167. package/src/azure/resources/disk.ts +46 -4
  168. package/src/azure/resources/public-ip.ts +61 -2
  169. package/src/azure/resources/vm.ts +89 -11
  170. package/src/azure/types.ts +19 -3
  171. package/src/finding.ts +10 -3
  172. package/src/index.ts +4 -3
  173. package/src/schema.ts +7 -3
  174. package/src/types.ts +12 -0
@@ -26,12 +26,12 @@ export function createDefaultAnalyzers() {
26
26
  supports: (r) => r.type?.toLowerCase() === "microsoft.app/containerapps",
27
27
  },
28
28
  {
29
- analyze: ({ clients, resource, verbose }) => analyzeDisk(resource, clients.compute, verbose),
29
+ analyze: ({ clients, pricing, resource, verbose }) => analyzeDisk(resource, clients.compute, verbose, pricing),
30
30
  id: "azure.disk",
31
31
  supports: (r) => r.type?.toLowerCase() === "microsoft.compute/disks",
32
32
  },
33
33
  {
34
- analyze: ({ clients, metricsCache, resource, thresholds, timespanDays, verbose, }) => analyzeVM(resource, clients.monitor, clients.compute, timespanDays, thresholds, verbose, metricsCache),
34
+ analyze: ({ clients, metricsCache, pricing, resource, thresholds, timespanDays, verbose, }) => analyzeVM(resource, clients.monitor, clients.compute, timespanDays, thresholds, verbose, metricsCache, pricing),
35
35
  id: "azure.vm",
36
36
  supports: (r) => r.type?.toLowerCase() === "microsoft.compute/virtualmachines",
37
37
  },
@@ -46,7 +46,7 @@ export function createDefaultAnalyzers() {
46
46
  supports: (r) => r.type?.toLowerCase() === "microsoft.network/privateendpoints",
47
47
  },
48
48
  {
49
- analyze: ({ clients, metricsCache, resource, thresholds, timespanDays, verbose, }) => analyzePublicIp(resource, clients.network, clients.monitor, timespanDays, thresholds, verbose, metricsCache),
49
+ analyze: ({ clients, metricsCache, pricing, resource, thresholds, timespanDays, verbose, }) => analyzePublicIp(resource, clients.network, clients.monitor, timespanDays, thresholds, verbose, metricsCache, pricing),
50
50
  id: "azure.public-ip",
51
51
  supports: (r) => r.type?.toLowerCase() === "microsoft.network/publicipaddresses",
52
52
  },
@@ -56,7 +56,7 @@ export function createDefaultAnalyzers() {
56
56
  supports: (r) => r.type?.toLowerCase() === "microsoft.storage/storageaccounts",
57
57
  },
58
58
  {
59
- analyze: ({ clients, metricsCache, resource, thresholds, timespanDays, verbose, }) => analyzeAppServicePlan(resource, clients.webSite, clients.monitor, timespanDays, thresholds, verbose, metricsCache),
59
+ analyze: ({ clients, metricsCache, pricing, resource, thresholds, timespanDays, verbose, }) => analyzeAppServicePlan(resource, clients.webSite, clients.monitor, timespanDays, thresholds, verbose, metricsCache, pricing),
60
60
  id: "azure.app-service-plan",
61
61
  supports: (r) => r.type?.toLowerCase() === "microsoft.web/serverfarms",
62
62
  },
@@ -1 +1 @@
1
- {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../../src/azure/analyzers/registry.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../../src/azure/analyzers/registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAKH,OAAO,EACL,qBAAqB,EACrB,mBAAmB,EACnB,WAAW,EACX,UAAU,EACV,sBAAsB,EACtB,eAAe,EACf,iBAAiB,EACjB,qBAAqB,EACrB,SAAS,GACV,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAErD;;;;;;GAMG;AACH,MAAM,UAAU,sBAAsB;IACpC,OAAO;QACL;YACE,OAAO,EAAE,CAAC,EACR,OAAO,EACP,YAAY,EACZ,QAAQ,EACR,UAAU,EACV,YAAY,EACZ,OAAO,GACR,EAAE,EAAE,CACH,mBAAmB,CACjB,QAAQ,EACR,OAAO,CAAC,aAAa,EACrB,OAAO,CAAC,OAAO,EACf,YAAY,EACZ,UAAU,EACV,OAAO,EACP,YAAY,CACb;YACH,EAAE,EAAE,qBAAqB;YACzB,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,WAAW,EAAE,KAAK,6BAA6B;SACzE;QACD;YACE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE,EAAE,CACnD,WAAW,CAAC,QAAQ,EAAE,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC;YAC1D,EAAE,EAAE,YAAY;YAChB,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,WAAW,EAAE,KAAK,yBAAyB;SACrE;QACD;YACE,OAAO,EAAE,CAAC,EACR,OAAO,EACP,YAAY,EACZ,OAAO,EACP,QAAQ,EACR,UAAU,EACV,YAAY,EACZ,OAAO,GACR,EAAE,EAAE,CACH,SAAS,CACP,QAAQ,EACR,OAAO,CAAC,OAAO,EACf,OAAO,CAAC,OAAO,EACf,YAAY,EACZ,UAAU,EACV,OAAO,EACP,YAAY,EACZ,OAAO,CACR;YACH,EAAE,EAAE,UAAU;YACd,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CACd,CAAC,CAAC,IAAI,EAAE,WAAW,EAAE,KAAK,mCAAmC;SAChE;QACD;YACE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE,EAAE,CAC1C,UAAU,CAAC,QAAQ,EAAE,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC;YAChD,EAAE,EAAE,WAAW;YACf,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CACd,CAAC,CAAC,IAAI,EAAE,WAAW,EAAE,KAAK,qCAAqC;SAClE;QACD;YACE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE,EAAE,CAC1C,sBAAsB,CAAC,QAAQ,EAAE,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC;YAC5D,EAAE,EAAE,wBAAwB;YAC5B,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CACd,CAAC,CAAC,IAAI,EAAE,WAAW,EAAE,KAAK,oCAAoC;SACjE;QACD;YACE,OAAO,EAAE,CAAC,EACR,OAAO,EACP,YAAY,EACZ,OAAO,EACP,QAAQ,EACR,UAAU,EACV,YAAY,EACZ,OAAO,GACR,EAAE,EAAE,CACH,eAAe,CACb,QAAQ,EACR,OAAO,CAAC,OAAO,EACf,OAAO,CAAC,OAAO,EACf,YAAY,EACZ,UAAU,EACV,OAAO,EACP,YAAY,EACZ,OAAO,CACR;YACH,EAAE,EAAE,iBAAiB;YACrB,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CACd,CAAC,CAAC,IAAI,EAAE,WAAW,EAAE,KAAK,qCAAqC;SAClE;QACD;YACE,OAAO,EAAE,CAAC,EACR,OAAO,EACP,YAAY,EACZ,QAAQ,EACR,UAAU,EACV,YAAY,EACZ,OAAO,GACR,EAAE,EAAE,CACH,qBAAqB,CACnB,QAAQ,EACR,OAAO,CAAC,OAAO,EACf,YAAY,EACZ,UAAU,EACV,OAAO,EACP,YAAY,CACb;YACH,EAAE,EAAE,uBAAuB;YAC3B,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CACd,CAAC,CAAC,IAAI,EAAE,WAAW,EAAE,KAAK,mCAAmC;SAChE;QACD;YACE,OAAO,EAAE,CAAC,EACR,OAAO,EACP,YAAY,EACZ,OAAO,EACP,QAAQ,EACR,UAAU,EACV,YAAY,EACZ,OAAO,GACR,EAAE,EAAE,CACH,qBAAqB,CACnB,QAAQ,EACR,OAAO,CAAC,OAAO,EACf,OAAO,CAAC,OAAO,EACf,YAAY,EACZ,UAAU,EACV,OAAO,EACP,YAAY,EACZ,OAAO,CACR;YACH,EAAE,EAAE,wBAAwB;YAC5B,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,WAAW,EAAE,KAAK,2BAA2B;SACvE;QACD;YACE,OAAO,EAAE,CAAC,EACR,OAAO,EACP,YAAY,EACZ,QAAQ,EACR,UAAU,EACV,YAAY,EACZ,OAAO,GACR,EAAE,EAAE,CACH,iBAAiB,CACf,QAAQ,EACR,OAAO,CAAC,OAAO,EACf,YAAY,EACZ,UAAU,EACV,OAAO,EACP,YAAY,CACb;YACH,EAAE,EAAE,sBAAsB;YAC1B,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,WAAW,EAAE,KAAK,2BAA2B;SACvE;KACF,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,kCAAkC;IAChD,OAAO,CAAC,qBAAqB,EAAE,CAAC,CAAC;AACnC,CAAC"}
@@ -18,6 +18,7 @@ import type { MonitorClient } from "@azure/arm-monitor";
18
18
  import type { NetworkManagementClient } from "@azure/arm-network";
19
19
  import type * as armResources from "@azure/arm-resources";
20
20
  import type { AnalysisResult, Thresholds } from "../../types.js";
21
+ import type { PricingService } from "../pricing/pricing-service.js";
21
22
  import type { MetricsCache } from "../utils.js";
22
23
  /**
23
24
  * Contract every analyzer must satisfy.
@@ -42,6 +43,11 @@ export type AnalyzerContext = {
42
43
  */
43
44
  metricsCache: MetricsCache;
44
45
  preferredLocation: string;
46
+ /**
47
+ * Optional pricing facade used to enrich findings with an estimated
48
+ * monthly cost. Absent when pricing is disabled via config / CLI.
49
+ */
50
+ pricing?: PricingService;
45
51
  resource: armResources.GenericResource;
46
52
  thresholds: Thresholds;
47
53
  timespanDays: number;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/azure/analyzers/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AACvE,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AACrE,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AAClE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AAClE,OAAO,KAAK,KAAK,YAAY,MAAM,sBAAsB,CAAC;AAE1D,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACjE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD;;GAEG;AACH,MAAM,MAAM,QAAQ,GAAG;IACrB,OAAO,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;IACvD;;;OAGG;IACH,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAC,eAAe,GAAG,OAAO,CAAC;CAC3D,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG;IAC5B,OAAO,EAAE,YAAY,CAAC;IACtB;;;OAGG;IACH,YAAY,EAAE,YAAY,CAAC;IAC3B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,QAAQ,EAAE,YAAY,CAAC,eAAe,CAAC;IACvC,UAAU,EAAE,UAAU,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,OAAO,CAAC;CAClB,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,YAAY,GAAG;IACzB,OAAO,EAAE,uBAAuB,CAAC;IACjC,aAAa,EAAE,sBAAsB,CAAC;IACtC,OAAO,EAAE,aAAa,CAAC;IACvB,OAAO,EAAE,uBAAuB,CAAC;IACjC,OAAO,EAAE,uBAAuB,CAAC;CAClC,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/azure/analyzers/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AACvE,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AACrE,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AAClE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AAClE,OAAO,KAAK,KAAK,YAAY,MAAM,sBAAsB,CAAC;AAE1D,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACjE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AACpE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD;;GAEG;AACH,MAAM,MAAM,QAAQ,GAAG;IACrB,OAAO,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;IACvD;;;OAGG;IACH,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAC,eAAe,GAAG,OAAO,CAAC;CAC3D,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG;IAC5B,OAAO,EAAE,YAAY,CAAC;IACtB;;;OAGG;IACH,YAAY,EAAE,YAAY,CAAC;IAC3B,iBAAiB,EAAE,MAAM,CAAC;IAC1B;;;OAGG;IACH,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB,QAAQ,EAAE,YAAY,CAAC,eAAe,CAAC;IACvC,UAAU,EAAE,UAAU,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,OAAO,CAAC;CAClB,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,YAAY,GAAG;IACzB,OAAO,EAAE,uBAAuB,CAAC;IACjC,aAAa,EAAE,sBAAsB,CAAC;IACtC,OAAO,EAAE,aAAa,CAAC;IACvB,OAAO,EAAE,uBAAuB,CAAC;IACjC,OAAO,EAAE,uBAAuB,CAAC;CAClC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/azure/config.ts"],"names":[],"mappings":"AAAA;;GAEG;AAQH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAI9C;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,eAAe,CACnC,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,WAAW,CAAC,CA4CtB;AAED;;;;;GAKG;AACH,wBAAsB,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAW9D"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/azure/config.ts"],"names":[],"mappings":"AAAA;;GAEG;AAQH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAI9C;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,eAAe,CACnC,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,WAAW,CAAC,CAwCtB;AAED;;;;;GAKG;AACH,wBAAsB,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAW9D"}
@@ -57,11 +57,7 @@ export async function loadAzureConfig(configPath) {
57
57
  const subscriptionIds = process.env.ARM_SUBSCRIPTION_ID
58
58
  ? process.env.ARM_SUBSCRIPTION_ID.split(",")
59
59
  : (await prompt("Enter Subscription IDs (comma-separated): ")).split(",");
60
- return {
61
- preferredLocation: "italynorth",
62
- subscriptionIds,
63
- timespanDays: 30,
64
- };
60
+ return ConfigSchema.parse({ azure: { subscriptionIds } }).azure;
65
61
  }
66
62
  /**
67
63
  * Prompts user for input via stdin.
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/azure/config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/azure/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Tests for the disk-backed pricing cache.
3
+ *
4
+ * Each test uses a freshly-created temp directory so they do not leak
5
+ * state into the developer's real pricing cache.
6
+ */
7
+ export {};
8
+ //# sourceMappingURL=cache.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.test.d.ts","sourceRoot":"","sources":["../../../../src/azure/pricing/__tests__/cache.test.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Tests for the disk-backed pricing cache.
3
+ *
4
+ * Each test uses a freshly-created temp directory so they do not leak
5
+ * state into the developer's real pricing cache.
6
+ */
7
+ import { writeFile } from "node:fs/promises";
8
+ import { afterEach, beforeEach, describe, expect, it } from "vitest";
9
+ import { DiskCache } from "../cache.js";
10
+ import { makeTestCacheDir, removeTestCacheDir } from "../test-cache-dir.js";
11
+ describe("DiskCache", () => {
12
+ let dir;
13
+ beforeEach(async () => {
14
+ dir = await makeTestCacheDir("cache");
15
+ });
16
+ afterEach(async () => {
17
+ await removeTestCacheDir(dir);
18
+ });
19
+ it("returns undefined on a miss", async () => {
20
+ const cache = new DiskCache({ dir });
21
+ await expect(cache.get("nope")).resolves.toBeUndefined();
22
+ });
23
+ it("returns the value written under the same key", async () => {
24
+ const cache = new DiskCache({ dir });
25
+ await cache.set("hello", { hits: 42 });
26
+ await expect(cache.get("hello")).resolves.toEqual({ hits: 42 });
27
+ });
28
+ it("treats different keys as independent entries", async () => {
29
+ const cache = new DiskCache({ dir });
30
+ await cache.set("a", 1);
31
+ await cache.set("b", 2);
32
+ await expect(cache.get("a")).resolves.toBe(1);
33
+ await expect(cache.get("b")).resolves.toBe(2);
34
+ });
35
+ it("returns undefined once the entry is older than ttlMs", async () => {
36
+ const cache = new DiskCache({ dir, ttlMs: 1 });
37
+ await cache.set("stale", { v: 1 });
38
+ // Wait long enough to outlast the 1 ms TTL.
39
+ await new Promise((resolve) => setTimeout(resolve, 25));
40
+ await expect(cache.get("stale")).resolves.toBeUndefined();
41
+ });
42
+ it("returns undefined when the cache file contains invalid JSON", async () => {
43
+ const cache = new DiskCache({ dir });
44
+ const path = cache.pathFor("broken");
45
+ await writeFile(path, "{not json", "utf8");
46
+ await expect(cache.get("broken")).resolves.toBeUndefined();
47
+ });
48
+ it("derives different paths for different keys", () => {
49
+ const cache = new DiskCache({ dir });
50
+ expect(cache.pathFor("a")).not.toBe(cache.pathFor("b"));
51
+ });
52
+ it("refuses to remove directories outside the test cache parent", async () => {
53
+ await expect(removeTestCacheDir(process.cwd())).rejects.toThrow(/non-test cache directory/);
54
+ });
55
+ });
56
+ //# sourceMappingURL=cache.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.test.js","sourceRoot":"","sources":["../../../../src/azure/pricing/__tests__/cache.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Tests for the Azure Retail Prices HTTP client.
3
+ *
4
+ * The client is exercised against an in-process fake `fetch` so the suite
5
+ * never reaches the real `prices.azure.com` endpoint. A temp directory is
6
+ * used as cache so each test starts from a cold state.
7
+ */
8
+ export {};
9
+ //# sourceMappingURL=client.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.test.d.ts","sourceRoot":"","sources":["../../../../src/azure/pricing/__tests__/client.test.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG"}
@@ -0,0 +1,181 @@
1
+ /**
2
+ * Tests for the Azure Retail Prices HTTP client.
3
+ *
4
+ * The client is exercised against an in-process fake `fetch` so the suite
5
+ * never reaches the real `prices.azure.com` endpoint. A temp directory is
6
+ * used as cache so each test starts from a cold state.
7
+ */
8
+ import { readFile } from "node:fs/promises";
9
+ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
10
+ import { DiskCache } from "../cache.js";
11
+ import { PricingClient } from "../client.js";
12
+ import { makeTestCacheDir, removeTestCacheDir } from "../test-cache-dir.js";
13
+ const FIXTURE_PATH = new URL("./fixtures/vm-b2s-westeurope.json", import.meta.url);
14
+ async function loadFixture() {
15
+ const raw = await readFile(FIXTURE_PATH, "utf8");
16
+ return JSON.parse(raw);
17
+ }
18
+ function makeOkFetch(body) {
19
+ return vi.fn(async () => ({
20
+ json: async () => body,
21
+ ok: true,
22
+ status: 200,
23
+ statusText: "OK",
24
+ }));
25
+ }
26
+ describe("PricingClient.query", () => {
27
+ let dir;
28
+ beforeEach(async () => {
29
+ dir = await makeTestCacheDir("client");
30
+ });
31
+ afterEach(async () => {
32
+ await removeTestCacheDir(dir);
33
+ });
34
+ it("returns the items from a single page response", async () => {
35
+ const body = await loadFixture();
36
+ const fetchImpl = makeOkFetch(body);
37
+ const client = new PricingClient({
38
+ cache: new DiskCache({ dir }),
39
+ fetch: fetchImpl,
40
+ });
41
+ const items = await client.query("serviceName eq 'Virtual Machines'");
42
+ expect(items).toHaveLength(2);
43
+ expect(items[0].armSkuName).toBe("Standard_B2s");
44
+ expect(items[0].unitPrice).toBe(0.057);
45
+ expect(fetchImpl).toHaveBeenCalledTimes(1);
46
+ });
47
+ it("includes the filter, currency, and api-version in the request URL", async () => {
48
+ const body = await loadFixture();
49
+ const fetchImpl = makeOkFetch(body);
50
+ const client = new PricingClient({
51
+ cache: new DiskCache({ dir }),
52
+ currencyCode: "EUR",
53
+ fetch: fetchImpl,
54
+ });
55
+ await client.query("serviceName eq 'Virtual Machines'");
56
+ const url = fetchImpl.mock
57
+ .calls[0][0];
58
+ expect(url).toContain("prices.azure.com/api/retail/prices");
59
+ expect(url).toContain("currencyCode=EUR");
60
+ expect(url).toContain("api-version=");
61
+ // URLSearchParams encodes spaces as `+` (form-urlencoded), so we
62
+ // convert them back before decoding the filter expression.
63
+ const decoded = decodeURIComponent(url.replace(/\+/g, " "));
64
+ expect(decoded).toContain("$filter=serviceName eq 'Virtual Machines'");
65
+ });
66
+ it("follows NextPageLink across multiple pages", async () => {
67
+ const page1 = {
68
+ Count: 1,
69
+ Items: [
70
+ {
71
+ currencyCode: "EUR",
72
+ retailPrice: 1,
73
+ type: "Consumption",
74
+ unitOfMeasure: "1 Hour",
75
+ unitPrice: 1,
76
+ },
77
+ ],
78
+ NextPageLink: "https://prices.azure.com/api/retail/prices?next=2",
79
+ };
80
+ const page2 = {
81
+ Count: 1,
82
+ Items: [
83
+ {
84
+ currencyCode: "EUR",
85
+ retailPrice: 2,
86
+ type: "Consumption",
87
+ unitOfMeasure: "1 Hour",
88
+ unitPrice: 2,
89
+ },
90
+ ],
91
+ NextPageLink: null,
92
+ };
93
+ const fetchImpl = vi
94
+ .fn()
95
+ .mockResolvedValueOnce({
96
+ json: async () => page1,
97
+ ok: true,
98
+ status: 200,
99
+ statusText: "OK",
100
+ })
101
+ .mockResolvedValueOnce({
102
+ json: async () => page2,
103
+ ok: true,
104
+ status: 200,
105
+ statusText: "OK",
106
+ });
107
+ const client = new PricingClient({
108
+ cache: new DiskCache({ dir }),
109
+ fetch: fetchImpl,
110
+ });
111
+ const items = await client.query("anything");
112
+ expect(items.map((i) => i.unitPrice)).toEqual([1, 2]);
113
+ expect(fetchImpl).toHaveBeenCalledTimes(2);
114
+ });
115
+ it("serves a cached response without hitting the network on the second call", async () => {
116
+ const body = await loadFixture();
117
+ const fetchImpl = makeOkFetch(body);
118
+ const cache = new DiskCache({ dir });
119
+ const client = new PricingClient({ cache, fetch: fetchImpl });
120
+ const first = await client.query("filter-a");
121
+ const second = await client.query("filter-a");
122
+ expect(first).toEqual(second);
123
+ expect(fetchImpl).toHaveBeenCalledTimes(1);
124
+ });
125
+ it("keeps cache entries scoped by currency", async () => {
126
+ const body = await loadFixture();
127
+ const fetchImpl = makeOkFetch(body);
128
+ const cache = new DiskCache({ dir });
129
+ const eur = new PricingClient({
130
+ cache,
131
+ currencyCode: "EUR",
132
+ fetch: fetchImpl,
133
+ });
134
+ const usd = new PricingClient({
135
+ cache,
136
+ currencyCode: "USD",
137
+ fetch: fetchImpl,
138
+ });
139
+ await eur.query("same-filter");
140
+ await usd.query("same-filter");
141
+ // Two distinct cache keys → two API round-trips, no cross-contamination.
142
+ expect(fetchImpl).toHaveBeenCalledTimes(2);
143
+ });
144
+ it("throws a descriptive error on a non-2xx response", async () => {
145
+ const fetchImpl = vi.fn(async () => ({
146
+ json: async () => ({}),
147
+ ok: false,
148
+ status: 503,
149
+ statusText: "Service Unavailable",
150
+ }));
151
+ const client = new PricingClient({
152
+ cache: new DiskCache({ dir }),
153
+ fetch: fetchImpl,
154
+ });
155
+ await expect(client.query("x")).rejects.toThrow(/503/);
156
+ });
157
+ it("throws when the response body fails schema validation", async () => {
158
+ const fetchImpl = makeOkFetch({ wrong: "shape" });
159
+ const client = new PricingClient({
160
+ cache: new DiskCache({ dir }),
161
+ fetch: fetchImpl,
162
+ });
163
+ await expect(client.query("x")).rejects.toThrow();
164
+ });
165
+ it("throws a descriptive error when the response body is not JSON", async () => {
166
+ const fetchImpl = vi.fn(async () => ({
167
+ json: async () => {
168
+ throw new SyntaxError("Unexpected token");
169
+ },
170
+ ok: true,
171
+ status: 200,
172
+ statusText: "OK",
173
+ }));
174
+ const client = new PricingClient({
175
+ cache: new DiskCache({ dir }),
176
+ fetch: fetchImpl,
177
+ });
178
+ await expect(client.query("x")).rejects.toThrow(/invalid JSON/);
179
+ });
180
+ });
181
+ //# sourceMappingURL=client.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.test.js","sourceRoot":"","sources":["../../../../src/azure/pricing/__tests__/client.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Tests for the PricingService façade — covers memoization and error
3
+ * swallowing. The underlying resolvers are exercised in their own tests.
4
+ */
5
+ export {};
6
+ //# sourceMappingURL=pricing-service.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pricing-service.test.d.ts","sourceRoot":"","sources":["../../../../src/azure/pricing/__tests__/pricing-service.test.ts"],"names":[],"mappings":"AAAA;;;GAGG"}