mirror of
https://github.com/documenso/documenso.git
synced 2025-11-10 04:22:32 +10:00
wip: refresh design
This commit is contained in:
7
packages/trpc/client/guards.ts
Normal file
7
packages/trpc/client/guards.ts
Normal file
@ -0,0 +1,7 @@
|
||||
import { TRPCClientError } from '@trpc/client';
|
||||
|
||||
import { AppRouter } from '../server/router';
|
||||
|
||||
export const isTRPCBadRequestError = (err: unknown): err is TRPCClientError<AppRouter> => {
|
||||
return err instanceof TRPCClientError && err.shape?.code === 'BAD_REQUEST';
|
||||
};
|
||||
18
packages/trpc/client/index.ts
Normal file
18
packages/trpc/client/index.ts
Normal file
@ -0,0 +1,18 @@
|
||||
import { createTRPCProxyClient, httpBatchLink } from '@trpc/client';
|
||||
import SuperJSON from 'superjson';
|
||||
|
||||
import { getBaseUrl } from '@documenso/lib/universal/get-base-url';
|
||||
|
||||
import { AppRouter } from '../server/router';
|
||||
|
||||
export const trpc = createTRPCProxyClient<AppRouter>({
|
||||
transformer: SuperJSON,
|
||||
|
||||
links: [
|
||||
httpBatchLink({
|
||||
url: `${getBaseUrl()}/api/trpc`,
|
||||
}),
|
||||
],
|
||||
});
|
||||
|
||||
export { TRPCClientError } from '@trpc/client';
|
||||
1
packages/trpc/index.ts
Normal file
1
packages/trpc/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export {};
|
||||
18
packages/trpc/package.json
Normal file
18
packages/trpc/package.json
Normal file
@ -0,0 +1,18 @@
|
||||
{
|
||||
"name": "@documenso/trpc",
|
||||
"version": "1.0.0",
|
||||
"main": "./index.ts",
|
||||
"types": "./index.ts",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
},
|
||||
"dependencies": {
|
||||
"@tanstack/react-query": "^4.29.5",
|
||||
"@trpc/client": "^10.25.1",
|
||||
"@trpc/next": "^10.25.1",
|
||||
"@trpc/react-query": "^10.25.1",
|
||||
"@trpc/server": "^10.25.1",
|
||||
"superjson": "^1.12.3",
|
||||
"zod": "^3.21.4"
|
||||
}
|
||||
}
|
||||
49
packages/trpc/react/index.tsx
Normal file
49
packages/trpc/react/index.tsx
Normal file
@ -0,0 +1,49 @@
|
||||
'use client';
|
||||
|
||||
import { useState } from 'react';
|
||||
|
||||
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
||||
import { httpBatchLink } from '@trpc/client';
|
||||
import { createTRPCReact } from '@trpc/react-query';
|
||||
import SuperJSON from 'superjson';
|
||||
|
||||
import { getBaseUrl } from '@documenso/lib/universal/get-base-url';
|
||||
|
||||
import { AppRouter } from '../server/router';
|
||||
|
||||
export const trpc = createTRPCReact<AppRouter>({
|
||||
unstable_overrides: {
|
||||
useMutation: {
|
||||
async onSuccess(opts) {
|
||||
await opts.originalFn();
|
||||
await opts.queryClient.invalidateQueries();
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
export interface TrpcProviderProps {
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
export function TrpcProvider({ children }: TrpcProviderProps) {
|
||||
const [queryClient] = useState(() => new QueryClient());
|
||||
|
||||
const [trpcClient] = useState(() =>
|
||||
trpc.createClient({
|
||||
transformer: SuperJSON,
|
||||
|
||||
links: [
|
||||
httpBatchLink({
|
||||
url: `${getBaseUrl()}/api/trpc`,
|
||||
}),
|
||||
],
|
||||
}),
|
||||
);
|
||||
|
||||
return (
|
||||
<trpc.Provider client={trpcClient} queryClient={queryClient}>
|
||||
<QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
|
||||
</trpc.Provider>
|
||||
);
|
||||
}
|
||||
1
packages/trpc/server/adapters/next.ts
Normal file
1
packages/trpc/server/adapters/next.ts
Normal file
@ -0,0 +1 @@
|
||||
export * from '@trpc/server/adapters/next';
|
||||
24
packages/trpc/server/auth-router/router.ts
Normal file
24
packages/trpc/server/auth-router/router.ts
Normal file
@ -0,0 +1,24 @@
|
||||
import { TRPCError } from '@trpc/server';
|
||||
|
||||
import { createUser } from '@documenso/lib/server-only/user/create-user';
|
||||
|
||||
import { procedure, router } from '../trpc';
|
||||
import { ZSignUpMutationSchema } from './schema';
|
||||
|
||||
export const authRouter = router({
|
||||
signup: procedure.input(ZSignUpMutationSchema).mutation(async ({ input }) => {
|
||||
try {
|
||||
const { name, email, password } = input;
|
||||
|
||||
return await createUser({ name, email, password });
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
|
||||
throw new TRPCError({
|
||||
code: 'BAD_REQUEST',
|
||||
message:
|
||||
'We were unable to create your account. Please review the information you provided and try again.',
|
||||
});
|
||||
}
|
||||
}),
|
||||
});
|
||||
10
packages/trpc/server/auth-router/schema.ts
Normal file
10
packages/trpc/server/auth-router/schema.ts
Normal file
@ -0,0 +1,10 @@
|
||||
import 'zod';
|
||||
import { z } from 'zod';
|
||||
|
||||
export const ZSignUpMutationSchema = z.object({
|
||||
name: z.string().min(1),
|
||||
email: z.string().email(),
|
||||
password: z.string().min(6),
|
||||
});
|
||||
|
||||
export type TSignUpMutationSchema = z.infer<typeof ZSignUpMutationSchema>;
|
||||
21
packages/trpc/server/context.ts
Normal file
21
packages/trpc/server/context.ts
Normal file
@ -0,0 +1,21 @@
|
||||
import { CreateNextContextOptions } from '@trpc/server/adapters/next';
|
||||
|
||||
import { getServerSession } from '@documenso/lib/next-auth/get-server-session';
|
||||
|
||||
export const createTrpcContext = async ({ req, res }: CreateNextContextOptions) => {
|
||||
const session = await getServerSession({ req, res });
|
||||
|
||||
if (!session) {
|
||||
return {
|
||||
session: null,
|
||||
user: null,
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
session,
|
||||
user: session,
|
||||
};
|
||||
};
|
||||
|
||||
export type TrpcContext = Awaited<ReturnType<typeof createTrpcContext>>;
|
||||
1
packages/trpc/server/index.ts
Normal file
1
packages/trpc/server/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export * from '@trpc/server';
|
||||
52
packages/trpc/server/profile-router/router.ts
Normal file
52
packages/trpc/server/profile-router/router.ts
Normal file
@ -0,0 +1,52 @@
|
||||
import { TRPCError } from '@trpc/server';
|
||||
|
||||
import { updatePassword } from '@documenso/lib/server-only/user/update-password';
|
||||
import { updateProfile } from '@documenso/lib/server-only/user/update-profile';
|
||||
|
||||
import { authenticatedProcedure, router } from '../trpc';
|
||||
import { ZUpdatePasswordMutationSchema, ZUpdateProfileMutationSchema } from './schema';
|
||||
|
||||
export const profileRouter = router({
|
||||
updateProfile: authenticatedProcedure
|
||||
.input(ZUpdateProfileMutationSchema)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
try {
|
||||
const { name, signature } = input;
|
||||
|
||||
return await updateProfile({
|
||||
userId: ctx.user.id,
|
||||
name,
|
||||
signature,
|
||||
});
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
|
||||
throw new TRPCError({
|
||||
code: 'BAD_REQUEST',
|
||||
message:
|
||||
'We were unable to update your profile. Please review the information you provided and try again.',
|
||||
});
|
||||
}
|
||||
}),
|
||||
|
||||
updatePassword: authenticatedProcedure
|
||||
.input(ZUpdatePasswordMutationSchema)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
try {
|
||||
const { password } = input;
|
||||
|
||||
return await updatePassword({
|
||||
userId: ctx.user.id,
|
||||
password,
|
||||
});
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
|
||||
throw new TRPCError({
|
||||
code: 'BAD_REQUEST',
|
||||
message:
|
||||
'We were unable to update your profile. Please review the information you provided and try again.',
|
||||
});
|
||||
}
|
||||
}),
|
||||
});
|
||||
14
packages/trpc/server/profile-router/schema.ts
Normal file
14
packages/trpc/server/profile-router/schema.ts
Normal file
@ -0,0 +1,14 @@
|
||||
import { z } from 'zod';
|
||||
|
||||
export const ZUpdateProfileMutationSchema = z.object({
|
||||
name: z.string().min(1),
|
||||
signature: z.string(),
|
||||
});
|
||||
|
||||
export type TUpdateProfileMutationSchema = z.infer<typeof ZUpdateProfileMutationSchema>;
|
||||
|
||||
export const ZUpdatePasswordMutationSchema = z.object({
|
||||
password: z.string().min(6),
|
||||
});
|
||||
|
||||
export type TUpdatePasswordMutationSchema = z.infer<typeof ZUpdatePasswordMutationSchema>;
|
||||
11
packages/trpc/server/router.ts
Normal file
11
packages/trpc/server/router.ts
Normal file
@ -0,0 +1,11 @@
|
||||
import { authRouter } from './auth-router/router';
|
||||
import { profileRouter } from './profile-router/router';
|
||||
import { procedure, router } from './trpc';
|
||||
|
||||
export const appRouter = router({
|
||||
hello: procedure.query(() => 'Hello, world!'),
|
||||
auth: authRouter,
|
||||
profile: profileRouter,
|
||||
});
|
||||
|
||||
export type AppRouter = typeof appRouter;
|
||||
36
packages/trpc/server/trpc.ts
Normal file
36
packages/trpc/server/trpc.ts
Normal file
@ -0,0 +1,36 @@
|
||||
import { TRPCError, initTRPC } from '@trpc/server';
|
||||
import SuperJSON from 'superjson';
|
||||
|
||||
import { TrpcContext } from './context';
|
||||
|
||||
const t = initTRPC.context<TrpcContext>().create({
|
||||
transformer: SuperJSON,
|
||||
});
|
||||
|
||||
/**
|
||||
* Middlewares
|
||||
*/
|
||||
export const authenticatedMiddleware = t.middleware(({ ctx, next }) => {
|
||||
if (!ctx.session) {
|
||||
throw new TRPCError({
|
||||
code: 'UNAUTHORIZED',
|
||||
message: 'You must be logged in to perform this action.',
|
||||
});
|
||||
}
|
||||
|
||||
return next({
|
||||
ctx: {
|
||||
...ctx,
|
||||
|
||||
user: ctx.user,
|
||||
session: ctx.session,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Routers and Procedures
|
||||
*/
|
||||
export const router = t.router;
|
||||
export const procedure = t.procedure;
|
||||
export const authenticatedProcedure = t.procedure.use(authenticatedMiddleware);
|
||||
5
packages/trpc/tsconfig.json
Normal file
5
packages/trpc/tsconfig.json
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"extends": "@documenso/tsconfig/react-library.json",
|
||||
"include": ["."],
|
||||
"exclude": ["dist", "build", "node_modules"]
|
||||
}
|
||||
Reference in New Issue
Block a user