NextJS 路由处理程序上的 ParamCheck 类型错误

问题描述 投票:0回答:1
  1. 我有一个使用 App Router 的 NextJS 13.4 应用程序。
  2. 我有一个用于检索个人资料信息的路线处理程序 (
    /api/me
    )。
  3. 路由处理程序受 Auth0 的
    withApiAuthRequired()
    功能保护。
  4. 当我在开发模式下运行应用程序时,端点按预期工作(
    yarn dev
    ),但是:
  5. 生产构建失败 (
    yarn build
    ),并出现以下错误。

构建错误

.next/types/app/api/me/route.ts:32:7
Type error: Type '{ __tag__: "GET"; __param_position__: "first"; __param_type__: NextApiRequest; }' does not satisfy the constraint 'ParamCheck<NextRequest | Request>'.
  Types of property '__param_type__' are incompatible.
    Type 'NextApiRequest' is not assignable to type 'NextRequest | Request'.
      Type 'NextApiRequest' is missing the following properties from type 'NextRequest': geo, ip, nextUrl, page, and 19 more.

  30 |     Diff<
  31 |       ParamCheck<Request | NextRequest>,
> 32 |       {
     |       ^
  33 |         __tag__: 'GET'
  34 |         __param_position__: 'first'
  35 |         __param_type__: FirstArg<MaybeField<TEntry, 'GET'>>
error Command failed with exit code 1.

路线处理程序

// ~/src/app/api/me/route.ts

import { getSession, withApiAuthRequired } from '@auth0/nextjs-auth0';
import { firebaseApp } from '@muze/lib/firebase';
import { getFirestore } from 'firebase-admin/firestore';
import { getDownloadURL, getStorage } from 'firebase-admin/storage';
import { NextApiHandler, NextApiRequest, NextApiResponse } from 'next';

const GET: NextApiHandler = withApiAuthRequired(
  async (req: NextApiRequest, res: NextApiResponse) => {
    const session = await getSession();

    if (!!session && !!firebaseApp) {
      // Auth0
      const auth0User = session.user;

      // Firebase Firestore
      const db = getFirestore(firebaseApp);

      const firebaseUser = await db
        .collection('users')
        .where('email', '==', auth0User.email)
        .get();

      const firebaseUserData = firebaseUser.docs.map((user) => user.data());

      // Firebase Storage
      const storage = getStorage();
      const fileRef = storage
        .bucket()
        .file(`users/${auth0User.email}/kitmasked.png`);
      const fileUrl = await getDownloadURL(fileRef);

      // return res.end();
      return res.status(200).json({
        idNickname: auth0User.nickname,
        idName: auth0User.name,
        idPicture: auth0User.picture,
        idUpdatedAt: auth0User.updated_at,
        idEmail: auth0User.email,
        idEmailVerified: auth0User.email_verified,
        profileJoined: firebaseUserData[0].joined,
        profileEmail: firebaseUserData[0].email,
        profileUsername: firebaseUserData[0].username,
        profileImageUrl: fileUrl,
      });
    }
  }
);

export { GET };

我正在使用:

  1. "next": "^13.4.6"
  2. "@auth0/nextjs-auth0": "^3.0.1"
  3. "@auth0/auth0-react": "^2.2.0"

显然,路由处理程序的参数是

NextApiRequest
NextApiResponse
,而不是
NextRequest
NextResponse
,但我不知道为什么路由被编译为包含这个
ParamCheck
NextRequest | Request
作为输入参数。

那么:为什么会发生这种情况?我是否错误地构建了处理程序?

我尝试过的事情

我尝试更改参数类型,但

withApiAuthRequired()
不接受其他类型的处理程序。

我不想将 api 移至

pages
文件夹并同时使用页面路由器和应用程序路由器。

我已经看到了一些解决方法,涉及创建一个包含

NextApiRequest
NextRequest
的“超级类型”,但这感觉就像一个黑客。我想了解为什么会发生这种情况并按预期使用这些工具。我不想让它正常工作。

typescript auth0 next.js13
1个回答
0
投票

我仍然没有弄清楚如何更改 ParamCheck,但经过更多研究,我的理解是,如果您还使用

withApiAuthRequired()
钩子并需要有效的会话,那么使用
getSession()
是多余的。所以我刚刚删除了
withApiAuthRequired()
并分别使用
NextRequest
NextResponse
代替
NextApiRequest
NextApiResponse

import { getSession } from '@auth0/nextjs-auth0';
import { firebaseApp } from '@muze/lib/firebase';
import { getFirestore } from 'firebase-admin/firestore';
import { getDownloadURL, getStorage } from 'firebase-admin/storage';
import { NextRequest, NextResponse } from 'next/server';

const GET = async (req: NextRequest, res: NextResponse) => {
  const session = await getSession();

  if (!!session && !!firebaseApp) {
    // Auth0
    const auth0User = session.user;

    // Firebase Firestore
    const db = getFirestore(firebaseApp);

    const firebaseUser = await db
      .collection('users')
      .where('email', '==', auth0User.email)
      .get();

    const firebaseUserData = firebaseUser.docs.map((user) => user.data());

    // Firebase Storage
    const storage = getStorage();
    const fileRef = storage
      .bucket()
      .file(`users/${auth0User.email}/profile.png`);
    const fileUrl = await getDownloadURL(fileRef);

    // return res.end();
    return NextResponse.json({
      idNickname: auth0User.nickname,
      idName: auth0User.name,
      idPicture: auth0User.picture,
      idUpdatedAt: auth0User.updated_at,
      idEmail: auth0User.email,
      idEmailVerified: auth0User.email_verified,
      profileJoined: firebaseUserData[0].joined,
      profileEmail: firebaseUserData[0].email,
      profileUsername: firebaseUserData[0].username,
      profileImageUrl: fileUrl,
    });
  }
};

export { GET };
© www.soinside.com 2019 - 2024. All rights reserved.