2025-01-02 15:33:37 +11:00
import { DocumentSigningOrder , DocumentVisibility , TemplateType } from '@prisma/client' ;
2023-10-06 22:54:24 +00:00
import { z } from 'zod' ;
2025-01-14 00:43:35 +11:00
import { ZDocumentSchema } from '@documenso/lib/types/document' ;
2024-05-10 19:45:19 +07:00
import {
ZDocumentAccessAuthTypesSchema ,
ZDocumentActionAuthTypesSchema ,
} from '@documenso/lib/types/document-auth' ;
2024-11-08 13:32:13 +09:00
import { ZDocumentEmailSettingsSchema } from '@documenso/lib/types/document-email' ;
feat: allow fields prefill when generating a document from a template (#1615)
This change allows API users to pre-fill fields with values by
passing the data in the request body. Example body for V2 API endpoint
`/api/v2-beta/template/use`:
```json
{
"templateId": 1,
"recipients": [
{
"id": 1,
"email": "signer1@mail.com",
"name": "Signer 1"
},
{
"id": 2,
"email": "signer2@mail.com",
"name": "Signer 2"
}
],
"prefillValues": [
{
"id": 14,
"fieldMeta": {
"type": "text",
"label": "my label",
"placeholder": "text placeholder test",
"text": "auto-sign value",
"characterLimit": 25,
"textAlign": "right",
"fontSize": 94,
"required": true
}
},
{
"id": 15,
"fieldMeta": {
"type": "radio",
"label": "radio label",
"placeholder": "new radio placeholder",
"required": false,
"readOnly": true,
"values": [
{
"id": 2,
"checked": true,
"value": "radio val 1"
},
{
"id": 3,
"checked": false,
"value": "radio val 2"
}
]
}
},
{
"id": 16,
"fieldMeta": {
"type": "dropdown",
"label": "dropdown label",
"placeholder": "DD placeholder",
"required": false,
"readOnly": false,
"values": [
{
"value": "option 1"
},
{
"value": "option 2"
},
{
"value": "option 3"
}
],
"defaultValue": "option 2"
}
}
],
"distributeDocument": false,
"customDocumentDataId": ""
}
```
2025-03-06 00:44:09 +02:00
import { ZFieldMetaPrefillFieldsSchema } from '@documenso/lib/types/field-meta' ;
2025-01-16 13:36:00 +11:00
import { ZFindResultResponse , ZFindSearchParamsSchema } from '@documenso/lib/types/search-params' ;
import {
ZTemplateLiteSchema ,
ZTemplateManySchema ,
ZTemplateSchema ,
} from '@documenso/lib/types/template' ;
2025-01-02 15:33:37 +11:00
import { TemplateDirectLinkSchema } from '@documenso/prisma/generated/zod/modelSchema/TemplateDirectLinkSchema' ;
2024-05-10 19:45:19 +07:00
2025-01-11 15:33:20 +11:00
import {
ZDocumentMetaDateFormatSchema ,
ZDocumentMetaDistributionMethodSchema ,
2025-03-24 15:25:29 +11:00
ZDocumentMetaDrawSignatureEnabledSchema ,
2025-01-11 15:33:20 +11:00
ZDocumentMetaLanguageSchema ,
ZDocumentMetaMessageSchema ,
ZDocumentMetaRedirectUrlSchema ,
ZDocumentMetaSubjectSchema ,
ZDocumentMetaTimezoneSchema ,
ZDocumentMetaTypedSignatureEnabledSchema ,
2025-03-24 15:25:29 +11:00
ZDocumentMetaUploadSignatureEnabledSchema ,
2025-01-11 15:33:20 +11:00
} from '../document-router/schema' ;
2024-06-02 15:49:09 +10:00
import { ZSignFieldWithTokenMutationSchema } from '../field-router/schema' ;
2023-10-06 22:54:24 +00:00
export const ZCreateTemplateMutationSchema = z . object ( {
2024-02-08 12:33:20 +11:00
title : z.string ( ) . min ( 1 ) . trim ( ) ,
2023-10-06 22:54:24 +00:00
templateDocumentDataId : z.string ( ) . min ( 1 ) ,
} ) ;
2025-01-14 00:43:35 +11:00
export const ZCreateDocumentFromDirectTemplateRequestSchema = z . object ( {
2024-07-05 03:03:22 +00:00
directRecipientName : z.string ( ) . optional ( ) ,
2024-06-02 15:49:09 +10:00
directRecipientEmail : z.string ( ) . email ( ) ,
directTemplateToken : z.string ( ) . min ( 1 ) ,
2024-08-09 11:06:17 +10:00
directTemplateExternalId : z.string ( ) . optional ( ) ,
2024-06-02 15:49:09 +10:00
signedFieldValues : z.array ( ZSignFieldWithTokenMutationSchema ) ,
templateUpdatedAt : z.date ( ) ,
} ) ;
2025-01-14 00:43:35 +11:00
export const ZCreateDocumentFromTemplateRequestSchema = z . object ( {
2023-10-06 22:54:24 +00:00
templateId : z.number ( ) ,
2024-02-20 19:11:12 +00:00
recipients : z
. array (
z . object ( {
2025-01-11 15:33:20 +11:00
id : z.number ( ) . describe ( 'The ID of the recipient in the template.' ) ,
2024-02-20 19:11:12 +00:00
email : z.string ( ) . email ( ) ,
2024-05-07 15:04:12 +07:00
name : z.string ( ) . optional ( ) ,
2024-02-20 19:11:12 +00:00
} ) ,
)
2025-01-11 15:33:20 +11:00
. describe ( 'The information of the recipients to create the document with.' )
2024-05-07 15:04:12 +07:00
. refine ( ( recipients ) = > {
const emails = recipients . map ( ( signer ) = > signer . email ) ;
2025-01-11 15:33:20 +11:00
2024-05-07 15:04:12 +07:00
return new Set ( emails ) . size === emails . length ;
} , 'Recipients must have unique emails' ) ,
2025-01-11 15:33:20 +11:00
distributeDocument : z
. boolean ( )
. describe ( 'Whether to create the document as pending and distribute it to recipients.' )
. optional ( ) ,
customDocumentDataId : z
. string ( )
. describe (
'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 ( ) ,
2025-03-12 13:54:58 +02:00
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 ( ) ,
2023-10-06 22:54:24 +00:00
} ) ;
2025-01-14 00:43:35 +11:00
export const ZCreateDocumentFromTemplateResponseSchema = ZDocumentSchema ;
2023-10-06 22:54:24 +00:00
export const ZDuplicateTemplateMutationSchema = z . object ( {
templateId : z.number ( ) ,
} ) ;
2025-01-16 13:36:00 +11:00
export const ZDuplicateTemplateResponseSchema = ZTemplateLiteSchema ;
export const ZCreateTemplateDirectLinkRequestSchema = z . object ( {
2025-01-11 15:33:20 +11:00
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 ( ) ,
2024-06-02 15:49:09 +10:00
} ) ;
2025-01-16 13:36:00 +11:00
const GenericDirectLinkResponseSchema = TemplateDirectLinkSchema . pick ( {
id : true ,
templateId : true ,
token : true ,
createdAt : true ,
enabled : true ,
directTemplateRecipientId : true ,
} ) ;
export const ZCreateTemplateDirectLinkResponseSchema = GenericDirectLinkResponseSchema ;
export const ZDeleteTemplateDirectLinkRequestSchema = z . object ( {
2025-01-11 15:33:20 +11:00
templateId : z.number ( ) ,
2024-06-02 15:49:09 +10:00
} ) ;
2025-01-16 13:36:00 +11:00
export const ZToggleTemplateDirectLinkRequestSchema = z . object ( {
2025-01-11 15:33:20 +11:00
templateId : z.number ( ) ,
2024-06-02 15:49:09 +10:00
enabled : z.boolean ( ) ,
} ) ;
2025-01-16 13:36:00 +11:00
export const ZToggleTemplateDirectLinkResponseSchema = GenericDirectLinkResponseSchema ;
2023-10-06 22:54:24 +00:00
export const ZDeleteTemplateMutationSchema = z . object ( {
2025-01-11 15:33:20 +11:00
templateId : z.number ( ) ,
2023-10-06 22:54:24 +00:00
} ) ;
2024-06-06 14:46:48 +10:00
export const MAX_TEMPLATE_PUBLIC_TITLE_LENGTH = 50 ;
export const MAX_TEMPLATE_PUBLIC_DESCRIPTION_LENGTH = 256 ;
2025-01-11 15:33:20 +11:00
export const ZUpdateTemplateRequestSchema = z . object ( {
2024-05-10 19:45:19 +07:00
templateId : z.number ( ) ,
2025-01-11 15:33:20 +11:00
data : z
2024-06-06 14:46:48 +10:00
. object ( {
2025-01-11 15:33:20 +11:00
title : z.string ( ) . min ( 1 ) . optional ( ) ,
externalId : z.string ( ) . nullish ( ) ,
visibility : z.nativeEnum ( DocumentVisibility ) . optional ( ) ,
globalAccessAuth : ZDocumentAccessAuthTypesSchema.nullable ( ) . optional ( ) ,
globalActionAuth : ZDocumentActionAuthTypesSchema.nullable ( ) . optional ( ) ,
publicTitle : z
2024-06-06 14:46:48 +10:00
. string ( )
2025-01-11 15:33:20 +11:00
. 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.' ,
)
. optional ( ) ,
publicDescription : 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.' ,
)
. optional ( ) ,
type : z . nativeEnum ( TemplateType ) . optional ( ) ,
} )
. optional ( ) ,
meta : z
. object ( {
subject : ZDocumentMetaSubjectSchema.optional ( ) ,
message : ZDocumentMetaMessageSchema.optional ( ) ,
timezone : ZDocumentMetaTimezoneSchema.optional ( ) ,
dateFormat : ZDocumentMetaDateFormatSchema.optional ( ) ,
distributionMethod : ZDocumentMetaDistributionMethodSchema.optional ( ) ,
emailSettings : ZDocumentEmailSettingsSchema.optional ( ) ,
redirectUrl : ZDocumentMetaRedirectUrlSchema.optional ( ) ,
language : ZDocumentMetaLanguageSchema.optional ( ) ,
typedSignatureEnabled : ZDocumentMetaTypedSignatureEnabledSchema.optional ( ) ,
2025-03-24 15:25:29 +11:00
uploadSignatureEnabled : ZDocumentMetaUploadSignatureEnabledSchema.optional ( ) ,
drawSignatureEnabled : ZDocumentMetaDrawSignatureEnabledSchema.optional ( ) ,
2025-01-11 15:33:20 +11:00
signingOrder : z.nativeEnum ( DocumentSigningOrder ) . optional ( ) ,
2025-03-21 13:27:04 +11:00
allowDictateNextSigner : z.boolean ( ) . optional ( ) ,
2024-06-06 14:46:48 +10:00
} )
. optional ( ) ,
2024-09-16 12:36:45 +00:00
} ) ;
2025-01-16 13:36:00 +11:00
export const ZUpdateTemplateResponseSchema = ZTemplateLiteSchema ;
2025-01-14 00:43:35 +11:00
export const ZFindTemplatesRequestSchema = ZFindSearchParamsSchema . extend ( {
2025-01-11 15:33:20 +11:00
type : z . nativeEnum ( TemplateType ) . describe ( 'Filter templates by type.' ) . optional ( ) ,
2024-05-10 19:45:19 +07:00
} ) ;
2025-01-16 13:36:00 +11:00
export const ZFindTemplatesResponseSchema = ZFindResultResponse . extend ( {
data : ZTemplateManySchema.array ( ) ,
} ) ;
export type TFindTemplatesResponse = z . infer < typeof ZFindTemplatesResponseSchema > ;
export type FindTemplateRow = TFindTemplatesResponse [ 'data' ] [ number ] ;
2025-01-14 00:43:35 +11:00
export const ZGetTemplateByIdRequestSchema = z . object ( {
templateId : z.number ( ) ,
2024-05-10 19:45:19 +07:00
} ) ;
2025-01-16 13:36:00 +11:00
export const ZGetTemplateByIdResponseSchema = ZTemplateSchema ;
export const ZMoveTemplateToTeamRequestSchema = z . object ( {
2025-01-11 15:33:20 +11:00
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.' ) ,
2024-11-26 12:03:44 +02:00
} ) ;
2025-01-16 13:36:00 +11:00
export const ZMoveTemplateToTeamResponseSchema = ZTemplateLiteSchema ;
2025-01-28 15:33:32 +11:00
export const ZBulkSendTemplateMutationSchema = z . object ( {
templateId : z.number ( ) ,
teamId : z.number ( ) . optional ( ) ,
csv : z.string ( ) . min ( 1 ) ,
sendImmediately : z.boolean ( ) ,
} ) ;
2023-10-06 22:54:24 +00:00
export type TCreateTemplateMutationSchema = z . infer < typeof ZCreateTemplateMutationSchema > ;
export type TDuplicateTemplateMutationSchema = z . infer < typeof ZDuplicateTemplateMutationSchema > ;
export type TDeleteTemplateMutationSchema = z . infer < typeof ZDeleteTemplateMutationSchema > ;
2025-01-28 15:33:32 +11:00
export type TBulkSendTemplateMutationSchema = z . infer < typeof ZBulkSendTemplateMutationSchema > ;