@sentry/junior 0.9.4 → 0.10.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 +0 -7
- package/dist/{chunk-WM66QDLA.js → chunk-3KBAD3OR.js} +1 -1
- package/dist/{chunk-FS5Y4CF2.js → chunk-LNCWHJH5.js} +18 -35
- package/dist/{chunk-FLP5I4NM.js → chunk-T66A2F7U.js} +285 -591
- package/dist/{chunk-MY7JNCS2.js → chunk-VWHGDGDH.js} +2 -2
- package/dist/cli/check.js +2 -2
- package/dist/cli/init.js +21 -12
- package/dist/cli/snapshot-warmup.js +2 -2
- package/dist/handlers/router.d.ts +2 -4
- package/dist/handlers/router.js +28 -50
- package/dist/handlers/webhooks.d.ts +8 -1
- package/dist/handlers/webhooks.js +8 -7
- package/dist/next-config.js +0 -1
- package/package.json +16 -18
- package/dist/chunk-SO4ORZJR.js +0 -103
- package/dist/chunk-YGERYE7Y.js +0 -685
- package/dist/handlers/queue-callback.d.ts +0 -10
- package/dist/handlers/queue-callback.js +0 -11
|
@@ -95,8 +95,8 @@ var CONSOLE_PREVIEW_KEYS = /* @__PURE__ */ new Set([
|
|
|
95
95
|
function getSentryEnvironment() {
|
|
96
96
|
return (process.env.SENTRY_ENVIRONMENT ?? process.env.NEXT_PUBLIC_SENTRY_ENVIRONMENT ?? process.env.VERCEL_ENV ?? process.env.NODE_ENV ?? "").trim().toLowerCase();
|
|
97
97
|
}
|
|
98
|
-
function shouldSuppressInfoLog(
|
|
99
|
-
return
|
|
98
|
+
function shouldSuppressInfoLog(level) {
|
|
99
|
+
return level === "info";
|
|
100
100
|
}
|
|
101
101
|
function shouldEmitConsole(level) {
|
|
102
102
|
if (process.env.NODE_ENV === "test") {
|
package/dist/cli/check.js
CHANGED
package/dist/cli/init.js
CHANGED
|
@@ -2,19 +2,19 @@
|
|
|
2
2
|
import fs from "fs";
|
|
3
3
|
import path from "path";
|
|
4
4
|
function writeRouteModule(filePath, exportLine) {
|
|
5
|
-
fs.writeFileSync(
|
|
5
|
+
fs.writeFileSync(
|
|
6
|
+
filePath,
|
|
7
|
+
`${exportLine}
|
|
6
8
|
export const runtime = "nodejs";
|
|
7
|
-
`
|
|
9
|
+
`
|
|
10
|
+
);
|
|
8
11
|
}
|
|
9
12
|
function writeWrapperFiles(targetDir) {
|
|
10
13
|
const routeDir = path.join(targetDir, "app", "api", "[...path]");
|
|
11
14
|
fs.mkdirSync(routeDir, { recursive: true });
|
|
12
|
-
writeRouteModule(path.join(routeDir, "route.js"), 'export { GET, POST } from "@sentry/junior/handler";');
|
|
13
|
-
const queueRouteDir = path.join(targetDir, "app", "api", "queue", "callback");
|
|
14
|
-
fs.mkdirSync(queueRouteDir, { recursive: true });
|
|
15
15
|
writeRouteModule(
|
|
16
|
-
path.join(
|
|
17
|
-
'export { POST } from "@sentry/junior/
|
|
16
|
+
path.join(routeDir, "route.js"),
|
|
17
|
+
'export { GET, POST } from "@sentry/junior/handler";'
|
|
18
18
|
);
|
|
19
19
|
fs.mkdirSync(path.join(targetDir, "app"), { recursive: true });
|
|
20
20
|
fs.writeFileSync(
|
|
@@ -66,14 +66,20 @@ async function runInit(dir, log = console.log) {
|
|
|
66
66
|
"@sentry/nextjs": "^10.0.0"
|
|
67
67
|
}
|
|
68
68
|
};
|
|
69
|
-
fs.writeFileSync(
|
|
70
|
-
|
|
69
|
+
fs.writeFileSync(
|
|
70
|
+
path.join(target, "package.json"),
|
|
71
|
+
`${JSON.stringify(pkg, null, 2)}
|
|
72
|
+
`
|
|
73
|
+
);
|
|
71
74
|
const dataDir = path.join(target, "app", "data");
|
|
72
75
|
fs.mkdirSync(dataDir, { recursive: true });
|
|
73
|
-
fs.writeFileSync(
|
|
76
|
+
fs.writeFileSync(
|
|
77
|
+
path.join(dataDir, "SOUL.md"),
|
|
78
|
+
`# ${name}
|
|
74
79
|
|
|
75
80
|
You are ${name}, a helpful assistant.
|
|
76
|
-
`
|
|
81
|
+
`
|
|
82
|
+
);
|
|
77
83
|
fs.writeFileSync(
|
|
78
84
|
path.join(dataDir, "ABOUT.md"),
|
|
79
85
|
`# About ${name}
|
|
@@ -87,7 +93,10 @@ Describe what ${name} helps users do.
|
|
|
87
93
|
const pluginsDir = path.join(target, "app", "plugins");
|
|
88
94
|
fs.mkdirSync(pluginsDir, { recursive: true });
|
|
89
95
|
fs.writeFileSync(path.join(pluginsDir, ".gitkeep"), "");
|
|
90
|
-
fs.writeFileSync(
|
|
96
|
+
fs.writeFileSync(
|
|
97
|
+
path.join(target, ".gitignore"),
|
|
98
|
+
["node_modules/", ".next/", ".env", ".env.local", ""].join("\n")
|
|
99
|
+
);
|
|
91
100
|
fs.writeFileSync(
|
|
92
101
|
path.join(target, ".env.example"),
|
|
93
102
|
[
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
disconnectStateAdapter,
|
|
3
3
|
resolveRuntimeDependencySnapshot
|
|
4
|
-
} from "../chunk-
|
|
4
|
+
} from "../chunk-LNCWHJH5.js";
|
|
5
5
|
import {
|
|
6
6
|
getPluginProviders,
|
|
7
7
|
getPluginRuntimeDependencies,
|
|
8
8
|
getPluginRuntimePostinstall
|
|
9
|
-
} from "../chunk-
|
|
9
|
+
} from "../chunk-VWHGDGDH.js";
|
|
10
10
|
import "../chunk-KCLEEKYX.js";
|
|
11
11
|
|
|
12
12
|
// src/cli/snapshot-warmup.ts
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
export { maxDuration } from './webhooks.js';
|
|
2
|
+
|
|
1
3
|
type RouteContext = {
|
|
2
4
|
params: Promise<unknown>;
|
|
3
5
|
};
|
|
@@ -15,10 +17,6 @@ declare function GET(request: Request, context: RouteContext): Promise<Response>
|
|
|
15
17
|
*
|
|
16
18
|
* Supported routes:
|
|
17
19
|
* - `api/webhooks/:platform`
|
|
18
|
-
* - `api/queue/callback`
|
|
19
|
-
*
|
|
20
|
-
* `queue/callback` is routed here for local/dev parity, but production queue triggers
|
|
21
|
-
* should still target the dedicated `app/api/queue/callback/route.ts` endpoint.
|
|
22
20
|
*/
|
|
23
21
|
declare function POST(request: Request, context: RouteContext): Promise<Response>;
|
|
24
22
|
|
package/dist/handlers/router.js
CHANGED
|
@@ -1,10 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
|
-
POST
|
|
3
|
-
} from "../chunk-SO4ORZJR.js";
|
|
4
|
-
import {
|
|
5
|
-
POST
|
|
6
|
-
} from "../chunk-YGERYE7Y.js";
|
|
7
|
-
import {
|
|
2
|
+
POST,
|
|
8
3
|
buildConversationContext,
|
|
9
4
|
buildSlackOutputMessage,
|
|
10
5
|
coerceThreadArtifactsState,
|
|
@@ -16,14 +11,16 @@ import {
|
|
|
16
11
|
formatProviderLabel,
|
|
17
12
|
generateAssistantReply,
|
|
18
13
|
generateConversationId,
|
|
14
|
+
getPersistedThreadState,
|
|
19
15
|
getSlackClient,
|
|
20
16
|
isRetryableTurnError,
|
|
21
17
|
markConversationMessage,
|
|
22
18
|
markTurnCompleted,
|
|
23
19
|
markTurnFailed,
|
|
20
|
+
maxDuration,
|
|
24
21
|
mergeArtifactsState,
|
|
25
22
|
normalizeConversationText,
|
|
26
|
-
|
|
23
|
+
persistThreadStateById,
|
|
27
24
|
publishAppHomeView,
|
|
28
25
|
resolveBaseUrl,
|
|
29
26
|
resolveReplyDelivery,
|
|
@@ -31,15 +28,15 @@ import {
|
|
|
31
28
|
updateConversationStats,
|
|
32
29
|
uploadFilesToThread,
|
|
33
30
|
upsertConversationMessage
|
|
34
|
-
} from "../chunk-
|
|
35
|
-
import {
|
|
36
|
-
botConfig,
|
|
37
|
-
getStateAdapter
|
|
38
|
-
} from "../chunk-FS5Y4CF2.js";
|
|
31
|
+
} from "../chunk-T66A2F7U.js";
|
|
39
32
|
import {
|
|
40
33
|
GET
|
|
41
34
|
} from "../chunk-4RBEYCOG.js";
|
|
42
|
-
import "../chunk-
|
|
35
|
+
import "../chunk-3KBAD3OR.js";
|
|
36
|
+
import {
|
|
37
|
+
botConfig,
|
|
38
|
+
getStateAdapter
|
|
39
|
+
} from "../chunk-LNCWHJH5.js";
|
|
43
40
|
import {
|
|
44
41
|
buildOAuthTokenRequest,
|
|
45
42
|
getPluginOAuthConfig,
|
|
@@ -47,13 +44,12 @@ import {
|
|
|
47
44
|
logInfo,
|
|
48
45
|
logWarn,
|
|
49
46
|
parseOAuthTokenResponse
|
|
50
|
-
} from "../chunk-
|
|
47
|
+
} from "../chunk-VWHGDGDH.js";
|
|
51
48
|
import "../chunk-KCLEEKYX.js";
|
|
52
49
|
|
|
53
50
|
// src/handlers/mcp-oauth-callback.ts
|
|
54
51
|
import { Buffer } from "buffer";
|
|
55
52
|
import { after } from "next/server";
|
|
56
|
-
import { ThreadImpl } from "chat";
|
|
57
53
|
|
|
58
54
|
// src/handlers/oauth-resume.ts
|
|
59
55
|
function resolveReplyTimeoutMs(explicitTimeoutMs) {
|
|
@@ -328,15 +324,6 @@ async function deliverReplyToThread(channelId, threadTs, reply) {
|
|
|
328
324
|
} catch {
|
|
329
325
|
}
|
|
330
326
|
}
|
|
331
|
-
function createSlackThread(channelId, threadTs) {
|
|
332
|
-
return ThreadImpl.fromJSON({
|
|
333
|
-
_type: "chat:Thread",
|
|
334
|
-
adapterName: "slack",
|
|
335
|
-
channelId,
|
|
336
|
-
id: `slack:${channelId}:${threadTs}`,
|
|
337
|
-
isDM: channelId.startsWith("D")
|
|
338
|
-
});
|
|
339
|
-
}
|
|
340
327
|
function buildDeterministicTurnId(messageId) {
|
|
341
328
|
const sanitized = messageId.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
342
329
|
return `turn_${sanitized}`;
|
|
@@ -354,16 +341,18 @@ function getUserMessageIdForTurn(conversation, sessionId) {
|
|
|
354
341
|
return void 0;
|
|
355
342
|
}
|
|
356
343
|
async function buildResumeConversationContext(channelId, threadTs, sessionId) {
|
|
357
|
-
const
|
|
358
|
-
const conversation = coerceThreadConversationState(
|
|
344
|
+
const threadId = `slack:${channelId}:${threadTs}`;
|
|
345
|
+
const conversation = coerceThreadConversationState(
|
|
346
|
+
await getPersistedThreadState(threadId)
|
|
347
|
+
);
|
|
359
348
|
const userMessageId = getUserMessageIdForTurn(conversation, sessionId);
|
|
360
349
|
return buildConversationContext(conversation, {
|
|
361
350
|
excludeMessageId: userMessageId
|
|
362
351
|
});
|
|
363
352
|
}
|
|
364
353
|
async function persistCompletedReplyState(channelId, threadTs, sessionId, reply) {
|
|
365
|
-
const
|
|
366
|
-
const currentState = await
|
|
354
|
+
const threadId = `slack:${channelId}:${threadTs}`;
|
|
355
|
+
const currentState = await getPersistedThreadState(threadId);
|
|
367
356
|
const conversation = coerceThreadConversationState(currentState);
|
|
368
357
|
const artifacts = coerceThreadArtifactsState(currentState);
|
|
369
358
|
const nextArtifacts = reply.artifactStatePatch ? mergeArtifactsState(artifacts, reply.artifactStatePatch) : void 0;
|
|
@@ -390,7 +379,7 @@ async function persistCompletedReplyState(channelId, threadTs, sessionId, reply)
|
|
|
390
379
|
nowMs: Date.now(),
|
|
391
380
|
updateConversationStats
|
|
392
381
|
});
|
|
393
|
-
await
|
|
382
|
+
await persistThreadStateById(threadId, {
|
|
394
383
|
artifacts: nextArtifacts,
|
|
395
384
|
conversation,
|
|
396
385
|
sandboxId: reply.sandboxId,
|
|
@@ -398,8 +387,8 @@ async function persistCompletedReplyState(channelId, threadTs, sessionId, reply)
|
|
|
398
387
|
});
|
|
399
388
|
}
|
|
400
389
|
async function persistFailedReplyState(channelId, threadTs, sessionId) {
|
|
401
|
-
const
|
|
402
|
-
const currentState = await
|
|
390
|
+
const threadId = `slack:${channelId}:${threadTs}`;
|
|
391
|
+
const currentState = await getPersistedThreadState(threadId);
|
|
403
392
|
const conversation = coerceThreadConversationState(currentState);
|
|
404
393
|
markTurnFailed({
|
|
405
394
|
conversation,
|
|
@@ -408,7 +397,7 @@ async function persistFailedReplyState(channelId, threadTs, sessionId) {
|
|
|
408
397
|
markConversationMessage,
|
|
409
398
|
updateConversationStats
|
|
410
399
|
});
|
|
411
|
-
await
|
|
400
|
+
await persistThreadStateById(threadId, {
|
|
412
401
|
conversation
|
|
413
402
|
});
|
|
414
403
|
}
|
|
@@ -549,7 +538,6 @@ async function GET2(request, context) {
|
|
|
549
538
|
|
|
550
539
|
// src/handlers/oauth-callback.ts
|
|
551
540
|
import { after as after2 } from "next/server";
|
|
552
|
-
import { ThreadImpl as ThreadImpl2 } from "chat";
|
|
553
541
|
function htmlErrorResponse(title, message, status) {
|
|
554
542
|
const safeTitle = escapeXml(title);
|
|
555
543
|
const safeMessage = escapeXml(message);
|
|
@@ -569,18 +557,10 @@ function htmlErrorResponse(title, message, status) {
|
|
|
569
557
|
headers: { "Content-Type": "text/html; charset=utf-8" }
|
|
570
558
|
});
|
|
571
559
|
}
|
|
572
|
-
function createSlackThread2(channelId, threadTs) {
|
|
573
|
-
return ThreadImpl2.fromJSON({
|
|
574
|
-
_type: "chat:Thread",
|
|
575
|
-
adapterName: "slack",
|
|
576
|
-
channelId,
|
|
577
|
-
id: `slack:${channelId}:${threadTs}`,
|
|
578
|
-
isDM: channelId.startsWith("D")
|
|
579
|
-
});
|
|
580
|
-
}
|
|
581
560
|
async function buildResumeConversationContext2(channelId, threadTs) {
|
|
582
|
-
const
|
|
583
|
-
|
|
561
|
+
const conversation = coerceThreadConversationState(
|
|
562
|
+
await getPersistedThreadState(`slack:${channelId}:${threadTs}`)
|
|
563
|
+
);
|
|
584
564
|
const latestUserMessageId = [...conversation.messages].reverse().find((message) => message.role === "user")?.id;
|
|
585
565
|
return buildConversationContext(conversation, {
|
|
586
566
|
excludeMessageId: latestUserMessageId
|
|
@@ -829,15 +809,12 @@ async function GET4(request, context) {
|
|
|
829
809
|
}
|
|
830
810
|
return new Response("Not Found", { status: 404 });
|
|
831
811
|
}
|
|
832
|
-
async function
|
|
812
|
+
async function POST2(request, context) {
|
|
833
813
|
const route = normalizeRoutePath(getRoutePathParts(await context.params));
|
|
834
|
-
if (route === "queue/callback") {
|
|
835
|
-
return POST(request);
|
|
836
|
-
}
|
|
837
814
|
const webhookMatch = route.match(/^webhooks\/([^/]+)$/);
|
|
838
815
|
if (webhookMatch) {
|
|
839
816
|
const platform = webhookMatch[1];
|
|
840
|
-
return
|
|
817
|
+
return POST(request, {
|
|
841
818
|
params: Promise.resolve({ platform })
|
|
842
819
|
});
|
|
843
820
|
}
|
|
@@ -845,5 +822,6 @@ async function POST3(request, context) {
|
|
|
845
822
|
}
|
|
846
823
|
export {
|
|
847
824
|
GET4 as GET,
|
|
848
|
-
|
|
825
|
+
POST2 as POST,
|
|
826
|
+
maxDuration
|
|
849
827
|
};
|
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vercel function timeout in seconds.
|
|
3
|
+
*
|
|
4
|
+
* Agent turns run inside `after()` which shares the function's timeout budget.
|
|
5
|
+
* This must be at least as large as the configured turn timeout plus buffer.
|
|
6
|
+
*/
|
|
7
|
+
declare const maxDuration: number;
|
|
1
8
|
/**
|
|
2
9
|
* Webhook route contract for `@sentry/junior`.
|
|
3
10
|
*
|
|
@@ -18,4 +25,4 @@ type WebhookRouteContext = {
|
|
|
18
25
|
*/
|
|
19
26
|
declare function POST(request: Request, context: WebhookRouteContext): Promise<Response>;
|
|
20
27
|
|
|
21
|
-
export { POST };
|
|
28
|
+
export { POST, maxDuration };
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
|
-
POST
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
import "../chunk-
|
|
6
|
-
import "../chunk-
|
|
7
|
-
import "../chunk-
|
|
2
|
+
POST,
|
|
3
|
+
maxDuration
|
|
4
|
+
} from "../chunk-T66A2F7U.js";
|
|
5
|
+
import "../chunk-3KBAD3OR.js";
|
|
6
|
+
import "../chunk-LNCWHJH5.js";
|
|
7
|
+
import "../chunk-VWHGDGDH.js";
|
|
8
8
|
import "../chunk-KCLEEKYX.js";
|
|
9
9
|
export {
|
|
10
|
-
POST
|
|
10
|
+
POST,
|
|
11
|
+
maxDuration
|
|
11
12
|
};
|
package/dist/next-config.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sentry/junior",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.1",
|
|
4
4
|
"private": false,
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -12,7 +12,6 @@
|
|
|
12
12
|
"exports": {
|
|
13
13
|
"./handler": "./dist/handlers/router.js",
|
|
14
14
|
"./handlers/webhooks": "./dist/handlers/webhooks.js",
|
|
15
|
-
"./handlers/queue-callback": "./dist/handlers/queue-callback.js",
|
|
16
15
|
"./handlers/health": "./dist/handlers/health.js",
|
|
17
16
|
"./config": "./dist/next-config.js",
|
|
18
17
|
"./instrumentation": "./dist/instrumentation.js",
|
|
@@ -23,23 +22,22 @@
|
|
|
23
22
|
"bin"
|
|
24
23
|
],
|
|
25
24
|
"dependencies": {
|
|
26
|
-
"@ai-sdk/gateway": "^3.0.
|
|
27
|
-
"@chat-adapter/slack": "4.
|
|
28
|
-
"@chat-adapter/state-memory": "4.
|
|
29
|
-
"@chat-adapter/state-redis": "4.
|
|
25
|
+
"@ai-sdk/gateway": "^3.0.83",
|
|
26
|
+
"@chat-adapter/slack": "4.22.0",
|
|
27
|
+
"@chat-adapter/state-memory": "4.22.0",
|
|
28
|
+
"@chat-adapter/state-redis": "4.22.0",
|
|
30
29
|
"@mariozechner/pi-agent-core": "^0.59.0",
|
|
31
30
|
"@mariozechner/pi-ai": "^0.59.0",
|
|
32
31
|
"@modelcontextprotocol/sdk": "1.27.1",
|
|
33
32
|
"@sinclair/typebox": "^0.34.48",
|
|
34
33
|
"@slack/web-api": "^7.15.0",
|
|
35
|
-
"@vercel/
|
|
36
|
-
"
|
|
37
|
-
"ai": "^6.0.116",
|
|
34
|
+
"@vercel/sandbox": "^1.9.0",
|
|
35
|
+
"ai": "^6.0.141",
|
|
38
36
|
"bash-tool": "^1.3.15",
|
|
39
|
-
"chat": "4.
|
|
40
|
-
"just-bash": "^2.
|
|
37
|
+
"chat": "4.22.0",
|
|
38
|
+
"just-bash": "^2.14.0",
|
|
41
39
|
"node-html-markdown": "^2.0.0",
|
|
42
|
-
"yaml": "^2.8.
|
|
40
|
+
"yaml": "^2.8.3",
|
|
43
41
|
"zod": "^4.3.6"
|
|
44
42
|
},
|
|
45
43
|
"peerDependencies": {
|
|
@@ -49,18 +47,18 @@
|
|
|
49
47
|
"react-dom": ">=19.0.0"
|
|
50
48
|
},
|
|
51
49
|
"devDependencies": {
|
|
52
|
-
"@sentry/nextjs": "^10.
|
|
53
|
-
"@types/node": "^25.
|
|
50
|
+
"@sentry/nextjs": "^10.46.0",
|
|
51
|
+
"@types/node": "^25.5.0",
|
|
54
52
|
"@types/react": "^19.2.14",
|
|
55
53
|
"@types/react-dom": "^19.2.3",
|
|
56
|
-
"msw": "^2.12.
|
|
57
|
-
"next": "^16.1
|
|
54
|
+
"msw": "^2.12.14",
|
|
55
|
+
"next": "^16.2.1",
|
|
58
56
|
"react": "^19.2.4",
|
|
59
57
|
"react-dom": "^19.2.4",
|
|
60
58
|
"tsup": "^8.5.1",
|
|
61
59
|
"typescript": "^5.9.3",
|
|
62
|
-
"vercel": "^50.
|
|
63
|
-
"vitest": "^4.1.
|
|
60
|
+
"vercel": "^50.37.2",
|
|
61
|
+
"vitest": "^4.1.2"
|
|
64
62
|
},
|
|
65
63
|
"scripts": {
|
|
66
64
|
"build": "tsup",
|
package/dist/chunk-SO4ORZJR.js
DELETED
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
getProductionBot
|
|
3
|
-
} from "./chunk-FLP5I4NM.js";
|
|
4
|
-
import {
|
|
5
|
-
createRequestContext,
|
|
6
|
-
logException,
|
|
7
|
-
logWarn,
|
|
8
|
-
setSpanAttributes,
|
|
9
|
-
setSpanStatus,
|
|
10
|
-
withContext,
|
|
11
|
-
withSpan
|
|
12
|
-
} from "./chunk-MY7JNCS2.js";
|
|
13
|
-
|
|
14
|
-
// src/handlers/webhooks.ts
|
|
15
|
-
import { after } from "next/server";
|
|
16
|
-
import * as Sentry from "@sentry/nextjs";
|
|
17
|
-
async function POST(request, context) {
|
|
18
|
-
const bot = getProductionBot();
|
|
19
|
-
const { platform } = await context.params;
|
|
20
|
-
const handler = bot.webhooks[platform];
|
|
21
|
-
const requestContext = createRequestContext(request, { platform });
|
|
22
|
-
const requestUrl = new URL(request.url);
|
|
23
|
-
return withContext(requestContext, async () => {
|
|
24
|
-
if (!handler) {
|
|
25
|
-
const error = new Error(`Unknown platform: ${platform}`);
|
|
26
|
-
logException(
|
|
27
|
-
error,
|
|
28
|
-
"webhook_platform_unknown",
|
|
29
|
-
{},
|
|
30
|
-
{
|
|
31
|
-
"http.response.status_code": 404
|
|
32
|
-
},
|
|
33
|
-
`Unknown platform: ${platform}`
|
|
34
|
-
);
|
|
35
|
-
return new Response(`Unknown platform: ${platform}`, { status: 404 });
|
|
36
|
-
}
|
|
37
|
-
try {
|
|
38
|
-
return await withSpan(
|
|
39
|
-
"http.server.request",
|
|
40
|
-
"http.server",
|
|
41
|
-
requestContext,
|
|
42
|
-
async () => {
|
|
43
|
-
try {
|
|
44
|
-
const activeSpan = Sentry.getActiveSpan();
|
|
45
|
-
const response = await handler(request, {
|
|
46
|
-
waitUntil: (task) => after(() => {
|
|
47
|
-
const runTask = () => {
|
|
48
|
-
const taskOrFactory = task;
|
|
49
|
-
return typeof taskOrFactory === "function" ? taskOrFactory() : taskOrFactory;
|
|
50
|
-
};
|
|
51
|
-
if (activeSpan) {
|
|
52
|
-
return Sentry.withActiveSpan(activeSpan, runTask);
|
|
53
|
-
}
|
|
54
|
-
return runTask();
|
|
55
|
-
})
|
|
56
|
-
});
|
|
57
|
-
if (response.status >= 400) {
|
|
58
|
-
let responseBodySnippet;
|
|
59
|
-
try {
|
|
60
|
-
responseBodySnippet = (await response.clone().text()).slice(
|
|
61
|
-
0,
|
|
62
|
-
300
|
|
63
|
-
);
|
|
64
|
-
} catch {
|
|
65
|
-
responseBodySnippet = void 0;
|
|
66
|
-
}
|
|
67
|
-
logWarn(
|
|
68
|
-
"webhook_non_success_response",
|
|
69
|
-
{},
|
|
70
|
-
{
|
|
71
|
-
"http.response.status_code": response.status,
|
|
72
|
-
"http.request.header.x_slack_signature": request.headers.get("x-slack-signature") ?? void 0,
|
|
73
|
-
"http.request.header.x_slack_request_timestamp": request.headers.get("x-slack-request-timestamp") ?? void 0,
|
|
74
|
-
...responseBodySnippet ? { "app.webhook.response_body": responseBodySnippet } : {}
|
|
75
|
-
},
|
|
76
|
-
`Webhook ${platform} returned ${response.status}`
|
|
77
|
-
);
|
|
78
|
-
}
|
|
79
|
-
setSpanAttributes({
|
|
80
|
-
"http.response.status_code": response.status
|
|
81
|
-
});
|
|
82
|
-
setSpanStatus(response.status >= 500 ? "error" : "ok");
|
|
83
|
-
return response;
|
|
84
|
-
} catch (error) {
|
|
85
|
-
setSpanStatus("error");
|
|
86
|
-
throw error;
|
|
87
|
-
}
|
|
88
|
-
},
|
|
89
|
-
{
|
|
90
|
-
"http.request.method": request.method,
|
|
91
|
-
"url.path": requestUrl.pathname
|
|
92
|
-
}
|
|
93
|
-
);
|
|
94
|
-
} catch (error) {
|
|
95
|
-
logException(error, "webhook_handler_failed");
|
|
96
|
-
throw error;
|
|
97
|
-
}
|
|
98
|
-
});
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
export {
|
|
102
|
-
POST
|
|
103
|
-
};
|