@keystrokehq/sentry 0.0.1

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 (71) hide show
  1. package/README.md +218 -0
  2. package/dist/_official/index.d.mts +3 -0
  3. package/dist/_official/index.mjs +3 -0
  4. package/dist/_runtime/index.d.mts +2 -0
  5. package/dist/_runtime/index.mjs +3 -0
  6. package/dist/alerts.d.mts +551 -0
  7. package/dist/alerts.mjs +300 -0
  8. package/dist/client.d.mts +86 -0
  9. package/dist/client.mjs +233 -0
  10. package/dist/connection.d.mts +3 -0
  11. package/dist/connection.mjs +3 -0
  12. package/dist/dashboards.d.mts +203 -0
  13. package/dist/dashboards.mjs +122 -0
  14. package/dist/debug-files.d.mts +127 -0
  15. package/dist/debug-files.mjs +73 -0
  16. package/dist/deploys.d.mts +103 -0
  17. package/dist/deploys.mjs +67 -0
  18. package/dist/discover.d.mts +235 -0
  19. package/dist/discover.mjs +138 -0
  20. package/dist/endpoint-factory-BwjbcPwW.mjs +96 -0
  21. package/dist/environments.d.mts +121 -0
  22. package/dist/environments.mjs +71 -0
  23. package/dist/errors-DfEFwcTe.mjs +142 -0
  24. package/dist/events-api.d.mts +311 -0
  25. package/dist/events-api.mjs +184 -0
  26. package/dist/events.d.mts +754 -0
  27. package/dist/events.mjs +142 -0
  28. package/dist/feedback.d.mts +99 -0
  29. package/dist/feedback.mjs +63 -0
  30. package/dist/index.d.mts +1 -0
  31. package/dist/index.mjs +1 -0
  32. package/dist/integration-C8KHkeNG.d.mts +58 -0
  33. package/dist/integration-WwY95cWE.mjs +156 -0
  34. package/dist/issues.d.mts +563 -0
  35. package/dist/issues.mjs +324 -0
  36. package/dist/members.d.mts +365 -0
  37. package/dist/members.mjs +156 -0
  38. package/dist/messaging.d.mts +1 -0
  39. package/dist/messaging.mjs +1 -0
  40. package/dist/monitors.d.mts +539 -0
  41. package/dist/monitors.mjs +234 -0
  42. package/dist/notifications.d.mts +221 -0
  43. package/dist/notifications.mjs +133 -0
  44. package/dist/organizations.d.mts +563 -0
  45. package/dist/organizations.mjs +334 -0
  46. package/dist/pagination-PlgAqbZt.mjs +116 -0
  47. package/dist/project-keys.d.mts +287 -0
  48. package/dist/project-keys.mjs +122 -0
  49. package/dist/projects.d.mts +687 -0
  50. package/dist/projects.mjs +378 -0
  51. package/dist/provider-app-BANn4KOL.d.mts +45 -0
  52. package/dist/releases.d.mts +949 -0
  53. package/dist/releases.mjs +479 -0
  54. package/dist/replays.d.mts +307 -0
  55. package/dist/replays.mjs +192 -0
  56. package/dist/schemas.d.mts +381 -0
  57. package/dist/schemas.mjs +318 -0
  58. package/dist/scim.d.mts +413 -0
  59. package/dist/scim.mjs +249 -0
  60. package/dist/scopes-RRU0vt-a.mjs +36 -0
  61. package/dist/teams.d.mts +561 -0
  62. package/dist/teams.mjs +266 -0
  63. package/dist/triggers.d.mts +83 -0
  64. package/dist/triggers.mjs +263 -0
  65. package/dist/user-emails.d.mts +117 -0
  66. package/dist/user-emails.mjs +60 -0
  67. package/dist/verification.d.mts +30 -0
  68. package/dist/verification.mjs +83 -0
  69. package/dist/webhooks.d.mts +199 -0
  70. package/dist/webhooks.mjs +108 -0
  71. package/package.json +178 -0
@@ -0,0 +1,334 @@
1
+ import { orgScopeInputSchema, sentryEnvironmentSchema, sentryJsonArraySchema, sentryJsonObjectSchema, sentryListInputSchema, sentryOrganizationDetailsSchema, sentryProjectSummarySchema, sentrySlugSchema } from "./schemas.mjs";
2
+ import { t as defineSentryEndpoint } from "./endpoint-factory-BwjbcPwW.mjs";
3
+ import { t as SENTRY_SCOPE } from "./scopes-RRU0vt-a.mjs";
4
+ import { z } from "zod";
5
+
6
+ //#region src/organizations.ts
7
+ /**
8
+ * Operations for Sentry organization-level endpoints.
9
+ * Maps to PLAN.md §6.1 (15 actions).
10
+ */
11
+ const ORG_PATH_PARAMS = [{
12
+ name: "organization_slug",
13
+ placeholder: "{organization_slug}"
14
+ }];
15
+ const getOrganizationByIdOrSlug = defineSentryEndpoint({
16
+ id: "get_organization_by_id_or_slug",
17
+ name: "Get Organization By ID or Slug",
18
+ description: "Return metadata for a single organization identified by its slug or numeric ID.",
19
+ method: "GET",
20
+ path: "/api/0/organizations/{organization_slug}/",
21
+ pathParams: ORG_PATH_PARAMS,
22
+ input: orgScopeInputSchema,
23
+ output: sentryOrganizationDetailsSchema,
24
+ requiredOAuthScopes: [...SENTRY_SCOPE.orgRead]
25
+ });
26
+ const getOrganizationDetails = defineSentryEndpoint({
27
+ id: "get_organization_details",
28
+ name: "Get Organization Details",
29
+ description: "Alias of `get_organization_by_id_or_slug` preserved for Composio parity.",
30
+ method: "GET",
31
+ path: "/api/0/organizations/{organization_slug}/",
32
+ pathParams: ORG_PATH_PARAMS,
33
+ input: orgScopeInputSchema,
34
+ output: sentryOrganizationDetailsSchema,
35
+ requiredOAuthScopes: [...SENTRY_SCOPE.orgRead]
36
+ });
37
+ const modifyOrganizationSettings = defineSentryEndpoint({
38
+ id: "modify_organization_settings",
39
+ name: "Modify Organization Settings",
40
+ description: "Update organization settings such as display name, slug, or feature flags.",
41
+ method: "PUT",
42
+ path: "/api/0/organizations/{organization_slug}/",
43
+ pathParams: ORG_PATH_PARAMS,
44
+ input: orgScopeInputSchema.extend({
45
+ name: z.string().min(1).optional(),
46
+ slug: sentrySlugSchema.optional(),
47
+ defaultRole: z.string().optional(),
48
+ openMembership: z.boolean().optional(),
49
+ allowSharedIssues: z.boolean().optional(),
50
+ enhancedPrivacy: z.boolean().optional(),
51
+ dataScrubber: z.boolean().optional(),
52
+ dataScrubberDefaults: z.boolean().optional(),
53
+ scrubIPAddresses: z.boolean().optional(),
54
+ storeCrashReports: z.number().int().optional(),
55
+ attachmentsRole: z.string().optional(),
56
+ debugFilesRole: z.string().optional(),
57
+ eventsMemberAdmin: z.boolean().optional(),
58
+ alertsMemberWrite: z.boolean().optional(),
59
+ codecovAccess: z.boolean().optional(),
60
+ githubOpenPRBot: z.boolean().optional(),
61
+ githubNudgeInvite: z.boolean().optional()
62
+ }),
63
+ bodyFields: [
64
+ "name",
65
+ "slug",
66
+ "defaultRole",
67
+ "openMembership",
68
+ "allowSharedIssues",
69
+ "enhancedPrivacy",
70
+ "dataScrubber",
71
+ "dataScrubberDefaults",
72
+ "scrubIPAddresses",
73
+ "storeCrashReports",
74
+ "attachmentsRole",
75
+ "debugFilesRole",
76
+ "eventsMemberAdmin",
77
+ "alertsMemberWrite",
78
+ "codecovAccess",
79
+ "githubOpenPRBot",
80
+ "githubNudgeInvite"
81
+ ],
82
+ output: sentryOrganizationDetailsSchema,
83
+ needsApproval: true,
84
+ requiredOAuthScopes: [...SENTRY_SCOPE.orgWrite]
85
+ });
86
+ const getOrganizationEnvironments = defineSentryEndpoint({
87
+ id: "get_organization_environments",
88
+ name: "Get Organization Environments",
89
+ description: "List the environments visible to the organization across all projects.",
90
+ method: "GET",
91
+ path: "/api/0/organizations/{organization_slug}/environments/",
92
+ pathParams: ORG_PATH_PARAMS,
93
+ input: orgScopeInputSchema.extend({ visibility: z.enum([
94
+ "visible",
95
+ "hidden",
96
+ "all"
97
+ ]).optional() }),
98
+ queryFields: ["visibility"],
99
+ output: z.array(sentryEnvironmentSchema),
100
+ requiredOAuthScopes: [...SENTRY_SCOPE.projectRead]
101
+ });
102
+ const getOrganizationSessions = defineSentryEndpoint({
103
+ id: "get_organization_sessions",
104
+ name: "Get Organization Sessions",
105
+ description: "Fetch session-health aggregates for the organization. Supports Release Health queries.",
106
+ method: "GET",
107
+ path: "/api/0/organizations/{organization_slug}/sessions/",
108
+ pathParams: ORG_PATH_PARAMS,
109
+ input: orgScopeInputSchema.extend({
110
+ project: z.array(z.number().int()).optional(),
111
+ environment: z.array(z.string()).optional(),
112
+ field: z.array(z.string()).min(1),
113
+ statsPeriod: z.string().optional(),
114
+ interval: z.string().optional(),
115
+ groupBy: z.array(z.string()).optional(),
116
+ query: z.string().optional(),
117
+ orderBy: z.string().optional(),
118
+ per_page: z.number().int().optional(),
119
+ includeTotals: z.number().int().optional(),
120
+ includeSeries: z.number().int().optional()
121
+ }),
122
+ queryFields: [
123
+ "project",
124
+ "environment",
125
+ "field",
126
+ "statsPeriod",
127
+ "interval",
128
+ "groupBy",
129
+ "query",
130
+ "orderBy",
131
+ "per_page",
132
+ "includeTotals",
133
+ "includeSeries"
134
+ ],
135
+ output: sentryJsonObjectSchema,
136
+ requiredOAuthScopes: [...SENTRY_SCOPE.projectRead]
137
+ });
138
+ const getOrganizationStatsSummary = defineSentryEndpoint({
139
+ id: "get_organization_stats_summary",
140
+ name: "Get Organization Stats Summary",
141
+ description: "Return a high-level stats summary for the organization.",
142
+ method: "GET",
143
+ path: "/api/0/organizations/{organization_slug}/stats-summary/",
144
+ pathParams: ORG_PATH_PARAMS,
145
+ input: orgScopeInputSchema.extend({
146
+ project: z.array(z.number().int()).optional(),
147
+ statsPeriod: z.string().optional(),
148
+ start: z.string().optional(),
149
+ end: z.string().optional(),
150
+ field: z.array(z.string()).optional(),
151
+ category: z.array(z.string()).optional(),
152
+ outcome: z.array(z.string()).optional(),
153
+ reason: z.array(z.string()).optional()
154
+ }),
155
+ queryFields: [
156
+ "project",
157
+ "statsPeriod",
158
+ "start",
159
+ "end",
160
+ "field",
161
+ "category",
162
+ "outcome",
163
+ "reason"
164
+ ],
165
+ output: sentryJsonObjectSchema,
166
+ requiredOAuthScopes: [...SENTRY_SCOPE.orgRead]
167
+ });
168
+ const retrieveOrganizationStatsV2 = defineSentryEndpoint({
169
+ id: "retrieve_organization_stats_v2",
170
+ name: "Retrieve Organization Stats (v2)",
171
+ description: "Return the v2 stats endpoint for outcomes/categories.",
172
+ method: "GET",
173
+ path: "/api/0/organizations/{organization_slug}/stats_v2/",
174
+ pathParams: ORG_PATH_PARAMS,
175
+ input: orgScopeInputSchema.extend({
176
+ field: z.array(z.string()).min(1),
177
+ statsPeriod: z.string().optional(),
178
+ interval: z.string().optional(),
179
+ groupBy: z.array(z.string()).optional(),
180
+ project: z.array(z.number().int()).optional(),
181
+ category: z.array(z.string()).optional(),
182
+ outcome: z.array(z.string()).optional(),
183
+ reason: z.array(z.string()).optional(),
184
+ start: z.string().optional(),
185
+ end: z.string().optional()
186
+ }),
187
+ queryFields: [
188
+ "field",
189
+ "statsPeriod",
190
+ "interval",
191
+ "groupBy",
192
+ "project",
193
+ "category",
194
+ "outcome",
195
+ "reason",
196
+ "start",
197
+ "end"
198
+ ],
199
+ output: sentryJsonObjectSchema,
200
+ requiredOAuthScopes: [...SENTRY_SCOPE.orgRead]
201
+ });
202
+ const retrieveOrganizationRelayUsage = defineSentryEndpoint({
203
+ id: "retrieve_organization_relay_usage",
204
+ name: "Retrieve Organization Relay Usage",
205
+ description: "Return Relay (Sentry ingest proxy) usage metrics for the organization.",
206
+ method: "GET",
207
+ path: "/api/0/organizations/{organization_slug}/relay_usage/",
208
+ pathParams: ORG_PATH_PARAMS,
209
+ input: orgScopeInputSchema,
210
+ output: sentryJsonObjectSchema,
211
+ requiredOAuthScopes: [...SENTRY_SCOPE.orgRead]
212
+ });
213
+ const retrieveOrganizationProjects = defineSentryEndpoint({
214
+ id: "retrieve_organization_projects",
215
+ name: "Retrieve Organization Projects",
216
+ description: "List projects in an organization with pagination.",
217
+ method: "GET",
218
+ path: "/api/0/organizations/{organization_slug}/projects/",
219
+ pathParams: ORG_PATH_PARAMS,
220
+ input: sentryListInputSchema.merge(orgScopeInputSchema),
221
+ queryFields: [
222
+ "query",
223
+ "cursor",
224
+ "per_page"
225
+ ],
226
+ output: z.array(sentryProjectSummarySchema),
227
+ pagination: "cursor",
228
+ requiredOAuthScopes: [...SENTRY_SCOPE.projectRead]
229
+ });
230
+ const postSpikeProtectionForOrganization = defineSentryEndpoint({
231
+ id: "post_spike_protection_for_organization",
232
+ name: "Enable / Disable Spike Protection",
233
+ description: "Toggle spike-protection on or off at the organization level.",
234
+ method: "POST",
235
+ path: "/api/0/organizations/{organization_slug}/spike-protections/",
236
+ pathParams: ORG_PATH_PARAMS,
237
+ input: orgScopeInputSchema.extend({ projects: z.array(z.union([z.string(), z.number()])).min(1) }),
238
+ bodyFields: ["projects"],
239
+ output: sentryJsonObjectSchema,
240
+ needsApproval: true,
241
+ requiredOAuthScopes: [...SENTRY_SCOPE.projectWrite]
242
+ });
243
+ const retrieveOrgIntegrationConfig = defineSentryEndpoint({
244
+ id: "retrieve_org_integration_config",
245
+ name: "Retrieve Organization Integration Config",
246
+ description: "Fetch the configuration schema for the set of integrations the org can install.",
247
+ method: "GET",
248
+ path: "/api/0/organizations/{organization_slug}/config/integrations/",
249
+ pathParams: ORG_PATH_PARAMS,
250
+ input: orgScopeInputSchema.extend({ providerKey: z.string().optional() }),
251
+ queryFields: ["providerKey"],
252
+ output: sentryJsonObjectSchema,
253
+ requiredOAuthScopes: [...SENTRY_SCOPE.orgRead]
254
+ });
255
+ const retrieveOrganizationIntegrationsList = defineSentryEndpoint({
256
+ id: "retrieve_organization_integrations_list",
257
+ name: "List Installed Organization Integrations",
258
+ description: "Return every provider integration installed on the organization.",
259
+ method: "GET",
260
+ path: "/api/0/organizations/{organization_slug}/integrations/",
261
+ pathParams: ORG_PATH_PARAMS,
262
+ input: orgScopeInputSchema.extend({
263
+ providerKey: z.string().optional(),
264
+ features: z.array(z.string()).optional(),
265
+ includeConfig: z.boolean().optional()
266
+ }),
267
+ queryFields: [
268
+ "providerKey",
269
+ "features",
270
+ "includeConfig"
271
+ ],
272
+ output: sentryJsonArraySchema,
273
+ requiredOAuthScopes: [...SENTRY_SCOPE.orgRead]
274
+ });
275
+ const getIntegrationDetailsByOrg = defineSentryEndpoint({
276
+ id: "get_integration_details_by_org",
277
+ name: "Get Organization Integration Details",
278
+ description: "Fetch one installed integration record by its integration id.",
279
+ method: "GET",
280
+ path: "/api/0/organizations/{organization_slug}/integrations/{integration_id}/",
281
+ pathParams: [...ORG_PATH_PARAMS, {
282
+ name: "integration_id",
283
+ placeholder: "{integration_id}"
284
+ }],
285
+ input: orgScopeInputSchema.extend({ integration_id: z.string().min(1) }),
286
+ output: sentryJsonObjectSchema,
287
+ requiredOAuthScopes: [...SENTRY_SCOPE.orgRead]
288
+ });
289
+ const deleteOrganizationIntegration = defineSentryEndpoint({
290
+ id: "delete_organization_integration",
291
+ name: "Delete Organization Integration",
292
+ description: "Uninstall an integration installation from the organization.",
293
+ method: "DELETE",
294
+ path: "/api/0/organizations/{organization_slug}/integrations/{integration_id}/",
295
+ pathParams: [...ORG_PATH_PARAMS, {
296
+ name: "integration_id",
297
+ placeholder: "{integration_id}"
298
+ }],
299
+ input: orgScopeInputSchema.extend({ integration_id: z.string().min(1) }),
300
+ output: z.unknown(),
301
+ needsApproval: true,
302
+ requiredOAuthScopes: [...SENTRY_SCOPE.orgAdmin]
303
+ });
304
+ const getSentryAppInstallationsForOrganization = defineSentryEndpoint({
305
+ id: "get_sentry_app_installations_for_organization",
306
+ name: "List Sentry App Installations for Organization",
307
+ description: "List all Sentry-app (integration platform) installations for the organization.",
308
+ method: "GET",
309
+ path: "/api/0/organizations/{organization_slug}/sentry-app-installations/",
310
+ pathParams: ORG_PATH_PARAMS,
311
+ input: orgScopeInputSchema,
312
+ output: sentryJsonArraySchema,
313
+ requiredOAuthScopes: [...SENTRY_SCOPE.orgRead]
314
+ });
315
+ const sentryOrganizationOperations = {
316
+ getOrganizationByIdOrSlug,
317
+ getOrganizationDetails,
318
+ modifyOrganizationSettings,
319
+ getOrganizationEnvironments,
320
+ getOrganizationSessions,
321
+ getOrganizationStatsSummary,
322
+ retrieveOrganizationStatsV2,
323
+ retrieveOrganizationRelayUsage,
324
+ retrieveOrganizationProjects,
325
+ postSpikeProtectionForOrganization,
326
+ retrieveOrgIntegrationConfig,
327
+ retrieveOrganizationIntegrationsList,
328
+ getIntegrationDetailsByOrg,
329
+ deleteOrganizationIntegration,
330
+ getSentryAppInstallationsForOrganization
331
+ };
332
+
333
+ //#endregion
334
+ export { deleteOrganizationIntegration, getIntegrationDetailsByOrg, getOrganizationByIdOrSlug, getOrganizationDetails, getOrganizationEnvironments, getOrganizationSessions, getOrganizationStatsSummary, getSentryAppInstallationsForOrganization, modifyOrganizationSettings, postSpikeProtectionForOrganization, retrieveOrgIntegrationConfig, retrieveOrganizationIntegrationsList, retrieveOrganizationProjects, retrieveOrganizationRelayUsage, retrieveOrganizationStatsV2, sentryOrganizationOperations };
@@ -0,0 +1,116 @@
1
+ //#region src/pagination.ts
2
+ function parseSentryLinkHeader(header) {
3
+ if (header == null || header.length === 0) return {
4
+ previous: null,
5
+ next: null
6
+ };
7
+ let previous = null;
8
+ let next = null;
9
+ for (const entry of splitLinkEntries(header)) {
10
+ const parsed = parseLinkEntry(entry);
11
+ if (!parsed) continue;
12
+ if (parsed.rel === "previous") previous = toPageLink(parsed.url);
13
+ else if (parsed.rel === "next") next = toPageLink(parsed.url);
14
+ }
15
+ return {
16
+ previous,
17
+ next
18
+ };
19
+ }
20
+ /**
21
+ * Splits a single raw `Link` header value into its comma-separated entries.
22
+ * Naive splitting on `,` is unsafe because cursor strings can legally contain
23
+ * commas; we track angle-bracket depth.
24
+ */
25
+ function splitLinkEntries(header) {
26
+ const entries = [];
27
+ let depth = 0;
28
+ let start = 0;
29
+ for (let i = 0; i < header.length; i += 1) {
30
+ const ch = header.charAt(i);
31
+ if (ch === "<") depth += 1;
32
+ else if (ch === ">") depth -= 1;
33
+ else if (ch === "," && depth === 0) {
34
+ entries.push(header.slice(start, i));
35
+ start = i + 1;
36
+ }
37
+ }
38
+ entries.push(header.slice(start));
39
+ return entries.map((e) => e.trim()).filter(Boolean);
40
+ }
41
+ function parseLinkEntry(entry) {
42
+ const openBracket = entry.indexOf("<");
43
+ const closeBracket = entry.indexOf(">", openBracket);
44
+ if (openBracket === -1 || closeBracket === -1) return null;
45
+ const url = entry.slice(openBracket + 1, closeBracket);
46
+ const params = parseLinkParams(entry.slice(closeBracket + 1));
47
+ const rel = params.rel ?? "";
48
+ const results = params.results === "true";
49
+ if (!rel) return null;
50
+ return {
51
+ url,
52
+ rel,
53
+ results
54
+ };
55
+ }
56
+ function parseLinkParams(paramsSection) {
57
+ const params = {};
58
+ for (const part of paramsSection.split(";").map((s) => s.trim())) {
59
+ if (!part) continue;
60
+ const eq = part.indexOf("=");
61
+ if (eq === -1) continue;
62
+ const key = part.slice(0, eq).trim();
63
+ let value = part.slice(eq + 1).trim();
64
+ if (value.startsWith("\"") && value.endsWith("\"")) value = value.slice(1, -1);
65
+ if (key) params[key] = value;
66
+ }
67
+ return params;
68
+ }
69
+ function toPageLink(url) {
70
+ return {
71
+ url,
72
+ cursor: extractCursor(url),
73
+ results: extractResults(url)
74
+ };
75
+ }
76
+ function extractCursor(url) {
77
+ const queryIndex = url.indexOf("?");
78
+ if (queryIndex === -1) return null;
79
+ const query = url.slice(queryIndex + 1);
80
+ for (const pair of query.split("&")) {
81
+ const eq = pair.indexOf("=");
82
+ if (eq === -1) continue;
83
+ if (pair.slice(0, eq) === "cursor") return decodeURIComponent(pair.slice(eq + 1));
84
+ }
85
+ return null;
86
+ }
87
+ function extractResults(url) {
88
+ const queryIndex = url.indexOf("?");
89
+ if (queryIndex === -1) return false;
90
+ const query = url.slice(queryIndex + 1);
91
+ for (const pair of query.split("&")) {
92
+ const eq = pair.indexOf("=");
93
+ if (eq === -1) continue;
94
+ if (pair.slice(0, eq) === "results") return pair.slice(eq + 1) === "true";
95
+ }
96
+ return false;
97
+ }
98
+ /**
99
+ * Detects a Sentry DSN pasted where a bearer auth token was expected. DSNs
100
+ * look like `https://<publicKey>@o<org>.ingest.sentry.io/<projectId>` (or
101
+ * http(s) against a self-hosted host with an `@` before the host). We never
102
+ * want to send these to the management API.
103
+ */
104
+ function looksLikeSentryDsn(value) {
105
+ if (!value.includes("://")) return false;
106
+ try {
107
+ const parsed = new URL(value);
108
+ if (parsed.protocol !== "https:" && parsed.protocol !== "http:") return false;
109
+ return parsed.username.length > 0;
110
+ } catch {
111
+ return false;
112
+ }
113
+ }
114
+
115
+ //#endregion
116
+ export { parseSentryLinkHeader as n, looksLikeSentryDsn as t };