@rustrak/client 0.12.2 → 0.13.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.cjs CHANGED
@@ -363,6 +363,28 @@ var upsertProjectMemberSchema = zod.z.object({
363
363
  user_id: zod.z.number().int(),
364
364
  role: projectRoleSchema
365
365
  });
366
+ var metricDeltaSchema = zod.z.object({
367
+ current: zod.z.number().int(),
368
+ /**
369
+ * The same window immediately before this one. Null only for all-time
370
+ * requests, where a `0` would render as a misleading "+100%".
371
+ */
372
+ previous: zod.z.number().int().nullable()
373
+ });
374
+ var projectListStatsSchema = zod.z.object({
375
+ /**
376
+ * Distinct issues active in each bucket, oldest first. A shape, not a
377
+ * total: an issue firing all day appears in every bucket it touched.
378
+ */
379
+ trend: zod.z.array(zod.z.number().int()),
380
+ events: metricDeltaSchema,
381
+ /** Issues first seen in the window. Drives the "getting worse" signal. */
382
+ new_issues: metricDeltaSchema,
383
+ /** Unresolved issues right now, independent of the window. */
384
+ open_issues: zod.z.number().int(),
385
+ /** The subset of `open_issues` at `fatal` level. */
386
+ fatal_issues: zod.z.number().int()
387
+ });
366
388
  var projectSchema = zod.z.object({
367
389
  id: zod.z.number().int(),
368
390
  name: zod.z.string(),
@@ -373,15 +395,31 @@ var projectSchema = zod.z.object({
373
395
  digested_event_count: zod.z.number().int(),
374
396
  created_at: dateTimeSchema,
375
397
  updated_at: dateTimeSchema,
376
- platform: zod.z.string().nullable()
398
+ platform: zod.z.string().nullable(),
399
+ stats: projectListStatsSchema.optional()
377
400
  });
378
401
  var createProjectSchema = zod.z.object({
379
402
  name: zod.z.string().min(1),
380
- slug: zod.z.string().optional()
403
+ /**
404
+ * Slugified server-side. Supplying it means the user chose it, so a taken
405
+ * slug is a 409. Omitting it derives one from the name and silently
406
+ * de-duplicates, since nobody chose that value.
407
+ */
408
+ slug: zod.z.string().min(1).optional(),
409
+ /**
410
+ * Validated server-side against SELECTABLE_PLATFORMS. Omitting it leaves the
411
+ * project eligible for platform auto-detection from its first event.
412
+ */
413
+ platform: zod.z.string().min(1).optional()
381
414
  });
382
415
  var updateProjectSchema = zod.z.object({
383
416
  name: zod.z.string().min(1).optional(),
384
- platform: zod.z.string().min(1).optional()
417
+ platform: zod.z.string().min(1).optional(),
418
+ /**
419
+ * Slugified server-side. Unlike on create, a taken slug is a 409 rather than
420
+ * being silently de-duplicated.
421
+ */
422
+ slug: zod.z.string().min(1).optional()
385
423
  });
386
424
  var releaseHealthRowSchema = zod.z.object({
387
425
  release: zod.z.string(),
@@ -394,7 +432,6 @@ var releaseHealthRowSchema = zod.z.object({
394
432
  crash_free_sessions_rate: zod.z.number().nullable(),
395
433
  crash_free_users_rate: zod.z.number().nullable()
396
434
  });
397
- var releaseHealthSchema = zod.z.array(releaseHealthRowSchema);
398
435
  var sessionSummarySchema = zod.z.object({
399
436
  total: zod.z.number().int(),
400
437
  errored: zod.z.number().int(),
@@ -435,6 +472,27 @@ var sourceMapFileSchema = zod.z.object({
435
472
  var listSourceMapsResponseSchema = zod.z.object({
436
473
  data: zod.z.array(sourceMapFileSchema)
437
474
  });
475
+ var eventTimeseriesPointSchema = zod.z.object({
476
+ bucket: dateTimeSchema,
477
+ total: zod.z.number().int(),
478
+ fatal: zod.z.number().int(),
479
+ error: zod.z.number().int(),
480
+ warning: zod.z.number().int(),
481
+ info: zod.z.number().int()
482
+ });
483
+ var eventTimeseriesSchema = zod.z.array(eventTimeseriesPointSchema);
484
+ var metricDeltaSchema2 = zod.z.object({
485
+ current: zod.z.number().int(),
486
+ previous: zod.z.number().int().nullable()
487
+ });
488
+ var projectStatsSummarySchema = zod.z.object({
489
+ /** Resolved window in hours, or `null` for all time. */
490
+ period_hours: zod.z.number().int().nullable(),
491
+ events: metricDeltaSchema2,
492
+ new_issues: metricDeltaSchema2,
493
+ /** Currently unresolved issues, independent of the window. */
494
+ open_issues: zod.z.number().int()
495
+ });
438
496
  var sourceMapStorageSchema = zod.z.object({
439
497
  chunk_bytes: zod.z.number(),
440
498
  source_file_bytes: zod.z.number(),
@@ -1280,6 +1338,9 @@ var ProjectsResource = class extends BaseResource {
1280
1338
  if (options?.order) {
1281
1339
  searchParams.set("order", options.order);
1282
1340
  }
1341
+ if (options?.stats_period) {
1342
+ searchParams.set("stats_period", options.stats_period);
1343
+ }
1283
1344
  const query = searchParams.toString();
1284
1345
  const url = query ? `api/projects?${query}` : "api/projects";
1285
1346
  const data = await this.http.get(url).json();
@@ -1339,22 +1400,30 @@ var ReleasesResource = class extends BaseResource {
1339
1400
  // src/resources/sessions.ts
1340
1401
  var SessionsResource = class extends BaseResource {
1341
1402
  /**
1342
- * Get per-release health stats for a project.
1403
+ * Get per-release health stats for a project, one offset-based page of
1404
+ * (release, environment) rows at a time, ordered by session volume.
1343
1405
  * @param projectId - Project ID
1344
- * @param period - Time window (e.g. '24h', '7d'). Defaults to '24h'.
1345
- * @param release - Scope to a single release (all environments), computed
1346
- * server-side. Omit to get every release in the project.
1406
+ * @param options - Time window, release scoping and pagination.
1347
1407
  */
1348
- async stats(projectId, period, release) {
1408
+ async stats(projectId, options) {
1349
1409
  const searchParams = {};
1350
- if (period) {
1351
- searchParams.period = period;
1410
+ if (options?.period) {
1411
+ searchParams.period = options.period;
1352
1412
  }
1353
- if (release) {
1354
- searchParams.release = release;
1413
+ if (options?.release) {
1414
+ searchParams.release = options.release;
1415
+ }
1416
+ if (options?.page) {
1417
+ searchParams.page = String(options.page);
1418
+ }
1419
+ if (options?.per_page) {
1420
+ searchParams.per_page = String(options.per_page);
1355
1421
  }
1356
1422
  const data = await this.http.get(`api/projects/${projectId}/sessions/stats`, { searchParams }).json();
1357
- return this.validate(data, releaseHealthSchema);
1423
+ return this.validate(
1424
+ data,
1425
+ offsetPaginatedResponseSchema(releaseHealthRowSchema)
1426
+ );
1358
1427
  }
1359
1428
  /**
1360
1429
  * Get project-wide session health, aggregated across all releases and environments.
@@ -1471,6 +1540,48 @@ var SpansResource = class extends BaseResource {
1471
1540
  return this.validate(data, offsetPaginatedResponseSchema(spanSchema));
1472
1541
  }
1473
1542
  };
1543
+
1544
+ // src/resources/stats.ts
1545
+ var StatsResource = class extends BaseResource {
1546
+ /**
1547
+ * Get time-bucketed error-event volume for a project, split by severity.
1548
+ *
1549
+ * Buckets are zero-filled across the window, so a quiet hour comes back as a
1550
+ * point with `total: 0` rather than being absent. All-time requests (no
1551
+ * `period`) are sparse: there is no lower bound to fill from.
1552
+ *
1553
+ * @param projectId - Project ID
1554
+ * @param period - Time window (e.g. '24h', '7d'). Omit for all time.
1555
+ * @param interval - Bucket width in hours (default: 1, max: 24).
1556
+ */
1557
+ async timeseries(projectId, period, interval) {
1558
+ const searchParams = {};
1559
+ if (period) {
1560
+ searchParams.period = period;
1561
+ }
1562
+ if (interval !== void 0) {
1563
+ searchParams.interval = interval.toString();
1564
+ }
1565
+ const data = await this.http.get(`api/projects/${projectId}/events/stats`, { searchParams }).json();
1566
+ return this.validate(data, eventTimeseriesSchema);
1567
+ }
1568
+ /**
1569
+ * Get project-wide counters for a window, each paired with the same counter
1570
+ * over the window immediately before it.
1571
+ *
1572
+ * @param projectId - Project ID
1573
+ * @param period - Time window (e.g. '24h', '7d'). Omit for all time, which
1574
+ * leaves every `previous` null.
1575
+ */
1576
+ async summary(projectId, period) {
1577
+ const searchParams = {};
1578
+ if (period) {
1579
+ searchParams.period = period;
1580
+ }
1581
+ const data = await this.http.get(`api/projects/${projectId}/stats/summary`, { searchParams }).json();
1582
+ return this.validate(data, projectStatsSummarySchema);
1583
+ }
1584
+ };
1474
1585
  var StorageResource = class extends BaseResource {
1475
1586
  /**
1476
1587
  * Get the instance-wide storage summary: row counts per data category, the
@@ -1678,7 +1789,8 @@ function transformHttpError(error) {
1678
1789
  let errorMessage = `HTTP ${status} error`;
1679
1790
  const body = error.data;
1680
1791
  if (body) {
1681
- errorMessage = body.error || body.message || errorMessage;
1792
+ const nested = typeof body.error === "object" ? body.error?.message : body.error;
1793
+ errorMessage = nested || body.message || errorMessage;
1682
1794
  }
1683
1795
  switch (status) {
1684
1796
  case 400:
@@ -1807,6 +1919,10 @@ var RustrakClient = class {
1807
1919
  * AI Agent Monitoring dashboard API resource
1808
1920
  */
1809
1921
  agents;
1922
+ /**
1923
+ * Stats API resource (project-wide overview aggregates)
1924
+ */
1925
+ stats;
1810
1926
  /**
1811
1927
  * Storage API resource (usage + retention cleanup, admin only)
1812
1928
  */
@@ -1839,6 +1955,7 @@ var RustrakClient = class {
1839
1955
  this.logs = new LogsResource(this.http);
1840
1956
  this.spans = new SpansResource(this.http);
1841
1957
  this.agents = new AgentsResource(this.http);
1958
+ this.stats = new StatsResource(this.http);
1842
1959
  this.storage = new StorageResource(this.http);
1843
1960
  this.health = new HealthResource(this.http);
1844
1961
  }