fix(google-drive): add auto export format and validate against Drive API docs (#4161)

* fix(google-drive): add auto export format and Azure storage debug logging

* chore: remove Azure storage debug logging

* fix(google-drive): use status-based fallback instead of string matching for export errors

* fix(google-drive): validate export formats against Drive API docs, remove fallback

* fix(google-drive): use value function for dropdown default

* fix(google-drive): add text/markdown to valid export formats for Google Docs

* fix(google-drive): correct ODS MIME type for Sheets export format
This commit is contained in:
Waleed
2026-04-14 15:09:36 -07:00
committed by GitHub
parent 7529a75ac0
commit 48e174b21f
3 changed files with 70 additions and 5 deletions
@@ -13,6 +13,7 @@ import {
ALL_REVISION_FIELDS,
DEFAULT_EXPORT_FORMATS,
GOOGLE_WORKSPACE_MIME_TYPES,
VALID_EXPORT_FORMATS,
} from '@/tools/google_drive/utils'
export const dynamic = 'force-dynamic'
@@ -65,10 +66,12 @@ export async function POST(request: NextRequest) {
const {
accessToken,
fileId,
mimeType: exportMimeType,
mimeType: rawExportMimeType,
fileName,
includeRevisions,
} = validatedData
const exportMimeType =
rawExportMimeType && rawExportMimeType !== 'auto' ? rawExportMimeType : null
const authHeader = `Bearer ${accessToken}`
logger.info(`[${requestId}] Getting file metadata from Google Drive`, { fileId })
@@ -112,6 +115,24 @@ export async function POST(request: NextRequest) {
if (GOOGLE_WORKSPACE_MIME_TYPES.includes(fileMimeType)) {
const exportFormat = exportMimeType || DEFAULT_EXPORT_FORMATS[fileMimeType] || 'text/plain'
const validFormats = VALID_EXPORT_FORMATS[fileMimeType]
if (validFormats && !validFormats.includes(exportFormat)) {
logger.warn(`[${requestId}] Unsupported export format requested`, {
fileId,
fileMimeType,
requestedFormat: exportFormat,
validFormats,
})
return NextResponse.json(
{
success: false,
error: `Export format "${exportFormat}" is not supported for this file type. Supported formats: ${validFormats.join(', ')}`,
},
{ status: 400 }
)
}
finalMimeType = exportFormat
logger.info(`[${requestId}] Exporting Google Workspace file`, {
+4 -2
View File
@@ -316,6 +316,7 @@ Return ONLY the query string - no explanations, no quotes around the whole thing
title: 'Export Format',
type: 'dropdown',
options: [
{ label: 'Auto (best format for file type)', id: 'auto' },
{ label: 'Plain Text (text/plain)', id: 'text/plain' },
{ label: 'HTML (text/html)', id: 'text/html' },
{ label: 'PDF (application/pdf)', id: 'application/pdf' },
@@ -333,7 +334,8 @@ Return ONLY the query string - no explanations, no quotes around the whole thing
},
{ label: 'CSV (text/csv)', id: 'text/csv' },
],
placeholder: 'Optional: Choose export format for Google Docs/Sheets/Slides',
value: () => 'auto',
placeholder: 'Export format for Google Docs/Sheets/Slides',
condition: { field: 'operation', value: 'download' },
},
{
@@ -867,7 +869,7 @@ Return ONLY the message text - no subject line, no greetings/signatures, no extr
destinationFolderId: effectiveDestinationFolderId,
file: normalizedFile,
pageSize: rest.pageSize ? Number.parseInt(rest.pageSize as string, 10) : undefined,
mimeType: mimeType,
mimeType: mimeType === 'auto' ? undefined : mimeType,
type: shareType, // Map shareType to type for share tool
starred: starredValue,
sendNotification: sendNotificationValue,
+44 -2
View File
@@ -111,8 +111,50 @@ export const DEFAULT_EXPORT_FORMATS: Record<string, string> = {
'application/vnd.google-apps.spreadsheet': 'text/csv',
'application/vnd.google-apps.presentation': 'text/plain',
'application/vnd.google-apps.drawing': 'image/png',
'application/vnd.google-apps.form': 'application/pdf',
'application/vnd.google-apps.script': 'application/json',
'application/vnd.google-apps.form': 'application/zip',
'application/vnd.google-apps.script': 'application/vnd.google-apps.script+json',
}
/**
* Valid export formats per Google Workspace file type.
* See: https://developers.google.com/drive/api/guides/ref-export-formats
*/
export const VALID_EXPORT_FORMATS: Record<string, string[]> = {
'application/vnd.google-apps.document': [
'text/plain',
'text/html',
'application/pdf',
'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
'application/vnd.oasis.opendocument.text',
'application/rtf',
'application/epub+zip',
'text/markdown',
],
'application/vnd.google-apps.spreadsheet': [
'text/csv',
'text/tab-separated-values',
'application/pdf',
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
'application/vnd.oasis.opendocument.spreadsheet',
'application/zip',
],
'application/vnd.google-apps.presentation': [
'text/plain',
'application/pdf',
'application/vnd.openxmlformats-officedocument.presentationml.presentation',
'application/vnd.oasis.opendocument.presentation',
'image/jpeg',
'image/png',
'image/svg+xml',
],
'application/vnd.google-apps.drawing': [
'application/pdf',
'image/jpeg',
'image/png',
'image/svg+xml',
],
'application/vnd.google-apps.form': ['application/zip'],
'application/vnd.google-apps.script': ['application/vnd.google-apps.script+json'],
}
export const SOURCE_MIME_TYPES: Record<string, string> = {