@zhin.js/adapter-github 1.1.25 β†’ 1.1.27

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/src/protocol.ts CHANGED
@@ -5,7 +5,6 @@ import type { EndpointProfileConfiguration } from 'zhin.js/adapter';
5
5
  */
6
6
 
7
7
  import { createHmac, timingSafeEqual } from 'node:crypto';
8
- import type { IncomingMessage } from 'node:http';
9
8
  import { isMediaRef, type ConversationRef } from '@zhin.js/im-contract';
10
9
  import { formatCompact, getLogger } from '@zhin.js/logger';
11
10
 
@@ -242,32 +241,12 @@ export function verifyWebhookSignature(
242
241
  }
243
242
 
244
243
  export function headerValue(
245
- headers: IncomingMessage['headers'],
244
+ headers: Headers,
246
245
  name: string,
247
246
  ): string {
248
- const raw = headers[name] ?? headers[name.toLowerCase()];
249
- if (Array.isArray(raw)) return raw[0] ?? '';
250
- return raw ?? '';
247
+ return headers.get(name) ?? '';
251
248
  }
252
249
 
253
- export async function readTextBody(
254
- request: IncomingMessage,
255
- options: { readonly limit?: number } = {},
256
- ): Promise<string> {
257
- const limit = options.limit ?? 1_048_576;
258
- const chunks: Buffer[] = [];
259
- let size = 0;
260
- for await (const chunk of request) {
261
- const buffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
262
- size += buffer.length;
263
- if (size > limit) {
264
- request.destroy();
265
- throw new Error(`Request body exceeds ${limit} bytes`);
266
- }
267
- chunks.push(buffer);
268
- }
269
- return Buffer.concat(chunks).toString('utf8');
270
- }
271
250
 
272
251
  export function parseIssueCommentInbound(payload: IssueCommentPayload): GithubInboundComment | null {
273
252
  if (payload.action !== 'created' || !payload.comment) return null;
@@ -366,8 +345,3 @@ export function formatNotification(event: string, p: GenericWebhookPayload): str
366
345
  return `πŸ“¬ ${repo}\nπŸ“‘ ${event}${p.action ? ` (${p.action})` : ''} by ${sender}\nπŸ”— ${repoUrl}`;
367
346
  }
368
347
  }
369
-
370
- /** Parse @mentions in markdown into a flat display string (gateway text path). */
371
- export function parseMarkdownMentions(md: string): string {
372
- return md;
373
- }
package/src/webhook.ts CHANGED
@@ -1,15 +1,14 @@
1
1
  /**
2
2
  * GitHub webhook HTTP: verify β†’ parse β†’ admit inbound comments.
3
3
  */
4
- import type { IncomingMessage, ServerResponse } from 'node:http';
5
4
  import type { HttpHost, HttpRouteRegistration } from '@zhin.js/host-http';
5
+ import { readTextBody } from '@zhin.js/host-http-contract';
6
6
  import { formatCompact, getLogger } from '@zhin.js/logger';
7
7
  import {
8
8
  headerValue,
9
9
  parseIssueCommentInbound,
10
10
  parsePrReviewCommentInbound,
11
11
  parsePrReviewInbound,
12
- readTextBody,
13
12
  verifyWebhookSignature,
14
13
  type GithubInboundComment,
15
14
  type IssueCommentPayload,
@@ -32,22 +31,17 @@ export function registerGithubWebhookRoutes(
32
31
  ): HttpRouteRegistration[] {
33
32
  const routePath = handler.config.webhookPath;
34
33
  return [
35
- http.route('POST', routePath, async (request, response) => {
36
- await handleGithubWebhookRequest(request, response, handler);
37
- }, { summary: 'GitHub webhook', tags: ['github'] }),
34
+ http.route('POST', routePath, (request) => handleGithubWebhookRequest(request, handler), { summary: 'GitHub webhook', tags: ['github'] }),
38
35
  ];
39
36
  }
40
37
 
41
38
  export async function handleGithubWebhookRequest(
42
- request: IncomingMessage,
43
- response: ServerResponse,
39
+ request: Request,
44
40
  handler: GithubWebhookHandler,
45
- ): Promise<void> {
41
+ ): Promise<Response> {
46
42
  const secret = handler.config.webhookSecret;
47
43
  if (!secret) {
48
- response.writeHead(503, { 'Content-Type': 'application/json' });
49
- response.end(JSON.stringify({ error: 'Webhook not configured' }));
50
- return;
44
+ return new Response(JSON.stringify({ error: 'Webhook not configured' }), { status: 503, headers: { 'Content-Type': 'application/json' } });
51
45
  }
52
46
 
53
47
  const signature = headerValue(request.headers, 'x-hub-signature-256');
@@ -55,9 +49,7 @@ export async function handleGithubWebhookRequest(
55
49
  const deliveryId = headerValue(request.headers, 'x-github-delivery');
56
50
 
57
51
  if (!signature || !event) {
58
- response.writeHead(400, { 'Content-Type': 'application/json' });
59
- response.end(JSON.stringify({ error: 'Missing signature or event header' }));
60
- return;
52
+ return new Response(JSON.stringify({ error: 'Missing signature or event header' }), { status: 400, headers: { 'Content-Type': 'application/json' } });
61
53
  }
62
54
 
63
55
  try {
@@ -69,32 +61,23 @@ export async function handleGithubWebhookRequest(
69
61
  error: 'invalid signature',
70
62
  delivery: deliveryId,
71
63
  }));
72
- response.writeHead(401, { 'Content-Type': 'application/json' });
73
- response.end(JSON.stringify({ error: 'Invalid signature' }));
74
- return;
64
+ return new Response(JSON.stringify({ error: 'Invalid signature' }), { status: 401, headers: { 'Content-Type': 'application/json' } });
75
65
  }
76
66
 
77
67
  let payload: unknown;
78
68
  try {
79
69
  payload = rawBody ? JSON.parse(rawBody) : {};
80
70
  } catch {
81
- response.writeHead(400, { 'Content-Type': 'application/json' });
82
- response.end(JSON.stringify({ error: 'Invalid JSON' }));
83
- return;
71
+ return new Response(JSON.stringify({ error: 'Invalid JSON' }), { status: 400, headers: { 'Content-Type': 'application/json' } });
84
72
  }
85
73
 
86
- response.writeHead(200, { 'Content-Type': 'application/json' });
87
- response.end(JSON.stringify({ ok: true }));
88
-
89
74
  void dispatchGithubWebhookPayload(event, payload, handler).catch((e) => {
90
75
  logger.error(`Webhook 事仢倄理倱θ΄₯ (${event}):`, e);
91
76
  });
77
+ return new Response(JSON.stringify({ ok: true }), { status: 200, headers: { 'Content-Type': 'application/json' } });
92
78
  } catch (error) {
93
79
  logger.error('Webhook error:', error);
94
- if (!response.headersSent) {
95
- response.writeHead(500, { 'Content-Type': 'application/json' });
96
- response.end(JSON.stringify({ error: 'Internal Server Error' }));
97
- }
80
+ return new Response(JSON.stringify({ error: 'Internal Server Error' }), { status: 500, headers: { 'Content-Type': 'application/json' } });
98
81
  }
99
82
  }
100
83