feat: switch TRPC to edge

This commit is contained in:
Henry
2024-04-24 22:11:53 +01:00
parent 0c1de23a19
commit 850b0fa876
7 changed files with 65 additions and 32 deletions

BIN
bun.lockb

Binary file not shown.

View File

@@ -16,6 +16,7 @@
"src/email"
],
"dependencies": {
"@edge-runtime/cookies": "^4.1.1",
"@headlessui/react": "^1.7.17",
"@react-email/render": "^0.0.10",
"@supabase/ssr": "^0.3.0",
@@ -43,6 +44,7 @@
"zod": "^3.22.4"
},
"devDependencies": {
"@types/cookie": "^0.6.0",
"@types/eslint": "^8.56.2",
"@types/node": "^20.11.20",
"@types/react": "^18.2.57",

View File

@@ -1,7 +1,7 @@
import { type EmailOtpType } from "@supabase/supabase-js";
import type { NextApiRequest, NextApiResponse } from "next";
import createClient from "~/utils/supabase/api";
import { createNextClient } from "~/utils/supabase/api";
function stringOrFirstString(item: string | string[] | undefined) {
return Array.isArray(item) ? item[0] : item;
@@ -23,7 +23,7 @@ export default async function handler(
let next = "/error";
if (token_hash && type) {
const supabase = createClient(req, res);
const supabase = createNextClient(req, res);
const { error } = await supabase.auth.verifyOtp({
type: type as EmailOtpType,
token_hash,
@@ -37,3 +37,7 @@ export default async function handler(
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 { createNextApiHandler } from "@trpc/server/adapters/next";
import { type NextRequest } from "next/server";
import { fetchRequestHandler } from "@trpc/server/adapters/fetch";
import { env } from "~/env.mjs";
import { appRouter } from "~/server/api/root";
import { createTRPCContext } from "~/server/api/trpc";
const nextApiHandler = createNextApiHandler({
router: appRouter,
createContext: createTRPCContext,
onError:
env.NODE_ENV === "development"
? ({ path, error }) => {
console.error(
`❌ tRPC failed on ${path ?? "<no-path>"}: ${error.message}`,
);
}
: undefined,
});
export default function handler(req: NextApiRequest, res: NextApiResponse) {
return nextApiHandler(req, res);
export default async function handler(req: NextRequest) {
return fetchRequestHandler({
endpoint: "/api/trpc",
router: appRouter,
req,
createContext: createTRPCContext,
onError:
env.NODE_ENV === "development"
? ({ path, error }) => {
console.error(
`❌ tRPC failed on ${path ?? "<no-path>"}: ${error.message}`,
);
}
: undefined,
});
}
// export const runtime = "edge";
// export const preferredRegion = 'lhr1';
// export const dynamic = 'force-dynamic'
export const runtime = "edge";
export const preferredRegion = "lhr1";
export const dynamic = "force-dynamic";

View File

@@ -9,7 +9,7 @@ export const authRouter = createTRPCRouter({
const { data } = await ctx.db.auth.signInWithOtp({
email: input.email,
options: {
emailRedirectTo: "/boards",
emailRedirectTo: `${process.env.WEBSITE_URL}/boards`,
},
});

View File

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

View File

@@ -3,13 +3,12 @@ import {
type CookieOptions,
serialize,
} from "@supabase/ssr";
import { type NextApiRequest, type NextApiResponse } from "next";
import { RequestCookies } from "@edge-runtime/cookies";
import { type Database } from "~/types/database.types";
export default function createClient(
req: NextApiRequest,
res: NextApiResponse,
) {
import { type NextApiRequest, type NextApiResponse } from "next";
export function createNextClient(req: NextApiRequest, res: NextApiResponse) {
const supabase = createServerClient<Database>(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
@@ -32,3 +31,28 @@ export default function createClient(
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;
}