mirror of
https://github.com/documenso/documenso.git
synced 2025-11-22 04:31:39 +10:00
fix: refactor api routes
This commit is contained in:
@ -0,0 +1,64 @@
|
||||
import { z } from 'zod';
|
||||
|
||||
import { createDocumentFromDirectTemplate } from '@documenso/lib/server-only/template/create-document-from-direct-template';
|
||||
import { extractNextApiRequestMetadata } from '@documenso/lib/universal/extract-request-metadata';
|
||||
|
||||
import { ZSignFieldWithTokenMutationSchema } from '../field-router/schema';
|
||||
import { maybeAuthenticatedProcedure } from '../trpc';
|
||||
|
||||
export const ZCreateDocumentFromTemplateRequestSchema = z.object({
|
||||
directRecipientName: z.string().optional(),
|
||||
directRecipientEmail: z.string().email(),
|
||||
directTemplateToken: z.string().min(1),
|
||||
directTemplateExternalId: z.string().optional(),
|
||||
signedFieldValues: z.array(ZSignFieldWithTokenMutationSchema),
|
||||
templateUpdatedAt: z.date(),
|
||||
});
|
||||
|
||||
export const ZCreateDocumentFromTemplateResponseSchema = z.object({
|
||||
token: z.string(),
|
||||
documentId: z.number(),
|
||||
recipientId: z.number(),
|
||||
});
|
||||
|
||||
export const createDocumentFromTemplateRoute = maybeAuthenticatedProcedure
|
||||
.meta({
|
||||
openapi: {
|
||||
method: 'POST',
|
||||
path: '/template/use',
|
||||
summary: 'Use direct template',
|
||||
description: 'Use a direct template to create a document',
|
||||
tags: ['Template'],
|
||||
},
|
||||
})
|
||||
.input(ZCreateDocumentFromTemplateRequestSchema)
|
||||
.output(ZCreateDocumentFromTemplateResponseSchema)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const {
|
||||
directRecipientName,
|
||||
directRecipientEmail,
|
||||
directTemplateToken,
|
||||
directTemplateExternalId,
|
||||
signedFieldValues,
|
||||
templateUpdatedAt,
|
||||
} = input;
|
||||
|
||||
const requestMetadata = extractNextApiRequestMetadata(ctx.req);
|
||||
|
||||
return await createDocumentFromDirectTemplate({
|
||||
directRecipientName,
|
||||
directRecipientEmail,
|
||||
directTemplateToken,
|
||||
directTemplateExternalId,
|
||||
signedFieldValues,
|
||||
templateUpdatedAt,
|
||||
user: ctx.user
|
||||
? {
|
||||
id: ctx.user.id,
|
||||
name: ctx.user.name || undefined,
|
||||
email: ctx.user.email,
|
||||
}
|
||||
: undefined,
|
||||
requestMetadata,
|
||||
});
|
||||
});
|
||||
@ -0,0 +1,94 @@
|
||||
import { z } from 'zod';
|
||||
|
||||
import { getServerLimits } from '@documenso/ee/server-only/limits/server';
|
||||
import { AppError } from '@documenso/lib/errors/app-error';
|
||||
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 { createDocumentFromTemplate } from '@documenso/lib/server-only/template/create-document-from-template';
|
||||
import { extractNextApiRequestMetadata } from '@documenso/lib/universal/extract-request-metadata';
|
||||
import type { Document } from '@documenso/prisma/client';
|
||||
import {
|
||||
DocumentDataSchema,
|
||||
DocumentMetaSchema,
|
||||
DocumentSchema,
|
||||
FieldSchema,
|
||||
RecipientSchema,
|
||||
} from '@documenso/prisma/generated/zod';
|
||||
|
||||
import { authenticatedProcedure } from '../trpc';
|
||||
|
||||
export const ZCreateDocumentFromTemplateRequestSchema = z.object({
|
||||
templateId: z.number(),
|
||||
teamId: z.number().optional(),
|
||||
recipients: z
|
||||
.array(
|
||||
z.object({
|
||||
id: z.number(),
|
||||
email: z.string().email(),
|
||||
name: z.string().optional(),
|
||||
}),
|
||||
)
|
||||
.refine((recipients) => {
|
||||
const emails = recipients.map((signer) => signer.email);
|
||||
return new Set(emails).size === emails.length;
|
||||
}, 'Recipients must have unique emails'),
|
||||
distributeDocument: z.boolean().optional(),
|
||||
});
|
||||
|
||||
export const ZCreateDocumentFromTemplateResponseSchema = DocumentSchema.extend({
|
||||
documentData: DocumentDataSchema,
|
||||
documentMeta: DocumentMetaSchema.nullable(),
|
||||
Recipient: RecipientSchema.array(),
|
||||
Field: FieldSchema.array(),
|
||||
});
|
||||
|
||||
export const createDocumentFromTemplateRoute = authenticatedProcedure
|
||||
.meta({
|
||||
openapi: {
|
||||
method: 'POST',
|
||||
path: '/template/{templateId}/use',
|
||||
summary: 'Use template',
|
||||
description: 'Use the template to create a document',
|
||||
tags: ['Template'],
|
||||
},
|
||||
})
|
||||
.input(ZCreateDocumentFromTemplateRequestSchema)
|
||||
.output(ZCreateDocumentFromTemplateResponseSchema)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const { templateId, teamId, recipients, distributeDocument } = input;
|
||||
|
||||
const limits = await getServerLimits({ email: ctx.user.email, teamId });
|
||||
|
||||
if (limits.remaining.documents === 0) {
|
||||
throw new Error('You have reached your document limit.');
|
||||
}
|
||||
|
||||
const requestMetadata = extractNextApiRequestMetadata(ctx.req);
|
||||
|
||||
const document: Document = await createDocumentFromTemplate({
|
||||
templateId,
|
||||
teamId,
|
||||
userId: ctx.user.id,
|
||||
recipients,
|
||||
requestMetadata,
|
||||
});
|
||||
|
||||
if (distributeDocument) {
|
||||
await sendDocument({
|
||||
documentId: document.id,
|
||||
userId: ctx.user.id,
|
||||
teamId,
|
||||
requestMetadata,
|
||||
}).catch((err) => {
|
||||
console.error(err);
|
||||
|
||||
throw new AppError('DOCUMENT_SEND_FAILED');
|
||||
});
|
||||
}
|
||||
|
||||
return getDocumentWithDetailsById({
|
||||
documentId: document.id,
|
||||
userId: ctx.user.id,
|
||||
teamId,
|
||||
});
|
||||
});
|
||||
@ -0,0 +1,47 @@
|
||||
import { z } from 'zod';
|
||||
|
||||
import { getServerLimits } from '@documenso/ee/server-only/limits/server';
|
||||
import { AppError, AppErrorCode } from '@documenso/lib/errors/app-error';
|
||||
import { createTemplateDirectLink } from '@documenso/lib/server-only/template/create-template-direct-link';
|
||||
import { getTemplateById } from '@documenso/lib/server-only/template/get-template-by-id';
|
||||
import { TemplateDirectLinkSchema } from '@documenso/prisma/generated/zod';
|
||||
|
||||
import { authenticatedProcedure } from '../trpc';
|
||||
|
||||
export const ZCreateTemplateDirectLinkRequestSchema = z.object({
|
||||
templateId: z.number().min(1),
|
||||
teamId: z.number().optional(),
|
||||
directRecipientId: z.number().min(1).optional(),
|
||||
});
|
||||
|
||||
export const ZCreateTemplateDirectLinkResponseSchema = TemplateDirectLinkSchema;
|
||||
|
||||
export const createTemplateDirectLinkRoute = authenticatedProcedure
|
||||
.meta({
|
||||
openapi: {
|
||||
method: 'POST',
|
||||
path: '/template/{templateId}/direct/create',
|
||||
summary: 'Create direct link',
|
||||
description: 'Create a direct link for a template',
|
||||
tags: ['Template'],
|
||||
},
|
||||
})
|
||||
.input(ZCreateTemplateDirectLinkRequestSchema)
|
||||
.output(ZCreateTemplateDirectLinkResponseSchema)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const { templateId, teamId, directRecipientId } = input;
|
||||
|
||||
const userId = ctx.user.id;
|
||||
|
||||
const template = await getTemplateById({ id: templateId, teamId, userId: ctx.user.id });
|
||||
|
||||
const limits = await getServerLimits({ email: ctx.user.email, teamId: template.teamId });
|
||||
|
||||
if (limits.remaining.directTemplates === 0) {
|
||||
throw new AppError(AppErrorCode.LIMIT_EXCEEDED, {
|
||||
message: 'You have reached your direct templates limit.',
|
||||
});
|
||||
}
|
||||
|
||||
return await createTemplateDirectLink({ userId, templateId, directRecipientId });
|
||||
});
|
||||
@ -0,0 +1,37 @@
|
||||
import { z } from 'zod';
|
||||
|
||||
import { createTemplate } from '@documenso/lib/server-only/template/create-template';
|
||||
import { TemplateSchema } from '@documenso/prisma/generated/zod';
|
||||
|
||||
import { authenticatedProcedure } from '../trpc';
|
||||
|
||||
export const ZCreateTemplateRequestSchema = z.object({
|
||||
title: z.string().min(1).trim(),
|
||||
teamId: z.number().optional(),
|
||||
templateDocumentDataId: z.string().min(1),
|
||||
});
|
||||
|
||||
export const ZCreateTemplateResponseSchema = TemplateSchema;
|
||||
|
||||
export const createTemplateRoute = authenticatedProcedure
|
||||
.meta({
|
||||
openapi: {
|
||||
method: 'POST',
|
||||
path: '/template/create',
|
||||
summary: 'Create template',
|
||||
description: 'Create a new template',
|
||||
tags: ['Template'],
|
||||
},
|
||||
})
|
||||
.input(ZCreateTemplateRequestSchema)
|
||||
.output(ZCreateTemplateResponseSchema)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const { teamId, title, templateDocumentDataId } = input;
|
||||
|
||||
return await createTemplate({
|
||||
userId: ctx.user.id,
|
||||
teamId,
|
||||
title,
|
||||
templateDocumentDataId,
|
||||
});
|
||||
});
|
||||
@ -0,0 +1,32 @@
|
||||
import { z } from 'zod';
|
||||
|
||||
import { deleteTemplateDirectLink } from '@documenso/lib/server-only/template/delete-template-direct-link';
|
||||
import { TemplateDirectLinkSchema } from '@documenso/prisma/generated/zod';
|
||||
|
||||
import { authenticatedProcedure } from '../trpc';
|
||||
|
||||
export const ZDeleteTemplateDirectLinkRequestSchema = z.object({
|
||||
templateId: z.number().min(1),
|
||||
});
|
||||
|
||||
export const ZDeleteTemplateDirectLinkResponseSchema = TemplateDirectLinkSchema;
|
||||
|
||||
export const deleteTemplateDirectLinkRoute = authenticatedProcedure
|
||||
.meta({
|
||||
openapi: {
|
||||
method: 'POST',
|
||||
path: '/template/{templateId}/direct/delete',
|
||||
summary: 'Delete direct link',
|
||||
description: 'Delete a direct link for a template',
|
||||
tags: ['Template'],
|
||||
},
|
||||
})
|
||||
.input(ZDeleteTemplateDirectLinkResponseSchema)
|
||||
.output(z.void())
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const { templateId } = input;
|
||||
|
||||
const userId = ctx.user.id;
|
||||
|
||||
await deleteTemplateDirectLink({ userId, templateId });
|
||||
});
|
||||
@ -0,0 +1,33 @@
|
||||
import { z } from 'zod';
|
||||
|
||||
import { deleteTemplate } from '@documenso/lib/server-only/template/delete-template';
|
||||
import { TemplateSchema } from '@documenso/prisma/generated/zod';
|
||||
|
||||
import { authenticatedProcedure } from '../trpc';
|
||||
import { ZDeleteTemplateMutationSchema } from './schema';
|
||||
|
||||
export const ZDeleteTemplateRequestSchema = z.object({
|
||||
templateId: z.number().min(1),
|
||||
teamId: z.number().optional(),
|
||||
});
|
||||
|
||||
export const ZDeleteTemplateResponseSchema = TemplateSchema;
|
||||
|
||||
export const deleteTemplateRoute = authenticatedProcedure
|
||||
.meta({
|
||||
openapi: {
|
||||
method: 'POST',
|
||||
path: '/template/{templateId}/delete',
|
||||
summary: 'Delete template',
|
||||
tags: ['Template'],
|
||||
},
|
||||
})
|
||||
.input(ZDeleteTemplateMutationSchema)
|
||||
.output(z.void())
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const { templateId, teamId } = input;
|
||||
|
||||
const userId = ctx.user.id;
|
||||
|
||||
await deleteTemplate({ userId, id: templateId, teamId });
|
||||
});
|
||||
@ -0,0 +1,34 @@
|
||||
import { z } from 'zod';
|
||||
|
||||
import { duplicateTemplate } from '@documenso/lib/server-only/template/duplicate-template';
|
||||
import { TemplateSchema } from '@documenso/prisma/generated/zod';
|
||||
|
||||
import { authenticatedProcedure } from '../trpc';
|
||||
|
||||
export const ZDuplicateTemplateRequestSchema = z.object({
|
||||
templateId: z.number(),
|
||||
teamId: z.number().optional(),
|
||||
});
|
||||
|
||||
export const ZDuplicateTemplateResponseSchema = TemplateSchema;
|
||||
|
||||
export const duplicateTemplateRoute = authenticatedProcedure
|
||||
.meta({
|
||||
openapi: {
|
||||
method: 'POST',
|
||||
path: '/template/{templateId}/duplicate',
|
||||
summary: 'Duplicate template',
|
||||
tags: ['Template'],
|
||||
},
|
||||
})
|
||||
.input(ZDuplicateTemplateRequestSchema)
|
||||
.output(ZDuplicateTemplateResponseSchema)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const { teamId, templateId } = input;
|
||||
|
||||
return await duplicateTemplate({
|
||||
userId: ctx.user.id,
|
||||
teamId,
|
||||
templateId,
|
||||
});
|
||||
});
|
||||
62
packages/trpc/server/template-router/find-templates-route.ts
Normal file
62
packages/trpc/server/template-router/find-templates-route.ts
Normal file
@ -0,0 +1,62 @@
|
||||
import { z } from 'zod';
|
||||
|
||||
import { findTemplates } from '@documenso/lib/server-only/template/find-templates';
|
||||
import { ZFindResultResponse, ZFindSearchParamsSchema } from '@documenso/lib/types/search-params';
|
||||
import { TemplateType } from '@documenso/prisma/client';
|
||||
import {
|
||||
DocumentDataSchema,
|
||||
FieldSchema,
|
||||
RecipientSchema,
|
||||
TeamSchema,
|
||||
TemplateDirectLinkSchema,
|
||||
TemplateMetaSchema,
|
||||
TemplateSchema,
|
||||
} from '@documenso/prisma/generated/zod';
|
||||
|
||||
import { authenticatedProcedure } from '../trpc';
|
||||
|
||||
export const ZFindTemplatesRequestSchema = ZFindSearchParamsSchema.extend({
|
||||
teamId: z.number().optional(),
|
||||
type: z.nativeEnum(TemplateType).optional(),
|
||||
});
|
||||
|
||||
export const ZFindTemplatesResponseSchema = ZFindResultResponse.extend({
|
||||
data: TemplateSchema.extend({
|
||||
templateDocumentData: DocumentDataSchema,
|
||||
team: TeamSchema.pick({
|
||||
id: true,
|
||||
url: true,
|
||||
}).nullable(),
|
||||
Field: FieldSchema.array(),
|
||||
Recipient: RecipientSchema.array(),
|
||||
templateMeta: TemplateMetaSchema.pick({
|
||||
signingOrder: true,
|
||||
distributionMethod: true,
|
||||
}).nullable(),
|
||||
directLink: TemplateDirectLinkSchema.pick({
|
||||
token: true,
|
||||
enabled: true,
|
||||
}).nullable(),
|
||||
}).array(), // Todo: openapi.
|
||||
});
|
||||
|
||||
export type FindTemplateRow = z.infer<typeof ZFindTemplatesResponseSchema>['data'][number];
|
||||
|
||||
export const findTemplatesRoute = authenticatedProcedure
|
||||
.meta({
|
||||
openapi: {
|
||||
method: 'GET',
|
||||
path: '/template/find',
|
||||
summary: 'Find templates',
|
||||
description: 'Find templates based on a search criteria',
|
||||
tags: ['Template'],
|
||||
},
|
||||
})
|
||||
.input(ZFindTemplatesRequestSchema)
|
||||
.output(ZFindTemplatesResponseSchema)
|
||||
.query(async ({ input, ctx }) => {
|
||||
return await findTemplates({
|
||||
userId: ctx.user.id,
|
||||
...input,
|
||||
});
|
||||
});
|
||||
53
packages/trpc/server/template-router/get-template-route.ts
Normal file
53
packages/trpc/server/template-router/get-template-route.ts
Normal file
@ -0,0 +1,53 @@
|
||||
import { z } from 'zod';
|
||||
|
||||
import { getTemplateById } from '@documenso/lib/server-only/template/get-template-by-id';
|
||||
import {
|
||||
DocumentDataSchema,
|
||||
FieldSchema,
|
||||
RecipientSchema,
|
||||
TemplateDirectLinkSchema,
|
||||
TemplateMetaSchema,
|
||||
TemplateSchema,
|
||||
UserSchema,
|
||||
} from '@documenso/prisma/generated/zod';
|
||||
|
||||
import { authenticatedProcedure } from '../trpc';
|
||||
|
||||
export const ZGetTemplateRequestSchema = z.object({
|
||||
templateId: z.number().min(1),
|
||||
teamId: z.number().optional(),
|
||||
});
|
||||
|
||||
export const ZGetTemplateResponseSchema = TemplateSchema.extend({
|
||||
directLink: TemplateDirectLinkSchema.nullable(),
|
||||
templateDocumentData: DocumentDataSchema,
|
||||
templateMeta: TemplateMetaSchema.nullable(),
|
||||
Recipient: RecipientSchema.array(),
|
||||
Field: FieldSchema.array(),
|
||||
User: UserSchema.pick({
|
||||
id: true,
|
||||
name: true,
|
||||
email: true,
|
||||
}),
|
||||
});
|
||||
|
||||
export const getTemplateRoute = authenticatedProcedure
|
||||
.meta({
|
||||
openapi: {
|
||||
method: 'GET',
|
||||
path: '/template/{templateId}',
|
||||
summary: 'Get template',
|
||||
tags: ['Template'],
|
||||
},
|
||||
})
|
||||
.input(ZGetTemplateRequestSchema)
|
||||
.output(ZGetTemplateResponseSchema)
|
||||
.query(async ({ input, ctx }) => {
|
||||
const { templateId, teamId } = input;
|
||||
|
||||
return await getTemplateById({
|
||||
id: templateId,
|
||||
userId: ctx.user.id,
|
||||
teamId,
|
||||
});
|
||||
});
|
||||
@ -0,0 +1,36 @@
|
||||
import { z } from 'zod';
|
||||
|
||||
import { moveTemplateToTeam } from '@documenso/lib/server-only/template/move-template-to-team';
|
||||
import { TemplateSchema } from '@documenso/prisma/generated/zod';
|
||||
|
||||
import { authenticatedProcedure } from '../trpc';
|
||||
|
||||
export const ZMoveTemplateToTeamRequestSchema = z.object({
|
||||
templateId: z.number(),
|
||||
teamId: z.number(),
|
||||
});
|
||||
|
||||
export const ZMoveTemplateToTeamResponseSchema = TemplateSchema;
|
||||
|
||||
export const moveTemplateToTeamRoute = authenticatedProcedure
|
||||
.meta({
|
||||
openapi: {
|
||||
method: 'POST',
|
||||
path: '/template/{templateId}/move',
|
||||
summary: 'Move template',
|
||||
description: 'Move a template to a team',
|
||||
tags: ['Template'],
|
||||
},
|
||||
})
|
||||
.input(ZMoveTemplateToTeamRequestSchema)
|
||||
.output(ZMoveTemplateToTeamResponseSchema)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const { templateId, teamId } = input;
|
||||
const userId = ctx.user.id;
|
||||
|
||||
return await moveTemplateToTeam({
|
||||
templateId,
|
||||
teamId,
|
||||
userId,
|
||||
});
|
||||
});
|
||||
@ -1,479 +1,38 @@
|
||||
import { TRPCError } from '@trpc/server';
|
||||
import { z } from 'zod';
|
||||
|
||||
import { getServerLimits } from '@documenso/ee/server-only/limits/server';
|
||||
import { isValidLanguageCode } from '@documenso/lib/constants/i18n';
|
||||
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 { sendDocument } from '@documenso/lib/server-only/document/send-document';
|
||||
import {
|
||||
ZCreateDocumentFromDirectTemplateResponseSchema,
|
||||
createDocumentFromDirectTemplate,
|
||||
} from '@documenso/lib/server-only/template/create-document-from-direct-template';
|
||||
import { createDocumentFromTemplate } from '@documenso/lib/server-only/template/create-document-from-template';
|
||||
import {
|
||||
ZCreateTemplateResponseSchema,
|
||||
createTemplate,
|
||||
} from '@documenso/lib/server-only/template/create-template';
|
||||
import {
|
||||
ZCreateTemplateDirectLinkResponseSchema,
|
||||
createTemplateDirectLink,
|
||||
} from '@documenso/lib/server-only/template/create-template-direct-link';
|
||||
import { deleteTemplate } from '@documenso/lib/server-only/template/delete-template';
|
||||
import { deleteTemplateDirectLink } from '@documenso/lib/server-only/template/delete-template-direct-link';
|
||||
import {
|
||||
ZDuplicateTemplateResponseSchema,
|
||||
duplicateTemplate,
|
||||
} from '@documenso/lib/server-only/template/duplicate-template';
|
||||
import {
|
||||
ZFindTemplatesResponseSchema,
|
||||
findTemplates,
|
||||
} from '@documenso/lib/server-only/template/find-templates';
|
||||
import {
|
||||
ZGetTemplateByIdResponseSchema,
|
||||
getTemplateById,
|
||||
} from '@documenso/lib/server-only/template/get-template-by-id';
|
||||
import {
|
||||
ZMoveTemplateToTeamResponseSchema,
|
||||
moveTemplateToTeam,
|
||||
} from '@documenso/lib/server-only/template/move-template-to-team';
|
||||
import {
|
||||
ZToggleTemplateDirectLinkResponseSchema,
|
||||
toggleTemplateDirectLink,
|
||||
} from '@documenso/lib/server-only/template/toggle-template-direct-link';
|
||||
import {
|
||||
ZUpdateTemplateSettingsResponseSchema,
|
||||
updateTemplateSettings,
|
||||
} from '@documenso/lib/server-only/template/update-template-settings';
|
||||
import { extractNextApiRequestMetadata } from '@documenso/lib/universal/extract-request-metadata';
|
||||
import type { Document } from '@documenso/prisma/client';
|
||||
|
||||
import { authenticatedProcedure, maybeAuthenticatedProcedure, router } from '../trpc';
|
||||
import {
|
||||
ZCreateDocumentFromDirectTemplateMutationSchema,
|
||||
ZCreateDocumentFromTemplateMutationSchema,
|
||||
ZCreateTemplateDirectLinkMutationSchema,
|
||||
ZCreateTemplateMutationSchema,
|
||||
ZDeleteTemplateDirectLinkMutationSchema,
|
||||
ZDeleteTemplateMutationSchema,
|
||||
ZDuplicateTemplateMutationSchema,
|
||||
ZFindTemplatesQuerySchema,
|
||||
ZGetTemplateByIdQuerySchema,
|
||||
ZMoveTemplatesToTeamSchema,
|
||||
ZSetSigningOrderForTemplateMutationSchema,
|
||||
ZToggleTemplateDirectLinkMutationSchema,
|
||||
ZUpdateTemplateSettingsMutationSchema,
|
||||
ZUpdateTemplateTypedSignatureSettingsMutationSchema,
|
||||
} from './schema';
|
||||
import { router } from '../trpc';
|
||||
import { createDocumentFromTemplateRoute } from './create-document-from-template-route';
|
||||
import { createTemplateDirectLinkRoute } from './create-template-direct-link-route';
|
||||
import { createTemplateRoute } from './create-template-route';
|
||||
import { deleteTemplateDirectLinkRoute } from './delete-template-direct-link-route';
|
||||
import { deleteTemplateRoute } from './delete-template-route';
|
||||
import { duplicateTemplateRoute } from './duplicate-template-route';
|
||||
import { findTemplatesRoute } from './find-templates-route';
|
||||
import { getTemplateRoute } from './get-template-route';
|
||||
import { moveTemplateToTeamRoute } from './move-template-to-team-route';
|
||||
import { setSigningOrderForTemplateRoute } from './set-signing-order-for-template-route';
|
||||
import { toggleTemplateDirectLinkRoute } from './toggle-template-direct-link-route';
|
||||
import { updateTemplateRoute } from './update-template-route';
|
||||
import { updateTemplateTypedSignatureSettingsRoute } from './update-template-typed-signature-settings-route';
|
||||
|
||||
export const templateRouter = router({
|
||||
/**
|
||||
* @public
|
||||
* Public endpoints.
|
||||
*/
|
||||
findTemplates: authenticatedProcedure
|
||||
.meta({
|
||||
openapi: {
|
||||
method: 'GET',
|
||||
path: '/template/find',
|
||||
summary: 'Find templates',
|
||||
description: 'Find templates based on a search criteria',
|
||||
tags: ['Template'],
|
||||
},
|
||||
})
|
||||
.input(ZFindTemplatesQuerySchema)
|
||||
.output(ZFindTemplatesResponseSchema)
|
||||
.query(async ({ input, ctx }) => {
|
||||
return await findTemplates({
|
||||
userId: ctx.user.id,
|
||||
...input,
|
||||
});
|
||||
}),
|
||||
findTemplates: findTemplatesRoute,
|
||||
getTemplateById: getTemplateRoute,
|
||||
createTemplate: createTemplateRoute,
|
||||
updateTemplate: updateTemplateRoute,
|
||||
duplicateTemplate: duplicateTemplateRoute,
|
||||
deleteTemplate: deleteTemplateRoute,
|
||||
createDocumentFromTemplate: createDocumentFromTemplateRoute,
|
||||
createDocumentFromDirectTemplate: createDocumentFromTemplateRoute,
|
||||
createTemplateDirectLink: createTemplateDirectLinkRoute,
|
||||
deleteTemplateDirectLink: deleteTemplateDirectLinkRoute,
|
||||
toggleTemplateDirectLink: toggleTemplateDirectLinkRoute,
|
||||
moveTemplateToTeam: moveTemplateToTeamRoute,
|
||||
|
||||
/**
|
||||
* @public
|
||||
* Private endpoints.
|
||||
*/
|
||||
getTemplateById: authenticatedProcedure
|
||||
.meta({
|
||||
openapi: {
|
||||
method: 'GET',
|
||||
path: '/template/{templateId}',
|
||||
summary: 'Get template',
|
||||
tags: ['Template'],
|
||||
},
|
||||
})
|
||||
.input(ZGetTemplateByIdQuerySchema)
|
||||
.output(ZGetTemplateByIdResponseSchema)
|
||||
.query(async ({ input, ctx }) => {
|
||||
const { templateId, teamId } = input;
|
||||
|
||||
return await getTemplateById({
|
||||
id: templateId,
|
||||
userId: ctx.user.id,
|
||||
teamId,
|
||||
});
|
||||
}),
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
createTemplate: authenticatedProcedure
|
||||
.meta({
|
||||
openapi: {
|
||||
method: 'POST',
|
||||
path: '/template/create',
|
||||
summary: 'Create template',
|
||||
description: 'Create a new template',
|
||||
tags: ['Template'],
|
||||
},
|
||||
})
|
||||
.input(ZCreateTemplateMutationSchema)
|
||||
.output(ZCreateTemplateResponseSchema)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const { teamId, title, templateDocumentDataId } = input;
|
||||
|
||||
return await createTemplate({
|
||||
userId: ctx.user.id,
|
||||
teamId,
|
||||
title,
|
||||
templateDocumentDataId,
|
||||
});
|
||||
}),
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
updateTemplate: authenticatedProcedure
|
||||
.meta({
|
||||
openapi: {
|
||||
method: 'POST',
|
||||
path: '/template/{templateId}',
|
||||
summary: 'Update template',
|
||||
tags: ['Template'],
|
||||
},
|
||||
})
|
||||
.input(ZUpdateTemplateSettingsMutationSchema)
|
||||
.output(ZUpdateTemplateSettingsResponseSchema)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const { templateId, teamId, data, meta } = input;
|
||||
|
||||
const userId = ctx.user.id;
|
||||
|
||||
const requestMetadata = extractNextApiRequestMetadata(ctx.req);
|
||||
|
||||
return await updateTemplateSettings({
|
||||
userId,
|
||||
teamId,
|
||||
templateId,
|
||||
data,
|
||||
meta: {
|
||||
...meta,
|
||||
language: isValidLanguageCode(meta?.language) ? meta?.language : undefined,
|
||||
},
|
||||
requestMetadata,
|
||||
});
|
||||
}),
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
duplicateTemplate: authenticatedProcedure
|
||||
.meta({
|
||||
openapi: {
|
||||
method: 'POST',
|
||||
path: '/template/{templateId}/duplicate',
|
||||
summary: 'Duplicate template',
|
||||
tags: ['Template'],
|
||||
},
|
||||
})
|
||||
.input(ZDuplicateTemplateMutationSchema)
|
||||
.output(ZDuplicateTemplateResponseSchema)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const { teamId, templateId } = input;
|
||||
|
||||
return await duplicateTemplate({
|
||||
userId: ctx.user.id,
|
||||
teamId,
|
||||
templateId,
|
||||
});
|
||||
}),
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
deleteTemplate: authenticatedProcedure
|
||||
.meta({
|
||||
openapi: {
|
||||
method: 'POST',
|
||||
path: '/template/{templateId}/delete',
|
||||
summary: 'Delete template',
|
||||
tags: ['Template'],
|
||||
},
|
||||
})
|
||||
.input(ZDeleteTemplateMutationSchema)
|
||||
.output(z.void())
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const { templateId, teamId } = input;
|
||||
|
||||
const userId = ctx.user.id;
|
||||
|
||||
await deleteTemplate({ userId, id: templateId, teamId });
|
||||
}),
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
createDocumentFromTemplate: authenticatedProcedure
|
||||
.meta({
|
||||
openapi: {
|
||||
method: 'POST',
|
||||
path: '/template/{templateId}/use',
|
||||
summary: 'Use template',
|
||||
description: 'Use the template to create a document',
|
||||
tags: ['Template'],
|
||||
},
|
||||
})
|
||||
.input(ZCreateDocumentFromTemplateMutationSchema)
|
||||
.output(ZGetDocumentWithDetailsByIdResponseSchema)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const { templateId, teamId, recipients, distributeDocument } = input;
|
||||
|
||||
const limits = await getServerLimits({ email: ctx.user.email, teamId });
|
||||
|
||||
if (limits.remaining.documents === 0) {
|
||||
throw new Error('You have reached your document limit.');
|
||||
}
|
||||
|
||||
const requestMetadata = extractNextApiRequestMetadata(ctx.req);
|
||||
|
||||
const document: Document = await createDocumentFromTemplate({
|
||||
templateId,
|
||||
teamId,
|
||||
userId: ctx.user.id,
|
||||
recipients,
|
||||
requestMetadata,
|
||||
});
|
||||
|
||||
if (distributeDocument) {
|
||||
await sendDocument({
|
||||
documentId: document.id,
|
||||
userId: ctx.user.id,
|
||||
teamId,
|
||||
requestMetadata,
|
||||
}).catch((err) => {
|
||||
console.error(err);
|
||||
|
||||
throw new AppError('DOCUMENT_SEND_FAILED');
|
||||
});
|
||||
}
|
||||
|
||||
return getDocumentWithDetailsById({
|
||||
documentId: document.id,
|
||||
userId: ctx.user.id,
|
||||
teamId,
|
||||
});
|
||||
}),
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
createDocumentFromDirectTemplate: maybeAuthenticatedProcedure
|
||||
.meta({
|
||||
openapi: {
|
||||
method: 'POST',
|
||||
path: '/template/use',
|
||||
summary: 'Use direct template',
|
||||
description: 'Use a direct template to create a document',
|
||||
tags: ['Template'],
|
||||
},
|
||||
})
|
||||
.input(ZCreateDocumentFromDirectTemplateMutationSchema)
|
||||
.output(ZCreateDocumentFromDirectTemplateResponseSchema)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const {
|
||||
directRecipientName,
|
||||
directRecipientEmail,
|
||||
directTemplateToken,
|
||||
directTemplateExternalId,
|
||||
signedFieldValues,
|
||||
templateUpdatedAt,
|
||||
} = input;
|
||||
|
||||
const requestMetadata = extractNextApiRequestMetadata(ctx.req);
|
||||
|
||||
return await createDocumentFromDirectTemplate({
|
||||
directRecipientName,
|
||||
directRecipientEmail,
|
||||
directTemplateToken,
|
||||
directTemplateExternalId,
|
||||
signedFieldValues,
|
||||
templateUpdatedAt,
|
||||
user: ctx.user
|
||||
? {
|
||||
id: ctx.user.id,
|
||||
name: ctx.user.name || undefined,
|
||||
email: ctx.user.email,
|
||||
}
|
||||
: undefined,
|
||||
requestMetadata,
|
||||
});
|
||||
}),
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
setSigningOrderForTemplate: authenticatedProcedure
|
||||
.input(ZSetSigningOrderForTemplateMutationSchema)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const { templateId, teamId, signingOrder } = input;
|
||||
|
||||
return await updateTemplateSettings({
|
||||
templateId,
|
||||
teamId,
|
||||
data: {},
|
||||
meta: { signingOrder },
|
||||
userId: ctx.user.id,
|
||||
requestMetadata: extractNextApiRequestMetadata(ctx.req),
|
||||
});
|
||||
}),
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
createTemplateDirectLink: authenticatedProcedure
|
||||
.meta({
|
||||
openapi: {
|
||||
method: 'POST',
|
||||
path: '/template/{templateId}/direct/create',
|
||||
summary: 'Create direct link',
|
||||
description: 'Create a direct link for a template',
|
||||
tags: ['Template'],
|
||||
},
|
||||
})
|
||||
.input(ZCreateTemplateDirectLinkMutationSchema)
|
||||
.output(ZCreateTemplateDirectLinkResponseSchema)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const { templateId, teamId, directRecipientId } = input;
|
||||
|
||||
const userId = ctx.user.id;
|
||||
|
||||
const template = await getTemplateById({ id: templateId, teamId, userId: ctx.user.id });
|
||||
|
||||
const limits = await getServerLimits({ email: ctx.user.email, teamId: template.teamId });
|
||||
|
||||
if (limits.remaining.directTemplates === 0) {
|
||||
throw new AppError(AppErrorCode.LIMIT_EXCEEDED, {
|
||||
message: 'You have reached your direct templates limit.',
|
||||
});
|
||||
}
|
||||
|
||||
return await createTemplateDirectLink({ userId, templateId, directRecipientId });
|
||||
}),
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
deleteTemplateDirectLink: authenticatedProcedure
|
||||
.meta({
|
||||
openapi: {
|
||||
method: 'POST',
|
||||
path: '/template/{templateId}/direct/delete',
|
||||
summary: 'Delete direct link',
|
||||
description: 'Delete a direct link for a template',
|
||||
tags: ['Template'],
|
||||
},
|
||||
})
|
||||
.input(ZDeleteTemplateDirectLinkMutationSchema)
|
||||
.output(z.void())
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const { templateId } = input;
|
||||
|
||||
const userId = ctx.user.id;
|
||||
|
||||
await deleteTemplateDirectLink({ userId, templateId });
|
||||
}),
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
toggleTemplateDirectLink: authenticatedProcedure
|
||||
.meta({
|
||||
openapi: {
|
||||
method: 'POST',
|
||||
path: '/template/{templateId}/direct/toggle',
|
||||
summary: 'Toggle direct link',
|
||||
description: 'Enable or disable a direct link for a template',
|
||||
tags: ['Template'],
|
||||
},
|
||||
})
|
||||
.input(ZToggleTemplateDirectLinkMutationSchema)
|
||||
.output(ZToggleTemplateDirectLinkResponseSchema)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const { templateId, enabled } = input;
|
||||
|
||||
const userId = ctx.user.id;
|
||||
|
||||
return await toggleTemplateDirectLink({ userId, templateId, enabled });
|
||||
}),
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
moveTemplateToTeam: authenticatedProcedure
|
||||
.meta({
|
||||
openapi: {
|
||||
method: 'POST',
|
||||
path: '/template/{templateId}/move',
|
||||
summary: 'Move template',
|
||||
description: 'Move a template to a team',
|
||||
tags: ['Template'],
|
||||
},
|
||||
})
|
||||
.input(ZMoveTemplatesToTeamSchema)
|
||||
.output(ZMoveTemplateToTeamResponseSchema)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const { templateId, teamId } = input;
|
||||
const userId = ctx.user.id;
|
||||
|
||||
return await moveTemplateToTeam({
|
||||
templateId,
|
||||
teamId,
|
||||
userId,
|
||||
});
|
||||
}),
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
updateTemplateTypedSignatureSettings: authenticatedProcedure
|
||||
.input(ZUpdateTemplateTypedSignatureSettingsMutationSchema)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const { templateId, teamId, typedSignatureEnabled } = input;
|
||||
|
||||
const template = await getTemplateById({
|
||||
id: templateId,
|
||||
userId: ctx.user.id,
|
||||
teamId,
|
||||
}).catch(() => null);
|
||||
|
||||
if (!template) {
|
||||
throw new TRPCError({
|
||||
code: 'NOT_FOUND',
|
||||
message: 'Template not found',
|
||||
});
|
||||
}
|
||||
|
||||
return await updateTemplateSettings({
|
||||
templateId,
|
||||
teamId,
|
||||
userId: ctx.user.id,
|
||||
data: {},
|
||||
meta: {
|
||||
typedSignatureEnabled,
|
||||
},
|
||||
requestMetadata: extractNextApiRequestMetadata(ctx.req),
|
||||
});
|
||||
}),
|
||||
setSigningOrderForTemplate: setSigningOrderForTemplateRoute,
|
||||
updateTemplateTypedSignatureSettings: updateTemplateTypedSignatureSettingsRoute,
|
||||
});
|
||||
|
||||
@ -0,0 +1,28 @@
|
||||
import { z } from 'zod';
|
||||
|
||||
import { updateTemplateSettings } from '@documenso/lib/server-only/template/update-template-settings';
|
||||
import { extractNextApiRequestMetadata } from '@documenso/lib/universal/extract-request-metadata';
|
||||
import { DocumentSigningOrder } from '@documenso/prisma/client';
|
||||
|
||||
import { authenticatedProcedure } from '../trpc';
|
||||
|
||||
export const ZSetSigningOrderForTemplateRequestSchema = z.object({
|
||||
templateId: z.number(),
|
||||
teamId: z.number().optional(),
|
||||
signingOrder: z.nativeEnum(DocumentSigningOrder),
|
||||
});
|
||||
|
||||
export const setSigningOrderForTemplateRoute = authenticatedProcedure
|
||||
.input(ZSetSigningOrderForTemplateRequestSchema)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const { templateId, teamId, signingOrder } = input;
|
||||
|
||||
return await updateTemplateSettings({
|
||||
templateId,
|
||||
teamId,
|
||||
data: {},
|
||||
meta: { signingOrder },
|
||||
userId: ctx.user.id,
|
||||
requestMetadata: extractNextApiRequestMetadata(ctx.req),
|
||||
});
|
||||
});
|
||||
@ -0,0 +1,33 @@
|
||||
import { z } from 'zod';
|
||||
|
||||
import { toggleTemplateDirectLink } from '@documenso/lib/server-only/template/toggle-template-direct-link';
|
||||
import { TemplateDirectLinkSchema } from '@documenso/prisma/generated/zod';
|
||||
|
||||
import { authenticatedProcedure } from '../trpc';
|
||||
|
||||
export const ZToggleTemplateDirectLinkRequestSchema = z.object({
|
||||
templateId: z.number().min(1),
|
||||
enabled: z.boolean(),
|
||||
});
|
||||
|
||||
export const ZToggleTemplateDirectLinkResponseSchema = TemplateDirectLinkSchema;
|
||||
|
||||
export const toggleTemplateDirectLinkRoute = authenticatedProcedure
|
||||
.meta({
|
||||
openapi: {
|
||||
method: 'POST',
|
||||
path: '/template/{templateId}/direct/toggle',
|
||||
summary: 'Toggle direct link',
|
||||
description: 'Enable or disable a direct link for a template',
|
||||
tags: ['Template'],
|
||||
},
|
||||
})
|
||||
.input(ZToggleTemplateDirectLinkRequestSchema)
|
||||
.output(ZToggleTemplateDirectLinkResponseSchema)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const { templateId, enabled } = input;
|
||||
|
||||
const userId = ctx.user.id;
|
||||
|
||||
return await toggleTemplateDirectLink({ userId, templateId, enabled });
|
||||
});
|
||||
@ -0,0 +1,91 @@
|
||||
import { z } from 'zod';
|
||||
|
||||
import { SUPPORTED_LANGUAGE_CODES, isValidLanguageCode } from '@documenso/lib/constants/i18n';
|
||||
import { updateTemplateSettings } from '@documenso/lib/server-only/template/update-template-settings';
|
||||
import {
|
||||
ZDocumentAccessAuthTypesSchema,
|
||||
ZDocumentActionAuthTypesSchema,
|
||||
} from '@documenso/lib/types/document-auth';
|
||||
import { ZDocumentEmailSettingsSchema } from '@documenso/lib/types/document-email';
|
||||
import { extractNextApiRequestMetadata } from '@documenso/lib/universal/extract-request-metadata';
|
||||
import { isValidRedirectUrl } from '@documenso/lib/utils/is-valid-redirect-url';
|
||||
import { DocumentDistributionMethod, TemplateType } from '@documenso/prisma/client';
|
||||
import { TemplateSchema } from '@documenso/prisma/generated/zod';
|
||||
|
||||
import { authenticatedProcedure } from '../trpc';
|
||||
import { MAX_TEMPLATE_PUBLIC_DESCRIPTION_LENGTH, MAX_TEMPLATE_PUBLIC_TITLE_LENGTH } from './schema';
|
||||
|
||||
export const ZUpdateTemplateRequestSchema = z.object({
|
||||
templateId: z.number(),
|
||||
teamId: z.number().min(1).optional(),
|
||||
data: z.object({
|
||||
title: z.string().min(1).optional(),
|
||||
externalId: z.string().nullish(),
|
||||
globalAccessAuth: ZDocumentAccessAuthTypesSchema.nullable().optional(),
|
||||
globalActionAuth: ZDocumentActionAuthTypesSchema.nullable().optional(),
|
||||
publicTitle: z.string().trim().min(1).max(MAX_TEMPLATE_PUBLIC_TITLE_LENGTH).optional(),
|
||||
publicDescription: z
|
||||
.string()
|
||||
.trim()
|
||||
.min(1)
|
||||
.max(MAX_TEMPLATE_PUBLIC_DESCRIPTION_LENGTH)
|
||||
.optional(),
|
||||
type: z.nativeEnum(TemplateType).optional(),
|
||||
language: z
|
||||
.union([z.string(), z.enum(SUPPORTED_LANGUAGE_CODES)])
|
||||
.optional()
|
||||
.default('en'),
|
||||
}),
|
||||
meta: z
|
||||
.object({
|
||||
subject: z.string(),
|
||||
message: z.string(),
|
||||
timezone: z.string(),
|
||||
dateFormat: z.string(),
|
||||
distributionMethod: z.nativeEnum(DocumentDistributionMethod),
|
||||
emailSettings: ZDocumentEmailSettingsSchema,
|
||||
redirectUrl: z
|
||||
.string()
|
||||
.optional()
|
||||
.refine((value) => value === undefined || value === '' || isValidRedirectUrl(value), {
|
||||
message:
|
||||
'Please enter a valid URL, make sure you include http:// or https:// part of the url.',
|
||||
}),
|
||||
language: z.enum(SUPPORTED_LANGUAGE_CODES).optional(),
|
||||
typedSignatureEnabled: z.boolean().optional(),
|
||||
})
|
||||
.optional(),
|
||||
});
|
||||
|
||||
export const ZUpdateTemplateResponseSchema = TemplateSchema;
|
||||
|
||||
export const updateTemplateRoute = authenticatedProcedure
|
||||
.meta({
|
||||
openapi: {
|
||||
method: 'POST',
|
||||
path: '/template/{templateId}',
|
||||
summary: 'Update template',
|
||||
tags: ['Template'],
|
||||
},
|
||||
})
|
||||
.input(ZUpdateTemplateRequestSchema)
|
||||
.output(ZUpdateTemplateResponseSchema)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const { templateId, teamId, data, meta } = input;
|
||||
|
||||
const userId = ctx.user.id;
|
||||
|
||||
const requestMetadata = extractNextApiRequestMetadata(ctx.req);
|
||||
|
||||
return await updateTemplateSettings({
|
||||
userId,
|
||||
teamId,
|
||||
templateId,
|
||||
data,
|
||||
meta: {
|
||||
...meta,
|
||||
language: isValidLanguageCode(meta?.language) ? meta?.language : undefined,
|
||||
},
|
||||
requestMetadata,
|
||||
});
|
||||
});
|
||||
@ -0,0 +1,44 @@
|
||||
import { TRPCError } from '@trpc/server';
|
||||
import { z } from 'zod';
|
||||
|
||||
import { getTemplateById } from '@documenso/lib/server-only/template/get-template-by-id';
|
||||
import { updateTemplateSettings } from '@documenso/lib/server-only/template/update-template-settings';
|
||||
import { extractNextApiRequestMetadata } from '@documenso/lib/universal/extract-request-metadata';
|
||||
|
||||
import { authenticatedProcedure } from '../trpc';
|
||||
|
||||
export const ZUpdateTemplateTypedSignatureSettingsRequestSchema = z.object({
|
||||
templateId: z.number(),
|
||||
teamId: z.number().optional(),
|
||||
typedSignatureEnabled: z.boolean(),
|
||||
});
|
||||
|
||||
export const updateTemplateTypedSignatureSettingsRoute = authenticatedProcedure
|
||||
.input(ZUpdateTemplateTypedSignatureSettingsRequestSchema)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const { templateId, teamId, typedSignatureEnabled } = input;
|
||||
|
||||
const template = await getTemplateById({
|
||||
id: templateId,
|
||||
userId: ctx.user.id,
|
||||
teamId,
|
||||
}).catch(() => null);
|
||||
|
||||
if (!template) {
|
||||
throw new TRPCError({
|
||||
code: 'NOT_FOUND',
|
||||
message: 'Template not found',
|
||||
});
|
||||
}
|
||||
|
||||
return await updateTemplateSettings({
|
||||
templateId,
|
||||
teamId,
|
||||
userId: ctx.user.id,
|
||||
data: {},
|
||||
meta: {
|
||||
typedSignatureEnabled,
|
||||
},
|
||||
requestMetadata: extractNextApiRequestMetadata(ctx.req),
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user