@rustrak/client 0.2.1 → 0.3.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
@@ -7,7 +7,7 @@ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
7
7
 
8
8
  var ky__default = /*#__PURE__*/_interopDefault(ky);
9
9
 
10
- // src/resources/alert-channels.ts
10
+ // src/resources/alert-integrations.ts
11
11
  var paginatedResponseSchema = (itemSchema) => zod.z.object({
12
12
  items: zod.z.array(itemSchema),
13
13
  next_cursor: zod.z.string().optional(),
@@ -31,7 +31,7 @@ zod.z.object({
31
31
  });
32
32
 
33
33
  // src/schemas/alert.ts
34
- var channelTypeSchema = zod.z.enum(["webhook", "email", "slack"]);
34
+ var providerTypeSchema = zod.z.enum(["webhook", "email", "slack"]);
35
35
  var alertTypeSchema = zod.z.enum(["new_issue", "regression", "unmute"]);
36
36
  var alertStatusSchema = zod.z.enum([
37
37
  "pending",
@@ -39,11 +39,11 @@ var alertStatusSchema = zod.z.enum([
39
39
  "failed",
40
40
  "skipped"
41
41
  ]);
42
- var notificationChannelSchema = zod.z.object({
42
+ var alertIntegrationSchema = zod.z.object({
43
43
  id: zod.z.number().int(),
44
44
  name: zod.z.string(),
45
- channel_type: channelTypeSchema,
46
- config: zod.z.record(zod.z.string(), zod.z.unknown()),
45
+ provider_type: providerTypeSchema,
46
+ credentials: zod.z.record(zod.z.string(), zod.z.unknown()),
47
47
  is_enabled: zod.z.boolean(),
48
48
  failure_count: zod.z.number().int(),
49
49
  last_failure_at: dateTimeSchema.nullable(),
@@ -52,17 +52,21 @@ var notificationChannelSchema = zod.z.object({
52
52
  created_at: dateTimeSchema,
53
53
  updated_at: dateTimeSchema
54
54
  });
55
- var createNotificationChannelSchema = zod.z.object({
55
+ var createAlertIntegrationSchema = zod.z.object({
56
56
  name: zod.z.string().min(1),
57
- channel_type: channelTypeSchema,
58
- config: zod.z.record(zod.z.string(), zod.z.unknown()),
57
+ provider_type: providerTypeSchema,
58
+ credentials: zod.z.record(zod.z.string(), zod.z.unknown()),
59
59
  is_enabled: zod.z.boolean().optional()
60
60
  });
61
- var updateNotificationChannelSchema = zod.z.object({
61
+ var updateAlertIntegrationSchema = zod.z.object({
62
62
  name: zod.z.string().min(1).optional(),
63
- config: zod.z.record(zod.z.string(), zod.z.unknown()).optional(),
63
+ credentials: zod.z.record(zod.z.string(), zod.z.unknown()).optional(),
64
64
  is_enabled: zod.z.boolean().optional()
65
65
  });
66
+ var alertRuleChannelInputSchema = zod.z.object({
67
+ integration_id: zod.z.number().int(),
68
+ routing_override: zod.z.record(zod.z.string(), zod.z.unknown()).default({})
69
+ });
66
70
  var alertRuleSchema = zod.z.object({
67
71
  id: zod.z.number().int(),
68
72
  project_id: zod.z.number().int(),
@@ -74,12 +78,13 @@ var alertRuleSchema = zod.z.object({
74
78
  last_triggered_at: dateTimeSchema.nullable(),
75
79
  created_at: dateTimeSchema,
76
80
  updated_at: dateTimeSchema,
77
- channel_ids: zod.z.array(zod.z.number().int())
81
+ channels: zod.z.array(alertRuleChannelInputSchema).default([]),
82
+ integration_ids: zod.z.array(zod.z.number().int())
78
83
  });
79
84
  var createAlertRuleSchema = zod.z.object({
80
85
  name: zod.z.string().min(1),
81
86
  alert_type: alertTypeSchema,
82
- channel_ids: zod.z.array(zod.z.number().int()).min(1),
87
+ channels: zod.z.array(alertRuleChannelInputSchema).default([]),
83
88
  is_enabled: zod.z.boolean().optional(),
84
89
  conditions: zod.z.record(zod.z.string(), zod.z.unknown()).optional(),
85
90
  cooldown_minutes: zod.z.number().int().min(0).optional()
@@ -89,12 +94,12 @@ var updateAlertRuleSchema = zod.z.object({
89
94
  is_enabled: zod.z.boolean().optional(),
90
95
  conditions: zod.z.record(zod.z.string(), zod.z.unknown()).optional(),
91
96
  cooldown_minutes: zod.z.number().int().min(0).optional(),
92
- channel_ids: zod.z.array(zod.z.number().int()).optional()
97
+ channels: zod.z.array(alertRuleChannelInputSchema).optional()
93
98
  });
94
99
  var alertHistorySchema = zod.z.object({
95
100
  id: zod.z.number().int(),
96
101
  alert_rule_id: zod.z.number().int().nullable(),
97
- channel_id: zod.z.number().int().nullable(),
102
+ integration_id: zod.z.number().int().nullable(),
98
103
  issue_id: zod.z.string().uuid().nullable(),
99
104
  project_id: zod.z.number().int().nullable(),
100
105
  alert_type: zod.z.string(),
@@ -113,6 +118,9 @@ var testChannelResponseSchema = zod.z.object({
113
118
  success: zod.z.boolean(),
114
119
  message: zod.z.string()
115
120
  });
121
+ var testIntegrationBodySchema = zod.z.object({
122
+ routing_override: zod.z.record(zod.z.string(), zod.z.unknown()).optional()
123
+ });
116
124
 
117
125
  // src/errors/base.ts
118
126
  var RustrakError = class extends Error {
@@ -228,55 +236,57 @@ var BaseResource = class {
228
236
  }
229
237
  };
230
238
 
231
- // src/resources/alert-channels.ts
232
- var AlertChannelsResource = class extends BaseResource {
239
+ // src/resources/alert-integrations.ts
240
+ var AlertIntegrationsResource = class extends BaseResource {
233
241
  /**
234
- * List all notification channels
242
+ * List all alert integrations
235
243
  */
236
244
  async list() {
237
- const data = await this.http.get("api/alert-channels").json();
238
- return this.validate(data, zod.z.array(notificationChannelSchema));
245
+ const data = await this.http.get("api/integrations").json();
246
+ return this.validate(data, zod.z.array(alertIntegrationSchema));
239
247
  }
240
248
  /**
241
- * Get a single notification channel by ID
249
+ * Get a single alert integration by ID
242
250
  */
243
251
  async get(id) {
244
- const data = await this.http.get(`api/alert-channels/${id}`).json();
245
- return this.validate(data, notificationChannelSchema);
252
+ const data = await this.http.get(`api/integrations/${id}`).json();
253
+ return this.validate(data, alertIntegrationSchema);
246
254
  }
247
255
  /**
248
- * Create a new notification channel
256
+ * Create a new alert integration
249
257
  */
250
258
  async create(input) {
251
- const validatedInput = this.validate(
252
- input,
253
- createNotificationChannelSchema
254
- );
255
- const data = await this.http.post("api/alert-channels", { json: validatedInput }).json();
256
- return this.validate(data, notificationChannelSchema);
259
+ const validatedInput = this.validate(input, createAlertIntegrationSchema);
260
+ const data = await this.http.post("api/integrations", { json: validatedInput }).json();
261
+ return this.validate(data, alertIntegrationSchema);
257
262
  }
258
263
  /**
259
- * Update an existing notification channel
264
+ * Update an existing alert integration
260
265
  */
261
266
  async update(id, input) {
262
- const validatedInput = this.validate(
263
- input,
264
- updateNotificationChannelSchema
265
- );
266
- const data = await this.http.patch(`api/alert-channels/${id}`, { json: validatedInput }).json();
267
- return this.validate(data, notificationChannelSchema);
267
+ const validatedInput = this.validate(input, updateAlertIntegrationSchema);
268
+ const data = await this.http.patch(`api/integrations/${id}`, { json: validatedInput }).json();
269
+ return this.validate(data, alertIntegrationSchema);
268
270
  }
269
271
  /**
270
- * Delete a notification channel
272
+ * Delete an alert integration
271
273
  */
272
274
  async delete(id) {
273
- await this.http.delete(`api/alert-channels/${id}`);
275
+ await this.http.delete(`api/integrations/${id}`);
274
276
  }
275
277
  /**
276
- * Send a test notification to verify channel configuration
278
+ * Send a test notification to verify integration configuration.
279
+ * For Slack bot_token integrations, routingOverride must include `channel`.
277
280
  */
278
- async test(id) {
279
- const data = await this.http.post(`api/alert-channels/${id}/test`).json();
281
+ async test(id, routingOverride) {
282
+ const body = routingOverride !== void 0 ? this.validate(
283
+ { routing_override: routingOverride },
284
+ testIntegrationBodySchema
285
+ ) : void 0;
286
+ const data = await this.http.post(
287
+ `api/integrations/${id}/test`,
288
+ body !== void 0 ? { json: body } : void 0
289
+ ).json();
280
290
  return this.validate(data, testChannelResponseSchema);
281
291
  }
282
292
  };
@@ -333,9 +343,49 @@ var AlertRulesResource = class extends BaseResource {
333
343
  return this.validate(data, zod.z.array(alertHistorySchema));
334
344
  }
335
345
  };
346
+ var globalRoleSchema = zod.z.enum(["admin", "member"]);
347
+ var teamMemberSchema = zod.z.object({
348
+ id: zod.z.number().int(),
349
+ email: zod.z.string().email(),
350
+ role: globalRoleSchema,
351
+ is_active: zod.z.boolean(),
352
+ /** True for the first-registered account, which cannot be demoted or deleted. */
353
+ is_primary: zod.z.boolean().optional(),
354
+ created_at: dateTimeSchema,
355
+ last_login: dateTimeSchema.nullable().optional()
356
+ });
357
+ var updateUserRoleSchema = zod.z.object({
358
+ role: globalRoleSchema
359
+ });
360
+
361
+ // src/schemas/invitation.ts
362
+ var invitationStatusSchema = zod.z.string();
363
+ var invitationSchema = zod.z.object({
364
+ token: zod.z.string(),
365
+ email: zod.z.string().email(),
366
+ role: globalRoleSchema,
367
+ status: invitationStatusSchema,
368
+ expires_at: dateTimeSchema,
369
+ created_at: dateTimeSchema
370
+ });
371
+ var invitationInfoSchema = zod.z.object({
372
+ email: zod.z.string().email(),
373
+ role: globalRoleSchema,
374
+ status: invitationStatusSchema,
375
+ expires_at: dateTimeSchema
376
+ });
377
+ var createInvitationSchema = zod.z.object({
378
+ email: zod.z.string().email(),
379
+ role: globalRoleSchema
380
+ });
381
+ var acceptInvitationSchema = zod.z.object({
382
+ token: zod.z.string().min(1),
383
+ password: zod.z.string().min(1)
384
+ });
336
385
  var userSchema = zod.z.object({
337
386
  id: zod.z.number().int().positive(),
338
387
  email: zod.z.string().email(),
388
+ role: globalRoleSchema,
339
389
  is_admin: zod.z.boolean()
340
390
  });
341
391
  var authResponseSchema = zod.z.object({
@@ -347,11 +397,11 @@ zod.z.object({
347
397
  });
348
398
  var loginRequestSchema = zod.z.object({
349
399
  email: zod.z.string().email(),
350
- password: zod.z.string().min(8)
400
+ password: zod.z.string().min(1)
351
401
  });
352
402
  var registerRequestSchema = zod.z.object({
353
403
  email: zod.z.string().email(),
354
- password: zod.z.string().min(8)
404
+ password: zod.z.string().min(1)
355
405
  });
356
406
 
357
407
  // src/resources/auth.ts
@@ -412,6 +462,34 @@ var AuthResource = class extends BaseResource {
412
462
  const data = await this.http.get("auth/me").json();
413
463
  return this.validate(data, userSchema);
414
464
  }
465
+ /**
466
+ * Get the details of a pending invitation by its token (public endpoint)
467
+ * Used by the accept-invitation page before the user has an account
468
+ * @param token - Invitation token
469
+ * @returns Invitation info (email, role, status, expiry)
470
+ */
471
+ async getInvitation(token) {
472
+ const data = await this.http.get(`auth/invitation/${token}`).json();
473
+ return this.validate(data, invitationInfoSchema);
474
+ }
475
+ /**
476
+ * Accept a pending invitation, creating the user account and logging in
477
+ * @param input - Invitation token and the new account's password
478
+ * @returns LoginResult with user information and session cookies
479
+ */
480
+ async acceptInvitation(input) {
481
+ const validatedInput = this.validate(input, acceptInvitationSchema);
482
+ const response = await this.http.post("auth/accept-invitation", {
483
+ json: validatedInput
484
+ });
485
+ const cookies = response.headers.getSetCookie();
486
+ const data = await response.json();
487
+ const authResponse = this.validate(data, authResponseSchema);
488
+ return {
489
+ user: authResponse.user,
490
+ cookies
491
+ };
492
+ }
415
493
  };
416
494
  var eventSchema = zod.z.object({
417
495
  id: uuidSchema,
@@ -459,6 +537,17 @@ var updateIssueStateSchema = zod.z.object({
459
537
  is_resolved: zod.z.boolean().optional(),
460
538
  is_muted: zod.z.boolean().optional()
461
539
  });
540
+ var projectRoleSchema = zod.z.enum(["viewer", "editor", "admin"]);
541
+ var projectMemberSchema = zod.z.object({
542
+ user_id: zod.z.number().int(),
543
+ email: zod.z.string().email(),
544
+ role: projectRoleSchema,
545
+ created_at: dateTimeSchema
546
+ });
547
+ var upsertProjectMemberSchema = zod.z.object({
548
+ user_id: zod.z.number().int(),
549
+ role: projectRoleSchema
550
+ });
462
551
  var projectSchema = zod.z.object({
463
552
  id: zod.z.number().int(),
464
553
  name: zod.z.string(),
@@ -545,6 +634,33 @@ var EventsResource = class extends BaseResource {
545
634
  }
546
635
  };
547
636
 
637
+ // src/resources/invitations.ts
638
+ var InvitationsResource = class extends BaseResource {
639
+ /**
640
+ * Create a new invitation
641
+ * @param input - Email and global role for the invited user
642
+ */
643
+ async create(input) {
644
+ const validatedInput = this.validate(input, createInvitationSchema);
645
+ const data = await this.http.post("api/invitations", { json: validatedInput }).json();
646
+ return this.validate(data, invitationSchema);
647
+ }
648
+ /**
649
+ * List all invitations
650
+ */
651
+ async list() {
652
+ const data = await this.http.get("api/invitations").json();
653
+ return this.validate(data, invitationSchema.array());
654
+ }
655
+ /**
656
+ * Revoke a pending invitation
657
+ * @param token - Invitation token to revoke
658
+ */
659
+ async revoke(token) {
660
+ await this.http.delete(`api/invitations/${token}`);
661
+ }
662
+ };
663
+
548
664
  // src/resources/issues.ts
549
665
  var IssuesResource = class extends BaseResource {
550
666
  /**
@@ -595,6 +711,37 @@ var IssuesResource = class extends BaseResource {
595
711
  }
596
712
  };
597
713
 
714
+ // src/resources/members.ts
715
+ var MembersResource = class extends BaseResource {
716
+ /**
717
+ * List members of a project
718
+ * @param projectId - ID of the project
719
+ */
720
+ async list(projectId) {
721
+ const data = await this.http.get(`api/projects/${projectId}/members`).json();
722
+ return this.validate(data, projectMemberSchema.array());
723
+ }
724
+ /**
725
+ * Add or update a project member
726
+ * @param projectId - ID of the project
727
+ * @param input - User ID and per-project role
728
+ */
729
+ async upsert(projectId, input) {
730
+ const validatedInput = this.validate(input, upsertProjectMemberSchema);
731
+ await this.http.put(`api/projects/${projectId}/members`, {
732
+ json: validatedInput
733
+ });
734
+ }
735
+ /**
736
+ * Remove a member from a project
737
+ * @param projectId - ID of the project
738
+ * @param userId - ID of the user to remove
739
+ */
740
+ async remove(projectId, userId) {
741
+ await this.http.delete(`api/projects/${projectId}/members/${userId}`);
742
+ }
743
+ };
744
+
598
745
  // src/resources/projects.ts
599
746
  var ProjectsResource = class extends BaseResource {
600
747
  /**
@@ -699,6 +846,33 @@ var SourceMapsResource = class extends BaseResource {
699
846
  }
700
847
  };
701
848
 
849
+ // src/resources/team.ts
850
+ var TeamResource = class extends BaseResource {
851
+ /**
852
+ * List all team members (users)
853
+ */
854
+ async list() {
855
+ const data = await this.http.get("api/team").json();
856
+ return this.validate(data, teamMemberSchema.array());
857
+ }
858
+ /**
859
+ * Change a user's global role
860
+ * @param userId - ID of the user to update
861
+ * @param role - New global role to assign
862
+ */
863
+ async updateRole(userId, role) {
864
+ const body = this.validate({ role }, updateUserRoleSchema);
865
+ await this.http.patch(`api/team/${userId}/role`, { json: body });
866
+ }
867
+ /**
868
+ * Permanently remove a user from the instance.
869
+ * @param userId - ID of the user to delete
870
+ */
871
+ async remove(userId) {
872
+ await this.http.delete(`api/team/${userId}`);
873
+ }
874
+ };
875
+
702
876
  // src/resources/tokens.ts
703
877
  var TokensResource = class extends BaseResource {
704
878
  /**
@@ -819,9 +993,9 @@ var RustrakClient = class {
819
993
  */
820
994
  tokens;
821
995
  /**
822
- * Alert Channels API resource (global notification destinations)
996
+ * Alert Integrations API resource (global credential destinations)
823
997
  */
824
- alertChannels;
998
+ alertIntegrations;
825
999
  /**
826
1000
  * Alert Rules API resource (per-project alert configuration)
827
1001
  */
@@ -830,6 +1004,18 @@ var RustrakClient = class {
830
1004
  * Source Maps API resource (sentry-cli artifact bundle upload protocol)
831
1005
  */
832
1006
  sourceMaps;
1007
+ /**
1008
+ * Team API resource (global user roster and roles)
1009
+ */
1010
+ team;
1011
+ /**
1012
+ * Invitations API resource (pending user invitations)
1013
+ */
1014
+ invitations;
1015
+ /**
1016
+ * Project Members API resource (per-project membership and roles)
1017
+ */
1018
+ members;
833
1019
  /**
834
1020
  * Create a new Rustrak API client
835
1021
  *
@@ -842,9 +1028,12 @@ var RustrakClient = class {
842
1028
  this.issues = new IssuesResource(this.http);
843
1029
  this.events = new EventsResource(this.http);
844
1030
  this.tokens = new TokensResource(this.http);
845
- this.alertChannels = new AlertChannelsResource(this.http);
1031
+ this.alertIntegrations = new AlertIntegrationsResource(this.http);
846
1032
  this.alertRules = new AlertRulesResource(this.http);
847
1033
  this.sourceMaps = new SourceMapsResource(this.http);
1034
+ this.team = new TeamResource(this.http);
1035
+ this.invitations = new InvitationsResource(this.http);
1036
+ this.members = new MembersResource(this.http);
848
1037
  }
849
1038
  };
850
1039