From c956a65ab80b3b4e8e606c74788fdaceb6e1a9da Mon Sep 17 00:00:00 2001 From: Adam Mcgrath Date: Fri, 28 Jul 2023 15:22:09 +0100 Subject: [PATCH 1/3] Fix auth handler types when using custom handlers --- src/handlers/auth.ts | 4 ++-- src/handlers/router-helpers.ts | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/handlers/auth.ts b/src/handlers/auth.ts index 26919b61c..36c6fd9d0 100644 --- a/src/handlers/auth.ts +++ b/src/handlers/auth.ts @@ -5,7 +5,7 @@ import { HandleLogout } from './logout'; import { HandleCallback } from './callback'; import { HandleProfile } from './profile'; import { HandlerError } from '../utils/errors'; -import { AppRouteHandlerFn, AppRouteHandlerFnContext, Handler } from './router-helpers'; +import { AppRouteHandlerFn, AppRouteHandlerFnContext, AppRouterHandler, PageRouterHandler } from './router-helpers'; import { isRequest } from '../utils/req-helpers'; /** @@ -66,7 +66,7 @@ export type Handlers = ApiHandlers | ErrorHandlers; /** * @ignore */ -type ApiHandlers = { [key: string]: Handler }; +type ApiHandlers = { [key: string]: PageRouterHandler | AppRouterHandler }; /** * @ignore diff --git a/src/handlers/router-helpers.ts b/src/handlers/router-helpers.ts index ff36aa671..fa47800f3 100644 --- a/src/handlers/router-helpers.ts +++ b/src/handlers/router-helpers.ts @@ -47,6 +47,9 @@ export type AuthHandler = Handler & { (options?: Opts): Handler; }; +export type PageRouterHandler = (req: NextRequest, ctx: AppRouteHandlerFnContext) => Promise | Response; +export type AppRouterHandler = (req: NextApiRequest, res: NextApiResponse) => Promise | unknown; + export type Handler = { (req: NextRequest, ctx: AppRouteHandlerFnContext, options?: Opts): Promise | Response; (req: NextApiRequest, res: NextApiResponse, options?: Opts): Promise | unknown; From 78a336e65358ffccc6c72978dada3ce76fb6a32f Mon Sep 17 00:00:00 2001 From: Adam Mcgrath Date: Fri, 28 Jul 2023 17:02:20 +0100 Subject: [PATCH 2/3] Fix withPageAuthReq app router types and add tests --- package-lock.json | 16 +++++++ package.json | 1 + src/helpers/with-page-auth-required.ts | 2 +- src/shared.ts | 3 +- tests/types.test.tsx | 64 ++++++++++++++++++++++++++ 5 files changed, 84 insertions(+), 2 deletions(-) create mode 100644 tests/types.test.tsx diff --git a/package-lock.json b/package-lock.json index 0ab38d681..95e70196b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -51,6 +51,7 @@ "eslint-plugin-prettier": "^3.3.1", "eslint-plugin-react": "^7.22.0", "eslint-plugin-react-hooks": "^4.2.0", + "expect-type": "^0.16.0", "jest": "^29.5.0", "jest-environment-jsdom": "^29.5.0", "jest-environment-node-single-context": "^27.3.0", @@ -6321,6 +6322,15 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/expect-type": { + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-0.16.0.tgz", + "integrity": "sha512-wCpFeVBiAPGiYkQZzaqvGuuBnNCHbtnowMOBpBGY8a27XbG8VAit3lklWph1r8VmgsH61mOZqI3NuGm8bZnUlw==", + "dev": true, + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/expect/node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -19641,6 +19651,12 @@ } } }, + "expect-type": { + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-0.16.0.tgz", + "integrity": "sha512-wCpFeVBiAPGiYkQZzaqvGuuBnNCHbtnowMOBpBGY8a27XbG8VAit3lklWph1r8VmgsH61mOZqI3NuGm8bZnUlw==", + "dev": true + }, "extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", diff --git a/package.json b/package.json index f0cbd4969..a2aa8e2fd 100644 --- a/package.json +++ b/package.json @@ -99,6 +99,7 @@ "eslint-plugin-prettier": "^3.3.1", "eslint-plugin-react": "^7.22.0", "eslint-plugin-react-hooks": "^4.2.0", + "expect-type": "^0.16.0", "jest": "^29.5.0", "jest-environment-jsdom": "^29.5.0", "jest-environment-node-single-context": "^27.3.0", diff --git a/src/helpers/with-page-auth-required.ts b/src/helpers/with-page-auth-required.ts index b5061e38a..54716978a 100644 --- a/src/helpers/with-page-auth-required.ts +++ b/src/helpers/with-page-auth-required.ts @@ -39,7 +39,7 @@ export type PageRoute = ( * @category Server */ export type AppRouterPageRouteOpts = { - params?: { slug: string }; + params?: Record; searchParams?: { [key: string]: string | string[] | undefined }; }; diff --git a/src/shared.ts b/src/shared.ts index 2bf7aa76a..1668303ea 100644 --- a/src/shared.ts +++ b/src/shared.ts @@ -106,7 +106,8 @@ export { AfterRefetchPageRoute, AfterRefetchAppRoute, AppRouterOnError, - PageRouterOnError + PageRouterOnError, + AppRouteHandlerFnContext } from './handlers'; export { diff --git a/tests/types.test.tsx b/tests/types.test.tsx new file mode 100644 index 000000000..70f0dc892 --- /dev/null +++ b/tests/types.test.tsx @@ -0,0 +1,64 @@ +import React from 'react'; +import { NextApiRequest, NextApiResponse } from 'next'; +import { NextRequest, NextResponse } from 'next/server'; +import { expectTypeOf } from 'expect-type'; +import { handleAuth, HandlerError, AppRouteHandlerFnContext, withPageAuthRequired } from '../src'; + +describe('types', () => { + test('should allow customisation of page router auth handlers', () => { + expectTypeOf(handleAuth).toBeCallableWith({ + login(_req: NextApiRequest, _res: NextApiResponse) {} + }); + }); + + test('should allow customisation of page router error handler', () => { + expectTypeOf(handleAuth).toBeCallableWith({ + onError(_req: NextApiRequest, _res: NextApiResponse, _err: HandlerError) {} + }); + }); + + test('should allow customisation of app router auth handlers', () => { + expectTypeOf(handleAuth).toBeCallableWith({ + login(_req: NextRequest) { + return new NextResponse(); + } + }); + }); + + test('should allow customisation of app router auth handlers with context', () => { + expectTypeOf(handleAuth).toBeCallableWith({ + login(_req: NextRequest, _ctx: AppRouteHandlerFnContext) { + return new NextResponse(); + } + }); + }); + + test('should allow customisation of app router auth handlers with context literal', () => { + expectTypeOf(handleAuth).toBeCallableWith({ + login(_req: NextRequest, _ctx: { params: Record }) { + return new NextResponse(); + } + }); + }); + + test('should allow withPageAuthRequired in app router', () => { + async function Page() { + return Foo; + } + expectTypeOf(withPageAuthRequired).toBeCallableWith(Page); + }); + + test('should allow withPageAuthRequired in app router with opts', () => { + async function Page() { + return Foo; + } + expectTypeOf(withPageAuthRequired).toBeCallableWith(Page, { returnTo: 'foo' }); + }); + + test('should allow custom params in withPageAuthRequired', () => { + async function Page({ params }: { params?: Record }) { + return {typeof params}; + } + expectTypeOf(withPageAuthRequired).toBeCallableWith(Page); + }); +}); From df968ea964f4049b3d01466d6938adbbe63b3869 Mon Sep 17 00:00:00 2001 From: Adam Mcgrath Date: Fri, 28 Jul 2023 17:13:24 +0100 Subject: [PATCH 3/3] Export Next primitives --- src/handlers/index.ts | 3 +-- src/shared.ts | 4 +++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/handlers/index.ts b/src/handlers/index.ts index 22f8b8a29..a86819c06 100644 --- a/src/handlers/index.ts +++ b/src/handlers/index.ts @@ -24,5 +24,4 @@ export { AfterRefetchAppRoute } from './profile'; export { default as handlerFactory, Handlers, HandleAuth, AppRouterOnError, PageRouterOnError } from './auth'; -export { AppRouteHandlerFn } from './router-helpers'; -export { AppRouteHandlerFnContext } from './router-helpers'; +export { AppRouteHandlerFnContext, PageRouterHandler, AppRouterHandler } from './router-helpers'; diff --git a/src/shared.ts b/src/shared.ts index 1668303ea..c000f207d 100644 --- a/src/shared.ts +++ b/src/shared.ts @@ -107,7 +107,9 @@ export { AfterRefetchAppRoute, AppRouterOnError, PageRouterOnError, - AppRouteHandlerFnContext + AppRouteHandlerFnContext, + AppRouterHandler, + PageRouterHandler } from './handlers'; export {