@theholocron/holocron-plugin-sentry 5.0.0-alpha.223 → 5.0.0-alpha.225
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.mjs +28 -15
- package/package.json +3 -3
package/dist/index.mjs
CHANGED
|
@@ -34,16 +34,23 @@ function resolveRelayToken(input = {}) {
|
|
|
34
34
|
/** What the integration needs to read: the alert's event. It is also why reading its secret needs the same scope. */
|
|
35
35
|
const INTEGRATION_SCOPES = ["event:read"];
|
|
36
36
|
const DEFAULT_FREQUENCY = 5;
|
|
37
|
-
/**
|
|
38
|
-
|
|
39
|
-
|
|
37
|
+
/**
|
|
38
|
+
* The alert action that sends through an integration, in the shape Sentry's own page writes when "Send a notification via
|
|
39
|
+
* an integration" is picked: a `webhook` action named by the integration's slug. (A `sentry_app` action with the numeric
|
|
40
|
+
* id is accepted too, but the page shows it as an unknown integration.)
|
|
41
|
+
*/
|
|
42
|
+
const integrationAction = (slug) => ({
|
|
43
|
+
type: "webhook",
|
|
40
44
|
config: {
|
|
41
|
-
targetType:
|
|
42
|
-
|
|
45
|
+
targetType: null,
|
|
46
|
+
targetDisplay: null,
|
|
47
|
+
targetIdentifier: slug
|
|
43
48
|
},
|
|
44
49
|
data: {}
|
|
45
50
|
});
|
|
46
|
-
const
|
|
51
|
+
const sendsThrough = (action, slug) => action.type === "webhook" && action.config["targetIdentifier"] === slug;
|
|
52
|
+
/** The `sentry_app` form an earlier version wrote for this integration, which the page cannot name. */
|
|
53
|
+
const isLegacyAction = (action, appId) => action.type === "sentry_app" && String(action.config["targetIdentifier"]) === String(appId);
|
|
47
54
|
/** A workflow as Sentry returned it, as the body to send back (the nested ids are not part of an update). */
|
|
48
55
|
function toInput(wf) {
|
|
49
56
|
return {
|
|
@@ -76,7 +83,7 @@ function toInput(wf) {
|
|
|
76
83
|
};
|
|
77
84
|
}
|
|
78
85
|
/** Sentry's own "high priority issues" rule, which is the default for a new alert. */
|
|
79
|
-
function newWorkflow(name, frequency, detectorIds,
|
|
86
|
+
function newWorkflow(name, frequency, detectorIds, slug) {
|
|
80
87
|
return {
|
|
81
88
|
name,
|
|
82
89
|
enabled: true,
|
|
@@ -98,7 +105,7 @@ function newWorkflow(name, frequency, detectorIds, appId) {
|
|
|
98
105
|
actionFilters: [{
|
|
99
106
|
logicType: "all",
|
|
100
107
|
conditions: [],
|
|
101
|
-
actions: [
|
|
108
|
+
actions: [integrationAction(slug)]
|
|
102
109
|
}]
|
|
103
110
|
};
|
|
104
111
|
}
|
|
@@ -148,12 +155,12 @@ async function detectorsFor(client, org, slugs) {
|
|
|
148
155
|
});
|
|
149
156
|
}
|
|
150
157
|
/** The alert rule: one workflow for every project, found by name, made if missing, reconciled if not. */
|
|
151
|
-
async function ensureRule(client, org, input,
|
|
158
|
+
async function ensureRule(client, org, input, install, detectorIds) {
|
|
152
159
|
const workflows = await client.workflows.list(org);
|
|
153
160
|
const frequency = input.rule.frequency ?? DEFAULT_FREQUENCY;
|
|
154
161
|
const existing = workflows.find((w) => w.name === input.rule.name);
|
|
155
162
|
if (!existing) {
|
|
156
|
-
await client.workflows.create(org, newWorkflow(input.rule.name, frequency, detectorIds,
|
|
163
|
+
await client.workflows.create(org, newWorkflow(input.rule.name, frequency, detectorIds, install.slug));
|
|
157
164
|
return {
|
|
158
165
|
created: true,
|
|
159
166
|
updated: []
|
|
@@ -177,16 +184,19 @@ async function ensureRule(client, org, input, appId, detectorIds) {
|
|
|
177
184
|
next.detectorIds = [...existing.detectorIds, ...missing];
|
|
178
185
|
updated.push("projects");
|
|
179
186
|
}
|
|
180
|
-
|
|
187
|
+
const sends = existing.actionFilters.some((f) => f.actions.some((a) => sendsThrough(a, install.slug)));
|
|
188
|
+
const legacy = existing.actionFilters.some((f) => f.actions.some((a) => isLegacyAction(a, install.appId)));
|
|
189
|
+
if (legacy) for (const f of next.actionFilters) f.actions = f.actions.filter((a) => !isLegacyAction(a, install.appId));
|
|
190
|
+
if (!sends) {
|
|
181
191
|
const open = next.actionFilters.find((f) => f.conditions.length === 0);
|
|
182
|
-
if (open) open.actions.push(
|
|
192
|
+
if (open) open.actions.push(integrationAction(install.slug));
|
|
183
193
|
else next.actionFilters.push({
|
|
184
194
|
logicType: "all",
|
|
185
195
|
conditions: [],
|
|
186
|
-
actions: [
|
|
196
|
+
actions: [integrationAction(install.slug)]
|
|
187
197
|
});
|
|
188
|
-
updated.push("action");
|
|
189
198
|
}
|
|
199
|
+
if (legacy || !sends) updated.push("action");
|
|
190
200
|
if (updated.length === 0) return {
|
|
191
201
|
created: false,
|
|
192
202
|
updated
|
|
@@ -208,7 +218,10 @@ async function ensureSentryRelay(client, org, input) {
|
|
|
208
218
|
const integration = await ensureIntegration(client, org, input);
|
|
209
219
|
const install = (await client.sentryApps.installations(org)).find((i) => i.app.slug === integration.app.slug);
|
|
210
220
|
if (!install) throw new Error(`the integration \`${integration.app.name}\` is not installed on ${org}`);
|
|
211
|
-
const rule = await ensureRule(client, org, input,
|
|
221
|
+
const rule = await ensureRule(client, org, input, {
|
|
222
|
+
slug: install.app.slug,
|
|
223
|
+
appId: install.app.sentryAppId
|
|
224
|
+
}, detectorIds);
|
|
212
225
|
const clientSecret = await secretOf(client, integration.app);
|
|
213
226
|
return {
|
|
214
227
|
integration: {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@theholocron/holocron-plugin-sentry",
|
|
3
|
-
"version": "5.0.0-alpha.
|
|
3
|
+
"version": "5.0.0-alpha.225",
|
|
4
4
|
"description": "Holocron plugin for Sentry. Implements the errors capability against Sentry's management API — project provisioning and DSN retrieval.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"errors",
|
|
@@ -48,12 +48,12 @@
|
|
|
48
48
|
"tsx": "4.23.15",
|
|
49
49
|
"typescript": "^5.9.3",
|
|
50
50
|
"vitest": "^4.1.11",
|
|
51
|
-
"@theholocron/cli": "5.0.0-alpha.
|
|
51
|
+
"@theholocron/cli": "5.0.0-alpha.225"
|
|
52
52
|
},
|
|
53
53
|
"peerDependencies": {
|
|
54
54
|
"@theholocron/misc-utils": "^1.16.0",
|
|
55
55
|
"@theholocron/sentry-client": "^1.54.0",
|
|
56
|
-
"@theholocron/cli": "5.0.0-alpha.
|
|
56
|
+
"@theholocron/cli": "5.0.0-alpha.225"
|
|
57
57
|
},
|
|
58
58
|
"peerDependenciesMeta": {
|
|
59
59
|
"@theholocron/sentry-client": {}
|