#3067·crystal

Next.js 适配器

作者: benjie创建于 2026年6月17日更新于 2026年6月29日
标签✨ feature

function getDigest(req: NextApiRequest, res: NextApiResponse): RequestDigest { return { httpVersionMajor: req.httpVersionMajor, httpVersionMinor: req.httpVersionMinor, isSecure: "encrypted" in req.socket ? !!req.socket.encrypted : false, method: req.method!, path: req.url!, headers: processHeaders(req.headers), getQueryParams() { return req.query as Record<string, string | string[]>; }, async getBody() { const body = req.body; if (Buffer.isBuffer(body)) { return { type: "buffer", buffer: body, } as GrafservBodyBuffer; } else if (typeof body === "object" && body !== null) { return { type: "json", json: body, } as GrafservBodyJSON; } else { throw new Error("Failed to retrieve body from next"); } }, requestContext: { nextv16: { req, res, }, }, }; }

export class NextGrafserv extends GrafservBase { constructor(config: GrafservConfig) { super(config); }

public async send( req: NextApiRequest, res: NextApiResponse, result: Result | null, ) { if (result === null) { return res.status(404).send("¯\(ツ)/¯"); }

switch (result.type) {
  case "error": {
    const { statusCode, headers } = result;
    res
      .setHeaders(new Map(Object.entries(headers)))
      .status(statusCode)
      .json({ errors: [result.error] });
    return;
  }
  case "buffer": {
    const { statusCode, headers, buffer } = result;
    res
      .setHeaders(new Map(Object.entries(headers)))
      .status(statusCode)
      .send(buffer);
    return;
  }
  case "json": {
    const { statusCode, headers, json } = result;
    res
      .setHeaders(new Map(Object.entries(headers)))
      .status(statusCode)
      .json(json);
    return;
  }
  case "stream": {
    const { statusCode, headers, stream } = result;
    res
      .setHeaders(new Map(Object.entries(headers)))
      .status(statusCode)
      .send(stream);
    return;
  }
  default: {
    throw new Error("Unsupported result type");
  }
}

} }

内容来源: graphile/crystal