@keystrokehq/sentry 0.0.15 → 0.0.16-integration-id-canonicalization.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.
Files changed (80) hide show
  1. package/README.md +40 -187
  2. package/dist/credential-sets/index.d.mts +2 -0
  3. package/dist/credential-sets/index.mjs +4 -0
  4. package/dist/index.d.mts +4 -1
  5. package/dist/index.mjs +6 -1
  6. package/dist/operations/index.d.mts +2 -0
  7. package/dist/operations/index.mjs +3 -0
  8. package/dist/{schemas.d.mts → schemas/index.d.mts} +3 -3
  9. package/dist/schemas/index.mjs +3 -0
  10. package/dist/{schemas.mjs → sentry-api-DjJ24hwX.mjs} +2 -2
  11. package/dist/sentry-app.credential-set-4DLRUKF9.d.mts +59 -0
  12. package/dist/sentry-app.credential-set-Cdj6Qxiz.mjs +23 -0
  13. package/dist/sentry.credential-set-2b3TPFqv.mjs +696 -0
  14. package/dist/view-organization-notification-actions.operation-BI2aB_Mj.mjs +4548 -0
  15. package/dist/view-organization-notification-actions.operation-C7pc8cl_.d.mts +6840 -0
  16. package/package.json +14 -121
  17. package/dist/_official/index.d.mts +0 -41
  18. package/dist/_official/index.mjs +0 -3
  19. package/dist/_runtime/index.d.mts +0 -2
  20. package/dist/_runtime/index.mjs +0 -3
  21. package/dist/alerts.d.mts +0 -462
  22. package/dist/alerts.mjs +0 -300
  23. package/dist/client.d.mts +0 -86
  24. package/dist/client.mjs +0 -233
  25. package/dist/connection.d.mts +0 -3
  26. package/dist/connection.mjs +0 -3
  27. package/dist/dashboards.d.mts +0 -162
  28. package/dist/dashboards.mjs +0 -122
  29. package/dist/debug-files.d.mts +0 -102
  30. package/dist/debug-files.mjs +0 -73
  31. package/dist/deploys.d.mts +0 -86
  32. package/dist/deploys.mjs +0 -67
  33. package/dist/discover.d.mts +0 -194
  34. package/dist/discover.mjs +0 -138
  35. package/dist/endpoint-factory-DcT49a8O.mjs +0 -96
  36. package/dist/environments.d.mts +0 -96
  37. package/dist/environments.mjs +0 -71
  38. package/dist/errors-DfEFwcTe.mjs +0 -142
  39. package/dist/events-api.d.mts +0 -254
  40. package/dist/events-api.mjs +0 -184
  41. package/dist/events.d.mts +0 -754
  42. package/dist/events.mjs +0 -142
  43. package/dist/feedback.d.mts +0 -82
  44. package/dist/feedback.mjs +0 -63
  45. package/dist/integration-D7KCM1-p.mjs +0 -75
  46. package/dist/integration-veqa_7yB.d.mts +0 -33
  47. package/dist/issues.d.mts +0 -458
  48. package/dist/issues.mjs +0 -324
  49. package/dist/members.d.mts +0 -308
  50. package/dist/members.mjs +0 -156
  51. package/dist/messaging.d.mts +0 -1
  52. package/dist/messaging.mjs +0 -1
  53. package/dist/monitors.d.mts +0 -458
  54. package/dist/monitors.mjs +0 -234
  55. package/dist/notifications.d.mts +0 -180
  56. package/dist/notifications.mjs +0 -133
  57. package/dist/organizations.d.mts +0 -442
  58. package/dist/organizations.mjs +0 -334
  59. package/dist/pagination-PlgAqbZt.mjs +0 -116
  60. package/dist/project-keys.d.mts +0 -246
  61. package/dist/project-keys.mjs +0 -122
  62. package/dist/projects.d.mts +0 -534
  63. package/dist/projects.mjs +0 -378
  64. package/dist/releases.d.mts +0 -780
  65. package/dist/releases.mjs +0 -479
  66. package/dist/replays.d.mts +0 -234
  67. package/dist/replays.mjs +0 -192
  68. package/dist/scim.d.mts +0 -324
  69. package/dist/scim.mjs +0 -249
  70. package/dist/scopes-RRU0vt-a.mjs +0 -36
  71. package/dist/teams.d.mts +0 -448
  72. package/dist/teams.mjs +0 -266
  73. package/dist/triggers.d.mts +0 -41
  74. package/dist/triggers.mjs +0 -56
  75. package/dist/user-emails.d.mts +0 -84
  76. package/dist/user-emails.mjs +0 -60
  77. package/dist/verification.d.mts +0 -30
  78. package/dist/verification.mjs +0 -83
  79. package/dist/webhooks.d.mts +0 -158
  80. package/dist/webhooks.mjs +0 -108
package/dist/teams.mjs DELETED
@@ -1,266 +0,0 @@
1
- import { orgScopeInputSchema, orgTeamScopeInputSchema, sentryIdSchema, sentryJsonObjectSchema, sentryListInputSchema, sentryMemberSchema, sentryProjectSummarySchema, sentrySlugSchema, sentryTeamSchema } from "./schemas.mjs";
2
- import { t as defineSentryEndpoint } from "./endpoint-factory-DcT49a8O.mjs";
3
- import { t as SENTRY_SCOPE } from "./scopes-RRU0vt-a.mjs";
4
- import { z } from "zod";
5
-
6
- //#region src/teams.ts
7
- /**
8
- * Sentry team operations. Maps to PLAN.md §6.3 (14 actions).
9
- */
10
- const ORG = [{
11
- name: "organization_slug",
12
- placeholder: "{organization_slug}"
13
- }];
14
- const ORG_TEAM = [...ORG, {
15
- name: "team_slug",
16
- placeholder: "{team_slug}"
17
- }];
18
- const ORG_TEAM_MEMBER = [...ORG_TEAM, {
19
- name: "member_id",
20
- placeholder: "{member_id}"
21
- }];
22
- const listTeamsInOrganization = defineSentryEndpoint({
23
- id: "sentry.list-teams-in-organization",
24
- name: "List Teams In Organization",
25
- description: "List the teams in an organization with pagination.",
26
- method: "GET",
27
- path: "/api/0/organizations/{organization_slug}/teams/",
28
- pathParams: ORG,
29
- input: sentryListInputSchema.merge(orgScopeInputSchema).extend({ detailed: z.string().optional() }),
30
- queryFields: [
31
- "query",
32
- "cursor",
33
- "per_page",
34
- "detailed"
35
- ],
36
- output: z.array(sentryTeamSchema),
37
- pagination: "cursor",
38
- requiredOAuthScopes: [...SENTRY_SCOPE.teamRead]
39
- });
40
- const listOrganizationUserTeams = defineSentryEndpoint({
41
- id: "sentry.list-organization-user-teams",
42
- name: "List Teams For Current User",
43
- description: "List the teams the authenticated user belongs to in this organization.",
44
- method: "GET",
45
- path: "/api/0/organizations/{organization_slug}/user-teams/",
46
- pathParams: ORG,
47
- input: orgScopeInputSchema,
48
- output: z.array(sentryTeamSchema),
49
- requiredOAuthScopes: [...SENTRY_SCOPE.teamRead]
50
- });
51
- const createOrganizationTeam = defineSentryEndpoint({
52
- id: "sentry.create-organization-team",
53
- name: "Create Organization Team",
54
- description: "Create a new team inside the organization.",
55
- method: "POST",
56
- path: "/api/0/organizations/{organization_slug}/teams/",
57
- pathParams: ORG,
58
- input: orgScopeInputSchema.extend({
59
- slug: sentrySlugSchema.optional(),
60
- name: z.string().min(1).optional(),
61
- idp_provisioned: z.boolean().optional()
62
- }),
63
- bodyFields: [
64
- "slug",
65
- "name",
66
- "idp_provisioned"
67
- ],
68
- output: sentryTeamSchema,
69
- needsApproval: true,
70
- requiredOAuthScopes: [...SENTRY_SCOPE.teamWrite]
71
- });
72
- const retrieveTeamInfoViaOrganizationIdOrSlug = defineSentryEndpoint({
73
- id: "sentry.retrieve-team-info-via-organization-id-or-slug",
74
- name: "Retrieve Team Info",
75
- description: "Fetch a single team by its slug.",
76
- method: "GET",
77
- path: "/api/0/teams/{organization_slug}/{team_slug}/",
78
- pathParams: ORG_TEAM,
79
- input: orgTeamScopeInputSchema,
80
- output: sentryTeamSchema,
81
- requiredOAuthScopes: [...SENTRY_SCOPE.teamRead]
82
- });
83
- const updateTeamInformationByOrganizationId = defineSentryEndpoint({
84
- id: "sentry.update-team-information-by-organization-id",
85
- name: "Update Team",
86
- description: "Update a team’s slug or display name.",
87
- method: "PUT",
88
- path: "/api/0/teams/{organization_slug}/{team_slug}/",
89
- pathParams: ORG_TEAM,
90
- input: orgTeamScopeInputSchema.extend({
91
- slug: sentrySlugSchema.optional(),
92
- name: z.string().min(1).optional()
93
- }),
94
- bodyFields: ["slug", "name"],
95
- output: sentryTeamSchema,
96
- needsApproval: true,
97
- requiredOAuthScopes: [...SENTRY_SCOPE.teamWrite]
98
- });
99
- const deleteTeamByOrganizationOrTeamSlug = defineSentryEndpoint({
100
- id: "sentry.delete-team-by-organization-or-team-slug",
101
- name: "Delete Team",
102
- description: "Delete a team by slug.",
103
- method: "DELETE",
104
- path: "/api/0/teams/{organization_slug}/{team_slug}/",
105
- pathParams: ORG_TEAM,
106
- input: orgTeamScopeInputSchema,
107
- output: z.unknown(),
108
- needsApproval: true,
109
- requiredOAuthScopes: [...SENTRY_SCOPE.teamAdmin]
110
- });
111
- const addTeamMemberInOrganization = defineSentryEndpoint({
112
- id: "sentry.add-team-member-in-organization",
113
- name: "Add Team Member",
114
- description: "Add a member to a team.",
115
- method: "POST",
116
- path: "/api/0/organizations/{organization_slug}/members/{member_id}/teams/{team_slug}/",
117
- pathParams: ORG_TEAM_MEMBER,
118
- input: orgTeamScopeInputSchema.extend({ member_id: sentryIdSchema }),
119
- output: sentryMemberSchema,
120
- needsApproval: true,
121
- requiredOAuthScopes: [...SENTRY_SCOPE.teamWrite]
122
- });
123
- const getTeamMembersByIdOrSlug = defineSentryEndpoint({
124
- id: "sentry.get-team-members-by-id-or-slug",
125
- name: "Get Team Members",
126
- description: "List the members of a team.",
127
- method: "GET",
128
- path: "/api/0/teams/{organization_slug}/{team_slug}/members/",
129
- pathParams: ORG_TEAM,
130
- input: sentryListInputSchema.merge(orgTeamScopeInputSchema),
131
- queryFields: [
132
- "cursor",
133
- "per_page",
134
- "query"
135
- ],
136
- output: z.array(sentryMemberSchema),
137
- pagination: "cursor",
138
- requiredOAuthScopes: [...SENTRY_SCOPE.teamRead]
139
- });
140
- const deleteMemberFromTeam = defineSentryEndpoint({
141
- id: "sentry.delete-member-from-team",
142
- name: "Remove Member From Team",
143
- description: "Remove a member from a team.",
144
- method: "DELETE",
145
- path: "/api/0/organizations/{organization_slug}/members/{member_id}/teams/{team_slug}/",
146
- pathParams: ORG_TEAM_MEMBER,
147
- input: orgTeamScopeInputSchema.extend({ member_id: sentryIdSchema }),
148
- output: z.unknown(),
149
- needsApproval: true,
150
- requiredOAuthScopes: [...SENTRY_SCOPE.teamWrite]
151
- });
152
- const switchTeamRoleForMember = defineSentryEndpoint({
153
- id: "sentry.switch-team-role-for-member",
154
- name: "Switch Member Team Role",
155
- description: "Update a member’s role within a team.",
156
- method: "PUT",
157
- path: "/api/0/organizations/{organization_slug}/members/{member_id}/teams/{team_slug}/",
158
- pathParams: ORG_TEAM_MEMBER,
159
- input: orgTeamScopeInputSchema.extend({
160
- member_id: sentryIdSchema,
161
- teamRole: z.string().nullable()
162
- }),
163
- bodyFields: ["teamRole"],
164
- output: sentryMemberSchema,
165
- needsApproval: true,
166
- requiredOAuthScopes: [...SENTRY_SCOPE.teamWrite]
167
- });
168
- const retrieveTeamProjects = defineSentryEndpoint({
169
- id: "sentry.retrieve-team-projects",
170
- name: "Retrieve Team Projects",
171
- description: "List the projects owned by a team.",
172
- method: "GET",
173
- path: "/api/0/teams/{organization_slug}/{team_slug}/projects/",
174
- pathParams: ORG_TEAM,
175
- input: sentryListInputSchema.merge(orgTeamScopeInputSchema),
176
- queryFields: [
177
- "cursor",
178
- "per_page",
179
- "query"
180
- ],
181
- output: z.array(sentryProjectSummarySchema),
182
- pagination: "cursor",
183
- requiredOAuthScopes: [...SENTRY_SCOPE.projectRead]
184
- });
185
- const manageTeamExternalIntegrations = defineSentryEndpoint({
186
- id: "sentry.manage-team-external-integrations",
187
- name: "Manage Team External Integrations",
188
- description: "Create an external-team link between a Sentry team and a third-party team (Slack, PagerDuty, etc.).",
189
- method: "POST",
190
- path: "/api/0/teams/{organization_slug}/{team_slug}/external-teams/",
191
- pathParams: ORG_TEAM,
192
- input: orgTeamScopeInputSchema.extend({
193
- externalName: z.string().min(1),
194
- provider: z.string().min(1),
195
- externalId: z.string().optional(),
196
- integrationId: z.string().optional()
197
- }),
198
- bodyFields: [
199
- "externalName",
200
- "provider",
201
- "externalId",
202
- "integrationId"
203
- ],
204
- output: sentryJsonObjectSchema,
205
- needsApproval: true,
206
- requiredOAuthScopes: [...SENTRY_SCOPE.teamWrite]
207
- });
208
- const updateExternalTeamIntegration = defineSentryEndpoint({
209
- id: "sentry.update-external-team-integration",
210
- name: "Update External Team Integration",
211
- description: "Update an existing external-team link by id.",
212
- method: "PUT",
213
- path: "/api/0/teams/{organization_slug}/{team_slug}/external-teams/{external_team_id}/",
214
- pathParams: [...ORG_TEAM, {
215
- name: "external_team_id",
216
- placeholder: "{external_team_id}"
217
- }],
218
- input: orgTeamScopeInputSchema.extend({
219
- external_team_id: sentryIdSchema,
220
- externalName: z.string().min(1).optional(),
221
- integrationId: z.string().optional(),
222
- externalId: z.string().optional()
223
- }),
224
- bodyFields: [
225
- "externalName",
226
- "integrationId",
227
- "externalId"
228
- ],
229
- output: sentryJsonObjectSchema,
230
- needsApproval: true,
231
- requiredOAuthScopes: [...SENTRY_SCOPE.teamWrite]
232
- });
233
- const deleteExternalTeamById = defineSentryEndpoint({
234
- id: "sentry.delete-external-team-by-id",
235
- name: "Delete External Team",
236
- description: "Remove an external-team link by id.",
237
- method: "DELETE",
238
- path: "/api/0/teams/{organization_slug}/{team_slug}/external-teams/{external_team_id}/",
239
- pathParams: [...ORG_TEAM, {
240
- name: "external_team_id",
241
- placeholder: "{external_team_id}"
242
- }],
243
- input: orgTeamScopeInputSchema.extend({ external_team_id: sentryIdSchema }),
244
- output: z.unknown(),
245
- needsApproval: true,
246
- requiredOAuthScopes: [...SENTRY_SCOPE.teamAdmin]
247
- });
248
- const sentryTeamOperations = {
249
- listTeamsInOrganization,
250
- listOrganizationUserTeams,
251
- createOrganizationTeam,
252
- retrieveTeamInfoViaOrganizationIdOrSlug,
253
- updateTeamInformationByOrganizationId,
254
- deleteTeamByOrganizationOrTeamSlug,
255
- addTeamMemberInOrganization,
256
- getTeamMembersByIdOrSlug,
257
- deleteMemberFromTeam,
258
- switchTeamRoleForMember,
259
- retrieveTeamProjects,
260
- manageTeamExternalIntegrations,
261
- updateExternalTeamIntegration,
262
- deleteExternalTeamById
263
- };
264
-
265
- //#endregion
266
- export { addTeamMemberInOrganization, createOrganizationTeam, deleteExternalTeamById, deleteMemberFromTeam, deleteTeamByOrganizationOrTeamSlug, getTeamMembersByIdOrSlug, listOrganizationUserTeams, listTeamsInOrganization, manageTeamExternalIntegrations, retrieveTeamInfoViaOrganizationIdOrSlug, retrieveTeamProjects, sentryTeamOperations, switchTeamRoleForMember, updateExternalTeamIntegration, updateTeamInformationByOrganizationId };
@@ -1,41 +0,0 @@
1
- import { createSentryClient } from "./client.mjs";
2
- import { SentryDiscoverEventsPollResponse } from "./events.mjs";
3
- import { BoundTrigger } from "@keystrokehq/core";
4
- import { IntegrationTriggerBindingOptions, createPollingTriggerBindingFactory } from "@keystrokehq/integration-authoring";
5
- import { PollingTriggerManifest } from "@keystrokehq/core/trigger";
6
-
7
- //#region src/triggers.d.ts
8
- type Schedule = Parameters<typeof createPollingTriggerBindingFactory>[0]['schedule'];
9
- interface DiscoverEventsPollParams {
10
- readonly field: readonly string[];
11
- readonly query?: string;
12
- readonly project?: readonly number[];
13
- readonly environment?: readonly string[];
14
- readonly statsPeriod?: string;
15
- readonly dataset?: 'discover' | 'errors' | 'transactions' | 'issuePlatform';
16
- readonly per_page?: number;
17
- /** Override the org slug stored on the credentials. */
18
- readonly organization_slug?: string;
19
- }
20
- interface DiscoverBindingOptions<TOutput = SentryDiscoverEventsPollResponse> extends IntegrationTriggerBindingOptions<SentryDiscoverEventsPollResponse, TOutput> {
21
- readonly schedule?: Schedule;
22
- }
23
- /**
24
- * Pure helper that the polling `poll` callback delegates to. Exported so it
25
- * can be unit-tested without standing up the full polling harness.
26
- */
27
- declare function executeDiscoverEventsPoll(params: DiscoverEventsPollParams, credentials: {
28
- readonly SENTRY_ACCESS_TOKEN: string;
29
- readonly SENTRY_REGION_URL?: string;
30
- readonly SENTRY_ORG_SLUG?: string;
31
- }, options?: {
32
- readonly clientFactory?: typeof createSentryClient;
33
- }): Promise<SentryDiscoverEventsPollResponse>;
34
- declare function computeDiscoverEventsPollIdempotencyKey(response: SentryDiscoverEventsPollResponse): string | undefined;
35
- declare function bindDiscoverEventsPollingTrigger<TOutput = SentryDiscoverEventsPollResponse>(params: DiscoverEventsPollParams, options?: DiscoverBindingOptions<TOutput>): BoundTrigger<SentryDiscoverEventsPollResponse, readonly [], PollingTriggerManifest, TOutput>;
36
- declare const polling: Readonly<{
37
- readonly discoverEvents: typeof bindDiscoverEventsPollingTrigger;
38
- }>;
39
- type SentryPollingTriggers = typeof polling;
40
- //#endregion
41
- export { DiscoverEventsPollParams, SentryPollingTriggers, computeDiscoverEventsPollIdempotencyKey, executeDiscoverEventsPoll, polling };
package/dist/triggers.mjs DELETED
@@ -1,56 +0,0 @@
1
- import { createSentryClient } from "./client.mjs";
2
- import { sentryDiscoverEventsPollResponseSchema } from "./events.mjs";
3
- import { createPollingTriggerBindingFactory } from "@keystrokehq/integration-authoring";
4
-
5
- //#region src/triggers.ts
6
- function withDefaultSchedule(schedule) {
7
- if (schedule === void 0) return "5m";
8
- return schedule;
9
- }
10
- /**
11
- * Pure helper that the polling `poll` callback delegates to. Exported so it
12
- * can be unit-tested without standing up the full polling harness.
13
- */
14
- async function executeDiscoverEventsPoll(params, credentials, options) {
15
- const clientCreds = {
16
- SENTRY_ACCESS_TOKEN: credentials.SENTRY_ACCESS_TOKEN,
17
- ...credentials.SENTRY_REGION_URL ? { SENTRY_REGION_URL: credentials.SENTRY_REGION_URL } : {},
18
- ...credentials.SENTRY_ORG_SLUG ? { SENTRY_ORG_SLUG: credentials.SENTRY_ORG_SLUG } : {}
19
- };
20
- const orgSlug = params.organization_slug ?? credentials.SENTRY_ORG_SLUG;
21
- if (!orgSlug) throw new Error("Sentry Discover polling trigger requires an organization slug — supply `params.organization_slug` or store `SENTRY_ORG_SLUG` on the credentials.");
22
- const client = (options?.clientFactory ?? createSentryClient)(clientCreds);
23
- const query = { field: [...params.field] };
24
- if (params.query != null) query.query = params.query;
25
- if (params.project) query.project = [...params.project];
26
- if (params.environment) query.environment = [...params.environment];
27
- if (params.statsPeriod) query.statsPeriod = params.statsPeriod;
28
- if (params.dataset) query.dataset = params.dataset;
29
- if (params.per_page != null) query.per_page = params.per_page;
30
- return (await client.get(`/api/0/organizations/${encodeURIComponent(orgSlug)}/events/`, query)).data;
31
- }
32
- function computeDiscoverEventsPollIdempotencyKey(response) {
33
- const first = response.data[0];
34
- if (!first) return void 0;
35
- const asRecord = first;
36
- const id = asRecord.event_id ?? asRecord.id;
37
- if (typeof id === "string" && id.length > 0) return `discover:${id}`;
38
- if (typeof id === "number") return `discover:${id}`;
39
- }
40
- function bindDiscoverEventsPollingTrigger(params, options) {
41
- return createPollingTriggerBindingFactory({
42
- defaultId: "sentry.discover_events.poll",
43
- defaultDescription: "Poll the Sentry Discover events endpoint on a schedule and emit new rows as triggers.",
44
- schedule: withDefaultSchedule(options?.schedule),
45
- response: sentryDiscoverEventsPollResponseSchema,
46
- poll: async (ctx) => executeDiscoverEventsPoll(params, ctx.credentials.sentry)
47
- })({
48
- ...options?.id ? { id: options.id } : {},
49
- ...options?.description ? { description: options.description } : {},
50
- ...options?.transform ? { transform: options.transform } : {}
51
- });
52
- }
53
- const polling = Object.freeze({ discoverEvents: bindDiscoverEventsPollingTrigger });
54
-
55
- //#endregion
56
- export { computeDiscoverEventsPollIdempotencyKey, executeDiscoverEventsPoll, polling };
@@ -1,84 +0,0 @@
1
- import * as _keystrokehq_core0 from "@keystrokehq/core";
2
- import { z } from "zod";
3
-
4
- //#region src/user-emails.d.ts
5
- declare const retrieveUserEmailInformation: _keystrokehq_core0.Operation<z.ZodObject<{}, z.core.$strip>, z.ZodArray<z.ZodObject<{
6
- email: z.ZodString;
7
- isPrimary: z.ZodOptional<z.ZodBoolean>;
8
- isVerified: z.ZodOptional<z.ZodBoolean>;
9
- }, z.core.$loose>>, readonly [_keystrokehq_core0.CredentialSet<"keystroke:sentry", z.ZodObject<{
10
- SENTRY_ACCESS_TOKEN: z.ZodString;
11
- SENTRY_REGION_URL: z.ZodOptional<z.ZodString>;
12
- SENTRY_ORG_SLUG: z.ZodOptional<z.ZodString>;
13
- }, z.core.$strip>>], undefined>;
14
- declare const addRemoveUserEmailById: _keystrokehq_core0.Operation<z.ZodObject<{
15
- email: z.ZodString;
16
- }, z.core.$strip>, z.ZodObject<{
17
- email: z.ZodString;
18
- isPrimary: z.ZodOptional<z.ZodBoolean>;
19
- isVerified: z.ZodOptional<z.ZodBoolean>;
20
- }, z.core.$loose>, readonly [_keystrokehq_core0.CredentialSet<"keystroke:sentry", z.ZodObject<{
21
- SENTRY_ACCESS_TOKEN: z.ZodString;
22
- SENTRY_REGION_URL: z.ZodOptional<z.ZodString>;
23
- SENTRY_ORG_SLUG: z.ZodOptional<z.ZodString>;
24
- }, z.core.$strip>>], undefined>;
25
- declare const updateUserEmail: _keystrokehq_core0.Operation<z.ZodObject<{
26
- email: z.ZodString;
27
- }, z.core.$strip>, z.ZodObject<{
28
- email: z.ZodString;
29
- isPrimary: z.ZodOptional<z.ZodBoolean>;
30
- isVerified: z.ZodOptional<z.ZodBoolean>;
31
- }, z.core.$loose>, readonly [_keystrokehq_core0.CredentialSet<"keystroke:sentry", z.ZodObject<{
32
- SENTRY_ACCESS_TOKEN: z.ZodString;
33
- SENTRY_REGION_URL: z.ZodOptional<z.ZodString>;
34
- SENTRY_ORG_SLUG: z.ZodOptional<z.ZodString>;
35
- }, z.core.$strip>>], undefined>;
36
- declare const deleteUserEmailsById: _keystrokehq_core0.Operation<z.ZodObject<{
37
- email: z.ZodString;
38
- }, z.core.$strip>, z.ZodUnknown, readonly [_keystrokehq_core0.CredentialSet<"keystroke:sentry", z.ZodObject<{
39
- SENTRY_ACCESS_TOKEN: z.ZodString;
40
- SENTRY_REGION_URL: z.ZodOptional<z.ZodString>;
41
- SENTRY_ORG_SLUG: z.ZodOptional<z.ZodString>;
42
- }, z.core.$strip>>], undefined>;
43
- declare const sentryUserEmailOperations: {
44
- readonly retrieveUserEmailInformation: _keystrokehq_core0.Operation<z.ZodObject<{}, z.core.$strip>, z.ZodArray<z.ZodObject<{
45
- email: z.ZodString;
46
- isPrimary: z.ZodOptional<z.ZodBoolean>;
47
- isVerified: z.ZodOptional<z.ZodBoolean>;
48
- }, z.core.$loose>>, readonly [_keystrokehq_core0.CredentialSet<"keystroke:sentry", z.ZodObject<{
49
- SENTRY_ACCESS_TOKEN: z.ZodString;
50
- SENTRY_REGION_URL: z.ZodOptional<z.ZodString>;
51
- SENTRY_ORG_SLUG: z.ZodOptional<z.ZodString>;
52
- }, z.core.$strip>>], undefined>;
53
- readonly addRemoveUserEmailById: _keystrokehq_core0.Operation<z.ZodObject<{
54
- email: z.ZodString;
55
- }, z.core.$strip>, z.ZodObject<{
56
- email: z.ZodString;
57
- isPrimary: z.ZodOptional<z.ZodBoolean>;
58
- isVerified: z.ZodOptional<z.ZodBoolean>;
59
- }, z.core.$loose>, readonly [_keystrokehq_core0.CredentialSet<"keystroke:sentry", z.ZodObject<{
60
- SENTRY_ACCESS_TOKEN: z.ZodString;
61
- SENTRY_REGION_URL: z.ZodOptional<z.ZodString>;
62
- SENTRY_ORG_SLUG: z.ZodOptional<z.ZodString>;
63
- }, z.core.$strip>>], undefined>;
64
- readonly updateUserEmail: _keystrokehq_core0.Operation<z.ZodObject<{
65
- email: z.ZodString;
66
- }, z.core.$strip>, z.ZodObject<{
67
- email: z.ZodString;
68
- isPrimary: z.ZodOptional<z.ZodBoolean>;
69
- isVerified: z.ZodOptional<z.ZodBoolean>;
70
- }, z.core.$loose>, readonly [_keystrokehq_core0.CredentialSet<"keystroke:sentry", z.ZodObject<{
71
- SENTRY_ACCESS_TOKEN: z.ZodString;
72
- SENTRY_REGION_URL: z.ZodOptional<z.ZodString>;
73
- SENTRY_ORG_SLUG: z.ZodOptional<z.ZodString>;
74
- }, z.core.$strip>>], undefined>;
75
- readonly deleteUserEmailsById: _keystrokehq_core0.Operation<z.ZodObject<{
76
- email: z.ZodString;
77
- }, z.core.$strip>, z.ZodUnknown, readonly [_keystrokehq_core0.CredentialSet<"keystroke:sentry", z.ZodObject<{
78
- SENTRY_ACCESS_TOKEN: z.ZodString;
79
- SENTRY_REGION_URL: z.ZodOptional<z.ZodString>;
80
- SENTRY_ORG_SLUG: z.ZodOptional<z.ZodString>;
81
- }, z.core.$strip>>], undefined>;
82
- };
83
- //#endregion
84
- export { addRemoveUserEmailById, deleteUserEmailsById, retrieveUserEmailInformation, sentryUserEmailOperations, updateUserEmail };
@@ -1,60 +0,0 @@
1
- import { sentryUserEmailSchema } from "./schemas.mjs";
2
- import { t as defineSentryEndpoint } from "./endpoint-factory-DcT49a8O.mjs";
3
- import { z } from "zod";
4
-
5
- //#region src/user-emails.ts
6
- /**
7
- * Sentry user-email operations (current-user account scope).
8
- * Maps to PLAN.md §6.21 (4 actions).
9
- */
10
- const retrieveUserEmailInformation = defineSentryEndpoint({
11
- id: "sentry.retrieve-user-email-information",
12
- name: "Retrieve User Emails",
13
- description: "List the emails on the authenticated Sentry account.",
14
- method: "GET",
15
- path: "/api/0/users/me/emails/",
16
- input: z.object({}),
17
- output: z.array(sentryUserEmailSchema)
18
- });
19
- const addRemoveUserEmailById = defineSentryEndpoint({
20
- id: "sentry.add-remove-user-email-by-id",
21
- name: "Add User Email",
22
- description: "Add a new email to the authenticated Sentry account.",
23
- method: "POST",
24
- path: "/api/0/users/me/emails/",
25
- input: z.object({ email: z.string().email() }),
26
- bodyFields: ["email"],
27
- output: sentryUserEmailSchema,
28
- needsApproval: true
29
- });
30
- const updateUserEmail = defineSentryEndpoint({
31
- id: "sentry.update-user-email",
32
- name: "Set Primary Email",
33
- description: "Mark an email as the primary address on the authenticated account.",
34
- method: "PUT",
35
- path: "/api/0/users/me/emails/",
36
- input: z.object({ email: z.string().email() }),
37
- bodyFields: ["email"],
38
- output: sentryUserEmailSchema,
39
- needsApproval: true
40
- });
41
- const deleteUserEmailsById = defineSentryEndpoint({
42
- id: "sentry.delete-user-emails-by-id",
43
- name: "Delete User Email",
44
- description: "Remove an email from the authenticated Sentry account.",
45
- method: "DELETE",
46
- path: "/api/0/users/me/emails/",
47
- input: z.object({ email: z.string().email() }),
48
- queryFields: ["email"],
49
- output: z.unknown(),
50
- needsApproval: true
51
- });
52
- const sentryUserEmailOperations = {
53
- retrieveUserEmailInformation,
54
- addRemoveUserEmailById,
55
- updateUserEmail,
56
- deleteUserEmailsById
57
- };
58
-
59
- //#endregion
60
- export { addRemoveUserEmailById, deleteUserEmailsById, retrieveUserEmailInformation, sentryUserEmailOperations, updateUserEmail };
@@ -1,30 +0,0 @@
1
- //#region src/verification.d.ts
2
- /**
3
- * Webhook-request verification helpers for Sentry.
4
- *
5
- * Two verification paths are exposed:
6
- *
7
- * 1. `verifySentryWebhookRequest` — for integration-platform webhooks,
8
- * signed with HMAC-SHA256 of the raw JSON body using the integration's
9
- * `clientSecret`. Header: `Sentry-Hook-Signature`. Timestamp skew is
10
- * enforced via `Sentry-Hook-Timestamp` with a configurable `maxSkewSeconds`
11
- * default of 300.
12
- * 2. `verifySentryServiceHookRequest` — for legacy project service hooks,
13
- * signed with a per-hook secret rather than the integration secret.
14
- * Same signing algorithm.
15
- *
16
- * Both helpers throw `SentryWebhookVerificationError` on failure and return
17
- * `void` on success. Comparisons use timing-safe equality.
18
- */
19
- interface SentryWebhookVerificationInput {
20
- readonly rawBody: string;
21
- readonly headers: Readonly<Record<string, string>> | Headers;
22
- readonly secret: string;
23
- readonly maxSkewSeconds?: number;
24
- /** Hook for tests to provide a deterministic "now" value. */
25
- readonly now?: () => number;
26
- }
27
- declare function verifySentryWebhookRequest(input: SentryWebhookVerificationInput): void;
28
- declare function verifySentryServiceHookRequest(input: SentryWebhookVerificationInput): void;
29
- //#endregion
30
- export { SentryWebhookVerificationInput, verifySentryServiceHookRequest, verifySentryWebhookRequest };
@@ -1,83 +0,0 @@
1
- import { n as SentryWebhookVerificationError } from "./errors-DfEFwcTe.mjs";
2
- import { createHmac, timingSafeEqual } from "node:crypto";
3
-
4
- //#region src/verification.ts
5
- /**
6
- * Webhook-request verification helpers for Sentry.
7
- *
8
- * Two verification paths are exposed:
9
- *
10
- * 1. `verifySentryWebhookRequest` — for integration-platform webhooks,
11
- * signed with HMAC-SHA256 of the raw JSON body using the integration's
12
- * `clientSecret`. Header: `Sentry-Hook-Signature`. Timestamp skew is
13
- * enforced via `Sentry-Hook-Timestamp` with a configurable `maxSkewSeconds`
14
- * default of 300.
15
- * 2. `verifySentryServiceHookRequest` — for legacy project service hooks,
16
- * signed with a per-hook secret rather than the integration secret.
17
- * Same signing algorithm.
18
- *
19
- * Both helpers throw `SentryWebhookVerificationError` on failure and return
20
- * `void` on success. Comparisons use timing-safe equality.
21
- */
22
- function verifySentryWebhookRequest(input) {
23
- verifyCommon({
24
- ...input,
25
- requireTimestamp: true
26
- });
27
- }
28
- function verifySentryServiceHookRequest(input) {
29
- verifyCommon({
30
- ...input,
31
- requireTimestamp: false
32
- });
33
- }
34
- function verifyCommon(input) {
35
- if (!input.secret || input.secret.length === 0) throw new SentryWebhookVerificationError({
36
- reason: "invalid_secret",
37
- message: "Sentry webhook verification requires a non-empty signing secret."
38
- });
39
- const signature = getHeader(input.headers, "sentry-hook-signature");
40
- if (!signature) throw new SentryWebhookVerificationError({
41
- reason: "missing_signature",
42
- message: "Sentry webhook request is missing the `Sentry-Hook-Signature` header."
43
- });
44
- if (input.requireTimestamp) {
45
- const timestamp = getHeader(input.headers, "sentry-hook-timestamp");
46
- if (!timestamp) throw new SentryWebhookVerificationError({
47
- reason: "missing_timestamp",
48
- message: "Sentry webhook request is missing the `Sentry-Hook-Timestamp` header."
49
- });
50
- const skewSeconds = input.maxSkewSeconds ?? 300;
51
- const tsSeconds = Number(timestamp);
52
- if (!Number.isFinite(tsSeconds)) throw new SentryWebhookVerificationError({
53
- reason: "missing_timestamp",
54
- message: "Sentry webhook `Sentry-Hook-Timestamp` header is not a number."
55
- });
56
- const nowSeconds = Math.floor((input.now ?? Date.now)() / 1e3);
57
- if (Math.abs(nowSeconds - tsSeconds) > skewSeconds) throw new SentryWebhookVerificationError({
58
- reason: "timestamp_skew",
59
- message: `Sentry webhook timestamp ${timestamp} is outside the acceptable skew of ${skewSeconds}s (server time ${nowSeconds}).`
60
- });
61
- }
62
- if (!isTimingSafeHexEqual(createHmac("sha256", input.secret).update(input.rawBody, "utf8").digest("hex"), signature)) throw new SentryWebhookVerificationError({
63
- reason: "invalid_signature",
64
- message: "Sentry webhook signature did not match the computed HMAC-SHA256."
65
- });
66
- }
67
- function getHeader(headers, name) {
68
- if (headers instanceof Headers) return headers.get(name);
69
- const lower = name.toLowerCase();
70
- for (const key of Object.keys(headers)) if (key.toLowerCase() === lower) return headers[key] ?? null;
71
- return null;
72
- }
73
- function isTimingSafeHexEqual(expectedHex, actualHex) {
74
- if (expectedHex.length !== actualHex.length) return false;
75
- try {
76
- return timingSafeEqual(Buffer.from(expectedHex, "hex"), Buffer.from(actualHex, "hex"));
77
- } catch {
78
- return false;
79
- }
80
- }
81
-
82
- //#endregion
83
- export { verifySentryServiceHookRequest, verifySentryWebhookRequest };