diff --git a/apps/web/src/app/(dashboard)/documents/[id]/edit-document.tsx b/apps/web/src/app/(dashboard)/documents/[id]/edit-document.tsx index 15a7c0c7d..7977aa2c6 100644 --- a/apps/web/src/app/(dashboard)/documents/[id]/edit-document.tsx +++ b/apps/web/src/app/(dashboard)/documents/[id]/edit-document.tsx @@ -12,7 +12,7 @@ import { DO_NOT_INVALIDATE_QUERY_ON_MUTATION, SKIP_QUERY_BATCH_META, } from '@documenso/lib/constants/trpc'; -import type { TGetDocumentWithDetailsByIdResponse } from '@documenso/lib/server-only/document/get-document-with-details-by-id'; +import type { TDocument } from '@documenso/lib/types/document'; import { DocumentDistributionMethod, DocumentStatus } from '@documenso/prisma/client'; import { trpc } from '@documenso/trpc/react'; import { cn } from '@documenso/ui/lib/utils'; @@ -35,7 +35,7 @@ import { useOptionalCurrentTeam } from '~/providers/team'; export type EditDocumentFormProps = { className?: string; - initialDocument: TGetDocumentWithDetailsByIdResponse; + initialDocument: TDocument; documentRootPath: string; isDocumentEnterprise: boolean; }; diff --git a/apps/web/src/app/(dashboard)/documents/data-table.tsx b/apps/web/src/app/(dashboard)/documents/data-table.tsx index b3b54512e..4051b7d1d 100644 --- a/apps/web/src/app/(dashboard)/documents/data-table.tsx +++ b/apps/web/src/app/(dashboard)/documents/data-table.tsx @@ -9,9 +9,9 @@ import { DateTime } from 'luxon'; import { useSession } from 'next-auth/react'; import { useUpdateSearchParams } from '@documenso/lib/client-only/hooks/use-update-search-params'; -import type { TFindDocumentsResponse } from '@documenso/lib/server-only/document/find-documents'; import type { Team } from '@documenso/prisma/client'; import { ExtendedDocumentStatus } from '@documenso/prisma/types/extended-document-status'; +import type { TFindDocumentsResponse } from '@documenso/trpc/server/document-router/schema'; import type { DataTableColumnDef } from '@documenso/ui/primitives/data-table'; import { DataTable } from '@documenso/ui/primitives/data-table'; import { DataTablePagination } from '@documenso/ui/primitives/data-table-pagination'; diff --git a/apps/web/src/pages/api/v2-beta/[...trpc].ts b/apps/web/src/pages/api/v2-beta/[...trpc].ts index 4f1e50375..db99e4739 100644 --- a/apps/web/src/pages/api/v2-beta/[...trpc].ts +++ b/apps/web/src/pages/api/v2-beta/[...trpc].ts @@ -1,8 +1,13 @@ import type { NextApiRequest, NextApiResponse } from 'next'; import { createOpenApiNextHandler } from 'trpc-openapi'; +import type { CreateOpenApiNextHandlerOptions } from 'trpc-openapi/dist/adapters/next'; -import { AppError, AppErrorCode } from '@documenso/lib/errors/app-error'; +import { + AppError, + AppErrorCode, + genericErrorCodeToTrpcErrorCodeMap, +} from '@documenso/lib/errors/app-error'; import { buildLogger } from '@documenso/lib/utils/logger'; import type { TRPCError } from '@documenso/trpc/server'; import { createTrpcContext } from '@documenso/trpc/server/context'; @@ -41,7 +46,18 @@ export default createOpenApiNextHandler({ }); } }, - responseMeta: () => {}, + // Not sure why we need to do this since we handle it in errorFormatter which runs after this. + responseMeta: (opts: CreateOpenApiNextHandlerOptions['responseMeta']) => { + if (opts.errors[0]?.cause instanceof AppError) { + const appError = AppError.parseError(opts.errors[0].cause); + + const httpStatus = genericErrorCodeToTrpcErrorCodeMap[appError.code]?.status ?? 400; + + return { + status: httpStatus, + }; + } + }, }); const errorCodesToAlertOn = [AppErrorCode.UNKNOWN_ERROR, 'INTERNAL_SERVER_ERROR']; diff --git a/package-lock.json b/package-lock.json index 2de1afdc2..6e073e849 100644 --- a/package-lock.json +++ b/package-lock.json @@ -34070,36 +34070,6 @@ "zod": "^3.20.2" } }, - "node_modules/zod-prisma-types": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/zod-prisma-types/-/zod-prisma-types-3.1.8.tgz", - "integrity": "sha512-5oe0ays3ur4u2GtuUqlhgCraKBcsuMaMI8o7VMV4YAnFeOuVid7K2zGvjI19V0ue9PeNF2ICyVREQVohaQm5dw==", - "dev": true, - "dependencies": { - "@prisma/generator-helper": "^5.14.0", - "code-block-writer": "^12.0.0", - "lodash": "^4.17.21", - "zod": "^3.23.8" - }, - "bin": { - "zod-prisma-types": "dist/bin.js" - } - }, - "node_modules/zod-prisma-types/node_modules/@prisma/debug": { - "version": "5.22.0", - "resolved": "https://registry.npmjs.org/@prisma/debug/-/debug-5.22.0.tgz", - "integrity": "sha512-AUt44v3YJeggO2ZU5BkXI7M4hu9BF2zzH2iF2V5pyXT/lRTyWiElZ7It+bRH1EshoMRxHgpYg4VB6rCM+mG5jQ==", - "dev": true - }, - "node_modules/zod-prisma-types/node_modules/@prisma/generator-helper": { - "version": "5.22.0", - "resolved": "https://registry.npmjs.org/@prisma/generator-helper/-/generator-helper-5.22.0.tgz", - "integrity": "sha512-LwqcBQ5/QsuAaLNQZAIVIAJDJBMjHwMwn16e06IYx/3Okj/xEEfw9IvrqB2cJCl3b2mCBlh3eVH0w9WGmi4aHg==", - "dev": true, - "dependencies": { - "@prisma/debug": "5.22.0" - } - }, "node_modules/zod-to-json-schema": { "version": "3.24.1", "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.24.1.tgz", @@ -35478,7 +35448,24 @@ "prisma-kysely": "^1.8.0", "tsx": "^4.11.0", "typescript": "5.2.2", - "zod-prisma-types": "^3.1.8" + "zod-prisma-types": "3.1.9" + } + }, + "packages/prisma/node_modules/@prisma/debug": { + "version": "5.22.0", + "resolved": "https://registry.npmjs.org/@prisma/debug/-/debug-5.22.0.tgz", + "integrity": "sha512-AUt44v3YJeggO2ZU5BkXI7M4hu9BF2zzH2iF2V5pyXT/lRTyWiElZ7It+bRH1EshoMRxHgpYg4VB6rCM+mG5jQ==", + "dev": true, + "license": "Apache-2.0" + }, + "packages/prisma/node_modules/@prisma/generator-helper": { + "version": "5.22.0", + "resolved": "https://registry.npmjs.org/@prisma/generator-helper/-/generator-helper-5.22.0.tgz", + "integrity": "sha512-LwqcBQ5/QsuAaLNQZAIVIAJDJBMjHwMwn16e06IYx/3Okj/xEEfw9IvrqB2cJCl3b2mCBlh3eVH0w9WGmi4aHg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@prisma/debug": "5.22.0" } }, "packages/prisma/node_modules/ts-pattern": { @@ -35499,6 +35486,25 @@ "node": ">=14.17" } }, + "packages/prisma/node_modules/zod-prisma-types": { + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/zod-prisma-types/-/zod-prisma-types-3.1.9.tgz", + "integrity": "sha512-3AzTtWY2E9nySwLl9QEOgHJYOAX6sKkA36dnu7DD9HhGEOHmLqWx5pects60biMW29VcP57wJZKCp7ZVmJrNtQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@prisma/generator-helper": "^5.14.0", + "code-block-writer": "^12.0.0", + "lodash": "^4.17.21", + "zod": "^3.23.8" + }, + "bin": { + "zod-prisma-types": "dist/bin.js" + }, + "peerDependencies": { + "prisma": "^4.x.x || ^5.x.x" + } + }, "packages/signing": { "name": "@documenso/signing", "version": "0.0.0", diff --git a/packages/api/v1/implementation.ts b/packages/api/v1/implementation.ts index 6d01461c3..c3e5da673 100644 --- a/packages/api/v1/implementation.ts +++ b/packages/api/v1/implementation.ts @@ -28,7 +28,6 @@ import { setDocumentRecipients } from '@documenso/lib/server-only/recipient/set- import { updateRecipient } from '@documenso/lib/server-only/recipient/update-recipient'; import { createTeamMemberInvites } from '@documenso/lib/server-only/team/create-team-member-invites'; import { deleteTeamMembers } from '@documenso/lib/server-only/team/delete-team-members'; -import type { TCreateDocumentFromTemplateResponse } from '@documenso/lib/server-only/template/create-document-from-template'; import { createDocumentFromTemplate } from '@documenso/lib/server-only/template/create-document-from-template'; import { createDocumentFromTemplateLegacy } from '@documenso/lib/server-only/template/create-document-from-template-legacy'; import { deleteTemplate } from '@documenso/lib/server-only/template/delete-template'; @@ -578,7 +577,7 @@ export const ApiContractV1Implementation = createNextRoute(ApiContractV1, { const templateId = Number(params.templateId); - let document: TCreateDocumentFromTemplateResponse | null = null; + let document: Awaited> | null = null; try { document = await createDocumentFromTemplate({ diff --git a/packages/lib/server-only/document-meta/upsert-document-meta.ts b/packages/lib/server-only/document-meta/upsert-document-meta.ts index 3c70d9c02..bec1a6404 100644 --- a/packages/lib/server-only/document-meta/upsert-document-meta.ts +++ b/packages/lib/server-only/document-meta/upsert-document-meta.ts @@ -10,6 +10,7 @@ import { prisma } from '@documenso/prisma'; import type { DocumentDistributionMethod, DocumentSigningOrder } from '@documenso/prisma/client'; import type { SupportedLanguageCodes } from '../../constants/i18n'; +import { AppError, AppErrorCode } from '../../errors/app-error'; import type { TDocumentEmailSettings } from '../../types/document-email'; export type CreateDocumentMetaOptions = { @@ -47,7 +48,7 @@ export const upsertDocumentMeta = async ({ language, requestMetadata, }: CreateDocumentMetaOptions) => { - const { documentMeta: originalDocumentMeta } = await prisma.document.findFirstOrThrow({ + const document = await prisma.document.findFirst({ where: { id: documentId, ...(teamId @@ -71,6 +72,14 @@ export const upsertDocumentMeta = async ({ }, }); + if (!document) { + throw new AppError(AppErrorCode.NOT_FOUND, { + message: 'Document not found', + }); + } + + const { documentMeta: originalDocumentMeta } = document; + return await prisma.$transaction(async (tx) => { const upsertedDocumentMeta = await tx.documentMeta.upsert({ where: { diff --git a/packages/lib/server-only/document/create-document.ts b/packages/lib/server-only/document/create-document.ts index 6dee14b98..3879427a2 100644 --- a/packages/lib/server-only/document/create-document.ts +++ b/packages/lib/server-only/document/create-document.ts @@ -1,7 +1,5 @@ 'use server'; -import type { z } from 'zod'; - import { AppError, AppErrorCode } from '@documenso/lib/errors/app-error'; import { normalizePdf as makeNormalizedPdf } from '@documenso/lib/server-only/pdf/normalize-pdf'; import { DOCUMENT_AUDIT_LOG_TYPE } from '@documenso/lib/types/document-audit-logs'; @@ -11,7 +9,6 @@ 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, @@ -33,10 +30,6 @@ export type CreateDocumentOptions = { requestMetadata: ApiRequestMetadata; }; -export const ZCreateDocumentResponseSchema = DocumentSchema; - -export type TCreateDocumentResponse = z.infer; - export const createDocument = async ({ userId, title, @@ -47,7 +40,7 @@ export const createDocument = async ({ formValues, requestMetadata, timezone, -}: CreateDocumentOptions): Promise => { +}: CreateDocumentOptions) => { const user = await prisma.user.findFirstOrThrow({ where: { id: userId, diff --git a/packages/lib/server-only/document/duplicate-document-by-id.ts b/packages/lib/server-only/document/duplicate-document-by-id.ts index 5c29d90fd..7206403c1 100644 --- a/packages/lib/server-only/document/duplicate-document-by-id.ts +++ b/packages/lib/server-only/document/duplicate-document-by-id.ts @@ -1,8 +1,7 @@ -import { z } from 'zod'; - import { prisma } from '@documenso/prisma'; import { DocumentSource, type Prisma } from '@documenso/prisma/client'; +import { AppError, AppErrorCode } from '../../errors/app-error'; import { getDocumentWhereInput } from './get-document-by-id'; export interface DuplicateDocumentOptions { @@ -11,24 +10,18 @@ export interface DuplicateDocumentOptions { teamId?: number; } -export const ZDuplicateDocumentResponseSchema = z.object({ - documentId: z.number(), -}); - -export type TDuplicateDocumentResponse = z.infer; - export const duplicateDocument = async ({ documentId, userId, teamId, -}: DuplicateDocumentOptions): Promise => { +}: DuplicateDocumentOptions) => { const documentWhereInput = await getDocumentWhereInput({ documentId, userId, teamId, }); - const document = await prisma.document.findUniqueOrThrow({ + const document = await prisma.document.findFirst({ where: documentWhereInput, select: { title: true, @@ -53,6 +46,12 @@ export const duplicateDocument = async ({ }, }); + if (!document) { + throw new AppError(AppErrorCode.NOT_FOUND, { + message: 'Document not found', + }); + } + const createDocumentArguments: Prisma.DocumentCreateArgs = { data: { title: document.title, diff --git a/packages/lib/server-only/document/find-documents.ts b/packages/lib/server-only/document/find-documents.ts index 32765699c..160b1b2ce 100644 --- a/packages/lib/server-only/document/find-documents.ts +++ b/packages/lib/server-only/document/find-documents.ts @@ -1,6 +1,5 @@ import { DateTime } from 'luxon'; import { match } from 'ts-pattern'; -import type { z } from 'zod'; import { prisma } from '@documenso/prisma'; import type { @@ -12,16 +11,10 @@ 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, ZFindResultResponse } from '../../types/search-params'; +import { type FindResultResponse } from '../../types/search-params'; import { maskRecipientTokensForDocument } from '../../utils/mask-recipient-tokens-for-document'; export type PeriodSelectorValue = '' | '7d' | '14d' | '30d'; @@ -43,23 +36,6 @@ export type FindDocumentsOptions = { query?: string; }; -export const ZFindDocumentsResponseSchema = ZFindResultResponse.extend({ - data: DocumentSchema.extend({ - user: UserSchema.pick({ - id: true, - name: true, - email: true, - }), - recipients: RecipientSchema.array(), - team: TeamSchema.pick({ - id: true, - url: true, - }).nullable(), - }).array(), // Todo: openapi remap. -}); - -export type TFindDocumentsResponse = z.infer; - export const findDocuments = async ({ userId, teamId, @@ -72,7 +48,7 @@ export const findDocuments = async ({ period, senderIds, query, -}: FindDocumentsOptions): Promise => { +}: FindDocumentsOptions) => { const user = await prisma.user.findFirstOrThrow({ where: { id: userId, diff --git a/packages/lib/server-only/document/get-document-with-details-by-id.ts b/packages/lib/server-only/document/get-document-with-details-by-id.ts index 955db895c..9cabb6838 100644 --- a/packages/lib/server-only/document/get-document-with-details-by-id.ts +++ b/packages/lib/server-only/document/get-document-with-details-by-id.ts @@ -1,13 +1,4 @@ -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'; @@ -18,22 +9,11 @@ export type GetDocumentWithDetailsByIdOptions = { teamId?: number; }; -export const ZGetDocumentWithDetailsByIdResponseSchema = DocumentSchema.extend({ - documentData: DocumentDataSchema, - documentMeta: DocumentMetaSchema.nullable(), - recipients: RecipientSchema.array(), - fields: FieldSchema.array(), -}); - -export type TGetDocumentWithDetailsByIdResponse = z.infer< - typeof ZGetDocumentWithDetailsByIdResponseSchema ->; - export const getDocumentWithDetailsById = async ({ documentId, userId, teamId, -}: GetDocumentWithDetailsByIdOptions): Promise => { +}: GetDocumentWithDetailsByIdOptions) => { const documentWhereInput = await getDocumentWhereInput({ documentId, userId, diff --git a/packages/lib/server-only/document/move-document-to-team.ts b/packages/lib/server-only/document/move-document-to-team.ts index 5f8875bc8..921b5ec77 100644 --- a/packages/lib/server-only/document/move-document-to-team.ts +++ b/packages/lib/server-only/document/move-document-to-team.ts @@ -1,8 +1,5 @@ -import type { z } from 'zod'; - import type { ApiRequestMetadata } from '@documenso/lib/universal/extract-request-metadata'; import { prisma } from '@documenso/prisma'; -import { DocumentSchema } from '@documenso/prisma/generated/zod'; import { AppError, AppErrorCode } from '../../errors/app-error'; import { DOCUMENT_AUDIT_LOG_TYPE } from '../../types/document-audit-logs'; @@ -15,16 +12,12 @@ export type MoveDocumentToTeamOptions = { requestMetadata: ApiRequestMetadata; }; -export const ZMoveDocumentToTeamResponseSchema = DocumentSchema; - -export type TMoveDocumentToTeamResponse = z.infer; - export const moveDocumentToTeam = async ({ documentId, teamId, userId, requestMetadata, -}: MoveDocumentToTeamOptions): Promise => { +}: MoveDocumentToTeamOptions) => { return await prisma.$transaction(async (tx) => { const document = await tx.document.findFirst({ where: { diff --git a/packages/lib/server-only/document/send-document.tsx b/packages/lib/server-only/document/send-document.tsx index 0212f7e28..ac91b5441 100644 --- a/packages/lib/server-only/document/send-document.tsx +++ b/packages/lib/server-only/document/send-document.tsx @@ -1,5 +1,3 @@ -import type { z } from 'zod'; - import { DOCUMENT_AUDIT_LOG_TYPE } from '@documenso/lib/types/document-audit-logs'; import type { ApiRequestMetadata } from '@documenso/lib/universal/extract-request-metadata'; import { putPdfFile } from '@documenso/lib/universal/upload/put-file'; @@ -13,11 +11,6 @@ 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'; @@ -37,20 +30,13 @@ export type SendDocumentOptions = { requestMetadata: ApiRequestMetadata; }; -export const ZSendDocumentResponseSchema = DocumentSchema.extend({ - documentMeta: DocumentMetaSchema.nullable(), - recipients: RecipientSchema.array(), -}); - -export type TSendDocumentResponse = z.infer; - export const sendDocument = async ({ documentId, userId, teamId, sendEmail, requestMetadata, -}: SendDocumentOptions): Promise => { +}: SendDocumentOptions) => { const document = await prisma.document.findUnique({ where: { id: documentId, diff --git a/packages/lib/server-only/document/update-document.ts b/packages/lib/server-only/document/update-document.ts index 85c2bd73e..bbacfbe1d 100644 --- a/packages/lib/server-only/document/update-document.ts +++ b/packages/lib/server-only/document/update-document.ts @@ -1,5 +1,4 @@ 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'; @@ -9,7 +8,6 @@ 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,17 +27,13 @@ export type UpdateDocumentOptions = { requestMetadata: ApiRequestMetadata; }; -export const ZUpdateDocumentResponseSchema = DocumentSchema; - -export type TUpdateDocumentResponse = z.infer; - export const updateDocument = async ({ userId, teamId, documentId, data, requestMetadata, -}: UpdateDocumentOptions): Promise => { +}: UpdateDocumentOptions) => { const document = await prisma.document.findFirst({ where: { id: documentId, diff --git a/packages/lib/server-only/field/create-document-fields.ts b/packages/lib/server-only/field/create-document-fields.ts index c3ea8021f..dacf29613 100644 --- a/packages/lib/server-only/field/create-document-fields.ts +++ b/packages/lib/server-only/field/create-document-fields.ts @@ -1,12 +1,9 @@ -import { z } from 'zod'; - import { DOCUMENT_AUDIT_LOG_TYPE } from '@documenso/lib/types/document-audit-logs'; import type { TFieldMetaSchema } from '@documenso/lib/types/field-meta'; import type { ApiRequestMetadata } from '@documenso/lib/universal/extract-request-metadata'; import { createDocumentAuditLogData } from '@documenso/lib/utils/document-audit-logs'; import { prisma } from '@documenso/prisma'; import type { FieldType } from '@documenso/prisma/client'; -import { FieldSchema } from '@documenso/prisma/generated/zod'; import { AppError, AppErrorCode } from '../../errors/app-error'; import { canRecipientFieldsBeModified } from '../../utils/recipients'; @@ -28,19 +25,13 @@ export interface CreateDocumentFieldsOptions { requestMetadata: ApiRequestMetadata; } -export const ZCreateDocumentFieldsResponseSchema = z.object({ - fields: z.array(FieldSchema), -}); - -export type TCreateDocumentFieldsResponse = z.infer; - export const createDocumentFields = async ({ userId, teamId, documentId, fields, requestMetadata, -}: CreateDocumentFieldsOptions): Promise => { +}: CreateDocumentFieldsOptions) => { const document = await prisma.document.findFirst({ where: { id: documentId, diff --git a/packages/lib/server-only/field/create-template-fields.ts b/packages/lib/server-only/field/create-template-fields.ts index ea6091328..0bd392175 100644 --- a/packages/lib/server-only/field/create-template-fields.ts +++ b/packages/lib/server-only/field/create-template-fields.ts @@ -1,9 +1,6 @@ -import { z } from 'zod'; - import type { TFieldMetaSchema } from '@documenso/lib/types/field-meta'; import { prisma } from '@documenso/prisma'; import type { FieldType } from '@documenso/prisma/client'; -import { FieldSchema } from '@documenso/prisma/generated/zod'; import { AppError, AppErrorCode } from '../../errors/app-error'; import { canRecipientFieldsBeModified } from '../../utils/recipients'; @@ -24,18 +21,12 @@ export interface CreateTemplateFieldsOptions { }[]; } -export const ZCreateTemplateFieldsResponseSchema = z.object({ - fields: z.array(FieldSchema), -}); - -export type TCreateTemplateFieldsResponse = z.infer; - export const createTemplateFields = async ({ userId, teamId, templateId, fields, -}: CreateTemplateFieldsOptions): Promise => { +}: CreateTemplateFieldsOptions) => { const template = await prisma.template.findFirst({ where: { id: templateId, diff --git a/packages/lib/server-only/field/get-field-by-id.ts b/packages/lib/server-only/field/get-field-by-id.ts index c29517cb0..4df97868f 100644 --- a/packages/lib/server-only/field/get-field-by-id.ts +++ b/packages/lib/server-only/field/get-field-by-id.ts @@ -1,7 +1,4 @@ -import type { z } from 'zod'; - import { prisma } from '@documenso/prisma'; -import { FieldSchema } from '@documenso/prisma/generated/zod'; import { AppError, AppErrorCode } from '../../errors/app-error'; @@ -13,17 +10,13 @@ export type GetFieldByIdOptions = { templateId?: number; }; -export const ZGetFieldByIdResponseSchema = FieldSchema; - -export type TGetFieldByIdResponse = z.infer; - export const getFieldById = async ({ userId, teamId, fieldId, documentId, templateId, -}: GetFieldByIdOptions): Promise => { +}: GetFieldByIdOptions) => { const field = await prisma.field.findFirst({ where: { id: fieldId, diff --git a/packages/lib/server-only/field/set-fields-for-document.ts b/packages/lib/server-only/field/set-fields-for-document.ts index da3c71dd6..b35deca02 100644 --- a/packages/lib/server-only/field/set-fields-for-document.ts +++ b/packages/lib/server-only/field/set-fields-for-document.ts @@ -1,5 +1,4 @@ import { isDeepEqual } from 'remeda'; -import { z } from 'zod'; import { validateCheckboxField } from '@documenso/lib/advanced-fields-validation/validate-checkbox'; import { validateDropdownField } from '@documenso/lib/advanced-fields-validation/validate-dropdown'; @@ -24,7 +23,6 @@ import { import { prisma } from '@documenso/prisma'; import type { Field } from '@documenso/prisma/client'; import { FieldType } from '@documenso/prisma/client'; -import { FieldSchema } from '@documenso/prisma/generated/zod'; import { AppError, AppErrorCode } from '../../errors/app-error'; import { canRecipientFieldsBeModified } from '../../utils/recipients'; @@ -37,19 +35,13 @@ export interface SetFieldsForDocumentOptions { requestMetadata: ApiRequestMetadata; } -export const ZSetFieldsForDocumentResponseSchema = z.object({ - fields: z.array(FieldSchema), -}); - -export type TSetFieldsForDocumentResponse = z.infer; - export const setFieldsForDocument = async ({ userId, teamId, documentId, fields, requestMetadata, -}: SetFieldsForDocumentOptions): Promise => { +}: SetFieldsForDocumentOptions) => { const document = await prisma.document.findFirst({ where: { id: documentId, diff --git a/packages/lib/server-only/field/set-fields-for-template.ts b/packages/lib/server-only/field/set-fields-for-template.ts index 9b003534e..156f0b359 100644 --- a/packages/lib/server-only/field/set-fields-for-template.ts +++ b/packages/lib/server-only/field/set-fields-for-template.ts @@ -1,5 +1,3 @@ -import { z } from 'zod'; - import { validateCheckboxField } from '@documenso/lib/advanced-fields-validation/validate-checkbox'; import { validateDropdownField } from '@documenso/lib/advanced-fields-validation/validate-dropdown'; import { validateNumberField } from '@documenso/lib/advanced-fields-validation/validate-number'; @@ -16,7 +14,6 @@ import { } from '@documenso/lib/types/field-meta'; import { prisma } from '@documenso/prisma'; import { FieldType } from '@documenso/prisma/client'; -import { FieldSchema } from '@documenso/prisma/generated/zod'; export type SetFieldsForTemplateOptions = { userId: number; @@ -35,18 +32,12 @@ export type SetFieldsForTemplateOptions = { }[]; }; -export const ZSetFieldsForTemplateResponseSchema = z.object({ - fields: z.array(FieldSchema), -}); - -export type TSetFieldsForTemplateResponse = z.infer; - export const setFieldsForTemplate = async ({ userId, teamId, templateId, fields, -}: SetFieldsForTemplateOptions): Promise => { +}: SetFieldsForTemplateOptions) => { const template = await prisma.template.findFirst({ where: { id: templateId, diff --git a/packages/lib/server-only/field/update-document-fields.ts b/packages/lib/server-only/field/update-document-fields.ts index fdad6ae09..0e279f2aa 100644 --- a/packages/lib/server-only/field/update-document-fields.ts +++ b/packages/lib/server-only/field/update-document-fields.ts @@ -1,5 +1,3 @@ -import { z } from 'zod'; - import { DOCUMENT_AUDIT_LOG_TYPE } from '@documenso/lib/types/document-audit-logs'; import type { TFieldMetaSchema } from '@documenso/lib/types/field-meta'; import type { ApiRequestMetadata } from '@documenso/lib/universal/extract-request-metadata'; @@ -9,7 +7,6 @@ import { } from '@documenso/lib/utils/document-audit-logs'; import { prisma } from '@documenso/prisma'; import type { FieldType } from '@documenso/prisma/client'; -import { FieldSchema } from '@documenso/prisma/generated/zod'; import { AppError, AppErrorCode } from '../../errors/app-error'; import { canRecipientFieldsBeModified } from '../../utils/recipients'; @@ -31,19 +28,13 @@ export interface UpdateDocumentFieldsOptions { requestMetadata: ApiRequestMetadata; } -export const ZUpdateDocumentFieldsResponseSchema = z.object({ - fields: z.array(FieldSchema), -}); - -export type TUpdateDocumentFieldsResponse = z.infer; - export const updateDocumentFields = async ({ userId, teamId, documentId, fields, requestMetadata, -}: UpdateDocumentFieldsOptions): Promise => { +}: UpdateDocumentFieldsOptions) => { const document = await prisma.document.findFirst({ where: { id: documentId, diff --git a/packages/lib/server-only/field/update-template-fields.ts b/packages/lib/server-only/field/update-template-fields.ts index 10f65626a..c1b3bc389 100644 --- a/packages/lib/server-only/field/update-template-fields.ts +++ b/packages/lib/server-only/field/update-template-fields.ts @@ -1,9 +1,6 @@ -import { z } from 'zod'; - import type { TFieldMetaSchema } from '@documenso/lib/types/field-meta'; import { prisma } from '@documenso/prisma'; import type { FieldType } from '@documenso/prisma/client'; -import { FieldSchema } from '@documenso/prisma/generated/zod'; import { AppError, AppErrorCode } from '../../errors/app-error'; import { canRecipientFieldsBeModified } from '../../utils/recipients'; @@ -24,18 +21,12 @@ export interface UpdateTemplateFieldsOptions { }[]; } -export const ZUpdateTemplateFieldsResponseSchema = z.object({ - fields: z.array(FieldSchema), -}); - -export type TUpdateTemplateFieldsResponse = z.infer; - export const updateTemplateFields = async ({ userId, teamId, templateId, fields, -}: UpdateTemplateFieldsOptions): Promise => { +}: UpdateTemplateFieldsOptions) => { const template = await prisma.template.findFirst({ where: { id: templateId, diff --git a/packages/lib/server-only/recipient/create-document-recipients.ts b/packages/lib/server-only/recipient/create-document-recipients.ts index 2a55d46ca..cd52b3632 100644 --- a/packages/lib/server-only/recipient/create-document-recipients.ts +++ b/packages/lib/server-only/recipient/create-document-recipients.ts @@ -1,5 +1,3 @@ -import { 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'; import type { TRecipientAccessAuthTypes } from '@documenso/lib/types/document-auth'; @@ -11,7 +9,6 @@ import { createRecipientAuthOptions } from '@documenso/lib/utils/document-auth'; import { prisma } from '@documenso/prisma'; import { RecipientRole } from '@documenso/prisma/client'; import { SendStatus, SigningStatus } from '@documenso/prisma/client'; -import { ZRecipientBaseResponseSchema } from '@documenso/trpc/server/recipient-router/schema'; import { AppError, AppErrorCode } from '../../errors/app-error'; @@ -30,21 +27,13 @@ export interface CreateDocumentRecipientsOptions { requestMetadata: ApiRequestMetadata; } -export const ZCreateDocumentRecipientsResponseSchema = z.object({ - recipients: ZRecipientBaseResponseSchema.array(), -}); - -export type TCreateDocumentRecipientsResponse = z.infer< - typeof ZCreateDocumentRecipientsResponseSchema ->; - export const createDocumentRecipients = async ({ userId, teamId, documentId, recipients: recipientsToCreate, requestMetadata, -}: CreateDocumentRecipientsOptions): Promise => { +}: CreateDocumentRecipientsOptions) => { const document = await prisma.document.findFirst({ where: { id: documentId, diff --git a/packages/lib/server-only/recipient/create-template-recipients.ts b/packages/lib/server-only/recipient/create-template-recipients.ts index 3ff726b99..a843a0adb 100644 --- a/packages/lib/server-only/recipient/create-template-recipients.ts +++ b/packages/lib/server-only/recipient/create-template-recipients.ts @@ -1,5 +1,3 @@ -import { z } from 'zod'; - import { isUserEnterprise } from '@documenso/ee/server-only/util/is-document-enterprise'; import type { TRecipientAccessAuthTypes } from '@documenso/lib/types/document-auth'; import { type TRecipientActionAuthTypes } from '@documenso/lib/types/document-auth'; @@ -8,7 +6,6 @@ import { createRecipientAuthOptions } from '@documenso/lib/utils/document-auth'; import { prisma } from '@documenso/prisma'; import { RecipientRole } from '@documenso/prisma/client'; import { SendStatus, SigningStatus } from '@documenso/prisma/client'; -import { ZRecipientBaseResponseSchema } from '@documenso/trpc/server/recipient-router/schema'; import { AppError, AppErrorCode } from '../../errors/app-error'; @@ -26,20 +23,12 @@ export interface CreateTemplateRecipientsOptions { }[]; } -export const ZCreateTemplateRecipientsResponseSchema = z.object({ - recipients: ZRecipientBaseResponseSchema.array(), -}); - -export type TCreateTemplateRecipientsResponse = z.infer< - typeof ZCreateTemplateRecipientsResponseSchema ->; - export const createTemplateRecipients = async ({ userId, teamId, templateId, recipients: recipientsToCreate, -}: CreateTemplateRecipientsOptions): Promise => { +}: CreateTemplateRecipientsOptions) => { const template = await prisma.template.findFirst({ where: { id: templateId, diff --git a/packages/lib/server-only/recipient/get-recipient-by-id.ts b/packages/lib/server-only/recipient/get-recipient-by-id.ts index f54e7abce..e14c93955 100644 --- a/packages/lib/server-only/recipient/get-recipient-by-id.ts +++ b/packages/lib/server-only/recipient/get-recipient-by-id.ts @@ -1,7 +1,4 @@ -import type { z } from 'zod'; - import { prisma } from '@documenso/prisma'; -import { FieldSchema, RecipientSchema } from '@documenso/prisma/generated/zod'; import { AppError, AppErrorCode } from '../../errors/app-error'; @@ -11,12 +8,6 @@ export type GetRecipientByIdOptions = { teamId?: number; }; -export const ZGetRecipientByIdResponseSchema = RecipientSchema.extend({ - fields: FieldSchema.array(), -}); - -export type TGetRecipientByIdResponse = z.infer; - /** * Get a recipient by ID. This will also return the recipient signing token so * be careful when using this. @@ -25,7 +16,7 @@ export const getRecipientById = async ({ recipientId, userId, teamId, -}: GetRecipientByIdOptions): Promise => { +}: GetRecipientByIdOptions) => { const recipient = await prisma.recipient.findFirst({ where: { id: recipientId, diff --git a/packages/lib/server-only/recipient/set-document-recipients.ts b/packages/lib/server-only/recipient/set-document-recipients.ts index 3a7eeed34..78ca3f176 100644 --- a/packages/lib/server-only/recipient/set-document-recipients.ts +++ b/packages/lib/server-only/recipient/set-document-recipients.ts @@ -1,7 +1,6 @@ import { createElement } from 'react'; import { msg } from '@lingui/macro'; -import { z } from 'zod'; import { isUserEnterprise } from '@documenso/ee/server-only/util/is-document-enterprise'; import { mailer } from '@documenso/email/mailer'; @@ -23,7 +22,6 @@ import { prisma } from '@documenso/prisma'; import type { Recipient } from '@documenso/prisma/client'; import { RecipientRole } from '@documenso/prisma/client'; import { SendStatus, SigningStatus } from '@documenso/prisma/client'; -import { RecipientSchema } from '@documenso/prisma/generated/zod'; import { getI18nInstance } from '../../client-only/providers/i18n.server'; import { NEXT_PUBLIC_WEBAPP_URL } from '../../constants/app'; @@ -42,19 +40,13 @@ export interface SetDocumentRecipientsOptions { requestMetadata: ApiRequestMetadata; } -export const ZSetDocumentRecipientsResponseSchema = z.object({ - recipients: RecipientSchema.array(), -}); - -export type TSetDocumentRecipientsResponse = z.infer; - export const setDocumentRecipients = async ({ userId, teamId, documentId, recipients, requestMetadata, -}: SetDocumentRecipientsOptions): Promise => { +}: SetDocumentRecipientsOptions) => { const document = await prisma.document.findFirst({ where: { id: documentId, diff --git a/packages/lib/server-only/recipient/set-template-recipients.ts b/packages/lib/server-only/recipient/set-template-recipients.ts index 4de8683a8..d4bb8cb8e 100644 --- a/packages/lib/server-only/recipient/set-template-recipients.ts +++ b/packages/lib/server-only/recipient/set-template-recipients.ts @@ -1,5 +1,3 @@ -import { z } from 'zod'; - import { isUserEnterprise } from '@documenso/ee/server-only/util/is-document-enterprise'; import { DIRECT_TEMPLATE_RECIPIENT_EMAIL, @@ -8,7 +6,6 @@ import { import { prisma } from '@documenso/prisma'; import type { Recipient } from '@documenso/prisma/client'; import { RecipientRole } from '@documenso/prisma/client'; -import { RecipientSchema } from '@documenso/prisma/generated/zod'; import { AppError, AppErrorCode } from '../../errors/app-error'; import { @@ -32,18 +29,12 @@ export type SetTemplateRecipientsOptions = { }[]; }; -export const ZSetTemplateRecipientsResponseSchema = z.object({ - recipients: RecipientSchema.array(), -}); - -export type TSetTemplateRecipientsResponse = z.infer; - export const setTemplateRecipients = async ({ userId, teamId, templateId, recipients, -}: SetTemplateRecipientsOptions): Promise => { +}: SetTemplateRecipientsOptions) => { const template = await prisma.template.findFirst({ where: { id: templateId, diff --git a/packages/lib/server-only/recipient/update-document-recipients.ts b/packages/lib/server-only/recipient/update-document-recipients.ts index 25be1b6de..62f53fbf9 100644 --- a/packages/lib/server-only/recipient/update-document-recipients.ts +++ b/packages/lib/server-only/recipient/update-document-recipients.ts @@ -1,5 +1,3 @@ -import { 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'; import type { TRecipientAccessAuthTypes } from '@documenso/lib/types/document-auth'; @@ -17,7 +15,6 @@ import { prisma } from '@documenso/prisma'; import type { Recipient } from '@documenso/prisma/client'; import { RecipientRole } from '@documenso/prisma/client'; import { SendStatus, SigningStatus } from '@documenso/prisma/client'; -import { ZRecipientResponseSchema } from '@documenso/trpc/server/recipient-router/schema'; import { AppError, AppErrorCode } from '../../errors/app-error'; import { canRecipientBeModified } from '../../utils/recipients'; @@ -30,21 +27,13 @@ export interface UpdateDocumentRecipientsOptions { requestMetadata: ApiRequestMetadata; } -export const ZUpdateDocumentRecipientsResponseSchema = z.object({ - recipients: ZRecipientResponseSchema.array(), -}); - -export type TUpdateDocumentRecipientsResponse = z.infer< - typeof ZUpdateDocumentRecipientsResponseSchema ->; - export const updateDocumentRecipients = async ({ userId, teamId, documentId, recipients, requestMetadata, -}: UpdateDocumentRecipientsOptions): Promise => { +}: UpdateDocumentRecipientsOptions) => { const document = await prisma.document.findFirst({ where: { id: documentId, diff --git a/packages/lib/server-only/recipient/update-template-recipients.ts b/packages/lib/server-only/recipient/update-template-recipients.ts index 3f1444664..de9b90383 100644 --- a/packages/lib/server-only/recipient/update-template-recipients.ts +++ b/packages/lib/server-only/recipient/update-template-recipients.ts @@ -1,5 +1,3 @@ -import { z } from 'zod'; - import { isUserEnterprise } from '@documenso/ee/server-only/util/is-document-enterprise'; import type { TRecipientAccessAuthTypes } from '@documenso/lib/types/document-auth'; import { @@ -10,7 +8,6 @@ import { createRecipientAuthOptions } from '@documenso/lib/utils/document-auth'; import { prisma } from '@documenso/prisma'; import { RecipientRole } from '@documenso/prisma/client'; import { SendStatus, SigningStatus } from '@documenso/prisma/client'; -import { ZRecipientResponseSchema } from '@documenso/trpc/server/recipient-router/schema'; import { AppError, AppErrorCode } from '../../errors/app-error'; @@ -29,20 +26,12 @@ export interface UpdateTemplateRecipientsOptions { }[]; } -export const ZUpdateTemplateRecipientsResponseSchema = z.object({ - recipients: ZRecipientResponseSchema.array(), -}); - -export type TUpdateTemplateRecipientsResponse = z.infer< - typeof ZUpdateTemplateRecipientsResponseSchema ->; - export const updateTemplateRecipients = async ({ userId, teamId, templateId, recipients, -}: UpdateTemplateRecipientsOptions): Promise => { +}: UpdateTemplateRecipientsOptions) => { const template = await prisma.template.findFirst({ where: { id: templateId, diff --git a/packages/lib/server-only/template/create-document-from-template.ts b/packages/lib/server-only/template/create-document-from-template.ts index 05fa23db1..470e909e5 100644 --- a/packages/lib/server-only/template/create-document-from-template.ts +++ b/packages/lib/server-only/template/create-document-from-template.ts @@ -1,5 +1,3 @@ -import type { z } from 'zod'; - import { nanoid } from '@documenso/lib/universal/id'; import { prisma } from '@documenso/prisma'; import type { DocumentDistributionMethod } from '@documenso/prisma/client'; @@ -13,11 +11,6 @@ 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'; @@ -79,15 +72,6 @@ export type CreateDocumentFromTemplateOptions = { requestMetadata: ApiRequestMetadata; }; -export const ZCreateDocumentFromTemplateResponseSchema = DocumentSchema.extend({ - documentData: DocumentDataSchema, - recipients: RecipientSchema.array(), -}); - -export type TCreateDocumentFromTemplateResponse = z.infer< - typeof ZCreateDocumentFromTemplateResponseSchema ->; - export const createDocumentFromTemplate = async ({ templateId, externalId, @@ -97,7 +81,7 @@ export const createDocumentFromTemplate = async ({ customDocumentDataId, override, requestMetadata, -}: CreateDocumentFromTemplateOptions): Promise => { +}: CreateDocumentFromTemplateOptions) => { const template = await prisma.template.findUnique({ where: { id: templateId, diff --git a/packages/lib/types/document.ts b/packages/lib/types/document.ts new file mode 100644 index 000000000..830842e83 --- /dev/null +++ b/packages/lib/types/document.ts @@ -0,0 +1,118 @@ +import type { z } from 'zod'; + +import { + DocumentDataSchema, + DocumentMetaSchema, + DocumentSchema, + TeamSchema, + UserSchema, +} from '@documenso/prisma/generated/zod'; + +import { ZFieldSchema } from './field'; +import { ZRecipientLiteSchema } from './recipient'; + +/** + * The full document response schema. + * + * Mainly used for returning a single document from the API. + */ +export const ZDocumentSchema = DocumentSchema.pick({ + visibility: true, + status: true, + source: true, + id: true, + externalId: true, + userId: true, + authOptions: true, + formValues: true, + title: true, + documentDataId: true, + createdAt: true, + updatedAt: true, + completedAt: true, + deletedAt: true, + teamId: true, + templateId: true, +}).extend({ + // Todo: Maybe we want to alter this a bit since this returns a lot of data. + documentData: DocumentDataSchema.pick({ + type: true, + id: true, + data: true, + initialData: true, + }), + documentMeta: DocumentMetaSchema.pick({ + signingOrder: true, + distributionMethod: true, + id: true, + subject: true, + message: true, + timezone: true, + password: true, + dateFormat: true, + documentId: true, + redirectUrl: true, + typedSignatureEnabled: true, + language: true, + emailSettings: true, + }).nullable(), + recipients: ZRecipientLiteSchema.array(), + fields: ZFieldSchema.array(), +}); + +export type TDocument = z.infer; + +/** + * A lite version of the document response schema without relations. + */ +export const ZDocumentLiteSchema = DocumentSchema.pick({ + visibility: true, + status: true, + source: true, + id: true, + externalId: true, + userId: true, + authOptions: true, + formValues: true, + title: true, + documentDataId: true, + createdAt: true, + updatedAt: true, + completedAt: true, + deletedAt: true, + teamId: true, + templateId: true, +}); + +/** + * A version of the document response schema when returning multiple documents at once from a single API endpoint. + */ +export const ZDocumentManySchema = DocumentSchema.pick({ + visibility: true, + status: true, + source: true, + id: true, + externalId: true, + userId: true, + authOptions: true, + formValues: true, + title: true, + documentDataId: true, + createdAt: true, + updatedAt: true, + completedAt: true, + deletedAt: true, + teamId: true, + templateId: true, +}).extend({ + user: UserSchema.pick({ + id: true, + name: true, + email: true, + }), + recipients: ZRecipientLiteSchema.array(), + team: TeamSchema.pick({ + id: true, + url: true, + }).nullable(), +}); diff --git a/packages/lib/types/field.ts b/packages/lib/types/field.ts new file mode 100644 index 000000000..cdbf00f35 --- /dev/null +++ b/packages/lib/types/field.ts @@ -0,0 +1,30 @@ +import { FieldSchema } from '@documenso/prisma/generated/zod'; + +/** + * The full field response schema. + * + * If you need to return something different, adjust this file to utilise the: + * - ZFieldSchema + * - ZFieldLiteSchema + * - ZFieldManySchema + * + * Setup similar to: + * - ./documents.ts + * - ./templates.ts + */ +export const ZFieldSchema = FieldSchema.pick({ + type: true, + id: true, + secondaryId: true, + documentId: true, + templateId: true, + recipientId: true, + page: true, + positionX: true, + positionY: true, + width: true, + height: true, + customText: true, + inserted: true, + fieldMeta: true, +}); diff --git a/packages/lib/types/recipient.ts b/packages/lib/types/recipient.ts new file mode 100644 index 000000000..3c0fa944f --- /dev/null +++ b/packages/lib/types/recipient.ts @@ -0,0 +1,85 @@ +import { TeamSchema, UserSchema } from '@documenso/prisma/generated/zod'; +import RecipientSchema from '@documenso/prisma/generated/zod/modelSchema/RecipientSchema'; + +import { ZFieldSchema } from './field'; + +/** + * The full recipient response schema. + * + * Mainly used for returning a single recipient from the API. + */ +export const ZRecipientSchema = RecipientSchema.pick({ + role: true, + readStatus: true, + signingStatus: true, + sendStatus: true, + id: true, + documentId: true, + templateId: true, + email: true, + name: true, + token: true, + documentDeletedAt: true, + expired: true, + signedAt: true, + authOptions: true, + signingOrder: true, + rejectionReason: true, +}).extend({ + fields: ZFieldSchema.array(), +}); + +/** + * A lite version of the recipient response schema without relations. + */ +export const ZRecipientLiteSchema = RecipientSchema.pick({ + role: true, + readStatus: true, + signingStatus: true, + sendStatus: true, + id: true, + documentId: true, + templateId: true, + email: true, + name: true, + token: true, + documentDeletedAt: true, + expired: true, + signedAt: true, + authOptions: true, + signingOrder: true, + rejectionReason: true, +}); + +/** + * A version of the recipient response schema when returning multiple recipients at once from a single API endpoint. + */ +export const ZRecipientManySchema = RecipientSchema.pick({ + role: true, + readStatus: true, + signingStatus: true, + sendStatus: true, + id: true, + documentId: true, + templateId: true, + email: true, + name: true, + token: true, + documentDeletedAt: true, + expired: true, + signedAt: true, + authOptions: true, + signingOrder: true, + rejectionReason: true, +}).extend({ + user: UserSchema.pick({ + id: true, + name: true, + email: true, + }), + recipients: RecipientSchema.array(), + team: TeamSchema.pick({ + id: true, + url: true, + }).nullable(), +}); diff --git a/packages/prisma/package.json b/packages/prisma/package.json index 5a5ff6d1d..c78e5a18c 100644 --- a/packages/prisma/package.json +++ b/packages/prisma/package.json @@ -33,6 +33,6 @@ "prisma-kysely": "^1.8.0", "tsx": "^4.11.0", "typescript": "5.2.2", - "zod-prisma-types": "^3.1.8" + "zod-prisma-types": "3.1.9" } -} +} \ No newline at end of file diff --git a/packages/prisma/schema.prisma b/packages/prisma/schema.prisma index 72291b1a5..a65692f37 100644 --- a/packages/prisma/schema.prisma +++ b/packages/prisma/schema.prisma @@ -7,7 +7,10 @@ generator client { } generator zod { - provider = "zod-prisma-types" + provider = "zod-prisma-types" + createInputTypes = false + writeBarrelFiles = true + useMultipleFiles = true } datasource db { @@ -294,12 +297,13 @@ enum DocumentVisibility { ADMIN } +/// @zod.import(["import { ZDocumentAuthOptionsSchema } from '@documenso/lib/types/document-auth';"]) model Document { id Int @id @default(autoincrement()) - externalId String? - userId Int + externalId String? /// @zod.string.describe("A custom external ID you can use to identify the document.") + userId Int /// @zod.number.describe("The ID of the user that created this document.") user User @relation(fields: [userId], references: [id], onDelete: Cascade) - authOptions Json? + authOptions Json? /// Todo: zod.custom.use(ZDocumentAuthOptionsSchema.describe("Hello")) formValues Json? visibility DocumentVisibility @default(EVERYONE) title String @@ -409,6 +413,7 @@ enum RecipientRole { APPROVER } +/// @zod.import(["import { ZRecipientAuthOptionsSchema } from '@documenso/lib/types/document-auth';"]) model Recipient { id Int @id @default(autoincrement()) documentId Int? @@ -419,8 +424,8 @@ model Recipient { documentDeletedAt DateTime? expired DateTime? signedAt DateTime? - authOptions Json? - signingOrder Int? + authOptions Json? /// Todo: zod.custom.use(ZRecipientAuthOptionsSchema) + signingOrder Int? /// @zod.number.describe("The order in which the recipient should sign the document. Only works if the document is set to sequential signing.") rejectionReason String? role RecipientRole @default(SIGNER) readStatus ReadStatus @default(NOT_OPENED) @@ -459,7 +464,7 @@ model Field { templateId Int? recipientId Int type FieldType - page Int + page Int /// @zod.number.describe("The page number of the field on the document. Starts from 1.") positionX Decimal @default(0) positionY Decimal @default(0) width Decimal @default(-1) @@ -470,7 +475,7 @@ model Field { template Template? @relation(fields: [templateId], references: [id], onDelete: Cascade) recipient Recipient @relation(fields: [recipientId], references: [id], onDelete: Cascade) signature Signature? - fieldMeta Json? + fieldMeta Json? // Todo: Fix ZFieldMetaSchema before using it here. @@index([documentId]) @@index([templateId]) diff --git a/packages/trpc/server/document-router/router.ts b/packages/trpc/server/document-router/router.ts index 3e254bb32..3cf176d4c 100644 --- a/packages/trpc/server/document-router/router.ts +++ b/packages/trpc/server/document-router/router.ts @@ -8,63 +8,47 @@ import { DOCUMENSO_ENCRYPTION_KEY } from '@documenso/lib/constants/crypto'; import { AppError } from '@documenso/lib/errors/app-error'; import { encryptSecondaryData } from '@documenso/lib/server-only/crypto/encrypt'; import { upsertDocumentMeta } from '@documenso/lib/server-only/document-meta/upsert-document-meta'; -import { - ZCreateDocumentResponseSchema, - createDocument, -} from '@documenso/lib/server-only/document/create-document'; +import { createDocument } from '@documenso/lib/server-only/document/create-document'; import { deleteDocument } from '@documenso/lib/server-only/document/delete-document'; -import { - ZDuplicateDocumentResponseSchema, - duplicateDocument, -} from '@documenso/lib/server-only/document/duplicate-document-by-id'; +import { duplicateDocument } from '@documenso/lib/server-only/document/duplicate-document-by-id'; import { findDocumentAuditLogs } from '@documenso/lib/server-only/document/find-document-audit-logs'; -import { - ZFindDocumentsResponseSchema, - findDocuments, -} from '@documenso/lib/server-only/document/find-documents'; +import { findDocuments } from '@documenso/lib/server-only/document/find-documents'; import { getDocumentById } from '@documenso/lib/server-only/document/get-document-by-id'; import { getDocumentAndSenderByToken } from '@documenso/lib/server-only/document/get-document-by-token'; -import { - ZGetDocumentWithDetailsByIdResponseSchema, - getDocumentWithDetailsById, -} from '@documenso/lib/server-only/document/get-document-with-details-by-id'; -import { - ZMoveDocumentToTeamResponseSchema, - moveDocumentToTeam, -} from '@documenso/lib/server-only/document/move-document-to-team'; +import { getDocumentWithDetailsById } from '@documenso/lib/server-only/document/get-document-with-details-by-id'; +import { moveDocumentToTeam } from '@documenso/lib/server-only/document/move-document-to-team'; import { resendDocument } from '@documenso/lib/server-only/document/resend-document'; import { searchDocumentsWithKeyword } from '@documenso/lib/server-only/document/search-documents-with-keyword'; -import { - ZSendDocumentResponseSchema, - sendDocument, -} from '@documenso/lib/server-only/document/send-document'; -import { - ZUpdateDocumentResponseSchema, - updateDocument, -} from '@documenso/lib/server-only/document/update-document'; +import { sendDocument } from '@documenso/lib/server-only/document/send-document'; +import { updateDocument } from '@documenso/lib/server-only/document/update-document'; import { symmetricEncrypt } from '@documenso/lib/universal/crypto'; import { DocumentStatus } from '@documenso/prisma/client'; import { authenticatedProcedure, procedure, router } from '../trpc'; import { - ZCreateDocumentMutationSchema, + ZCreateDocumentRequestSchema, ZDeleteDocumentMutationSchema, + ZDistributeDocumentRequestSchema, + ZDistributeDocumentResponseSchema, ZDownloadAuditLogsMutationSchema, ZDownloadCertificateMutationSchema, - ZDuplicateDocumentMutationSchema, + ZDuplicateDocumentRequestSchema, + ZDuplicateDocumentResponseSchema, ZFindDocumentAuditLogsQuerySchema, - ZFindDocumentsQuerySchema, + ZFindDocumentsRequestSchema, + ZFindDocumentsResponseSchema, ZGetDocumentByIdQuerySchema, ZGetDocumentByTokenQuerySchema, - ZGetDocumentWithDetailsByIdQuerySchema, + ZGetDocumentWithDetailsByIdRequestSchema, + ZGetDocumentWithDetailsByIdResponseSchema, + ZMoveDocumentToTeamResponseSchema, ZMoveDocumentToTeamSchema, ZResendDocumentMutationSchema, ZSearchDocumentsMutationSchema, - ZSendDocumentMutationSchema, ZSetPasswordForDocumentMutationSchema, ZSetSigningOrderForDocumentMutationSchema, ZUpdateDocumentRequestSchema, - ZUpdateTypedSignatureSettingsMutationSchema, + ZUpdateDocumentResponseSchema, } from './schema'; export const documentRouter = router({ @@ -111,7 +95,7 @@ export const documentRouter = router({ tags: ['Document'], }, }) - .input(ZFindDocumentsQuerySchema) + .input(ZFindDocumentsRequestSchema) .output(ZFindDocumentsResponseSchema) .query(async ({ input, ctx }) => { const { user, teamId } = ctx; @@ -149,7 +133,7 @@ export const documentRouter = router({ tags: ['Document'], }, }) - .input(ZGetDocumentWithDetailsByIdQuerySchema) + .input(ZGetDocumentWithDetailsByIdRequestSchema) .output(ZGetDocumentWithDetailsByIdResponseSchema) .query(async ({ input, ctx }) => { const { teamId, user } = ctx; @@ -176,8 +160,7 @@ export const documentRouter = router({ // tags: ['Document'], // }, // }) - .input(ZCreateDocumentMutationSchema) - .output(ZCreateDocumentResponseSchema) + .input(ZCreateDocumentRequestSchema) .mutation(async ({ input, ctx }) => { const { teamId } = ctx; const { title, documentDataId, timezone } = input; @@ -353,39 +336,6 @@ export const documentRouter = router({ }); }), - /** - * @deprecated Remove after deployment. - * - * @private - */ - updateTypedSignatureSettings: authenticatedProcedure - .input(ZUpdateTypedSignatureSettingsMutationSchema) - .mutation(async ({ input, ctx }) => { - const { teamId } = ctx; - const { documentId, typedSignatureEnabled } = input; - - const document = await getDocumentById({ - documentId, - teamId, - userId: ctx.user.id, - }).catch(() => null); - - if (!document) { - throw new TRPCError({ - code: 'NOT_FOUND', - message: 'Document not found', - }); - } - - return await upsertDocumentMeta({ - userId: ctx.user.id, - teamId, - documentId, - typedSignatureEnabled, - requestMetadata: ctx.metadata, - }); - }), - /** * @public * @@ -402,8 +352,8 @@ export const documentRouter = router({ tags: ['Document'], }, }) - .input(ZSendDocumentMutationSchema) - .output(ZSendDocumentResponseSchema) + .input(ZDistributeDocumentRequestSchema) + .output(ZDistributeDocumentResponseSchema) .mutation(async ({ input, ctx }) => { const { teamId } = ctx; const { documentId, meta = {} } = input; @@ -476,7 +426,7 @@ export const documentRouter = router({ tags: ['Document'], }, }) - .input(ZDuplicateDocumentMutationSchema) + .input(ZDuplicateDocumentRequestSchema) .output(ZDuplicateDocumentResponseSchema) .mutation(async ({ input, ctx }) => { const { teamId, user } = ctx; diff --git a/packages/trpc/server/document-router/schema.ts b/packages/trpc/server/document-router/schema.ts index 565399a45..ddb9bea72 100644 --- a/packages/trpc/server/document-router/schema.ts +++ b/packages/trpc/server/document-router/schema.ts @@ -1,12 +1,17 @@ import { z } from 'zod'; import { SUPPORTED_LANGUAGE_CODES } from '@documenso/lib/constants/i18n'; +import { + ZDocumentLiteSchema, + ZDocumentManySchema, + ZDocumentSchema, +} from '@documenso/lib/types/document'; import { ZDocumentAccessAuthTypesSchema, ZDocumentActionAuthTypesSchema, } from '@documenso/lib/types/document-auth'; import { ZDocumentEmailSettingsSchema } from '@documenso/lib/types/document-email'; -import { ZFindSearchParamsSchema } from '@documenso/lib/types/search-params'; +import { ZFindResultResponse, ZFindSearchParamsSchema } from '@documenso/lib/types/search-params'; import { isValidRedirectUrl } from '@documenso/lib/utils/is-valid-redirect-url'; import { DocumentDistributionMethod, @@ -17,7 +22,6 @@ import { FieldType, } from '@documenso/prisma/client'; -// Todo: Refactor all to ZDocumentMeta--- export const ZDocumentMetaTimezoneSchema = z .string() .describe('The timezone to use for date fields and signing the document.'); @@ -53,7 +57,7 @@ export const ZDocumentMetaTypedSignatureEnabledSchema = z .boolean() .describe('Whether to allow typed signatures.'); -export const ZFindDocumentsQuerySchema = ZFindSearchParamsSchema.extend({ +export const ZFindDocumentsRequestSchema = ZFindSearchParamsSchema.extend({ templateId: z .number() .describe('Filter documents by the template ID used to create it.') @@ -70,6 +74,12 @@ export const ZFindDocumentsQuerySchema = ZFindSearchParamsSchema.extend({ orderByDirection: z.enum(['asc', 'desc']).describe('').default('desc'), }); +export const ZFindDocumentsResponseSchema = ZFindResultResponse.extend({ + data: ZDocumentManySchema.array(), +}); + +export type TFindDocumentsResponse = z.infer; + export const ZFindDocumentAuditLogsQuerySchema = ZFindSearchParamsSchema.extend({ documentId: z.number().min(1), cursor: z.string().optional(), @@ -82,11 +92,13 @@ export const ZGetDocumentByIdQuerySchema = z.object({ documentId: z.number(), }); -export const ZDuplicateDocumentMutationSchema = z.object({ +export const ZDuplicateDocumentRequestSchema = z.object({ documentId: z.number(), }); -export type TGetDocumentByIdQuerySchema = z.infer; +export const ZDuplicateDocumentResponseSchema = z.object({ + documentId: z.number(), +}); export const ZGetDocumentByTokenQuerySchema = z.object({ token: z.string().min(1), @@ -94,22 +106,18 @@ export const ZGetDocumentByTokenQuerySchema = z.object({ export type TGetDocumentByTokenQuerySchema = z.infer; -export const ZGetDocumentWithDetailsByIdQuerySchema = z.object({ +export const ZGetDocumentWithDetailsByIdRequestSchema = z.object({ documentId: z.number(), }); -export type TGetDocumentWithDetailsByIdQuerySchema = z.infer< - typeof ZGetDocumentWithDetailsByIdQuerySchema ->; +export const ZGetDocumentWithDetailsByIdResponseSchema = ZDocumentSchema; -export const ZCreateDocumentMutationSchema = z.object({ +export const ZCreateDocumentRequestSchema = z.object({ title: z.string().min(1), documentDataId: z.string().min(1), timezone: z.string().optional(), }); -export type TCreateDocumentMutationSchema = z.infer; - export const ZUpdateDocumentRequestSchema = z.object({ documentId: z.number(), data: z @@ -139,7 +147,7 @@ export const ZUpdateDocumentRequestSchema = z.object({ .optional(), }); -export type TUpdateDocumentRequestSchema = z.infer; +export const ZUpdateDocumentResponseSchema = ZDocumentLiteSchema; export const ZSetFieldsForDocumentMutationSchema = z.object({ documentId: z.number(), @@ -161,7 +169,7 @@ export type TSetFieldsForDocumentMutationSchema = z.infer< typeof ZSetFieldsForDocumentMutationSchema >; -export const ZSendDocumentMutationSchema = z.object({ +export const ZDistributeDocumentRequestSchema = z.object({ documentId: z.number().describe('The ID of the document to send.'), meta: z .object({ @@ -177,6 +185,8 @@ export const ZSendDocumentMutationSchema = z.object({ .optional(), }); +export const ZDistributeDocumentResponseSchema = ZDocumentLiteSchema; + export const ZSetPasswordForDocumentMutationSchema = z.object({ documentId: z.number(), password: z.string(), @@ -195,15 +205,6 @@ export type TSetSigningOrderForDocumentMutationSchema = z.infer< typeof ZSetSigningOrderForDocumentMutationSchema >; -export const ZUpdateTypedSignatureSettingsMutationSchema = z.object({ - documentId: z.number(), - typedSignatureEnabled: z.boolean(), -}); - -export type TUpdateTypedSignatureSettingsMutationSchema = z.infer< - typeof ZUpdateTypedSignatureSettingsMutationSchema ->; - export const ZResendDocumentMutationSchema = z.object({ documentId: z.number(), recipients: z @@ -212,8 +213,6 @@ export const ZResendDocumentMutationSchema = z.object({ .describe('The IDs of the recipients to redistribute the document to.'), }); -export type TSendDocumentMutationSchema = z.infer; - export const ZDeleteDocumentMutationSchema = z.object({ documentId: z.number(), }); @@ -236,3 +235,5 @@ export const ZMoveDocumentToTeamSchema = z.object({ documentId: z.number().describe('The ID of the document to move to a team.'), teamId: z.number().describe('The ID of the team to move the document to.'), }); + +export const ZMoveDocumentToTeamResponseSchema = ZDocumentLiteSchema; diff --git a/packages/trpc/server/field-router/router.ts b/packages/trpc/server/field-router/router.ts index 31bfc92ab..5bd3c7089 100644 --- a/packages/trpc/server/field-router/router.ts +++ b/packages/trpc/server/field-router/router.ts @@ -1,60 +1,46 @@ import { z } from 'zod'; -import { - ZCreateDocumentFieldsResponseSchema, - createDocumentFields, -} from '@documenso/lib/server-only/field/create-document-fields'; -import { - ZCreateTemplateFieldsResponseSchema, - createTemplateFields, -} from '@documenso/lib/server-only/field/create-template-fields'; +import { createDocumentFields } from '@documenso/lib/server-only/field/create-document-fields'; +import { createTemplateFields } from '@documenso/lib/server-only/field/create-template-fields'; import { deleteDocumentField } from '@documenso/lib/server-only/field/delete-document-field'; import { deleteTemplateField } from '@documenso/lib/server-only/field/delete-template-field'; -import { - ZGetFieldByIdResponseSchema, - getFieldById, -} from '@documenso/lib/server-only/field/get-field-by-id'; +import { getFieldById } from '@documenso/lib/server-only/field/get-field-by-id'; import { removeSignedFieldWithToken } from '@documenso/lib/server-only/field/remove-signed-field-with-token'; -import { - ZSetFieldsForDocumentResponseSchema, - setFieldsForDocument, -} from '@documenso/lib/server-only/field/set-fields-for-document'; -import { - ZSetFieldsForTemplateResponseSchema, - setFieldsForTemplate, -} from '@documenso/lib/server-only/field/set-fields-for-template'; +import { setFieldsForDocument } from '@documenso/lib/server-only/field/set-fields-for-document'; +import { setFieldsForTemplate } from '@documenso/lib/server-only/field/set-fields-for-template'; import { signFieldWithToken } from '@documenso/lib/server-only/field/sign-field-with-token'; -import { - ZUpdateDocumentFieldsResponseSchema, - updateDocumentFields, -} from '@documenso/lib/server-only/field/update-document-fields'; -import { - ZUpdateTemplateFieldsResponseSchema, - updateTemplateFields, -} from '@documenso/lib/server-only/field/update-template-fields'; +import { updateDocumentFields } from '@documenso/lib/server-only/field/update-document-fields'; +import { updateTemplateFields } from '@documenso/lib/server-only/field/update-template-fields'; import { extractNextApiRequestMetadata } from '@documenso/lib/universal/extract-request-metadata'; import { authenticatedProcedure, procedure, router } from '../trpc'; import { - ZAddFieldsMutationSchema, - ZAddTemplateFieldsMutationSchema, ZCreateDocumentFieldRequestSchema, ZCreateDocumentFieldResponseSchema, ZCreateDocumentFieldsRequestSchema, + ZCreateDocumentFieldsResponseSchema, ZCreateTemplateFieldRequestSchema, ZCreateTemplateFieldResponseSchema, ZCreateTemplateFieldsRequestSchema, + ZCreateTemplateFieldsResponseSchema, ZDeleteDocumentFieldRequestSchema, ZDeleteTemplateFieldRequestSchema, - ZGetFieldQuerySchema, + ZGetFieldRequestSchema, + ZGetFieldResponseSchema, ZRemovedSignedFieldWithTokenMutationSchema, + ZSetDocumentFieldsRequestSchema, + ZSetDocumentFieldsResponseSchema, + ZSetFieldsForTemplateRequestSchema, + ZSetFieldsForTemplateResponseSchema, ZSignFieldWithTokenMutationSchema, ZUpdateDocumentFieldRequestSchema, ZUpdateDocumentFieldResponseSchema, ZUpdateDocumentFieldsRequestSchema, + ZUpdateDocumentFieldsResponseSchema, ZUpdateTemplateFieldRequestSchema, ZUpdateTemplateFieldResponseSchema, ZUpdateTemplateFieldsRequestSchema, + ZUpdateTemplateFieldsResponseSchema, } from './schema'; export const fieldRouter = router({ @@ -72,8 +58,8 @@ export const fieldRouter = router({ tags: ['Document Fields', 'Template Fields'], }, }) - .input(ZGetFieldQuerySchema) - .output(ZGetFieldByIdResponseSchema) + .input(ZGetFieldRequestSchema) + .output(ZGetFieldResponseSchema) .query(async ({ input, ctx }) => { const { teamId } = ctx; const { fieldId } = input; @@ -229,6 +215,8 @@ export const fieldRouter = router({ /** * @private + * + * Todo: Refactor to setFieldsForDocument function. */ addFields: authenticatedProcedure // .meta({ @@ -239,8 +227,8 @@ export const fieldRouter = router({ // tags: ['Document Fields'], // }, // }) - .input(ZAddFieldsMutationSchema) - .output(ZSetFieldsForDocumentResponseSchema) + .input(ZSetDocumentFieldsRequestSchema) + .output(ZSetDocumentFieldsResponseSchema) .mutation(async ({ input, ctx }) => { const { teamId } = ctx; const { documentId, fields } = input; @@ -403,6 +391,8 @@ export const fieldRouter = router({ /** * @private + * + * Todo: Refactor to setFieldsForTemplate. */ addTemplateFields: authenticatedProcedure // .meta({ @@ -413,7 +403,7 @@ export const fieldRouter = router({ // tags: ['Template Fields'], // }, // }) - .input(ZAddTemplateFieldsMutationSchema) + .input(ZSetFieldsForTemplateRequestSchema) .output(ZSetFieldsForTemplateResponseSchema) .mutation(async ({ input, ctx }) => { const { teamId } = ctx; diff --git a/packages/trpc/server/field-router/schema.ts b/packages/trpc/server/field-router/schema.ts index feaa20f95..6f38cb08a 100644 --- a/packages/trpc/server/field-router/schema.ts +++ b/packages/trpc/server/field-router/schema.ts @@ -1,13 +1,13 @@ import { z } from 'zod'; import { ZRecipientActionAuthSchema } from '@documenso/lib/types/document-auth'; +import { ZFieldSchema } from '@documenso/lib/types/field'; import { ZFieldMetaSchema } from '@documenso/lib/types/field-meta'; import { FieldType } from '@documenso/prisma/client'; -import { FieldSchema } from '@documenso/prisma/generated/zod'; const ZCreateFieldSchema = z.object({ recipientId: z.number().describe('The ID of the recipient to create the field for.'), - type: FieldSchema.shape.type.describe('The type of the field to create.'), + type: ZFieldSchema.shape.type.describe('The type of the field to create.'), pageNumber: z.number().describe('The page number the field will be on.'), pageX: z.number().describe('The X coordinate of where the field will be placed.'), pageY: z.number().describe('The Y coordinate of where the field will be placed.'), @@ -18,7 +18,7 @@ const ZCreateFieldSchema = z.object({ const ZUpdateFieldSchema = z.object({ id: z.number().describe('The ID of the field to update.'), - type: FieldSchema.shape.type.optional().describe('The type of the field to update.'), + type: ZFieldSchema.shape.type.optional().describe('The type of the field to update.'), pageNumber: z.number().optional().describe('The page number the field will be on.'), pageX: z.number().optional().describe('The X coordinate of where the field will be placed.'), pageY: z.number().optional().describe('The Y coordinate of where the field will be placed.'), @@ -28,59 +28,78 @@ const ZUpdateFieldSchema = z.object({ }); export const ZCreateDocumentFieldRequestSchema = z.object({ - documentId: z.number().min(1), + documentId: z.number(), field: ZCreateFieldSchema, }); +export const ZCreateDocumentFieldResponseSchema = ZFieldSchema; + export const ZCreateDocumentFieldsRequestSchema = z.object({ - documentId: z.number().min(1), + documentId: z.number(), fields: ZCreateFieldSchema.array(), }); +export const ZCreateDocumentFieldsResponseSchema = z.object({ + fields: z.array(ZFieldSchema), +}); + export const ZUpdateDocumentFieldRequestSchema = z.object({ - documentId: z.number().min(1), + documentId: z.number(), field: ZUpdateFieldSchema, }); +export const ZUpdateDocumentFieldResponseSchema = ZFieldSchema; + export const ZUpdateDocumentFieldsRequestSchema = z.object({ - documentId: z.number().min(1), + documentId: z.number(), fields: ZUpdateFieldSchema.array(), }); +export const ZUpdateDocumentFieldsResponseSchema = z.object({ + fields: z.array(ZFieldSchema), +}); + export const ZDeleteDocumentFieldRequestSchema = z.object({ - fieldId: z.number().min(1), + fieldId: z.number(), }); export const ZCreateTemplateFieldRequestSchema = z.object({ - templateId: z.number().min(1), + templateId: z.number(), field: ZCreateFieldSchema, }); -export const ZCreateDocumentFieldResponseSchema = FieldSchema; -export const ZUpdateTemplateFieldResponseSchema = FieldSchema; -export const ZUpdateDocumentFieldResponseSchema = FieldSchema; -export const ZCreateTemplateFieldResponseSchema = FieldSchema; +export const ZCreateTemplateFieldResponseSchema = ZFieldSchema; export const ZCreateTemplateFieldsRequestSchema = z.object({ - templateId: z.number().min(1), + templateId: z.number(), fields: ZCreateFieldSchema.array(), }); +export const ZCreateTemplateFieldsResponseSchema = z.object({ + fields: z.array(ZFieldSchema), +}); + export const ZUpdateTemplateFieldRequestSchema = z.object({ - templateId: z.number().min(1), + templateId: z.number(), field: ZUpdateFieldSchema, }); export const ZUpdateTemplateFieldsRequestSchema = z.object({ - templateId: z.number().min(1), + templateId: z.number(), fields: ZUpdateFieldSchema.array(), }); -export const ZDeleteTemplateFieldRequestSchema = z.object({ - fieldId: z.number().min(1), +export const ZUpdateTemplateFieldsResponseSchema = z.object({ + fields: z.array(ZFieldSchema), }); -export const ZAddFieldsMutationSchema = z.object({ +export const ZUpdateTemplateFieldResponseSchema = ZFieldSchema; + +export const ZDeleteTemplateFieldRequestSchema = z.object({ + fieldId: z.number(), +}); + +export const ZSetDocumentFieldsRequestSchema = z.object({ documentId: z.number(), fields: z.array( z.object({ @@ -98,9 +117,11 @@ export const ZAddFieldsMutationSchema = z.object({ ), }); -export type TAddFieldsMutationSchema = z.infer; +export const ZSetDocumentFieldsResponseSchema = z.object({ + fields: z.array(ZFieldSchema), +}); -export const ZAddTemplateFieldsMutationSchema = z.object({ +export const ZSetFieldsForTemplateRequestSchema = z.object({ templateId: z.number(), fields: z.array( z.object({ @@ -118,7 +139,9 @@ export const ZAddTemplateFieldsMutationSchema = z.object({ ), }); -export type TAddTemplateFieldsMutationSchema = z.infer; +export const ZSetFieldsForTemplateResponseSchema = z.object({ + fields: z.array(ZFieldSchema), +}); export const ZSignFieldWithTokenMutationSchema = z.object({ token: z.string(), @@ -139,15 +162,8 @@ export type TRemovedSignedFieldWithTokenMutationSchema = z.infer< typeof ZRemovedSignedFieldWithTokenMutationSchema >; -export const ZGetFieldQuerySchema = z.object({ +export const ZGetFieldRequestSchema = z.object({ fieldId: z.number(), }); -export type TGetFieldQuerySchema = z.infer; - -export const ZUpdateFieldMutationSchema = z.object({ - fieldId: z.number(), - documentId: z.number(), - fieldMeta: ZFieldMetaSchema, - teamId: z.number().optional(), -}); +export const ZGetFieldResponseSchema = ZFieldSchema; diff --git a/packages/trpc/server/recipient-router/router.ts b/packages/trpc/server/recipient-router/router.ts index 757061bca..803867971 100644 --- a/packages/trpc/server/recipient-router/router.ts +++ b/packages/trpc/server/recipient-router/router.ts @@ -2,48 +2,37 @@ import { z } from 'zod'; import { completeDocumentWithToken } from '@documenso/lib/server-only/document/complete-document-with-token'; import { rejectDocumentWithToken } from '@documenso/lib/server-only/document/reject-document-with-token'; -import { - ZCreateDocumentRecipientsResponseSchema, - createDocumentRecipients, -} from '@documenso/lib/server-only/recipient/create-document-recipients'; -import { - ZCreateTemplateRecipientsResponseSchema, - createTemplateRecipients, -} from '@documenso/lib/server-only/recipient/create-template-recipients'; +import { createDocumentRecipients } from '@documenso/lib/server-only/recipient/create-document-recipients'; +import { createTemplateRecipients } from '@documenso/lib/server-only/recipient/create-template-recipients'; import { deleteDocumentRecipient } from '@documenso/lib/server-only/recipient/delete-document-recipient'; import { deleteTemplateRecipient } from '@documenso/lib/server-only/recipient/delete-template-recipient'; -import { - ZGetRecipientByIdResponseSchema, - getRecipientById, -} from '@documenso/lib/server-only/recipient/get-recipient-by-id'; -import { - ZSetDocumentRecipientsResponseSchema, - setDocumentRecipients, -} from '@documenso/lib/server-only/recipient/set-document-recipients'; -import { - ZSetTemplateRecipientsResponseSchema, - setTemplateRecipients, -} from '@documenso/lib/server-only/recipient/set-template-recipients'; +import { getRecipientById } from '@documenso/lib/server-only/recipient/get-recipient-by-id'; +import { setDocumentRecipients } from '@documenso/lib/server-only/recipient/set-document-recipients'; +import { setTemplateRecipients } from '@documenso/lib/server-only/recipient/set-template-recipients'; import { updateDocumentRecipients } from '@documenso/lib/server-only/recipient/update-document-recipients'; import { updateTemplateRecipients } from '@documenso/lib/server-only/recipient/update-template-recipients'; import { extractNextApiRequestMetadata } from '@documenso/lib/universal/extract-request-metadata'; import { authenticatedProcedure, procedure, router } from '../trpc'; import { - ZAddSignersMutationSchema, ZCompleteDocumentWithTokenMutationSchema, ZCreateDocumentRecipientRequestSchema, ZCreateDocumentRecipientResponseSchema, ZCreateDocumentRecipientsRequestSchema, + ZCreateDocumentRecipientsResponseSchema, ZCreateTemplateRecipientRequestSchema, ZCreateTemplateRecipientResponseSchema, ZCreateTemplateRecipientsRequestSchema, + ZCreateTemplateRecipientsResponseSchema, ZDeleteDocumentRecipientRequestSchema, ZDeleteTemplateRecipientRequestSchema, - ZGetRecipientQuerySchema, + ZGetRecipientRequestSchema, + ZGetRecipientResponseSchema, ZRejectDocumentWithTokenMutationSchema, ZSetDocumentRecipientsRequestSchema, + ZSetDocumentRecipientsResponseSchema, ZSetTemplateRecipientsRequestSchema, + ZSetTemplateRecipientsResponseSchema, ZUpdateDocumentRecipientRequestSchema, ZUpdateDocumentRecipientResponseSchema, ZUpdateDocumentRecipientsRequestSchema, @@ -69,8 +58,8 @@ export const recipientRouter = router({ tags: ['Document Recipients', 'Template Recipients'], }, }) - .input(ZGetRecipientQuerySchema) - .output(ZGetRecipientByIdResponseSchema) + .input(ZGetRecipientRequestSchema) + .output(ZGetRecipientResponseSchema) .query(async ({ input, ctx }) => { const { teamId } = ctx; const { recipientId } = input; @@ -464,32 +453,4 @@ export const recipientRouter = router({ requestMetadata: extractNextApiRequestMetadata(ctx.req), }); }), - - /** - * Leaving this here and will remove after deployment. - * - * @deprecated Remove after deployment. - */ - addSigners: authenticatedProcedure - .input(ZAddSignersMutationSchema) - .output(ZSetDocumentRecipientsResponseSchema) - .mutation(async ({ input, ctx }) => { - const { teamId } = ctx; - const { documentId, signers } = input; - - return await setDocumentRecipients({ - userId: ctx.user.id, - documentId, - teamId, - recipients: signers.map((signer) => ({ - id: signer.nativeId, - email: signer.email, - name: signer.name, - role: signer.role, - signingOrder: signer.signingOrder, - actionAuth: signer.actionAuth, - })), - requestMetadata: ctx.metadata, - }); - }), }); diff --git a/packages/trpc/server/recipient-router/schema.ts b/packages/trpc/server/recipient-router/schema.ts index 56d1fefe3..984b08d06 100644 --- a/packages/trpc/server/recipient-router/schema.ts +++ b/packages/trpc/server/recipient-router/schema.ts @@ -5,13 +5,15 @@ import { ZRecipientActionAuthSchema, ZRecipientActionAuthTypesSchema, } from '@documenso/lib/types/document-auth'; +import { ZRecipientLiteSchema, ZRecipientSchema } from '@documenso/lib/types/recipient'; import { RecipientRole } from '@documenso/prisma/client'; -import { FieldSchema, RecipientSchema } from '@documenso/prisma/generated/zod'; -export const ZGetRecipientQuerySchema = z.object({ +export const ZGetRecipientRequestSchema = z.object({ recipientId: z.number(), }); +export const ZGetRecipientResponseSchema = ZRecipientSchema; + const ZCreateRecipientSchema = z.object({ email: z.string().toLowerCase().email().min(1), name: z.string(), @@ -31,41 +33,12 @@ const ZUpdateRecipientSchema = z.object({ actionAuth: ZRecipientActionAuthTypesSchema.optional().nullable(), }); -/** - * Use this when returning base recipients from the API. - */ -export const ZRecipientBaseResponseSchema = RecipientSchema.pick({ - id: true, - documentId: true, - templateId: true, - email: true, - name: true, - token: true, - documentDeletedAt: true, - expired: true, - signedAt: true, - authOptions: true, - signingOrder: true, - rejectionReason: true, - role: true, - readStatus: true, - signingStatus: true, - sendStatus: true, -}); - -/** - * Use this when returning a full recipient from the API. - */ -export const ZRecipientResponseSchema = ZRecipientBaseResponseSchema.extend({ - fields: FieldSchema.array(), -}); - export const ZCreateDocumentRecipientRequestSchema = z.object({ documentId: z.number(), recipient: ZCreateRecipientSchema, }); -export const ZCreateDocumentRecipientResponseSchema = ZRecipientBaseResponseSchema; +export const ZCreateDocumentRecipientResponseSchema = ZRecipientLiteSchema; export const ZCreateDocumentRecipientsRequestSchema = z.object({ documentId: z.number(), @@ -76,12 +49,16 @@ export const ZCreateDocumentRecipientsRequestSchema = z.object({ }), }); +export const ZCreateDocumentRecipientsResponseSchema = z.object({ + recipients: ZRecipientLiteSchema.array(), +}); + export const ZUpdateDocumentRecipientRequestSchema = z.object({ documentId: z.number(), recipient: ZUpdateRecipientSchema, }); -export const ZUpdateDocumentRecipientResponseSchema = ZRecipientResponseSchema; +export const ZUpdateDocumentRecipientResponseSchema = ZRecipientSchema; export const ZUpdateDocumentRecipientsRequestSchema = z.object({ documentId: z.number(), @@ -95,7 +72,7 @@ export const ZUpdateDocumentRecipientsRequestSchema = z.object({ }); export const ZUpdateDocumentRecipientsResponseSchema = z.object({ - recipients: z.array(ZRecipientResponseSchema), + recipients: z.array(ZRecipientSchema), }); export const ZDeleteDocumentRecipientRequestSchema = z.object({ @@ -126,12 +103,16 @@ export const ZSetDocumentRecipientsRequestSchema = z { message: 'Signers must have unique emails', path: ['signers__root'] }, ); +export const ZSetDocumentRecipientsResponseSchema = z.object({ + recipients: ZRecipientLiteSchema.array(), +}); + export const ZCreateTemplateRecipientRequestSchema = z.object({ templateId: z.number(), recipient: ZCreateRecipientSchema, }); -export const ZCreateTemplateRecipientResponseSchema = ZRecipientBaseResponseSchema; +export const ZCreateTemplateRecipientResponseSchema = ZRecipientLiteSchema; export const ZCreateTemplateRecipientsRequestSchema = z.object({ templateId: z.number(), @@ -142,12 +123,16 @@ export const ZCreateTemplateRecipientsRequestSchema = z.object({ }), }); +export const ZCreateTemplateRecipientsResponseSchema = z.object({ + recipients: ZRecipientLiteSchema.array(), +}); + export const ZUpdateTemplateRecipientRequestSchema = z.object({ templateId: z.number(), recipient: ZUpdateRecipientSchema, }); -export const ZUpdateTemplateRecipientResponseSchema = ZRecipientResponseSchema; +export const ZUpdateTemplateRecipientResponseSchema = ZRecipientSchema; export const ZUpdateTemplateRecipientsRequestSchema = z.object({ templateId: z.number(), @@ -161,11 +146,7 @@ export const ZUpdateTemplateRecipientsRequestSchema = z.object({ }); export const ZUpdateTemplateRecipientsResponseSchema = z.object({ - recipients: z.array(ZRecipientResponseSchema).refine((recipients) => { - const emails = recipients.map((recipient) => recipient.email); - - return new Set(emails).size === emails.length; - }), + recipients: z.array(ZRecipientSchema), }); export const ZDeleteTemplateRecipientRequestSchema = z.object({ @@ -196,6 +177,10 @@ export const ZSetTemplateRecipientsRequestSchema = z { message: 'Recipients must have unique emails', path: ['recipients__root'] }, ); +export const ZSetTemplateRecipientsResponseSchema = z.object({ + recipients: ZRecipientLiteSchema.array(), +}); + export const ZCompleteDocumentWithTokenMutationSchema = z.object({ token: z.string(), documentId: z.number(), @@ -216,32 +201,3 @@ export const ZRejectDocumentWithTokenMutationSchema = z.object({ export type TRejectDocumentWithTokenMutationSchema = z.infer< typeof ZRejectDocumentWithTokenMutationSchema >; - -/** - * Legacy schema. Remove after deployment (when addSigners trpc is removed). - * - * @deprecated - */ -export const ZAddSignersMutationSchema = z - .object({ - documentId: z.number(), - signers: z.array( - z.object({ - nativeId: z.number().optional(), - email: z.string().toLowerCase().email().min(1), - name: z.string(), - role: z.nativeEnum(RecipientRole), - signingOrder: z.number().optional(), - actionAuth: ZRecipientActionAuthTypesSchema.optional().nullable(), - }), - ), - }) - .refine( - (schema) => { - const emails = schema.signers.map((signer) => signer.email.toLowerCase()); - - return new Set(emails).size === emails.length; - }, - // Dirty hack to handle errors when .root is populated for an array type - { message: 'Signers must have unique emails', path: ['signers__root'] }, - ); diff --git a/packages/trpc/server/template-router/router.ts b/packages/trpc/server/template-router/router.ts index b50a1adaf..56238c14a 100644 --- a/packages/trpc/server/template-router/router.ts +++ b/packages/trpc/server/template-router/router.ts @@ -2,10 +2,7 @@ import { z } from 'zod'; import { getServerLimits } from '@documenso/ee/server-only/limits/server'; import { AppError, AppErrorCode } from '@documenso/lib/errors/app-error'; -import { - ZGetDocumentWithDetailsByIdResponseSchema, - getDocumentWithDetailsById, -} from '@documenso/lib/server-only/document/get-document-with-details-by-id'; +import { getDocumentWithDetailsById } from '@documenso/lib/server-only/document/get-document-with-details-by-id'; import { sendDocument } from '@documenso/lib/server-only/document/send-document'; import { ZCreateDocumentFromDirectTemplateResponseSchema, @@ -50,16 +47,17 @@ import type { Document } from '@documenso/prisma/client'; import { authenticatedProcedure, maybeAuthenticatedProcedure, router } from '../trpc'; import { - ZCreateDocumentFromDirectTemplateMutationSchema, - ZCreateDocumentFromTemplateMutationSchema, + ZCreateDocumentFromDirectTemplateRequestSchema, + ZCreateDocumentFromTemplateRequestSchema, + ZCreateDocumentFromTemplateResponseSchema, ZCreateTemplateDirectLinkMutationSchema, ZCreateTemplateMutationSchema, ZDeleteTemplateDirectLinkMutationSchema, ZDeleteTemplateMutationSchema, ZDuplicateTemplateMutationSchema, - ZFindTemplatesQuerySchema, - ZGetTemplateByIdQuerySchema, - ZMoveTemplatesToTeamSchema, + ZFindTemplatesRequestSchema, + ZGetTemplateByIdRequestSchema, + ZMoveTemplatesToTeamRequestSchema, ZToggleTemplateDirectLinkMutationSchema, ZUpdateTemplateRequestSchema, } from './schema'; @@ -78,7 +76,7 @@ export const templateRouter = router({ tags: ['Template'], }, }) - .input(ZFindTemplatesQuerySchema) + .input(ZFindTemplatesRequestSchema) .output(ZFindTemplatesResponseSchema) .query(async ({ input, ctx }) => { const { teamId } = ctx; @@ -102,7 +100,7 @@ export const templateRouter = router({ tags: ['Template'], }, }) - .input(ZGetTemplateByIdQuerySchema) + .input(ZGetTemplateByIdRequestSchema) .output(ZGetTemplateByIdResponseSchema) .query(async ({ input, ctx }) => { const { teamId } = ctx; @@ -234,8 +232,8 @@ export const templateRouter = router({ tags: ['Template'], }, }) - .input(ZCreateDocumentFromTemplateMutationSchema) - .output(ZGetDocumentWithDetailsByIdResponseSchema) + .input(ZCreateDocumentFromTemplateRequestSchema) + .output(ZCreateDocumentFromTemplateResponseSchema) .mutation(async ({ ctx, input }) => { const { teamId } = ctx; const { templateId, recipients, distributeDocument, customDocumentDataId } = input; @@ -290,7 +288,7 @@ export const templateRouter = router({ // tags: ['Template'], // }, // }) - .input(ZCreateDocumentFromDirectTemplateMutationSchema) + .input(ZCreateDocumentFromDirectTemplateRequestSchema) .output(ZCreateDocumentFromDirectTemplateResponseSchema) .mutation(async ({ input, ctx }) => { const { @@ -415,7 +413,7 @@ export const templateRouter = router({ tags: ['Template'], }, }) - .input(ZMoveTemplatesToTeamSchema) + .input(ZMoveTemplatesToTeamRequestSchema) .output(ZMoveTemplateToTeamResponseSchema) .mutation(async ({ input, ctx }) => { const { templateId, teamId } = input; diff --git a/packages/trpc/server/template-router/schema.ts b/packages/trpc/server/template-router/schema.ts index 9b230eadd..4e6409793 100644 --- a/packages/trpc/server/template-router/schema.ts +++ b/packages/trpc/server/template-router/schema.ts @@ -1,5 +1,6 @@ import { z } from 'zod'; +import { ZDocumentSchema } from '@documenso/lib/types/document'; import { ZDocumentAccessAuthTypesSchema, ZDocumentActionAuthTypesSchema, @@ -25,7 +26,7 @@ export const ZCreateTemplateMutationSchema = z.object({ templateDocumentDataId: z.string().min(1), }); -export const ZCreateDocumentFromDirectTemplateMutationSchema = z.object({ +export const ZCreateDocumentFromDirectTemplateRequestSchema = z.object({ directRecipientName: z.string().optional(), directRecipientEmail: z.string().email(), directTemplateToken: z.string().min(1), @@ -34,7 +35,7 @@ export const ZCreateDocumentFromDirectTemplateMutationSchema = z.object({ templateUpdatedAt: z.date(), }); -export const ZCreateDocumentFromTemplateMutationSchema = z.object({ +export const ZCreateDocumentFromTemplateRequestSchema = z.object({ templateId: z.number(), recipients: z .array( @@ -62,6 +63,8 @@ export const ZCreateDocumentFromTemplateMutationSchema = z.object({ .optional(), }); +export const ZCreateDocumentFromTemplateResponseSchema = ZDocumentSchema; + export const ZDuplicateTemplateMutationSchema = z.object({ templateId: z.number(), }); @@ -138,24 +141,19 @@ export const ZUpdateTemplateRequestSchema = z.object({ .optional(), }); -export const ZFindTemplatesQuerySchema = ZFindSearchParamsSchema.extend({ +export const ZFindTemplatesRequestSchema = ZFindSearchParamsSchema.extend({ type: z.nativeEnum(TemplateType).describe('Filter templates by type.').optional(), }); -export const ZGetTemplateByIdQuerySchema = z.object({ - templateId: z.number().min(1), +export const ZGetTemplateByIdRequestSchema = z.object({ + templateId: z.number(), }); -export const ZMoveTemplatesToTeamSchema = z.object({ +export const ZMoveTemplatesToTeamRequestSchema = z.object({ templateId: z.number().describe('The ID of the template to move to.'), teamId: z.number().describe('The ID of the team to move the template to.'), }); export type TCreateTemplateMutationSchema = z.infer; -export type TCreateDocumentFromTemplateMutationSchema = z.infer< - typeof ZCreateDocumentFromTemplateMutationSchema ->; export type TDuplicateTemplateMutationSchema = z.infer; export type TDeleteTemplateMutationSchema = z.infer; -export type TGetTemplateByIdQuerySchema = z.infer; -export type TMoveTemplatesToSchema = z.infer;