mirror of
https://github.com/documenso/documenso.git
synced 2025-11-14 00:32:43 +10:00
feat: embed authoring part two (#1768)
This commit is contained in:
@ -2,7 +2,8 @@ import { router } from '../trpc';
|
||||
import { createEmbeddingDocumentRoute } from './create-embedding-document';
|
||||
import { createEmbeddingPresignTokenRoute } from './create-embedding-presign-token';
|
||||
import { createEmbeddingTemplateRoute } from './create-embedding-template';
|
||||
import { getEmbeddingDocumentRoute } from './get-embedding-document';
|
||||
import { updateEmbeddingDocumentRoute } from './update-embedding-document';
|
||||
import { updateEmbeddingTemplateRoute } from './update-embedding-template';
|
||||
import { verifyEmbeddingPresignTokenRoute } from './verify-embedding-presign-token';
|
||||
|
||||
export const embeddingPresignRouter = router({
|
||||
@ -10,5 +11,6 @@ export const embeddingPresignRouter = router({
|
||||
verifyEmbeddingPresignToken: verifyEmbeddingPresignTokenRoute,
|
||||
createEmbeddingDocument: createEmbeddingDocumentRoute,
|
||||
createEmbeddingTemplate: createEmbeddingTemplateRoute,
|
||||
getEmbeddingDocument: getEmbeddingDocumentRoute,
|
||||
updateEmbeddingDocument: updateEmbeddingDocumentRoute,
|
||||
updateEmbeddingTemplate: updateEmbeddingTemplateRoute,
|
||||
});
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
import { isCommunityPlan } from '@documenso/ee/server-only/util/is-community-plan';
|
||||
import { isUserEnterprise } from '@documenso/ee/server-only/util/is-document-enterprise';
|
||||
import { isDocumentPlatform } from '@documenso/ee/server-only/util/is-document-platform';
|
||||
import { IS_BILLING_ENABLED } from '@documenso/lib/constants/app';
|
||||
import { AppError, AppErrorCode } from '@documenso/lib/errors/app-error';
|
||||
import { createEmbeddingPresignToken } from '@documenso/lib/server-only/embedding-presign/create-embedding-presign-token';
|
||||
import { getApiTokenByToken } from '@documenso/lib/server-only/public-api/get-api-token-by-token';
|
||||
import { prisma } from '@documenso/prisma';
|
||||
|
||||
import { procedure } from '../trpc';
|
||||
import {
|
||||
@ -42,13 +42,24 @@ export const createEmbeddingPresignTokenRoute = procedure
|
||||
});
|
||||
}
|
||||
|
||||
const [hasCommunityPlan, hasPlatformPlan, hasEnterprisePlan] = await Promise.all([
|
||||
const [hasCommunityPlan, hasEnterprisePlan] = await Promise.all([
|
||||
isCommunityPlan({ userId: token.userId, teamId: token.teamId ?? undefined }),
|
||||
isDocumentPlatform({ userId: token.userId, teamId: token.teamId }),
|
||||
isUserEnterprise({ userId: token.userId, teamId: token.teamId ?? undefined }),
|
||||
]);
|
||||
|
||||
if (!hasCommunityPlan && !hasPlatformPlan && !hasEnterprisePlan) {
|
||||
let hasTeamAuthoringFlag = false;
|
||||
|
||||
if (token.teamId) {
|
||||
const teamGlobalSettings = await prisma.teamGlobalSettings.findFirst({
|
||||
where: {
|
||||
teamId: token.teamId,
|
||||
},
|
||||
});
|
||||
|
||||
hasTeamAuthoringFlag = teamGlobalSettings?.allowEmbeddedAuthoring ?? false;
|
||||
}
|
||||
|
||||
if (!hasCommunityPlan && !hasEnterprisePlan && !hasTeamAuthoringFlag) {
|
||||
throw new AppError(AppErrorCode.UNAUTHORIZED, {
|
||||
message: 'You do not have permission to create embedding presign tokens',
|
||||
});
|
||||
|
||||
@ -1,63 +0,0 @@
|
||||
import { AppError, AppErrorCode } from '@documenso/lib/errors/app-error';
|
||||
import { verifyEmbeddingPresignToken } from '@documenso/lib/server-only/embedding-presign/verify-embedding-presign-token';
|
||||
import { prisma } from '@documenso/prisma';
|
||||
|
||||
import { procedure } from '../trpc';
|
||||
import {
|
||||
ZGetEmbeddingDocumentRequestSchema,
|
||||
ZGetEmbeddingDocumentResponseSchema,
|
||||
} from './get-embedding-document.types';
|
||||
|
||||
export const getEmbeddingDocumentRoute = procedure
|
||||
.input(ZGetEmbeddingDocumentRequestSchema)
|
||||
.output(ZGetEmbeddingDocumentResponseSchema)
|
||||
.query(async ({ input, ctx: { req } }) => {
|
||||
try {
|
||||
const authorizationHeader = req.headers.get('authorization');
|
||||
|
||||
const [presignToken] = (authorizationHeader || '')
|
||||
.split('Bearer ')
|
||||
.filter((s) => s.length > 0);
|
||||
|
||||
if (!presignToken) {
|
||||
throw new AppError(AppErrorCode.UNAUTHORIZED, {
|
||||
message: 'No presign token provided',
|
||||
});
|
||||
}
|
||||
|
||||
const apiToken = await verifyEmbeddingPresignToken({ token: presignToken });
|
||||
|
||||
const { documentId } = input;
|
||||
|
||||
const document = await prisma.document.findFirst({
|
||||
where: {
|
||||
id: documentId,
|
||||
userId: apiToken.userId,
|
||||
...(apiToken.teamId ? { teamId: apiToken.teamId } : {}),
|
||||
},
|
||||
include: {
|
||||
documentData: true,
|
||||
recipients: true,
|
||||
fields: true,
|
||||
},
|
||||
});
|
||||
|
||||
if (!document) {
|
||||
throw new AppError(AppErrorCode.NOT_FOUND, {
|
||||
message: 'Document not found',
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
document,
|
||||
};
|
||||
} catch (error) {
|
||||
if (error instanceof AppError) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
throw new AppError(AppErrorCode.UNKNOWN_ERROR, {
|
||||
message: 'Failed to get document',
|
||||
});
|
||||
}
|
||||
});
|
||||
@ -1,34 +0,0 @@
|
||||
import { DocumentDataType, type Field, type Recipient } from '@prisma/client';
|
||||
import { z } from 'zod';
|
||||
|
||||
export const ZGetEmbeddingDocumentRequestSchema = z.object({
|
||||
documentId: z.number(),
|
||||
});
|
||||
|
||||
export const ZGetEmbeddingDocumentResponseSchema = z.object({
|
||||
document: z
|
||||
.object({
|
||||
id: z.number(),
|
||||
title: z.string(),
|
||||
status: z.string(),
|
||||
documentDataId: z.string(),
|
||||
userId: z.number(),
|
||||
teamId: z.number().nullable(),
|
||||
createdAt: z.date(),
|
||||
updatedAt: z.date(),
|
||||
documentData: z.object({
|
||||
id: z.string(),
|
||||
type: z.nativeEnum(DocumentDataType),
|
||||
data: z.string(),
|
||||
initialData: z.string(),
|
||||
}),
|
||||
recipients: z.array(z.custom<Recipient>()),
|
||||
fields: z.array(z.custom<Field>()),
|
||||
})
|
||||
.nullable(),
|
||||
});
|
||||
|
||||
export type TGetEmbeddingDocumentRequestSchema = z.infer<typeof ZGetEmbeddingDocumentRequestSchema>;
|
||||
export type TGetEmbeddingDocumentResponseSchema = z.infer<
|
||||
typeof ZGetEmbeddingDocumentResponseSchema
|
||||
>;
|
||||
@ -0,0 +1,118 @@
|
||||
import { AppError, AppErrorCode } from '@documenso/lib/errors/app-error';
|
||||
import { upsertDocumentMeta } from '@documenso/lib/server-only/document-meta/upsert-document-meta';
|
||||
import { updateDocument } from '@documenso/lib/server-only/document/update-document';
|
||||
import { verifyEmbeddingPresignToken } from '@documenso/lib/server-only/embedding-presign/verify-embedding-presign-token';
|
||||
import { setFieldsForDocument } from '@documenso/lib/server-only/field/set-fields-for-document';
|
||||
import { setDocumentRecipients } from '@documenso/lib/server-only/recipient/set-document-recipients';
|
||||
import { nanoid } from '@documenso/lib/universal/id';
|
||||
|
||||
import { procedure } from '../trpc';
|
||||
import {
|
||||
ZUpdateEmbeddingDocumentRequestSchema,
|
||||
ZUpdateEmbeddingDocumentResponseSchema,
|
||||
} from './update-embedding-document.types';
|
||||
|
||||
export const updateEmbeddingDocumentRoute = procedure
|
||||
.input(ZUpdateEmbeddingDocumentRequestSchema)
|
||||
.output(ZUpdateEmbeddingDocumentResponseSchema)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
try {
|
||||
const authorizationHeader = ctx.req.headers.get('authorization');
|
||||
|
||||
const [presignToken] = (authorizationHeader || '')
|
||||
.split('Bearer ')
|
||||
.filter((s) => s.length > 0);
|
||||
|
||||
if (!presignToken) {
|
||||
throw new AppError(AppErrorCode.UNAUTHORIZED, {
|
||||
message: 'No presign token provided',
|
||||
});
|
||||
}
|
||||
|
||||
const apiToken = await verifyEmbeddingPresignToken({ token: presignToken });
|
||||
|
||||
const { documentId, title, externalId, recipients, meta } = input;
|
||||
|
||||
if (meta && Object.values(meta).length > 0) {
|
||||
await upsertDocumentMeta({
|
||||
documentId: documentId,
|
||||
userId: apiToken.userId,
|
||||
teamId: apiToken.teamId ?? undefined,
|
||||
...meta,
|
||||
requestMetadata: ctx.metadata,
|
||||
});
|
||||
}
|
||||
|
||||
await updateDocument({
|
||||
userId: apiToken.userId,
|
||||
teamId: apiToken.teamId ?? undefined,
|
||||
documentId: documentId,
|
||||
data: {
|
||||
title,
|
||||
externalId,
|
||||
},
|
||||
requestMetadata: ctx.metadata,
|
||||
});
|
||||
|
||||
const recipientsWithClientId = recipients.map((recipient) => ({
|
||||
...recipient,
|
||||
clientId: nanoid(),
|
||||
}));
|
||||
|
||||
const { recipients: updatedRecipients } = await setDocumentRecipients({
|
||||
userId: apiToken.userId,
|
||||
teamId: apiToken.teamId ?? undefined,
|
||||
documentId: documentId,
|
||||
recipients: recipientsWithClientId.map((recipient) => ({
|
||||
id: recipient.id,
|
||||
clientId: recipient.clientId,
|
||||
email: recipient.email,
|
||||
name: recipient.name ?? '',
|
||||
role: recipient.role,
|
||||
signingOrder: recipient.signingOrder,
|
||||
})),
|
||||
requestMetadata: ctx.metadata,
|
||||
});
|
||||
|
||||
const fields = recipientsWithClientId.flatMap((recipient) => {
|
||||
const recipientId = updatedRecipients.find((r) => r.clientId === recipient.clientId)?.id;
|
||||
|
||||
if (!recipientId) {
|
||||
throw new AppError(AppErrorCode.UNKNOWN_ERROR, {
|
||||
message: 'Recipient not found',
|
||||
});
|
||||
}
|
||||
|
||||
return (recipient.fields ?? []).map((field) => ({
|
||||
...field,
|
||||
recipientId,
|
||||
// !: Temp property to be removed once we don't link based on signer email
|
||||
signerEmail: recipient.email,
|
||||
}));
|
||||
});
|
||||
|
||||
await setFieldsForDocument({
|
||||
userId: apiToken.userId,
|
||||
teamId: apiToken.teamId ?? undefined,
|
||||
documentId,
|
||||
fields: fields.map((field) => ({
|
||||
...field,
|
||||
pageWidth: field.width,
|
||||
pageHeight: field.height,
|
||||
})),
|
||||
requestMetadata: ctx.metadata,
|
||||
});
|
||||
|
||||
return {
|
||||
documentId,
|
||||
};
|
||||
} catch (error) {
|
||||
if (error instanceof AppError) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
throw new AppError(AppErrorCode.UNKNOWN_ERROR, {
|
||||
message: 'Failed to update document',
|
||||
});
|
||||
}
|
||||
});
|
||||
@ -0,0 +1,87 @@
|
||||
import { z } from 'zod';
|
||||
|
||||
import { ZDocumentEmailSettingsSchema } from '@documenso/lib/types/document-email';
|
||||
import {
|
||||
ZFieldHeightSchema,
|
||||
ZFieldPageNumberSchema,
|
||||
ZFieldPageXSchema,
|
||||
ZFieldPageYSchema,
|
||||
ZFieldWidthSchema,
|
||||
} from '@documenso/lib/types/field';
|
||||
import { ZFieldAndMetaSchema } from '@documenso/lib/types/field-meta';
|
||||
import { DocumentSigningOrder, RecipientRole } from '@documenso/prisma/generated/types';
|
||||
|
||||
import {
|
||||
ZDocumentExternalIdSchema,
|
||||
ZDocumentMetaDateFormatSchema,
|
||||
ZDocumentMetaDistributionMethodSchema,
|
||||
ZDocumentMetaDrawSignatureEnabledSchema,
|
||||
ZDocumentMetaLanguageSchema,
|
||||
ZDocumentMetaMessageSchema,
|
||||
ZDocumentMetaRedirectUrlSchema,
|
||||
ZDocumentMetaSubjectSchema,
|
||||
ZDocumentMetaTimezoneSchema,
|
||||
ZDocumentMetaTypedSignatureEnabledSchema,
|
||||
ZDocumentMetaUploadSignatureEnabledSchema,
|
||||
ZDocumentTitleSchema,
|
||||
} from '../document-router/schema';
|
||||
|
||||
export const ZUpdateEmbeddingDocumentRequestSchema = z.object({
|
||||
documentId: z.number(),
|
||||
title: ZDocumentTitleSchema,
|
||||
externalId: ZDocumentExternalIdSchema.optional(),
|
||||
recipients: z
|
||||
.array(
|
||||
z.object({
|
||||
id: z.number().optional(),
|
||||
email: z.string().toLowerCase().email().min(1),
|
||||
name: z.string(),
|
||||
role: z.nativeEnum(RecipientRole),
|
||||
signingOrder: z.number().optional(),
|
||||
fields: ZFieldAndMetaSchema.and(
|
||||
z.object({
|
||||
id: z.number().optional(),
|
||||
pageNumber: ZFieldPageNumberSchema,
|
||||
pageX: ZFieldPageXSchema,
|
||||
pageY: ZFieldPageYSchema,
|
||||
width: ZFieldWidthSchema,
|
||||
height: ZFieldHeightSchema,
|
||||
}),
|
||||
)
|
||||
.array()
|
||||
.optional(),
|
||||
}),
|
||||
)
|
||||
.refine(
|
||||
(recipients) => {
|
||||
const emails = recipients.map((recipient) => recipient.email);
|
||||
|
||||
return new Set(emails).size === emails.length;
|
||||
},
|
||||
{ message: 'Recipients must have unique emails' },
|
||||
),
|
||||
meta: z
|
||||
.object({
|
||||
subject: ZDocumentMetaSubjectSchema.optional(),
|
||||
message: ZDocumentMetaMessageSchema.optional(),
|
||||
timezone: ZDocumentMetaTimezoneSchema.optional(),
|
||||
dateFormat: ZDocumentMetaDateFormatSchema.optional(),
|
||||
distributionMethod: ZDocumentMetaDistributionMethodSchema.optional(),
|
||||
signingOrder: z.nativeEnum(DocumentSigningOrder).optional(),
|
||||
redirectUrl: ZDocumentMetaRedirectUrlSchema.optional(),
|
||||
language: ZDocumentMetaLanguageSchema.optional(),
|
||||
typedSignatureEnabled: ZDocumentMetaTypedSignatureEnabledSchema.optional(),
|
||||
drawSignatureEnabled: ZDocumentMetaDrawSignatureEnabledSchema.optional(),
|
||||
uploadSignatureEnabled: ZDocumentMetaUploadSignatureEnabledSchema.optional(),
|
||||
emailSettings: ZDocumentEmailSettingsSchema.optional(),
|
||||
})
|
||||
.optional(),
|
||||
});
|
||||
|
||||
export const ZUpdateEmbeddingDocumentResponseSchema = z.object({
|
||||
documentId: z.number(),
|
||||
});
|
||||
|
||||
export type TUpdateEmbeddingDocumentRequestSchema = z.infer<
|
||||
typeof ZUpdateEmbeddingDocumentRequestSchema
|
||||
>;
|
||||
@ -0,0 +1,104 @@
|
||||
import { AppError, AppErrorCode } from '@documenso/lib/errors/app-error';
|
||||
import { verifyEmbeddingPresignToken } from '@documenso/lib/server-only/embedding-presign/verify-embedding-presign-token';
|
||||
import { setFieldsForTemplate } from '@documenso/lib/server-only/field/set-fields-for-template';
|
||||
import { setTemplateRecipients } from '@documenso/lib/server-only/recipient/set-template-recipients';
|
||||
import { updateTemplate } from '@documenso/lib/server-only/template/update-template';
|
||||
import { nanoid } from '@documenso/lib/universal/id';
|
||||
|
||||
import { procedure } from '../trpc';
|
||||
import {
|
||||
ZUpdateEmbeddingTemplateRequestSchema,
|
||||
ZUpdateEmbeddingTemplateResponseSchema,
|
||||
} from './update-embedding-template.types';
|
||||
|
||||
export const updateEmbeddingTemplateRoute = procedure
|
||||
.input(ZUpdateEmbeddingTemplateRequestSchema)
|
||||
.output(ZUpdateEmbeddingTemplateResponseSchema)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
try {
|
||||
const authorizationHeader = ctx.req.headers.get('authorization');
|
||||
|
||||
const [presignToken] = (authorizationHeader || '')
|
||||
.split('Bearer ')
|
||||
.filter((s) => s.length > 0);
|
||||
|
||||
if (!presignToken) {
|
||||
throw new AppError(AppErrorCode.UNAUTHORIZED, {
|
||||
message: 'No presign token provided',
|
||||
});
|
||||
}
|
||||
|
||||
const apiToken = await verifyEmbeddingPresignToken({ token: presignToken });
|
||||
|
||||
const { templateId, title, externalId, recipients, meta } = input;
|
||||
|
||||
await updateTemplate({
|
||||
templateId,
|
||||
userId: apiToken.userId,
|
||||
teamId: apiToken.teamId ?? undefined,
|
||||
data: {
|
||||
title,
|
||||
externalId,
|
||||
},
|
||||
meta,
|
||||
});
|
||||
|
||||
const recipientsWithClientId = recipients.map((recipient) => ({
|
||||
...recipient,
|
||||
clientId: nanoid(),
|
||||
}));
|
||||
|
||||
const { recipients: updatedRecipients } = await setTemplateRecipients({
|
||||
userId: apiToken.userId,
|
||||
teamId: apiToken.teamId ?? undefined,
|
||||
templateId,
|
||||
recipients: recipientsWithClientId.map((recipient) => ({
|
||||
id: recipient.id,
|
||||
email: recipient.email,
|
||||
name: recipient.name ?? '',
|
||||
role: recipient.role ?? 'SIGNER',
|
||||
signingOrder: recipient.signingOrder,
|
||||
})),
|
||||
});
|
||||
|
||||
const fields = recipientsWithClientId.flatMap((recipient) => {
|
||||
const recipientId = updatedRecipients.find((r) => r.email === recipient.email)?.id;
|
||||
|
||||
if (!recipientId) {
|
||||
throw new AppError(AppErrorCode.UNKNOWN_ERROR, {
|
||||
message: 'Recipient not found',
|
||||
});
|
||||
}
|
||||
|
||||
return (recipient.fields ?? []).map((field) => ({
|
||||
...field,
|
||||
recipientId,
|
||||
// !: Temp property to be removed once we don't link based on signer email
|
||||
signerEmail: recipient.email,
|
||||
}));
|
||||
});
|
||||
|
||||
await setFieldsForTemplate({
|
||||
userId: apiToken.userId,
|
||||
teamId: apiToken.teamId ?? undefined,
|
||||
templateId,
|
||||
fields: fields.map((field) => ({
|
||||
...field,
|
||||
pageWidth: field.width,
|
||||
pageHeight: field.height,
|
||||
})),
|
||||
});
|
||||
|
||||
return {
|
||||
templateId,
|
||||
};
|
||||
} catch (error) {
|
||||
if (error instanceof AppError) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
throw new AppError(AppErrorCode.UNKNOWN_ERROR, {
|
||||
message: 'Failed to update template',
|
||||
});
|
||||
}
|
||||
});
|
||||
@ -0,0 +1,77 @@
|
||||
import { DocumentSigningOrder, FieldType, RecipientRole } from '@prisma/client';
|
||||
import { z } from 'zod';
|
||||
|
||||
import { ZDocumentEmailSettingsSchema } from '@documenso/lib/types/document-email';
|
||||
import {
|
||||
ZFieldHeightSchema,
|
||||
ZFieldPageNumberSchema,
|
||||
ZFieldPageXSchema,
|
||||
ZFieldPageYSchema,
|
||||
ZFieldWidthSchema,
|
||||
} from '@documenso/lib/types/field';
|
||||
import { ZFieldMetaSchema } from '@documenso/lib/types/field-meta';
|
||||
|
||||
import {
|
||||
ZDocumentMetaDateFormatSchema,
|
||||
ZDocumentMetaDistributionMethodSchema,
|
||||
ZDocumentMetaDrawSignatureEnabledSchema,
|
||||
ZDocumentMetaLanguageSchema,
|
||||
ZDocumentMetaMessageSchema,
|
||||
ZDocumentMetaRedirectUrlSchema,
|
||||
ZDocumentMetaSubjectSchema,
|
||||
ZDocumentMetaTimezoneSchema,
|
||||
ZDocumentMetaTypedSignatureEnabledSchema,
|
||||
ZDocumentMetaUploadSignatureEnabledSchema,
|
||||
ZDocumentTitleSchema,
|
||||
} from '../document-router/schema';
|
||||
|
||||
const ZFieldSchema = z.object({
|
||||
id: z.number().optional(),
|
||||
type: z.nativeEnum(FieldType),
|
||||
pageNumber: ZFieldPageNumberSchema,
|
||||
pageX: ZFieldPageXSchema,
|
||||
pageY: ZFieldPageYSchema,
|
||||
width: ZFieldWidthSchema,
|
||||
height: ZFieldHeightSchema,
|
||||
fieldMeta: ZFieldMetaSchema.optional(),
|
||||
});
|
||||
|
||||
export const ZUpdateEmbeddingTemplateRequestSchema = z.object({
|
||||
templateId: z.number(),
|
||||
title: ZDocumentTitleSchema.optional(),
|
||||
externalId: z.string().optional(),
|
||||
recipients: z.array(
|
||||
z.object({
|
||||
id: z.number().optional(),
|
||||
email: z.string().email(),
|
||||
name: z.string().optional(),
|
||||
role: z.nativeEnum(RecipientRole).optional(),
|
||||
signingOrder: z.number().optional(),
|
||||
fields: z.array(ZFieldSchema).optional(),
|
||||
}),
|
||||
),
|
||||
meta: z
|
||||
.object({
|
||||
subject: ZDocumentMetaSubjectSchema.optional(),
|
||||
message: ZDocumentMetaMessageSchema.optional(),
|
||||
timezone: ZDocumentMetaTimezoneSchema.optional(),
|
||||
dateFormat: ZDocumentMetaDateFormatSchema.optional(),
|
||||
distributionMethod: ZDocumentMetaDistributionMethodSchema.optional(),
|
||||
signingOrder: z.nativeEnum(DocumentSigningOrder).optional(),
|
||||
redirectUrl: ZDocumentMetaRedirectUrlSchema.optional(),
|
||||
language: ZDocumentMetaLanguageSchema.optional(),
|
||||
typedSignatureEnabled: ZDocumentMetaTypedSignatureEnabledSchema.optional(),
|
||||
drawSignatureEnabled: ZDocumentMetaDrawSignatureEnabledSchema.optional(),
|
||||
uploadSignatureEnabled: ZDocumentMetaUploadSignatureEnabledSchema.optional(),
|
||||
emailSettings: ZDocumentEmailSettingsSchema.optional(),
|
||||
})
|
||||
.optional(),
|
||||
});
|
||||
|
||||
export const ZUpdateEmbeddingTemplateResponseSchema = z.object({
|
||||
templateId: z.number(),
|
||||
});
|
||||
|
||||
export type TUpdateEmbeddingTemplateRequestSchema = z.infer<
|
||||
typeof ZUpdateEmbeddingTemplateRequestSchema
|
||||
>;
|
||||
@ -30,7 +30,7 @@ export const ZCreateRecipientSchema = z.object({
|
||||
actionAuth: ZRecipientActionAuthTypesSchema.optional().nullable(),
|
||||
});
|
||||
|
||||
const ZUpdateRecipientSchema = z.object({
|
||||
export const ZUpdateRecipientSchema = z.object({
|
||||
id: z.number().describe('The ID of the recipient to update.'),
|
||||
email: z.string().toLowerCase().email().min(1).optional(),
|
||||
name: z.string().optional(),
|
||||
|
||||
Reference in New Issue
Block a user