@sentry/junior-vercel 0.265.0 → 0.267.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/dist/{chunk-XALO46RT.js → chunk-5IIQV7WI.js} +91 -63
- package/dist/events/deployment.d.ts +18 -2
- package/dist/index.js +13 -2
- package/dist/testing.js +1 -1
- package/dist/webhooks/events.d.ts +4 -1
- package/package.json +4 -3
package/README.md
CHANGED
|
@@ -59,6 +59,8 @@ Each event has the name of the Vercel webhook that it comes from:
|
|
|
59
59
|
|
|
60
60
|
All three events end a commit-scoped watch. Project and target watches stay active.
|
|
61
61
|
|
|
62
|
+
Each deployment event has trusted data: `deploymentId`, `target`, and `commitSha` when the deployment came from a Git commit. Watches and event automations can filter on `target` (`preview`, `production`, or `staging`) and `commitSha`.
|
|
63
|
+
|
|
62
64
|
Create the conversation watch or event automation before the terminal deployment event. A valid webhook delivery does not create a watch by itself, and unmatched deliveries are not replayed later.
|
|
63
65
|
|
|
64
66
|
## Auth model
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
// src/events/deployment.ts
|
|
2
|
+
import {
|
|
3
|
+
eventMatchFieldsSchema
|
|
4
|
+
} from "@sentry/junior-plugin-api";
|
|
2
5
|
var VERCEL_DEPLOYMENT_EVENTS = [
|
|
3
6
|
"deployment.succeeded",
|
|
4
7
|
"deployment.error",
|
|
@@ -9,15 +12,44 @@ var VERCEL_DEPLOYMENT_SUGGESTED_EVENTS = [
|
|
|
9
12
|
"deployment.error",
|
|
10
13
|
"deployment.canceled"
|
|
11
14
|
];
|
|
15
|
+
var VERCEL_DEPLOYMENT_TARGETS = [
|
|
16
|
+
"preview",
|
|
17
|
+
"production",
|
|
18
|
+
"staging"
|
|
19
|
+
];
|
|
20
|
+
var VERCEL_DEPLOYMENT_MATCH_FIELDS = eventMatchFieldsSchema.parse({
|
|
21
|
+
projectId: {
|
|
22
|
+
kind: "string",
|
|
23
|
+
description: "Vercel project id, such as prj_abc123",
|
|
24
|
+
events: [...VERCEL_DEPLOYMENT_EVENTS]
|
|
25
|
+
},
|
|
26
|
+
deploymentId: {
|
|
27
|
+
kind: "string",
|
|
28
|
+
description: "Vercel deployment id, such as dpl_abc123",
|
|
29
|
+
events: [...VERCEL_DEPLOYMENT_EVENTS]
|
|
30
|
+
},
|
|
31
|
+
target: {
|
|
32
|
+
kind: "string",
|
|
33
|
+
description: "where Vercel deployed: preview, production, or staging",
|
|
34
|
+
enum: [...VERCEL_DEPLOYMENT_TARGETS],
|
|
35
|
+
events: [...VERCEL_DEPLOYMENT_EVENTS]
|
|
36
|
+
},
|
|
37
|
+
commitSha: {
|
|
38
|
+
kind: "string",
|
|
39
|
+
case: "lower",
|
|
40
|
+
description: "full lowercase Git commit SHA of the deployment, when it came from a Git commit",
|
|
41
|
+
events: [...VERCEL_DEPLOYMENT_EVENTS]
|
|
42
|
+
}
|
|
43
|
+
});
|
|
12
44
|
function vercelDeploymentResource(input) {
|
|
13
|
-
const
|
|
45
|
+
const commitSha = input.commitSha?.toLowerCase();
|
|
14
46
|
const target = input.target;
|
|
15
47
|
const parts = [input.projectId];
|
|
16
48
|
if (target) parts.push(target);
|
|
17
|
-
if (
|
|
49
|
+
if (commitSha) parts.push(commitSha);
|
|
18
50
|
let label;
|
|
19
|
-
if (target &&
|
|
20
|
-
label = `Vercel ${target} deployment for ${input.projectId} at ${
|
|
51
|
+
if (target && commitSha) {
|
|
52
|
+
label = `Vercel ${target} deployment for ${input.projectId} at ${commitSha.slice(0, 12)}`;
|
|
21
53
|
} else if (target) {
|
|
22
54
|
label = `Vercel ${target} deployments for ${input.projectId}`;
|
|
23
55
|
} else {
|
|
@@ -122,17 +154,17 @@ function createVercelDeploymentTool(ctx) {
|
|
|
122
154
|
throw new Error(message);
|
|
123
155
|
}
|
|
124
156
|
const projectId = z2.object({ id: vercelProjectIdSchema }).parse(parsed).id;
|
|
125
|
-
const
|
|
126
|
-
const
|
|
157
|
+
const commitSha = input.commitSha?.toLowerCase();
|
|
158
|
+
const deploymentTarget = input.target ?? (commitSha ? "production" : void 0);
|
|
127
159
|
const subscribable = vercelDeploymentSubscribable({
|
|
128
160
|
canSubscribe: ctx.events.canSubscribe,
|
|
129
|
-
commitSha
|
|
161
|
+
commitSha,
|
|
130
162
|
projectId,
|
|
131
|
-
target:
|
|
163
|
+
target: deploymentTarget
|
|
132
164
|
});
|
|
133
165
|
const data = {
|
|
134
|
-
commitSha:
|
|
135
|
-
deploymentTarget:
|
|
166
|
+
commitSha: commitSha ?? null,
|
|
167
|
+
deploymentTarget: deploymentTarget ?? null,
|
|
136
168
|
projectId,
|
|
137
169
|
...subscribable ? { subscribable } : void 0
|
|
138
170
|
};
|
|
@@ -147,50 +179,49 @@ function createVercelDeploymentTool(ctx) {
|
|
|
147
179
|
// src/webhooks/events.ts
|
|
148
180
|
import { z as z3 } from "zod";
|
|
149
181
|
var deploymentIdSchema = z3.string().regex(/^dpl_[A-Za-z0-9]+$/);
|
|
150
|
-
var commitShaSchema2 = z3.string().regex(/^[0-9a-f]{40}$/i);
|
|
182
|
+
var commitShaSchema2 = z3.string().regex(/^[0-9a-f]{40}$/i).transform((sha) => sha.toLowerCase());
|
|
183
|
+
var deploymentTargetSchema = z3.string().nullable().transform((target) => target ?? "preview").pipe(z3.enum(VERCEL_DEPLOYMENT_TARGETS));
|
|
184
|
+
var metaCommitShaSchema = commitShaSchema2.optional().catch(void 0);
|
|
185
|
+
var deploymentMetaSchema = z3.object({
|
|
186
|
+
githubCommitSha: metaCommitShaSchema,
|
|
187
|
+
gitlabCommitSha: metaCommitShaSchema,
|
|
188
|
+
bitbucketCommitSha: metaCommitShaSchema,
|
|
189
|
+
gitCommitSha: metaCommitShaSchema
|
|
190
|
+
}).transform((meta) => ({
|
|
191
|
+
commitSha: meta.githubCommitSha ?? meta.gitlabCommitSha ?? meta.bitbucketCommitSha ?? meta.gitCommitSha
|
|
192
|
+
}));
|
|
151
193
|
var webhookEnvelopeSchema = z3.object({
|
|
152
194
|
createdAt: z3.number().finite(),
|
|
153
195
|
id: z3.string().min(1),
|
|
154
196
|
payload: z3.unknown(),
|
|
155
|
-
type: z3.
|
|
197
|
+
type: z3.enum(VERCEL_DEPLOYMENT_EVENTS)
|
|
156
198
|
});
|
|
157
199
|
var deploymentPayloadSchema = z3.object({
|
|
158
200
|
deployment: z3.object({
|
|
159
201
|
id: deploymentIdSchema,
|
|
160
|
-
meta:
|
|
202
|
+
meta: deploymentMetaSchema
|
|
161
203
|
}),
|
|
162
204
|
project: z3.object({
|
|
163
205
|
id: vercelProjectIdSchema
|
|
164
206
|
}),
|
|
165
|
-
target:
|
|
207
|
+
target: deploymentTargetSchema
|
|
166
208
|
}).transform((payload) => ({
|
|
167
|
-
commitSha:
|
|
209
|
+
commitSha: payload.deployment.meta.commitSha,
|
|
168
210
|
deploymentId: payload.deployment.id,
|
|
169
211
|
projectId: payload.project.id,
|
|
170
|
-
target:
|
|
212
|
+
target: payload.target
|
|
171
213
|
}));
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
]) {
|
|
184
|
-
const parsed = commitShaSchema2.safeParse(meta[key]);
|
|
185
|
-
if (parsed.success) return parsed.data.toLowerCase();
|
|
186
|
-
}
|
|
187
|
-
return void 0;
|
|
188
|
-
}
|
|
189
|
-
function isDeploymentEvent(value) {
|
|
190
|
-
return VERCEL_DEPLOYMENT_EVENTS.includes(
|
|
191
|
-
value
|
|
192
|
-
);
|
|
193
|
-
}
|
|
214
|
+
var deploymentEventDataSchema = z3.object({
|
|
215
|
+
projectId: vercelProjectIdSchema,
|
|
216
|
+
deploymentId: deploymentIdSchema,
|
|
217
|
+
target: z3.enum(VERCEL_DEPLOYMENT_TARGETS),
|
|
218
|
+
commitSha: commitShaSchema2.optional()
|
|
219
|
+
}).strict();
|
|
220
|
+
var DEPLOYMENT_OUTCOMES = {
|
|
221
|
+
"deployment.succeeded": "succeeded",
|
|
222
|
+
"deployment.error": "failed",
|
|
223
|
+
"deployment.canceled": "was canceled"
|
|
224
|
+
};
|
|
194
225
|
function deploymentTargets(input) {
|
|
195
226
|
const targets = [
|
|
196
227
|
{
|
|
@@ -221,33 +252,29 @@ function deploymentTargets(input) {
|
|
|
221
252
|
}
|
|
222
253
|
function normalizeVercelEvents(args) {
|
|
223
254
|
const envelope = webhookEnvelopeSchema.safeParse(args.body);
|
|
224
|
-
if (!envelope.success
|
|
255
|
+
if (!envelope.success) return [];
|
|
225
256
|
const payload = deploymentPayloadSchema.safeParse(envelope.data.payload);
|
|
226
257
|
if (!payload.success) return [];
|
|
227
|
-
const target = payload.data.target;
|
|
228
|
-
if (!target) return [];
|
|
229
258
|
const eventType = envelope.data.type;
|
|
230
|
-
const deploymentId = payload.data
|
|
231
|
-
const
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
untrustedText
|
|
250
|
-
}));
|
|
259
|
+
const { commitSha, deploymentId, projectId, target } = payload.data;
|
|
260
|
+
const data = deploymentEventDataSchema.parse({
|
|
261
|
+
projectId,
|
|
262
|
+
deploymentId,
|
|
263
|
+
target,
|
|
264
|
+
...commitSha ? { commitSha } : void 0
|
|
265
|
+
});
|
|
266
|
+
return deploymentTargets({ commitSha, projectId, target }).map(
|
|
267
|
+
({ completeOnTerminalEvent, resource }) => ({
|
|
268
|
+
data,
|
|
269
|
+
eventKey: `vercel:${envelope.data.id}:${eventType}`,
|
|
270
|
+
eventType,
|
|
271
|
+
identifier: resource.identifier,
|
|
272
|
+
objectType: "deployment",
|
|
273
|
+
occurredAtMs: envelope.data.createdAt,
|
|
274
|
+
...completeOnTerminalEvent ? { terminal: true } : void 0,
|
|
275
|
+
trustedSummary: `${resource.label} (${deploymentId}) ${DEPLOYMENT_OUTCOMES[eventType]}.`
|
|
276
|
+
})
|
|
277
|
+
);
|
|
251
278
|
}
|
|
252
279
|
|
|
253
280
|
// src/webhooks/handler.ts
|
|
@@ -283,7 +310,7 @@ function createVercelWebhookRoute(args) {
|
|
|
283
310
|
}
|
|
284
311
|
const events = normalizeVercelEvents({ body });
|
|
285
312
|
for (const event of events) {
|
|
286
|
-
await args.events.publish(
|
|
313
|
+
await args.events.publish(event);
|
|
287
314
|
}
|
|
288
315
|
return new Response(events.length ? "Accepted" : "Ignored", {
|
|
289
316
|
status: 202
|
|
@@ -295,6 +322,7 @@ function createVercelWebhookRoute(args) {
|
|
|
295
322
|
export {
|
|
296
323
|
VERCEL_DEPLOYMENT_EVENTS,
|
|
297
324
|
VERCEL_DEPLOYMENT_SUGGESTED_EVENTS,
|
|
325
|
+
VERCEL_DEPLOYMENT_MATCH_FIELDS,
|
|
298
326
|
createVercelDeploymentTool,
|
|
299
327
|
normalizeVercelEvents,
|
|
300
328
|
createVercelWebhookRoute
|
|
@@ -1,7 +1,23 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type SubscribableResource } from "@sentry/junior-plugin-api";
|
|
2
2
|
export declare const VERCEL_DEPLOYMENT_EVENTS: readonly ["deployment.succeeded", "deployment.error", "deployment.canceled"];
|
|
3
3
|
export declare const VERCEL_DEPLOYMENT_SUGGESTED_EVENTS: string[];
|
|
4
|
-
|
|
4
|
+
/** The deployment targets that Vercel webhooks report. */
|
|
5
|
+
export declare const VERCEL_DEPLOYMENT_TARGETS: readonly ["preview", "production", "staging"];
|
|
6
|
+
export type VercelDeploymentTarget = (typeof VERCEL_DEPLOYMENT_TARGETS)[number];
|
|
7
|
+
/**
|
|
8
|
+
* Trusted values that every Vercel deployment event sets. `commitSha` is left
|
|
9
|
+
* out when the deployment has no Git commit, so a filter on it does not match.
|
|
10
|
+
* Vercel ids keep the case that Vercel sends, the same as identifiers,
|
|
11
|
+
* because they are case-sensitive.
|
|
12
|
+
*/
|
|
13
|
+
export declare const VERCEL_DEPLOYMENT_MATCH_FIELDS: Record<string, {
|
|
14
|
+
kind: "boolean" | "number" | "string";
|
|
15
|
+
description: string;
|
|
16
|
+
enum?: string[] | undefined;
|
|
17
|
+
list?: true | undefined;
|
|
18
|
+
case?: "lower" | "upper" | undefined;
|
|
19
|
+
events?: string[] | undefined;
|
|
20
|
+
}>;
|
|
5
21
|
/** Build the stable deployment identity shared by tools and webhooks. */
|
|
6
22
|
export declare function vercelDeploymentResource(input: {
|
|
7
23
|
commitSha?: string;
|
package/dist/index.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
VERCEL_DEPLOYMENT_EVENTS,
|
|
3
|
+
VERCEL_DEPLOYMENT_MATCH_FIELDS,
|
|
3
4
|
VERCEL_DEPLOYMENT_SUGGESTED_EVENTS,
|
|
4
5
|
createVercelDeploymentTool,
|
|
5
6
|
createVercelWebhookRoute
|
|
6
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-5IIQV7WI.js";
|
|
7
8
|
|
|
8
9
|
// src/index.ts
|
|
9
10
|
import {
|
|
@@ -302,9 +303,19 @@ function vercelPlugin() {
|
|
|
302
303
|
{
|
|
303
304
|
type: "deployment",
|
|
304
305
|
supportedEvents: [...VERCEL_DEPLOYMENT_EVENTS],
|
|
305
|
-
suggestedEvents: [...VERCEL_DEPLOYMENT_SUGGESTED_EVENTS]
|
|
306
|
+
suggestedEvents: [...VERCEL_DEPLOYMENT_SUGGESTED_EVENTS],
|
|
307
|
+
matchFields: VERCEL_DEPLOYMENT_MATCH_FIELDS
|
|
306
308
|
}
|
|
307
309
|
],
|
|
310
|
+
// Deployment events carry status facts, and Junior adds nothing to
|
|
311
|
+
// Vercel, so they can run for every project. Use the `projectId`
|
|
312
|
+
// filter to narrow them.
|
|
313
|
+
events: Object.fromEntries(
|
|
314
|
+
VERCEL_DEPLOYMENT_EVENTS.map((eventType) => [
|
|
315
|
+
eventType,
|
|
316
|
+
{ reach: "all" }
|
|
317
|
+
])
|
|
318
|
+
),
|
|
308
319
|
isEnabled: () => Boolean(vercelWebhookSecret())
|
|
309
320
|
},
|
|
310
321
|
manifest: {
|
package/dist/testing.js
CHANGED
|
@@ -5,7 +5,10 @@
|
|
|
5
5
|
* and emits canonical events for project, target, and commit watches.
|
|
6
6
|
*/
|
|
7
7
|
import type { EventInput } from "@sentry/junior-plugin-api";
|
|
8
|
-
/**
|
|
8
|
+
/**
|
|
9
|
+
* Normalize one verified Vercel delivery into deployment events. Target,
|
|
10
|
+
* commit, and deployment id come from Vercel, so they go in trusted data.
|
|
11
|
+
*/
|
|
9
12
|
export declare function normalizeVercelEvents(args: {
|
|
10
13
|
body: unknown;
|
|
11
14
|
}): EventInput[];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sentry/junior-vercel",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.267.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
],
|
|
28
28
|
"dependencies": {
|
|
29
29
|
"zod": "^4.5.4",
|
|
30
|
-
"@sentry/junior-plugin-api": "0.
|
|
30
|
+
"@sentry/junior-plugin-api": "0.267.0"
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|
|
33
33
|
"@oxlint/plugins": "1.79.0",
|
|
@@ -35,7 +35,8 @@
|
|
|
35
35
|
"oxlint": "^1.79.0",
|
|
36
36
|
"tsup": "^8.5.1",
|
|
37
37
|
"typescript": "^7.0.2",
|
|
38
|
-
"vitest": "^4.1.12"
|
|
38
|
+
"vitest": "^4.1.12",
|
|
39
|
+
"@sentry/junior-testing": "0.0.0"
|
|
39
40
|
},
|
|
40
41
|
"scripts": {
|
|
41
42
|
"build": "tsup && tsc -p tsconfig.build.json --emitDeclarationOnly",
|