From 4fd0a7667e71c165fffa7c3d99fbece592aaaaed Mon Sep 17 00:00:00 2001 From: Baoshan Sheng Date: Sun, 11 Sep 2022 04:51:35 +0800 Subject: [PATCH 1/5] fix: return 404 for unknown routes (#341) BREAKING CHANGE: drop `onUnhandledRequest` middleware option --- README.md | 75 --------------- src/index.ts | 18 +++- src/middleware/README.md | 4 +- src/middleware/aws-lambda/api-gateway-v2.ts | 32 ++----- src/middleware/handle-request.ts | 30 +++--- src/middleware/node/index.ts | 41 ++------ ...t-default.ts => unknown-route-response.ts} | 6 +- src/middleware/web-worker/index.ts | 46 ++------- test/aws-lambda-api-gateway-v2.test.ts | 34 +++++-- test/deprecations.test.ts | 40 +------- test/node-middleware.test.ts | 93 +++++++++---------- test/smoke.test.ts | 19 +++- test/web-worker-handler.test.ts | 76 +++++++-------- 13 files changed, 181 insertions(+), 333 deletions(-) rename src/middleware/{on-unhandled-request-default.ts => unknown-route-response.ts} (55%) diff --git a/README.md b/README.md index c3898ed7d..fb61b8f32 100644 --- a/README.md +++ b/README.md @@ -937,31 +937,6 @@ All exposed paths will be prefixed with the provided prefix. Defaults to `"/api/ - - - options.onUnhandledRequest - - - function - - - -Defaults to - -```js -function onUnhandledRequest(request, response) { - response.writeHead(404, { - "content-type": "application/json", - }); - response.end( - JSON.stringify({ - error: `Unknown route: ${request.method} ${request.url}`, - }) - ); -} -``` - - @@ -1025,31 +1000,6 @@ addEventListener("fetch", (event) => { All exposed paths will be prefixed with the provided prefix. Defaults to `"/api/github/oauth"` - - - - - options.onUnhandledRequest - - - function - - Defaults to - -```js -function onUnhandledRequest(request) { - return new Response( - JSON.stringify({ - error: `Unknown route: ${request.method} ${request.url}`, - }), - { - status: 404, - headers: { "content-type": "application/json" }, - } - ); -} -``` - @@ -1115,31 +1065,6 @@ export const handler = createAWSLambdaAPIGatewayV2Handler(app, { All exposed paths will be prefixed with the provided prefix. Defaults to `"/api/github/oauth"` - - - - - options.onUnhandledRequest - - - function - - Defaults to returns: - -```js -function onUnhandledRequest(request) { - return - { - status: 404, - headers: { "content-type": "application/json" }, - body: JSON.stringify({ - error: `Unknown route: [METHOD] [URL]`, - }) - } - ); -} -``` - diff --git a/src/index.ts b/src/index.ts index a129bb2ba..b38eb0bea 100644 --- a/src/index.ts +++ b/src/index.ts @@ -50,11 +50,21 @@ import type { Options, State, } from "./types"; + +// types required by external handlers (aws-lambda, etc) +export type { + HandlerOptions, + OctokitRequest, + OctokitResponse, +} from "./middleware/types"; + +// generic handlers +export { handleRequest } from "./middleware/handle-request"; +export { unknownRouteResponse } from "./middleware/unknown-route-response"; + export { createNodeMiddleware } from "./middleware/node/index"; -export { - createCloudflareHandler, - createWebWorkerHandler, -} from "./middleware/web-worker/index"; +export { sendResponse as sendNodeResponse } from "./middleware/node/send-response"; +export { createWebWorkerHandler } from "./middleware/web-worker/index"; export { createAWSLambdaAPIGatewayV2Handler } from "./middleware/aws-lambda/api-gateway-v2"; type Constructor = new (...args: any[]) => T; diff --git a/src/middleware/README.md b/src/middleware/README.md index d08c0ba08..5f148e838 100644 --- a/src/middleware/README.md +++ b/src/middleware/README.md @@ -7,11 +7,9 @@ The `middleware` directory contains the generic HTTP handler. Each sub-directory ``` middleware ├── handle-request.ts -├── on-unhandled-request-default.ts ├── types.ts ├── node/ ├── web-worker/ (Cloudflare Workers & Deno) -└── deno/ (to be implemented) ``` ## Generic HTTP Handler @@ -85,5 +83,5 @@ Implementing an HTTP handler/middleware for a certain environment involves three 2. Write a function to render an `OctokitResponse` object (e.g., as `ServerResponse` in Node.js). See [`node/send-response.ts`](node/send-response.ts) for reference. 3. Expose an HTTP handler/middleware in the dialect of the environment which performs three steps: 1. Parse the HTTP request using (1). - 2. Process the `OctokitRequest` object using `handleRequest`. If the request is not handled by `handleRequest` (the request does not match any predefined route), [`onUnhandledRequestDefault`](on-unhandled-request-default.ts) can be used to generate a `404` response consistently. + 2. Process the `OctokitRequest` object using `handleRequest`. 3. Render the `OctokitResponse` object using (2). diff --git a/src/middleware/aws-lambda/api-gateway-v2.ts b/src/middleware/aws-lambda/api-gateway-v2.ts index 873c9ae05..d2a9a0844 100644 --- a/src/middleware/aws-lambda/api-gateway-v2.ts +++ b/src/middleware/aws-lambda/api-gateway-v2.ts @@ -1,37 +1,23 @@ import { parseRequest } from "./api-gateway-v2-parse-request"; import { sendResponse } from "./api-gateway-v2-send-response"; import { handleRequest } from "../handle-request"; -import { onUnhandledRequestDefault } from "../on-unhandled-request-default"; -import { HandlerOptions } from "../types"; -import { OAuthApp } from "../../index"; -import { Options, ClientType } from "../../types"; +import type { HandlerOptions } from "../types"; +import type { OAuthApp } from "../../index"; +import type { ClientType, Options } from "../../types"; import type { APIGatewayProxyEventV2, APIGatewayProxyStructuredResultV2, } from "aws-lambda"; -async function onUnhandledRequestDefaultAWSAPIGatewayV2( - event: APIGatewayProxyEventV2 -): Promise { - const request = parseRequest(event); - const response = onUnhandledRequestDefault(request); - return sendResponse(response); -} - export function createAWSLambdaAPIGatewayV2Handler( app: OAuthApp>, - { - pathPrefix, - onUnhandledRequest = onUnhandledRequestDefaultAWSAPIGatewayV2, - }: HandlerOptions & { - onUnhandledRequest?: ( - event: APIGatewayProxyEventV2 - ) => Promise; - } = {} + options: HandlerOptions = {} ) { - return async function (event: APIGatewayProxyEventV2) { + return async function ( + event: APIGatewayProxyEventV2 + ): Promise { const request = parseRequest(event); - const response = await handleRequest(app, { pathPrefix }, request); - return response ? sendResponse(response) : onUnhandledRequest(event); + const response = await handleRequest(app, options, request); + return response ? sendResponse(response) : undefined; }; } diff --git a/src/middleware/handle-request.ts b/src/middleware/handle-request.ts index 87ac5b9ad..3b4b9c1aa 100644 --- a/src/middleware/handle-request.ts +++ b/src/middleware/handle-request.ts @@ -1,4 +1,5 @@ import { OAuthApp } from "../index"; +import { unknownRouteResponse } from "./unknown-route-response"; import { HandlerOptions, OctokitRequest, OctokitResponse } from "./types"; import { ClientType, Options } from "../types"; // @ts-ignore - requires esModuleInterop flag @@ -8,7 +9,7 @@ export async function handleRequest( app: OAuthApp>, { pathPrefix = "/api/github/oauth" }: HandlerOptions, request: OctokitRequest -): Promise { +): Promise { if (request.method === "OPTIONS") { return { status: 200, @@ -23,23 +24,28 @@ export async function handleRequest( // request.url may include ?query parameters which we don't want for `route` // hence the workaround using new URL() - const { pathname } = new URL(request.url as string, "http://localhost"); + let { pathname } = new URL(request.url as string, "http://localhost"); + if (!pathname.startsWith(`${pathPrefix}/`)) { + return undefined; + } + pathname = pathname.slice(pathPrefix.length + 1); + const route = [request.method, pathname].join(" "); const routes = { - getLogin: `GET ${pathPrefix}/login`, - getCallback: `GET ${pathPrefix}/callback`, - createToken: `POST ${pathPrefix}/token`, - getToken: `GET ${pathPrefix}/token`, - patchToken: `PATCH ${pathPrefix}/token`, - patchRefreshToken: `PATCH ${pathPrefix}/refresh-token`, - scopeToken: `POST ${pathPrefix}/token/scoped`, - deleteToken: `DELETE ${pathPrefix}/token`, - deleteGrant: `DELETE ${pathPrefix}/grant`, + getLogin: `GET login`, + getCallback: `GET callback`, + createToken: `POST token`, + getToken: `GET token`, + patchToken: `PATCH token`, + patchRefreshToken: `PATCH refresh-token`, + scopeToken: `POST token/scoped`, + deleteToken: `DELETE token`, + deleteGrant: `DELETE grant`, }; // handle unknown routes if (!Object.values(routes).includes(route)) { - return null; + return unknownRouteResponse(request); } let json: any; diff --git a/src/middleware/node/index.ts b/src/middleware/node/index.ts index 9bc05f71f..efd86532a 100644 --- a/src/middleware/node/index.ts +++ b/src/middleware/node/index.ts @@ -6,51 +6,28 @@ type ServerResponse = any; import { parseRequest } from "./parse-request"; import { sendResponse } from "./send-response"; -import { onUnhandledRequestDefault } from "../on-unhandled-request-default"; import { handleRequest } from "../handle-request"; -import { OAuthApp } from "../../index"; -import { HandlerOptions } from "../types"; -import { ClientType, Options } from "../../types"; - -function onUnhandledRequestDefaultNode( - request: IncomingMessage, - response: ServerResponse -) { - const octokitRequest = parseRequest(request); - const octokitResponse = onUnhandledRequestDefault(octokitRequest); - sendResponse(octokitResponse, response); -} +import type { OAuthApp } from "../../index"; +import type { HandlerOptions } from "../types"; +import type { ClientType, Options } from "../../types"; export function createNodeMiddleware( app: OAuthApp>, - { - pathPrefix, - onUnhandledRequest = onUnhandledRequestDefaultNode, - }: HandlerOptions & { - onUnhandledRequest?: ( - request: IncomingMessage, - response: ServerResponse - ) => void; - } = {} + options: HandlerOptions = {} ) { return async function ( request: IncomingMessage, response: ServerResponse, next?: Function ) { - const octokitRequest = parseRequest(request); - const octokitResponse = await handleRequest( - app, - { pathPrefix }, - octokitRequest - ); - + const octokitRequest = await parseRequest(request); + const octokitResponse = await handleRequest(app, options, octokitRequest); if (octokitResponse) { sendResponse(octokitResponse, response); - } else if (typeof next === "function") { - next(); + return true; } else { - onUnhandledRequest(request, response); + next?.(); + return false; } }; } diff --git a/src/middleware/on-unhandled-request-default.ts b/src/middleware/unknown-route-response.ts similarity index 55% rename from src/middleware/on-unhandled-request-default.ts rename to src/middleware/unknown-route-response.ts index 14dd11757..12050c025 100644 --- a/src/middleware/on-unhandled-request-default.ts +++ b/src/middleware/unknown-route-response.ts @@ -1,8 +1,6 @@ -import { OctokitRequest, OctokitResponse } from "./types"; +import type { OctokitRequest } from "./types"; -export function onUnhandledRequestDefault( - request: OctokitRequest -): OctokitResponse { +export function unknownRouteResponse(request: OctokitRequest) { return { status: 404, headers: { "content-type": "application/json" }, diff --git a/src/middleware/web-worker/index.ts b/src/middleware/web-worker/index.ts index 68511336a..3e7462f4d 100644 --- a/src/middleware/web-worker/index.ts +++ b/src/middleware/web-worker/index.ts @@ -1,47 +1,17 @@ import { parseRequest } from "./parse-request"; import { sendResponse } from "./send-response"; import { handleRequest } from "../handle-request"; -import { onUnhandledRequestDefault } from "../on-unhandled-request-default"; -import { OAuthApp } from "../../index"; -import { HandlerOptions } from "../types"; -import { ClientType, Options } from "../../types"; - -async function onUnhandledRequestDefaultWebWorker( - request: Request -): Promise { - const octokitRequest = parseRequest(request); - const octokitResponse = onUnhandledRequestDefault(octokitRequest); - return sendResponse(octokitResponse); -} +import type { OAuthApp } from "../../index"; +import type { HandlerOptions } from "../types"; +import type { ClientType, Options } from "../../types"; export function createWebWorkerHandler>( app: OAuthApp, - { - pathPrefix, - onUnhandledRequest = onUnhandledRequestDefaultWebWorker, - }: HandlerOptions & { - onUnhandledRequest?: (request: Request) => Response | Promise; - } = {} + options: HandlerOptions = {} ) { - return async function (request: Request): Promise { - const octokitRequest = parseRequest(request); - const octokitResponse = await handleRequest( - app, - { pathPrefix }, - octokitRequest - ); - return octokitResponse - ? sendResponse(octokitResponse) - : await onUnhandledRequest(request); + return async function (request: Request): Promise { + const octokitRequest = await parseRequest(request); + const octokitResponse = await handleRequest(app, options, octokitRequest); + return octokitResponse ? sendResponse(octokitResponse) : undefined; }; } - -/** @deprecated */ -export function createCloudflareHandler( - ...args: Parameters -) { - args[0].octokit.log.warn( - "[@octokit/oauth-app] `createCloudflareHandler` is deprecated, use `createWebWorkerHandler` instead" - ); - return createWebWorkerHandler(...args); -} diff --git a/test/aws-lambda-api-gateway-v2.test.ts b/test/aws-lambda-api-gateway-v2.test.ts index 3209f1902..d40c72722 100644 --- a/test/aws-lambda-api-gateway-v2.test.ts +++ b/test/aws-lambda-api-gateway-v2.test.ts @@ -1,4 +1,4 @@ -import { OAuthApp, createAWSLambdaAPIGatewayV2Handler } from "../src/"; +import { createAWSLambdaAPIGatewayV2Handler, OAuthApp } from "../src/"; import { URL } from "url"; import { APIGatewayProxyEventV2 } from "aws-lambda"; @@ -21,7 +21,7 @@ describe("createAWSLambdaAPIGatewayV2Handler(app)", () => { createAWSLambdaAPIGatewayV2Handler(app); }); - it("fail-over to default unhandled request handler", async () => { + it("do not handle request with different prefix", async () => { const appMock = {}; const handleRequest = createAWSLambdaAPIGatewayV2Handler( appMock as unknown as OAuthApp @@ -32,6 +32,20 @@ describe("createAWSLambdaAPIGatewayV2Handler(app)", () => { rawPath: "/prod/unknown", } as APIGatewayProxyEventV2); + expect(response).toBeUndefined(); + }); + + it("fail-over to default unhandled request handler", async () => { + const appMock = {}; + const handleRequest = createAWSLambdaAPIGatewayV2Handler( + appMock as unknown as OAuthApp + ); + + const response = (await handleRequest({ + requestContext: { http: { method: "GET" }, stage: "prod" }, + rawPath: "/prod/api/github/oauth/unknown", + } as APIGatewayProxyEventV2))!; + expect(response.statusCode).toBe(404); }); @@ -39,10 +53,10 @@ describe("createAWSLambdaAPIGatewayV2Handler(app)", () => { const app = new OAuthApp({ clientId: "0123", clientSecret: "0123secret" }); const handleRequest = createAWSLambdaAPIGatewayV2Handler(app); - const response = await handleRequest({ + const response = (await handleRequest({ requestContext: { http: { method: "OPTIONS" }, stage: "prod" }, rawPath: "/prod/api/github/oauth/token", - } as APIGatewayProxyEventV2); + } as APIGatewayProxyEventV2))!; expect(response.statusCode).toStrictEqual(200); expect(response.headers!["access-control-allow-origin"]).toBe("*"); @@ -56,10 +70,10 @@ describe("createAWSLambdaAPIGatewayV2Handler(app)", () => { const app = new OAuthApp({ clientId: "0123", clientSecret: "0123secret" }); const handleRequest = createAWSLambdaAPIGatewayV2Handler(app); - const response = await handleRequest({ + const response = (await handleRequest({ requestContext: { http: { method: "GET" }, stage: "$default" }, rawPath: "/api/github/oauth/login", - } as APIGatewayProxyEventV2); + } as APIGatewayProxyEventV2))!; expect(response.statusCode).toBe(302); const url = new URL(response.headers!.location as string); @@ -74,10 +88,10 @@ describe("createAWSLambdaAPIGatewayV2Handler(app)", () => { const app = new OAuthApp({ clientId: "0123", clientSecret: "0123secret" }); const handleRequest = createAWSLambdaAPIGatewayV2Handler(app); - const response = await handleRequest({ + const response = (await handleRequest({ requestContext: { http: { method: "GET" }, stage: "prod" }, rawPath: "/prod/api/github/oauth/login", - } as APIGatewayProxyEventV2); + } as APIGatewayProxyEventV2))!; expect(response.statusCode).toBe(302); const url = new URL(response.headers!.location as string); @@ -92,11 +106,11 @@ describe("createAWSLambdaAPIGatewayV2Handler(app)", () => { const app = new OAuthApp({ clientId: "0123", clientSecret: "0123secret" }); const handleRequest = createAWSLambdaAPIGatewayV2Handler(app); - const response = await handleRequest({ + const response = (await handleRequest({ requestContext: { http: { method: "GET" }, stage: "prod" }, rawPath: "/prod/api/github/oauth/login", rawQueryString: "state=mystate123&scopes=one,two,three", - } as APIGatewayProxyEventV2); + } as APIGatewayProxyEventV2))!; expect(response.statusCode).toBe(302); const url = new URL(response.headers!.location as string); diff --git a/test/deprecations.test.ts b/test/deprecations.test.ts index 7d9c9e871..9afaa6400 100644 --- a/test/deprecations.test.ts +++ b/test/deprecations.test.ts @@ -1,8 +1,5 @@ -import { URL } from "url"; import * as nodeFetch from "node-fetch"; import fromEntries from "fromentries"; -import { createCloudflareHandler, OAuthApp } from "../src"; -import { Octokit } from "@octokit/core"; describe("deprecations", () => { beforeAll(() => { @@ -16,40 +13,5 @@ describe("deprecations", () => { delete (global as any).Response; }); - it("createCloudflareHandler works but logs out deprecation message", async () => { - const warn = jest.fn().mockResolvedValue(undefined); - const handleRequest = createCloudflareHandler( - new OAuthApp({ - clientType: "github-app", - clientId: "client_id_123", - clientSecret: "client_secret_456", - Octokit: Octokit.defaults({ - log: { - debug: () => undefined, - info: () => undefined, - warn, - error: () => undefined, - }, - }), - }) - ); - - expect(warn.mock.calls.length).toEqual(1); - expect(warn.mock.calls[0][0]).toEqual( - "[@octokit/oauth-app] `createCloudflareHandler` is deprecated, use `createWebWorkerHandler` instead" - ); - - const request = new Request("/api/github/oauth/login"); - const { status, headers } = await handleRequest(request); - - expect(status).toEqual(302); - const url = new URL(headers.get("location") as string); - expect(url).toMatchObject({ - origin: "https://github.com", - pathname: "/login/oauth/authorize", - }); - expect(url.searchParams.get("client_id")).toEqual("client_id_123"); - expect(url.searchParams.get("state")).toMatch(/^\w+$/); - expect(url.searchParams.get("scope")).toEqual(null); - }); + it("has no deprecations currently", async () => {}); }); diff --git a/test/node-middleware.test.ts b/test/node-middleware.test.ts index 28b2827ae..5fec802bc 100644 --- a/test/node-middleware.test.ts +++ b/test/node-middleware.test.ts @@ -1,4 +1,4 @@ -import { createServer } from "http"; +import { createServer, IncomingMessage } from "http"; import { URL } from "url"; import fetch from "node-fetch"; @@ -492,55 +492,18 @@ describe("createNodeMiddleware(app)", () => { }); }); - it("POST /unrelated", async () => { - expect.assertions(4); - - const app = new OAuthApp({ - clientId: "0123", - clientSecret: "0123secret", - }); - - const server = createServer( - createNodeMiddleware(app, { - onUnhandledRequest: (request, response) => { - expect(request.method).toEqual("POST"); - expect(request.url).toEqual("/unrelated"); - - // test that the request has not yet been consumed with .on("data") - expect(request.complete).toEqual(false); - - response.writeHead(200); - response.end(); - }, - }) - ).listen(); - // @ts-expect-error complains about { port } although it's included in returned AddressInfo interface - const { port } = server.address(); - - const { status, headers } = await fetch( - `http://localhost:${port}/unrelated`, - { - method: "POST", - body: JSON.stringify({ ok: true }), - headers: { - "content-type": "application/json", - }, - } - ); - - server.close(); - - expect(status).toEqual(200); - }); - - // errors - it("GET /unknown", async () => { const appMock = {}; - const server = createServer( - createNodeMiddleware(appMock as unknown as OAuthApp) - ).listen(); + const middleware = createNodeMiddleware(appMock as unknown as OAuthApp); + const requestListener = async (req: IncomingMessage, res: any) => { + if (!(await middleware(req, res))) { + res.writeHead(404, { "Content-Type": "text/plain" }); + res.write("Not found."); + res.end(); + } + }; + const server = createServer(requestListener).listen(); // @ts-expect-error complains about { port } although it's included in returned AddressInfo interface const { port } = server.address(); @@ -860,6 +823,42 @@ describe("createNodeMiddleware(app)", () => { server.close(); }); + it("???", async () => { + const app = express(); + + // app.all("/foo", (_request: any, response: any) => response.end("ok\n")); + app.use( + createNodeMiddleware( + new OAuthApp({ + clientId: "0123", + clientSecret: "0123secret", + }) + ) + ); + + const server = app.listen(); + + const { port } = server.address(); + + const response = await fetch(`http://localhost:${port}/test`, { + method: "POST", + body: "{}", + }); + + await expect(response.text()).resolves.toContain("Cannot POST /test"); + expect(response.status).toEqual(404); + + // const responseForFoo = await fetch(`http://localhost:${port}/foo`, { + // method: "POST", + // body: "{}", + // }); + + // await expect(responseForFoo.text()).resolves.toContain("ok\n"); + // expect(responseForFoo.status).toEqual(200); + + server.close(); + }); + it("express middleware no mount path no next", async () => { const app = express(); diff --git a/test/smoke.test.ts b/test/smoke.test.ts index 2cb6c4ec9..266026277 100644 --- a/test/smoke.test.ts +++ b/test/smoke.test.ts @@ -1,4 +1,9 @@ -import { OAuthApp } from "../src"; +import { + handleRequest, + OAuthApp, + sendNodeResponse, + unknownRouteResponse, +} from "../src"; describe("Smoke test", () => { it("OAuthApp is a function", () => { @@ -12,4 +17,16 @@ describe("Smoke test", () => { it("OAuthApp.VERSION is set", () => { expect(OAuthApp.VERSION).toEqual("0.0.0-development"); }); + + it("handleRequest is a function", () => { + expect(typeof handleRequest).toEqual("function"); + }); + + it("unknownRouteResponse is a function", () => { + expect(typeof unknownRouteResponse).toEqual("function"); + }); + + it("sendNodeResponse is a function", () => { + expect(typeof sendNodeResponse).toEqual("function"); + }); }); diff --git a/test/web-worker-handler.test.ts b/test/web-worker-handler.test.ts index ba26da54c..413e28fec 100644 --- a/test/web-worker-handler.test.ts +++ b/test/web-worker-handler.test.ts @@ -1,11 +1,7 @@ import { URL } from "url"; import * as nodeFetch from "node-fetch"; import fromEntries from "fromentries"; -import { - createCloudflareHandler, - createWebWorkerHandler, - OAuthApp, -} from "../src"; +import { createWebWorkerHandler, OAuthApp } from "../src"; import { Octokit } from "@octokit/core"; describe("createWebWorkerHandler(app)", () => { @@ -46,7 +42,7 @@ describe("createWebWorkerHandler(app)", () => { method: "OPTIONS", }); const response = await handleRequest(request); - expect(response.status).toStrictEqual(200); + expect(response!.status).toStrictEqual(200); }); it("GET /api/github/oauth/login", async () => { @@ -57,7 +53,7 @@ describe("createWebWorkerHandler(app)", () => { const handleRequest = createWebWorkerHandler(app); const request = new Request("/api/github/oauth/login"); - const { status, headers } = await handleRequest(request); + const { status, headers } = (await handleRequest(request))!; expect(status).toEqual(302); const url = new URL(headers.get("location") as string); @@ -79,7 +75,7 @@ describe("createWebWorkerHandler(app)", () => { const handleRequest = createWebWorkerHandler(app); const request = new Request("/api/github/oauth/login"); - const { status, headers } = await handleRequest(request); + const { status, headers } = (await handleRequest(request))!; expect(status).toEqual(302); const url = new URL(headers.get("location") as string); @@ -102,7 +98,7 @@ describe("createWebWorkerHandler(app)", () => { const request = new Request( "/api/github/oauth/login?state=mystate123&scopes=one,two,three" ); - const { status, headers } = await handleRequest(request); + const { status, headers } = (await handleRequest(request))!; expect(status).toEqual(302); const url = new URL(headers.get("location") as string); @@ -132,7 +128,7 @@ describe("createWebWorkerHandler(app)", () => { const request = new Request( "/api/github/oauth/callback?code=012345&state=state123" ); - const response = await handleRequest(request); + const response = (await handleRequest(request))!; expect(response.status).toEqual(200); expect(await response.text()).toMatch(/token123/); @@ -164,7 +160,7 @@ describe("createWebWorkerHandler(app)", () => { redirectUrl: "http://example.com", }), }); - const response = await handleRequest(request); + const response = (await handleRequest(request))!; expect(response.status).toEqual(201); expect(await response.json()).toStrictEqual({ @@ -198,7 +194,7 @@ describe("createWebWorkerHandler(app)", () => { authorization: "token token123", }, }); - const response = await handleRequest(request); + const response = (await handleRequest(request))!; expect(response.status).toEqual(200); expect(await response.json()).toStrictEqual({ @@ -231,7 +227,7 @@ describe("createWebWorkerHandler(app)", () => { method: "PATCH", headers: { authorization: "token token123" }, }); - const response = await handleRequest(request); + const response = (await handleRequest(request))!; expect(response.status).toEqual(200); expect(await response.json()).toStrictEqual({ @@ -269,7 +265,7 @@ describe("createWebWorkerHandler(app)", () => { permissions: { issues: "write" }, }), }); - const response = await handleRequest(request); + const response = (await handleRequest(request))!; expect(response.status).toEqual(200); expect(response.status).toEqual(200); @@ -320,7 +316,7 @@ describe("createWebWorkerHandler(app)", () => { headers: { authorization: "token token123" }, body: JSON.stringify({ refreshToken: "r1.refreshtoken123" }), }); - const response = await handleRequest(request); + const response = (await handleRequest(request))!; expect(await response.json()).toStrictEqual({ data: { id: 1 }, @@ -353,7 +349,7 @@ describe("createWebWorkerHandler(app)", () => { method: "PATCH", headers: { authorization: "token token123" }, }); - const response = await handleRequest(request); + const response = (await handleRequest(request))!; expect(response.status).toEqual(200); expect(await response.json()).toStrictEqual({ @@ -379,7 +375,7 @@ describe("createWebWorkerHandler(app)", () => { method: "DELETE", headers: { authorization: "token token123" }, }); - const response = await handleRequest(request); + const response = (await handleRequest(request))!; expect(response.status).toEqual(204); @@ -401,7 +397,7 @@ describe("createWebWorkerHandler(app)", () => { method: "DELETE", headers: { authorization: "token token123" }, }); - const response = await handleRequest(request); + const response = (await handleRequest(request))!; expect(response.status).toEqual(204); @@ -412,21 +408,11 @@ describe("createWebWorkerHandler(app)", () => { }); it("POST /unrelated", async () => { - expect.assertions(4); - const app = new OAuthApp({ clientId: "0123", clientSecret: "0123secret", }); - const handleRequest = createWebWorkerHandler(app, { - onUnhandledRequest: async (request: Request) => { - expect(request.method).toEqual("POST"); - expect(request.url).toEqual("/unrelated"); - const text = await request.text(); - expect(text).toEqual('{"ok":true}'); - return new Response(null, { status: 200 }); - }, - }); + const handleRequest = createWebWorkerHandler(app); const request = new Request("/unrelated", { method: "POST", @@ -435,9 +421,9 @@ describe("createWebWorkerHandler(app)", () => { "content-type": "application/json", }, }); - const { status } = await handleRequest(request); + const response = await handleRequest(request); - expect(status).toEqual(200); + expect(response).toBeUndefined(); }); // // errors @@ -449,8 +435,8 @@ describe("createWebWorkerHandler(app)", () => { ); const request = new Request("/unknown"); - const response = await handleRequest(request); - expect(response.status).toEqual(404); + const response = (await handleRequest(request))!; + expect(response).toBeUndefined(); }); it("GET /api/github/oauth/callback without code", async () => { @@ -460,7 +446,7 @@ describe("createWebWorkerHandler(app)", () => { ); const request = new Request("/api/github/oauth/callback"); - const response = await handleRequest(request); + const response = (await handleRequest(request))!; expect(response.status).toEqual(400); expect(await response.json()).toStrictEqual({ @@ -477,7 +463,7 @@ describe("createWebWorkerHandler(app)", () => { const request = new Request( "/api/github/oauth/callback?error=redirect_uri_mismatch&error_description=The+redirect_uri+MUST+match+the+registered+callback+URL+for+this+application.&error_uri=https://docs.github.com/en/developers/apps/troubleshooting-authorization-request-errors/%23redirect-uri-mismatch&state=xyz" ); - const response = await handleRequest(request); + const response = (await handleRequest(request))!; expect(response.status).toEqual(400); expect(await response.json()).toStrictEqual({ @@ -496,7 +482,7 @@ describe("createWebWorkerHandler(app)", () => { method: "POST", body: JSON.stringify({}), }); - const response = await handleRequest(request); + const response = (await handleRequest(request))!; expect(response.status).toEqual(400); expect(await response.json()).toStrictEqual({ @@ -514,7 +500,7 @@ describe("createWebWorkerHandler(app)", () => { method: "POST", body: "foo", }); - const response = await handleRequest(request); + const response = (await handleRequest(request))!; expect(response.status).toEqual(400); expect(await response.json()).toStrictEqual({ @@ -531,7 +517,7 @@ describe("createWebWorkerHandler(app)", () => { const request = new Request("/api/github/oauth/token", { headers: {}, }); - const response = await handleRequest(request); + const response = (await handleRequest(request))!; expect(response.status).toEqual(400); expect(await response.json()).toStrictEqual({ @@ -549,7 +535,7 @@ describe("createWebWorkerHandler(app)", () => { method: "PATCH", headers: {}, }); - const response = await handleRequest(request); + const response = (await handleRequest(request))!; expect(response.status).toEqual(400); expect(await response.json()).toStrictEqual({ @@ -567,7 +553,7 @@ describe("createWebWorkerHandler(app)", () => { method: "POST", headers: {}, }); - const response = await handleRequest(request); + const response = (await handleRequest(request))!; expect(response.status).toEqual(400); expect(await response.json()).toStrictEqual({ @@ -591,7 +577,7 @@ describe("createWebWorkerHandler(app)", () => { refreshToken: "r1.refreshtoken123", }), }); - const response = await handleRequest(request); + const response = (await handleRequest(request))!; expect(response.status).toEqual(400); expect(await response.json()).toStrictEqual({ @@ -615,7 +601,7 @@ describe("createWebWorkerHandler(app)", () => { authorization: "token token123", }, }); - const response = await handleRequest(request); + const response = (await handleRequest(request))!; expect(response.status).toEqual(400); expect(await response.json()).toStrictEqual({ @@ -633,7 +619,7 @@ describe("createWebWorkerHandler(app)", () => { method: "DELETE", headers: {}, }); - const response = await handleRequest(request); + const response = (await handleRequest(request))!; expect(response.status).toEqual(400); expect(await response.json()).toStrictEqual({ @@ -651,7 +637,7 @@ describe("createWebWorkerHandler(app)", () => { method: "DELETE", headers: {}, }); - const response = await handleRequest(request); + const response = (await handleRequest(request))!; expect(response.status).toEqual(400); expect(await response.json()).toStrictEqual({ @@ -669,7 +655,7 @@ describe("createWebWorkerHandler(app)", () => { ); const request = new Request("/test/login", { redirect: "manual" }); - const { status } = await handleRequest(request); + const { status } = (await handleRequest(request))!; expect(status).toEqual(302); }); From a73cd5e370091a7be1d10241a52892426034a14f Mon Sep 17 00:00:00 2001 From: wolfy1339 <4595477+wolfy1339@users.noreply.github.com> Date: Tue, 13 Jun 2023 18:08:09 -0400 Subject: [PATCH 2/5] ci: stop testing against NodeJS v14, v16 (#414) BREAKING CHANGE: Drop support for NodeJS v14, v16 --- .github/workflows/test.yml | 3 +-- package.json | 2 +- scripts/build.mjs | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index d2fc25df3..83d1aa643 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -13,9 +13,8 @@ jobs: strategy: matrix: node_version: - - 14 - - 16 - 18 + - 20 steps: - uses: actions/checkout@v3 - name: Use Node.js ${{ matrix.node_version }} diff --git a/package.json b/package.json index f3eefd1f1..9d527eb99 100644 --- a/package.json +++ b/package.json @@ -94,6 +94,6 @@ "access": "public" }, "engines": { - "node": ">= 14" + "node": ">= 18" } } diff --git a/scripts/build.mjs b/scripts/build.mjs index 7b7ce7f3e..57f7d7b99 100644 --- a/scripts/build.mjs +++ b/scripts/build.mjs @@ -45,7 +45,7 @@ async function main() { outdir: "pkg/dist-node", bundle: true, platform: "node", - target: "node14", + target: "node18", format: "cjs", ...sharedOptions, }); From c43e5e48e3e8aa0aedb086f3f82d1cfdc4778496 Mon Sep 17 00:00:00 2001 From: wolfy1339 Date: Sat, 17 Jun 2023 12:26:23 -0400 Subject: [PATCH 3/5] fix(deps): update Octokit dependencies --- package-lock.json | 645 +++++++++++++++++++++++++++++++++++++++------- package.json | 12 +- 2 files changed, 564 insertions(+), 93 deletions(-) diff --git a/package-lock.json b/package-lock.json index 61e08cc1f..a6a41d0b2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,12 +9,12 @@ "version": "0.0.0-development", "license": "MIT", "dependencies": { - "@octokit/auth-oauth-app": "^5.0.0", - "@octokit/auth-oauth-user": "^2.0.0", - "@octokit/auth-unauthenticated": "^3.0.0", - "@octokit/core": "^4.0.0", - "@octokit/oauth-authorization-url": "^5.0.0", - "@octokit/oauth-methods": "^2.0.0", + "@octokit/auth-oauth-app": "^6.0.0", + "@octokit/auth-oauth-user": "^3.0.0", + "@octokit/auth-unauthenticated": "^4.0.1", + "@octokit/core": "^5.0.0-beta.3", + "@octokit/oauth-authorization-url": "^6.0.2", + "@octokit/oauth-methods": "^3.0.1", "@types/aws-lambda": "^8.10.83", "fromentries": "^1.3.1", "universal-user-agent": "^6.0.0" @@ -37,7 +37,7 @@ "typescript": "^5.0.0" }, "engines": { - "node": ">= 14" + "node": ">= 18" } }, "node_modules/@ampproject/remapping": { @@ -1760,9 +1760,9 @@ "dev": true }, "node_modules/@octokit/auth-oauth-app": { - "version": "5.0.6", - "resolved": "https://registry.npmjs.org/@octokit/auth-oauth-app/-/auth-oauth-app-5.0.6.tgz", - "integrity": "sha512-SxyfIBfeFcWd9Z/m1xa4LENTQ3l1y6Nrg31k2Dcb1jS5ov7pmwMJZ6OGX8q3K9slRgVpeAjNA1ipOAMHkieqyw==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@octokit/auth-oauth-app/-/auth-oauth-app-6.0.0.tgz", + "integrity": "sha512-ihIanzc2dX/FQJwTDeKR2xT2K+5IFV33yjkn4zhJ7HL7FPJjw0ynNcGkEJMzrFEsgIn7Qfjd+MA4jTay0rrbLQ==", "dependencies": { "@octokit/auth-oauth-device": "^4.0.0", "@octokit/auth-oauth-user": "^2.0.0", @@ -1772,6 +1772,45 @@ "btoa-lite": "^1.0.0", "universal-user-agent": "^6.0.0" }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/auth-oauth-app/node_modules/@octokit/auth-oauth-user": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@octokit/auth-oauth-user/-/auth-oauth-user-2.1.2.tgz", + "integrity": "sha512-kkRqNmFe7s5GQcojE3nSlF+AzYPpPv7kvP/xYEnE57584pixaFBH8Vovt+w5Y3E4zWUEOxjdLItmBTFAWECPAg==", + "dependencies": { + "@octokit/auth-oauth-device": "^4.0.0", + "@octokit/oauth-methods": "^2.0.0", + "@octokit/request": "^6.0.0", + "@octokit/types": "^9.0.0", + "btoa-lite": "^1.0.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/@octokit/auth-oauth-app/node_modules/@octokit/oauth-authorization-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@octokit/oauth-authorization-url/-/oauth-authorization-url-5.0.0.tgz", + "integrity": "sha512-y1WhN+ERDZTh0qZ4SR+zotgsQUE1ysKnvBt1hvDRB2WRzYtVKQjn97HEPzoehh66Fj9LwNdlZh+p6TJatT0zzg==", + "engines": { + "node": ">= 14" + } + }, + "node_modules/@octokit/auth-oauth-app/node_modules/@octokit/oauth-methods": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@octokit/oauth-methods/-/oauth-methods-2.0.6.tgz", + "integrity": "sha512-l9Uml2iGN2aTWLZcm8hV+neBiFXAQ9+3sKiQe/sgumHlL6HDg0AQ8/l16xX/5jJvfxueqTW5CWbzd0MjnlfHZw==", + "dependencies": { + "@octokit/oauth-authorization-url": "^5.0.0", + "@octokit/request": "^6.2.3", + "@octokit/request-error": "^3.0.3", + "@octokit/types": "^9.0.0", + "btoa-lite": "^1.0.0" + }, "engines": { "node": ">= 14" } @@ -1790,10 +1829,33 @@ "node": ">= 14" } }, + "node_modules/@octokit/auth-oauth-device/node_modules/@octokit/oauth-authorization-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@octokit/oauth-authorization-url/-/oauth-authorization-url-5.0.0.tgz", + "integrity": "sha512-y1WhN+ERDZTh0qZ4SR+zotgsQUE1ysKnvBt1hvDRB2WRzYtVKQjn97HEPzoehh66Fj9LwNdlZh+p6TJatT0zzg==", + "engines": { + "node": ">= 14" + } + }, + "node_modules/@octokit/auth-oauth-device/node_modules/@octokit/oauth-methods": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@octokit/oauth-methods/-/oauth-methods-2.0.6.tgz", + "integrity": "sha512-l9Uml2iGN2aTWLZcm8hV+neBiFXAQ9+3sKiQe/sgumHlL6HDg0AQ8/l16xX/5jJvfxueqTW5CWbzd0MjnlfHZw==", + "dependencies": { + "@octokit/oauth-authorization-url": "^5.0.0", + "@octokit/request": "^6.2.3", + "@octokit/request-error": "^3.0.3", + "@octokit/types": "^9.0.0", + "btoa-lite": "^1.0.0" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/@octokit/auth-oauth-user": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@octokit/auth-oauth-user/-/auth-oauth-user-2.1.2.tgz", - "integrity": "sha512-kkRqNmFe7s5GQcojE3nSlF+AzYPpPv7kvP/xYEnE57584pixaFBH8Vovt+w5Y3E4zWUEOxjdLItmBTFAWECPAg==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@octokit/auth-oauth-user/-/auth-oauth-user-3.0.0.tgz", + "integrity": "sha512-qEyN6j4m72MFyTuOZZUqhJyNye1FKBJlu1JtkkiCG6dWN/iHB21uSsUM0qRQ6XpsS+dgG74JyncRHY3W9Nwz0Q==", "dependencies": { "@octokit/auth-oauth-device": "^4.0.0", "@octokit/oauth-methods": "^2.0.0", @@ -1802,45 +1864,138 @@ "btoa-lite": "^1.0.0", "universal-user-agent": "^6.0.0" }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/auth-oauth-user/node_modules/@octokit/oauth-authorization-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@octokit/oauth-authorization-url/-/oauth-authorization-url-5.0.0.tgz", + "integrity": "sha512-y1WhN+ERDZTh0qZ4SR+zotgsQUE1ysKnvBt1hvDRB2WRzYtVKQjn97HEPzoehh66Fj9LwNdlZh+p6TJatT0zzg==", "engines": { "node": ">= 14" } }, - "node_modules/@octokit/auth-token": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-3.0.4.tgz", - "integrity": "sha512-TWFX7cZF2LXoCvdmJWY7XVPi74aSY0+FfBZNSXEXFkMpjcqsQwDSYVv5FhRFaI0V1ECnwbz4j59T/G+rXNWaIQ==", + "node_modules/@octokit/auth-oauth-user/node_modules/@octokit/oauth-methods": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@octokit/oauth-methods/-/oauth-methods-2.0.6.tgz", + "integrity": "sha512-l9Uml2iGN2aTWLZcm8hV+neBiFXAQ9+3sKiQe/sgumHlL6HDg0AQ8/l16xX/5jJvfxueqTW5CWbzd0MjnlfHZw==", + "dependencies": { + "@octokit/oauth-authorization-url": "^5.0.0", + "@octokit/request": "^6.2.3", + "@octokit/request-error": "^3.0.3", + "@octokit/types": "^9.0.0", + "btoa-lite": "^1.0.0" + }, "engines": { "node": ">= 14" } }, + "node_modules/@octokit/auth-token": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-4.0.0.tgz", + "integrity": "sha512-tY/msAuJo6ARbK6SPIxZrPBms3xPbfwBrulZe0Wtr/DIY9lje2HeV1uoebShn6mx7SjCHif6EjMvoREj+gZ+SA==", + "engines": { + "node": ">= 18" + } + }, "node_modules/@octokit/auth-unauthenticated": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@octokit/auth-unauthenticated/-/auth-unauthenticated-3.0.5.tgz", - "integrity": "sha512-yH2GPFcjrTvDWPwJWWCh0tPPtTL5SMgivgKPA+6v/XmYN6hGQkAto8JtZibSKOpf8ipmeYhLNWQ2UgW0GYILCw==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@octokit/auth-unauthenticated/-/auth-unauthenticated-4.0.1.tgz", + "integrity": "sha512-sbjeKHnaKMZ0KmodpYXKAEJhsXQNDUzrJgLMQCXFUF5Il5oXMZrq2BCVsDT+VVh428QkEN64RHWUkPafFTMlNQ==", "dependencies": { - "@octokit/request-error": "^3.0.0", + "@octokit/request-error": "^4.0.0", "@octokit/types": "^9.0.0" }, "engines": { - "node": ">= 14" + "node": ">= 18" } }, - "node_modules/@octokit/core": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@octokit/core/-/core-4.2.1.tgz", - "integrity": "sha512-tEDxFx8E38zF3gT7sSMDrT1tGumDgsw5yPG6BBh/X+5ClIQfMH/Yqocxz1PnHx6CHyF6pxmovUTOfZAUvQ0Lvw==", + "node_modules/@octokit/auth-unauthenticated/node_modules/@octokit/request-error": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-4.0.2.tgz", + "integrity": "sha512-uqwUEmZw3x4I9DGYq9fODVAAvcLsPQv97NRycP6syEFu5916M189VnNBW2zANNwqg3OiligNcAey7P0SET843w==", "dependencies": { - "@octokit/auth-token": "^3.0.0", - "@octokit/graphql": "^5.0.0", - "@octokit/request": "^6.0.0", - "@octokit/request-error": "^3.0.0", - "@octokit/types": "^9.0.0", + "@octokit/types": "^10.0.0", + "deprecation": "^2.0.0", + "once": "^1.4.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/auth-unauthenticated/node_modules/@octokit/request-error/node_modules/@octokit/types": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-10.0.0.tgz", + "integrity": "sha512-Vm8IddVmhCgU1fxC1eyinpwqzXPEYu0NrYzD3YZjlGjyftdLBTeqNblRC0jmJmgxbJIsQlyogVeGnrNaaMVzIg==", + "dependencies": { + "@octokit/openapi-types": "^18.0.0" + } + }, + "node_modules/@octokit/core": { + "version": "5.0.0-beta.3", + "resolved": "https://registry.npmjs.org/@octokit/core/-/core-5.0.0-beta.3.tgz", + "integrity": "sha512-I/4eNh2Our9ZMhSlF9806ChymkwUdpM2DEV+9nMvUK9EjSJqDiCVUP9M6oti0cw0tgYHEFWUWj6VfK40mDIDpw==", + "dependencies": { + "@octokit/auth-token": "^4.0.0", + "@octokit/graphql": "^6.0.0-beta.2", + "@octokit/request": "^7.0.0", + "@octokit/request-error": "^4.0.1", + "@octokit/types": "^10.0.0", "before-after-hook": "^2.2.0", "universal-user-agent": "^6.0.0" }, "engines": { - "node": ">= 14" + "node": ">= 18" + } + }, + "node_modules/@octokit/core/node_modules/@octokit/endpoint": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-8.0.1.tgz", + "integrity": "sha512-tVviBdPuf3kcCiIvXYDJg7NAJrkTh8QEnc+UCybknKdEBCjIi7uQbFX3liQrpk1m5PjwC7fUJg08DYZ4F+l1RQ==", + "dependencies": { + "@octokit/types": "^10.0.0", + "is-plain-object": "^5.0.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/core/node_modules/@octokit/request": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-7.0.0.tgz", + "integrity": "sha512-iUnS9KDsFWfHLwomq/QZmEja8nQZ9FnkMp58+6qz1AKFIBi+sF6w1HGpimRxmmpstFHHGB3eE0qYjuV1Z/Gc3Q==", + "dependencies": { + "@octokit/endpoint": "^8.0.0", + "@octokit/request-error": "^4.0.1", + "@octokit/types": "^10.0.0", + "is-plain-object": "^5.0.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/core/node_modules/@octokit/request-error": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-4.0.2.tgz", + "integrity": "sha512-uqwUEmZw3x4I9DGYq9fODVAAvcLsPQv97NRycP6syEFu5916M189VnNBW2zANNwqg3OiligNcAey7P0SET843w==", + "dependencies": { + "@octokit/types": "^10.0.0", + "deprecation": "^2.0.0", + "once": "^1.4.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/core/node_modules/@octokit/types": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-10.0.0.tgz", + "integrity": "sha512-Vm8IddVmhCgU1fxC1eyinpwqzXPEYu0NrYzD3YZjlGjyftdLBTeqNblRC0jmJmgxbJIsQlyogVeGnrNaaMVzIg==", + "dependencies": { + "@octokit/openapi-types": "^18.0.0" } }, "node_modules/@octokit/endpoint": { @@ -1857,39 +2012,137 @@ } }, "node_modules/@octokit/graphql": { - "version": "5.0.6", - "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-5.0.6.tgz", - "integrity": "sha512-Fxyxdy/JH0MnIB5h+UQ3yCoh1FG4kWXfFKkpWqjZHw/p+Kc8Y44Hu/kCgNBT6nU1shNumEchmW/sUO1JuQnPcw==", + "version": "6.0.0-beta.2", + "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-6.0.0-beta.2.tgz", + "integrity": "sha512-41ujApYqTh4gU1Htyx9s/iQuew8hOtLIbRqlydWPGCfJpSHnTz/BXDqoq/LQWh9KZ7TRM+1/JweRk+EhT0LqnQ==", "dependencies": { - "@octokit/request": "^6.0.0", - "@octokit/types": "^9.0.0", + "@octokit/request": "^7.0.0", + "@octokit/types": "^10.0.0", "universal-user-agent": "^6.0.0" }, "engines": { - "node": ">= 14" + "node": ">= 18" + } + }, + "node_modules/@octokit/graphql/node_modules/@octokit/endpoint": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-8.0.1.tgz", + "integrity": "sha512-tVviBdPuf3kcCiIvXYDJg7NAJrkTh8QEnc+UCybknKdEBCjIi7uQbFX3liQrpk1m5PjwC7fUJg08DYZ4F+l1RQ==", + "dependencies": { + "@octokit/types": "^10.0.0", + "is-plain-object": "^5.0.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/graphql/node_modules/@octokit/request": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-7.0.0.tgz", + "integrity": "sha512-iUnS9KDsFWfHLwomq/QZmEja8nQZ9FnkMp58+6qz1AKFIBi+sF6w1HGpimRxmmpstFHHGB3eE0qYjuV1Z/Gc3Q==", + "dependencies": { + "@octokit/endpoint": "^8.0.0", + "@octokit/request-error": "^4.0.1", + "@octokit/types": "^10.0.0", + "is-plain-object": "^5.0.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/graphql/node_modules/@octokit/request-error": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-4.0.2.tgz", + "integrity": "sha512-uqwUEmZw3x4I9DGYq9fODVAAvcLsPQv97NRycP6syEFu5916M189VnNBW2zANNwqg3OiligNcAey7P0SET843w==", + "dependencies": { + "@octokit/types": "^10.0.0", + "deprecation": "^2.0.0", + "once": "^1.4.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/graphql/node_modules/@octokit/types": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-10.0.0.tgz", + "integrity": "sha512-Vm8IddVmhCgU1fxC1eyinpwqzXPEYu0NrYzD3YZjlGjyftdLBTeqNblRC0jmJmgxbJIsQlyogVeGnrNaaMVzIg==", + "dependencies": { + "@octokit/openapi-types": "^18.0.0" } }, "node_modules/@octokit/oauth-authorization-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@octokit/oauth-authorization-url/-/oauth-authorization-url-5.0.0.tgz", - "integrity": "sha512-y1WhN+ERDZTh0qZ4SR+zotgsQUE1ysKnvBt1hvDRB2WRzYtVKQjn97HEPzoehh66Fj9LwNdlZh+p6TJatT0zzg==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@octokit/oauth-authorization-url/-/oauth-authorization-url-6.0.2.tgz", + "integrity": "sha512-CdoJukjXXxqLNK4y/VOiVzQVjibqoj/xHgInekviUJV73y/BSIcwvJ/4aNHPBPKcPWFnd4/lO9uqRV65jXhcLA==", "engines": { - "node": ">= 14" + "node": ">= 18" } }, "node_modules/@octokit/oauth-methods": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/@octokit/oauth-methods/-/oauth-methods-2.0.6.tgz", - "integrity": "sha512-l9Uml2iGN2aTWLZcm8hV+neBiFXAQ9+3sKiQe/sgumHlL6HDg0AQ8/l16xX/5jJvfxueqTW5CWbzd0MjnlfHZw==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@octokit/oauth-methods/-/oauth-methods-3.0.1.tgz", + "integrity": "sha512-TIoJQq4BxGueYwGzxmSpCMqbJwCdPaeYYFbZdpA0xtUpDYw0vS1Yr5yzWshuL1sMk3oBJ7zqouWSapd2+PxU9Q==", "dependencies": { - "@octokit/oauth-authorization-url": "^5.0.0", - "@octokit/request": "^6.2.3", - "@octokit/request-error": "^3.0.3", - "@octokit/types": "^9.0.0", + "@octokit/oauth-authorization-url": "^6.0.2", + "@octokit/request": "^7.0.0", + "@octokit/request-error": "^4.0.1", + "@octokit/types": "^10.0.0", "btoa-lite": "^1.0.0" }, "engines": { - "node": ">= 14" + "node": ">= 18" + } + }, + "node_modules/@octokit/oauth-methods/node_modules/@octokit/endpoint": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-8.0.1.tgz", + "integrity": "sha512-tVviBdPuf3kcCiIvXYDJg7NAJrkTh8QEnc+UCybknKdEBCjIi7uQbFX3liQrpk1m5PjwC7fUJg08DYZ4F+l1RQ==", + "dependencies": { + "@octokit/types": "^10.0.0", + "is-plain-object": "^5.0.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/oauth-methods/node_modules/@octokit/request": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-7.0.0.tgz", + "integrity": "sha512-iUnS9KDsFWfHLwomq/QZmEja8nQZ9FnkMp58+6qz1AKFIBi+sF6w1HGpimRxmmpstFHHGB3eE0qYjuV1Z/Gc3Q==", + "dependencies": { + "@octokit/endpoint": "^8.0.0", + "@octokit/request-error": "^4.0.1", + "@octokit/types": "^10.0.0", + "is-plain-object": "^5.0.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/oauth-methods/node_modules/@octokit/request-error": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-4.0.2.tgz", + "integrity": "sha512-uqwUEmZw3x4I9DGYq9fODVAAvcLsPQv97NRycP6syEFu5916M189VnNBW2zANNwqg3OiligNcAey7P0SET843w==", + "dependencies": { + "@octokit/types": "^10.0.0", + "deprecation": "^2.0.0", + "once": "^1.4.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/oauth-methods/node_modules/@octokit/types": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-10.0.0.tgz", + "integrity": "sha512-Vm8IddVmhCgU1fxC1eyinpwqzXPEYu0NrYzD3YZjlGjyftdLBTeqNblRC0jmJmgxbJIsQlyogVeGnrNaaMVzIg==", + "dependencies": { + "@octokit/openapi-types": "^18.0.0" } }, "node_modules/@octokit/openapi-types": { @@ -8499,9 +8752,9 @@ } }, "@octokit/auth-oauth-app": { - "version": "5.0.6", - "resolved": "https://registry.npmjs.org/@octokit/auth-oauth-app/-/auth-oauth-app-5.0.6.tgz", - "integrity": "sha512-SxyfIBfeFcWd9Z/m1xa4LENTQ3l1y6Nrg31k2Dcb1jS5ov7pmwMJZ6OGX8q3K9slRgVpeAjNA1ipOAMHkieqyw==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@octokit/auth-oauth-app/-/auth-oauth-app-6.0.0.tgz", + "integrity": "sha512-ihIanzc2dX/FQJwTDeKR2xT2K+5IFV33yjkn4zhJ7HL7FPJjw0ynNcGkEJMzrFEsgIn7Qfjd+MA4jTay0rrbLQ==", "requires": { "@octokit/auth-oauth-device": "^4.0.0", "@octokit/auth-oauth-user": "^2.0.0", @@ -8510,6 +8763,38 @@ "@types/btoa-lite": "^1.0.0", "btoa-lite": "^1.0.0", "universal-user-agent": "^6.0.0" + }, + "dependencies": { + "@octokit/auth-oauth-user": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@octokit/auth-oauth-user/-/auth-oauth-user-2.1.2.tgz", + "integrity": "sha512-kkRqNmFe7s5GQcojE3nSlF+AzYPpPv7kvP/xYEnE57584pixaFBH8Vovt+w5Y3E4zWUEOxjdLItmBTFAWECPAg==", + "requires": { + "@octokit/auth-oauth-device": "^4.0.0", + "@octokit/oauth-methods": "^2.0.0", + "@octokit/request": "^6.0.0", + "@octokit/types": "^9.0.0", + "btoa-lite": "^1.0.0", + "universal-user-agent": "^6.0.0" + } + }, + "@octokit/oauth-authorization-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@octokit/oauth-authorization-url/-/oauth-authorization-url-5.0.0.tgz", + "integrity": "sha512-y1WhN+ERDZTh0qZ4SR+zotgsQUE1ysKnvBt1hvDRB2WRzYtVKQjn97HEPzoehh66Fj9LwNdlZh+p6TJatT0zzg==" + }, + "@octokit/oauth-methods": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@octokit/oauth-methods/-/oauth-methods-2.0.6.tgz", + "integrity": "sha512-l9Uml2iGN2aTWLZcm8hV+neBiFXAQ9+3sKiQe/sgumHlL6HDg0AQ8/l16xX/5jJvfxueqTW5CWbzd0MjnlfHZw==", + "requires": { + "@octokit/oauth-authorization-url": "^5.0.0", + "@octokit/request": "^6.2.3", + "@octokit/request-error": "^3.0.3", + "@octokit/types": "^9.0.0", + "btoa-lite": "^1.0.0" + } + } } }, "@octokit/auth-oauth-device": { @@ -8521,12 +8806,31 @@ "@octokit/request": "^6.0.0", "@octokit/types": "^9.0.0", "universal-user-agent": "^6.0.0" + }, + "dependencies": { + "@octokit/oauth-authorization-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@octokit/oauth-authorization-url/-/oauth-authorization-url-5.0.0.tgz", + "integrity": "sha512-y1WhN+ERDZTh0qZ4SR+zotgsQUE1ysKnvBt1hvDRB2WRzYtVKQjn97HEPzoehh66Fj9LwNdlZh+p6TJatT0zzg==" + }, + "@octokit/oauth-methods": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@octokit/oauth-methods/-/oauth-methods-2.0.6.tgz", + "integrity": "sha512-l9Uml2iGN2aTWLZcm8hV+neBiFXAQ9+3sKiQe/sgumHlL6HDg0AQ8/l16xX/5jJvfxueqTW5CWbzd0MjnlfHZw==", + "requires": { + "@octokit/oauth-authorization-url": "^5.0.0", + "@octokit/request": "^6.2.3", + "@octokit/request-error": "^3.0.3", + "@octokit/types": "^9.0.0", + "btoa-lite": "^1.0.0" + } + } } }, "@octokit/auth-oauth-user": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@octokit/auth-oauth-user/-/auth-oauth-user-2.1.2.tgz", - "integrity": "sha512-kkRqNmFe7s5GQcojE3nSlF+AzYPpPv7kvP/xYEnE57584pixaFBH8Vovt+w5Y3E4zWUEOxjdLItmBTFAWECPAg==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@octokit/auth-oauth-user/-/auth-oauth-user-3.0.0.tgz", + "integrity": "sha512-qEyN6j4m72MFyTuOZZUqhJyNye1FKBJlu1JtkkiCG6dWN/iHB21uSsUM0qRQ6XpsS+dgG74JyncRHY3W9Nwz0Q==", "requires": { "@octokit/auth-oauth-device": "^4.0.0", "@octokit/oauth-methods": "^2.0.0", @@ -8534,34 +8838,117 @@ "@octokit/types": "^9.0.0", "btoa-lite": "^1.0.0", "universal-user-agent": "^6.0.0" + }, + "dependencies": { + "@octokit/oauth-authorization-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@octokit/oauth-authorization-url/-/oauth-authorization-url-5.0.0.tgz", + "integrity": "sha512-y1WhN+ERDZTh0qZ4SR+zotgsQUE1ysKnvBt1hvDRB2WRzYtVKQjn97HEPzoehh66Fj9LwNdlZh+p6TJatT0zzg==" + }, + "@octokit/oauth-methods": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@octokit/oauth-methods/-/oauth-methods-2.0.6.tgz", + "integrity": "sha512-l9Uml2iGN2aTWLZcm8hV+neBiFXAQ9+3sKiQe/sgumHlL6HDg0AQ8/l16xX/5jJvfxueqTW5CWbzd0MjnlfHZw==", + "requires": { + "@octokit/oauth-authorization-url": "^5.0.0", + "@octokit/request": "^6.2.3", + "@octokit/request-error": "^3.0.3", + "@octokit/types": "^9.0.0", + "btoa-lite": "^1.0.0" + } + } } }, "@octokit/auth-token": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-3.0.4.tgz", - "integrity": "sha512-TWFX7cZF2LXoCvdmJWY7XVPi74aSY0+FfBZNSXEXFkMpjcqsQwDSYVv5FhRFaI0V1ECnwbz4j59T/G+rXNWaIQ==" + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-4.0.0.tgz", + "integrity": "sha512-tY/msAuJo6ARbK6SPIxZrPBms3xPbfwBrulZe0Wtr/DIY9lje2HeV1uoebShn6mx7SjCHif6EjMvoREj+gZ+SA==" }, "@octokit/auth-unauthenticated": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@octokit/auth-unauthenticated/-/auth-unauthenticated-3.0.5.tgz", - "integrity": "sha512-yH2GPFcjrTvDWPwJWWCh0tPPtTL5SMgivgKPA+6v/XmYN6hGQkAto8JtZibSKOpf8ipmeYhLNWQ2UgW0GYILCw==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@octokit/auth-unauthenticated/-/auth-unauthenticated-4.0.1.tgz", + "integrity": "sha512-sbjeKHnaKMZ0KmodpYXKAEJhsXQNDUzrJgLMQCXFUF5Il5oXMZrq2BCVsDT+VVh428QkEN64RHWUkPafFTMlNQ==", "requires": { - "@octokit/request-error": "^3.0.0", + "@octokit/request-error": "^4.0.0", "@octokit/types": "^9.0.0" + }, + "dependencies": { + "@octokit/request-error": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-4.0.2.tgz", + "integrity": "sha512-uqwUEmZw3x4I9DGYq9fODVAAvcLsPQv97NRycP6syEFu5916M189VnNBW2zANNwqg3OiligNcAey7P0SET843w==", + "requires": { + "@octokit/types": "^10.0.0", + "deprecation": "^2.0.0", + "once": "^1.4.0" + }, + "dependencies": { + "@octokit/types": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-10.0.0.tgz", + "integrity": "sha512-Vm8IddVmhCgU1fxC1eyinpwqzXPEYu0NrYzD3YZjlGjyftdLBTeqNblRC0jmJmgxbJIsQlyogVeGnrNaaMVzIg==", + "requires": { + "@octokit/openapi-types": "^18.0.0" + } + } + } + } } }, "@octokit/core": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@octokit/core/-/core-4.2.1.tgz", - "integrity": "sha512-tEDxFx8E38zF3gT7sSMDrT1tGumDgsw5yPG6BBh/X+5ClIQfMH/Yqocxz1PnHx6CHyF6pxmovUTOfZAUvQ0Lvw==", - "requires": { - "@octokit/auth-token": "^3.0.0", - "@octokit/graphql": "^5.0.0", - "@octokit/request": "^6.0.0", - "@octokit/request-error": "^3.0.0", - "@octokit/types": "^9.0.0", + "version": "5.0.0-beta.3", + "resolved": "https://registry.npmjs.org/@octokit/core/-/core-5.0.0-beta.3.tgz", + "integrity": "sha512-I/4eNh2Our9ZMhSlF9806ChymkwUdpM2DEV+9nMvUK9EjSJqDiCVUP9M6oti0cw0tgYHEFWUWj6VfK40mDIDpw==", + "requires": { + "@octokit/auth-token": "^4.0.0", + "@octokit/graphql": "^6.0.0-beta.2", + "@octokit/request": "^7.0.0", + "@octokit/request-error": "^4.0.1", + "@octokit/types": "^10.0.0", "before-after-hook": "^2.2.0", "universal-user-agent": "^6.0.0" + }, + "dependencies": { + "@octokit/endpoint": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-8.0.1.tgz", + "integrity": "sha512-tVviBdPuf3kcCiIvXYDJg7NAJrkTh8QEnc+UCybknKdEBCjIi7uQbFX3liQrpk1m5PjwC7fUJg08DYZ4F+l1RQ==", + "requires": { + "@octokit/types": "^10.0.0", + "is-plain-object": "^5.0.0", + "universal-user-agent": "^6.0.0" + } + }, + "@octokit/request": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-7.0.0.tgz", + "integrity": "sha512-iUnS9KDsFWfHLwomq/QZmEja8nQZ9FnkMp58+6qz1AKFIBi+sF6w1HGpimRxmmpstFHHGB3eE0qYjuV1Z/Gc3Q==", + "requires": { + "@octokit/endpoint": "^8.0.0", + "@octokit/request-error": "^4.0.1", + "@octokit/types": "^10.0.0", + "is-plain-object": "^5.0.0", + "universal-user-agent": "^6.0.0" + } + }, + "@octokit/request-error": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-4.0.2.tgz", + "integrity": "sha512-uqwUEmZw3x4I9DGYq9fODVAAvcLsPQv97NRycP6syEFu5916M189VnNBW2zANNwqg3OiligNcAey7P0SET843w==", + "requires": { + "@octokit/types": "^10.0.0", + "deprecation": "^2.0.0", + "once": "^1.4.0" + } + }, + "@octokit/types": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-10.0.0.tgz", + "integrity": "sha512-Vm8IddVmhCgU1fxC1eyinpwqzXPEYu0NrYzD3YZjlGjyftdLBTeqNblRC0jmJmgxbJIsQlyogVeGnrNaaMVzIg==", + "requires": { + "@octokit/openapi-types": "^18.0.0" + } + } } }, "@octokit/endpoint": { @@ -8575,30 +8962,114 @@ } }, "@octokit/graphql": { - "version": "5.0.6", - "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-5.0.6.tgz", - "integrity": "sha512-Fxyxdy/JH0MnIB5h+UQ3yCoh1FG4kWXfFKkpWqjZHw/p+Kc8Y44Hu/kCgNBT6nU1shNumEchmW/sUO1JuQnPcw==", + "version": "6.0.0-beta.2", + "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-6.0.0-beta.2.tgz", + "integrity": "sha512-41ujApYqTh4gU1Htyx9s/iQuew8hOtLIbRqlydWPGCfJpSHnTz/BXDqoq/LQWh9KZ7TRM+1/JweRk+EhT0LqnQ==", "requires": { - "@octokit/request": "^6.0.0", - "@octokit/types": "^9.0.0", + "@octokit/request": "^7.0.0", + "@octokit/types": "^10.0.0", "universal-user-agent": "^6.0.0" + }, + "dependencies": { + "@octokit/endpoint": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-8.0.1.tgz", + "integrity": "sha512-tVviBdPuf3kcCiIvXYDJg7NAJrkTh8QEnc+UCybknKdEBCjIi7uQbFX3liQrpk1m5PjwC7fUJg08DYZ4F+l1RQ==", + "requires": { + "@octokit/types": "^10.0.0", + "is-plain-object": "^5.0.0", + "universal-user-agent": "^6.0.0" + } + }, + "@octokit/request": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-7.0.0.tgz", + "integrity": "sha512-iUnS9KDsFWfHLwomq/QZmEja8nQZ9FnkMp58+6qz1AKFIBi+sF6w1HGpimRxmmpstFHHGB3eE0qYjuV1Z/Gc3Q==", + "requires": { + "@octokit/endpoint": "^8.0.0", + "@octokit/request-error": "^4.0.1", + "@octokit/types": "^10.0.0", + "is-plain-object": "^5.0.0", + "universal-user-agent": "^6.0.0" + } + }, + "@octokit/request-error": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-4.0.2.tgz", + "integrity": "sha512-uqwUEmZw3x4I9DGYq9fODVAAvcLsPQv97NRycP6syEFu5916M189VnNBW2zANNwqg3OiligNcAey7P0SET843w==", + "requires": { + "@octokit/types": "^10.0.0", + "deprecation": "^2.0.0", + "once": "^1.4.0" + } + }, + "@octokit/types": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-10.0.0.tgz", + "integrity": "sha512-Vm8IddVmhCgU1fxC1eyinpwqzXPEYu0NrYzD3YZjlGjyftdLBTeqNblRC0jmJmgxbJIsQlyogVeGnrNaaMVzIg==", + "requires": { + "@octokit/openapi-types": "^18.0.0" + } + } } }, "@octokit/oauth-authorization-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@octokit/oauth-authorization-url/-/oauth-authorization-url-5.0.0.tgz", - "integrity": "sha512-y1WhN+ERDZTh0qZ4SR+zotgsQUE1ysKnvBt1hvDRB2WRzYtVKQjn97HEPzoehh66Fj9LwNdlZh+p6TJatT0zzg==" + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@octokit/oauth-authorization-url/-/oauth-authorization-url-6.0.2.tgz", + "integrity": "sha512-CdoJukjXXxqLNK4y/VOiVzQVjibqoj/xHgInekviUJV73y/BSIcwvJ/4aNHPBPKcPWFnd4/lO9uqRV65jXhcLA==" }, "@octokit/oauth-methods": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/@octokit/oauth-methods/-/oauth-methods-2.0.6.tgz", - "integrity": "sha512-l9Uml2iGN2aTWLZcm8hV+neBiFXAQ9+3sKiQe/sgumHlL6HDg0AQ8/l16xX/5jJvfxueqTW5CWbzd0MjnlfHZw==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@octokit/oauth-methods/-/oauth-methods-3.0.1.tgz", + "integrity": "sha512-TIoJQq4BxGueYwGzxmSpCMqbJwCdPaeYYFbZdpA0xtUpDYw0vS1Yr5yzWshuL1sMk3oBJ7zqouWSapd2+PxU9Q==", "requires": { - "@octokit/oauth-authorization-url": "^5.0.0", - "@octokit/request": "^6.2.3", - "@octokit/request-error": "^3.0.3", - "@octokit/types": "^9.0.0", + "@octokit/oauth-authorization-url": "^6.0.2", + "@octokit/request": "^7.0.0", + "@octokit/request-error": "^4.0.1", + "@octokit/types": "^10.0.0", "btoa-lite": "^1.0.0" + }, + "dependencies": { + "@octokit/endpoint": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-8.0.1.tgz", + "integrity": "sha512-tVviBdPuf3kcCiIvXYDJg7NAJrkTh8QEnc+UCybknKdEBCjIi7uQbFX3liQrpk1m5PjwC7fUJg08DYZ4F+l1RQ==", + "requires": { + "@octokit/types": "^10.0.0", + "is-plain-object": "^5.0.0", + "universal-user-agent": "^6.0.0" + } + }, + "@octokit/request": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-7.0.0.tgz", + "integrity": "sha512-iUnS9KDsFWfHLwomq/QZmEja8nQZ9FnkMp58+6qz1AKFIBi+sF6w1HGpimRxmmpstFHHGB3eE0qYjuV1Z/Gc3Q==", + "requires": { + "@octokit/endpoint": "^8.0.0", + "@octokit/request-error": "^4.0.1", + "@octokit/types": "^10.0.0", + "is-plain-object": "^5.0.0", + "universal-user-agent": "^6.0.0" + } + }, + "@octokit/request-error": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-4.0.2.tgz", + "integrity": "sha512-uqwUEmZw3x4I9DGYq9fODVAAvcLsPQv97NRycP6syEFu5916M189VnNBW2zANNwqg3OiligNcAey7P0SET843w==", + "requires": { + "@octokit/types": "^10.0.0", + "deprecation": "^2.0.0", + "once": "^1.4.0" + } + }, + "@octokit/types": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-10.0.0.tgz", + "integrity": "sha512-Vm8IddVmhCgU1fxC1eyinpwqzXPEYu0NrYzD3YZjlGjyftdLBTeqNblRC0jmJmgxbJIsQlyogVeGnrNaaMVzIg==", + "requires": { + "@octokit/openapi-types": "^18.0.0" + } + } } }, "@octokit/openapi-types": { diff --git a/package.json b/package.json index 92dfe4089..c2414ecb7 100644 --- a/package.json +++ b/package.json @@ -20,12 +20,12 @@ "author": "Gregor Martynus (https://twitter.com/gr2m)", "license": "MIT", "dependencies": { - "@octokit/auth-oauth-app": "^5.0.0", - "@octokit/auth-oauth-user": "^2.0.0", - "@octokit/auth-unauthenticated": "^3.0.0", - "@octokit/core": "^4.0.0", - "@octokit/oauth-authorization-url": "^5.0.0", - "@octokit/oauth-methods": "^2.0.0", + "@octokit/auth-oauth-app": "^6.0.0", + "@octokit/auth-oauth-user": "^3.0.0", + "@octokit/auth-unauthenticated": "^4.0.1", + "@octokit/core": "^5.0.0-beta.3", + "@octokit/oauth-authorization-url": "^6.0.2", + "@octokit/oauth-methods": "^3.0.1", "@types/aws-lambda": "^8.10.83", "fromentries": "^1.3.1", "universal-user-agent": "^6.0.0" From 009ef0eeb8b09bdd03956127a44e3d60b3e218a2 Mon Sep 17 00:00:00 2001 From: wolfy1339 Date: Sat, 17 Jun 2023 12:32:13 -0400 Subject: [PATCH 4/5] fix: remove old polyfills Remove `node-fetch` as we only support NodeJS v18+ Remove `fromentries` as support for `Object.fromEntries()` was added in NodeJS v12 --- package-lock.json | 120 ------------------------------- package.json | 3 - src/middleware/handle-request.ts | 4 +- test/deprecations.test.ts | 14 ---- test/web-worker-handler.test.ts | 13 ---- 5 files changed, 1 insertion(+), 153 deletions(-) diff --git a/package-lock.json b/package-lock.json index a6a41d0b2..f550226e6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,21 +16,18 @@ "@octokit/oauth-authorization-url": "^6.0.2", "@octokit/oauth-methods": "^3.0.1", "@types/aws-lambda": "^8.10.83", - "fromentries": "^1.3.1", "universal-user-agent": "^6.0.0" }, "devDependencies": { "@octokit/tsconfig": "^2.0.0", "@types/jest": "^29.0.0", "@types/node": "^18.0.0", - "@types/node-fetch": "^2.5.4", "esbuild": "^0.18.0", "express": "^4.17.1", "fetch-mock": "^9.0.0", "glob": "^10.2.5", "jest": "^29.0.0", "nock": "^13.0.0", - "node-fetch": "^2.6.0", "prettier": "2.8.8", "semantic-release-plugin-update-version-in-files": "^1.0.0", "ts-jest": "^29.0.0", @@ -2327,16 +2324,6 @@ "integrity": "sha512-QAkjjRA1N7gPJeAP4WLXZtYv6+eMXFNviqktCDt4GLcmCugMr5BcRHfkOjCQzvCsnMp+L79a54zBkbw356xv9Q==", "dev": true }, - "node_modules/@types/node-fetch": { - "version": "2.6.4", - "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.4.tgz", - "integrity": "sha512-1ZX9fcN4Rvkvgv4E6PAY5WXUFWFcRWxZa3EW83UjycOB9ljJCedb2CupIP4RZMEwF/M3eTcCihbBRgwtGbg5Rg==", - "dev": true, - "dependencies": { - "@types/node": "*", - "form-data": "^3.0.0" - } - }, "node_modules/@types/prettier": { "version": "2.7.3", "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.3.tgz", @@ -2444,12 +2431,6 @@ "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", "dev": true }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "dev": true - }, "node_modules/babel-jest": { "version": "29.5.0", "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.5.0.tgz", @@ -2971,18 +2952,6 @@ "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", "dev": true }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -3080,15 +3049,6 @@ "node": ">=0.10.0" } }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", @@ -3500,20 +3460,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/form-data": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", - "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", - "dev": true, - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", @@ -3532,25 +3478,6 @@ "node": ">= 0.6" } }, - "node_modules/fromentries": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.3.2.tgz", - "integrity": "sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -9245,16 +9172,6 @@ "integrity": "sha512-QAkjjRA1N7gPJeAP4WLXZtYv6+eMXFNviqktCDt4GLcmCugMr5BcRHfkOjCQzvCsnMp+L79a54zBkbw356xv9Q==", "dev": true }, - "@types/node-fetch": { - "version": "2.6.4", - "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.4.tgz", - "integrity": "sha512-1ZX9fcN4Rvkvgv4E6PAY5WXUFWFcRWxZa3EW83UjycOB9ljJCedb2CupIP4RZMEwF/M3eTcCihbBRgwtGbg5Rg==", - "dev": true, - "requires": { - "@types/node": "*", - "form-data": "^3.0.0" - } - }, "@types/prettier": { "version": "2.7.3", "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.3.tgz", @@ -9341,12 +9258,6 @@ "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", "dev": true }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "dev": true - }, "babel-jest": { "version": "29.5.0", "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.5.0.tgz", @@ -9728,15 +9639,6 @@ "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", "dev": true }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, - "requires": { - "delayed-stream": "~1.0.0" - } - }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -9814,12 +9716,6 @@ "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", "dev": true }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "dev": true - }, "depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", @@ -10137,17 +10033,6 @@ "signal-exit": "^4.0.1" } }, - "form-data": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", - "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", - "dev": true, - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - } - }, "forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", @@ -10160,11 +10045,6 @@ "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", "dev": true }, - "fromentries": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.3.2.tgz", - "integrity": "sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==" - }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", diff --git a/package.json b/package.json index c2414ecb7..d65034f9c 100644 --- a/package.json +++ b/package.json @@ -27,21 +27,18 @@ "@octokit/oauth-authorization-url": "^6.0.2", "@octokit/oauth-methods": "^3.0.1", "@types/aws-lambda": "^8.10.83", - "fromentries": "^1.3.1", "universal-user-agent": "^6.0.0" }, "devDependencies": { "@octokit/tsconfig": "^2.0.0", "@types/jest": "^29.0.0", "@types/node": "^18.0.0", - "@types/node-fetch": "^2.5.4", "esbuild": "^0.18.0", "express": "^4.17.1", "fetch-mock": "^9.0.0", "glob": "^10.2.5", "jest": "^29.0.0", "nock": "^13.0.0", - "node-fetch": "^2.6.0", "prettier": "2.8.8", "semantic-release-plugin-update-version-in-files": "^1.0.0", "ts-jest": "^29.0.0", diff --git a/src/middleware/handle-request.ts b/src/middleware/handle-request.ts index e8f0212e8..12216132f 100644 --- a/src/middleware/handle-request.ts +++ b/src/middleware/handle-request.ts @@ -2,8 +2,6 @@ import { OAuthApp } from "../index"; import { unknownRouteResponse } from "./unknown-route-response"; import type { HandlerOptions, OctokitRequest, OctokitResponse } from "./types"; import type { ClientType, Options } from "../types"; -// @ts-ignore - requires esModuleInterop flag -import fromEntries from "fromentries"; export async function handleRequest( app: OAuthApp>, @@ -65,7 +63,7 @@ export async function handleRequest( }; } const { searchParams } = new URL(request.url as string, "http://localhost"); - const query = fromEntries(searchParams) as { + const query = Object.fromEntries(searchParams) as { state?: string; scopes?: string; code?: string; diff --git a/test/deprecations.test.ts b/test/deprecations.test.ts index 9afaa6400..ca1decb4c 100644 --- a/test/deprecations.test.ts +++ b/test/deprecations.test.ts @@ -1,17 +1,3 @@ -import * as nodeFetch from "node-fetch"; -import fromEntries from "fromentries"; - describe("deprecations", () => { - beforeAll(() => { - Object.fromEntries ||= fromEntries; - (global as any).Request = nodeFetch.Request; - (global as any).Response = nodeFetch.Response; - }); - - afterAll(() => { - delete (global as any).Request; - delete (global as any).Response; - }); - it("has no deprecations currently", async () => {}); }); diff --git a/test/web-worker-handler.test.ts b/test/web-worker-handler.test.ts index 1bab6c7a7..51eaf900b 100644 --- a/test/web-worker-handler.test.ts +++ b/test/web-worker-handler.test.ts @@ -1,20 +1,7 @@ import { URL } from "url"; -import * as nodeFetch from "node-fetch"; -import fromEntries from "fromentries"; import { createWebWorkerHandler, OAuthApp } from "../src"; describe("createWebWorkerHandler(app)", () => { - beforeAll(() => { - Object.fromEntries ||= fromEntries; - (global as any).Request = nodeFetch.Request; - (global as any).Response = nodeFetch.Response; - }); - - afterAll(() => { - delete (global as any).Request; - delete (global as any).Response; - }); - it("support both oauth-app and github-app", () => { const oauthApp = new OAuthApp({ clientType: "oauth-app", From b67213593793349159f27a6d27b2809fd8759301 Mon Sep 17 00:00:00 2001 From: wolfy1339 Date: Sat, 17 Jun 2023 13:16:40 -0400 Subject: [PATCH 5/5] test: switch from `toStrictEqual` to `toMatchObject` --- test/node-middleware.test.ts | 49 +++++---- test/web-worker-handler.test.ts | 171 ++++++++++++++++++-------------- 2 files changed, 119 insertions(+), 101 deletions(-) diff --git a/test/node-middleware.test.ts b/test/node-middleware.test.ts index 620a6afca..89a6e97ef 100644 --- a/test/node-middleware.test.ts +++ b/test/node-middleware.test.ts @@ -1,7 +1,6 @@ import { createServer, IncomingMessage } from "http"; import { URL } from "url"; -import fetch from "node-fetch"; import { createNodeMiddleware, OAuthApp } from "../src/"; // import without types @@ -151,7 +150,7 @@ describe("createNodeMiddleware(app)", () => { expect(await response.text()).toMatch(/token123/); expect(appMock.createToken.mock.calls.length).toEqual(1); - expect(appMock.createToken.mock.calls[0][0]).toStrictEqual({ + expect(appMock.createToken.mock.calls[0][0]).toMatchObject({ code: "012345", }); }); @@ -187,12 +186,12 @@ describe("createNodeMiddleware(app)", () => { server.close(); expect(response.status).toEqual(201); - expect(await response.json()).toStrictEqual({ + expect(await response.json()).toMatchObject({ authentication: { type: "token", tokenType: "oauth" }, }); expect(appMock.createToken.mock.calls.length).toEqual(1); - expect(appMock.createToken.mock.calls[0][0]).toStrictEqual({ + expect(appMock.createToken.mock.calls[0][0]).toMatchObject({ code: "012345", redirectUrl: "http://example.com", }); @@ -228,13 +227,13 @@ describe("createNodeMiddleware(app)", () => { server.close(); expect(response.status).toEqual(200); - expect(await response.json()).toStrictEqual({ + expect(await response.json()).toMatchObject({ data: { id: 1 }, authentication: { type: "token", tokenType: "oauth" }, }); expect(appMock.checkToken.mock.calls.length).toEqual(1); - expect(appMock.checkToken.mock.calls[0][0]).toStrictEqual({ + expect(appMock.checkToken.mock.calls[0][0]).toMatchObject({ token: "token123", }); }); @@ -270,13 +269,13 @@ describe("createNodeMiddleware(app)", () => { server.close(); expect(response.status).toEqual(200); - expect(await response.json()).toStrictEqual({ + expect(await response.json()).toMatchObject({ data: { id: 1 }, authentication: { type: "token", tokenType: "oauth" }, }); expect(appMock.resetToken.mock.calls.length).toEqual(1); - expect(appMock.resetToken.mock.calls[0][0]).toStrictEqual({ + expect(appMock.resetToken.mock.calls[0][0]).toMatchObject({ token: "token123", }); }); @@ -377,14 +376,14 @@ describe("createNodeMiddleware(app)", () => { server.close(); - expect(await response.json()).toStrictEqual({ + expect(await response.json()).toMatchObject({ data: { id: 1 }, authentication: { type: "token", tokenType: "oauth" }, }); expect(response.status).toEqual(200); expect(appMock.refreshToken.mock.calls.length).toEqual(1); - expect(appMock.refreshToken.mock.calls[0][0]).toStrictEqual({ + expect(appMock.refreshToken.mock.calls[0][0]).toMatchObject({ refreshToken: "r1.refreshtoken123", }); }); @@ -419,13 +418,13 @@ describe("createNodeMiddleware(app)", () => { server.close(); expect(response.status).toEqual(200); - expect(await response.json()).toStrictEqual({ + expect(await response.json()).toMatchObject({ data: { id: 1 }, authentication: { type: "token", tokenType: "oauth" }, }); expect(appMock.resetToken.mock.calls.length).toEqual(1); - expect(appMock.resetToken.mock.calls[0][0]).toStrictEqual({ + expect(appMock.resetToken.mock.calls[0][0]).toMatchObject({ token: "token123", }); }); @@ -456,7 +455,7 @@ describe("createNodeMiddleware(app)", () => { expect(response.status).toEqual(204); expect(appMock.deleteToken.mock.calls.length).toEqual(1); - expect(appMock.deleteToken.mock.calls[0][0]).toStrictEqual({ + expect(appMock.deleteToken.mock.calls[0][0]).toMatchObject({ token: "token123", }); }); @@ -487,7 +486,7 @@ describe("createNodeMiddleware(app)", () => { expect(response.status).toEqual(204); expect(appMock.deleteAuthorization.mock.calls.length).toEqual(1); - expect(appMock.deleteAuthorization.mock.calls[0][0]).toStrictEqual({ + expect(appMock.deleteAuthorization.mock.calls[0][0]).toMatchObject({ token: "token123", }); }); @@ -530,7 +529,7 @@ describe("createNodeMiddleware(app)", () => { server.close(); expect(response.status).toEqual(400); - expect(await response.json()).toStrictEqual({ + expect(await response.json()).toMatchObject({ error: '[@octokit/oauth-app] "code" parameter is required', }); }); @@ -551,7 +550,7 @@ describe("createNodeMiddleware(app)", () => { server.close(); expect(response.status).toEqual(400); - expect(await response.json()).toStrictEqual({ + expect(await response.json()).toMatchObject({ error: "[@octokit/oauth-app] redirect_uri_mismatch The redirect_uri MUST match the registered callback URL for this application.", }); @@ -577,7 +576,7 @@ describe("createNodeMiddleware(app)", () => { server.close(); expect(response.status).toEqual(400); - expect(await response.json()).toStrictEqual({ + expect(await response.json()).toMatchObject({ error: '[@octokit/oauth-app] "code" parameter is required', }); }); @@ -602,7 +601,7 @@ describe("createNodeMiddleware(app)", () => { server.close(); expect(response.status).toEqual(400); - expect(await response.json()).toStrictEqual({ + expect(await response.json()).toMatchObject({ error: "[@octokit/oauth-app] request error", }); }); @@ -626,7 +625,7 @@ describe("createNodeMiddleware(app)", () => { server.close(); expect(response.status).toEqual(400); - expect(await response.json()).toStrictEqual({ + expect(await response.json()).toMatchObject({ error: '[@octokit/oauth-app] "Authorization" header is required', }); }); @@ -651,7 +650,7 @@ describe("createNodeMiddleware(app)", () => { server.close(); expect(response.status).toEqual(400); - expect(await response.json()).toStrictEqual({ + expect(await response.json()).toMatchObject({ error: '[@octokit/oauth-app] "Authorization" header is required', }); }); @@ -676,7 +675,7 @@ describe("createNodeMiddleware(app)", () => { server.close(); expect(response.status).toEqual(400); - expect(await response.json()).toStrictEqual({ + expect(await response.json()).toMatchObject({ error: '[@octokit/oauth-app] "Authorization" header is required', }); }); @@ -707,7 +706,7 @@ describe("createNodeMiddleware(app)", () => { server.close(); expect(response.status).toEqual(400); - expect(await response.json()).toStrictEqual({ + expect(await response.json()).toMatchObject({ error: '[@octokit/oauth-app] "Authorization" header is required', }); }); @@ -738,7 +737,7 @@ describe("createNodeMiddleware(app)", () => { server.close(); expect(response.status).toEqual(400); - expect(await response.json()).toStrictEqual({ + expect(await response.json()).toMatchObject({ error: "[@octokit/oauth-app] refreshToken must be sent in request body", }); }); @@ -763,7 +762,7 @@ describe("createNodeMiddleware(app)", () => { server.close(); expect(response.status).toEqual(400); - expect(await response.json()).toStrictEqual({ + expect(await response.json()).toMatchObject({ error: '[@octokit/oauth-app] "Authorization" header is required', }); }); @@ -788,7 +787,7 @@ describe("createNodeMiddleware(app)", () => { server.close(); expect(response.status).toEqual(400); - expect(await response.json()).toStrictEqual({ + expect(await response.json()).toMatchObject({ error: '[@octokit/oauth-app] "Authorization" header is required', }); }); diff --git a/test/web-worker-handler.test.ts b/test/web-worker-handler.test.ts index 51eaf900b..e162a03e9 100644 --- a/test/web-worker-handler.test.ts +++ b/test/web-worker-handler.test.ts @@ -24,7 +24,7 @@ describe("createWebWorkerHandler(app)", () => { clientSecret: "0123secret", }); const handleRequest = createWebWorkerHandler(app); - const request = new Request("/api/github/oauth/token", { + const request = new Request("https://example.com/api/github/oauth/token", { method: "OPTIONS", }); const response = await handleRequest(request); @@ -38,7 +38,7 @@ describe("createWebWorkerHandler(app)", () => { }); const handleRequest = createWebWorkerHandler(app); - const request = new Request("/api/github/oauth/login"); + const request = new Request("https://example.com/api/github/oauth/login"); const { status, headers } = (await handleRequest(request))!; expect(status).toEqual(302); @@ -60,7 +60,7 @@ describe("createWebWorkerHandler(app)", () => { }); const handleRequest = createWebWorkerHandler(app); - const request = new Request("/api/github/oauth/login"); + const request = new Request("https://example.com/api/github/oauth/login"); const { status, headers } = (await handleRequest(request))!; expect(status).toEqual(302); @@ -82,7 +82,7 @@ describe("createWebWorkerHandler(app)", () => { const handleRequest = createWebWorkerHandler(app); const request = new Request( - "/api/github/oauth/login?state=mystate123&scopes=one,two,three" + "https://example.com/api/github/oauth/login?state=mystate123&scopes=one,two,three" ); const { status, headers } = (await handleRequest(request))!; @@ -112,7 +112,7 @@ describe("createWebWorkerHandler(app)", () => { ); const request = new Request( - "/api/github/oauth/callback?code=012345&state=state123" + "https://example.com/api/github/oauth/callback?code=012345&state=state123" ); const response = (await handleRequest(request))!; @@ -120,7 +120,7 @@ describe("createWebWorkerHandler(app)", () => { expect(await response.text()).toMatch(/token123/); expect(appMock.createToken.mock.calls.length).toEqual(1); - expect(appMock.createToken.mock.calls[0][0]).toStrictEqual({ + expect(appMock.createToken.mock.calls[0][0]).toMatchObject({ code: "012345", }); }); @@ -139,7 +139,7 @@ describe("createWebWorkerHandler(app)", () => { appMock as unknown as OAuthApp ); - const request = new Request("/api/github/oauth/token", { + const request = new Request("https://example.com/api/github/oauth/token", { method: "POST", body: JSON.stringify({ code: "012345", @@ -149,12 +149,12 @@ describe("createWebWorkerHandler(app)", () => { const response = (await handleRequest(request))!; expect(response.status).toEqual(201); - expect(await response.json()).toStrictEqual({ + expect(await response.json()).toMatchObject({ authentication: { type: "token", tokenType: "oauth" }, }); expect(appMock.createToken.mock.calls.length).toEqual(1); - expect(appMock.createToken.mock.calls[0][0]).toStrictEqual({ + expect(appMock.createToken.mock.calls[0][0]).toMatchObject({ code: "012345", redirectUrl: "http://example.com", }); @@ -175,7 +175,7 @@ describe("createWebWorkerHandler(app)", () => { appMock as unknown as OAuthApp ); - const request = new Request("/api/github/oauth/token", { + const request = new Request("https://example.com/api/github/oauth/token", { headers: { authorization: "token token123", }, @@ -183,13 +183,13 @@ describe("createWebWorkerHandler(app)", () => { const response = (await handleRequest(request))!; expect(response.status).toEqual(200); - expect(await response.json()).toStrictEqual({ + expect(await response.json()).toMatchObject({ data: { id: 1 }, authentication: { type: "token", tokenType: "oauth" }, }); expect(appMock.checkToken.mock.calls.length).toEqual(1); - expect(appMock.checkToken.mock.calls[0][0]).toStrictEqual({ + expect(appMock.checkToken.mock.calls[0][0]).toMatchObject({ token: "token123", }); }); @@ -209,20 +209,20 @@ describe("createWebWorkerHandler(app)", () => { appMock as unknown as OAuthApp ); - const request = new Request("/api/github/oauth/token", { + const request = new Request("https://example.com/api/github/oauth/token", { method: "PATCH", headers: { authorization: "token token123" }, }); const response = (await handleRequest(request))!; expect(response.status).toEqual(200); - expect(await response.json()).toStrictEqual({ + expect(await response.json()).toMatchObject({ data: { id: 1 }, authentication: { type: "token", tokenType: "oauth" }, }); expect(appMock.resetToken.mock.calls.length).toEqual(1); - expect(appMock.resetToken.mock.calls[0][0]).toStrictEqual({ + expect(appMock.resetToken.mock.calls[0][0]).toMatchObject({ token: "token123", }); }); @@ -242,15 +242,18 @@ describe("createWebWorkerHandler(app)", () => { appMock as unknown as OAuthApp ); - const request = new Request("/api/github/oauth/token/scoped", { - method: "POST", - headers: { authorization: "token token123" }, - body: JSON.stringify({ - target: "octokit", - repositories: ["oauth-methods.js"], - permissions: { issues: "write" }, - }), - }); + const request = new Request( + "https://example.com/api/github/oauth/token/scoped", + { + method: "POST", + headers: { authorization: "token token123" }, + body: JSON.stringify({ + target: "octokit", + repositories: ["oauth-methods.js"], + permissions: { issues: "write" }, + }), + } + ); const response = (await handleRequest(request))!; expect(response.status).toEqual(200); @@ -297,21 +300,24 @@ describe("createWebWorkerHandler(app)", () => { appMock as unknown as OAuthApp ); - const request = new Request("/api/github/oauth/refresh-token", { - method: "PATCH", - headers: { authorization: "token token123" }, - body: JSON.stringify({ refreshToken: "r1.refreshtoken123" }), - }); + const request = new Request( + "https://example.com/api/github/oauth/refresh-token", + { + method: "PATCH", + headers: { authorization: "token token123" }, + body: JSON.stringify({ refreshToken: "r1.refreshtoken123" }), + } + ); const response = (await handleRequest(request))!; - expect(await response.json()).toStrictEqual({ + expect(await response.json()).toMatchObject({ data: { id: 1 }, authentication: { type: "token", tokenType: "oauth" }, }); expect(response.status).toEqual(200); expect(appMock.refreshToken.mock.calls.length).toEqual(1); - expect(appMock.refreshToken.mock.calls[0][0]).toStrictEqual({ + expect(appMock.refreshToken.mock.calls[0][0]).toMatchObject({ refreshToken: "r1.refreshtoken123", }); }); @@ -331,20 +337,20 @@ describe("createWebWorkerHandler(app)", () => { appMock as unknown as OAuthApp ); - const request = new Request("/api/github/oauth/token", { + const request = new Request("https://example.com/api/github/oauth/token", { method: "PATCH", headers: { authorization: "token token123" }, }); const response = (await handleRequest(request))!; expect(response.status).toEqual(200); - expect(await response.json()).toStrictEqual({ + expect(await response.json()).toMatchObject({ data: { id: 1 }, authentication: { type: "token", tokenType: "oauth" }, }); expect(appMock.resetToken.mock.calls.length).toEqual(1); - expect(appMock.resetToken.mock.calls[0][0]).toStrictEqual({ + expect(appMock.resetToken.mock.calls[0][0]).toMatchObject({ token: "token123", }); }); @@ -357,7 +363,7 @@ describe("createWebWorkerHandler(app)", () => { appMock as unknown as OAuthApp ); - const request = new Request("/api/github/oauth/token", { + const request = new Request("https://example.com/api/github/oauth/token", { method: "DELETE", headers: { authorization: "token token123" }, }); @@ -366,7 +372,7 @@ describe("createWebWorkerHandler(app)", () => { expect(response.status).toEqual(204); expect(appMock.deleteToken.mock.calls.length).toEqual(1); - expect(appMock.deleteToken.mock.calls[0][0]).toStrictEqual({ + expect(appMock.deleteToken.mock.calls[0][0]).toMatchObject({ token: "token123", }); }); @@ -379,7 +385,7 @@ describe("createWebWorkerHandler(app)", () => { appMock as unknown as OAuthApp ); - const request = new Request("/api/github/oauth/grant", { + const request = new Request("https://example.com/api/github/oauth/grant", { method: "DELETE", headers: { authorization: "token token123" }, }); @@ -388,7 +394,7 @@ describe("createWebWorkerHandler(app)", () => { expect(response.status).toEqual(204); expect(appMock.deleteAuthorization.mock.calls.length).toEqual(1); - expect(appMock.deleteAuthorization.mock.calls[0][0]).toStrictEqual({ + expect(appMock.deleteAuthorization.mock.calls[0][0]).toMatchObject({ token: "token123", }); }); @@ -400,7 +406,7 @@ describe("createWebWorkerHandler(app)", () => { }); const handleRequest = createWebWorkerHandler(app); - const request = new Request("/unrelated", { + const request = new Request("https://example.com/unrelated", { method: "POST", body: JSON.stringify({ ok: true }), headers: { @@ -420,7 +426,7 @@ describe("createWebWorkerHandler(app)", () => { appMock as unknown as OAuthApp ); - const request = new Request("/unknown"); + const request = new Request("https://some.tld/unknown"); const response = (await handleRequest(request))!; expect(response).toBeUndefined(); }); @@ -431,11 +437,13 @@ describe("createWebWorkerHandler(app)", () => { appMock as unknown as OAuthApp ); - const request = new Request("/api/github/oauth/callback"); + const request = new Request( + "https://example.com/api/github/oauth/callback" + ); const response = (await handleRequest(request))!; expect(response.status).toEqual(400); - expect(await response.json()).toStrictEqual({ + expect(await response.json()).toMatchObject({ error: '[@octokit/oauth-app] "code" parameter is required', }); }); @@ -447,12 +455,12 @@ describe("createWebWorkerHandler(app)", () => { ); const request = new Request( - "/api/github/oauth/callback?error=redirect_uri_mismatch&error_description=The+redirect_uri+MUST+match+the+registered+callback+URL+for+this+application.&error_uri=https://docs.github.com/en/developers/apps/troubleshooting-authorization-request-errors/%23redirect-uri-mismatch&state=xyz" + "https://example.com/api/github/oauth/callback?error=redirect_uri_mismatch&error_description=The+redirect_uri+MUST+match+the+registered+callback+URL+for+this+application.&error_uri=https://docs.github.com/en/developers/apps/troubleshooting-authorization-request-errors/%23redirect-uri-mismatch&state=xyz" ); const response = (await handleRequest(request))!; expect(response.status).toEqual(400); - expect(await response.json()).toStrictEqual({ + expect(await response.json()).toMatchObject({ error: "[@octokit/oauth-app] redirect_uri_mismatch The redirect_uri MUST match the registered callback URL for this application.", }); @@ -464,14 +472,14 @@ describe("createWebWorkerHandler(app)", () => { appMock as unknown as OAuthApp ); - const request = new Request("/api/github/oauth/token", { + const request = new Request("https://example.com/api/github/oauth/token", { method: "POST", body: JSON.stringify({}), }); const response = (await handleRequest(request))!; expect(response.status).toEqual(400); - expect(await response.json()).toStrictEqual({ + expect(await response.json()).toMatchObject({ error: '[@octokit/oauth-app] "code" parameter is required', }); }); @@ -482,14 +490,14 @@ describe("createWebWorkerHandler(app)", () => { appMock as unknown as OAuthApp ); - const request = new Request("/api/github/oauth/token", { + const request = new Request("https://example.com/api/github/oauth/token", { method: "POST", body: "foo", }); const response = (await handleRequest(request))!; expect(response.status).toEqual(400); - expect(await response.json()).toStrictEqual({ + expect(await response.json()).toMatchObject({ error: "[@octokit/oauth-app] request error", }); }); @@ -500,13 +508,13 @@ describe("createWebWorkerHandler(app)", () => { appMock as unknown as OAuthApp ); - const request = new Request("/api/github/oauth/token", { + const request = new Request("https://example.com/api/github/oauth/token", { headers: {}, }); const response = (await handleRequest(request))!; expect(response.status).toEqual(400); - expect(await response.json()).toStrictEqual({ + expect(await response.json()).toMatchObject({ error: '[@octokit/oauth-app] "Authorization" header is required', }); }); @@ -517,14 +525,14 @@ describe("createWebWorkerHandler(app)", () => { appMock as unknown as OAuthApp ); - const request = new Request("/api/github/oauth/token", { + const request = new Request("https://example.com/api/github/oauth/token", { method: "PATCH", headers: {}, }); const response = (await handleRequest(request))!; expect(response.status).toEqual(400); - expect(await response.json()).toStrictEqual({ + expect(await response.json()).toMatchObject({ error: '[@octokit/oauth-app] "Authorization" header is required', }); }); @@ -535,14 +543,17 @@ describe("createWebWorkerHandler(app)", () => { appMock as unknown as OAuthApp ); - const request = new Request("/api/github/oauth/token/scoped", { - method: "POST", - headers: {}, - }); + const request = new Request( + "https://example.com/api/github/oauth/token/scoped", + { + method: "POST", + headers: {}, + } + ); const response = (await handleRequest(request))!; expect(response.status).toEqual(400); - expect(await response.json()).toStrictEqual({ + expect(await response.json()).toMatchObject({ error: '[@octokit/oauth-app] "Authorization" header is required', }); }); @@ -557,16 +568,19 @@ describe("createWebWorkerHandler(app)", () => { appMock as unknown as OAuthApp ); - const request = new Request("/api/github/oauth/refresh-token", { - method: "PATCH", - body: JSON.stringify({ - refreshToken: "r1.refreshtoken123", - }), - }); + const request = new Request( + "https://example.com/api/github/oauth/refresh-token", + { + method: "PATCH", + body: JSON.stringify({ + refreshToken: "r1.refreshtoken123", + }), + } + ); const response = (await handleRequest(request))!; expect(response.status).toEqual(400); - expect(await response.json()).toStrictEqual({ + expect(await response.json()).toMatchObject({ error: '[@octokit/oauth-app] "Authorization" header is required', }); }); @@ -581,16 +595,19 @@ describe("createWebWorkerHandler(app)", () => { appMock as unknown as OAuthApp ); - const request = new Request("/api/github/oauth/refresh-token", { - method: "PATCH", - headers: { - authorization: "token token123", - }, - }); + const request = new Request( + "https://example.com/api/github/oauth/refresh-token", + { + method: "PATCH", + headers: { + authorization: "token token123", + }, + } + ); const response = (await handleRequest(request))!; expect(response.status).toEqual(400); - expect(await response.json()).toStrictEqual({ + expect(await response.json()).toMatchObject({ error: "[@octokit/oauth-app] refreshToken must be sent in request body", }); }); @@ -601,14 +618,14 @@ describe("createWebWorkerHandler(app)", () => { appMock as unknown as OAuthApp ); - const request = new Request("/api/github/oauth/token", { + const request = new Request("https://example.com/api/github/oauth/token", { method: "DELETE", headers: {}, }); const response = (await handleRequest(request))!; expect(response.status).toEqual(400); - expect(await response.json()).toStrictEqual({ + expect(await response.json()).toMatchObject({ error: '[@octokit/oauth-app] "Authorization" header is required', }); }); @@ -619,14 +636,14 @@ describe("createWebWorkerHandler(app)", () => { appMock as unknown as OAuthApp ); - const request = new Request("/api/github/oauth/grant", { + const request = new Request("https://example.com/api/github/oauth/grant", { method: "DELETE", headers: {}, }); const response = (await handleRequest(request))!; expect(response.status).toEqual(400); - expect(await response.json()).toStrictEqual({ + expect(await response.json()).toMatchObject({ error: '[@octokit/oauth-app] "Authorization" header is required', }); }); @@ -640,7 +657,9 @@ describe("createWebWorkerHandler(app)", () => { { pathPrefix: "/test" } ); - const request = new Request("/test/login", { redirect: "manual" }); + const request = new Request("https://example.com/test/login", { + redirect: "manual", + }); const { status } = (await handleRequest(request))!; expect(status).toEqual(302);