juico
juico
TtRPC
Created by juico on 11/22/2023 in #❓-help
trpc mutation call stuck
I have an issue with a simple mutation procedure: getPublicUser: publicProcedure .input(z.object({ walletAddress: z.string() })) .mutation(async ({ ctx, input }) => { console.log('ctx.prisma: ', ctx.prisma) try { const user = await ctx.prisma.users.findUnique({ where: { walletAddress: input.walletAddress }, select: { walletAddress: true, id: true, } }) return user } catch (e: any) { console.log('E: ', e) } }) It shows in my console that it calls the mutation successfully, but it keeps on being stuck. It does not log the first like in the code even. My trpc.ts setup: const t = initTRPC.context<typeof createTRPCContext>().create({ transformer: superjson, errorFormatter({ shape, error }) { return { ...shape, data: { ...shape.data, zodError: error.cause instanceof ZodError ? error.cause.flatten() : null, }, }; }, }); export const createTRPCContext = async (_opts: CreateNextContextOptions) => { const { req, res } = _opts; async function getUserFromHeader() { console.log('req.headers.authorization: ', req.headers.authorization) if (req.headers.authorization && req.headers.authorization.split(' ')[1]) { try { const token = localStorage.getItem('crypties:auth') if (!token) return null; const parsedToken = JSON.parse(token); if (new Date(parsedToken.validUntil) < new Date()) return null console.log('token: ', token) const user = await prisma.users.findFirst({ where: { walletAddress: parsedToken.userWalletAddress }, }); return user; } catch (error) { return null; } } return null; } return { req, res, user: await getUserFromHeader(), prisma }; }; export const publicProcedure = t.procedure;
17 replies
TtRPC
Created by juico on 8/26/2023 in #❓-help
How do I set a context dynamically?
I don't fully understand middleware in trpc and especially using it for adminProcedures. So my trpc.ts looks like this:
import { UserRoles } from '@/pages/api/enums';
import { UserDocument } from '@/pages/api/schemas/user_schema';
import { TRPCError, initTRPC } from '@trpc/server';

interface Context {
user?: UserDocument
}
const t = initTRPC.context<Context>().create();

export const middleware = t.middleware;
export const router = t.router;
export const publicProcedure = t.procedure;


const isAdmin = middleware(async (opts) => {

const { ctx } = opts;

if (!ctx.user?.roles.includes(UserRoles.ADMIN || UserRoles.SUPERADMIN)) {
throw new TRPCError({ code: 'UNAUTHORIZED' });
}
return opts.next({
ctx: {
user: ctx.user,
},
});
});

export const adminProcedure = publicProcedure.use(isAdmin);
import { UserRoles } from '@/pages/api/enums';
import { UserDocument } from '@/pages/api/schemas/user_schema';
import { TRPCError, initTRPC } from '@trpc/server';

interface Context {
user?: UserDocument
}
const t = initTRPC.context<Context>().create();

export const middleware = t.middleware;
export const router = t.router;
export const publicProcedure = t.procedure;


const isAdmin = middleware(async (opts) => {

const { ctx } = opts;

if (!ctx.user?.roles.includes(UserRoles.ADMIN || UserRoles.SUPERADMIN)) {
throw new TRPCError({ code: 'UNAUTHORIZED' });
}
return opts.next({
ctx: {
user: ctx.user,
},
});
});

export const adminProcedure = publicProcedure.use(isAdmin);
What I don't understand is how do I inject user into the context? I get user with public procedure:
export const getUser = publicProcedure
.input(
z.object({
walletAddress: z.string(),
})
)
.mutation(async (opts) => {

const db = await connectDB();
const user = await User.findOne({
walletAddress: opts.input.walletAddress,
});

opts.ctx.user = user ?? undefined;
return user as UserDocument;
});
export const getUser = publicProcedure
.input(
z.object({
walletAddress: z.string(),
})
)
.mutation(async (opts) => {

const db = await connectDB();
const user = await User.findOne({
walletAddress: opts.input.walletAddress,
});

opts.ctx.user = user ?? undefined;
return user as UserDocument;
});
Now I try to inject it inside the procedure but when I console log the user inside the middleware function it shows undefined.
2 replies
TtRPC
Created by juico on 8/23/2023 in #❓-help
Type return error when using mongoose.
node - v16.15.1 npm I'm somewhat new to trpc. Using it with mongoose. Love it so far althought I do have a problem with how types are returned. For example I have a simple procedure:
export const getUser = procedure
.input(
z.object({
walletAddress: z.string(),
})
)
.mutation(async (opts) => {
const db = await connectDB();
const user: UserDocument | null = await User.findOne({
walletAddress: opts.input.walletAddress,
});
return user;
});
export const getUser = procedure
.input(
z.object({
walletAddress: z.string(),
})
)
.mutation(async (opts) => {
const db = await connectDB();
const user: UserDocument | null = await User.findOne({
walletAddress: opts.input.walletAddress,
});
return user;
});
This should return either UserDocument or null. I call it in my client:
const getUser = trpc.getUser.useMutation();
const currentUser: UserDocument | null = await getUser.mutateAsync({
walletAddress: userWalletAddress
})
const getUser = trpc.getUser.useMutation();
const currentUser: UserDocument | null = await getUser.mutateAsync({
walletAddress: userWalletAddress
})
But this gives error:
Type '{ walletAddress: string; _id: string; createdAt?: string | undefined; updatedAt?: string | undefined; readonly URL: string; alinkColor: string; readonly all: { [x: number]: { id: string; onfullscreenchange: null; ... 97 more ...; readonly assignedSlot: { ...; } | null; }; readonly length: number; }; ... 196 more ......' is not assignable to type 'UserDocument | null'.
Type '{ walletAddress: string; _id: string; createdAt?: string | undefined; updatedAt?: string | undefined; readonly URL: string; alinkColor: string; readonly all: { [x: number]: { id: string; onfullscreenchange: null; ... 97 more ...; readonly assignedSlot: { ...; } | null; }; readonly length: number; }; ... 196 more ......' is missing the following properties from type 'UserDocument': adoptNode, captureEvents, caretRangeFromPoint, clear, and 66 more.
Type '{ walletAddress: string; _id: string; createdAt?: string | undefined; updatedAt?: string | undefined; readonly URL: string; alinkColor: string; readonly all: { [x: number]: { id: string; onfullscreenchange: null; ... 97 more ...; readonly assignedSlot: { ...; } | null; }; readonly length: number; }; ... 196 more ......' is not assignable to type 'UserDocument | null'.
Type '{ walletAddress: string; _id: string; createdAt?: string | undefined; updatedAt?: string | undefined; readonly URL: string; alinkColor: string; readonly all: { [x: number]: { id: string; onfullscreenchange: null; ... 97 more ...; readonly assignedSlot: { ...; } | null; }; readonly length: number; }; ... 196 more ......' is missing the following properties from type 'UserDocument': adoptNode, captureEvents, caretRangeFromPoint, clear, and 66 more.
So it seems to be returning a different type than specified.
8 replies