import { DocumentSigningOrder, DocumentVisibility, TemplateType } from '@prisma/client'; import { z } from 'zod'; import { ZDocumentSchema } from '@documenso/lib/types/document'; import { ZDocumentAccessAuthTypesSchema, ZDocumentActionAuthTypesSchema, } from '@documenso/lib/types/document-auth'; import { ZDocumentEmailSettingsSchema } from '@documenso/lib/types/document-email'; import { ZDocumentMetaDateFormatSchema, ZDocumentMetaDistributionMethodSchema, ZDocumentMetaDrawSignatureEnabledSchema, ZDocumentMetaLanguageSchema, ZDocumentMetaMessageSchema, ZDocumentMetaRedirectUrlSchema, ZDocumentMetaSubjectSchema, ZDocumentMetaTimezoneSchema, ZDocumentMetaTypedSignatureEnabledSchema, ZDocumentMetaUploadSignatureEnabledSchema, } from '@documenso/lib/types/document-meta'; import { ZEnvelopeAttachmentTypeSchema } from '@documenso/lib/types/envelope-attachment'; import { ZFieldMetaPrefillFieldsSchema } from '@documenso/lib/types/field-meta'; import { ZFindResultResponse, ZFindSearchParamsSchema } from '@documenso/lib/types/search-params'; import { ZTemplateLiteSchema, ZTemplateManySchema, ZTemplateSchema, } from '@documenso/lib/types/template'; import { LegacyTemplateDirectLinkSchema } from '@documenso/prisma/types/template-legacy-schema'; import { ZSignFieldWithTokenMutationSchema } from '../field-router/schema'; export const MAX_TEMPLATE_PUBLIC_TITLE_LENGTH = 50; export const MAX_TEMPLATE_PUBLIC_DESCRIPTION_LENGTH = 256; export const ZTemplateTitleSchema = z .string() .trim() .min(1) .max(255) .describe('The title of the document.'); export const ZTemplatePublicTitleSchema = z .string() .trim() .min(1) .max(MAX_TEMPLATE_PUBLIC_TITLE_LENGTH) .describe( 'The title of the template that will be displayed to the public. Only applicable for public templates.', ); export const ZTemplatePublicDescriptionSchema = z .string() .trim() .min(1) .max(MAX_TEMPLATE_PUBLIC_DESCRIPTION_LENGTH) .describe( 'The description of the template that will be displayed to the public. Only applicable for public templates.', ); export const ZTemplateMetaUpsertSchema = z.object({ subject: ZDocumentMetaSubjectSchema.optional(), message: ZDocumentMetaMessageSchema.optional(), timezone: ZDocumentMetaTimezoneSchema.optional(), dateFormat: ZDocumentMetaDateFormatSchema.optional(), distributionMethod: ZDocumentMetaDistributionMethodSchema.optional(), emailId: z.string().nullish(), emailReplyTo: z.string().email().nullish(), emailSettings: ZDocumentEmailSettingsSchema.optional(), redirectUrl: ZDocumentMetaRedirectUrlSchema.optional(), language: ZDocumentMetaLanguageSchema.optional(), typedSignatureEnabled: ZDocumentMetaTypedSignatureEnabledSchema.optional(), uploadSignatureEnabled: ZDocumentMetaUploadSignatureEnabledSchema.optional(), drawSignatureEnabled: ZDocumentMetaDrawSignatureEnabledSchema.optional(), signingOrder: z.nativeEnum(DocumentSigningOrder).optional(), allowDictateNextSigner: z.boolean().optional(), }); export const ZCreateTemplateMutationSchema = z.object({ title: z.string().min(1).trim(), templateDocumentDataId: z.string().min(1), folderId: z.string().optional(), }); export const ZCreateDocumentFromDirectTemplateRequestSchema = z.object({ directRecipientName: z.string().max(255).optional(), directRecipientEmail: z.string().email().max(254), directTemplateToken: z.string().min(1), directTemplateExternalId: z.string().optional(), signedFieldValues: z.array(ZSignFieldWithTokenMutationSchema), templateUpdatedAt: z.date(), nextSigner: z .object({ email: z.string().email().max(254), name: z.string().min(1).max(255), }) .optional(), }); export const ZCreateDocumentFromTemplateRequestSchema = z.object({ templateId: z.number(), recipients: z .array( z.object({ id: z.number().describe('The ID of the recipient in the template.'), email: z.string().email().max(254), name: z.string().max(255).optional(), }), ) .describe('The information of the recipients to create the document with.'), distributeDocument: z .boolean() .describe('Whether to create the document as pending and distribute it to recipients.') .optional(), customDocumentDataId: z .string() .describe( '[DEPRECATED] - Use customDocumentData instead. The data ID of an alternative PDF to use when creating the document. If not provided, the PDF attached to the template will be used.', ) .optional(), customDocumentData: z .array( z.object({ documentDataId: z.string(), envelopeItemId: z.string(), }), ) .describe( 'The data IDs of alternative PDFs to use when creating the document. If not provided, the PDF attached to the template will be used.', ) .optional(), folderId: z .string() .describe( 'The ID of the folder to create the document in. If not provided, the document will be created in the root folder.', ) .optional(), prefillFields: z .array(ZFieldMetaPrefillFieldsSchema) .describe( 'The fields to prefill on the document before sending it out. Useful when you want to create a document from an existing template and pre-fill the fields with specific values.', ) .optional(), }); export const ZCreateDocumentFromTemplateResponseSchema = ZDocumentSchema; export const ZDuplicateTemplateMutationSchema = z.object({ templateId: z.number(), }); export const ZDuplicateTemplateResponseSchema = ZTemplateLiteSchema; export const ZCreateTemplateDirectLinkRequestSchema = z.object({ templateId: z.number(), directRecipientId: z .number() .describe( 'The of the recipient in the current template to transform into the primary recipient when the template is used.', ) .optional(), }); const GenericDirectLinkResponseSchema = LegacyTemplateDirectLinkSchema.pick({ id: true, token: true, createdAt: true, enabled: true, directTemplateRecipientId: true, envelopeId: true, templateId: true, }); export const ZCreateTemplateDirectLinkResponseSchema = GenericDirectLinkResponseSchema; export const ZDeleteTemplateDirectLinkRequestSchema = z.object({ templateId: z.number(), }); export const ZToggleTemplateDirectLinkRequestSchema = z.object({ templateId: z.number(), enabled: z.boolean(), }); export const ZToggleTemplateDirectLinkResponseSchema = GenericDirectLinkResponseSchema; export const ZDeleteTemplateMutationSchema = z.object({ templateId: z.number(), }); /** * Note: This is the same between V1 and V2. Be careful when updating this schema and think of the consequences. */ export const ZCreateTemplateV2RequestSchema = z.object({ title: ZTemplateTitleSchema, folderId: z.string().optional(), externalId: z.string().nullish(), visibility: z.nativeEnum(DocumentVisibility).optional(), globalAccessAuth: z.array(ZDocumentAccessAuthTypesSchema).optional().default([]), globalActionAuth: z.array(ZDocumentActionAuthTypesSchema).optional().default([]), publicTitle: ZTemplatePublicTitleSchema.optional(), publicDescription: ZTemplatePublicDescriptionSchema.optional(), type: z.nativeEnum(TemplateType).optional(), meta: ZTemplateMetaUpsertSchema.optional(), attachments: z .array( z.object({ label: z.string().min(1, 'Label is required'), data: z.string().url('Must be a valid URL'), type: ZEnvelopeAttachmentTypeSchema.optional().default('link'), }), ) .optional(), }); /** * Note: This is the same between V1 and V2. Be careful when updating this schema and think of the consequences. */ export const ZCreateTemplateV2ResponseSchema = z.object({ template: ZTemplateSchema, uploadUrl: z.string().min(1), }); export const ZCreateTemplateResponseSchema = z.object({ legacyTemplateId: z.number(), }); export const ZUpdateTemplateRequestSchema = z.object({ templateId: z.number(), data: z .object({ title: ZTemplateTitleSchema.optional(), externalId: z.string().nullish(), visibility: z.nativeEnum(DocumentVisibility).optional(), globalAccessAuth: z.array(ZDocumentAccessAuthTypesSchema).optional().default([]), globalActionAuth: z.array(ZDocumentActionAuthTypesSchema).optional().default([]), publicTitle: ZTemplatePublicTitleSchema.optional(), publicDescription: ZTemplatePublicDescriptionSchema.optional(), type: z.nativeEnum(TemplateType).optional(), useLegacyFieldInsertion: z.boolean().optional(), folderId: z.string().nullish(), }) .optional(), meta: ZTemplateMetaUpsertSchema.optional(), }); export const ZUpdateTemplateResponseSchema = ZTemplateLiteSchema; export const ZFindTemplatesRequestSchema = ZFindSearchParamsSchema.extend({ type: z.nativeEnum(TemplateType).describe('Filter templates by type.').optional(), folderId: z.string().describe('The ID of the folder to filter templates by.').optional(), }); export const ZFindTemplatesResponseSchema = ZFindResultResponse.extend({ data: ZTemplateManySchema.array(), }); export type TFindTemplatesResponse = z.infer; export type FindTemplateRow = TFindTemplatesResponse['data'][number]; export const ZGetTemplateByIdRequestSchema = z.object({ templateId: z.number(), }); export const ZGetTemplateByIdResponseSchema = ZTemplateSchema; export const ZBulkSendTemplateMutationSchema = z.object({ templateId: z.number(), teamId: z.number(), csv: z.string().min(1), sendImmediately: z.boolean(), }); export type TCreateTemplateMutationSchema = z.infer; export type TDuplicateTemplateMutationSchema = z.infer; export type TDeleteTemplateMutationSchema = z.infer; export type TBulkSendTemplateMutationSchema = z.infer;