aboutsummaryrefslogtreecommitdiffstats
path: root/packages/trpc/index.ts
diff options
context:
space:
mode:
authorMohamedBassem <me@mbassem.com>2024-03-05 13:11:06 +0000
committerMohamedBassem <me@mbassem.com>2024-03-05 13:11:06 +0000
commit8a46ecb7373d6c5e7300861169ea51a7917cd2b4 (patch)
tree4ad318c3b5fc8b7a74cba6d0e37b6ade24db829a /packages/trpc/index.ts
parent224aa38d5976523f213e2860b6addc7630d472ba (diff)
downloadkarakeep-8a46ecb7373d6c5e7300861169ea51a7917cd2b4.tar.zst
refactor: Extract trpc logic into its package
Diffstat (limited to 'packages/trpc/index.ts')
-rw-r--r--packages/trpc/index.ts57
1 files changed, 57 insertions, 0 deletions
diff --git a/packages/trpc/index.ts b/packages/trpc/index.ts
new file mode 100644
index 00000000..a32eb871
--- /dev/null
+++ b/packages/trpc/index.ts
@@ -0,0 +1,57 @@
+import { db } from "@hoarder/db";
+import serverConfig from "@hoarder/shared/config";
+import { TRPCError, initTRPC } from "@trpc/server";
+import superjson from "superjson";
+
+type User = {
+ id: string;
+ role: "admin" | "user" | null;
+};
+
+export type Context = {
+ user: User | null;
+ db: typeof db;
+};
+
+// Avoid exporting the entire t-object
+// since it's not very descriptive.
+// For instance, the use of a t variable
+// is common in i18n libraries.
+const t = initTRPC.context<Context>().create({
+ transformer: superjson,
+});
+export const createCallerFactory = t.createCallerFactory;
+// Base router and procedure helpers
+export const router = t.router;
+export const procedure = t.procedure.use(function isDemoMode(opts) {
+ if (serverConfig.demoMode && opts.type == "mutation") {
+ throw new TRPCError({
+ message: "Mutations are not allowed in demo mode",
+ code: "FORBIDDEN",
+ });
+ }
+ return opts.next();
+});
+export const publicProcedure = procedure;
+
+export const authedProcedure = procedure.use(function isAuthed(opts) {
+ const user = opts.ctx.user;
+
+ if (!user || !user.id) {
+ throw new TRPCError({ code: "UNAUTHORIZED" });
+ }
+
+ return opts.next({
+ ctx: {
+ user,
+ },
+ });
+});
+
+export const adminProcedure = authedProcedure.use(function isAdmin(opts) {
+ const user = opts.ctx.user;
+ if (user.role != "admin") {
+ throw new TRPCError({ code: "FORBIDDEN" });
+ }
+ return opts.next(opts);
+});