@camunda/ccma-api 5.4.0 → 5.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,41 @@
1
+ import { request } from "../../utils/api.js";
2
+ import { HttpError } from "../../utils/errors.js";
3
+ class AccountsLogsService {
4
+ /**
5
+ * The machine-to-machine tokens that were taken for each cluster in the
6
+ * range, one row for each cluster, and whether the read of the Auth0 log
7
+ * stopped before the end of the range. See `M2mTokenCountsDto`.
8
+ */
9
+ static async getM2mTokenCounts(params) {
10
+ const serviceContext = {
11
+ method: {
12
+ name: "AccountsLogsService.getM2mTokenCounts",
13
+ url: `api/logs/clients/tokens/count?rangeInHours=${encodeURIComponent(params.params.rangeInHours)}`,
14
+ normalizedUrl: "api/logs/clients/tokens/count",
15
+ type: "get"
16
+ },
17
+ source: params.config.metrics?.source || "unset",
18
+ target: { name: "accounts", type: "internal" }
19
+ };
20
+ const response = await request({
21
+ config: params.config,
22
+ base: { id: "accounts" },
23
+ url: serviceContext.method.url,
24
+ method: serviceContext.method.type,
25
+ metricsDetails: serviceContext,
26
+ responseType: "json"
27
+ });
28
+ if (!response.ok) {
29
+ throw new HttpError(
30
+ `${serviceContext.method.name}: ${response.status} ${response.statusText}`,
31
+ response.status,
32
+ response.statusText
33
+ );
34
+ }
35
+ return response.body ?? { clusters: [], counted: 0, total: 0, truncated: false };
36
+ }
37
+ }
38
+ export {
39
+ AccountsLogsService
40
+ };
41
+ //# sourceMappingURL=logs.service.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/services/accounts/logs.service.ts"],
4
+ "sourcesContent": ["/*\n * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH\n * under one or more contributor license agreements. Licensed under a commercial license.\n * You may not use this file except in compliance with the commercial license.\n */\n\nimport type { M2mTokenCountsDto } from '@camunda/ccma-shared-types'\nimport type {\n RequestBaseParams,\n RequestBaseServiceContext,\n} from '../../types/general.types.js'\nimport { request } from '../../utils/api.js'\nimport { HttpError } from '../../utils/errors.js'\n\nexport interface GetM2mTokenCountsRequest extends RequestBaseParams {\n params: {\n /** How far back the Auth0 log is read, in hours. The accounts tool read 24. */\n rangeInHours: number\n }\n}\n\n/**\n * The log reads of accounts-backend (`api/logs`). They answer to\n * `admin.readAll` only.\n */\nexport class AccountsLogsService {\n /**\n * The machine-to-machine tokens that were taken for each cluster in the\n * range, one row for each cluster, and whether the read of the Auth0 log\n * stopped before the end of the range. See `M2mTokenCountsDto`.\n */\n public static async getM2mTokenCounts(\n params: GetM2mTokenCountsRequest,\n ): Promise<M2mTokenCountsDto> {\n const serviceContext: RequestBaseServiceContext = {\n method: {\n name: 'AccountsLogsService.getM2mTokenCounts',\n url: `api/logs/clients/tokens/count?rangeInHours=${encodeURIComponent(params.params.rangeInHours)}`,\n normalizedUrl: 'api/logs/clients/tokens/count',\n type: 'get',\n },\n source: params.config.metrics?.source || 'unset',\n target: { name: 'accounts', type: 'internal' },\n }\n const response = await request<M2mTokenCountsDto>({\n config: params.config,\n base: { id: 'accounts' },\n url: serviceContext.method.url,\n method: serviceContext.method.type,\n metricsDetails: serviceContext,\n responseType: 'json',\n })\n if (!response.ok) {\n throw new HttpError(\n `${serviceContext.method.name}: ${response.status} ${response.statusText}`,\n response.status,\n response.statusText,\n )\n }\n return (\n response.body ?? { clusters: [], counted: 0, total: 0, truncated: false }\n )\n }\n}\n"],
5
+ "mappings": "AAWA,SAAS,eAAe;AACxB,SAAS,iBAAiB;AAanB,MAAM,oBAAoB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAM/B,aAAoB,kBAClB,QAC4B;AAC5B,UAAM,iBAA4C;AAAA,MAChD,QAAQ;AAAA,QACN,MAAM;AAAA,QACN,KAAK,8CAA8C,mBAAmB,OAAO,OAAO,YAAY,CAAC;AAAA,QACjG,eAAe;AAAA,QACf,MAAM;AAAA,MACR;AAAA,MACA,QAAQ,OAAO,OAAO,SAAS,UAAU;AAAA,MACzC,QAAQ,EAAE,MAAM,YAAY,MAAM,WAAW;AAAA,IAC/C;AACA,UAAM,WAAW,MAAM,QAA2B;AAAA,MAChD,QAAQ,OAAO;AAAA,MACf,MAAM,EAAE,IAAI,WAAW;AAAA,MACvB,KAAK,eAAe,OAAO;AAAA,MAC3B,QAAQ,eAAe,OAAO;AAAA,MAC9B,gBAAgB;AAAA,MAChB,cAAc;AAAA,IAChB,CAAC;AACD,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,IAAI;AAAA,QACR,GAAG,eAAe,OAAO,IAAI,KAAK,SAAS,MAAM,IAAI,SAAS,UAAU;AAAA,QACxE,SAAS;AAAA,QACT,SAAS;AAAA,MACX;AAAA,IACF;AACA,WACE,SAAS,QAAQ,EAAE,UAAU,CAAC,GAAG,SAAS,GAAG,OAAO,GAAG,WAAW,MAAM;AAAA,EAE5E;AACF;",
6
+ "names": []
7
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -1,4 +1,4 @@
1
- import type { AlertSubscriptionDto, BackupDto, BackupScheduleDto, ByomClientDto, ByomStatus, ClusterBulkOperationAck, ClusterBulkOperationDto, ClusterBulkOperationPostContent, ClusterModificationConfigDto, ClusterModificationDto, ClusterPlanTypeDto, ClusterTtlDto, ClusterUsageMetricsData, ConsoleClusterDto, UniqueTaskUser, UpdateClusterTtlBody, ValueMetrics } from '@camunda/ccma-shared-types';
1
+ import type { AlertSubscriptionDto, BackupDto, BackupScheduleDto, ByomClientDto, ByomStatus, ClusterBulkOperationAck, ClusterBulkOperationDto, ClusterBulkOperationPostContent, ClusterModificationConfigDto, ClusterModificationDto, ClusterPlanTypeDto, ClusterTtlDto, ClusterUsageMetadataDto, ClusterUsageMetricsData, ConsoleClusterDto, UniqueTaskUser, UpdateClusterTtlBody, ValueMetrics } from '@camunda/ccma-shared-types';
2
2
  import type { RequestBaseParams } from '../../types/general.types.js';
3
3
  import type { OpenIncident } from '../incident-io/incident-io.service.js';
4
4
  import type { ConsoleClusterClientDto } from './console.cluster-clients.service.js';
@@ -219,6 +219,18 @@ export interface GetValueMetricsUsageDataRequest extends RequestBaseParams {
219
219
  };
220
220
  };
221
221
  }
222
+ export interface GetValueMetricsUsageDataPerDayRequest extends RequestBaseParams {
223
+ params: {
224
+ orgId: string;
225
+ /** How many days back from now the read covers. */
226
+ days: number;
227
+ };
228
+ }
229
+ export interface GetValueMetricsMetadataRequest extends RequestBaseParams {
230
+ params: {
231
+ orgId: string;
232
+ };
233
+ }
222
234
  export interface GetValueMetricsRequest extends RequestBaseParams {
223
235
  params: {
224
236
  orgId: string;
@@ -319,6 +331,18 @@ export interface AdminClusterNonSpotNodesRequest extends RequestBaseParams {
319
331
  nonSpotNodesEnabled: boolean;
320
332
  };
321
333
  }
334
+ /** What `GET api/admin/clusters/modifications` answers. */
335
+ export interface ModificationsAnswer {
336
+ clusters: ConsoleClusterDto[];
337
+ modifications: ClusterModificationDto[];
338
+ }
339
+ /**
340
+ * How many cluster ids one GET of the modifications carries in its query.
341
+ *
342
+ * 50 uuids are about 1.9 KB of request line, well under the 8 KB that the
343
+ * ingress and node accept. The bound is on the request, not on the answer.
344
+ */
345
+ export declare const CLUSTER_UUIDS_PER_READ = 50;
322
346
  export declare class ConsoleAdminService {
323
347
  static updateClusterToNewPlanType(params: UpdateClusterToNewPlanTypeRequest): Promise<void>;
324
348
  static updateClusterMetricsStartDate(params: UpdateClusterMetricsStartDateRequest): Promise<void>;
@@ -373,6 +397,22 @@ export declare class ConsoleAdminService {
373
397
  static getClusterPlanType(params: GetClusterPlanTypeRequest): Promise<ClusterPlanTypeDto>;
374
398
  static getAllClusterPlanTypes(params: GetAllClusterPlanTypesRequest): Promise<ClusterPlanTypeDto[]>;
375
399
  static getValueMetricsUsageData(params: GetValueMetricsUsageDataRequest): Promise<ClusterUsageMetricsData[]>;
400
+ /**
401
+ * The value metrics that console counted itself, one row for each cluster
402
+ * and day of the last `days` days
403
+ * (`GET api/orgs/:orgId/clusters/usage/value-metrics/:days`).
404
+ *
405
+ * This is the source that HDP replaced for a 2025 organization. The
406
+ * comparison of the two sources reads it on purpose, so it never reads HDP
407
+ * under this name: a comparison of a series with itself shows nothing.
408
+ */
409
+ static getValueMetricsUsageDataPerDay(params: GetValueMetricsUsageDataPerDayRequest): Promise<ClusterUsageMetricsData[]>;
410
+ /**
411
+ * The usage metadata of an organization: the unique task users and the
412
+ * deployed models for each billing period
413
+ * (`GET api/orgs/:orgId/clusters/usage/value-metrics-metadata`).
414
+ */
415
+ static getValueMetricsMetadata(params: GetValueMetricsMetadataRequest): Promise<ClusterUsageMetadataDto[]>;
376
416
  static getValueMetrics(params: GetValueMetricsRequest): Promise<ValueMetrics | undefined>;
377
417
  static getValueMetricsForAll(params: GetValueMetricsForAllRequest): Promise<ValueMetrics[]>;
378
418
  static getTaskUsers(params: GetTaskUsersRequest): Promise<UniqueTaskUser[]>;
@@ -390,14 +430,26 @@ export declare class ConsoleAdminService {
390
430
  static wakeCluster(params: {
391
431
  clusterId: string;
392
432
  } & RequestBaseParams): Promise<void | undefined>;
433
+ /**
434
+ * Every cluster modification, with the clusters they belong to.
435
+ *
436
+ * `clusterUuids` bounds the answer to those clusters. Console reads the
437
+ * whole table without it, and one cluster for each row of the answer, so a
438
+ * reader that asks about a few clusters names them. The ids go in the
439
+ * query of a GET, so they travel in groups of `CLUSTER_UUIDS_PER_READ`:
440
+ * the request line must not grow with the selection, or a large one
441
+ * answers 414. The groups are read one after the other and merged, with
442
+ * each cluster one time, so the caller sees one answer of the usual shape.
443
+ * An empty list reads nothing and answers nothing.
444
+ */
393
445
  static getAllModifications(params: RequestBaseParams & {
446
+ clusterUuids?: readonly string[];
394
447
  headers?: {
395
448
  'x-camunda-email'?: string;
396
449
  };
397
- }): Promise<{
398
- clusters: ConsoleClusterDto[];
399
- modifications: ClusterModificationDto[];
400
- } | undefined>;
450
+ }): Promise<ModificationsAnswer | undefined>;
451
+ /** One GET of the modifications, for every cluster or for the ids given. */
452
+ private static readModifications;
401
453
  static createModification(params: RequestBaseParams & {
402
454
  clusterUuid: string;
403
455
  headers?: {
@@ -1,5 +1,6 @@
1
1
  import { request } from "../../utils/api.js";
2
2
  import { HttpError } from "../../utils/errors.js";
3
+ const CLUSTER_UUIDS_PER_READ = 50;
3
4
  class ConsoleAdminService {
4
5
  static async updateClusterToNewPlanType(params) {
5
6
  const serviceContext = {
@@ -645,6 +646,84 @@ class ConsoleAdminService {
645
646
  }
646
647
  return response.body;
647
648
  }
649
+ /**
650
+ * The value metrics that console counted itself, one row for each cluster
651
+ * and day of the last `days` days
652
+ * (`GET api/orgs/:orgId/clusters/usage/value-metrics/:days`).
653
+ *
654
+ * This is the source that HDP replaced for a 2025 organization. The
655
+ * comparison of the two sources reads it on purpose, so it never reads HDP
656
+ * under this name: a comparison of a series with itself shows nothing.
657
+ */
658
+ static async getValueMetricsUsageDataPerDay(params) {
659
+ const serviceContext = {
660
+ method: {
661
+ name: `ConsoleAdminService.getValueMetricsUsageDataPerDay`,
662
+ url: `api/orgs/${params.params.orgId}/clusters/usage/value-metrics/${params.params.days}`,
663
+ normalizedUrl: `api/orgs/:orgId/clusters/usage/value-metrics/:days`,
664
+ type: "get"
665
+ },
666
+ source: params.config.metrics?.source || "unset",
667
+ target: {
668
+ name: "console",
669
+ type: "internal"
670
+ }
671
+ };
672
+ const response = await request({
673
+ config: params.config,
674
+ base: {
675
+ id: "console"
676
+ },
677
+ url: serviceContext.method.url,
678
+ method: serviceContext.method.type,
679
+ metricsDetails: serviceContext
680
+ });
681
+ if (!response.ok) {
682
+ throw new HttpError(
683
+ `${serviceContext.method.name}: ${response.status} ${response.statusText}`,
684
+ response.status,
685
+ response.statusText
686
+ );
687
+ }
688
+ return response.body ?? [];
689
+ }
690
+ /**
691
+ * The usage metadata of an organization: the unique task users and the
692
+ * deployed models for each billing period
693
+ * (`GET api/orgs/:orgId/clusters/usage/value-metrics-metadata`).
694
+ */
695
+ static async getValueMetricsMetadata(params) {
696
+ const serviceContext = {
697
+ method: {
698
+ name: `ConsoleAdminService.getValueMetricsMetadata`,
699
+ url: `api/orgs/${params.params.orgId}/clusters/usage/value-metrics-metadata`,
700
+ normalizedUrl: `api/orgs/:orgId/clusters/usage/value-metrics-metadata`,
701
+ type: "get"
702
+ },
703
+ source: params.config.metrics?.source || "unset",
704
+ target: {
705
+ name: "console",
706
+ type: "internal"
707
+ }
708
+ };
709
+ const response = await request({
710
+ config: params.config,
711
+ base: {
712
+ id: "console"
713
+ },
714
+ url: serviceContext.method.url,
715
+ method: serviceContext.method.type,
716
+ metricsDetails: serviceContext
717
+ });
718
+ if (!response.ok) {
719
+ throw new HttpError(
720
+ `${serviceContext.method.name}: ${response.status} ${response.statusText}`,
721
+ response.status,
722
+ response.statusText
723
+ );
724
+ }
725
+ return response.body?.metadata ?? [];
726
+ }
648
727
  static async getValueMetrics(params) {
649
728
  const serviceContext = {
650
729
  method: {
@@ -970,11 +1049,53 @@ class ConsoleAdminService {
970
1049
  }
971
1050
  return response.body;
972
1051
  }
1052
+ /**
1053
+ * Every cluster modification, with the clusters they belong to.
1054
+ *
1055
+ * `clusterUuids` bounds the answer to those clusters. Console reads the
1056
+ * whole table without it, and one cluster for each row of the answer, so a
1057
+ * reader that asks about a few clusters names them. The ids go in the
1058
+ * query of a GET, so they travel in groups of `CLUSTER_UUIDS_PER_READ`:
1059
+ * the request line must not grow with the selection, or a large one
1060
+ * answers 414. The groups are read one after the other and merged, with
1061
+ * each cluster one time, so the caller sees one answer of the usual shape.
1062
+ * An empty list reads nothing and answers nothing.
1063
+ */
973
1064
  static async getAllModifications(params) {
1065
+ const { clusterUuids, ...rest } = params;
1066
+ if (clusterUuids === void 0) {
1067
+ return ConsoleAdminService.readModifications(rest);
1068
+ }
1069
+ if (clusterUuids.length === 0) {
1070
+ return { clusters: [], modifications: [] };
1071
+ }
1072
+ const merged = { clusters: [], modifications: [] };
1073
+ const seenClusters = /* @__PURE__ */ new Set();
1074
+ for (let start = 0; start < clusterUuids.length; start += CLUSTER_UUIDS_PER_READ) {
1075
+ const page = await ConsoleAdminService.readModifications(
1076
+ rest,
1077
+ clusterUuids.slice(start, start + CLUSTER_UUIDS_PER_READ)
1078
+ );
1079
+ if (!page) {
1080
+ continue;
1081
+ }
1082
+ merged.modifications.push(...page.modifications);
1083
+ for (const cluster of page.clusters) {
1084
+ if (!seenClusters.has(cluster.uuid)) {
1085
+ seenClusters.add(cluster.uuid);
1086
+ merged.clusters.push(cluster);
1087
+ }
1088
+ }
1089
+ }
1090
+ return merged;
1091
+ }
1092
+ /** One GET of the modifications, for every cluster or for the ids given. */
1093
+ static async readModifications(params, clusterUuids) {
1094
+ const query = clusterUuids && clusterUuids.length > 0 ? `?clusterUuids=${clusterUuids.map(encodeURIComponent).join(",")}` : "";
974
1095
  const serviceContext = {
975
1096
  method: {
976
1097
  name: `ConsoleAdminService.getAllModifications`,
977
- url: `api/admin/clusters/modifications`,
1098
+ url: `api/admin/clusters/modifications${query}`,
978
1099
  normalizedUrl: `api/clusters/modifications`,
979
1100
  type: "get"
980
1101
  },
@@ -2075,6 +2196,7 @@ class ConsoleAdminService {
2075
2196
  }
2076
2197
  }
2077
2198
  export {
2199
+ CLUSTER_UUIDS_PER_READ,
2078
2200
  ConsoleAdminService
2079
2201
  };
2080
2202
  //# sourceMappingURL=console.admin.service.js.map