mirror of
https://github.com/documenso/documenso.git
synced 2025-11-13 00:03:33 +10:00
feat: add trpc openapi (#1535)
This commit is contained in:
@ -3,6 +3,7 @@ import { createElement } from 'react';
|
||||
import { msg } from '@lingui/macro';
|
||||
import { DateTime } from 'luxon';
|
||||
import { match } from 'ts-pattern';
|
||||
import { z } from 'zod';
|
||||
|
||||
import { mailer } from '@documenso/email/mailer';
|
||||
import { DocumentCreatedFromDirectTemplateEmailTemplate } from '@documenso/email/templates/document-created-from-direct-template';
|
||||
@ -67,6 +68,16 @@ type CreatedDirectRecipientField = {
|
||||
derivedRecipientActionAuth: TRecipientActionAuthTypes | null;
|
||||
};
|
||||
|
||||
export const ZCreateDocumentFromDirectTemplateResponseSchema = z.object({
|
||||
token: z.string(),
|
||||
documentId: z.number(),
|
||||
recipientId: z.number(),
|
||||
});
|
||||
|
||||
export type TCreateDocumentFromDirectTemplateResponse = z.infer<
|
||||
typeof ZCreateDocumentFromDirectTemplateResponseSchema
|
||||
>;
|
||||
|
||||
export const createDocumentFromDirectTemplate = async ({
|
||||
directRecipientName: initialDirectRecipientName,
|
||||
directRecipientEmail,
|
||||
@ -76,7 +87,7 @@ export const createDocumentFromDirectTemplate = async ({
|
||||
templateUpdatedAt,
|
||||
requestMetadata,
|
||||
user,
|
||||
}: CreateDocumentFromDirectTemplateOptions) => {
|
||||
}: CreateDocumentFromDirectTemplateOptions): Promise<TCreateDocumentFromDirectTemplateResponse> => {
|
||||
const template = await prisma.template.findFirst({
|
||||
where: {
|
||||
directLink: {
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
import type { z } from 'zod';
|
||||
|
||||
import { nanoid } from '@documenso/lib/universal/id';
|
||||
import { prisma } from '@documenso/prisma';
|
||||
import type { DocumentDistributionMethod } from '@documenso/prisma/client';
|
||||
@ -11,6 +13,11 @@ import {
|
||||
SigningStatus,
|
||||
WebhookTriggerEvents,
|
||||
} from '@documenso/prisma/client';
|
||||
import {
|
||||
DocumentDataSchema,
|
||||
DocumentSchema,
|
||||
RecipientSchema,
|
||||
} from '@documenso/prisma/generated/zod';
|
||||
|
||||
import type { SupportedLanguageCodes } from '../../constants/i18n';
|
||||
import { AppError, AppErrorCode } from '../../errors/app-error';
|
||||
@ -36,10 +43,6 @@ type FinalRecipient = Pick<
|
||||
fields: Field[];
|
||||
};
|
||||
|
||||
export type CreateDocumentFromTemplateResponse = Awaited<
|
||||
ReturnType<typeof createDocumentFromTemplate>
|
||||
>;
|
||||
|
||||
export type CreateDocumentFromTemplateOptions = {
|
||||
templateId: number;
|
||||
externalId?: string | null;
|
||||
@ -72,6 +75,15 @@ export type CreateDocumentFromTemplateOptions = {
|
||||
requestMetadata?: RequestMetadata;
|
||||
};
|
||||
|
||||
export const ZCreateDocumentFromTemplateResponseSchema = DocumentSchema.extend({
|
||||
documentData: DocumentDataSchema,
|
||||
Recipient: RecipientSchema.array(),
|
||||
});
|
||||
|
||||
export type TCreateDocumentFromTemplateResponse = z.infer<
|
||||
typeof ZCreateDocumentFromTemplateResponseSchema
|
||||
>;
|
||||
|
||||
export const createDocumentFromTemplate = async ({
|
||||
templateId,
|
||||
externalId,
|
||||
@ -80,7 +92,7 @@ export const createDocumentFromTemplate = async ({
|
||||
recipients,
|
||||
override,
|
||||
requestMetadata,
|
||||
}: CreateDocumentFromTemplateOptions) => {
|
||||
}: CreateDocumentFromTemplateOptions): Promise<TCreateDocumentFromTemplateResponse> => {
|
||||
const user = await prisma.user.findFirstOrThrow({
|
||||
where: {
|
||||
id: userId,
|
||||
|
||||
@ -1,13 +1,15 @@
|
||||
'use server';
|
||||
|
||||
import { nanoid } from 'nanoid';
|
||||
import type { z } from 'zod';
|
||||
|
||||
import {
|
||||
DIRECT_TEMPLATE_RECIPIENT_EMAIL,
|
||||
DIRECT_TEMPLATE_RECIPIENT_NAME,
|
||||
} from '@documenso/lib/constants/direct-templates';
|
||||
import { prisma } from '@documenso/prisma';
|
||||
import type { Recipient, TemplateDirectLink } from '@documenso/prisma/client';
|
||||
import type { Recipient } from '@documenso/prisma/client';
|
||||
import { TemplateDirectLinkSchema } from '@documenso/prisma/generated/zod';
|
||||
|
||||
import { AppError, AppErrorCode } from '../../errors/app-error';
|
||||
|
||||
@ -17,11 +19,17 @@ export type CreateTemplateDirectLinkOptions = {
|
||||
directRecipientId?: number;
|
||||
};
|
||||
|
||||
export const ZCreateTemplateDirectLinkResponseSchema = TemplateDirectLinkSchema;
|
||||
|
||||
export type TCreateTemplateDirectLinkResponse = z.infer<
|
||||
typeof ZCreateTemplateDirectLinkResponseSchema
|
||||
>;
|
||||
|
||||
export const createTemplateDirectLink = async ({
|
||||
templateId,
|
||||
userId,
|
||||
directRecipientId,
|
||||
}: CreateTemplateDirectLinkOptions): Promise<TemplateDirectLink> => {
|
||||
}: CreateTemplateDirectLinkOptions): Promise<TCreateTemplateDirectLinkResponse> => {
|
||||
const template = await prisma.template.findFirst({
|
||||
where: {
|
||||
id: templateId,
|
||||
|
||||
@ -1,4 +1,7 @@
|
||||
import type { z } from 'zod';
|
||||
|
||||
import { prisma } from '@documenso/prisma';
|
||||
import { TemplateSchema } from '@documenso/prisma/generated/zod';
|
||||
import type { TCreateTemplateMutationSchema } from '@documenso/trpc/server/template-router/schema';
|
||||
|
||||
export type CreateTemplateOptions = TCreateTemplateMutationSchema & {
|
||||
@ -6,6 +9,10 @@ export type CreateTemplateOptions = TCreateTemplateMutationSchema & {
|
||||
teamId?: number;
|
||||
};
|
||||
|
||||
export const ZCreateTemplateResponseSchema = TemplateSchema;
|
||||
|
||||
export type TCreateTemplateResponse = z.infer<typeof ZCreateTemplateResponseSchema>;
|
||||
|
||||
export const createTemplate = async ({
|
||||
title,
|
||||
userId,
|
||||
|
||||
@ -1,19 +1,25 @@
|
||||
import { omit } from 'remeda';
|
||||
import type { z } from 'zod';
|
||||
|
||||
import { nanoid } from '@documenso/lib/universal/id';
|
||||
import { prisma } from '@documenso/prisma';
|
||||
import type { Prisma } from '@documenso/prisma/client';
|
||||
import { TemplateSchema } from '@documenso/prisma/generated/zod';
|
||||
import type { TDuplicateTemplateMutationSchema } from '@documenso/trpc/server/template-router/schema';
|
||||
|
||||
export type DuplicateTemplateOptions = TDuplicateTemplateMutationSchema & {
|
||||
userId: number;
|
||||
};
|
||||
|
||||
export const ZDuplicateTemplateResponseSchema = TemplateSchema;
|
||||
|
||||
export type TDuplicateTemplateResponse = z.infer<typeof ZDuplicateTemplateResponseSchema>;
|
||||
|
||||
export const duplicateTemplate = async ({
|
||||
templateId,
|
||||
userId,
|
||||
teamId,
|
||||
}: DuplicateTemplateOptions) => {
|
||||
}: DuplicateTemplateOptions): Promise<TDuplicateTemplateResponse> => {
|
||||
let templateWhereFilter: Prisma.TemplateWhereUniqueInput = {
|
||||
id: templateId,
|
||||
userId,
|
||||
|
||||
@ -1,7 +1,18 @@
|
||||
import type { z } from 'zod';
|
||||
|
||||
import { prisma } from '@documenso/prisma';
|
||||
import type { Prisma, Template } from '@documenso/prisma/client';
|
||||
import {
|
||||
DocumentDataSchema,
|
||||
FieldSchema,
|
||||
RecipientSchema,
|
||||
TeamSchema,
|
||||
TemplateDirectLinkSchema,
|
||||
TemplateMetaSchema,
|
||||
TemplateSchema,
|
||||
} from '@documenso/prisma/generated/zod';
|
||||
|
||||
import type { FindResultResponse } from '../../types/search-params';
|
||||
import { type FindResultResponse, ZFindResultResponse } from '../../types/search-params';
|
||||
|
||||
export type FindTemplatesOptions = {
|
||||
userId: number;
|
||||
@ -11,8 +22,28 @@ export type FindTemplatesOptions = {
|
||||
perPage?: number;
|
||||
};
|
||||
|
||||
export type FindTemplatesResponse = Awaited<ReturnType<typeof findTemplates>>;
|
||||
export type FindTemplateRow = FindTemplatesResponse['data'][number];
|
||||
export const ZFindTemplatesResponseSchema = ZFindResultResponse.extend({
|
||||
data: TemplateSchema.extend({
|
||||
templateDocumentData: DocumentDataSchema,
|
||||
team: TeamSchema.pick({
|
||||
id: true,
|
||||
url: true,
|
||||
}).nullable(),
|
||||
Field: FieldSchema.array(),
|
||||
Recipient: RecipientSchema.array(),
|
||||
templateMeta: TemplateMetaSchema.pick({
|
||||
signingOrder: true,
|
||||
distributionMethod: true,
|
||||
}).nullable(),
|
||||
directLink: TemplateDirectLinkSchema.pick({
|
||||
token: true,
|
||||
enabled: true,
|
||||
}).nullable(),
|
||||
}).array(), // Todo: openapi.
|
||||
});
|
||||
|
||||
export type TFindTemplatesResponse = z.infer<typeof ZFindTemplatesResponseSchema>;
|
||||
export type FindTemplateRow = TFindTemplatesResponse['data'][number];
|
||||
|
||||
export const findTemplates = async ({
|
||||
userId,
|
||||
@ -20,7 +51,7 @@ export const findTemplates = async ({
|
||||
type,
|
||||
page = 1,
|
||||
perPage = 10,
|
||||
}: FindTemplatesOptions) => {
|
||||
}: FindTemplatesOptions): Promise<TFindTemplatesResponse> => {
|
||||
let whereFilter: Prisma.TemplateWhereInput = {
|
||||
userId,
|
||||
teamId: null,
|
||||
|
||||
@ -1,6 +1,9 @@
|
||||
import { TRPCError } from '@trpc/server';
|
||||
import type { z } from 'zod';
|
||||
|
||||
import { prisma } from '@documenso/prisma';
|
||||
import { TemplateSchema } from '@documenso/prisma/generated/zod';
|
||||
|
||||
import { AppError, AppErrorCode } from '../../errors/app-error';
|
||||
|
||||
export type MoveTemplateToTeamOptions = {
|
||||
templateId: number;
|
||||
@ -8,11 +11,15 @@ export type MoveTemplateToTeamOptions = {
|
||||
userId: number;
|
||||
};
|
||||
|
||||
export const ZMoveTemplateToTeamResponseSchema = TemplateSchema;
|
||||
|
||||
export type TMoveTemplateToTeamResponse = z.infer<typeof ZMoveTemplateToTeamResponseSchema>;
|
||||
|
||||
export const moveTemplateToTeam = async ({
|
||||
templateId,
|
||||
teamId,
|
||||
userId,
|
||||
}: MoveTemplateToTeamOptions) => {
|
||||
}: MoveTemplateToTeamOptions): Promise<TMoveTemplateToTeamResponse> => {
|
||||
return await prisma.$transaction(async (tx) => {
|
||||
const template = await tx.template.findFirst({
|
||||
where: {
|
||||
@ -23,8 +30,7 @@ export const moveTemplateToTeam = async ({
|
||||
});
|
||||
|
||||
if (!template) {
|
||||
throw new TRPCError({
|
||||
code: 'NOT_FOUND',
|
||||
throw new AppError(AppErrorCode.NOT_FOUND, {
|
||||
message: 'Template not found or already associated with a team.',
|
||||
});
|
||||
}
|
||||
@ -41,9 +47,8 @@ export const moveTemplateToTeam = async ({
|
||||
});
|
||||
|
||||
if (!team) {
|
||||
throw new TRPCError({
|
||||
code: 'FORBIDDEN',
|
||||
message: 'You are not a member of this team.',
|
||||
throw new AppError(AppErrorCode.UNAUTHORIZED, {
|
||||
message: 'Team does not exist or you are not a member of this team.',
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -1,6 +1,9 @@
|
||||
'use server';
|
||||
|
||||
import type { z } from 'zod';
|
||||
|
||||
import { prisma } from '@documenso/prisma';
|
||||
import { TemplateDirectLinkSchema } from '@documenso/prisma/generated/zod';
|
||||
|
||||
import { AppError, AppErrorCode } from '../../errors/app-error';
|
||||
|
||||
@ -10,11 +13,17 @@ export type ToggleTemplateDirectLinkOptions = {
|
||||
enabled: boolean;
|
||||
};
|
||||
|
||||
export const ZToggleTemplateDirectLinkResponseSchema = TemplateDirectLinkSchema;
|
||||
|
||||
export type TToggleTemplateDirectLinkResponse = z.infer<
|
||||
typeof ZToggleTemplateDirectLinkResponseSchema
|
||||
>;
|
||||
|
||||
export const toggleTemplateDirectLink = async ({
|
||||
templateId,
|
||||
userId,
|
||||
enabled,
|
||||
}: ToggleTemplateDirectLinkOptions) => {
|
||||
}: ToggleTemplateDirectLinkOptions): Promise<TToggleTemplateDirectLinkResponse> => {
|
||||
const template = await prisma.template.findFirst({
|
||||
where: {
|
||||
id: templateId,
|
||||
|
||||
@ -1,9 +1,12 @@
|
||||
'use server';
|
||||
|
||||
import type { z } from 'zod';
|
||||
|
||||
import { isUserEnterprise } from '@documenso/ee/server-only/util/is-document-enterprise';
|
||||
import type { RequestMetadata } from '@documenso/lib/universal/extract-request-metadata';
|
||||
import { prisma } from '@documenso/prisma';
|
||||
import type { Template, TemplateMeta } from '@documenso/prisma/client';
|
||||
import { TemplateSchema } from '@documenso/prisma/generated/zod';
|
||||
|
||||
import { AppError, AppErrorCode } from '../../errors/app-error';
|
||||
import type { TDocumentAccessAuthTypes, TDocumentActionAuthTypes } from '../../types/document-auth';
|
||||
@ -26,13 +29,17 @@ export type UpdateTemplateSettingsOptions = {
|
||||
requestMetadata?: RequestMetadata;
|
||||
};
|
||||
|
||||
export const ZUpdateTemplateSettingsResponseSchema = TemplateSchema;
|
||||
|
||||
export type TUpdateTemplateSettingsResponse = z.infer<typeof ZUpdateTemplateSettingsResponseSchema>;
|
||||
|
||||
export const updateTemplateSettings = async ({
|
||||
userId,
|
||||
teamId,
|
||||
templateId,
|
||||
meta,
|
||||
data,
|
||||
}: UpdateTemplateSettingsOptions) => {
|
||||
}: UpdateTemplateSettingsOptions): Promise<TUpdateTemplateSettingsResponse> => {
|
||||
if (Object.values(data).length === 0 && Object.keys(meta ?? {}).length === 0) {
|
||||
throw new AppError(AppErrorCode.INVALID_BODY, {
|
||||
message: 'Missing data to update',
|
||||
|
||||
Reference in New Issue
Block a user