feat: add trpc openapi (#1535)

This commit is contained in:
David Nguyen
2024-12-14 01:23:35 +09:00
committed by GitHub
parent f73441ee85
commit b4a7f1887d
42 changed files with 1198 additions and 341 deletions

View File

@ -1,5 +1,7 @@
'use server';
import type { z } from 'zod';
import { AppError, AppErrorCode } from '@documenso/lib/errors/app-error';
import { DOCUMENT_AUDIT_LOG_TYPE } from '@documenso/lib/types/document-audit-logs';
import type { RequestMetadata } from '@documenso/lib/universal/extract-request-metadata';
@ -8,6 +10,7 @@ import { prisma } from '@documenso/prisma';
import { DocumentSource, DocumentVisibility, WebhookTriggerEvents } from '@documenso/prisma/client';
import type { Team, TeamGlobalSettings } from '@documenso/prisma/client';
import { TeamMemberRole } from '@documenso/prisma/client';
import { DocumentSchema } from '@documenso/prisma/generated/zod';
import { ZWebhookDocumentSchema } from '../../types/webhook-payload';
import { triggerWebhook } from '../webhooks/trigger/trigger-webhook';
@ -22,6 +25,10 @@ export type CreateDocumentOptions = {
requestMetadata?: RequestMetadata;
};
export const ZCreateDocumentResponseSchema = DocumentSchema;
export type TCreateDocumentResponse = z.infer<typeof ZCreateDocumentResponseSchema>;
export const createDocument = async ({
userId,
title,
@ -30,7 +37,7 @@ export const createDocument = async ({
teamId,
formValues,
requestMetadata,
}: CreateDocumentOptions) => {
}: CreateDocumentOptions): Promise<TCreateDocumentResponse> => {
const user = await prisma.user.findFirstOrThrow({
where: {
id: userId,

View File

@ -1,19 +1,27 @@
import { z } from 'zod';
import { prisma } from '@documenso/prisma';
import { DocumentSource, type Prisma } from '@documenso/prisma/client';
import { getDocumentWhereInput } from './get-document-by-id';
export interface DuplicateDocumentByIdOptions {
export interface DuplicateDocumentOptions {
documentId: number;
userId: number;
teamId?: number;
}
export const duplicateDocumentById = async ({
export const ZDuplicateDocumentResponseSchema = z.object({
documentId: z.number(),
});
export type TDuplicateDocumentResponse = z.infer<typeof ZDuplicateDocumentResponseSchema>;
export const duplicateDocument = async ({
documentId,
userId,
teamId,
}: DuplicateDocumentByIdOptions) => {
}: DuplicateDocumentOptions): Promise<TDuplicateDocumentResponse> => {
const documentWhereInput = await getDocumentWhereInput({
documentId,
userId,
@ -78,5 +86,7 @@ export const duplicateDocumentById = async ({
const createdDocument = await prisma.document.create(createDocumentArguments);
return createdDocument.id;
return {
documentId: createdDocument.id,
};
};

View File

@ -1,5 +1,6 @@
import { DateTime } from 'luxon';
import { match } from 'ts-pattern';
import type { z } from 'zod';
import { prisma } from '@documenso/prisma';
import type {
@ -11,10 +12,16 @@ import type {
User,
} from '@documenso/prisma/client';
import { RecipientRole, SigningStatus, TeamMemberRole } from '@documenso/prisma/client';
import {
DocumentSchema,
RecipientSchema,
TeamSchema,
UserSchema,
} from '@documenso/prisma/generated/zod';
import { ExtendedDocumentStatus } from '@documenso/prisma/types/extended-document-status';
import { DocumentVisibility } from '../../types/document-visibility';
import type { FindResultResponse } from '../../types/search-params';
import { type FindResultResponse, ZFindResultResponse } from '../../types/search-params';
import { maskRecipientTokensForDocument } from '../../utils/mask-recipient-tokens-for-document';
export type PeriodSelectorValue = '' | '7d' | '14d' | '30d';
@ -36,6 +43,23 @@ export type FindDocumentsOptions = {
query?: string;
};
export const ZFindDocumentsResponseSchema = ZFindResultResponse.extend({
data: DocumentSchema.extend({
User: UserSchema.pick({
id: true,
name: true,
email: true,
}),
Recipient: RecipientSchema.array(),
team: TeamSchema.pick({
id: true,
url: true,
}).nullable(),
}).array(), // Todo: openapi remap.
});
export type TFindDocumentsResponse = z.infer<typeof ZFindDocumentsResponseSchema>;
export const findDocuments = async ({
userId,
teamId,
@ -48,7 +72,7 @@ export const findDocuments = async ({
period,
senderIds,
query,
}: FindDocumentsOptions) => {
}: FindDocumentsOptions): Promise<TFindDocumentsResponse> => {
const user = await prisma.user.findFirstOrThrow({
where: {
id: userId,

View File

@ -1,6 +1,15 @@
import { prisma } from '@documenso/prisma';
import type { DocumentWithDetails } from '@documenso/prisma/types/document';
import type { z } from 'zod';
import { prisma } from '@documenso/prisma';
import {
DocumentDataSchema,
DocumentMetaSchema,
DocumentSchema,
FieldSchema,
RecipientSchema,
} from '@documenso/prisma/generated/zod';
import { AppError, AppErrorCode } from '../../errors/app-error';
import { getDocumentWhereInput } from './get-document-by-id';
export type GetDocumentWithDetailsByIdOptions = {
@ -9,18 +18,29 @@ export type GetDocumentWithDetailsByIdOptions = {
teamId?: number;
};
export const ZGetDocumentWithDetailsByIdResponseSchema = DocumentSchema.extend({
documentData: DocumentDataSchema,
documentMeta: DocumentMetaSchema.nullable(),
Recipient: RecipientSchema.array(),
Field: FieldSchema.array(),
});
export type TGetDocumentWithDetailsByIdResponse = z.infer<
typeof ZGetDocumentWithDetailsByIdResponseSchema
>;
export const getDocumentWithDetailsById = async ({
documentId,
userId,
teamId,
}: GetDocumentWithDetailsByIdOptions): Promise<DocumentWithDetails> => {
}: GetDocumentWithDetailsByIdOptions): Promise<TGetDocumentWithDetailsByIdResponse> => {
const documentWhereInput = await getDocumentWhereInput({
documentId,
userId,
teamId,
});
return await prisma.document.findFirstOrThrow({
const document = await prisma.document.findFirst({
where: documentWhereInput,
include: {
documentData: true,
@ -29,4 +49,12 @@ export const getDocumentWithDetailsById = async ({
Field: true,
},
});
if (!document) {
throw new AppError(AppErrorCode.NOT_FOUND, {
message: 'Document not found',
});
}
return document;
};

View File

@ -1,7 +1,9 @@
import { TRPCError } from '@trpc/server';
import type { z } from 'zod';
import type { RequestMetadata } from '@documenso/lib/universal/extract-request-metadata';
import { prisma } from '@documenso/prisma';
import { DocumentSchema } from '@documenso/prisma/generated/zod';
import { DOCUMENT_AUDIT_LOG_TYPE } from '../../types/document-audit-logs';
import { createDocumentAuditLogData } from '../../utils/document-audit-logs';
@ -13,12 +15,16 @@ export type MoveDocumentToTeamOptions = {
requestMetadata?: RequestMetadata;
};
export const ZMoveDocumentToTeamResponseSchema = DocumentSchema;
export type TMoveDocumentToTeamResponse = z.infer<typeof ZMoveDocumentToTeamResponseSchema>;
export const moveDocumentToTeam = async ({
documentId,
teamId,
userId,
requestMetadata,
}: MoveDocumentToTeamOptions) => {
}: MoveDocumentToTeamOptions): Promise<TMoveDocumentToTeamResponse> => {
return await prisma.$transaction(async (tx) => {
const user = await tx.user.findUniqueOrThrow({
where: { id: userId },

View File

@ -38,7 +38,7 @@ export const resendDocument = async ({
recipients,
teamId,
requestMetadata,
}: ResendDocumentOptions) => {
}: ResendDocumentOptions): Promise<void> => {
const user = await prisma.user.findFirstOrThrow({
where: {
id: userId,

View File

@ -1,3 +1,5 @@
import type { z } from 'zod';
import { DOCUMENT_AUDIT_LOG_TYPE } from '@documenso/lib/types/document-audit-logs';
import type { RequestMetadata } from '@documenso/lib/universal/extract-request-metadata';
import { putPdfFile } from '@documenso/lib/universal/upload/put-file';
@ -11,6 +13,11 @@ import {
SigningStatus,
WebhookTriggerEvents,
} from '@documenso/prisma/client';
import {
DocumentMetaSchema,
DocumentSchema,
RecipientSchema,
} from '@documenso/prisma/generated/zod';
import { jobs } from '../../jobs/client';
import { extractDerivedDocumentEmailSettings } from '../../types/document-email';
@ -27,13 +34,20 @@ export type SendDocumentOptions = {
requestMetadata?: RequestMetadata;
};
export const ZSendDocumentResponseSchema = DocumentSchema.extend({
documentMeta: DocumentMetaSchema.nullable(),
Recipient: RecipientSchema.array(),
});
export type TSendDocumentResponse = z.infer<typeof ZSendDocumentResponseSchema>;
export const sendDocument = async ({
documentId,
userId,
teamId,
sendEmail,
requestMetadata,
}: SendDocumentOptions) => {
}: SendDocumentOptions): Promise<TSendDocumentResponse> => {
const user = await prisma.user.findFirstOrThrow({
where: {
id: userId,
@ -211,6 +225,7 @@ export const sendDocument = async ({
id: documentId,
},
include: {
documentMeta: true,
Recipient: true,
},
});

View File

@ -1,6 +1,7 @@
'use server';
import { match } from 'ts-pattern';
import type { z } from 'zod';
import { isUserEnterprise } from '@documenso/ee/server-only/util/is-document-enterprise';
import { DOCUMENT_AUDIT_LOG_TYPE } from '@documenso/lib/types/document-audit-logs';
@ -10,6 +11,7 @@ import { createDocumentAuditLogData } from '@documenso/lib/utils/document-audit-
import { prisma } from '@documenso/prisma';
import { DocumentVisibility } from '@documenso/prisma/client';
import { DocumentStatus, TeamMemberRole } from '@documenso/prisma/client';
import { DocumentSchema } from '@documenso/prisma/generated/zod';
import { AppError, AppErrorCode } from '../../errors/app-error';
import type { TDocumentAccessAuthTypes, TDocumentActionAuthTypes } from '../../types/document-auth';
@ -29,13 +31,17 @@ export type UpdateDocumentSettingsOptions = {
requestMetadata?: RequestMetadata;
};
export const ZUpdateDocumentSettingsResponseSchema = DocumentSchema;
export type TUpdateDocumentSettingsResponse = z.infer<typeof ZUpdateDocumentSettingsResponseSchema>;
export const updateDocumentSettings = async ({
userId,
teamId,
documentId,
data,
requestMetadata,
}: UpdateDocumentSettingsOptions) => {
}: UpdateDocumentSettingsOptions): Promise<TUpdateDocumentSettingsResponse> => {
if (!data.title && !data.globalAccessAuth && !data.globalActionAuth) {
throw new AppError(AppErrorCode.INVALID_BODY, {
message: 'Missing data to update',