@salesforce/b2c-tooling-sdk 1.18.0 → 1.19.1

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 (37) hide show
  1. package/dist/esm/clients/index.d.ts +2 -0
  2. package/dist/esm/clients/index.js +1 -0
  3. package/dist/esm/clients/index.js.map +1 -1
  4. package/dist/esm/clients/metrics.d.ts +123 -0
  5. package/dist/esm/clients/metrics.generated.d.ts +1016 -0
  6. package/dist/esm/clients/metrics.generated.js +6 -0
  7. package/dist/esm/clients/metrics.generated.js.map +1 -0
  8. package/dist/esm/clients/metrics.js +65 -0
  9. package/dist/esm/clients/metrics.js.map +1 -0
  10. package/dist/esm/clients/middleware-registry.d.ts +1 -1
  11. package/dist/esm/clients/middleware-registry.js.map +1 -1
  12. package/dist/esm/discovery/detector.d.ts +1 -0
  13. package/dist/esm/discovery/detector.js +3 -1
  14. package/dist/esm/discovery/detector.js.map +1 -1
  15. package/dist/esm/discovery/index.d.ts +1 -1
  16. package/dist/esm/discovery/patterns/cartridges.js +4 -2
  17. package/dist/esm/discovery/patterns/cartridges.js.map +1 -1
  18. package/dist/esm/discovery/patterns/sfra.js +10 -5
  19. package/dist/esm/discovery/patterns/sfra.js.map +1 -1
  20. package/dist/esm/discovery/types.d.ts +20 -1
  21. package/dist/esm/index.d.ts +4 -2
  22. package/dist/esm/index.js +3 -1
  23. package/dist/esm/index.js.map +1 -1
  24. package/dist/esm/operations/code/cartridges.d.ts +18 -0
  25. package/dist/esm/operations/code/cartridges.js +31 -20
  26. package/dist/esm/operations/code/cartridges.js.map +1 -1
  27. package/dist/esm/operations/logs/filter.d.ts +6 -1
  28. package/dist/esm/operations/logs/filter.js +7 -2
  29. package/dist/esm/operations/logs/filter.js.map +1 -1
  30. package/dist/esm/operations/metrics/index.d.ts +371 -0
  31. package/dist/esm/operations/metrics/index.js +478 -0
  32. package/dist/esm/operations/metrics/index.js.map +1 -0
  33. package/dist/esm/operations/metrics/tags.d.ts +148 -0
  34. package/dist/esm/operations/metrics/tags.js +235 -0
  35. package/dist/esm/operations/metrics/tags.js.map +1 -0
  36. package/package.json +6 -2
  37. package/specs/metrics-v1.json +1713 -0
@@ -0,0 +1,478 @@
1
+ import { toOrganizationId } from '../../clients/custom-apis.js';
2
+ import { getApiErrorMessage } from '../../clients/error-utils.js';
3
+ import { getLogger } from '../../logging/logger.js';
4
+ import { parseSinceTime, parseRelativeTime } from '../logs/filter.js';
5
+ /**
6
+ * All metric categories exposed by the Metrics API, in a stable, documented order.
7
+ *
8
+ * Values match the API path segments (e.g. `overall` → `/metrics/overall`).
9
+ */
10
+ export const METRIC_CATEGORIES = [
11
+ 'overall',
12
+ 'sales',
13
+ 'ecdn',
14
+ 'third-party',
15
+ 'scapi',
16
+ 'scapi-hooks',
17
+ 'mrt',
18
+ 'controller',
19
+ 'ocapi',
20
+ ];
21
+ /**
22
+ * How far back the Metrics API retains data: `from` must be no older than
23
+ * `serverNow - 30 days`, or the API returns 400.
24
+ */
25
+ export const METRICS_RETENTION_MS = 30 * 24 * 60 * 60 * 1000;
26
+ /**
27
+ * Default (and maximum) width of a metrics time window: 24 hours.
28
+ *
29
+ * The Metrics API pairs a request that omits `to` with its own `now` and then
30
+ * enforces a maximum window of `to - from ≤ 24h`, rejecting anything wider with a
31
+ * 400. An open-ended `from` older than 24h therefore always fails. To make the
32
+ * behavior predictable, {@link resolveMetricsWindow} fills in a 24-hour window
33
+ * (clamped so `to` never exceeds `now`) for any bound the caller leaves open, and
34
+ * always sends both `from` and `to`. This is only a *default* for derivation — an
35
+ * explicit `from`+`to` range wider than 24h is still sent as-is, letting the API
36
+ * remain authoritative and return its own error.
37
+ */
38
+ export const METRICS_DEFAULT_WINDOW_MS = 24 * 60 * 60 * 1000;
39
+ /**
40
+ * Safety margin kept *inside* the retention window when clamping `from`. Because
41
+ * the server evaluates retention against its own clock at request time, a `from`
42
+ * computed as exactly "30 days ago" on the client is reliably rejected once
43
+ * request latency and client/server clock skew are added. {@link resolveMetricsWindow}
44
+ * therefore clamps a `from` that lands within this margin of the retention floor
45
+ * up to `now - 30 days + margin`, so edge requests (e.g. `--from 30d`) succeed.
46
+ * 5 minutes comfortably covers latency and typical skew while costing a
47
+ * negligible fraction of the 30-day window.
48
+ */
49
+ export const METRICS_RETENTION_SAFETY_MARGIN_MS = 5 * 60 * 1000;
50
+ /**
51
+ * Parses a single metrics time bound (`from` or `to`) into a {@link Date}.
52
+ *
53
+ * This is the shared bound parser for the CLI `metrics get` command and the MCP
54
+ * `metrics_get` tool. It resolves a single bound in isolation; deriving the
55
+ * companion bound and applying the 24-hour default window is the job of
56
+ * {@link resolveMetricsWindow}.
57
+ *
58
+ * @param value - The bound: a Date, epoch milliseconds, a relative duration
59
+ * (`5m`/`1h`/`2d`, relative to `now`), or an ISO 8601 timestamp
60
+ * @param now - Reference time for relative durations (defaults to the current
61
+ * time; injectable for deterministic tests)
62
+ * @returns The resolved {@link Date}
63
+ * @throws TypeError if a string value is neither a valid relative duration nor
64
+ * a parseable ISO 8601 timestamp
65
+ *
66
+ * @example
67
+ * ```typescript
68
+ * const from = parseMetricsBound('2d'); // 2 days ago
69
+ * const to = parseMetricsBound('2026-01-25T12:00:00Z');
70
+ * await getSalesMetrics(client, tenantId, {from, to});
71
+ * ```
72
+ */
73
+ export function parseMetricsBound(value, now = new Date()) {
74
+ if (value instanceof Date)
75
+ return value;
76
+ if (typeof value === 'number')
77
+ return new Date(value);
78
+ return parseSinceTime(value, now);
79
+ }
80
+ /**
81
+ * Parses a `--window`/`--for` duration into milliseconds. Accepts a relative
82
+ * string (`1h`, `30m`, `2d`) or a raw number of milliseconds.
83
+ *
84
+ * @throws TypeError if a string is not a valid relative duration
85
+ */
86
+ function parseWindowMs(window) {
87
+ if (typeof window === 'number')
88
+ return window;
89
+ const ms = parseRelativeTime(window);
90
+ if (ms === null) {
91
+ throw new TypeError(`Invalid window duration: "${window}". Use a relative duration like "30m", "1h", or "2d".`);
92
+ }
93
+ return ms;
94
+ }
95
+ /**
96
+ * Resolves `from`/`to`/`window` inputs into the concrete bounds to send to the
97
+ * Metrics API. This is the shared resolver for the CLI `metrics get` command and
98
+ * the MCP `metrics_get` tool, so both share identical, tested semantics.
99
+ *
100
+ * The resolver always produces an explicit `from`+`to` pair. The Metrics API
101
+ * pairs a request that omits `to` with its own `now` and enforces a 24-hour
102
+ * maximum window, so an open-ended `from` older than 24 hours always fails; to
103
+ * make the behavior predictable, any bound the caller leaves open is filled from
104
+ * the 24-hour default window (see {@link METRICS_DEFAULT_WINDOW_MS}) rather than
105
+ * relying on the server's implicit end.
106
+ *
107
+ * The `window` duration makes fixed-width lookbacks easy without hand-computing
108
+ * a second timestamp — e.g. "a 1-hour window starting 7 days ago" is
109
+ * `{from: '7d', window: '1h'}`. Resolution rules:
110
+ *
111
+ * - `from` + `to` — used as given; `window` must NOT also be set. An explicit
112
+ * range wider than the 24-hour maximum is still sent as-is, leaving the API to
113
+ * return its own error.
114
+ * - `from` + `window` — `to = from + window`.
115
+ * - `to` + `window` — `from = to - window`.
116
+ * - `window` only — the last `window`: `to = now`, `from = now - window`.
117
+ * - `from` only — a 24-hour window forward from `from`: `to = min(from + 24h, now)`.
118
+ * - `to` only — a 24-hour window back from `to`: `from = to - 24h`.
119
+ * - nothing — the last 24 hours: `to = now`, `from = now - 24h`.
120
+ *
121
+ * Bounds filled from the 24-hour default (the last three rules) set
122
+ * {@link ResolvedMetricsWindow.defaultedWindow}. Validation is structural
123
+ * (over-specification and `from` after `to`). Additionally, a `from` that lands
124
+ * at or beyond the 30-day retention floor is clamped *forward* to
125
+ * `now - 30 days + margin` (see {@link METRICS_RETENTION_SAFETY_MARGIN_MS}) so
126
+ * requests like `--from 30d` are not rejected by the server's own slightly-later
127
+ * clock; the clamp is applied before deriving the companion bound so the window
128
+ * width is preserved, only ever moves `from` toward `now`, and is reported via
129
+ * {@link ResolvedMetricsWindow.clampedFrom}.
130
+ *
131
+ * @param input - The raw `from`/`to`/`window` inputs
132
+ * @param now - Reference time for relative bounds, default/window modes, and the
133
+ * retention clamp (defaults to the current time; injectable for deterministic tests)
134
+ * @returns The resolved bounds plus ISO/epoch-second echoes and clamp/default flags
135
+ * @throws TypeError if a bound or the window string is unparseable
136
+ * @throws RangeError if all three are supplied, or the resolved `from` is after `to`
137
+ *
138
+ * @example
139
+ * ```typescript
140
+ * // A 1-hour window starting 7 days ago:
141
+ * const w = resolveMetricsWindow({from: '7d', window: '1h'});
142
+ * await getScapiMetrics(client, tenantId, {from: w.from, to: w.to});
143
+ * ```
144
+ */
145
+ export function resolveMetricsWindow(input = {}, now = new Date()) {
146
+ const hasFrom = input.from !== undefined && input.from !== '';
147
+ const hasTo = input.to !== undefined && input.to !== '';
148
+ const hasWindow = input.window !== undefined && input.window !== '';
149
+ if (hasFrom && hasTo && hasWindow) {
150
+ throw new RangeError('Specify at most two of from, to, and window — not all three.');
151
+ }
152
+ // Clamp a `from` forward if it predates the retention floor, to survive the
153
+ // server evaluating retention against its own (slightly later) clock. Only
154
+ // ever moves `from` toward `now`, never fetches out-of-range data.
155
+ const earliestSafe = now.getTime() - METRICS_RETENTION_MS + METRICS_RETENTION_SAFETY_MARGIN_MS;
156
+ let clampedFrom = false;
157
+ const clampFrom = (d) => {
158
+ if (d.getTime() < earliestSafe) {
159
+ clampedFrom = true;
160
+ return new Date(earliestSafe);
161
+ }
162
+ return d;
163
+ };
164
+ // Clamp a provided `from` up front so a window derived from it stays inside
165
+ // retention (and a full-width window fits).
166
+ let from = hasFrom ? clampFrom(parseMetricsBound(input.from, now)) : undefined;
167
+ let to = hasTo ? parseMetricsBound(input.to, now) : undefined;
168
+ let defaultedWindow = false;
169
+ if (hasWindow) {
170
+ const windowMs = parseWindowMs(input.window);
171
+ if (from && !to) {
172
+ to = new Date(from.getTime() + windowMs);
173
+ }
174
+ else if (to && !from) {
175
+ from = new Date(to.getTime() - windowMs);
176
+ }
177
+ else {
178
+ // window alone → the last {window}
179
+ to = now;
180
+ from = new Date(now.getTime() - windowMs);
181
+ }
182
+ }
183
+ else if (!(from && to)) {
184
+ // No explicit window and at least one bound open → fill it from the 24-hour
185
+ // default window, sending an explicit range instead of relying on the
186
+ // server's implicit `to = now` + 24h-maximum behavior.
187
+ defaultedWindow = true;
188
+ if (from && !to) {
189
+ // A window forward from `from`, but never past `now` (no future data).
190
+ to = new Date(Math.min(from.getTime() + METRICS_DEFAULT_WINDOW_MS, now.getTime()));
191
+ }
192
+ else if (to && !from) {
193
+ from = new Date(to.getTime() - METRICS_DEFAULT_WINDOW_MS);
194
+ }
195
+ else {
196
+ // Nothing supplied → the last 24 hours.
197
+ to = now;
198
+ from = new Date(now.getTime() - METRICS_DEFAULT_WINDOW_MS);
199
+ }
200
+ }
201
+ // A `from` derived from `to` (via window or the default) may itself predate
202
+ // retention; clamp it forward too. Idempotent for an already-clamped bound.
203
+ from = clampFrom(from);
204
+ if (from.getTime() > to.getTime()) {
205
+ throw new RangeError(`Invalid time window: from (${from.toISOString()}) must be before to (${to.toISOString()}).`);
206
+ }
207
+ return {
208
+ from: from,
209
+ to: to,
210
+ fromIso: from.toISOString(),
211
+ toIso: to.toISOString(),
212
+ fromEpochSeconds: toEpochSeconds(from),
213
+ toEpochSeconds: toEpochSeconds(to),
214
+ clampedFrom,
215
+ defaultedWindow,
216
+ };
217
+ }
218
+ /**
219
+ * Converts a millisecond time input ({@link Date} or epoch ms) to the epoch
220
+ * **seconds** the Metrics API expects on the wire.
221
+ */
222
+ function toEpochSeconds(value) {
223
+ const ms = value instanceof Date ? value.getTime() : value;
224
+ return Math.floor(ms / 1000);
225
+ }
226
+ /**
227
+ * Normalizes an optional time-window into the query object openapi-fetch expects.
228
+ * Converts millisecond inputs to epoch seconds and drops undefined values so they
229
+ * are not serialized.
230
+ */
231
+ function timeWindowQuery(options) {
232
+ const query = {};
233
+ if (options?.from !== undefined)
234
+ query.from = toEpochSeconds(options.from);
235
+ if (options?.to !== undefined)
236
+ query.to = toEpochSeconds(options.to);
237
+ return query;
238
+ }
239
+ /**
240
+ * Normalizes a successful metrics response for JS consumers: rewrites every data
241
+ * point timestamp from the API's epoch **seconds** to epoch **milliseconds** so
242
+ * that `new Date(point.timestamp)` yields the correct instant. Returns a new
243
+ * response object; the input is not mutated.
244
+ */
245
+ function normalizeResponse(data) {
246
+ return {
247
+ ...data,
248
+ data: (data.data ?? []).map((metric) => ({
249
+ ...metric,
250
+ dataSeries: (metric.dataSeries ?? []).map((series) => ({
251
+ ...series,
252
+ data: (series.data ?? []).map((point) => ({ ...point, timestamp: point.timestamp * 1000 })),
253
+ })),
254
+ })),
255
+ };
256
+ }
257
+ /**
258
+ * Wraps a failed metrics request in a descriptive Error.
259
+ */
260
+ function metricsError(category, error, response) {
261
+ return new Error(`Failed to get ${category} metrics: ${getApiErrorMessage(error, response)}`, { cause: error });
262
+ }
263
+ /**
264
+ * Retrieves overall application metrics for an organization.
265
+ *
266
+ * @param client - Metrics API client from {@link createMetricsClient}
267
+ * @param tenantId - Tenant ID (with or without the `f_ecom_` prefix)
268
+ * @param options - Optional time window (epoch milliseconds)
269
+ * @returns The metrics data response
270
+ * @throws Error if the request fails
271
+ */
272
+ export async function getOverallMetrics(client, tenantId, options) {
273
+ getLogger().debug({ tenantId, options }, 'Fetching overall metrics');
274
+ const { data, error, response } = await client.GET('/organizations/{organizationId}/metrics/overall', {
275
+ params: { path: { organizationId: toOrganizationId(tenantId) }, query: timeWindowQuery(options) },
276
+ });
277
+ if (error || !data)
278
+ throw metricsError('overall', error, response);
279
+ return normalizeResponse(data);
280
+ }
281
+ /**
282
+ * Retrieves sales metrics for an organization.
283
+ *
284
+ * @param client - Metrics API client from {@link createMetricsClient}
285
+ * @param tenantId - Tenant ID (with or without the `f_ecom_` prefix)
286
+ * @param options - Optional time window (epoch milliseconds)
287
+ * @returns The metrics data response
288
+ * @throws Error if the request fails
289
+ */
290
+ export async function getSalesMetrics(client, tenantId, options) {
291
+ getLogger().debug({ tenantId, options }, 'Fetching sales metrics');
292
+ const { data, error, response } = await client.GET('/organizations/{organizationId}/metrics/sales', {
293
+ params: { path: { organizationId: toOrganizationId(tenantId) }, query: timeWindowQuery(options) },
294
+ });
295
+ if (error || !data)
296
+ throw metricsError('sales', error, response);
297
+ return normalizeResponse(data);
298
+ }
299
+ /**
300
+ * Retrieves embedded CDN (eCDN) metrics for an organization.
301
+ *
302
+ * @param client - Metrics API client from {@link createMetricsClient}
303
+ * @param tenantId - Tenant ID (with or without the `f_ecom_` prefix)
304
+ * @param options - Optional time window (epoch milliseconds)
305
+ * @returns The metrics data response
306
+ * @throws Error if the request fails
307
+ */
308
+ export async function getEcdnMetrics(client, tenantId, options) {
309
+ getLogger().debug({ tenantId, options }, 'Fetching ecdn metrics');
310
+ const { data, error, response } = await client.GET('/organizations/{organizationId}/metrics/ecdn', {
311
+ params: { path: { organizationId: toOrganizationId(tenantId) }, query: timeWindowQuery(options) },
312
+ });
313
+ if (error || !data)
314
+ throw metricsError('ecdn', error, response);
315
+ return normalizeResponse(data);
316
+ }
317
+ /**
318
+ * Retrieves third-party service call metrics for an organization.
319
+ *
320
+ * @param client - Metrics API client from {@link createMetricsClient}
321
+ * @param tenantId - Tenant ID (with or without the `f_ecom_` prefix)
322
+ * @param options - Optional time window and `thirdPartyServiceId` filter
323
+ * @returns The metrics data response
324
+ * @throws Error if the request fails
325
+ */
326
+ export async function getThirdPartyMetrics(client, tenantId, options) {
327
+ getLogger().debug({ tenantId, options }, 'Fetching third-party metrics');
328
+ const { data, error, response } = await client.GET('/organizations/{organizationId}/metrics/third-party', {
329
+ params: {
330
+ path: { organizationId: toOrganizationId(tenantId) },
331
+ query: { ...timeWindowQuery(options), thirdPartyServiceId: options?.thirdPartyServiceId },
332
+ },
333
+ });
334
+ if (error || !data)
335
+ throw metricsError('third-party', error, response);
336
+ return normalizeResponse(data);
337
+ }
338
+ /**
339
+ * Retrieves SCAPI request metrics for an organization.
340
+ *
341
+ * @param client - Metrics API client from {@link createMetricsClient}
342
+ * @param tenantId - Tenant ID (with or without the `f_ecom_` prefix)
343
+ * @param options - Optional time window and `apiFamily`/`apiName` filters
344
+ * @returns The metrics data response
345
+ * @throws Error if the request fails
346
+ */
347
+ export async function getScapiMetrics(client, tenantId, options) {
348
+ getLogger().debug({ tenantId, options }, 'Fetching scapi metrics');
349
+ const { data, error, response } = await client.GET('/organizations/{organizationId}/metrics/scapi', {
350
+ params: {
351
+ path: { organizationId: toOrganizationId(tenantId) },
352
+ query: { ...timeWindowQuery(options), apiFamily: options?.apiFamily, apiName: options?.apiName },
353
+ },
354
+ });
355
+ if (error || !data)
356
+ throw metricsError('scapi', error, response);
357
+ return normalizeResponse(data);
358
+ }
359
+ /**
360
+ * Retrieves SCAPI hook execution metrics for an organization.
361
+ *
362
+ * @param client - Metrics API client from {@link createMetricsClient}
363
+ * @param tenantId - Tenant ID (with or without the `f_ecom_` prefix)
364
+ * @param options - Optional time window (epoch milliseconds)
365
+ * @returns The metrics data response
366
+ * @throws Error if the request fails
367
+ */
368
+ export async function getScapiHooksMetrics(client, tenantId, options) {
369
+ getLogger().debug({ tenantId, options }, 'Fetching scapi-hooks metrics');
370
+ const { data, error, response } = await client.GET('/organizations/{organizationId}/metrics/scapi-hooks', {
371
+ params: { path: { organizationId: toOrganizationId(tenantId) }, query: timeWindowQuery(options) },
372
+ });
373
+ if (error || !data)
374
+ throw metricsError('scapi-hooks', error, response);
375
+ return normalizeResponse(data);
376
+ }
377
+ /**
378
+ * Retrieves Managed Runtime (MRT) metrics for an organization.
379
+ *
380
+ * @param client - Metrics API client from {@link createMetricsClient}
381
+ * @param tenantId - Tenant ID (with or without the `f_ecom_` prefix)
382
+ * @param options - Optional time window (epoch milliseconds)
383
+ * @returns The metrics data response
384
+ * @throws Error if the request fails
385
+ */
386
+ export async function getMrtMetrics(client, tenantId, options) {
387
+ getLogger().debug({ tenantId, options }, 'Fetching mrt metrics');
388
+ const { data, error, response } = await client.GET('/organizations/{organizationId}/metrics/mrt', {
389
+ params: { path: { organizationId: toOrganizationId(tenantId) }, query: timeWindowQuery(options) },
390
+ });
391
+ if (error || !data)
392
+ throw metricsError('mrt', error, response);
393
+ return normalizeResponse(data);
394
+ }
395
+ /**
396
+ * Retrieves controller/pipeline metrics for an organization.
397
+ *
398
+ * @param client - Metrics API client from {@link createMetricsClient}
399
+ * @param tenantId - Tenant ID (with or without the `f_ecom_` prefix)
400
+ * @param options - Optional time window (epoch milliseconds)
401
+ * @returns The metrics data response
402
+ * @throws Error if the request fails
403
+ */
404
+ export async function getControllerMetrics(client, tenantId, options) {
405
+ getLogger().debug({ tenantId, options }, 'Fetching controller metrics');
406
+ const { data, error, response } = await client.GET('/organizations/{organizationId}/metrics/controller', {
407
+ params: { path: { organizationId: toOrganizationId(tenantId) }, query: timeWindowQuery(options) },
408
+ });
409
+ if (error || !data)
410
+ throw metricsError('controller', error, response);
411
+ return normalizeResponse(data);
412
+ }
413
+ /**
414
+ * Retrieves OCAPI request metrics for an organization.
415
+ *
416
+ * @param client - Metrics API client from {@link createMetricsClient}
417
+ * @param tenantId - Tenant ID (with or without the `f_ecom_` prefix)
418
+ * @param options - Optional time window and `ocapiCategory`/`ocapiApi` filters
419
+ * @returns The metrics data response
420
+ * @throws Error if the request fails
421
+ */
422
+ export async function getOcapiMetrics(client, tenantId, options) {
423
+ getLogger().debug({ tenantId, options }, 'Fetching ocapi metrics');
424
+ const { data, error, response } = await client.GET('/organizations/{organizationId}/metrics/ocapi', {
425
+ params: {
426
+ path: { organizationId: toOrganizationId(tenantId) },
427
+ query: { ...timeWindowQuery(options), ocapiCategory: options?.ocapiCategory, ocapiApi: options?.ocapiApi },
428
+ },
429
+ });
430
+ if (error || !data)
431
+ throw metricsError('ocapi', error, response);
432
+ return normalizeResponse(data);
433
+ }
434
+ /**
435
+ * Retrieves metrics for a category by name, dispatching to the category-specific
436
+ * function. Category-specific filters (`thirdPartyServiceId`, `apiFamily`,
437
+ * `apiName`, `ocapiCategory`, `ocapiApi`) are applied only for the categories
438
+ * that support them and ignored otherwise.
439
+ *
440
+ * @param client - Metrics API client from {@link createMetricsClient}
441
+ * @param tenantId - Tenant ID (with or without the `f_ecom_` prefix)
442
+ * @param category - One of {@link METRIC_CATEGORIES}
443
+ * @param options - Optional time window and category-specific filters
444
+ * @returns The metrics data response
445
+ * @throws Error if the request fails or the category is unknown
446
+ */
447
+ export async function getMetricsByCategory(client, tenantId, category, options) {
448
+ switch (category) {
449
+ case 'overall':
450
+ return getOverallMetrics(client, tenantId, options);
451
+ case 'sales':
452
+ return getSalesMetrics(client, tenantId, options);
453
+ case 'ecdn':
454
+ return getEcdnMetrics(client, tenantId, options);
455
+ case 'third-party':
456
+ return getThirdPartyMetrics(client, tenantId, options);
457
+ case 'scapi':
458
+ return getScapiMetrics(client, tenantId, options);
459
+ case 'scapi-hooks':
460
+ return getScapiHooksMetrics(client, tenantId, options);
461
+ case 'mrt':
462
+ return getMrtMetrics(client, tenantId, options);
463
+ case 'controller':
464
+ return getControllerMetrics(client, tenantId, options);
465
+ case 'ocapi':
466
+ return getOcapiMetrics(client, tenantId, options);
467
+ default: {
468
+ // Exhaustiveness guard: if a new category is added to METRIC_CATEGORIES
469
+ // without a case here, this line fails to compile.
470
+ const exhaustive = category;
471
+ throw new Error(`Unknown metric category: ${String(exhaustive)}`);
472
+ }
473
+ }
474
+ }
475
+ // Client-side dimension/tag extraction for series (interim until the API
476
+ // exposes structured tags server-side). See ./tags.ts.
477
+ export { parseSeriesTags, enrichMetricsTags } from './tags.js';
478
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/operations/metrics/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,148 @@
1
+ /**
2
+ * Client-side dimension extraction for Metrics API series.
3
+ *
4
+ * The Metrics API returns each series as `{id, name, data}`, where `id`/`name`
5
+ * pack every identifying dimension into a single display string using
6
+ * inconsistent delimiters — e.g. `bdpx.product` (realm `.` apiFamily),
7
+ * `bdpx.product HIT` (realm `.` family ` ` cacheStatus), `2xx bdpx.host` (status
8
+ * class *before* the realm), or `bdpx.host.socketReadTimeout` (realm `.` host —
9
+ * whose own dots are ambiguous — `.` exceptionType). This makes the strings
10
+ * effectively unparseable in general and awkward to chart, group, or merge
11
+ * across realms.
12
+ *
13
+ * This module derives a structured, InfluxDB/Prometheus-style `tags` map for
14
+ * each series so consumers (dashboards, a Grafana plugin, ad-hoc analysis) can
15
+ * group and filter by dimension instead of regexing display strings. Two design
16
+ * rules keep it robust:
17
+ *
18
+ * 1. **Identity comes from the request, not the string.** `realm` and
19
+ * `environment` are derived from the tenant/organization the request targeted
20
+ * (`f_ecom_bdpx_prd` → `realm=bdpx`, `environment=prd`), never scraped from
21
+ * the packed id. This is reliable regardless of the id's delimiter soup and
22
+ * correctly distinguishes the *org's* environment from, say, eCDN hosts that
23
+ * span dev/stg/prod within a single prod request.
24
+ * 2. **Never throw, never drop data.** An id that matches no known pattern still
25
+ * gets `{realm, environment}` plus the unrecognized remainder under `series`,
26
+ * so enrichment only ever adds information.
27
+ *
28
+ * This is an interim client-side convenience. The intent is for the Metrics API
29
+ * to expose a `tags` object on each series server-side; when it does, this layer
30
+ * becomes a thin fallback (or is retired).
31
+ *
32
+ * @module operations/metrics/tags
33
+ */
34
+ import type { MetricsDataResponse } from '../../clients/metrics.js';
35
+ import type { MetricCategory } from './index.js';
36
+ /**
37
+ * A flat map of a series' identifying dimensions (string → string), following
38
+ * the InfluxDB/Prometheus/CloudWatch "tag"/"label"/"dimension" convention.
39
+ *
40
+ * Always contains `realm` and `environment` (derived from the request context).
41
+ * Category-specific keys (`apiFamily`, `host`, `cacheStatus`, `statusClass`,
42
+ * `ocapiCategory`, `controller`, `exceptionType`) are added when recognized. A
43
+ * rollup/aggregation series carries `aggregation` (a *statistic*, not a
44
+ * dimension — kept distinct so consumers can separate "how it was computed" from
45
+ * "what it describes"). An unrecognized remainder is preserved under `series`.
46
+ */
47
+ export type MetricSeriesTags = Record<string, string>;
48
+ /**
49
+ * The request identity and applied filters used to derive authoritative tags.
50
+ *
51
+ * `realm`/`environment` are parsed from `tenantId`. The optional filter fields
52
+ * mirror the Metrics API's category filters; when a filter was sent, that
53
+ * dimension is *known from the request* and is stamped onto every series as an
54
+ * authoritative tag — rather than being (mis)parsed from a drilled-down series
55
+ * id. For example, requesting `apiFamily=shopper` makes the server return
56
+ * finer-grained ids like `bdpx.shopper.auth.v1`; folding the filter in yields the
57
+ * correct `apiFamily: "shopper"` instead of the string-parser's wrong
58
+ * `apiFamily: "shopper.auth.v1"`.
59
+ */
60
+ export interface MetricsTagContext {
61
+ /** Tenant or organization id the request targeted (with or without `f_ecom_`). */
62
+ tenantId: string;
63
+ /** The `apiFamily` filter sent with a scapi request, if any. */
64
+ apiFamily?: string;
65
+ /** The `apiName` filter sent with a scapi request, if any. */
66
+ apiName?: string;
67
+ /** The `ocapiCategory` filter sent with an ocapi request, if any. */
68
+ ocapiCategory?: string;
69
+ /** The `ocapiApi` filter sent with an ocapi request, if any. */
70
+ ocapiApi?: string;
71
+ /** The `thirdPartyServiceId` filter sent with a third-party request, if any. */
72
+ thirdPartyServiceId?: string;
73
+ }
74
+ /**
75
+ * Extracts the dimension tags for a single series id.
76
+ *
77
+ * Combines three tiers, most-authoritative last:
78
+ * 1. **Request identity** — `realm`/`environment` from the tenant id (never parsed
79
+ * from the series string).
80
+ * 2. **String heuristics** — category/metric-specific dimensions parsed from the
81
+ * packed id (`apiFamily`, `host`, `cacheStatus`, …), or the raw remainder under
82
+ * `series` when no rule matches.
83
+ * 3. **Applied filters** — any filter that was sent with the request
84
+ * ({@link MetricsTagContext}) is stamped last, overriding a heuristic guess.
85
+ * This corrects drill-down ids: with `apiFamily=shopper` the server returns
86
+ * `bdpx.shopper.auth.v1`, which heuristics would mis-tag as
87
+ * `apiFamily: "shopper.auth.v1"`; the filter restores `apiFamily: "shopper"`.
88
+ *
89
+ * The result is always a superset of the request context and never throws.
90
+ *
91
+ * @param params - The series' category, metric id, series id, and request context
92
+ * @returns The extracted {@link MetricSeriesTags}
93
+ *
94
+ * @example
95
+ * ```typescript
96
+ * parseSeriesTags({
97
+ * category: 'scapi', metricId: 'cacheHitRate',
98
+ * seriesId: 'bdpx.product HIT', context: {tenantId: 'f_ecom_bdpx_prd'},
99
+ * });
100
+ * // → { realm: 'bdpx', environment: 'prd', apiFamily: 'product', cacheStatus: 'HIT' }
101
+ * ```
102
+ */
103
+ export declare function parseSeriesTags(params: {
104
+ category: MetricCategory;
105
+ metricId: string;
106
+ seriesId: string;
107
+ context: MetricsTagContext;
108
+ }): MetricSeriesTags;
109
+ /**
110
+ * Enriches a metrics response by adding a structured `tags` map to every series,
111
+ * in place-safe fashion (returns a new response; the input is not mutated).
112
+ *
113
+ * This is the batch counterpart to {@link parseSeriesTags}: it walks every
114
+ * metric and series and attaches `series.tags` derived from the series id, the
115
+ * metric id, the category, and the request context. Existing fields (`id`,
116
+ * `name`, `data`) are preserved exactly, so the enriched response is a
117
+ * structural superset — consumers that ignore `tags` are unaffected. The
118
+ * category must be supplied because a {@link MetricsDataResponse} does not carry
119
+ * it (it is implied by the endpoint that produced the response).
120
+ *
121
+ * @param response - The metrics response to enrich
122
+ * @param category - The metric category the response was fetched for
123
+ * @param context - The request identity used to derive `realm`/`environment`
124
+ * @returns A new response with `tags` added to each series
125
+ *
126
+ * @example
127
+ * ```typescript
128
+ * const raw = await getScapiMetrics(client, tenantId);
129
+ * const enriched = enrichMetricsTags(raw, 'scapi', {tenantId});
130
+ * for (const metric of enriched.data) {
131
+ * for (const series of metric.dataSeries) {
132
+ * console.log(series.tags, series.data);
133
+ * }
134
+ * }
135
+ * ```
136
+ */
137
+ export declare function enrichMetricsTags(response: MetricsDataResponse, category: MetricCategory, context: MetricsTagContext): MetricsTaggedResponse;
138
+ /**
139
+ * A metrics response whose series carry the structured {@link MetricSeriesTags}.
140
+ * Structurally a superset of {@link MetricsDataResponse}.
141
+ */
142
+ export interface MetricsTaggedResponse extends MetricsDataResponse {
143
+ data: Array<MetricsDataResponse['data'][number] & {
144
+ dataSeries: Array<MetricsDataResponse['data'][number]['dataSeries'][number] & {
145
+ tags: MetricSeriesTags;
146
+ }>;
147
+ }>;
148
+ }