feat: switch TRPC router to edge

This commit is contained in:
Henry
2024-04-27 17:02:02 +01:00
parent d15870118d
commit 0035aa6500
6 changed files with 63 additions and 31 deletions

BIN
bun.lockb

Binary file not shown.

View File

@@ -16,6 +16,7 @@
"src/email" "src/email"
], ],
"dependencies": { "dependencies": {
"@edge-runtime/cookies": "^4.1.1",
"@headlessui/react": "^1.7.17", "@headlessui/react": "^1.7.17",
"@react-email/render": "^0.0.10", "@react-email/render": "^0.0.10",
"@supabase/ssr": "^0.3.0", "@supabase/ssr": "^0.3.0",

View File

@@ -1,7 +1,7 @@
import { type EmailOtpType } from "@supabase/supabase-js"; import { type EmailOtpType } from "@supabase/supabase-js";
import type { NextApiRequest, NextApiResponse } from "next"; import type { NextApiRequest, NextApiResponse } from "next";
import createClient from "~/utils/supabase/api"; import { createNextClient } from "~/utils/supabase/api";
function stringOrFirstString(item: string | string[] | undefined) { function stringOrFirstString(item: string | string[] | undefined) {
return Array.isArray(item) ? item[0] : item; return Array.isArray(item) ? item[0] : item;
@@ -23,7 +23,7 @@ export default async function handler(
let next = "/error"; let next = "/error";
if (token_hash && type) { if (token_hash && type) {
const supabase = createClient(req, res); const supabase = createNextClient(req, res);
const { error } = await supabase.auth.verifyOtp({ const { error } = await supabase.auth.verifyOtp({
type: type as EmailOtpType, type: type as EmailOtpType,
token_hash, token_hash,
@@ -37,3 +37,7 @@ export default async function handler(
res.redirect(next); res.redirect(next);
} }
// export const runtime = "edge";
// export const preferredRegion = "lhr1";
// export const dynamic = "force-dynamic";

View File

@@ -1,27 +1,27 @@
import { type NextApiRequest, type NextApiResponse } from "next"; import { type NextRequest } from "next/server";
import { createNextApiHandler } from "@trpc/server/adapters/next"; import { fetchRequestHandler } from "@trpc/server/adapters/fetch";
import { env } from "~/env.mjs"; import { env } from "~/env.mjs";
import { appRouter } from "~/server/api/root"; import { appRouter } from "~/server/api/root";
import { createTRPCContext } from "~/server/api/trpc"; import { createTRPCContext } from "~/server/api/trpc";
const nextApiHandler = createNextApiHandler({ export default async function handler(req: NextRequest) {
router: appRouter, return fetchRequestHandler({
createContext: createTRPCContext, endpoint: "/api/trpc",
onError: router: appRouter,
env.NODE_ENV === "development" req,
? ({ path, error }) => { createContext: createTRPCContext,
console.error( onError:
`❌ tRPC failed on ${path ?? "<no-path>"}: ${error.message}`, env.NODE_ENV === "development"
); ? ({ path, error }) => {
} console.error(
: undefined, `❌ tRPC failed on ${path ?? "<no-path>"}: ${error.message}`,
}); );
}
export default function handler(req: NextApiRequest, res: NextApiResponse) { : undefined,
return nextApiHandler(req, res); });
} }
// export const runtime = "edge"; export const runtime = "edge";
// export const preferredRegion = 'lhr1'; export const preferredRegion = "lhr1";
// export const dynamic = 'force-dynamic' export const dynamic = "force-dynamic";

View File

@@ -7,11 +7,11 @@
* need to use are documented accordingly near the end. * need to use are documented accordingly near the end.
*/ */
import { initTRPC, TRPCError } from "@trpc/server"; import { initTRPC, TRPCError } from "@trpc/server";
import { type CreateNextContextOptions } from "@trpc/server/adapters/next"; import { type FetchCreateContextFnOptions } from "@trpc/server/adapters/fetch";
import superjson from "superjson"; import superjson from "superjson";
import { ZodError } from "zod"; import { ZodError } from "zod";
import createClient from "~/utils/supabase/api"; import { createTRPCClient } from "~/utils/supabase/api";
import { type Database } from "~/types/database.types"; import { type Database } from "~/types/database.types";
import { type SupabaseClient } from "@supabase/supabase-js"; import { type SupabaseClient } from "@supabase/supabase-js";
@@ -56,8 +56,11 @@ export const createInnerTRPCContext = (opts: CreateContextOptions) => {
* *
* @see https://trpc.io/docs/context * @see https://trpc.io/docs/context
*/ */
export const createTRPCContext = async (_opts: CreateNextContextOptions) => { export const createTRPCContext = async ({
const db = createClient(_opts.req, _opts.res); req,
resHeaders,
}: FetchCreateContextFnOptions) => {
const db = createTRPCClient(req, resHeaders);
const { const {
data: { user }, data: { user },

View File

@@ -3,13 +3,12 @@ import {
type CookieOptions, type CookieOptions,
serialize, serialize,
} from "@supabase/ssr"; } from "@supabase/ssr";
import { type NextApiRequest, type NextApiResponse } from "next"; import { RequestCookies } from "@edge-runtime/cookies";
import { type Database } from "~/types/database.types"; import { type Database } from "~/types/database.types";
export default function createClient( import { type NextApiRequest, type NextApiResponse } from "next";
req: NextApiRequest,
res: NextApiResponse, export function createNextClient(req: NextApiRequest, res: NextApiResponse) {
) {
const supabase = createServerClient<Database>( const supabase = createServerClient<Database>(
process.env.NEXT_PUBLIC_SUPABASE_URL!, process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!, process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
@@ -32,3 +31,28 @@ export default function createClient(
return supabase; return supabase;
} }
export function createTRPCClient(req: Request, resHeaders: Headers) {
const supabase = createServerClient<Database>(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
{
cookies: {
get(name: string) {
const cookies = new RequestCookies(req.headers);
return cookies.get(name)?.value;
},
set(name: string, value: string, options: CookieOptions) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-call
resHeaders.set("Set-Cookie", serialize(name, value, options));
},
remove(name: string, options: CookieOptions) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-call
resHeaders.set("Set-Cookie", serialize(name, "", options));
},
},
},
);
return supabase;
}