@pagopa/dx-savemoney 0.2.4 → 0.2.6

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 (80) hide show
  1. package/dist/azure/analyzer.d.ts +31 -16
  2. package/dist/azure/analyzer.d.ts.map +1 -1
  3. package/dist/azure/analyzer.js +110 -81
  4. package/dist/azure/analyzer.js.map +1 -1
  5. package/dist/azure/analyzers/index.d.ts +6 -0
  6. package/dist/azure/analyzers/index.d.ts.map +1 -0
  7. package/dist/azure/analyzers/index.js +5 -0
  8. package/dist/azure/analyzers/index.js.map +1 -0
  9. package/dist/azure/analyzers/registry.d.ts +21 -0
  10. package/dist/azure/analyzers/registry.d.ts.map +1 -0
  11. package/dist/azure/analyzers/registry.js +69 -0
  12. package/dist/azure/analyzers/registry.js.map +1 -0
  13. package/dist/azure/analyzers/types.d.ts +62 -0
  14. package/dist/azure/analyzers/types.d.ts.map +1 -0
  15. package/dist/azure/analyzers/types.js +15 -0
  16. package/dist/azure/analyzers/types.js.map +1 -0
  17. package/dist/azure/config.d.ts.map +1 -1
  18. package/dist/azure/config.js +1 -0
  19. package/dist/azure/config.js.map +1 -1
  20. package/dist/azure/resources/app-service.d.ts +2 -1
  21. package/dist/azure/resources/app-service.d.ts.map +1 -1
  22. package/dist/azure/resources/app-service.js +3 -3
  23. package/dist/azure/resources/app-service.js.map +1 -1
  24. package/dist/azure/resources/container-app.d.ts +2 -1
  25. package/dist/azure/resources/container-app.d.ts.map +1 -1
  26. package/dist/azure/resources/container-app.js +9 -9
  27. package/dist/azure/resources/container-app.js.map +1 -1
  28. package/dist/azure/resources/public-ip.d.ts +2 -1
  29. package/dist/azure/resources/public-ip.d.ts.map +1 -1
  30. package/dist/azure/resources/public-ip.js +2 -2
  31. package/dist/azure/resources/public-ip.js.map +1 -1
  32. package/dist/azure/resources/static-web-app.d.ts +2 -1
  33. package/dist/azure/resources/static-web-app.d.ts.map +1 -1
  34. package/dist/azure/resources/static-web-app.js +3 -3
  35. package/dist/azure/resources/static-web-app.js.map +1 -1
  36. package/dist/azure/resources/storage.d.ts +2 -1
  37. package/dist/azure/resources/storage.d.ts.map +1 -1
  38. package/dist/azure/resources/storage.js +2 -2
  39. package/dist/azure/resources/storage.js.map +1 -1
  40. package/dist/azure/resources/vm.d.ts +2 -1
  41. package/dist/azure/resources/vm.d.ts.map +1 -1
  42. package/dist/azure/resources/vm.js +3 -3
  43. package/dist/azure/resources/vm.js.map +1 -1
  44. package/dist/azure/types.d.ts +6 -0
  45. package/dist/azure/types.d.ts.map +1 -1
  46. package/dist/azure/utils.d.ts +35 -3
  47. package/dist/azure/utils.d.ts.map +1 -1
  48. package/dist/azure/utils.js +70 -29
  49. package/dist/azure/utils.js.map +1 -1
  50. package/dist/finding.d.ts +114 -0
  51. package/dist/finding.d.ts.map +1 -0
  52. package/dist/finding.js +51 -0
  53. package/dist/finding.js.map +1 -0
  54. package/dist/index.d.ts +3 -0
  55. package/dist/index.d.ts.map +1 -1
  56. package/dist/index.js +3 -0
  57. package/dist/index.js.map +1 -1
  58. package/dist/schema.d.ts +1 -0
  59. package/dist/schema.d.ts.map +1 -1
  60. package/dist/schema.js +5 -0
  61. package/dist/schema.js.map +1 -1
  62. package/package.json +6 -5
  63. package/src/__tests__/finding.test.ts +149 -0
  64. package/src/azure/__tests__/utils.test.ts +164 -2
  65. package/src/azure/analyzer.ts +140 -165
  66. package/src/azure/analyzers/index.ts +6 -0
  67. package/src/azure/analyzers/registry.ts +184 -0
  68. package/src/azure/analyzers/types.ts +66 -0
  69. package/src/azure/config.ts +1 -0
  70. package/src/azure/resources/app-service.ts +4 -0
  71. package/src/azure/resources/container-app.ts +10 -0
  72. package/src/azure/resources/public-ip.ts +3 -0
  73. package/src/azure/resources/static-web-app.ts +4 -0
  74. package/src/azure/resources/storage.ts +3 -0
  75. package/src/azure/resources/vm.ts +4 -0
  76. package/src/azure/types.ts +6 -0
  77. package/src/azure/utils.ts +110 -39
  78. package/src/finding.ts +152 -0
  79. package/src/index.ts +18 -0
  80. package/src/schema.ts +5 -0
@@ -1,14 +1,28 @@
1
1
  /**
2
2
  * Azure resource analyzer - Main orchestration logic
3
+ *
4
+ * Iterates every resource in every configured subscription, dispatches it
5
+ * to the registered analyzers (see `./analyzers/registry.ts`), and feeds
6
+ * the resulting findings into the report generator.
7
+ *
8
+ * Phase 0 refactor:
9
+ * - Resources are dispatched through a plugin-style `Analyzer` registry
10
+ * instead of a hard-coded `switch` statement.
11
+ * - Per-subscription resources are analyzed in parallel via a small
12
+ * in-process limiter (default concurrency 8, configurable via
13
+ * `AzureConfig.concurrency`).
14
+ * - Azure Monitor metric calls are memoized for the duration of a run via
15
+ * a per-run `MetricsCache` passed through `AnalyzerContext`, so concurrent
16
+ * calls to `analyzeAzureResources` stay fully isolated.
17
+ *
18
+ * The output schema (`AzureDetailedResourceReport`) is unchanged so the
19
+ * existing report formats keep working untouched.
3
20
  */
4
- import { ContainerAppsAPIClient } from "@azure/arm-appcontainers";
5
- import { WebSiteManagementClient } from "@azure/arm-appservice";
6
- import { ComputeManagementClient } from "@azure/arm-compute";
7
- import { MonitorClient } from "@azure/arm-monitor";
8
- import { NetworkManagementClient } from "@azure/arm-network";
9
21
  import * as armResources from "@azure/arm-resources";
10
22
  import type { AzureConfig } from "./types.js";
11
23
  import { type AnalysisResult, type Thresholds } from "../types.js";
24
+ import { type Analyzer, type AzureClients } from "./analyzers/index.js";
25
+ import { type MetricsCache } from "./utils.js";
12
26
  /**
13
27
  * Analyzes resources in multiple Azure subscriptions and generates a report.
14
28
  *
@@ -17,18 +31,19 @@ import { type AnalysisResult, type Thresholds } from "../types.js";
17
31
  */
18
32
  export declare function analyzeAzureResources(config: AzureConfig, format: "detailed-json" | "json" | "lint" | "table"): Promise<void>;
19
33
  /**
20
- * Analyzes a single Azure resource based on its type.
34
+ * Analyzes a single Azure resource by dispatching it to every registered
35
+ * analyzer that supports it. Generic checks (missing tags, location
36
+ * mismatch) are applied around the analyzer-specific logic.
21
37
  *
22
- * @param resource - The Azure resource to analyze
23
- * @param monitorClient - Azure Monitor client for metrics
24
- * @param computeClient - Azure Compute client
25
- * @param networkClient - Azure Network client
26
- * @param webSiteClient - Azure Web Site client
27
- * @param containerAppsClient - Azure Container Apps client
28
- * @param preferredLocation - Preferred Azure location
29
- * @param timespanDays - Number of days to analyze metrics
30
- * @param verbose - Whether verbose logging is enabled
38
+ * @param resource The Azure resource to analyze
39
+ * @param analyzers Registered analyzers (typically `createDefaultAnalyzers()`)
40
+ * @param clients Bundle of Azure SDK clients shared across analyzers
41
+ * @param metricsCache Run-scoped metrics cache to pass through to analyzers
42
+ * @param preferredLocation Preferred Azure region (resources elsewhere are flagged)
43
+ * @param timespanDays Look-back window for Azure Monitor metrics
44
+ * @param thresholds Numeric thresholds used during analysis
45
+ * @param verbose Whether verbose logging is enabled
31
46
  * @returns Analysis result with cost risk and reason
32
47
  */
33
- export declare function analyzeResource(resource: armResources.GenericResource, monitorClient: MonitorClient, computeClient: ComputeManagementClient, networkClient: NetworkManagementClient, webSiteClient: WebSiteManagementClient, containerAppsClient: ContainerAppsAPIClient, preferredLocation: string, timespanDays: number, thresholds: Thresholds, verbose?: boolean): Promise<AnalysisResult>;
48
+ export declare function analyzeResource(resource: armResources.GenericResource, analyzers: Analyzer[], clients: AzureClients, metricsCache: MetricsCache | undefined, preferredLocation: string, timespanDays: number, thresholds: Thresholds, verbose?: boolean): Promise<AnalysisResult>;
34
49
  //# sourceMappingURL=analyzer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"analyzer.d.ts","sourceRoot":"","sources":["../../src/azure/analyzer.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AAC7D,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AAC7D,OAAO,KAAK,YAAY,MAAM,sBAAsB,CAAC;AAIrD,OAAO,KAAK,EAAE,WAAW,EAA+B,MAAM,YAAY,CAAC;AAE3E,OAAO,EACL,KAAK,cAAc,EAGnB,KAAK,UAAU,EAChB,MAAM,aAAa,CAAC;AAerB;;;;;GAKG;AACH,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,WAAW,EACnB,MAAM,EAAE,eAAe,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,iBA2EpD;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,eAAe,CACnC,QAAQ,EAAE,YAAY,CAAC,eAAe,EACtC,aAAa,EAAE,aAAa,EAC5B,aAAa,EAAE,uBAAuB,EACtC,aAAa,EAAE,uBAAuB,EACtC,aAAa,EAAE,uBAAuB,EACtC,mBAAmB,EAAE,sBAAsB,EAC3C,iBAAiB,EAAE,MAAM,EACzB,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,UAAU,EACtB,OAAO,UAAQ,GACd,OAAO,CAAC,cAAc,CAAC,CAuHzB"}
1
+ {"version":3,"file":"analyzer.d.ts","sourceRoot":"","sources":["../../src/azure/analyzer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAOH,OAAO,KAAK,YAAY,MAAM,sBAAsB,CAAC;AAKrD,OAAO,KAAK,EAAE,WAAW,EAA+B,MAAM,YAAY,CAAC;AAE3E,OAAO,EACL,KAAK,cAAc,EAGnB,KAAK,UAAU,EAChB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,KAAK,QAAQ,EAEb,KAAK,YAAY,EAElB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAe,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAI5D;;;;;GAKG;AACH,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,WAAW,EACnB,MAAM,EAAE,eAAe,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,iBA6GpD;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,eAAe,CACnC,QAAQ,EAAE,YAAY,CAAC,eAAe,EACtC,SAAS,EAAE,QAAQ,EAAE,EACrB,OAAO,EAAE,YAAY,EACrB,YAAY,EAAE,YAAY,YAAY,EACtC,iBAAiB,EAAE,MAAM,EACzB,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,UAAU,EACtB,OAAO,UAAQ,GACd,OAAO,CAAC,cAAc,CAAC,CA8CzB"}
@@ -1,5 +1,22 @@
1
1
  /**
2
2
  * Azure resource analyzer - Main orchestration logic
3
+ *
4
+ * Iterates every resource in every configured subscription, dispatches it
5
+ * to the registered analyzers (see `./analyzers/registry.ts`), and feeds
6
+ * the resulting findings into the report generator.
7
+ *
8
+ * Phase 0 refactor:
9
+ * - Resources are dispatched through a plugin-style `Analyzer` registry
10
+ * instead of a hard-coded `switch` statement.
11
+ * - Per-subscription resources are analyzed in parallel via a small
12
+ * in-process limiter (default concurrency 8, configurable via
13
+ * `AzureConfig.concurrency`).
14
+ * - Azure Monitor metric calls are memoized for the duration of a run via
15
+ * a per-run `MetricsCache` passed through `AnalyzerContext`, so concurrent
16
+ * calls to `analyzeAzureResources` stay fully isolated.
17
+ *
18
+ * The output schema (`AzureDetailedResourceReport`) is unchanged so the
19
+ * existing report formats keep working untouched.
3
20
  */
4
21
  import { ContainerAppsAPIClient } from "@azure/arm-appcontainers";
5
22
  import { WebSiteManagementClient } from "@azure/arm-appservice";
@@ -9,10 +26,12 @@ import { NetworkManagementClient } from "@azure/arm-network";
9
26
  import * as armResources from "@azure/arm-resources";
10
27
  import { DefaultAzureCredential } from "@azure/identity";
11
28
  import { getLogger } from "@logtape/logtape";
29
+ import pLimit from "p-limit";
12
30
  import { DEFAULT_THRESHOLDS, mergeResults, } from "../types.js";
31
+ import { createDefaultAnalyzers, } from "./analyzers/index.js";
13
32
  import { generateReport } from "./report.js";
14
- import { analyzeAppServicePlan, analyzeContainerApp, analyzeDisk, analyzeNic, analyzePrivateEndpoint, analyzePublicIp, analyzeStaticSite, analyzeStorageAccount, analyzeVM, } from "./resources/index.js";
15
33
  import { matchesTags } from "./utils.js";
34
+ const DEFAULT_CONCURRENCY = 8;
16
35
  /**
17
36
  * Analyzes resources in multiple Azure subscriptions and generates a report.
18
37
  *
@@ -23,31 +42,71 @@ export async function analyzeAzureResources(config, format) {
23
42
  const logger = getLogger(["savemoney", "azure"]);
24
43
  const credential = new DefaultAzureCredential();
25
44
  const allReports = [];
45
+ const analyzers = createDefaultAnalyzers();
46
+ const thresholds = config.thresholds ?? DEFAULT_THRESHOLDS;
47
+ // Normalise concurrency the same way p-limit does to keep maxInFlight
48
+ // consistent. A raw value of 0/NaN would produce maxInFlight = 0/NaN and
49
+ // either deadlock or silently disable backpressure.
50
+ const rawConcurrency = config.concurrency ?? DEFAULT_CONCURRENCY;
51
+ const concurrency = Number.isFinite(rawConcurrency)
52
+ ? Math.max(1, Math.floor(rawConcurrency))
53
+ : 1;
54
+ const limit = pLimit(concurrency);
55
+ // Bound the in-flight Set to `2 × concurrency` so memory stays proportional
56
+ // to the limiter width, not the total resource count in a subscription.
57
+ const maxInFlight = concurrency * 2;
26
58
  for (const subscriptionId of config.subscriptionIds) {
27
59
  logger.info(`Analyzing subscription: ${subscriptionId}`);
28
- const resourceClient = new armResources.ResourceManagementClient(credential, subscriptionId.trim());
29
- const monitorClient = new MonitorClient(credential, subscriptionId.trim());
30
- const computeClient = new ComputeManagementClient(credential, subscriptionId.trim());
31
- const networkClient = new NetworkManagementClient(credential, subscriptionId.trim());
32
- const webSiteClient = new WebSiteManagementClient(credential, subscriptionId.trim());
33
- const containerAppsClient = new ContainerAppsAPIClient(credential, subscriptionId.trim());
34
- const thresholds = config.thresholds ?? DEFAULT_THRESHOLDS;
35
- // Use the async iterator to avoid memory explosion for large environments
60
+ const sid = subscriptionId.trim();
61
+ // Fresh cache per subscription — bounds peak memory to one subscription's
62
+ // worth of metrics and keeps concurrent analyzeAzureResources calls isolated.
63
+ const runCache = new Map();
64
+ const clients = {
65
+ compute: new ComputeManagementClient(credential, sid),
66
+ containerApps: new ContainerAppsAPIClient(credential, sid),
67
+ monitor: new MonitorClient(credential, sid),
68
+ network: new NetworkManagementClient(credential, sid),
69
+ webSite: new WebSiteManagementClient(credential, sid),
70
+ };
71
+ const resourceClient = new armResources.ResourceManagementClient(credential, sid);
72
+ const inFlight = new Set();
73
+ // Use the async iterator to avoid loading all resources into memory at once.
36
74
  for await (const resource of resourceClient.resources.list()) {
37
- // Skip resources that don't match the requested tag filter
38
75
  if (!matchesTags(resource, config.filterTags)) {
39
76
  continue;
40
77
  }
41
- const { costRisk, reason, suspectedUnused } = await analyzeResource(resource, monitorClient, computeClient, networkClient, webSiteClient, containerAppsClient, config.preferredLocation, config.timespanDays, thresholds, config.verbose || false);
42
- if (suspectedUnused) {
43
- allReports.push({
44
- analysis: {
45
- costRisk,
46
- reason: reason || "No specific findings.",
47
- suspectedUnused,
48
- },
49
- resource: resource,
50
- });
78
+ // Backpressure: wait for a slot before enqueuing the next task so that
79
+ // the inFlight Set stays bounded by maxInFlight instead of growing to the
80
+ // total resource count in the subscription.
81
+ while (inFlight.size >= maxInFlight) {
82
+ await Promise.race(inFlight).catch(() => undefined);
83
+ }
84
+ const task = limit(async () => {
85
+ const { costRisk, reason, suspectedUnused } = await analyzeResource(resource, analyzers, clients, runCache, config.preferredLocation, config.timespanDays, thresholds, config.verbose || false);
86
+ if (suspectedUnused) {
87
+ allReports.push({
88
+ analysis: {
89
+ costRisk,
90
+ reason: reason || "No specific findings.",
91
+ suspectedUnused,
92
+ },
93
+ resource,
94
+ });
95
+ }
96
+ });
97
+ inFlight.add(task);
98
+ // Suppress the unhandled-rejection that would occur between task creation
99
+ // and the Promise.allSettled drain below. The .catch() handler is a no-op
100
+ // because the actual error is still visible to allSettled (which logs it)
101
+ // via the original `task` reference kept in inFlight.
102
+ void task.catch(() => undefined).finally(() => inFlight.delete(task));
103
+ }
104
+ // Drain remaining tasks; surface any unexpected errors so they don't
105
+ // disappear silently and produce an incomplete report without a signal.
106
+ const results = await Promise.allSettled(inFlight);
107
+ for (const result of results) {
108
+ if (result.status === "rejected") {
109
+ logger.error(`Resource analysis failed: ${String(result.reason)}`);
51
110
  }
52
111
  }
53
112
  }
@@ -61,21 +120,21 @@ export async function analyzeAzureResources(config, format) {
61
120
  await generateReport(allReports, format);
62
121
  }
63
122
  /**
64
- * Analyzes a single Azure resource based on its type.
123
+ * Analyzes a single Azure resource by dispatching it to every registered
124
+ * analyzer that supports it. Generic checks (missing tags, location
125
+ * mismatch) are applied around the analyzer-specific logic.
65
126
  *
66
- * @param resource - The Azure resource to analyze
67
- * @param monitorClient - Azure Monitor client for metrics
68
- * @param computeClient - Azure Compute client
69
- * @param networkClient - Azure Network client
70
- * @param webSiteClient - Azure Web Site client
71
- * @param containerAppsClient - Azure Container Apps client
72
- * @param preferredLocation - Preferred Azure location
73
- * @param timespanDays - Number of days to analyze metrics
74
- * @param verbose - Whether verbose logging is enabled
127
+ * @param resource The Azure resource to analyze
128
+ * @param analyzers Registered analyzers (typically `createDefaultAnalyzers()`)
129
+ * @param clients Bundle of Azure SDK clients shared across analyzers
130
+ * @param metricsCache Run-scoped metrics cache to pass through to analyzers
131
+ * @param preferredLocation Preferred Azure region (resources elsewhere are flagged)
132
+ * @param timespanDays Look-back window for Azure Monitor metrics
133
+ * @param thresholds Numeric thresholds used during analysis
134
+ * @param verbose Whether verbose logging is enabled
75
135
  * @returns Analysis result with cost risk and reason
76
136
  */
77
- export async function analyzeResource(resource, monitorClient, computeClient, networkClient, webSiteClient, containerAppsClient, preferredLocation, timespanDays, thresholds, verbose = false) {
78
- const type = resource.type?.toLowerCase() || "";
137
+ export async function analyzeResource(resource, analyzers, clients, metricsCache = new Map(), preferredLocation, timespanDays, thresholds, verbose = false) {
79
138
  let result = {
80
139
  costRisk: "low",
81
140
  reason: "",
@@ -86,56 +145,26 @@ export async function analyzeResource(resource, monitorClient, computeClient, ne
86
145
  result.suspectedUnused = true;
87
146
  result.reason += "No tags found. ";
88
147
  }
89
- // Route to type-specific analysis hooks
90
- switch (type) {
91
- case "microsoft.app/containerapps": {
92
- const containerAppResult = await analyzeContainerApp(resource, containerAppsClient, monitorClient, timespanDays, thresholds, verbose);
93
- result = mergeResults(result, containerAppResult);
94
- break;
95
- }
96
- case "microsoft.compute/disks": {
97
- const diskResult = await analyzeDisk(resource, computeClient, verbose);
98
- result = mergeResults(result, diskResult);
99
- break;
100
- }
101
- case "microsoft.compute/virtualmachines": {
102
- const vmResult = await analyzeVM(resource, monitorClient, computeClient, timespanDays, thresholds, verbose);
103
- result = mergeResults(result, vmResult);
104
- break;
105
- }
106
- case "microsoft.network/networkinterfaces": {
107
- const nicResult = await analyzeNic(resource, networkClient, verbose);
108
- result = mergeResults(result, nicResult);
109
- break;
110
- }
111
- case "microsoft.network/privateendpoints": {
112
- const peResult = await analyzePrivateEndpoint(resource, networkClient, verbose);
113
- result = mergeResults(result, peResult);
114
- break;
115
- }
116
- case "microsoft.network/publicipaddresses": {
117
- const pipResult = await analyzePublicIp(resource, networkClient, monitorClient, timespanDays, thresholds, verbose);
118
- result = mergeResults(result, pipResult);
119
- break;
120
- }
121
- case "microsoft.storage/storageaccounts": {
122
- const storageResult = await analyzeStorageAccount(resource, monitorClient, timespanDays, thresholds, verbose);
123
- result = mergeResults(result, storageResult);
124
- break;
125
- }
126
- case "microsoft.web/serverfarms": {
127
- const aspResult = await analyzeAppServicePlan(resource, webSiteClient, monitorClient, timespanDays, thresholds, verbose);
128
- result = mergeResults(result, aspResult);
129
- break;
130
- }
131
- case "microsoft.web/staticsites": {
132
- const staticSiteResult = await analyzeStaticSite(resource, monitorClient, timespanDays, thresholds, verbose);
133
- result = mergeResults(result, staticSiteResult);
134
- break;
148
+ const ctx = {
149
+ clients,
150
+ metricsCache,
151
+ preferredLocation,
152
+ resource,
153
+ thresholds,
154
+ timespanDays,
155
+ verbose,
156
+ };
157
+ let matched = false;
158
+ for (const analyzer of analyzers) {
159
+ if (!analyzer.supports(resource)) {
160
+ continue;
135
161
  }
136
- default:
137
- result.reason += "No specific analysis for this resource type. ";
138
- break;
162
+ matched = true;
163
+ const specific = await analyzer.analyze(ctx);
164
+ result = mergeResults(result, specific);
165
+ }
166
+ if (!matched) {
167
+ result.reason += "No specific analysis for this resource type. ";
139
168
  }
140
169
  // Generic check for location
141
170
  if (resource.location &&
@@ -1 +1 @@
1
- {"version":3,"file":"analyzer.js","sourceRoot":"","sources":["../../src/azure/analyzer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"analyzer.js","sourceRoot":"","sources":["../../src/azure/analyzer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Re-exports for the Azure analyzer plugin layer.
3
+ */
4
+ export { createDefaultAnalyzers } from "./registry.js";
5
+ export type { Analyzer, AnalyzerContext, AzureClients } from "./types.js";
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/azure/analyzers/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAC;AACvD,YAAY,EAAE,QAAQ,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Re-exports for the Azure analyzer plugin layer.
3
+ */
4
+ export { createDefaultAnalyzers } from "./registry.js";
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/azure/analyzers/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAC"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Default registry of Azure analyzers.
3
+ *
4
+ * Each entry wraps an existing per-type analyzer function (kept in
5
+ * `../resources/`) and exposes it through the unified `Analyzer`
6
+ * interface. The orchestrator simply iterates the registry — no big
7
+ * `switch` statement, no risk of forgetting to wire a new analyzer
8
+ * into the orchestrator when the catalog grows.
9
+ *
10
+ * Adding a new analyzer is a single insertion here.
11
+ */
12
+ import type { Analyzer } from "./types.js";
13
+ /**
14
+ * Builds the default set of analyzers in the same order they were
15
+ * previously evaluated by the orchestrator's `switch` statement. The
16
+ * order is not behaviourally meaningful today (each resource is matched
17
+ * by exactly one analyzer) but is kept deterministic for predictable
18
+ * logging and to ease future debugging.
19
+ */
20
+ export declare function createDefaultAnalyzers(): Analyzer[];
21
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../src/azure/analyzers/registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAc3C;;;;;;GAMG;AACH,wBAAgB,sBAAsB,IAAI,QAAQ,EAAE,CAsJnD"}
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Default registry of Azure analyzers.
3
+ *
4
+ * Each entry wraps an existing per-type analyzer function (kept in
5
+ * `../resources/`) and exposes it through the unified `Analyzer`
6
+ * interface. The orchestrator simply iterates the registry — no big
7
+ * `switch` statement, no risk of forgetting to wire a new analyzer
8
+ * into the orchestrator when the catalog grows.
9
+ *
10
+ * Adding a new analyzer is a single insertion here.
11
+ */
12
+ import { analyzeAppServicePlan, analyzeContainerApp, analyzeDisk, analyzeNic, analyzePrivateEndpoint, analyzePublicIp, analyzeStaticSite, analyzeStorageAccount, analyzeVM, } from "../resources/index.js";
13
+ /**
14
+ * Builds the default set of analyzers in the same order they were
15
+ * previously evaluated by the orchestrator's `switch` statement. The
16
+ * order is not behaviourally meaningful today (each resource is matched
17
+ * by exactly one analyzer) but is kept deterministic for predictable
18
+ * logging and to ease future debugging.
19
+ */
20
+ export function createDefaultAnalyzers() {
21
+ return [
22
+ {
23
+ analyze: ({ clients, metricsCache, resource, thresholds, timespanDays, verbose, }) => analyzeContainerApp(resource, clients.containerApps, clients.monitor, timespanDays, thresholds, verbose, metricsCache),
24
+ id: "azure.container-app",
25
+ supports: (r) => r.type?.toLowerCase() === "microsoft.app/containerapps",
26
+ },
27
+ {
28
+ analyze: ({ clients, resource, verbose }) => analyzeDisk(resource, clients.compute, verbose),
29
+ id: "azure.disk",
30
+ supports: (r) => r.type?.toLowerCase() === "microsoft.compute/disks",
31
+ },
32
+ {
33
+ analyze: ({ clients, metricsCache, resource, thresholds, timespanDays, verbose, }) => analyzeVM(resource, clients.monitor, clients.compute, timespanDays, thresholds, verbose, metricsCache),
34
+ id: "azure.vm",
35
+ supports: (r) => r.type?.toLowerCase() === "microsoft.compute/virtualmachines",
36
+ },
37
+ {
38
+ analyze: ({ clients, resource, verbose }) => analyzeNic(resource, clients.network, verbose),
39
+ id: "azure.nic",
40
+ supports: (r) => r.type?.toLowerCase() === "microsoft.network/networkinterfaces",
41
+ },
42
+ {
43
+ analyze: ({ clients, resource, verbose }) => analyzePrivateEndpoint(resource, clients.network, verbose),
44
+ id: "azure.private-endpoint",
45
+ supports: (r) => r.type?.toLowerCase() === "microsoft.network/privateendpoints",
46
+ },
47
+ {
48
+ analyze: ({ clients, metricsCache, resource, thresholds, timespanDays, verbose, }) => analyzePublicIp(resource, clients.network, clients.monitor, timespanDays, thresholds, verbose, metricsCache),
49
+ id: "azure.public-ip",
50
+ supports: (r) => r.type?.toLowerCase() === "microsoft.network/publicipaddresses",
51
+ },
52
+ {
53
+ analyze: ({ clients, metricsCache, resource, thresholds, timespanDays, verbose, }) => analyzeStorageAccount(resource, clients.monitor, timespanDays, thresholds, verbose, metricsCache),
54
+ id: "azure.storage-account",
55
+ supports: (r) => r.type?.toLowerCase() === "microsoft.storage/storageaccounts",
56
+ },
57
+ {
58
+ analyze: ({ clients, metricsCache, resource, thresholds, timespanDays, verbose, }) => analyzeAppServicePlan(resource, clients.webSite, clients.monitor, timespanDays, thresholds, verbose, metricsCache),
59
+ id: "azure.app-service-plan",
60
+ supports: (r) => r.type?.toLowerCase() === "microsoft.web/serverfarms",
61
+ },
62
+ {
63
+ analyze: ({ clients, metricsCache, resource, thresholds, timespanDays, verbose, }) => analyzeStaticSite(resource, clients.monitor, timespanDays, thresholds, verbose, metricsCache),
64
+ id: "azure.static-web-app",
65
+ supports: (r) => r.type?.toLowerCase() === "microsoft.web/staticsites",
66
+ },
67
+ ];
68
+ }
69
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../../src/azure/analyzers/registry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Plugin architecture for Azure resource analyzers.
3
+ *
4
+ * Each `Analyzer` is a self-contained unit that:
5
+ * 1. declares the resource types it can handle (`supports`)
6
+ * 2. produces an `AnalysisResult` for a given resource (`analyze`)
7
+ *
8
+ * The orchestrator in `analyzer.ts` walks the registered analyzers for
9
+ * every resource it encounters. New sources (Azure Advisor, custom
10
+ * checks, pricing-enriched analyzers, …) can be added by implementing
11
+ * the interface and registering them in `registry.ts` without touching
12
+ * the orchestrator.
13
+ */
14
+ import type { ContainerAppsAPIClient } from "@azure/arm-appcontainers";
15
+ import type { WebSiteManagementClient } from "@azure/arm-appservice";
16
+ import type { ComputeManagementClient } from "@azure/arm-compute";
17
+ import type { MonitorClient } from "@azure/arm-monitor";
18
+ import type { NetworkManagementClient } from "@azure/arm-network";
19
+ import type * as armResources from "@azure/arm-resources";
20
+ import type { AnalysisResult, Thresholds } from "../../types.js";
21
+ import type { MetricsCache } from "../utils.js";
22
+ /**
23
+ * Contract every analyzer must satisfy.
24
+ */
25
+ export type Analyzer = {
26
+ analyze(ctx: AnalyzerContext): Promise<AnalysisResult>;
27
+ /**
28
+ * Stable identifier of the analyzer (e.g. `azure.vm`, `azure.advisor`).
29
+ * Used for logging, telemetry and future deduplication logic.
30
+ */
31
+ readonly id: string;
32
+ supports(resource: armResources.GenericResource): boolean;
33
+ };
34
+ /**
35
+ * Per-resource analysis context handed to every analyzer.
36
+ */
37
+ export type AnalyzerContext = {
38
+ clients: AzureClients;
39
+ /**
40
+ * Run-scoped metrics cache. Pass through to `getMetric` calls so that
41
+ * concurrent `analyzeAzureResources` invocations stay isolated.
42
+ */
43
+ metricsCache: MetricsCache;
44
+ preferredLocation: string;
45
+ resource: armResources.GenericResource;
46
+ thresholds: Thresholds;
47
+ timespanDays: number;
48
+ verbose: boolean;
49
+ };
50
+ /**
51
+ * Bundle of Azure SDK clients an analyzer might need. The orchestrator
52
+ * builds them once per subscription and passes the same instances to
53
+ * every analyzer.
54
+ */
55
+ export type AzureClients = {
56
+ compute: ComputeManagementClient;
57
+ containerApps: ContainerAppsAPIClient;
58
+ monitor: MonitorClient;
59
+ network: NetworkManagementClient;
60
+ webSite: WebSiteManagementClient;
61
+ };
62
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +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"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Plugin architecture for Azure resource analyzers.
3
+ *
4
+ * Each `Analyzer` is a self-contained unit that:
5
+ * 1. declares the resource types it can handle (`supports`)
6
+ * 2. produces an `AnalysisResult` for a given resource (`analyze`)
7
+ *
8
+ * The orchestrator in `analyzer.ts` walks the registered analyzers for
9
+ * every resource it encounters. New sources (Azure Advisor, custom
10
+ * checks, pricing-enriched analyzers, …) can be added by implementing
11
+ * the interface and registering them in `registry.ts` without touching
12
+ * the orchestrator.
13
+ */
14
+ export {};
15
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/azure/analyzers/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG"}
@@ -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,CA0CtB;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,CA2CtB;AAED;;;;;GAKG;AACH,wBAAsB,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAW9D"}
@@ -35,6 +35,7 @@ export async function loadAzureConfig(configPath) {
35
35
  const rawYaml = yaml.load(raw);
36
36
  const parsed = ConfigSchema.parse(rawYaml);
37
37
  return {
38
+ concurrency: parsed.azure.concurrency,
38
39
  preferredLocation: parsed.azure.preferredLocation,
39
40
  subscriptionIds: parsed.azure.subscriptionIds,
40
41
  thresholds: parsed.azure.thresholds,
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/azure/config.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,SAAS,CAAC;AAChC,OAAO,KAAK,QAAQ,MAAM,UAAU,CAAC;AACrC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,UAAmB;IAEnB,IAAI,UAAU,EAAE,CAAC;QACf,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YAC/B,MAAM,IAAI,KAAK,CAAC,0BAA0B,UAAU,EAAE,CAAC,CAAC;QAC1D,CAAC;QACD,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;YACjD,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAC/B,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YAC3C,OAAO;gBACL,iBAAiB,EAAE,MAAM,CAAC,KAAK,CAAC,iBAAiB;gBACjD,eAAe,EAAE,MAAM,CAAC,KAAK,CAAC,eAAe;gBAC7C,UAAU,EAAE,MAAM,CAAC,KAAK,CAAC,UAAU;gBACnC,YAAY,EAAE,MAAM,CAAC,KAAK,CAAC,YAAY;aACxC,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,KAAK,YAAY,CAAC,CAAC,QAAQ,EAAE,CAAC;gBAChC,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,EAAE,EAAE;oBACjE,KAAK,EAAE,KAAK;iBACb,CAAC,CAAC;YACL,CAAC;YACD,MAAM,IAAI,KAAK,CACb,+BAA+B,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,EAAE,EAC/E,EAAE,KAAK,EAAE,KAAK,EAAE,CACjB,CAAC;QACJ,CAAC;IACH,CAAC;IAED,MAAM,MAAM,GAAG,SAAS,CAAC,CAAC,WAAW,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC;IAC3D,MAAM,CAAC,IAAI,CACT,iEAAiE,CAClE,CAAC;IAEF,MAAM,eAAe,GAAG,OAAO,CAAC,GAAG,CAAC,mBAAmB;QACrD,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,KAAK,CAAC,GAAG,CAAC;QAC5C,CAAC,CAAC,CAAC,MAAM,MAAM,CAAC,4CAA4C,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAE5E,OAAO;QACL,iBAAiB,EAAE,YAAY;QAC/B,eAAe;QACf,YAAY,EAAE,EAAE;KACjB,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,QAAgB;IAC3C,MAAM,EAAE,GAAG,QAAQ,CAAC,eAAe,CAAC;QAClC,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,MAAM,EAAE,OAAO,CAAC,MAAM;KACvB,CAAC,CAAC;IACH,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAC7B,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,EAAE;QAC/B,EAAE,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,CAAC,MAAM,CAAC,CAAC;IAClB,CAAC,CAAC,CACH,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/azure/config.ts"],"names":[],"mappings":"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"}
@@ -5,6 +5,7 @@ import type { WebSiteManagementClient } from "@azure/arm-appservice";
5
5
  import type { MonitorClient } from "@azure/arm-monitor";
6
6
  import * as armResources from "@azure/arm-resources";
7
7
  import type { AnalysisResult, Thresholds } from "../../types.js";
8
+ import { type MetricsCache } from "../utils.js";
8
9
  /**
9
10
  * Analyzes an Azure App Service Plan for potential cost optimization.
10
11
  *
@@ -14,5 +15,5 @@ import type { AnalysisResult, Thresholds } from "../../types.js";
14
15
  * @param timespanDays - Number of days to analyze metrics
15
16
  * @returns Analysis result with cost risk and reason
16
17
  */
17
- export declare function analyzeAppServicePlan(resource: armResources.GenericResource, webSiteClient: WebSiteManagementClient, monitorClient: MonitorClient, timespanDays: number, thresholds?: Thresholds, verbose?: boolean): Promise<AnalysisResult>;
18
+ export declare function analyzeAppServicePlan(resource: armResources.GenericResource, webSiteClient: WebSiteManagementClient, monitorClient: MonitorClient, timespanDays: number, thresholds?: Thresholds, verbose?: boolean, cache?: MetricsCache): Promise<AnalysisResult>;
18
19
  //# sourceMappingURL=app-service.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"app-service.d.ts","sourceRoot":"","sources":["../../../src/azure/resources/app-service.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AACrE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAExD,OAAO,KAAK,YAAY,MAAM,sBAAsB,CAAC;AAGrD,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAUjE;;;;;;;;GAQG;AACH,wBAAsB,qBAAqB,CACzC,QAAQ,EAAE,YAAY,CAAC,eAAe,EACtC,aAAa,EAAE,uBAAuB,EACtC,aAAa,EAAE,aAAa,EAC5B,YAAY,EAAE,MAAM,EACpB,UAAU,GAAE,UAA+B,EAC3C,OAAO,UAAQ,GACd,OAAO,CAAC,cAAc,CAAC,CAyFzB"}
1
+ {"version":3,"file":"app-service.d.ts","sourceRoot":"","sources":["../../../src/azure/resources/app-service.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AACrE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAExD,OAAO,KAAK,YAAY,MAAM,sBAAsB,CAAC;AAGrD,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAGjE,OAAO,EAEL,KAAK,YAAY,EAIlB,MAAM,aAAa,CAAC;AAErB;;;;;;;;GAQG;AACH,wBAAsB,qBAAqB,CACzC,QAAQ,EAAE,YAAY,CAAC,eAAe,EACtC,aAAa,EAAE,uBAAuB,EACtC,aAAa,EAAE,aAAa,EAC5B,YAAY,EAAE,MAAM,EACpB,UAAU,GAAE,UAA+B,EAC3C,OAAO,UAAQ,EACf,KAAK,CAAC,EAAE,YAAY,GACnB,OAAO,CAAC,cAAc,CAAC,CA2FzB"}