@rustrak/client 0.3.10 → 0.3.12

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
@@ -15,7 +15,11 @@ var offsetPaginatedResponseSchema = (itemSchema) => z.object({
15
15
  total_pages: z.number().int()
16
16
  });
17
17
  z.enum(["asc", "desc"]);
18
- z.enum(["digest_order", "last_seen"]);
18
+ z.enum([
19
+ "digest_order",
20
+ "last_seen",
21
+ "event_count"
22
+ ]);
19
23
  z.enum(["open", "resolved", "muted", "all"]);
20
24
  var dateTimeSchema = z.string().datetime();
21
25
  var uuidSchema = z.string().uuid();
@@ -519,24 +523,129 @@ var eventDetailSchema = z.object({
519
523
  data: z.record(z.string(), z.any())
520
524
  // Full Sentry event JSON
521
525
  });
526
+ var issueStatusSchema = z.enum(["unresolved", "resolved", "ignored"]);
527
+ var issuePrioritySchema = z.enum(["low", "medium", "high"]);
522
528
  var issueSchema = z.object({
523
529
  id: uuidSchema,
524
530
  project_id: z.number().int(),
525
531
  short_id: z.string(),
526
532
  title: z.string(),
527
533
  value: z.string(),
534
+ culprit: z.string(),
535
+ logger: z.string(),
528
536
  first_seen: dateTimeSchema,
529
537
  last_seen: dateTimeSchema,
530
538
  event_count: z.number().int(),
531
539
  level: z.string().nullable(),
532
540
  platform: z.string().nullable(),
541
+ // Status model (#165)
542
+ status: issueStatusSchema,
543
+ substatus: z.string().nullable(),
544
+ priority: issuePrioritySchema.nullable(),
545
+ assigned_to: z.number().int().nullable(),
546
+ assignee_type: z.string().nullable(),
547
+ issue_type: z.string(),
548
+ issue_category: z.string(),
549
+ first_release: z.string(),
550
+ last_release: z.string(),
551
+ status_details: z.record(z.string(), z.unknown()),
552
+ // Aggregate enrichment — only the single-issue GET populates this; the list
553
+ // and PATCH endpoints return the lean response, so default to 0 when absent.
554
+ user_report_count: z.number().int().optional().default(0),
555
+ // Per-user fields — only present when the request carries a user session.
556
+ is_bookmarked: z.boolean().optional(),
557
+ is_subscribed: z.boolean().optional(),
558
+ has_seen: z.boolean().optional(),
559
+ // Bulk list stats — only the list endpoint populates these (computed once
560
+ // per page); the single-issue GET and PATCH responses omit them.
561
+ user_count: z.number().int().optional(),
562
+ trend: z.array(z.number().int()).optional(),
563
+ // Deprecated, derived from `status`; kept for backward compatibility.
533
564
  is_resolved: z.boolean(),
534
565
  is_muted: z.boolean()
535
566
  });
536
567
  var updateIssueStateSchema = z.object({
568
+ status: z.union([issueStatusSchema, z.literal("resolvedInNextRelease")]).optional(),
569
+ substatus: z.string().optional(),
570
+ priority: issuePrioritySchema.optional(),
571
+ assigned_to: z.number().int().nullable().optional(),
572
+ assignee_type: z.string().nullable().optional(),
537
573
  is_resolved: z.boolean().optional(),
538
574
  is_muted: z.boolean().optional()
539
575
  });
576
+ var issueHashSchema = z.object({
577
+ id: z.number().int(),
578
+ project_id: z.number().int(),
579
+ issue_id: uuidSchema,
580
+ grouping_key: z.string(),
581
+ grouping_key_hash: z.string(),
582
+ created_at: dateTimeSchema
583
+ });
584
+ var tagValueCountSchema = z.object({
585
+ value: z.string(),
586
+ count: z.number().int()
587
+ });
588
+ var issueTagValueSchema = z.object({
589
+ key: z.string(),
590
+ name: z.string(),
591
+ value: z.string(),
592
+ count: z.number().int(),
593
+ first_seen: dateTimeSchema,
594
+ last_seen: dateTimeSchema
595
+ });
596
+ var tagSummarySchema = z.object({
597
+ key: z.string(),
598
+ total_values: z.number().int(),
599
+ top_values: z.array(tagValueCountSchema)
600
+ });
601
+ var issueAggregatesSchema = z.object({
602
+ user_count: z.number().int(),
603
+ tags: z.array(tagSummarySchema)
604
+ });
605
+ z.enum(["24h", "30d"]);
606
+ var issueStatsSchema = z.object({
607
+ data: z.array(z.tuple([z.number(), z.number()]))
608
+ });
609
+ var activityEntrySchema = z.object({
610
+ id: uuidSchema,
611
+ issue_id: uuidSchema,
612
+ user_id: z.number().int().nullable(),
613
+ type: z.string(),
614
+ data: z.string(),
615
+ created_at: dateTimeSchema
616
+ });
617
+ var userReportSchema = z.object({
618
+ id: uuidSchema,
619
+ project_id: z.number().int(),
620
+ issue_id: uuidSchema.nullable(),
621
+ event_id: uuidSchema.nullable(),
622
+ name: z.string(),
623
+ // Server stores '' for anonymous reports (column DEFAULT '' / unwrap_or_default),
624
+ // matching real Sentry's own save_userreport(report.get("email", "")) — accept it.
625
+ email: z.union([z.email(), z.literal("")]),
626
+ comments: z.string(),
627
+ created_at: dateTimeSchema
628
+ });
629
+ var createCommentSchema = z.object({
630
+ text: z.string()
631
+ });
632
+ var createUserReportSchema = z.object({
633
+ name: z.string().optional(),
634
+ email: z.email().optional(),
635
+ comments: z.string().optional(),
636
+ event_id: uuidSchema.optional()
637
+ });
638
+ var bulkUpdateIssuesSchema = z.object({
639
+ ids: z.array(uuidSchema),
640
+ status: z.union([issueStatusSchema, z.literal("resolvedInNextRelease")]).optional(),
641
+ priority: issuePrioritySchema.optional()
642
+ });
643
+ var bulkDeleteIssuesSchema = z.object({
644
+ ids: z.array(uuidSchema)
645
+ });
646
+ var createDeploySchema = z.object({
647
+ version: z.string()
648
+ });
540
649
  var logSchema = z.object({
541
650
  id: uuidSchema,
542
651
  trace_id: z.string().nullable(),
@@ -569,7 +678,8 @@ var projectSchema = z.object({
569
678
  stored_event_count: z.number().int(),
570
679
  digested_event_count: z.number().int(),
571
680
  created_at: dateTimeSchema,
572
- updated_at: dateTimeSchema
681
+ updated_at: dateTimeSchema,
682
+ platform: z.string().nullable()
573
683
  });
574
684
  var createProjectSchema = z.object({
575
685
  name: z.string().min(1),
@@ -590,6 +700,22 @@ var releaseHealthRowSchema = z.object({
590
700
  crash_free_users_rate: z.number().nullable()
591
701
  });
592
702
  var releaseHealthSchema = z.array(releaseHealthRowSchema);
703
+ var sessionSummarySchema = z.object({
704
+ total: z.number().int(),
705
+ errored: z.number().int(),
706
+ crashed: z.number().int(),
707
+ abnormal: z.number().int(),
708
+ crash_free_sessions_rate: z.number().nullable(),
709
+ crash_free_users_rate: z.number().nullable(),
710
+ active_releases: z.number().int()
711
+ });
712
+ var sessionTimeseriesPointSchema = z.object({
713
+ bucket: dateTimeSchema,
714
+ total: z.number().int(),
715
+ crashed: z.number().int(),
716
+ crash_free_sessions_rate: z.number().nullable()
717
+ });
718
+ var sessionTimeseriesSchema = z.array(sessionTimeseriesPointSchema);
593
719
  var chunkUploadCapabilitySchema = z.object({
594
720
  url: z.string(),
595
721
  chunkSize: z.number().int(),
@@ -787,8 +913,6 @@ var InvitationsResource = class extends BaseResource {
787
913
  await this.http.delete(`api/invitations/${token}`);
788
914
  }
789
915
  };
790
-
791
- // src/resources/issues.ts
792
916
  var IssuesResource = class extends BaseResource {
793
917
  /**
794
918
  * List issues for a project with offset-based pagination
@@ -810,6 +934,9 @@ var IssuesResource = class extends BaseResource {
810
934
  if (options?.filter) {
811
935
  searchParams.filter = options.filter;
812
936
  }
937
+ if (options?.q) {
938
+ searchParams.q = options.q;
939
+ }
813
940
  const data = await this.http.get(`api/projects/${projectId}/issues`, { searchParams }).json();
814
941
  return this.validate(data, offsetPaginatedResponseSchema(issueSchema));
815
942
  }
@@ -821,7 +948,7 @@ var IssuesResource = class extends BaseResource {
821
948
  return this.validate(data, issueSchema);
822
949
  }
823
950
  /**
824
- * Update issue state (resolve, mute, etc.)
951
+ * Update issue state (status, substatus, priority, assignment, …)
825
952
  */
826
953
  async updateState(projectId, issueId, input) {
827
954
  const validatedInput = this.validate(input, updateIssueStateSchema);
@@ -830,12 +957,139 @@ var IssuesResource = class extends BaseResource {
830
957
  }).json();
831
958
  return this.validate(data, issueSchema);
832
959
  }
960
+ /**
961
+ * Resolve an issue in the next release (suppresses regression until a deploy).
962
+ */
963
+ async resolveInNextRelease(projectId, issueId) {
964
+ return this.updateState(projectId, issueId, {
965
+ status: "resolvedInNextRelease"
966
+ });
967
+ }
833
968
  /**
834
969
  * Delete an issue
835
970
  */
836
971
  async delete(projectId, issueId) {
837
972
  await this.http.delete(`api/projects/${projectId}/issues/${issueId}`);
838
973
  }
974
+ /**
975
+ * Bulk-mutate issues (status and/or priority).
976
+ */
977
+ async bulkUpdate(projectId, input) {
978
+ const validatedInput = this.validate(input, bulkUpdateIssuesSchema);
979
+ const data = await this.http.put(`api/projects/${projectId}/issues`, { json: validatedInput }).json();
980
+ return this.validate(data, z.object({ updated: z.number().int() }));
981
+ }
982
+ /**
983
+ * Bulk-delete issues.
984
+ */
985
+ async bulkDelete(projectId, input) {
986
+ const validatedInput = this.validate(input, bulkDeleteIssuesSchema);
987
+ const data = await this.http.delete(`api/projects/${projectId}/issues`, { json: validatedInput }).json();
988
+ return this.validate(data, z.object({ deleted: z.number().int() }));
989
+ }
990
+ /**
991
+ * List the grouping hashes that map to an issue.
992
+ */
993
+ async getHashes(projectId, issueId) {
994
+ const data = await this.http.get(`api/projects/${projectId}/issues/${issueId}/hashes`).json();
995
+ return this.validate(data, z.array(issueHashSchema));
996
+ }
997
+ /**
998
+ * List the distinct values (with counts) for a tag key across the issue.
999
+ * Returns a bare list, one entry per value (Sentry-compatible shape).
1000
+ */
1001
+ async getTagValues(projectId, issueId, key) {
1002
+ const data = await this.http.get(
1003
+ `api/projects/${projectId}/issues/${issueId}/tags/${encodeURIComponent(key)}`
1004
+ ).json();
1005
+ return this.validate(data, z.array(issueTagValueSchema));
1006
+ }
1007
+ /**
1008
+ * Fetch per-issue aggregates (unique user count + top tags).
1009
+ */
1010
+ async getAggregates(projectId, issueId) {
1011
+ const data = await this.http.get(`api/projects/${projectId}/issues/${issueId}/aggregates`).json();
1012
+ return this.validate(data, issueAggregatesSchema);
1013
+ }
1014
+ /**
1015
+ * Fetch a zero-filled event-count timeseries (24h or 30d).
1016
+ */
1017
+ async getStats(projectId, issueId, window = "24h") {
1018
+ const data = await this.http.get(`api/projects/${projectId}/issues/${issueId}/stats`, {
1019
+ searchParams: { window }
1020
+ }).json();
1021
+ return this.validate(data, issueStatsSchema);
1022
+ }
1023
+ /**
1024
+ * List an issue's activity log (status changes, comments/notes, …).
1025
+ */
1026
+ async getActivity(projectId, issueId) {
1027
+ const data = await this.http.get(`api/projects/${projectId}/issues/${issueId}/activity`).json();
1028
+ return this.validate(data, z.array(activityEntrySchema));
1029
+ }
1030
+ /**
1031
+ * Add a comment (note) to an issue.
1032
+ */
1033
+ async addComment(projectId, issueId, input) {
1034
+ const validatedInput = this.validate(input, createCommentSchema);
1035
+ const data = await this.http.post(`api/projects/${projectId}/issues/${issueId}/comments`, {
1036
+ json: validatedInput
1037
+ }).json();
1038
+ return this.validate(data, activityEntrySchema);
1039
+ }
1040
+ /**
1041
+ * Set or clear the current user's bookmark on an issue.
1042
+ */
1043
+ async setBookmark(projectId, issueId, enabled) {
1044
+ const data = await this.http.put(`api/projects/${projectId}/issues/${issueId}/bookmark`, {
1045
+ json: { enabled }
1046
+ }).json();
1047
+ return this.validate(data, z.object({ is_bookmarked: z.boolean() }));
1048
+ }
1049
+ /**
1050
+ * Set or clear the current user's subscription to an issue.
1051
+ */
1052
+ async setSubscription(projectId, issueId, enabled) {
1053
+ const data = await this.http.put(`api/projects/${projectId}/issues/${issueId}/subscription`, {
1054
+ json: { enabled }
1055
+ }).json();
1056
+ return this.validate(data, z.object({ is_subscribed: z.boolean() }));
1057
+ }
1058
+ /**
1059
+ * Mark the issue as seen by the current user.
1060
+ */
1061
+ async markSeen(projectId, issueId) {
1062
+ const data = await this.http.post(`api/projects/${projectId}/issues/${issueId}/seen`).json();
1063
+ return this.validate(data, z.object({ has_seen: z.boolean() }));
1064
+ }
1065
+ /**
1066
+ * List user feedback reports for an issue.
1067
+ */
1068
+ async listUserReports(projectId, issueId) {
1069
+ const data = await this.http.get(`api/projects/${projectId}/issues/${issueId}/user-reports`).json();
1070
+ return this.validate(data, z.array(userReportSchema));
1071
+ }
1072
+ /**
1073
+ * Attach a user feedback report to an issue.
1074
+ */
1075
+ async createUserReport(projectId, issueId, input) {
1076
+ const validatedInput = this.validate(input, createUserReportSchema);
1077
+ const data = await this.http.post(`api/projects/${projectId}/issues/${issueId}/user-reports`, {
1078
+ json: validatedInput
1079
+ }).json();
1080
+ return this.validate(data, userReportSchema);
1081
+ }
1082
+ /**
1083
+ * Record a deploy of a release, finalizing resolve-in-next-release issues.
1084
+ */
1085
+ async createDeploy(projectId, input) {
1086
+ const validatedInput = this.validate(input, createDeploySchema);
1087
+ const data = await this.http.post(`api/projects/${projectId}/deploys`, { json: validatedInput }).json();
1088
+ return this.validate(
1089
+ data,
1090
+ z.object({ version: z.string(), finalized: z.number().int() })
1091
+ );
1092
+ }
839
1093
  };
840
1094
 
841
1095
  // src/resources/logs.ts
@@ -945,6 +1199,26 @@ var ProjectsResource = class extends BaseResource {
945
1199
  await this.http.delete(`api/projects/${id}`);
946
1200
  }
947
1201
  };
1202
+ var ReleasesResource = class extends BaseResource {
1203
+ /**
1204
+ * Get issues first seen in a given release, most recently introduced first.
1205
+ *
1206
+ * @param projectId - Project ID
1207
+ * @param release - Release version
1208
+ * @param limit - Max issues to return (default: 10, max: 50)
1209
+ */
1210
+ async newIssues(projectId, release, limit) {
1211
+ const searchParams = {};
1212
+ if (limit !== void 0) {
1213
+ searchParams.limit = limit.toString();
1214
+ }
1215
+ const data = await this.http.get(
1216
+ `api/projects/${projectId}/releases/${encodeURIComponent(release)}/new-issues`,
1217
+ { searchParams }
1218
+ ).json();
1219
+ return this.validate(data, z.array(issueSchema));
1220
+ }
1221
+ };
948
1222
 
949
1223
  // src/resources/sessions.ts
950
1224
  var SessionsResource = class extends BaseResource {
@@ -952,15 +1226,51 @@ var SessionsResource = class extends BaseResource {
952
1226
  * Get per-release health stats for a project.
953
1227
  * @param projectId - Project ID
954
1228
  * @param period - Time window (e.g. '24h', '7d'). Defaults to '24h'.
1229
+ * @param release - Scope to a single release (all environments), computed
1230
+ * server-side. Omit to get every release in the project.
955
1231
  */
956
- async stats(projectId, period) {
1232
+ async stats(projectId, period, release) {
957
1233
  const searchParams = {};
958
1234
  if (period) {
959
1235
  searchParams.period = period;
960
1236
  }
1237
+ if (release) {
1238
+ searchParams.release = release;
1239
+ }
961
1240
  const data = await this.http.get(`api/projects/${projectId}/sessions/stats`, { searchParams }).json();
962
1241
  return this.validate(data, releaseHealthSchema);
963
1242
  }
1243
+ /**
1244
+ * Get project-wide session health, aggregated across all releases and environments.
1245
+ * @param projectId - Project ID
1246
+ * @param period - Time window (e.g. '24h', '7d'). Defaults to '24h'.
1247
+ */
1248
+ async summary(projectId, period) {
1249
+ const searchParams = {};
1250
+ if (period) {
1251
+ searchParams.period = period;
1252
+ }
1253
+ const data = await this.http.get(`api/projects/${projectId}/sessions/summary`, { searchParams }).json();
1254
+ return this.validate(data, sessionSummarySchema);
1255
+ }
1256
+ /**
1257
+ * Get a time-bucketed session trend for a project, aggregated across all
1258
+ * releases and environments.
1259
+ * @param projectId - Project ID
1260
+ * @param period - Time window (e.g. '24h', '7d'). Defaults to '24h'.
1261
+ * @param interval - Bucket width in hours (default: 1, max: 24).
1262
+ */
1263
+ async timeseries(projectId, period, interval) {
1264
+ const searchParams = {};
1265
+ if (period) {
1266
+ searchParams.period = period;
1267
+ }
1268
+ if (interval !== void 0) {
1269
+ searchParams.interval = interval.toString();
1270
+ }
1271
+ const data = await this.http.get(`api/projects/${projectId}/sessions/timeseries`, { searchParams }).json();
1272
+ return this.validate(data, sessionTimeseriesSchema);
1273
+ }
964
1274
  };
965
1275
 
966
1276
  // src/resources/sourcemaps.ts
@@ -1330,6 +1640,10 @@ var RustrakClient = class {
1330
1640
  * Sessions API resource (release health)
1331
1641
  */
1332
1642
  sessions;
1643
+ /**
1644
+ * Releases API resource (data scoped to a specific release)
1645
+ */
1646
+ releases;
1333
1647
  /**
1334
1648
  * Transactions API resource (performance monitoring)
1335
1649
  */
@@ -1365,6 +1679,7 @@ var RustrakClient = class {
1365
1679
  this.invitations = new InvitationsResource(this.http);
1366
1680
  this.members = new MembersResource(this.http);
1367
1681
  this.sessions = new SessionsResource(this.http);
1682
+ this.releases = new ReleasesResource(this.http);
1368
1683
  this.transactions = new TransactionsResource(this.http);
1369
1684
  this.logs = new LogsResource(this.http);
1370
1685
  this.storage = new StorageResource(this.http);