@iteradian-rpc/sdk 1.1.1 → 1.2.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/dist/index.js CHANGED
@@ -152,7 +152,11 @@ var HttpClient = class {
152
152
  if (!response.ok) {
153
153
  let errorBody;
154
154
  try {
155
- errorBody = await response.json();
155
+ const parsed = await response.json();
156
+ if (parsed === null || typeof parsed !== "object") {
157
+ throw new Error("error body is not an object");
158
+ }
159
+ errorBody = parsed;
156
160
  } catch {
157
161
  errorBody = {
158
162
  message: response.statusText || "Unknown error",
@@ -172,10 +176,14 @@ var HttpClient = class {
172
176
  await new Promise((r) => setTimeout(r, delay));
173
177
  return this.request(method, path, body, attempt + 1, base, signal);
174
178
  }
179
+ const rawMessage = errorBody.message;
180
+ const bodyMessage = Array.isArray(rawMessage) ? rawMessage.map(String).join(", ") : typeof rawMessage === "string" ? rawMessage : "";
181
+ const rpcMessage = typeof rpc?.message === "string" ? rpc.message : "";
182
+ const errorLabel = errorBody.error;
175
183
  throw new IteradianError(
176
- rpc?.message || errorBody.message || response.statusText,
177
- errorBody.statusCode || response.status,
178
- errorBody.error,
184
+ rpcMessage || bodyMessage || response.statusText || `HTTP ${response.status}`,
185
+ typeof errorBody.statusCode === "number" ? errorBody.statusCode : response.status,
186
+ typeof errorLabel === "string" ? errorLabel : void 0,
179
187
  { code: rpcCode, retryAfter, data: rpc?.data }
180
188
  );
181
189
  }
@@ -265,11 +273,23 @@ var AuthResource = class {
265
273
  acceptedTerms: data?.acceptedTerms === true
266
274
  });
267
275
  }
268
- /** Login with email/password (optionally with 2FA code) */
276
+ /**
277
+ * Login with email/password (optionally with a 2FA code or a backup code).
278
+ *
279
+ * When two-factor auth is on and no code was sent, the API answers
280
+ * `{ requires2FA: true }` with no tokens. Check `requires2FA` and call
281
+ * again with `twoFactorCode` or `backupCode`. The stored access token is
282
+ * only replaced when the answer carries one.
283
+ */
269
284
  async login(data) {
270
- const tokens = await this.http.post("/auth/login", data);
271
- this.http.setAccessToken(tokens.accessToken);
272
- return tokens;
285
+ const result = await this.http.post("/auth/login", data);
286
+ this.storeToken(result);
287
+ return result;
288
+ }
289
+ storeToken(result) {
290
+ if (result && typeof result.accessToken === "string" && result.accessToken) {
291
+ this.http.setAccessToken(result.accessToken);
292
+ }
273
293
  }
274
294
  /** Logout current session */
275
295
  logout() {
@@ -280,7 +300,7 @@ var AuthResource = class {
280
300
  const tokens = await this.http.post("/auth/refresh", {
281
301
  refreshToken
282
302
  });
283
- this.http.setAccessToken(tokens.accessToken);
303
+ this.storeToken(tokens);
284
304
  return tokens;
285
305
  }
286
306
  /** Verify email with token */
@@ -305,11 +325,11 @@ var AuthResource = class {
305
325
  }
306
326
  /** Login via magic link token */
307
327
  async loginWithMagicLink(token) {
308
- const tokens = await this.http.post("/auth/magic-login", {
328
+ const result = await this.http.post("/auth/magic-login", {
309
329
  token
310
330
  });
311
- this.http.setAccessToken(tokens.accessToken);
312
- return tokens;
331
+ this.storeToken(result);
332
+ return result;
313
333
  }
314
334
  /** Enable 2FA – returns QR code image and secret */
315
335
  enable2FA(password) {
@@ -338,7 +358,11 @@ var OrganizationsResource = class {
338
358
  list() {
339
359
  return this.http.get("/orgs");
340
360
  }
341
- /** Create a new organization */
361
+ /**
362
+ * Create a new organization. `name`, `planId` and `acceptedTerms` are
363
+ * required by the API; pass `acceptedTerms: true` only after the user
364
+ * agreed to the terms.
365
+ */
342
366
  create(data) {
343
367
  return this.http.post("/orgs", data);
344
368
  }
@@ -418,6 +442,12 @@ var OrganizationsResource = class {
418
442
  };
419
443
 
420
444
  // src/resources/api-keys.ts
445
+ function withKeyAlias(k) {
446
+ if (k && typeof k === "object" && typeof k.secret === "string") {
447
+ k.key = k.secret;
448
+ }
449
+ return k;
450
+ }
421
451
  var ApiKeysResource = class {
422
452
  constructor(http) {
423
453
  this.http = http;
@@ -430,9 +460,16 @@ var ApiKeysResource = class {
430
460
  get(orgId, keyId) {
431
461
  return this.http.get(`/orgs/${orgId}/keys/${keyId}`);
432
462
  }
433
- /** Create a new API key (returns the full key only once) */
434
- create(orgId, data) {
435
- return this.http.post(`/orgs/${orgId}/keys`, data);
463
+ /**
464
+ * Create a new API key. The full key comes back once, in `secret`
465
+ * (`key` is a deprecated alias with the same value).
466
+ */
467
+ async create(orgId, data) {
468
+ const created = await this.http.post(
469
+ `/orgs/${orgId}/keys`,
470
+ data
471
+ );
472
+ return withKeyAlias(created);
436
473
  }
437
474
  /** Update an API key */
438
475
  update(orgId, keyId, data) {
@@ -442,9 +479,15 @@ var ApiKeysResource = class {
442
479
  revoke(orgId, keyId) {
443
480
  return this.http.delete(`/orgs/${orgId}/keys/${keyId}`);
444
481
  }
445
- /** Rotate an API key (revoke old, create new) */
446
- rotate(orgId, keyId) {
447
- return this.http.post(`/orgs/${orgId}/keys/${keyId}/rotate`);
482
+ /**
483
+ * Rotate an API key (revoke old, create new). The new full key is in
484
+ * `secret`; `key` is a deprecated alias.
485
+ */
486
+ async rotate(orgId, keyId) {
487
+ const rotated = await this.http.post(
488
+ `/orgs/${orgId}/keys/${keyId}/rotate`
489
+ );
490
+ return withKeyAlias(rotated);
448
491
  }
449
492
  /** Get analytics for an API key */
450
493
  getAnalytics(orgId, keyId, timeRange = "7d") {
@@ -499,12 +542,16 @@ var EndpointsResource = class {
499
542
  return this.http.post(`/orgs/${orgId}/endpoints/${endpointId}/resume`);
500
543
  }
501
544
  // ==================== Health & Metrics ====================
502
- /** Trigger a health check */
545
+ /** Trigger a health check (POST .../health-check) */
503
546
  checkHealth(orgId, endpointId) {
504
547
  return this.http.post(
505
548
  `/orgs/${orgId}/endpoints/${endpointId}/health-check`
506
549
  );
507
550
  }
551
+ /** Get the current health of an endpoint (GET .../health) */
552
+ getHealth(orgId, endpointId) {
553
+ return this.http.get(`/orgs/${orgId}/endpoints/${endpointId}/health`);
554
+ }
508
555
  /** Get endpoint health summary */
509
556
  getHealthOverview(orgId) {
510
557
  return this.http.get(`/orgs/${orgId}/endpoints/summary`);
@@ -514,8 +561,9 @@ var EndpointsResource = class {
514
561
  const params = new URLSearchParams();
515
562
  if (from) params.append("from", from);
516
563
  if (to) params.append("to", to);
564
+ const qs = params.toString();
517
565
  return this.http.get(
518
- `/orgs/${orgId}/endpoints/${endpointId}/metrics?${params.toString()}`
566
+ `/orgs/${orgId}/endpoints/${endpointId}/metrics${qs ? `?${qs}` : ""}`
519
567
  );
520
568
  }
521
569
  /** Update endpoint priorities */
@@ -531,9 +579,13 @@ var UsageResource = class {
531
579
  constructor(http) {
532
580
  this.http = http;
533
581
  }
534
- /** Get usage analytics for a date range */
582
+ /**
583
+ * Get usage rows (one per key per day) for a date range. `from` and `to`
584
+ * are ISO dates, e.g. `2026-01-31`.
585
+ */
535
586
  get(orgId, from, to) {
536
- return this.http.get(`/orgs/${orgId}/usage?from=${from}&to=${to}`);
587
+ const qs = new URLSearchParams({ from, to }).toString();
588
+ return this.http.get(`/orgs/${orgId}/usage?${qs}`);
537
589
  }
538
590
  /** Get usage summary */
539
591
  getSummary(orgId) {
@@ -542,13 +594,27 @@ var UsageResource = class {
542
594
  };
543
595
 
544
596
  // src/resources/dashboard.ts
597
+ var TIME_RANGES = {
598
+ "1h": "last_hour",
599
+ "24h": "last_24_hours",
600
+ "7d": "last_7_days",
601
+ "30d": "last_30_days"
602
+ };
603
+ function rangeQuery(timeRange, custom) {
604
+ const qs = new URLSearchParams();
605
+ if (timeRange) qs.set("timeRange", TIME_RANGES[timeRange] ?? timeRange);
606
+ if (custom?.from) qs.set("from", custom.from);
607
+ if (custom?.to) qs.set("to", custom.to);
608
+ const s = qs.toString();
609
+ return s ? `?${s}` : "";
610
+ }
545
611
  var DashboardResource = class {
546
612
  constructor(http) {
547
613
  this.http = http;
548
614
  }
549
615
  /** Get full dashboard data */
550
- get(orgId, period) {
551
- const params = period ? `?period=${period}` : "";
616
+ get(orgId, timeRange, custom) {
617
+ const params = rangeQuery(timeRange, custom);
552
618
  return this.http.get(`/orgs/${orgId}/dashboard${params}`);
553
619
  }
554
620
  /** Get system health overview */
@@ -556,23 +622,23 @@ var DashboardResource = class {
556
622
  return this.http.get(`/orgs/${orgId}/dashboard/health`);
557
623
  }
558
624
  /** Get quick stats */
559
- getQuickStats(orgId, period) {
560
- const params = period ? `?period=${period}` : "";
625
+ getQuickStats(orgId, timeRange, custom) {
626
+ const params = rangeQuery(timeRange, custom);
561
627
  return this.http.get(`/orgs/${orgId}/dashboard/quick-stats${params}`);
562
628
  }
563
629
  /** Get request rate time series */
564
- getRequestRate(orgId, period) {
565
- const params = period ? `?period=${period}` : "";
630
+ getRequestRate(orgId, timeRange, custom) {
631
+ const params = rangeQuery(timeRange, custom);
566
632
  return this.http.get(`/orgs/${orgId}/dashboard/request-rate${params}`);
567
633
  }
568
634
  /** Get error rate time series */
569
- getErrorRate(orgId, period) {
570
- const params = period ? `?period=${period}` : "";
635
+ getErrorRate(orgId, timeRange, custom) {
636
+ const params = rangeQuery(timeRange, custom);
571
637
  return this.http.get(`/orgs/${orgId}/dashboard/error-rate${params}`);
572
638
  }
573
639
  /** Get latency metrics */
574
- getLatency(orgId, period) {
575
- const params = period ? `?period=${period}` : "";
640
+ getLatency(orgId, timeRange, custom) {
641
+ const params = rangeQuery(timeRange, custom);
576
642
  return this.http.get(`/orgs/${orgId}/dashboard/latency${params}`);
577
643
  }
578
644
  /** Get performance metrics */
@@ -587,8 +653,17 @@ var AlertsResource = class {
587
653
  this.http = http;
588
654
  }
589
655
  // ==================== Alerts ====================
590
- /** List alerts for an organization */
591
- list(orgId) {
656
+ /**
657
+ * List alerts for an organization. The API answers an overview object
658
+ * (`alerts`, counters, rules, channels); this returns just the alerts.
659
+ * Use `overview()` for the rest.
660
+ */
661
+ async list(orgId) {
662
+ const overview = await this.overview(orgId);
663
+ return Array.isArray(overview?.alerts) ? overview.alerts : [];
664
+ }
665
+ /** The full alerts overview: alerts, counters, rules and channels. */
666
+ overview(orgId) {
592
667
  return this.http.get(`/orgs/${orgId}/alerts`);
593
668
  }
594
669
  /** Acknowledge an alert */
@@ -664,7 +739,7 @@ var LogsResource = class {
664
739
  constructor(http) {
665
740
  this.http = http;
666
741
  }
667
- /** Query request logs with filters and pagination */
742
+ /** Query request logs with filters (`limit` / `offset` paginate) */
668
743
  query(orgId, params) {
669
744
  const searchParams = new URLSearchParams();
670
745
  if (params) {
@@ -753,8 +828,16 @@ var SupportResource = class {
753
828
  createTicket(orgId, data) {
754
829
  return this.http.post(`/orgs/${orgId}/support/tickets`, data);
755
830
  }
756
- /** List support tickets */
757
- listTickets(orgId) {
831
+ /**
832
+ * List support tickets. The API answers `{ tickets, total }`; this
833
+ * returns the tickets. Use `listTicketsWithTotal()` for the total.
834
+ */
835
+ async listTickets(orgId) {
836
+ const res = await this.listTicketsWithTotal(orgId);
837
+ return Array.isArray(res?.tickets) ? res.tickets : [];
838
+ }
839
+ /** List support tickets with the total count. */
840
+ listTicketsWithTotal(orgId) {
758
841
  return this.http.get(`/orgs/${orgId}/support/tickets`);
759
842
  }
760
843
  /** Get ticket statistics */
package/dist/index.mjs CHANGED
@@ -113,7 +113,11 @@ var HttpClient = class {
113
113
  if (!response.ok) {
114
114
  let errorBody;
115
115
  try {
116
- errorBody = await response.json();
116
+ const parsed = await response.json();
117
+ if (parsed === null || typeof parsed !== "object") {
118
+ throw new Error("error body is not an object");
119
+ }
120
+ errorBody = parsed;
117
121
  } catch {
118
122
  errorBody = {
119
123
  message: response.statusText || "Unknown error",
@@ -133,10 +137,14 @@ var HttpClient = class {
133
137
  await new Promise((r) => setTimeout(r, delay));
134
138
  return this.request(method, path, body, attempt + 1, base, signal);
135
139
  }
140
+ const rawMessage = errorBody.message;
141
+ const bodyMessage = Array.isArray(rawMessage) ? rawMessage.map(String).join(", ") : typeof rawMessage === "string" ? rawMessage : "";
142
+ const rpcMessage = typeof rpc?.message === "string" ? rpc.message : "";
143
+ const errorLabel = errorBody.error;
136
144
  throw new IteradianError(
137
- rpc?.message || errorBody.message || response.statusText,
138
- errorBody.statusCode || response.status,
139
- errorBody.error,
145
+ rpcMessage || bodyMessage || response.statusText || `HTTP ${response.status}`,
146
+ typeof errorBody.statusCode === "number" ? errorBody.statusCode : response.status,
147
+ typeof errorLabel === "string" ? errorLabel : void 0,
140
148
  { code: rpcCode, retryAfter, data: rpc?.data }
141
149
  );
142
150
  }
@@ -226,11 +234,23 @@ var AuthResource = class {
226
234
  acceptedTerms: data?.acceptedTerms === true
227
235
  });
228
236
  }
229
- /** Login with email/password (optionally with 2FA code) */
237
+ /**
238
+ * Login with email/password (optionally with a 2FA code or a backup code).
239
+ *
240
+ * When two-factor auth is on and no code was sent, the API answers
241
+ * `{ requires2FA: true }` with no tokens. Check `requires2FA` and call
242
+ * again with `twoFactorCode` or `backupCode`. The stored access token is
243
+ * only replaced when the answer carries one.
244
+ */
230
245
  async login(data) {
231
- const tokens = await this.http.post("/auth/login", data);
232
- this.http.setAccessToken(tokens.accessToken);
233
- return tokens;
246
+ const result = await this.http.post("/auth/login", data);
247
+ this.storeToken(result);
248
+ return result;
249
+ }
250
+ storeToken(result) {
251
+ if (result && typeof result.accessToken === "string" && result.accessToken) {
252
+ this.http.setAccessToken(result.accessToken);
253
+ }
234
254
  }
235
255
  /** Logout current session */
236
256
  logout() {
@@ -241,7 +261,7 @@ var AuthResource = class {
241
261
  const tokens = await this.http.post("/auth/refresh", {
242
262
  refreshToken
243
263
  });
244
- this.http.setAccessToken(tokens.accessToken);
264
+ this.storeToken(tokens);
245
265
  return tokens;
246
266
  }
247
267
  /** Verify email with token */
@@ -266,11 +286,11 @@ var AuthResource = class {
266
286
  }
267
287
  /** Login via magic link token */
268
288
  async loginWithMagicLink(token) {
269
- const tokens = await this.http.post("/auth/magic-login", {
289
+ const result = await this.http.post("/auth/magic-login", {
270
290
  token
271
291
  });
272
- this.http.setAccessToken(tokens.accessToken);
273
- return tokens;
292
+ this.storeToken(result);
293
+ return result;
274
294
  }
275
295
  /** Enable 2FA – returns QR code image and secret */
276
296
  enable2FA(password) {
@@ -299,7 +319,11 @@ var OrganizationsResource = class {
299
319
  list() {
300
320
  return this.http.get("/orgs");
301
321
  }
302
- /** Create a new organization */
322
+ /**
323
+ * Create a new organization. `name`, `planId` and `acceptedTerms` are
324
+ * required by the API; pass `acceptedTerms: true` only after the user
325
+ * agreed to the terms.
326
+ */
303
327
  create(data) {
304
328
  return this.http.post("/orgs", data);
305
329
  }
@@ -379,6 +403,12 @@ var OrganizationsResource = class {
379
403
  };
380
404
 
381
405
  // src/resources/api-keys.ts
406
+ function withKeyAlias(k) {
407
+ if (k && typeof k === "object" && typeof k.secret === "string") {
408
+ k.key = k.secret;
409
+ }
410
+ return k;
411
+ }
382
412
  var ApiKeysResource = class {
383
413
  constructor(http) {
384
414
  this.http = http;
@@ -391,9 +421,16 @@ var ApiKeysResource = class {
391
421
  get(orgId, keyId) {
392
422
  return this.http.get(`/orgs/${orgId}/keys/${keyId}`);
393
423
  }
394
- /** Create a new API key (returns the full key only once) */
395
- create(orgId, data) {
396
- return this.http.post(`/orgs/${orgId}/keys`, data);
424
+ /**
425
+ * Create a new API key. The full key comes back once, in `secret`
426
+ * (`key` is a deprecated alias with the same value).
427
+ */
428
+ async create(orgId, data) {
429
+ const created = await this.http.post(
430
+ `/orgs/${orgId}/keys`,
431
+ data
432
+ );
433
+ return withKeyAlias(created);
397
434
  }
398
435
  /** Update an API key */
399
436
  update(orgId, keyId, data) {
@@ -403,9 +440,15 @@ var ApiKeysResource = class {
403
440
  revoke(orgId, keyId) {
404
441
  return this.http.delete(`/orgs/${orgId}/keys/${keyId}`);
405
442
  }
406
- /** Rotate an API key (revoke old, create new) */
407
- rotate(orgId, keyId) {
408
- return this.http.post(`/orgs/${orgId}/keys/${keyId}/rotate`);
443
+ /**
444
+ * Rotate an API key (revoke old, create new). The new full key is in
445
+ * `secret`; `key` is a deprecated alias.
446
+ */
447
+ async rotate(orgId, keyId) {
448
+ const rotated = await this.http.post(
449
+ `/orgs/${orgId}/keys/${keyId}/rotate`
450
+ );
451
+ return withKeyAlias(rotated);
409
452
  }
410
453
  /** Get analytics for an API key */
411
454
  getAnalytics(orgId, keyId, timeRange = "7d") {
@@ -460,12 +503,16 @@ var EndpointsResource = class {
460
503
  return this.http.post(`/orgs/${orgId}/endpoints/${endpointId}/resume`);
461
504
  }
462
505
  // ==================== Health & Metrics ====================
463
- /** Trigger a health check */
506
+ /** Trigger a health check (POST .../health-check) */
464
507
  checkHealth(orgId, endpointId) {
465
508
  return this.http.post(
466
509
  `/orgs/${orgId}/endpoints/${endpointId}/health-check`
467
510
  );
468
511
  }
512
+ /** Get the current health of an endpoint (GET .../health) */
513
+ getHealth(orgId, endpointId) {
514
+ return this.http.get(`/orgs/${orgId}/endpoints/${endpointId}/health`);
515
+ }
469
516
  /** Get endpoint health summary */
470
517
  getHealthOverview(orgId) {
471
518
  return this.http.get(`/orgs/${orgId}/endpoints/summary`);
@@ -475,8 +522,9 @@ var EndpointsResource = class {
475
522
  const params = new URLSearchParams();
476
523
  if (from) params.append("from", from);
477
524
  if (to) params.append("to", to);
525
+ const qs = params.toString();
478
526
  return this.http.get(
479
- `/orgs/${orgId}/endpoints/${endpointId}/metrics?${params.toString()}`
527
+ `/orgs/${orgId}/endpoints/${endpointId}/metrics${qs ? `?${qs}` : ""}`
480
528
  );
481
529
  }
482
530
  /** Update endpoint priorities */
@@ -492,9 +540,13 @@ var UsageResource = class {
492
540
  constructor(http) {
493
541
  this.http = http;
494
542
  }
495
- /** Get usage analytics for a date range */
543
+ /**
544
+ * Get usage rows (one per key per day) for a date range. `from` and `to`
545
+ * are ISO dates, e.g. `2026-01-31`.
546
+ */
496
547
  get(orgId, from, to) {
497
- return this.http.get(`/orgs/${orgId}/usage?from=${from}&to=${to}`);
548
+ const qs = new URLSearchParams({ from, to }).toString();
549
+ return this.http.get(`/orgs/${orgId}/usage?${qs}`);
498
550
  }
499
551
  /** Get usage summary */
500
552
  getSummary(orgId) {
@@ -503,13 +555,27 @@ var UsageResource = class {
503
555
  };
504
556
 
505
557
  // src/resources/dashboard.ts
558
+ var TIME_RANGES = {
559
+ "1h": "last_hour",
560
+ "24h": "last_24_hours",
561
+ "7d": "last_7_days",
562
+ "30d": "last_30_days"
563
+ };
564
+ function rangeQuery(timeRange, custom) {
565
+ const qs = new URLSearchParams();
566
+ if (timeRange) qs.set("timeRange", TIME_RANGES[timeRange] ?? timeRange);
567
+ if (custom?.from) qs.set("from", custom.from);
568
+ if (custom?.to) qs.set("to", custom.to);
569
+ const s = qs.toString();
570
+ return s ? `?${s}` : "";
571
+ }
506
572
  var DashboardResource = class {
507
573
  constructor(http) {
508
574
  this.http = http;
509
575
  }
510
576
  /** Get full dashboard data */
511
- get(orgId, period) {
512
- const params = period ? `?period=${period}` : "";
577
+ get(orgId, timeRange, custom) {
578
+ const params = rangeQuery(timeRange, custom);
513
579
  return this.http.get(`/orgs/${orgId}/dashboard${params}`);
514
580
  }
515
581
  /** Get system health overview */
@@ -517,23 +583,23 @@ var DashboardResource = class {
517
583
  return this.http.get(`/orgs/${orgId}/dashboard/health`);
518
584
  }
519
585
  /** Get quick stats */
520
- getQuickStats(orgId, period) {
521
- const params = period ? `?period=${period}` : "";
586
+ getQuickStats(orgId, timeRange, custom) {
587
+ const params = rangeQuery(timeRange, custom);
522
588
  return this.http.get(`/orgs/${orgId}/dashboard/quick-stats${params}`);
523
589
  }
524
590
  /** Get request rate time series */
525
- getRequestRate(orgId, period) {
526
- const params = period ? `?period=${period}` : "";
591
+ getRequestRate(orgId, timeRange, custom) {
592
+ const params = rangeQuery(timeRange, custom);
527
593
  return this.http.get(`/orgs/${orgId}/dashboard/request-rate${params}`);
528
594
  }
529
595
  /** Get error rate time series */
530
- getErrorRate(orgId, period) {
531
- const params = period ? `?period=${period}` : "";
596
+ getErrorRate(orgId, timeRange, custom) {
597
+ const params = rangeQuery(timeRange, custom);
532
598
  return this.http.get(`/orgs/${orgId}/dashboard/error-rate${params}`);
533
599
  }
534
600
  /** Get latency metrics */
535
- getLatency(orgId, period) {
536
- const params = period ? `?period=${period}` : "";
601
+ getLatency(orgId, timeRange, custom) {
602
+ const params = rangeQuery(timeRange, custom);
537
603
  return this.http.get(`/orgs/${orgId}/dashboard/latency${params}`);
538
604
  }
539
605
  /** Get performance metrics */
@@ -548,8 +614,17 @@ var AlertsResource = class {
548
614
  this.http = http;
549
615
  }
550
616
  // ==================== Alerts ====================
551
- /** List alerts for an organization */
552
- list(orgId) {
617
+ /**
618
+ * List alerts for an organization. The API answers an overview object
619
+ * (`alerts`, counters, rules, channels); this returns just the alerts.
620
+ * Use `overview()` for the rest.
621
+ */
622
+ async list(orgId) {
623
+ const overview = await this.overview(orgId);
624
+ return Array.isArray(overview?.alerts) ? overview.alerts : [];
625
+ }
626
+ /** The full alerts overview: alerts, counters, rules and channels. */
627
+ overview(orgId) {
553
628
  return this.http.get(`/orgs/${orgId}/alerts`);
554
629
  }
555
630
  /** Acknowledge an alert */
@@ -625,7 +700,7 @@ var LogsResource = class {
625
700
  constructor(http) {
626
701
  this.http = http;
627
702
  }
628
- /** Query request logs with filters and pagination */
703
+ /** Query request logs with filters (`limit` / `offset` paginate) */
629
704
  query(orgId, params) {
630
705
  const searchParams = new URLSearchParams();
631
706
  if (params) {
@@ -714,8 +789,16 @@ var SupportResource = class {
714
789
  createTicket(orgId, data) {
715
790
  return this.http.post(`/orgs/${orgId}/support/tickets`, data);
716
791
  }
717
- /** List support tickets */
718
- listTickets(orgId) {
792
+ /**
793
+ * List support tickets. The API answers `{ tickets, total }`; this
794
+ * returns the tickets. Use `listTicketsWithTotal()` for the total.
795
+ */
796
+ async listTickets(orgId) {
797
+ const res = await this.listTicketsWithTotal(orgId);
798
+ return Array.isArray(res?.tickets) ? res.tickets : [];
799
+ }
800
+ /** List support tickets with the total count. */
801
+ listTicketsWithTotal(orgId) {
719
802
  return this.http.get(`/orgs/${orgId}/support/tickets`);
720
803
  }
721
804
  /** Get ticket statistics */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@iteradian-rpc/sdk",
3
- "version": "1.1.1",
3
+ "version": "1.2.0",
4
4
  "description": "Official Iteradian Control Plane SDK for JavaScript/TypeScript",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -20,7 +20,7 @@
20
20
  "build": "tsup src/index.ts --format cjs,esm --dts",
21
21
  "dev": "tsup src/index.ts --format cjs,esm --dts --watch",
22
22
  "lint": "tsc --noEmit",
23
- "test": "node --test test/account.test.mjs"
23
+ "test": "node --test test/account.test.mjs test/reality.test.mjs"
24
24
  },
25
25
  "keywords": [
26
26
  "iteradian",