@pagopa/dx-savemoney 0.2.5 → 0.3.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.
- package/README.md +33 -27
- package/dist/azure/analyzer.d.ts +49 -21
- package/dist/azure/analyzer.d.ts.map +1 -1
- package/dist/azure/analyzer.js +369 -93
- package/dist/azure/analyzer.js.map +1 -1
- package/dist/azure/analyzers/advisor.d.ts +68 -0
- package/dist/azure/analyzers/advisor.d.ts.map +1 -0
- package/dist/azure/analyzers/advisor.js +234 -0
- package/dist/azure/analyzers/advisor.js.map +1 -0
- package/dist/azure/analyzers/index.d.ts +8 -0
- package/dist/azure/analyzers/index.d.ts.map +1 -0
- package/dist/azure/analyzers/index.js +6 -0
- package/dist/azure/analyzers/index.js.map +1 -0
- package/dist/azure/analyzers/registry.d.ts +29 -0
- package/dist/azure/analyzers/registry.d.ts.map +1 -0
- package/dist/azure/analyzers/registry.js +79 -0
- package/dist/azure/analyzers/registry.js.map +1 -0
- package/dist/azure/analyzers/subscription.d.ts +53 -0
- package/dist/azure/analyzers/subscription.d.ts.map +1 -0
- package/dist/azure/analyzers/subscription.js +18 -0
- package/dist/azure/analyzers/subscription.js.map +1 -0
- package/dist/azure/analyzers/types.d.ts +62 -0
- package/dist/azure/analyzers/types.d.ts.map +1 -0
- package/dist/azure/analyzers/types.js +15 -0
- package/dist/azure/analyzers/types.js.map +1 -0
- package/dist/azure/config.d.ts.map +1 -1
- package/dist/azure/config.js +2 -0
- package/dist/azure/config.js.map +1 -1
- package/dist/azure/index.d.ts +1 -0
- package/dist/azure/index.d.ts.map +1 -1
- package/dist/azure/index.js +1 -0
- package/dist/azure/index.js.map +1 -1
- package/dist/azure/report.d.ts.map +1 -1
- package/dist/azure/report.js +178 -29
- package/dist/azure/report.js.map +1 -1
- package/dist/azure/resources/app-service.d.ts +2 -1
- package/dist/azure/resources/app-service.d.ts.map +1 -1
- package/dist/azure/resources/app-service.js +3 -3
- package/dist/azure/resources/app-service.js.map +1 -1
- package/dist/azure/resources/container-app.d.ts +2 -1
- package/dist/azure/resources/container-app.d.ts.map +1 -1
- package/dist/azure/resources/container-app.js +9 -9
- package/dist/azure/resources/container-app.js.map +1 -1
- package/dist/azure/resources/public-ip.d.ts +2 -1
- package/dist/azure/resources/public-ip.d.ts.map +1 -1
- package/dist/azure/resources/public-ip.js +2 -2
- package/dist/azure/resources/public-ip.js.map +1 -1
- package/dist/azure/resources/static-web-app.d.ts +2 -1
- package/dist/azure/resources/static-web-app.d.ts.map +1 -1
- package/dist/azure/resources/static-web-app.js +3 -3
- package/dist/azure/resources/static-web-app.js.map +1 -1
- package/dist/azure/resources/storage.d.ts +2 -1
- package/dist/azure/resources/storage.d.ts.map +1 -1
- package/dist/azure/resources/storage.js +2 -2
- package/dist/azure/resources/storage.js.map +1 -1
- package/dist/azure/resources/vm.d.ts +2 -1
- package/dist/azure/resources/vm.d.ts.map +1 -1
- package/dist/azure/resources/vm.js +3 -3
- package/dist/azure/resources/vm.js.map +1 -1
- package/dist/azure/types.d.ts +34 -1
- package/dist/azure/types.d.ts.map +1 -1
- package/dist/azure/utils.d.ts +35 -3
- package/dist/azure/utils.d.ts.map +1 -1
- package/dist/azure/utils.js +70 -29
- package/dist/azure/utils.js.map +1 -1
- package/dist/finding.d.ts +114 -0
- package/dist/finding.d.ts.map +1 -0
- package/dist/finding.js +51 -0
- package/dist/finding.js.map +1 -0
- package/dist/index.d.ts +4 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/schema.d.ts +5 -0
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +14 -0
- package/dist/schema.js.map +1 -1
- package/package.json +4 -1
- package/src/__tests__/finding.test.ts +149 -0
- package/src/azure/__tests__/analyzer-tags.test.ts +74 -0
- package/src/azure/__tests__/report.test.ts +27 -0
- package/src/azure/__tests__/utils.test.ts +164 -2
- package/src/azure/analyzer.ts +513 -182
- package/src/azure/analyzers/__tests__/advisor.test.ts +367 -0
- package/src/azure/analyzers/advisor.ts +324 -0
- package/src/azure/analyzers/index.ts +14 -0
- package/src/azure/analyzers/registry.ts +196 -0
- package/src/azure/analyzers/subscription.ts +56 -0
- package/src/azure/analyzers/types.ts +66 -0
- package/src/azure/config.ts +2 -0
- package/src/azure/index.ts +1 -0
- package/src/azure/report.ts +206 -35
- package/src/azure/resources/app-service.ts +4 -0
- package/src/azure/resources/container-app.ts +10 -0
- package/src/azure/resources/public-ip.ts +3 -0
- package/src/azure/resources/static-web-app.ts +4 -0
- package/src/azure/resources/storage.ts +3 -0
- package/src/azure/resources/vm.ts +4 -0
- package/src/azure/types.ts +35 -1
- package/src/azure/utils.ts +110 -39
- package/src/finding.ts +152 -0
- package/src/index.ts +19 -1
- package/src/schema.ts +14 -0
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Azure Advisor analyzer.
|
|
3
|
+
*
|
|
4
|
+
* Fetches all `Cost` recommendations for the target subscription via the
|
|
5
|
+
* `@azure/arm-advisor` SDK and normalises them into the unified `Finding`
|
|
6
|
+
* model.
|
|
7
|
+
*
|
|
8
|
+
* ## Two kinds of Advisor cost recommendations
|
|
9
|
+
*
|
|
10
|
+
* ### Resource-specific (resourceMetadata.resourceId contains /providers/)
|
|
11
|
+
* Recommendations about a particular Azure resource (e.g. "right-size this
|
|
12
|
+
* VM"). Each is emitted as a separate Finding so it appears next to the
|
|
13
|
+
* resource in the per-resource section of the report. `enrichReason` adds
|
|
14
|
+
* SKU / region / term context from `extendedProperties` so findings for
|
|
15
|
+
* the same recommendation type on different resources are distinguishable.
|
|
16
|
+
*
|
|
17
|
+
* ### Subscription-scoped (no resourceId, or resourceId without /providers/)
|
|
18
|
+
* Reserved Instance and Savings Plan recommendations. The Advisor API
|
|
19
|
+
* returns **one entry per qualifying combination** (term, scope, quantity,
|
|
20
|
+
* etc.) but the Azure Portal **groups them by `recommendationTypeId`** and
|
|
21
|
+
* shows a single entry for the best option — matching the mental model
|
|
22
|
+
* a user has when deciding whether to buy a commitment.
|
|
23
|
+
*
|
|
24
|
+
* Different amounts within the same `recommendationTypeId` represent
|
|
25
|
+
* **mutually exclusive purchase options** (e.g. different DB sizes or
|
|
26
|
+
* quantities); the user would choose one, not buy all. We therefore report
|
|
27
|
+
* the **maximum** savings amount across all unique configurations, matching
|
|
28
|
+
* the portal's behaviour. Scope variants (Shared / Single / ResourceGroup)
|
|
29
|
+
* that carry the same amount are deduplicated so they do not count more
|
|
30
|
+
* than once. True duplicates — recommendations with the same ARM ID —
|
|
31
|
+
* are also removed before taking the maximum.
|
|
32
|
+
*/
|
|
33
|
+
import { AdvisorManagementClient } from "@azure/arm-advisor";
|
|
34
|
+
import { getLogger } from "@logtape/logtape";
|
|
35
|
+
/**
|
|
36
|
+
* Builds the Advisor subscription-level analyzer.
|
|
37
|
+
*
|
|
38
|
+
* @param clientFactory Optional override to inject a mock client in tests.
|
|
39
|
+
* In production the default factory builds a real
|
|
40
|
+
* `AdvisorManagementClient` from the credential.
|
|
41
|
+
*/
|
|
42
|
+
export function createAdvisorAnalyzer(clientFactory) {
|
|
43
|
+
const build = clientFactory?.build ??
|
|
44
|
+
((credential, subscriptionId) => new AdvisorManagementClient(credential, subscriptionId));
|
|
45
|
+
return {
|
|
46
|
+
async analyze(ctx) {
|
|
47
|
+
const logger = getLogger(["savemoney", "azure", "advisor"]);
|
|
48
|
+
const client = build(ctx.credential, ctx.subscriptionId);
|
|
49
|
+
const resourceFindings = [];
|
|
50
|
+
const subGroups = new Map();
|
|
51
|
+
for await (const rec of client.recommendations.list({
|
|
52
|
+
filter: "Category eq 'Cost'",
|
|
53
|
+
})) {
|
|
54
|
+
if (rec.category?.toLowerCase() !== "cost")
|
|
55
|
+
continue;
|
|
56
|
+
const rawResourceId = rec.resourceMetadata?.resourceId;
|
|
57
|
+
const props = rec.extendedProperties;
|
|
58
|
+
const savings = parseSavings(props);
|
|
59
|
+
if (rawResourceId && /\/providers\//i.test(rawResourceId)) {
|
|
60
|
+
resourceFindings.push(buildResourceFinding(rec, savings, props, rawResourceId));
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
addToSubGroups(subGroups, rec, savings, ctx, logger);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
const findings = [...resourceFindings, ...flushSubGroups(subGroups)];
|
|
67
|
+
logger.info(`Advisor: ${findings.length} cost finding(s) for ${ctx.subscriptionId}` +
|
|
68
|
+
` (${resourceFindings.length} resource-specific, ${subGroups.size} subscription-level)`);
|
|
69
|
+
return findings;
|
|
70
|
+
},
|
|
71
|
+
id: "azure.advisor",
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
// ── helpers — extracted to keep `analyze` complexity within linter limits —
|
|
75
|
+
function addToSubGroups(subGroups, rec, savings, ctx, logger) {
|
|
76
|
+
const typeKey = rec.recommendationTypeId ??
|
|
77
|
+
`unknown.${rec.shortDescription?.problem ?? ""}`;
|
|
78
|
+
const existing = subGroups.get(typeKey);
|
|
79
|
+
if (existing) {
|
|
80
|
+
updateSubGroup(existing, rec.id ?? "", savings);
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
subGroups.set(typeKey, createSubGroup(rec, typeKey, savings, ctx, logger));
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
function buildResourceFinding(rec, savings, props, rawResourceId) {
|
|
87
|
+
const problem = rec.shortDescription?.problem ??
|
|
88
|
+
rec.shortDescription?.solution ??
|
|
89
|
+
"Azure Advisor cost recommendation";
|
|
90
|
+
return {
|
|
91
|
+
category: "cost",
|
|
92
|
+
code: `advisor.${rec.recommendationTypeId ?? "unknown"}`,
|
|
93
|
+
estimatedMonthlySavings: savings,
|
|
94
|
+
reason: enrichReason(problem, props),
|
|
95
|
+
recommendedAction: rec.shortDescription?.solution,
|
|
96
|
+
resourceId: rawResourceId,
|
|
97
|
+
severity: mapImpact(rec.impact),
|
|
98
|
+
source: "advisor",
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
function createSubGroup(rec, typeKey, savings, ctx, logger) {
|
|
102
|
+
const problem = rec.shortDescription?.problem ??
|
|
103
|
+
rec.shortDescription?.solution ??
|
|
104
|
+
"Azure Advisor cost recommendation";
|
|
105
|
+
const reason = problem.endsWith(".") ? problem : `${problem}.`;
|
|
106
|
+
const rawResourceId = rec.resourceMetadata?.resourceId;
|
|
107
|
+
const resourceId = rawResourceId ?? `/subscriptions/${ctx.subscriptionId}`;
|
|
108
|
+
if (!rawResourceId && ctx.verbose) {
|
|
109
|
+
logger.debug(`Advisor recommendation has no resourceId, attributed to subscription: ${typeKey}`);
|
|
110
|
+
}
|
|
111
|
+
return {
|
|
112
|
+
bestAmount: savings?.amount ?? 0,
|
|
113
|
+
count: savings ? 1 : 0,
|
|
114
|
+
currency: savings?.currency ?? "USD",
|
|
115
|
+
proto: {
|
|
116
|
+
category: "cost",
|
|
117
|
+
code: `advisor.${typeKey}`,
|
|
118
|
+
reason,
|
|
119
|
+
recommendedAction: rec.shortDescription?.solution,
|
|
120
|
+
resourceId,
|
|
121
|
+
severity: mapImpact(rec.impact),
|
|
122
|
+
source: "advisor",
|
|
123
|
+
},
|
|
124
|
+
recIds: new Set(rec.id ? [rec.id] : []),
|
|
125
|
+
uniqueSavingsKeys: new Set(savings ? [`${savings.amount}`] : []),
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Appends discriminating context (SKU, region, term, scope, …) to the
|
|
130
|
+
* Advisor short description so visually-duplicated reasons can be told
|
|
131
|
+
* apart. RI / Savings Plan recommendations in particular return the same
|
|
132
|
+
* `problem` string for every SKU+region+term combination, which made the
|
|
133
|
+
* report look like it carried duplicated rows. Each call stays a single
|
|
134
|
+
* Finding — we do NOT deduplicate, because every recommendation refers
|
|
135
|
+
* to a different commitment with its own savings figure.
|
|
136
|
+
*/
|
|
137
|
+
function enrichReason(problem, props) {
|
|
138
|
+
const base = problem.endsWith(".") ? problem : `${problem}.`;
|
|
139
|
+
if (!props)
|
|
140
|
+
return base;
|
|
141
|
+
const parts = [];
|
|
142
|
+
// armSkuName covers VM RIs; productName/serviceType cover SQL/Cosmos/etc.
|
|
143
|
+
const sku = props.armSkuName ?? props.productName ?? props.serviceType ?? props.sku;
|
|
144
|
+
if (sku)
|
|
145
|
+
parts.push(sku);
|
|
146
|
+
const region = props.region ?? props.location;
|
|
147
|
+
if (region)
|
|
148
|
+
parts.push(region);
|
|
149
|
+
// Normalise term values (P1Y / P3Y / 1_Year / 3_Year) into a compact label.
|
|
150
|
+
const rawTerm = props.term;
|
|
151
|
+
if (rawTerm) {
|
|
152
|
+
const term = /3/.test(rawTerm) ? "3y" : /1/.test(rawTerm) ? "1y" : rawTerm;
|
|
153
|
+
parts.push(term);
|
|
154
|
+
}
|
|
155
|
+
const scope = props.scope;
|
|
156
|
+
if (scope)
|
|
157
|
+
parts.push(scope.toLowerCase());
|
|
158
|
+
const qty = props.displayQuantity ?? props.quantity;
|
|
159
|
+
if (qty)
|
|
160
|
+
parts.push(`x${qty}`);
|
|
161
|
+
if (parts.length === 0)
|
|
162
|
+
return base;
|
|
163
|
+
return `${base} (${parts.join(", ")})`;
|
|
164
|
+
}
|
|
165
|
+
function flushSubGroups(subGroups) {
|
|
166
|
+
const findings = [];
|
|
167
|
+
for (const { bestAmount, count, currency, proto } of subGroups.values()) {
|
|
168
|
+
const estimatedMonthlySavings = bestAmount > 0 ? { amount: bestAmount, currency } : undefined;
|
|
169
|
+
const reason = count > 1
|
|
170
|
+
? proto.reason.replace(/\.$/, ` (${count} options).`)
|
|
171
|
+
: proto.reason;
|
|
172
|
+
findings.push({ ...proto, estimatedMonthlySavings, reason });
|
|
173
|
+
}
|
|
174
|
+
return findings;
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Maps Advisor's `impact` (`High` | `Medium` | `Low`) onto the savemoney
|
|
178
|
+
* `CostRisk` scale. Falls back to `low` for any unexpected value to keep
|
|
179
|
+
* the analyzer resilient to future Advisor enum extensions.
|
|
180
|
+
*/
|
|
181
|
+
function mapImpact(impact) {
|
|
182
|
+
switch (impact?.toLowerCase()) {
|
|
183
|
+
case "high":
|
|
184
|
+
return "high";
|
|
185
|
+
case "medium":
|
|
186
|
+
return "medium";
|
|
187
|
+
default:
|
|
188
|
+
return "low";
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Parses the savings amount from Advisor's `extendedProperties`. Advisor
|
|
193
|
+
* returns it as a string; treat anything non-numeric as "no estimate".
|
|
194
|
+
*/
|
|
195
|
+
function parseSavings(extendedProperties) {
|
|
196
|
+
if (!extendedProperties)
|
|
197
|
+
return undefined;
|
|
198
|
+
const raw = extendedProperties.savingsAmount ?? extendedProperties.savings;
|
|
199
|
+
if (!raw)
|
|
200
|
+
return undefined;
|
|
201
|
+
const amount = Number(raw);
|
|
202
|
+
if (!Number.isFinite(amount))
|
|
203
|
+
return undefined;
|
|
204
|
+
const currency = extendedProperties.savingsCurrency ?? extendedProperties.currency ?? "USD";
|
|
205
|
+
return { amount, currency };
|
|
206
|
+
}
|
|
207
|
+
function updateSubGroup(group, recId, savings) {
|
|
208
|
+
if (recId && group.recIds.has(recId))
|
|
209
|
+
return; // true API duplicate
|
|
210
|
+
if (recId)
|
|
211
|
+
group.recIds.add(recId);
|
|
212
|
+
if (!savings)
|
|
213
|
+
return;
|
|
214
|
+
// Bootstrap currency from the first recommendation that carries savings.
|
|
215
|
+
// createSubGroup() defaults currency to "USD" when the first entry has no
|
|
216
|
+
// savings; without this check, later entries with a different currency (e.g.
|
|
217
|
+
// "EUR") would be silently dropped and no savings would ever be surfaced.
|
|
218
|
+
if (group.count === 0) {
|
|
219
|
+
group.currency = savings.currency;
|
|
220
|
+
group.uniqueSavingsKeys.add(`${savings.amount}`);
|
|
221
|
+
group.bestAmount = savings.amount;
|
|
222
|
+
group.count = 1;
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
if (savings.currency !== group.currency)
|
|
226
|
+
return;
|
|
227
|
+
const key = `${savings.amount}`;
|
|
228
|
+
if (group.uniqueSavingsKeys.has(key))
|
|
229
|
+
return; // scope variant, already seen
|
|
230
|
+
group.uniqueSavingsKeys.add(key);
|
|
231
|
+
group.bestAmount = Math.max(group.bestAmount, savings.amount);
|
|
232
|
+
group.count++;
|
|
233
|
+
}
|
|
234
|
+
//# sourceMappingURL=advisor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"advisor.js","sourceRoot":"","sources":["../../../src/azure/analyzers/advisor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Re-exports for the Azure analyzer plugin layer.
|
|
3
|
+
*/
|
|
4
|
+
export { createAdvisorAnalyzer } from "./advisor.js";
|
|
5
|
+
export { createDefaultAnalyzers, createDefaultSubscriptionAnalyzers, } from "./registry.js";
|
|
6
|
+
export type { SubscriptionAnalyzer, SubscriptionContext, } from "./subscription.js";
|
|
7
|
+
export type { Analyzer, AnalyzerContext, AzureClients } from "./types.js";
|
|
8
|
+
//# 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,qBAAqB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,EACL,sBAAsB,EACtB,kCAAkC,GACnC,MAAM,eAAe,CAAC;AACvB,YAAY,EACV,oBAAoB,EACpB,mBAAmB,GACpB,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EAAE,QAAQ,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/azure/analyzers/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,EACL,sBAAsB,EACtB,kCAAkC,GACnC,MAAM,eAAe,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
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 { SubscriptionAnalyzer } from "./subscription.js";
|
|
13
|
+
import type { Analyzer } from "./types.js";
|
|
14
|
+
/**
|
|
15
|
+
* Builds the default set of analyzers in the same order they were
|
|
16
|
+
* previously evaluated by the orchestrator's `switch` statement. The
|
|
17
|
+
* order is not behaviourally meaningful today (each resource is matched
|
|
18
|
+
* by exactly one analyzer) but is kept deterministic for predictable
|
|
19
|
+
* logging and to ease future debugging.
|
|
20
|
+
*/
|
|
21
|
+
export declare function createDefaultAnalyzers(): Analyzer[];
|
|
22
|
+
/**
|
|
23
|
+
* Builds the default set of subscription-level analyzers.
|
|
24
|
+
*
|
|
25
|
+
* Today this is just Azure Advisor; Phase 4 will add a quota / usages
|
|
26
|
+
* analyzer here. Adding new sources is a single insertion.
|
|
27
|
+
*/
|
|
28
|
+
export declare function createDefaultSubscriptionAnalyzers(): SubscriptionAnalyzer[];
|
|
29
|
+
//# 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,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAC9D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAe3C;;;;;;GAMG;AACH,wBAAgB,sBAAsB,IAAI,QAAQ,EAAE,CAsJnD;AAED;;;;;GAKG;AACH,wBAAgB,kCAAkC,IAAI,oBAAoB,EAAE,CAE3E"}
|
|
@@ -0,0 +1,79 @@
|
|
|
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
|
+
import { createAdvisorAnalyzer } from "./advisor.js";
|
|
14
|
+
/**
|
|
15
|
+
* Builds the default set of analyzers in the same order they were
|
|
16
|
+
* previously evaluated by the orchestrator's `switch` statement. The
|
|
17
|
+
* order is not behaviourally meaningful today (each resource is matched
|
|
18
|
+
* by exactly one analyzer) but is kept deterministic for predictable
|
|
19
|
+
* logging and to ease future debugging.
|
|
20
|
+
*/
|
|
21
|
+
export function createDefaultAnalyzers() {
|
|
22
|
+
return [
|
|
23
|
+
{
|
|
24
|
+
analyze: ({ clients, metricsCache, resource, thresholds, timespanDays, verbose, }) => analyzeContainerApp(resource, clients.containerApps, clients.monitor, timespanDays, thresholds, verbose, metricsCache),
|
|
25
|
+
id: "azure.container-app",
|
|
26
|
+
supports: (r) => r.type?.toLowerCase() === "microsoft.app/containerapps",
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
analyze: ({ clients, resource, verbose }) => analyzeDisk(resource, clients.compute, verbose),
|
|
30
|
+
id: "azure.disk",
|
|
31
|
+
supports: (r) => r.type?.toLowerCase() === "microsoft.compute/disks",
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
analyze: ({ clients, metricsCache, resource, thresholds, timespanDays, verbose, }) => analyzeVM(resource, clients.monitor, clients.compute, timespanDays, thresholds, verbose, metricsCache),
|
|
35
|
+
id: "azure.vm",
|
|
36
|
+
supports: (r) => r.type?.toLowerCase() === "microsoft.compute/virtualmachines",
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
analyze: ({ clients, resource, verbose }) => analyzeNic(resource, clients.network, verbose),
|
|
40
|
+
id: "azure.nic",
|
|
41
|
+
supports: (r) => r.type?.toLowerCase() === "microsoft.network/networkinterfaces",
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
analyze: ({ clients, resource, verbose }) => analyzePrivateEndpoint(resource, clients.network, verbose),
|
|
45
|
+
id: "azure.private-endpoint",
|
|
46
|
+
supports: (r) => r.type?.toLowerCase() === "microsoft.network/privateendpoints",
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
analyze: ({ clients, metricsCache, resource, thresholds, timespanDays, verbose, }) => analyzePublicIp(resource, clients.network, clients.monitor, timespanDays, thresholds, verbose, metricsCache),
|
|
50
|
+
id: "azure.public-ip",
|
|
51
|
+
supports: (r) => r.type?.toLowerCase() === "microsoft.network/publicipaddresses",
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
analyze: ({ clients, metricsCache, resource, thresholds, timespanDays, verbose, }) => analyzeStorageAccount(resource, clients.monitor, timespanDays, thresholds, verbose, metricsCache),
|
|
55
|
+
id: "azure.storage-account",
|
|
56
|
+
supports: (r) => r.type?.toLowerCase() === "microsoft.storage/storageaccounts",
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
analyze: ({ clients, metricsCache, resource, thresholds, timespanDays, verbose, }) => analyzeAppServicePlan(resource, clients.webSite, clients.monitor, timespanDays, thresholds, verbose, metricsCache),
|
|
60
|
+
id: "azure.app-service-plan",
|
|
61
|
+
supports: (r) => r.type?.toLowerCase() === "microsoft.web/serverfarms",
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
analyze: ({ clients, metricsCache, resource, thresholds, timespanDays, verbose, }) => analyzeStaticSite(resource, clients.monitor, timespanDays, thresholds, verbose, metricsCache),
|
|
65
|
+
id: "azure.static-web-app",
|
|
66
|
+
supports: (r) => r.type?.toLowerCase() === "microsoft.web/staticsites",
|
|
67
|
+
},
|
|
68
|
+
];
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Builds the default set of subscription-level analyzers.
|
|
72
|
+
*
|
|
73
|
+
* Today this is just Azure Advisor; Phase 4 will add a quota / usages
|
|
74
|
+
* analyzer here. Adding new sources is a single insertion.
|
|
75
|
+
*/
|
|
76
|
+
export function createDefaultSubscriptionAnalyzers() {
|
|
77
|
+
return [createAdvisorAnalyzer()];
|
|
78
|
+
}
|
|
79
|
+
//# 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,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Subscription-level analyzer plugin contract.
|
|
3
|
+
*
|
|
4
|
+
* Some data sources are not naturally per-resource. Azure Advisor, for
|
|
5
|
+
* example, returns a flat list of recommendations for an entire
|
|
6
|
+
* subscription in a single call; future quota / `Microsoft.Capacity/usages`
|
|
7
|
+
* analyzers will follow the same shape.
|
|
8
|
+
*
|
|
9
|
+
* A `SubscriptionAnalyzer` is invoked once per subscription. It returns a
|
|
10
|
+
* flat list of `Finding`s carrying the `resourceId` they refer to; the
|
|
11
|
+
* orchestrator merges those findings into the per-resource reports.
|
|
12
|
+
*
|
|
13
|
+
* This interface is intentionally additive: per-resource `Analyzer`s
|
|
14
|
+
* (see `./types.ts`) keep working untouched. Sources written against the
|
|
15
|
+
* two interfaces can coexist in the same run.
|
|
16
|
+
*/
|
|
17
|
+
import type { TokenCredential } from "@azure/identity";
|
|
18
|
+
import type { Finding } from "../../finding.js";
|
|
19
|
+
/**
|
|
20
|
+
* Contract every subscription-level analyzer must satisfy.
|
|
21
|
+
*/
|
|
22
|
+
export type SubscriptionAnalyzer = {
|
|
23
|
+
/**
|
|
24
|
+
* Runs the analyzer for the given subscription. Implementations should
|
|
25
|
+
* be resilient: a failure here must not abort the whole run, the
|
|
26
|
+
* orchestrator logs and continues with the remaining analyzers.
|
|
27
|
+
*/
|
|
28
|
+
analyze(ctx: SubscriptionContext): Promise<Finding[]>;
|
|
29
|
+
/**
|
|
30
|
+
* Stable identifier of the analyzer (e.g. `azure.advisor`,
|
|
31
|
+
* `azure.quota`). Used for logging and future deduplication logic.
|
|
32
|
+
*/
|
|
33
|
+
readonly id: string;
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Context passed to every subscription-level analyzer.
|
|
37
|
+
*/
|
|
38
|
+
export type SubscriptionContext = {
|
|
39
|
+
/**
|
|
40
|
+
* Azure credential to instantiate management clients. The orchestrator
|
|
41
|
+
* builds it once and reuses it across analyzers.
|
|
42
|
+
*/
|
|
43
|
+
credential: TokenCredential;
|
|
44
|
+
/**
|
|
45
|
+
* Subscription ID to analyze.
|
|
46
|
+
*/
|
|
47
|
+
subscriptionId: string;
|
|
48
|
+
/**
|
|
49
|
+
* Whether verbose logging is enabled.
|
|
50
|
+
*/
|
|
51
|
+
verbose: boolean;
|
|
52
|
+
};
|
|
53
|
+
//# sourceMappingURL=subscription.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"subscription.d.ts","sourceRoot":"","sources":["../../../src/azure/analyzers/subscription.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAEvD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAEhD;;GAEG;AACH,MAAM,MAAM,oBAAoB,GAAG;IACjC;;;;OAIG;IACH,OAAO,CAAC,GAAG,EAAE,mBAAmB,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IACtD;;;OAGG;IACH,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,mBAAmB,GAAG;IAChC;;;OAGG;IACH,UAAU,EAAE,eAAe,CAAC;IAC5B;;OAEG;IACH,cAAc,EAAE,MAAM,CAAC;IACvB;;OAEG;IACH,OAAO,EAAE,OAAO,CAAC;CAClB,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Subscription-level analyzer plugin contract.
|
|
3
|
+
*
|
|
4
|
+
* Some data sources are not naturally per-resource. Azure Advisor, for
|
|
5
|
+
* example, returns a flat list of recommendations for an entire
|
|
6
|
+
* subscription in a single call; future quota / `Microsoft.Capacity/usages`
|
|
7
|
+
* analyzers will follow the same shape.
|
|
8
|
+
*
|
|
9
|
+
* A `SubscriptionAnalyzer` is invoked once per subscription. It returns a
|
|
10
|
+
* flat list of `Finding`s carrying the `resourceId` they refer to; the
|
|
11
|
+
* orchestrator merges those findings into the per-resource reports.
|
|
12
|
+
*
|
|
13
|
+
* This interface is intentionally additive: per-resource `Analyzer`s
|
|
14
|
+
* (see `./types.ts`) keep working untouched. Sources written against the
|
|
15
|
+
* two interfaces can coexist in the same run.
|
|
16
|
+
*/
|
|
17
|
+
export {};
|
|
18
|
+
//# sourceMappingURL=subscription.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"subscription.js","sourceRoot":"","sources":["../../../src/azure/analyzers/subscription.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG"}
|
|
@@ -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,
|
|
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"}
|
package/dist/azure/config.js
CHANGED
|
@@ -35,7 +35,9 @@ 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,
|
|
40
|
+
sources: parsed.azure.sources,
|
|
39
41
|
subscriptionIds: parsed.azure.subscriptionIds,
|
|
40
42
|
thresholds: parsed.azure.thresholds,
|
|
41
43
|
timespanDays: parsed.azure.timespanDays,
|
package/dist/azure/config.js.map
CHANGED
|
@@ -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":"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,WAAW,EAAE,MAAM,CAAC,KAAK,CAAC,WAAW;gBACrC,iBAAiB,EAAE,MAAM,CAAC,KAAK,CAAC,iBAAiB;gBACjD,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,OAAO;gBAC7B,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"}
|
package/dist/azure/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/azure/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/azure/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC"}
|
package/dist/azure/index.js
CHANGED
package/dist/azure/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/azure/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/azure/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../../src/azure/report.ts"],"names":[],"mappings":"AAAA;;GAEG;
|
|
1
|
+
{"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../../src/azure/report.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,KAAK,EACV,2BAA2B,EAE5B,MAAM,YAAY,CAAC;AAmCpB;;;;;GAKG;AACH,wBAAsB,cAAc,CAClC,MAAM,EAAE,2BAA2B,EAAE,EACrC,MAAM,EAAE,eAAe,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,iBAmDpD"}
|