@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.
- package/README.md +218 -0
- package/dist/_official/index.d.mts +3 -0
- package/dist/_official/index.mjs +3 -0
- package/dist/_runtime/index.d.mts +2 -0
- package/dist/_runtime/index.mjs +3 -0
- package/dist/alerts.d.mts +551 -0
- package/dist/alerts.mjs +300 -0
- package/dist/client.d.mts +86 -0
- package/dist/client.mjs +233 -0
- package/dist/connection.d.mts +3 -0
- package/dist/connection.mjs +3 -0
- package/dist/dashboards.d.mts +203 -0
- package/dist/dashboards.mjs +122 -0
- package/dist/debug-files.d.mts +127 -0
- package/dist/debug-files.mjs +73 -0
- package/dist/deploys.d.mts +103 -0
- package/dist/deploys.mjs +67 -0
- package/dist/discover.d.mts +235 -0
- package/dist/discover.mjs +138 -0
- package/dist/endpoint-factory-BwjbcPwW.mjs +96 -0
- package/dist/environments.d.mts +121 -0
- package/dist/environments.mjs +71 -0
- package/dist/errors-DfEFwcTe.mjs +142 -0
- package/dist/events-api.d.mts +311 -0
- package/dist/events-api.mjs +184 -0
- package/dist/events.d.mts +754 -0
- package/dist/events.mjs +142 -0
- package/dist/feedback.d.mts +99 -0
- package/dist/feedback.mjs +63 -0
- package/dist/index.d.mts +1 -0
- package/dist/index.mjs +1 -0
- package/dist/integration-C8KHkeNG.d.mts +58 -0
- package/dist/integration-WwY95cWE.mjs +156 -0
- package/dist/issues.d.mts +563 -0
- package/dist/issues.mjs +324 -0
- package/dist/members.d.mts +365 -0
- package/dist/members.mjs +156 -0
- package/dist/messaging.d.mts +1 -0
- package/dist/messaging.mjs +1 -0
- package/dist/monitors.d.mts +539 -0
- package/dist/monitors.mjs +234 -0
- package/dist/notifications.d.mts +221 -0
- package/dist/notifications.mjs +133 -0
- package/dist/organizations.d.mts +563 -0
- package/dist/organizations.mjs +334 -0
- package/dist/pagination-PlgAqbZt.mjs +116 -0
- package/dist/project-keys.d.mts +287 -0
- package/dist/project-keys.mjs +122 -0
- package/dist/projects.d.mts +687 -0
- package/dist/projects.mjs +378 -0
- package/dist/provider-app-BANn4KOL.d.mts +45 -0
- package/dist/releases.d.mts +949 -0
- package/dist/releases.mjs +479 -0
- package/dist/replays.d.mts +307 -0
- package/dist/replays.mjs +192 -0
- package/dist/schemas.d.mts +381 -0
- package/dist/schemas.mjs +318 -0
- package/dist/scim.d.mts +413 -0
- package/dist/scim.mjs +249 -0
- package/dist/scopes-RRU0vt-a.mjs +36 -0
- package/dist/teams.d.mts +561 -0
- package/dist/teams.mjs +266 -0
- package/dist/triggers.d.mts +83 -0
- package/dist/triggers.mjs +263 -0
- package/dist/user-emails.d.mts +117 -0
- package/dist/user-emails.mjs +60 -0
- package/dist/verification.d.mts +30 -0
- package/dist/verification.mjs +83 -0
- package/dist/webhooks.d.mts +199 -0
- package/dist/webhooks.mjs +108 -0
- package/package.json +178 -0
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import * as _keystrokehq_core0 from "@keystrokehq/core";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import * as _keystrokehq_core_credential_set0 from "@keystrokehq/core/credential-set";
|
|
4
|
+
|
|
5
|
+
//#region src/user-emails.d.ts
|
|
6
|
+
declare const retrieveUserEmailInformation: _keystrokehq_core0.Operation<z.ZodObject<{}, z.core.$strip>, z.ZodArray<z.ZodObject<{
|
|
7
|
+
email: z.ZodString;
|
|
8
|
+
isPrimary: z.ZodOptional<z.ZodBoolean>;
|
|
9
|
+
isVerified: z.ZodOptional<z.ZodBoolean>;
|
|
10
|
+
}, z.core.$loose>>, readonly [_keystrokehq_core0.CredentialSet<"sentry", z.ZodObject<{
|
|
11
|
+
SENTRY_ACCESS_TOKEN: z.ZodString;
|
|
12
|
+
SENTRY_REGION_URL: z.ZodOptional<z.ZodString>;
|
|
13
|
+
SENTRY_ORG_SLUG: z.ZodOptional<z.ZodString>;
|
|
14
|
+
}, z.core.$strip>, readonly _keystrokehq_core_credential_set0.CredentialConnection<z.ZodObject<{
|
|
15
|
+
SENTRY_ACCESS_TOKEN: z.ZodString;
|
|
16
|
+
SENTRY_REGION_URL: z.ZodOptional<z.ZodString>;
|
|
17
|
+
SENTRY_ORG_SLUG: z.ZodOptional<z.ZodString>;
|
|
18
|
+
}, z.core.$strip>>[] | undefined>], undefined>;
|
|
19
|
+
declare const addRemoveUserEmailById: _keystrokehq_core0.Operation<z.ZodObject<{
|
|
20
|
+
email: z.ZodString;
|
|
21
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
22
|
+
email: z.ZodString;
|
|
23
|
+
isPrimary: z.ZodOptional<z.ZodBoolean>;
|
|
24
|
+
isVerified: z.ZodOptional<z.ZodBoolean>;
|
|
25
|
+
}, z.core.$loose>, readonly [_keystrokehq_core0.CredentialSet<"sentry", z.ZodObject<{
|
|
26
|
+
SENTRY_ACCESS_TOKEN: z.ZodString;
|
|
27
|
+
SENTRY_REGION_URL: z.ZodOptional<z.ZodString>;
|
|
28
|
+
SENTRY_ORG_SLUG: z.ZodOptional<z.ZodString>;
|
|
29
|
+
}, z.core.$strip>, readonly _keystrokehq_core_credential_set0.CredentialConnection<z.ZodObject<{
|
|
30
|
+
SENTRY_ACCESS_TOKEN: z.ZodString;
|
|
31
|
+
SENTRY_REGION_URL: z.ZodOptional<z.ZodString>;
|
|
32
|
+
SENTRY_ORG_SLUG: z.ZodOptional<z.ZodString>;
|
|
33
|
+
}, z.core.$strip>>[] | undefined>], undefined>;
|
|
34
|
+
declare const updateUserEmail: _keystrokehq_core0.Operation<z.ZodObject<{
|
|
35
|
+
email: z.ZodString;
|
|
36
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
37
|
+
email: z.ZodString;
|
|
38
|
+
isPrimary: z.ZodOptional<z.ZodBoolean>;
|
|
39
|
+
isVerified: z.ZodOptional<z.ZodBoolean>;
|
|
40
|
+
}, z.core.$loose>, readonly [_keystrokehq_core0.CredentialSet<"sentry", z.ZodObject<{
|
|
41
|
+
SENTRY_ACCESS_TOKEN: z.ZodString;
|
|
42
|
+
SENTRY_REGION_URL: z.ZodOptional<z.ZodString>;
|
|
43
|
+
SENTRY_ORG_SLUG: z.ZodOptional<z.ZodString>;
|
|
44
|
+
}, z.core.$strip>, readonly _keystrokehq_core_credential_set0.CredentialConnection<z.ZodObject<{
|
|
45
|
+
SENTRY_ACCESS_TOKEN: z.ZodString;
|
|
46
|
+
SENTRY_REGION_URL: z.ZodOptional<z.ZodString>;
|
|
47
|
+
SENTRY_ORG_SLUG: z.ZodOptional<z.ZodString>;
|
|
48
|
+
}, z.core.$strip>>[] | undefined>], undefined>;
|
|
49
|
+
declare const deleteUserEmailsById: _keystrokehq_core0.Operation<z.ZodObject<{
|
|
50
|
+
email: z.ZodString;
|
|
51
|
+
}, z.core.$strip>, z.ZodUnknown, readonly [_keystrokehq_core0.CredentialSet<"sentry", z.ZodObject<{
|
|
52
|
+
SENTRY_ACCESS_TOKEN: z.ZodString;
|
|
53
|
+
SENTRY_REGION_URL: z.ZodOptional<z.ZodString>;
|
|
54
|
+
SENTRY_ORG_SLUG: z.ZodOptional<z.ZodString>;
|
|
55
|
+
}, z.core.$strip>, readonly _keystrokehq_core_credential_set0.CredentialConnection<z.ZodObject<{
|
|
56
|
+
SENTRY_ACCESS_TOKEN: z.ZodString;
|
|
57
|
+
SENTRY_REGION_URL: z.ZodOptional<z.ZodString>;
|
|
58
|
+
SENTRY_ORG_SLUG: z.ZodOptional<z.ZodString>;
|
|
59
|
+
}, z.core.$strip>>[] | undefined>], undefined>;
|
|
60
|
+
declare const sentryUserEmailOperations: {
|
|
61
|
+
readonly retrieveUserEmailInformation: _keystrokehq_core0.Operation<z.ZodObject<{}, z.core.$strip>, z.ZodArray<z.ZodObject<{
|
|
62
|
+
email: z.ZodString;
|
|
63
|
+
isPrimary: z.ZodOptional<z.ZodBoolean>;
|
|
64
|
+
isVerified: z.ZodOptional<z.ZodBoolean>;
|
|
65
|
+
}, z.core.$loose>>, readonly [_keystrokehq_core0.CredentialSet<"sentry", z.ZodObject<{
|
|
66
|
+
SENTRY_ACCESS_TOKEN: z.ZodString;
|
|
67
|
+
SENTRY_REGION_URL: z.ZodOptional<z.ZodString>;
|
|
68
|
+
SENTRY_ORG_SLUG: z.ZodOptional<z.ZodString>;
|
|
69
|
+
}, z.core.$strip>, readonly _keystrokehq_core_credential_set0.CredentialConnection<z.ZodObject<{
|
|
70
|
+
SENTRY_ACCESS_TOKEN: z.ZodString;
|
|
71
|
+
SENTRY_REGION_URL: z.ZodOptional<z.ZodString>;
|
|
72
|
+
SENTRY_ORG_SLUG: z.ZodOptional<z.ZodString>;
|
|
73
|
+
}, z.core.$strip>>[] | undefined>], undefined>;
|
|
74
|
+
readonly addRemoveUserEmailById: _keystrokehq_core0.Operation<z.ZodObject<{
|
|
75
|
+
email: z.ZodString;
|
|
76
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
77
|
+
email: z.ZodString;
|
|
78
|
+
isPrimary: z.ZodOptional<z.ZodBoolean>;
|
|
79
|
+
isVerified: z.ZodOptional<z.ZodBoolean>;
|
|
80
|
+
}, z.core.$loose>, readonly [_keystrokehq_core0.CredentialSet<"sentry", z.ZodObject<{
|
|
81
|
+
SENTRY_ACCESS_TOKEN: z.ZodString;
|
|
82
|
+
SENTRY_REGION_URL: z.ZodOptional<z.ZodString>;
|
|
83
|
+
SENTRY_ORG_SLUG: z.ZodOptional<z.ZodString>;
|
|
84
|
+
}, z.core.$strip>, readonly _keystrokehq_core_credential_set0.CredentialConnection<z.ZodObject<{
|
|
85
|
+
SENTRY_ACCESS_TOKEN: z.ZodString;
|
|
86
|
+
SENTRY_REGION_URL: z.ZodOptional<z.ZodString>;
|
|
87
|
+
SENTRY_ORG_SLUG: z.ZodOptional<z.ZodString>;
|
|
88
|
+
}, z.core.$strip>>[] | undefined>], undefined>;
|
|
89
|
+
readonly updateUserEmail: _keystrokehq_core0.Operation<z.ZodObject<{
|
|
90
|
+
email: z.ZodString;
|
|
91
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
92
|
+
email: z.ZodString;
|
|
93
|
+
isPrimary: z.ZodOptional<z.ZodBoolean>;
|
|
94
|
+
isVerified: z.ZodOptional<z.ZodBoolean>;
|
|
95
|
+
}, z.core.$loose>, readonly [_keystrokehq_core0.CredentialSet<"sentry", z.ZodObject<{
|
|
96
|
+
SENTRY_ACCESS_TOKEN: z.ZodString;
|
|
97
|
+
SENTRY_REGION_URL: z.ZodOptional<z.ZodString>;
|
|
98
|
+
SENTRY_ORG_SLUG: z.ZodOptional<z.ZodString>;
|
|
99
|
+
}, z.core.$strip>, readonly _keystrokehq_core_credential_set0.CredentialConnection<z.ZodObject<{
|
|
100
|
+
SENTRY_ACCESS_TOKEN: z.ZodString;
|
|
101
|
+
SENTRY_REGION_URL: z.ZodOptional<z.ZodString>;
|
|
102
|
+
SENTRY_ORG_SLUG: z.ZodOptional<z.ZodString>;
|
|
103
|
+
}, z.core.$strip>>[] | undefined>], undefined>;
|
|
104
|
+
readonly deleteUserEmailsById: _keystrokehq_core0.Operation<z.ZodObject<{
|
|
105
|
+
email: z.ZodString;
|
|
106
|
+
}, z.core.$strip>, z.ZodUnknown, readonly [_keystrokehq_core0.CredentialSet<"sentry", z.ZodObject<{
|
|
107
|
+
SENTRY_ACCESS_TOKEN: z.ZodString;
|
|
108
|
+
SENTRY_REGION_URL: z.ZodOptional<z.ZodString>;
|
|
109
|
+
SENTRY_ORG_SLUG: z.ZodOptional<z.ZodString>;
|
|
110
|
+
}, z.core.$strip>, readonly _keystrokehq_core_credential_set0.CredentialConnection<z.ZodObject<{
|
|
111
|
+
SENTRY_ACCESS_TOKEN: z.ZodString;
|
|
112
|
+
SENTRY_REGION_URL: z.ZodOptional<z.ZodString>;
|
|
113
|
+
SENTRY_ORG_SLUG: z.ZodOptional<z.ZodString>;
|
|
114
|
+
}, z.core.$strip>>[] | undefined>], undefined>;
|
|
115
|
+
};
|
|
116
|
+
//#endregion
|
|
117
|
+
export { addRemoveUserEmailById, deleteUserEmailsById, retrieveUserEmailInformation, sentryUserEmailOperations, updateUserEmail };
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { sentryUserEmailSchema } from "./schemas.mjs";
|
|
2
|
+
import { t as defineSentryEndpoint } from "./endpoint-factory-BwjbcPwW.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: "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: "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: "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: "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 };
|
|
@@ -0,0 +1,30 @@
|
|
|
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 };
|
|
@@ -0,0 +1,83 @@
|
|
|
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 };
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
import * as _keystrokehq_core0 from "@keystrokehq/core";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import * as _keystrokehq_core_credential_set0 from "@keystrokehq/core/credential-set";
|
|
4
|
+
|
|
5
|
+
//#region src/webhooks.d.ts
|
|
6
|
+
declare const createProjectWebhookSubscription: _keystrokehq_core0.Operation<z.ZodObject<{
|
|
7
|
+
organization_slug: z.ZodOptional<z.ZodString>;
|
|
8
|
+
project_slug: z.ZodString;
|
|
9
|
+
url: z.ZodString;
|
|
10
|
+
events: z.ZodArray<z.ZodString>;
|
|
11
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
12
|
+
id: z.ZodString;
|
|
13
|
+
url: z.ZodString;
|
|
14
|
+
events: z.ZodArray<z.ZodString>;
|
|
15
|
+
dateCreated: z.ZodOptional<z.ZodISODateTime>;
|
|
16
|
+
disabled: z.ZodOptional<z.ZodBoolean>;
|
|
17
|
+
}, z.core.$loose>, readonly [_keystrokehq_core0.CredentialSet<"sentry", z.ZodObject<{
|
|
18
|
+
SENTRY_ACCESS_TOKEN: z.ZodString;
|
|
19
|
+
SENTRY_REGION_URL: z.ZodOptional<z.ZodString>;
|
|
20
|
+
SENTRY_ORG_SLUG: z.ZodOptional<z.ZodString>;
|
|
21
|
+
}, z.core.$strip>, readonly _keystrokehq_core_credential_set0.CredentialConnection<z.ZodObject<{
|
|
22
|
+
SENTRY_ACCESS_TOKEN: z.ZodString;
|
|
23
|
+
SENTRY_REGION_URL: z.ZodOptional<z.ZodString>;
|
|
24
|
+
SENTRY_ORG_SLUG: z.ZodOptional<z.ZodString>;
|
|
25
|
+
}, z.core.$strip>>[] | undefined>], undefined>;
|
|
26
|
+
declare const retrieveProjectHooks: _keystrokehq_core0.Operation<z.ZodObject<{
|
|
27
|
+
cursor: z.ZodOptional<z.ZodString>;
|
|
28
|
+
per_page: z.ZodOptional<z.ZodNumber>;
|
|
29
|
+
query: z.ZodOptional<z.ZodString>;
|
|
30
|
+
organization_slug: z.ZodOptional<z.ZodString>;
|
|
31
|
+
project_slug: z.ZodString;
|
|
32
|
+
}, z.core.$strip>, z.ZodArray<z.ZodObject<{
|
|
33
|
+
id: z.ZodString;
|
|
34
|
+
url: z.ZodString;
|
|
35
|
+
events: z.ZodArray<z.ZodString>;
|
|
36
|
+
dateCreated: z.ZodOptional<z.ZodISODateTime>;
|
|
37
|
+
disabled: z.ZodOptional<z.ZodBoolean>;
|
|
38
|
+
}, z.core.$loose>>, readonly [_keystrokehq_core0.CredentialSet<"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>, readonly _keystrokehq_core_credential_set0.CredentialConnection<z.ZodObject<{
|
|
43
|
+
SENTRY_ACCESS_TOKEN: z.ZodString;
|
|
44
|
+
SENTRY_REGION_URL: z.ZodOptional<z.ZodString>;
|
|
45
|
+
SENTRY_ORG_SLUG: z.ZodOptional<z.ZodString>;
|
|
46
|
+
}, z.core.$strip>>[] | undefined>], undefined>;
|
|
47
|
+
declare const getProjectHook: _keystrokehq_core0.Operation<z.ZodObject<{
|
|
48
|
+
organization_slug: z.ZodOptional<z.ZodString>;
|
|
49
|
+
project_slug: z.ZodString;
|
|
50
|
+
hook_id: z.ZodString;
|
|
51
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
52
|
+
id: z.ZodString;
|
|
53
|
+
url: z.ZodString;
|
|
54
|
+
events: z.ZodArray<z.ZodString>;
|
|
55
|
+
dateCreated: z.ZodOptional<z.ZodISODateTime>;
|
|
56
|
+
disabled: z.ZodOptional<z.ZodBoolean>;
|
|
57
|
+
}, z.core.$loose>, readonly [_keystrokehq_core0.CredentialSet<"sentry", z.ZodObject<{
|
|
58
|
+
SENTRY_ACCESS_TOKEN: z.ZodString;
|
|
59
|
+
SENTRY_REGION_URL: z.ZodOptional<z.ZodString>;
|
|
60
|
+
SENTRY_ORG_SLUG: z.ZodOptional<z.ZodString>;
|
|
61
|
+
}, z.core.$strip>, readonly _keystrokehq_core_credential_set0.CredentialConnection<z.ZodObject<{
|
|
62
|
+
SENTRY_ACCESS_TOKEN: z.ZodString;
|
|
63
|
+
SENTRY_REGION_URL: z.ZodOptional<z.ZodString>;
|
|
64
|
+
SENTRY_ORG_SLUG: z.ZodOptional<z.ZodString>;
|
|
65
|
+
}, z.core.$strip>>[] | undefined>], undefined>;
|
|
66
|
+
declare const updateWebhookConfiguration: _keystrokehq_core0.Operation<z.ZodObject<{
|
|
67
|
+
organization_slug: z.ZodOptional<z.ZodString>;
|
|
68
|
+
project_slug: z.ZodString;
|
|
69
|
+
hook_id: z.ZodString;
|
|
70
|
+
url: z.ZodOptional<z.ZodString>;
|
|
71
|
+
events: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
72
|
+
isActive: z.ZodOptional<z.ZodBoolean>;
|
|
73
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
74
|
+
id: z.ZodString;
|
|
75
|
+
url: z.ZodString;
|
|
76
|
+
events: z.ZodArray<z.ZodString>;
|
|
77
|
+
dateCreated: z.ZodOptional<z.ZodISODateTime>;
|
|
78
|
+
disabled: z.ZodOptional<z.ZodBoolean>;
|
|
79
|
+
}, z.core.$loose>, readonly [_keystrokehq_core0.CredentialSet<"sentry", z.ZodObject<{
|
|
80
|
+
SENTRY_ACCESS_TOKEN: z.ZodString;
|
|
81
|
+
SENTRY_REGION_URL: z.ZodOptional<z.ZodString>;
|
|
82
|
+
SENTRY_ORG_SLUG: z.ZodOptional<z.ZodString>;
|
|
83
|
+
}, z.core.$strip>, readonly _keystrokehq_core_credential_set0.CredentialConnection<z.ZodObject<{
|
|
84
|
+
SENTRY_ACCESS_TOKEN: z.ZodString;
|
|
85
|
+
SENTRY_REGION_URL: z.ZodOptional<z.ZodString>;
|
|
86
|
+
SENTRY_ORG_SLUG: z.ZodOptional<z.ZodString>;
|
|
87
|
+
}, z.core.$strip>>[] | undefined>], undefined>;
|
|
88
|
+
declare const deleteProjectHook: _keystrokehq_core0.Operation<z.ZodObject<{
|
|
89
|
+
organization_slug: z.ZodOptional<z.ZodString>;
|
|
90
|
+
project_slug: z.ZodString;
|
|
91
|
+
hook_id: z.ZodString;
|
|
92
|
+
}, z.core.$strip>, z.ZodUnknown, readonly [_keystrokehq_core0.CredentialSet<"sentry", z.ZodObject<{
|
|
93
|
+
SENTRY_ACCESS_TOKEN: z.ZodString;
|
|
94
|
+
SENTRY_REGION_URL: z.ZodOptional<z.ZodString>;
|
|
95
|
+
SENTRY_ORG_SLUG: z.ZodOptional<z.ZodString>;
|
|
96
|
+
}, z.core.$strip>, readonly _keystrokehq_core_credential_set0.CredentialConnection<z.ZodObject<{
|
|
97
|
+
SENTRY_ACCESS_TOKEN: z.ZodString;
|
|
98
|
+
SENTRY_REGION_URL: z.ZodOptional<z.ZodString>;
|
|
99
|
+
SENTRY_ORG_SLUG: z.ZodOptional<z.ZodString>;
|
|
100
|
+
}, z.core.$strip>>[] | undefined>], undefined>;
|
|
101
|
+
declare const sentryWebhookOperations: {
|
|
102
|
+
readonly createProjectWebhookSubscription: _keystrokehq_core0.Operation<z.ZodObject<{
|
|
103
|
+
organization_slug: z.ZodOptional<z.ZodString>;
|
|
104
|
+
project_slug: z.ZodString;
|
|
105
|
+
url: z.ZodString;
|
|
106
|
+
events: z.ZodArray<z.ZodString>;
|
|
107
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
108
|
+
id: z.ZodString;
|
|
109
|
+
url: z.ZodString;
|
|
110
|
+
events: z.ZodArray<z.ZodString>;
|
|
111
|
+
dateCreated: z.ZodOptional<z.ZodISODateTime>;
|
|
112
|
+
disabled: z.ZodOptional<z.ZodBoolean>;
|
|
113
|
+
}, z.core.$loose>, readonly [_keystrokehq_core0.CredentialSet<"sentry", z.ZodObject<{
|
|
114
|
+
SENTRY_ACCESS_TOKEN: z.ZodString;
|
|
115
|
+
SENTRY_REGION_URL: z.ZodOptional<z.ZodString>;
|
|
116
|
+
SENTRY_ORG_SLUG: z.ZodOptional<z.ZodString>;
|
|
117
|
+
}, z.core.$strip>, readonly _keystrokehq_core_credential_set0.CredentialConnection<z.ZodObject<{
|
|
118
|
+
SENTRY_ACCESS_TOKEN: z.ZodString;
|
|
119
|
+
SENTRY_REGION_URL: z.ZodOptional<z.ZodString>;
|
|
120
|
+
SENTRY_ORG_SLUG: z.ZodOptional<z.ZodString>;
|
|
121
|
+
}, z.core.$strip>>[] | undefined>], undefined>;
|
|
122
|
+
readonly retrieveProjectHooks: _keystrokehq_core0.Operation<z.ZodObject<{
|
|
123
|
+
cursor: z.ZodOptional<z.ZodString>;
|
|
124
|
+
per_page: z.ZodOptional<z.ZodNumber>;
|
|
125
|
+
query: z.ZodOptional<z.ZodString>;
|
|
126
|
+
organization_slug: z.ZodOptional<z.ZodString>;
|
|
127
|
+
project_slug: z.ZodString;
|
|
128
|
+
}, z.core.$strip>, z.ZodArray<z.ZodObject<{
|
|
129
|
+
id: z.ZodString;
|
|
130
|
+
url: z.ZodString;
|
|
131
|
+
events: z.ZodArray<z.ZodString>;
|
|
132
|
+
dateCreated: z.ZodOptional<z.ZodISODateTime>;
|
|
133
|
+
disabled: z.ZodOptional<z.ZodBoolean>;
|
|
134
|
+
}, z.core.$loose>>, readonly [_keystrokehq_core0.CredentialSet<"sentry", z.ZodObject<{
|
|
135
|
+
SENTRY_ACCESS_TOKEN: z.ZodString;
|
|
136
|
+
SENTRY_REGION_URL: z.ZodOptional<z.ZodString>;
|
|
137
|
+
SENTRY_ORG_SLUG: z.ZodOptional<z.ZodString>;
|
|
138
|
+
}, z.core.$strip>, readonly _keystrokehq_core_credential_set0.CredentialConnection<z.ZodObject<{
|
|
139
|
+
SENTRY_ACCESS_TOKEN: z.ZodString;
|
|
140
|
+
SENTRY_REGION_URL: z.ZodOptional<z.ZodString>;
|
|
141
|
+
SENTRY_ORG_SLUG: z.ZodOptional<z.ZodString>;
|
|
142
|
+
}, z.core.$strip>>[] | undefined>], undefined>;
|
|
143
|
+
readonly getProjectHook: _keystrokehq_core0.Operation<z.ZodObject<{
|
|
144
|
+
organization_slug: z.ZodOptional<z.ZodString>;
|
|
145
|
+
project_slug: z.ZodString;
|
|
146
|
+
hook_id: z.ZodString;
|
|
147
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
148
|
+
id: z.ZodString;
|
|
149
|
+
url: z.ZodString;
|
|
150
|
+
events: z.ZodArray<z.ZodString>;
|
|
151
|
+
dateCreated: z.ZodOptional<z.ZodISODateTime>;
|
|
152
|
+
disabled: z.ZodOptional<z.ZodBoolean>;
|
|
153
|
+
}, z.core.$loose>, readonly [_keystrokehq_core0.CredentialSet<"sentry", z.ZodObject<{
|
|
154
|
+
SENTRY_ACCESS_TOKEN: z.ZodString;
|
|
155
|
+
SENTRY_REGION_URL: z.ZodOptional<z.ZodString>;
|
|
156
|
+
SENTRY_ORG_SLUG: z.ZodOptional<z.ZodString>;
|
|
157
|
+
}, z.core.$strip>, readonly _keystrokehq_core_credential_set0.CredentialConnection<z.ZodObject<{
|
|
158
|
+
SENTRY_ACCESS_TOKEN: z.ZodString;
|
|
159
|
+
SENTRY_REGION_URL: z.ZodOptional<z.ZodString>;
|
|
160
|
+
SENTRY_ORG_SLUG: z.ZodOptional<z.ZodString>;
|
|
161
|
+
}, z.core.$strip>>[] | undefined>], undefined>;
|
|
162
|
+
readonly updateWebhookConfiguration: _keystrokehq_core0.Operation<z.ZodObject<{
|
|
163
|
+
organization_slug: z.ZodOptional<z.ZodString>;
|
|
164
|
+
project_slug: z.ZodString;
|
|
165
|
+
hook_id: z.ZodString;
|
|
166
|
+
url: z.ZodOptional<z.ZodString>;
|
|
167
|
+
events: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
168
|
+
isActive: z.ZodOptional<z.ZodBoolean>;
|
|
169
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
170
|
+
id: z.ZodString;
|
|
171
|
+
url: z.ZodString;
|
|
172
|
+
events: z.ZodArray<z.ZodString>;
|
|
173
|
+
dateCreated: z.ZodOptional<z.ZodISODateTime>;
|
|
174
|
+
disabled: z.ZodOptional<z.ZodBoolean>;
|
|
175
|
+
}, z.core.$loose>, readonly [_keystrokehq_core0.CredentialSet<"sentry", z.ZodObject<{
|
|
176
|
+
SENTRY_ACCESS_TOKEN: z.ZodString;
|
|
177
|
+
SENTRY_REGION_URL: z.ZodOptional<z.ZodString>;
|
|
178
|
+
SENTRY_ORG_SLUG: z.ZodOptional<z.ZodString>;
|
|
179
|
+
}, z.core.$strip>, readonly _keystrokehq_core_credential_set0.CredentialConnection<z.ZodObject<{
|
|
180
|
+
SENTRY_ACCESS_TOKEN: z.ZodString;
|
|
181
|
+
SENTRY_REGION_URL: z.ZodOptional<z.ZodString>;
|
|
182
|
+
SENTRY_ORG_SLUG: z.ZodOptional<z.ZodString>;
|
|
183
|
+
}, z.core.$strip>>[] | undefined>], undefined>;
|
|
184
|
+
readonly deleteProjectHook: _keystrokehq_core0.Operation<z.ZodObject<{
|
|
185
|
+
organization_slug: z.ZodOptional<z.ZodString>;
|
|
186
|
+
project_slug: z.ZodString;
|
|
187
|
+
hook_id: z.ZodString;
|
|
188
|
+
}, z.core.$strip>, z.ZodUnknown, readonly [_keystrokehq_core0.CredentialSet<"sentry", z.ZodObject<{
|
|
189
|
+
SENTRY_ACCESS_TOKEN: z.ZodString;
|
|
190
|
+
SENTRY_REGION_URL: z.ZodOptional<z.ZodString>;
|
|
191
|
+
SENTRY_ORG_SLUG: z.ZodOptional<z.ZodString>;
|
|
192
|
+
}, z.core.$strip>, readonly _keystrokehq_core_credential_set0.CredentialConnection<z.ZodObject<{
|
|
193
|
+
SENTRY_ACCESS_TOKEN: z.ZodString;
|
|
194
|
+
SENTRY_REGION_URL: z.ZodOptional<z.ZodString>;
|
|
195
|
+
SENTRY_ORG_SLUG: z.ZodOptional<z.ZodString>;
|
|
196
|
+
}, z.core.$strip>>[] | undefined>], undefined>;
|
|
197
|
+
};
|
|
198
|
+
//#endregion
|
|
199
|
+
export { createProjectWebhookSubscription, deleteProjectHook, getProjectHook, retrieveProjectHooks, sentryWebhookOperations, updateWebhookConfiguration };
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { orgProjectScopeInputSchema, sentryIdSchema, sentryListInputSchema, sentryProjectHookSchema } 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/webhooks.ts
|
|
7
|
+
/**
|
|
8
|
+
* Sentry legacy project service-hook operations. Maps to PLAN.md §6.16 (5 actions).
|
|
9
|
+
*/
|
|
10
|
+
const ORG_PROJECT = [{
|
|
11
|
+
name: "organization_slug",
|
|
12
|
+
placeholder: "{organization_slug}"
|
|
13
|
+
}, {
|
|
14
|
+
name: "project_slug",
|
|
15
|
+
placeholder: "{project_slug}"
|
|
16
|
+
}];
|
|
17
|
+
const ORG_PROJECT_HOOK = [...ORG_PROJECT, {
|
|
18
|
+
name: "hook_id",
|
|
19
|
+
placeholder: "{hook_id}"
|
|
20
|
+
}];
|
|
21
|
+
const createProjectWebhookSubscription = defineSentryEndpoint({
|
|
22
|
+
id: "create_project_webhook_subscription",
|
|
23
|
+
name: "Create Project Service Hook",
|
|
24
|
+
description: "Create a legacy per-project service hook. Prefer an integration webhook for new installs.",
|
|
25
|
+
method: "POST",
|
|
26
|
+
path: "/api/0/projects/{organization_slug}/{project_slug}/hooks/",
|
|
27
|
+
pathParams: ORG_PROJECT,
|
|
28
|
+
input: orgProjectScopeInputSchema.extend({
|
|
29
|
+
url: z.string().url(),
|
|
30
|
+
events: z.array(z.string()).min(1)
|
|
31
|
+
}),
|
|
32
|
+
bodyFields: ["url", "events"],
|
|
33
|
+
output: sentryProjectHookSchema,
|
|
34
|
+
needsApproval: true,
|
|
35
|
+
requiredOAuthScopes: [...SENTRY_SCOPE.projectAdmin]
|
|
36
|
+
});
|
|
37
|
+
const retrieveProjectHooks = defineSentryEndpoint({
|
|
38
|
+
id: "retrieve_project_hooks",
|
|
39
|
+
name: "List Project Service Hooks",
|
|
40
|
+
description: "List the service hooks configured on a project.",
|
|
41
|
+
method: "GET",
|
|
42
|
+
path: "/api/0/projects/{organization_slug}/{project_slug}/hooks/",
|
|
43
|
+
pathParams: ORG_PROJECT,
|
|
44
|
+
input: sentryListInputSchema.merge(orgProjectScopeInputSchema),
|
|
45
|
+
queryFields: [
|
|
46
|
+
"cursor",
|
|
47
|
+
"per_page",
|
|
48
|
+
"query"
|
|
49
|
+
],
|
|
50
|
+
output: z.array(sentryProjectHookSchema),
|
|
51
|
+
pagination: "cursor",
|
|
52
|
+
requiredOAuthScopes: [...SENTRY_SCOPE.projectRead]
|
|
53
|
+
});
|
|
54
|
+
const getProjectHook = defineSentryEndpoint({
|
|
55
|
+
id: "get_project_hook",
|
|
56
|
+
name: "Get Project Service Hook",
|
|
57
|
+
description: "Fetch a project service hook by id.",
|
|
58
|
+
method: "GET",
|
|
59
|
+
path: "/api/0/projects/{organization_slug}/{project_slug}/hooks/{hook_id}/",
|
|
60
|
+
pathParams: ORG_PROJECT_HOOK,
|
|
61
|
+
input: orgProjectScopeInputSchema.extend({ hook_id: sentryIdSchema }),
|
|
62
|
+
output: sentryProjectHookSchema,
|
|
63
|
+
requiredOAuthScopes: [...SENTRY_SCOPE.projectRead]
|
|
64
|
+
});
|
|
65
|
+
const updateWebhookConfiguration = defineSentryEndpoint({
|
|
66
|
+
id: "update_webhook_configuration_xp",
|
|
67
|
+
name: "Update Project Service Hook",
|
|
68
|
+
description: "Update a project service hook in place.",
|
|
69
|
+
method: "PUT",
|
|
70
|
+
path: "/api/0/projects/{organization_slug}/{project_slug}/hooks/{hook_id}/",
|
|
71
|
+
pathParams: ORG_PROJECT_HOOK,
|
|
72
|
+
input: orgProjectScopeInputSchema.extend({
|
|
73
|
+
hook_id: sentryIdSchema,
|
|
74
|
+
url: z.string().url().optional(),
|
|
75
|
+
events: z.array(z.string()).optional(),
|
|
76
|
+
isActive: z.boolean().optional()
|
|
77
|
+
}),
|
|
78
|
+
bodyFields: [
|
|
79
|
+
"url",
|
|
80
|
+
"events",
|
|
81
|
+
"isActive"
|
|
82
|
+
],
|
|
83
|
+
output: sentryProjectHookSchema,
|
|
84
|
+
needsApproval: true,
|
|
85
|
+
requiredOAuthScopes: [...SENTRY_SCOPE.projectAdmin]
|
|
86
|
+
});
|
|
87
|
+
const deleteProjectHook = defineSentryEndpoint({
|
|
88
|
+
id: "delete_project_hook",
|
|
89
|
+
name: "Delete Project Service Hook",
|
|
90
|
+
description: "Delete a project service hook by id.",
|
|
91
|
+
method: "DELETE",
|
|
92
|
+
path: "/api/0/projects/{organization_slug}/{project_slug}/hooks/{hook_id}/",
|
|
93
|
+
pathParams: ORG_PROJECT_HOOK,
|
|
94
|
+
input: orgProjectScopeInputSchema.extend({ hook_id: sentryIdSchema }),
|
|
95
|
+
output: z.unknown(),
|
|
96
|
+
needsApproval: true,
|
|
97
|
+
requiredOAuthScopes: [...SENTRY_SCOPE.projectAdmin]
|
|
98
|
+
});
|
|
99
|
+
const sentryWebhookOperations = {
|
|
100
|
+
createProjectWebhookSubscription,
|
|
101
|
+
retrieveProjectHooks,
|
|
102
|
+
getProjectHook,
|
|
103
|
+
updateWebhookConfiguration,
|
|
104
|
+
deleteProjectHook
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
//#endregion
|
|
108
|
+
export { createProjectWebhookSubscription, deleteProjectHook, getProjectHook, retrieveProjectHooks, sentryWebhookOperations, updateWebhookConfiguration };
|