First upload version 0.0.1

This commit is contained in:
Neyra
2026-02-05 15:27:49 +08:00
commit 8e9b7201ed
4182 changed files with 593136 additions and 0 deletions

View File

@@ -0,0 +1,147 @@
import { normalizeTrailingSlashes } from "../normalize-trailing-slashes.js";
const isApplicationJsonRE = /^\s*(application\/json)\s*(?:;|$)/u;
const WEBHOOK_HEADERS = [
"x-github-event",
"x-hub-signature-256",
"x-github-delivery"
];
function createMiddleware(options) {
const { handleResponse, getRequestHeader, getPayload } = options;
return function middleware(webhooks, options2) {
const middlewarePath = normalizeTrailingSlashes(options2.path);
return async function octokitWebhooksMiddleware(request, response, next) {
let pathname;
try {
pathname = new URL(
normalizeTrailingSlashes(request.url),
"http://localhost"
).pathname;
} catch (error) {
return handleResponse(
JSON.stringify({
error: `Request URL could not be parsed: ${request.url}`
}),
422,
{
"content-type": "application/json"
},
response
);
}
if (pathname !== middlewarePath) {
next?.();
return handleResponse(null);
} else if (request.method !== "POST") {
return handleResponse(
JSON.stringify({
error: `Unknown route: ${request.method} ${pathname}`
}),
404,
{
"content-type": "application/json"
},
response
);
}
const contentType = getRequestHeader(request, "content-type");
if (typeof contentType !== "string" || !isApplicationJsonRE.test(contentType)) {
return handleResponse(
JSON.stringify({
error: `Unsupported "Content-Type" header value. Must be "application/json"`
}),
415,
{
"content-type": "application/json",
accept: "application/json"
},
response
);
}
const missingHeaders = WEBHOOK_HEADERS.filter((header) => {
return getRequestHeader(request, header) == void 0;
}).join(", ");
if (missingHeaders) {
return handleResponse(
JSON.stringify({
error: `Required headers missing: ${missingHeaders}`
}),
400,
{
"content-type": "application/json",
accept: "application/json"
},
response
);
}
const eventName = getRequestHeader(
request,
"x-github-event"
);
const signature = getRequestHeader(request, "x-hub-signature-256");
const id = getRequestHeader(request, "x-github-delivery");
options2.log.debug(`${eventName} event received (id: ${id})`);
let didTimeout = false;
let timeout;
const timeoutPromise = new Promise((resolve) => {
timeout = setTimeout(() => {
didTimeout = true;
resolve(
handleResponse(
"still processing\n",
202,
{
"Content-Type": "text/plain",
accept: "application/json"
},
response
)
);
}, options2.timeout);
});
const processWebhook = async () => {
try {
const payload = await getPayload(request);
await webhooks.verifyAndReceive({
id,
name: eventName,
payload,
signature
});
clearTimeout(timeout);
if (didTimeout) return handleResponse(null);
return handleResponse(
"ok\n",
200,
{
"content-type": "text/plain",
accept: "application/json"
},
response
);
} catch (error) {
clearTimeout(timeout);
if (didTimeout) return handleResponse(null);
const err = Array.from(error.errors)[0];
const errorMessage = err.message ? `${err.name}: ${err.message}` : "Error: An Unspecified error occurred";
const statusCode = typeof err.status !== "undefined" ? err.status : 500;
options2.log.error(error);
return handleResponse(
JSON.stringify({
error: errorMessage
}),
statusCode,
{
"content-type": "application/json",
accept: "application/json"
},
response
);
}
};
return await Promise.race([timeoutPromise, processWebhook()]);
};
};
}
export {
createMiddleware
};

View File

@@ -0,0 +1,30 @@
import { concatUint8Array } from "../../concat-uint8array.js";
const textDecoder = new TextDecoder("utf-8", { fatal: false });
const decode = textDecoder.decode.bind(textDecoder);
async function getPayload(request) {
if (typeof request.body === "object" && "rawBody" in request && request.rawBody instanceof Uint8Array) {
return decode(request.rawBody);
} else if (typeof request.body === "string") {
return request.body;
}
const payload = await getPayloadFromRequestStream(request);
return decode(payload);
}
function getPayloadFromRequestStream(request) {
return new Promise((resolve, reject) => {
let data = [];
request.on(
"error",
(error) => reject(new AggregateError([error], error.message))
);
request.on("data", data.push.bind(data));
request.on("end", () => {
const result = concatUint8Array(data);
queueMicrotask(() => resolve(result));
});
});
}
export {
getPayload,
getPayloadFromRequestStream
};

View File

@@ -0,0 +1,6 @@
function getRequestHeader(request, key) {
return request.headers[key];
}
export {
getRequestHeader
};

View File

@@ -0,0 +1,11 @@
function handleResponse(body, status = 200, headers = {}, response) {
if (body === null) {
return false;
}
headers["content-length"] = body.length.toString();
response.writeHead(status, headers).end(body);
return true;
}
export {
handleResponse
};

View File

@@ -0,0 +1,23 @@
import { createLogger } from "../../create-logger.js";
import { createMiddleware } from "../create-middleware.js";
import { handleResponse } from "./handle-response.js";
import { getRequestHeader } from "./get-request-header.js";
import { getPayload } from "./get-payload.js";
function createNodeMiddleware(webhooks, {
path = "/api/github/webhooks",
log = createLogger(),
timeout = 9e3
} = {}) {
return createMiddleware({
handleResponse,
getRequestHeader,
getPayload
})(webhooks, {
path,
log,
timeout
});
}
export {
createNodeMiddleware
};

View File

@@ -0,0 +1,6 @@
function getPayload(request) {
return request.text();
}
export {
getPayload
};

View File

@@ -0,0 +1,6 @@
function getRequestHeader(request, key) {
return request.headers.get(key);
}
export {
getRequestHeader
};

View File

@@ -0,0 +1,12 @@
function handleResponse(body, status = 200, headers = {}) {
if (body !== null) {
headers["content-length"] = body.length.toString();
}
return new Response(body, {
status,
headers
});
}
export {
handleResponse
};

View File

@@ -0,0 +1,23 @@
import { createLogger } from "../../create-logger.js";
import { createMiddleware } from "../create-middleware.js";
import { getPayload } from "./get-payload.js";
import { getRequestHeader } from "./get-request-header.js";
import { handleResponse } from "./handle-response.js";
function createWebMiddleware(webhooks, {
path = "/api/github/webhooks",
log = createLogger(),
timeout = 9e3
} = {}) {
return createMiddleware({
handleResponse,
getRequestHeader,
getPayload
})(webhooks, {
path,
log,
timeout
});
}
export {
createWebMiddleware
};