-
Notifications
You must be signed in to change notification settings - Fork 11
Expand file tree
/
Copy pathusage.ts
More file actions
154 lines (125 loc) · 4.54 KB
/
usage.ts
File metadata and controls
154 lines (125 loc) · 4.54 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
/*
* Copyright (c) 2025, Salesforce, Inc.
* SPDX-License-Identifier: Apache-2
* For full license text, see the license.txt file in the repo root or http://www.apache.org/licenses/LICENSE-2.0
*/
import {Args, Flags} from '@oclif/core';
import {OdsCommand} from '@salesforce/b2c-tooling-sdk/cli';
import {getApiErrorMessage, type OdsComponents} from '@salesforce/b2c-tooling-sdk';
import {t, withDocs} from '../../i18n/index.js';
type SandboxUsageModel = OdsComponents['schemas']['SandboxUsageModel'];
/**
* Show sandbox-level usage information.
*/
export default class SandboxUsage extends OdsCommand<typeof SandboxUsage> {
static aliases = ['ods:usage'];
static args = {
sandboxId: Args.string({
description: 'Sandbox ID (UUID or realm-instance, e.g., zzzz-001)',
required: true,
}),
};
static description = withDocs(
t('commands.sandbox.usage.description', 'Show usage information for a specific sandbox'),
'/cli/sandbox.html#b2c-sandbox-usage',
);
static enableJsonFlag = true;
static examples = [
'<%= config.bin %> <%= command.id %> zzzz-001',
'<%= config.bin %> <%= command.id %> zzzz-001 --from 2026-02-08 --to 2026-02-11',
'<%= config.bin %> <%= command.id %> zzzz-001 --from 2026-02-08 --to 2026-02-11 --json',
];
static flags = {
from: Flags.string({
description: 'Start date for usage data (ISO 8601 format, e.g., 2024-01-01)',
}),
to: Flags.string({
description: 'End date for usage data (ISO 8601 format, e.g., 2024-12-31)',
}),
} as const;
async run(): Promise<OdsComponents['schemas']['SandboxUsageResponse'] | SandboxUsageModel | undefined> {
const {args, flags} = await this.parse(SandboxUsage);
const rawId = args.sandboxId;
const host = this.odsHost;
const sandboxId = await this.resolveSandboxId(rawId);
this.log(
t('commands.sandbox.usage.fetching', 'Fetching sandbox usage for {{sandboxId}} from {{host}}...', {
sandboxId,
host,
}),
);
const result = await this.odsClient.GET('/sandboxes/{sandboxId}/usage', {
params: {
path: {sandboxId},
query: {
from: flags.from,
to: flags.to,
},
},
});
if (result.error) {
this.error(
t('commands.sandbox.usage.error', 'Failed to fetch sandbox usage: {{message}}', {
message: getApiErrorMessage(result.error, result.response),
}),
);
}
const data = (result.data as OdsComponents['schemas']['SandboxUsageResponse'] | undefined)?.data;
if (!data) {
this.log(t('commands.sandbox.usage.noData', 'No usage data was returned for this sandbox.'));
return undefined;
}
if (this.jsonEnabled()) {
return result.data as OdsComponents['schemas']['SandboxUsageResponse'];
}
this.printSandboxUsageSummary(data);
return data;
}
private printSandboxUsageSummary(usage: SandboxUsageModel): void {
this.log('Sandbox Usage Summary');
this.log('─────────────────────');
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const anyUsage = usage as any;
const metrics: Array<[string, number | undefined]> = [
['Sandbox seconds', anyUsage.sandboxSeconds],
['Minutes up', anyUsage.minutesUp],
['Minutes down', anyUsage.minutesDown],
];
let hasSummaryMetric = false;
for (const [label, value] of metrics) {
if (value !== undefined) {
hasSummaryMetric = true;
this.log(`${label}: ${value}`);
}
}
if (anyUsage.minutesUpByProfile && anyUsage.minutesUpByProfile.length > 0) {
this.log('');
this.log('Minutes up by profile:');
for (const item of anyUsage.minutesUpByProfile) {
if (item.profile && item.minutes !== undefined) {
this.log(` ${item.profile}: ${item.minutes} minutes`);
}
}
}
const hasDetailedData =
(anyUsage.granularUsage && anyUsage.granularUsage.length > 0) ||
(anyUsage.history && anyUsage.history.length > 0);
if (
!hasSummaryMetric &&
!hasDetailedData &&
!(anyUsage.minutesUpByProfile && anyUsage.minutesUpByProfile.length > 0)
) {
this.log(
t('commands.sandbox.usage.emptyPeriod', 'No usage data was returned for this sandbox in the requested period.'),
);
} else if (hasDetailedData) {
this.log('');
this.log(
t(
'commands.sandbox.usage.detailedHint',
'Detailed usage data is available; re-run with --json to see full details.',
),
);
}
}
}