Merge branch 'main' into feat/public-api

This commit is contained in:
Lucas Smith
2024-02-09 16:00:40 +11:00
committed by GitHub
401 changed files with 20803 additions and 2358 deletions

View File

@ -10,7 +10,20 @@ export const getFieldsForDocument = async ({ documentId, userId }: GetFieldsForD
where: {
documentId,
Document: {
userId,
OR: [
{
userId,
},
{
team: {
members: {
some: {
userId,
},
},
},
},
],
},
},
orderBy: {

View File

@ -0,0 +1,35 @@
import { prisma } from '@documenso/prisma';
export interface GetFieldsForTemplateOptions {
templateId: number;
userId: number;
}
export const getFieldsForTemplate = async ({ templateId, userId }: GetFieldsForTemplateOptions) => {
const fields = await prisma.field.findMany({
where: {
templateId,
Template: {
OR: [
{
userId,
},
{
team: {
members: {
some: {
userId,
},
},
},
},
],
},
},
orderBy: {
id: 'asc',
},
});
return fields;
};

View File

@ -27,6 +27,10 @@ export const removeSignedFieldWithToken = async ({
const { Document: document, Recipient: recipient } = field;
if (!document) {
throw new Error(`Document not found for field ${field.id}`);
}
if (document.status === DocumentStatus.COMPLETED) {
throw new Error(`Document ${document.id} has already been completed`);
}

View File

@ -1,5 +1,6 @@
import { prisma } from '@documenso/prisma';
import { FieldType, SendStatus, SigningStatus } from '@documenso/prisma/client';
import type { FieldType } from '@documenso/prisma/client';
import { SendStatus, SigningStatus } from '@documenso/prisma/client';
export interface SetFieldsForDocumentOptions {
userId: number;
@ -24,7 +25,20 @@ export const setFieldsForDocument = async ({
const document = await prisma.document.findFirst({
where: {
id: documentId,
userId,
OR: [
{
userId,
},
{
team: {
members: {
some: {
userId,
},
},
},
},
],
},
});
@ -32,6 +46,10 @@ export const setFieldsForDocument = async ({
throw new Error('Document not found');
}
if (document.completedAt) {
throw new Error('Document already complete');
}
const existingFields = await prisma.field.findMany({
where: {
documentId,
@ -42,11 +60,7 @@ export const setFieldsForDocument = async ({
});
const removedFields = existingFields.filter(
(existingField) =>
!fields.find(
(field) =>
field.id === existingField.id || field.signerEmail === existingField.Recipient?.email,
),
(existingField) => !fields.find((field) => field.id === existingField.id),
);
const linkedFields = fields

View File

@ -0,0 +1,131 @@
import { prisma } from '@documenso/prisma';
import type { FieldType } from '@documenso/prisma/client';
export type Field = {
id?: number | null;
type: FieldType;
signerEmail: string;
signerId?: number;
pageNumber: number;
pageX: number;
pageY: number;
pageWidth: number;
pageHeight: number;
};
export type SetFieldsForTemplateOptions = {
userId: number;
templateId: number;
fields: Field[];
};
export const setFieldsForTemplate = async ({
userId,
templateId,
fields,
}: SetFieldsForTemplateOptions) => {
const template = await prisma.template.findFirst({
where: {
id: templateId,
OR: [
{
userId,
},
{
team: {
members: {
some: {
userId,
},
},
},
},
],
},
});
if (!template) {
throw new Error('Template not found');
}
const existingFields = await prisma.field.findMany({
where: {
templateId,
},
include: {
Recipient: true,
},
});
const removedFields = existingFields.filter(
(existingField) =>
!fields.find(
(field) =>
field.id === existingField.id || field.signerEmail === existingField.Recipient?.email,
),
);
const linkedFields = fields.map((field) => {
const existing = existingFields.find((existingField) => existingField.id === field.id);
return {
...field,
_persisted: existing,
};
});
const persistedFields = await prisma.$transaction(
// Disabling as wrapping promises here causes type issues
// eslint-disable-next-line @typescript-eslint/promise-function-async
linkedFields.map((field) =>
prisma.field.upsert({
where: {
id: field._persisted?.id ?? -1,
templateId,
},
update: {
page: field.pageNumber,
positionX: field.pageX,
positionY: field.pageY,
width: field.pageWidth,
height: field.pageHeight,
},
create: {
type: field.type,
page: field.pageNumber,
positionX: field.pageX,
positionY: field.pageY,
width: field.pageWidth,
height: field.pageHeight,
customText: '',
inserted: false,
Template: {
connect: {
id: templateId,
},
},
Recipient: {
connect: {
templateId_email: {
templateId,
email: field.signerEmail.toLowerCase(),
},
},
},
},
}),
),
);
if (removedFields.length > 0) {
await prisma.field.deleteMany({
where: {
id: {
in: removedFields.map((field) => field.id),
},
},
});
}
return persistedFields;
};

View File

@ -5,6 +5,9 @@ import { DateTime } from 'luxon';
import { prisma } from '@documenso/prisma';
import { DocumentStatus, FieldType, SigningStatus } from '@documenso/prisma/client';
import { DEFAULT_DOCUMENT_DATE_FORMAT } from '../../constants/date-formats';
import { DEFAULT_DOCUMENT_TIME_ZONE } from '../../constants/time-zones';
export type SignFieldWithTokenOptions = {
token: string;
fieldId: number;
@ -33,6 +36,10 @@ export const signFieldWithToken = async ({
const { Document: document, Recipient: recipient } = field;
if (!document) {
throw new Error(`Document not found for field ${field.id}`);
}
if (document.status === DocumentStatus.COMPLETED) {
throw new Error(`Document ${document.id} has already been completed`);
}
@ -54,6 +61,12 @@ export const signFieldWithToken = async ({
throw new Error(`Field ${fieldId} has no recipientId`);
}
const documentMeta = await prisma.documentMeta.findFirst({
where: {
documentId: document.id,
},
});
const isSignatureField =
field.type === FieldType.SIGNATURE || field.type === FieldType.FREE_SIGNATURE;
@ -63,7 +76,9 @@ export const signFieldWithToken = async ({
const typedSignature = isSignatureField && !isBase64 ? value : undefined;
if (field.type === FieldType.DATE) {
customText = DateTime.now().toFormat('yyyy-MM-dd hh:mm a');
customText = DateTime.now()
.setZone(documentMeta?.timezone ?? DEFAULT_DOCUMENT_TIME_ZONE)
.toFormat(documentMeta?.dateFormat ?? DEFAULT_DOCUMENT_DATE_FORMAT);
}
if (isSignatureField && !signatureImageAsBase64 && !typedSignature) {