New to the t3 stack and tRPC, how do I share code between route functions correctly?

Maybe I'm going about this the complete wrong way. Basically, as you can see below I am trying to create two different routes that share a lot of logic that I want to make into a function. I tried making a function outside of the discordRouter but I couldn't figure out how to type ctx correctly, so any thoughts would be appreciated. What I've tried so far is import { type createTRPCContext } from "~/server/api/trpc"; then type Context = ReturnType<typeof createTRPCContext>; but that's a promise for the context and I feel like I'm going about it the wrong way.
import { createTRPCRouter, protectedProcedure } from "~/server/api/trpc";

import { type APIGuild } from "discord-api-types/v10";

const DISCORD_BASE_URL = "https://discord.com/api/v10";

export const discordRouter = createTRPCRouter({
getUserGuilds: protectedProcedure.query(async ({ ctx }) => {
console.log("getUserGuilds");
/* DUPLICATED CODE */
// Get user token first
const user = await ctx.db.query.accounts.findFirst({
where(fields, operators) {
return operators.eq(fields.userId, ctx.session.user.id);
},
});
const token = user?.access_token;

const response = await fetch(`${DISCORD_BASE_URL}/users/@me/guilds`, {
headers: {
Authorization: `Bearer ${token}`,
},
});
const data = (await response.json()) as APIGuild[];
/* DUPLICATED CODE */
return data;
}),
getUserGuildsWhereAdmin: protectedProcedure.query(async ({ ctx }) => {
console.log("getUserGuildsWhereAdmin");
/* DUPLICATED CODE */
...

// https://discord.com/developers/docs/topics/permissions
// ADMINISTRATOR * 0x0000000000000008 (1 << 3) Allows all permissions and bypasses channel permission overwrites
return data.filter((guild) => {
if (!guild.permissions) return false;
const permissions = BigInt(guild.permissions);
return (permissions & BigInt(8)) === BigInt(8);
});
}),
});
import { createTRPCRouter, protectedProcedure } from "~/server/api/trpc";

import { type APIGuild } from "discord-api-types/v10";

const DISCORD_BASE_URL = "https://discord.com/api/v10";

export const discordRouter = createTRPCRouter({
getUserGuilds: protectedProcedure.query(async ({ ctx }) => {
console.log("getUserGuilds");
/* DUPLICATED CODE */
// Get user token first
const user = await ctx.db.query.accounts.findFirst({
where(fields, operators) {
return operators.eq(fields.userId, ctx.session.user.id);
},
});
const token = user?.access_token;

const response = await fetch(`${DISCORD_BASE_URL}/users/@me/guilds`, {
headers: {
Authorization: `Bearer ${token}`,
},
});
const data = (await response.json()) as APIGuild[];
/* DUPLICATED CODE */
return data;
}),
getUserGuildsWhereAdmin: protectedProcedure.query(async ({ ctx }) => {
console.log("getUserGuildsWhereAdmin");
/* DUPLICATED CODE */
...

// https://discord.com/developers/docs/topics/permissions
// ADMINISTRATOR * 0x0000000000000008 (1 << 3) Allows all permissions and bypasses channel permission overwrites
return data.filter((guild) => {
if (!guild.permissions) return false;
const permissions = BigInt(guild.permissions);
return (permissions & BigInt(8)) === BigInt(8);
});
}),
});
3 Replies
marv 🍵
marv 🍵OP6mo ago
I think I figured it out just by adding
export type Context = Awaited<ReturnType<typeof createTRPCContext>>;
export type Context = Awaited<ReturnType<typeof createTRPCContext>>;
to my trpc.ts and importing that, but if there's a better way please let me know! especially since trpc.ts says YOU PROBABLY DON'T NEED TO EDIT THIS FILE, UNLESS: so i feel like this is still a hacky solution and not the correct way...
marv 🍵
marv 🍵OP6mo ago
yeah this doesn't take into account that in a protectedProcecure the session and user are guaranteed not null...
No description
marv 🍵
marv 🍵OP6mo ago
nvm i shoulda just read the fuckin docs https://trpc.io/docs/server/server-side-calls
Server Side Calls | tRPC
You may need to call your procedure(s) directly from the same server they're hosted in, createCallerFactory() can be used to achieve this. This is useful for server-side calls and for integration testing of your tRPC procedures.
Want results from more Discord servers?
Add your server