import { z } from 'zod' import type { ContractBodyInput, ContractJsonResponse } from '@/lib/api/contracts/types' import { defineRouteContract } from '@/lib/api/contracts/types' import { RawFileInputArraySchema, RawFileInputSchema } from '@/lib/uploads/utils/file-schemas' export const googleAccessTokenSchema = z.string().min(1, 'Access token is required') export const gmailMessageIdSchema = z.string().min(1, 'Message ID is required') export const gmailMessageBodySchema = z.object({ accessToken: googleAccessTokenSchema, messageId: gmailMessageIdSchema, }) export const gmailLabelBodySchema = gmailMessageBodySchema.extend({ labelIds: z.string().min(1, 'At least one label ID is required'), }) export const gmailMoveBodySchema = gmailMessageBodySchema.extend({ addLabelIds: z.string().min(1, 'At least one label to add is required'), removeLabelIds: z.string().optional().nullable(), }) export const gmailMailBodySchema = z.object({ accessToken: googleAccessTokenSchema, to: z.string().min(1, 'Recipient email is required'), subject: z.string().optional().nullable(), body: z.string().min(1, 'Email body is required'), contentType: z.enum(['text', 'html']).optional().nullable(), threadId: z.string().optional().nullable(), replyToMessageId: z.string().optional().nullable(), cc: z.string().optional().nullable(), bcc: z.string().optional().nullable(), attachments: RawFileInputArraySchema.optional().nullable(), }) export const gmailEditDraftBodySchema = gmailMailBodySchema.extend({ draftId: z.string().min(1, 'Draft ID is required'), }) export const googleDriveUploadBodySchema = z.object({ accessToken: googleAccessTokenSchema, fileName: z.string().min(1, 'File name is required'), file: RawFileInputSchema.optional().nullable(), mimeType: z.string().optional().nullable(), folderId: z.string().optional().nullable(), }) export const googleDriveDownloadBodySchema = z.object({ accessToken: googleAccessTokenSchema, fileId: z.string().min(1, 'File ID is required'), mimeType: z.string().optional().nullable(), fileName: z.string().optional().nullable(), includeRevisions: z.boolean().optional().default(true), }) export const googleDriveExportBodySchema = z.object({ accessToken: googleAccessTokenSchema, fileId: z.string().min(1, 'File ID is required'), mimeType: z.string().min(1, 'Target export MIME type is required'), fileName: z.string().optional().nullable(), }) export const googleVaultDownloadExportFileBodySchema = z.object({ accessToken: googleAccessTokenSchema, bucketName: z.string().min(1, 'Bucket name is required'), objectName: z.string().min(1, 'Object name is required'), fileName: z.string().optional().nullable(), }) export const googleSlidesExportFormatSchema = z.preprocess((value) => { if (typeof value !== 'string') return value const normalized = value.trim().toUpperCase() return normalized || undefined }, z.enum(['PDF', 'PPTX', 'ODP', 'TXT', 'PNG', 'JPEG', 'SVG']).optional()) /** Google Drive / Slides file IDs are opaque base62-ish strings without URL metacharacters. */ export const googlePresentationIdSchema = z .string() .trim() .min(1, 'Presentation ID is required') .regex(/^[a-zA-Z0-9_-]+$/, 'Presentation ID contains invalid characters') export const googleSlidesExportPresentationBodySchema = z.object({ accessToken: googleAccessTokenSchema, presentationId: googlePresentationIdSchema, exportFormat: googleSlidesExportFormatSchema, workspaceId: z.string().optional(), workflowId: z.string().optional(), executionId: z.string().optional(), }) const toolJsonResponseSchema = z.unknown() export const gmailAddLabelContract = defineRouteContract({ method: 'POST', path: '/api/tools/gmail/add-label', body: gmailLabelBodySchema, response: { mode: 'json', schema: toolJsonResponseSchema }, }) export const gmailArchiveContract = defineRouteContract({ method: 'POST', path: '/api/tools/gmail/archive', body: gmailMessageBodySchema, response: { mode: 'json', schema: toolJsonResponseSchema }, }) export const gmailDeleteContract = defineRouteContract({ method: 'POST', path: '/api/tools/gmail/delete', body: gmailMessageBodySchema, response: { mode: 'json', schema: toolJsonResponseSchema }, }) export const gmailDraftContract = defineRouteContract({ method: 'POST', path: '/api/tools/gmail/draft', body: gmailMailBodySchema, response: { mode: 'json', schema: toolJsonResponseSchema }, }) export const gmailEditDraftContract = defineRouteContract({ method: 'POST', path: '/api/tools/gmail/edit-draft', body: gmailEditDraftBodySchema, response: { mode: 'json', schema: toolJsonResponseSchema }, }) export const gmailMarkReadContract = defineRouteContract({ method: 'POST', path: '/api/tools/gmail/mark-read', body: gmailMessageBodySchema, response: { mode: 'json', schema: toolJsonResponseSchema }, }) export const gmailMarkUnreadContract = defineRouteContract({ method: 'POST', path: '/api/tools/gmail/mark-unread', body: gmailMessageBodySchema, response: { mode: 'json', schema: toolJsonResponseSchema }, }) export const gmailMoveContract = defineRouteContract({ method: 'POST', path: '/api/tools/gmail/move', body: gmailMoveBodySchema, response: { mode: 'json', schema: toolJsonResponseSchema }, }) export const gmailRemoveLabelContract = defineRouteContract({ method: 'POST', path: '/api/tools/gmail/remove-label', body: gmailLabelBodySchema, response: { mode: 'json', schema: toolJsonResponseSchema }, }) export const gmailSendContract = defineRouteContract({ method: 'POST', path: '/api/tools/gmail/send', body: gmailMailBodySchema, response: { mode: 'json', schema: toolJsonResponseSchema }, }) export const gmailUnarchiveContract = defineRouteContract({ method: 'POST', path: '/api/tools/gmail/unarchive', body: gmailMessageBodySchema, response: { mode: 'json', schema: toolJsonResponseSchema }, }) export const googleDriveUploadContract = defineRouteContract({ method: 'POST', path: '/api/tools/google_drive/upload', body: googleDriveUploadBodySchema, response: { mode: 'json', schema: toolJsonResponseSchema }, }) export const googleDriveDownloadContract = defineRouteContract({ method: 'POST', path: '/api/tools/google_drive/download', body: googleDriveDownloadBodySchema, response: { mode: 'json', schema: toolJsonResponseSchema }, }) export const googleDriveExportContract = defineRouteContract({ method: 'POST', path: '/api/tools/google_drive/export', body: googleDriveExportBodySchema, response: { mode: 'json', schema: toolJsonResponseSchema }, }) export const googleVaultDownloadExportFileContract = defineRouteContract({ method: 'POST', path: '/api/tools/google_vault/download-export-file', body: googleVaultDownloadExportFileBodySchema, response: { mode: 'json', schema: toolJsonResponseSchema }, }) export const googleSlidesExportPresentationContract = defineRouteContract({ method: 'POST', path: '/api/tools/google_slides/export-presentation', body: googleSlidesExportPresentationBodySchema, response: { mode: 'json', schema: toolJsonResponseSchema }, }) export type GmailAddLabelBody = ContractBodyInput export type GmailArchiveBody = ContractBodyInput export type GmailDeleteBody = ContractBodyInput export type GmailDraftBody = ContractBodyInput export type GmailEditDraftBody = ContractBodyInput export type GmailMarkReadBody = ContractBodyInput export type GmailMarkUnreadBody = ContractBodyInput export type GmailMoveBody = ContractBodyInput export type GmailRemoveLabelBody = ContractBodyInput export type GmailSendBody = ContractBodyInput export type GmailUnarchiveBody = ContractBodyInput export type GoogleDriveUploadBody = ContractBodyInput export type GoogleDriveDownloadBody = ContractBodyInput export type GoogleDriveExportBody = ContractBodyInput export type GoogleVaultDownloadExportFileBody = ContractBodyInput< typeof googleVaultDownloadExportFileContract > export type GoogleSlidesExportPresentationBody = ContractBodyInput< typeof googleSlidesExportPresentationContract > export type GmailAddLabelResponse = ContractJsonResponse export type GmailArchiveResponse = ContractJsonResponse export type GmailDeleteResponse = ContractJsonResponse export type GmailDraftResponse = ContractJsonResponse export type GmailEditDraftResponse = ContractJsonResponse export type GmailMarkReadResponse = ContractJsonResponse export type GmailMarkUnreadResponse = ContractJsonResponse export type GmailMoveResponse = ContractJsonResponse export type GmailRemoveLabelResponse = ContractJsonResponse export type GmailSendResponse = ContractJsonResponse export type GmailUnarchiveResponse = ContractJsonResponse export type GoogleDriveUploadResponse = ContractJsonResponse export type GoogleDriveDownloadResponse = ContractJsonResponse export type GoogleDriveExportResponse = ContractJsonResponse export type GoogleVaultDownloadExportFileResponse = ContractJsonResponse< typeof googleVaultDownloadExportFileContract > export type GoogleSlidesExportPresentationResponse = ContractJsonResponse< typeof googleSlidesExportPresentationContract >