Skip to content

Commit ce8773e

Browse files
feat: refactor Google Drive document loader for improved file info handling and stream processing
Updated the Google Drive document loader to streamline file information retrieval by consolidating the handling of file info into a single variable. Introduced a new helper function to convert Node.js streams to buffers, enhancing the efficiency of file data processing. Improved error messages for better clarity and added documentation for the new stream conversion method.
1 parent bd12f4b commit ce8773e

File tree

2 files changed

+42
-54
lines changed

2 files changed

+42
-54
lines changed

packages/components/nodes/documentloaders/GoogleDrive/GoogleDrive.ts

Lines changed: 41 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ import * as path from 'path'
1717
import * as os from 'os'
1818
import { LoadOfSheet } from '../MicrosoftExcel/ExcelLoader'
1919
import { PowerpointLoader } from '../MicrosoftPowerpoint/PowerpointLoader'
20-
// @ts-ignore
2120
import { google, drive_v3 } from 'googleapis'
2221

2322
// Helper function to get human-readable MIME type labels
@@ -241,7 +240,7 @@ class GoogleDrive_DocumentLoaders implements INode {
241240

242241
if (googleApplicationCredentialFilePath && googleApplicationCredential) {
243242
throw new Error(
244-
'Error: More than one component has been inputted. Please use only one of the following: Google Application Credential File Path or Google Credential JSON Object'
243+
'More than one component has been provided. Please use only one of the following: Google Application Credential File Path or Google Credential JSON Object'
245244
)
246245
}
247246

@@ -552,6 +551,8 @@ class GoogleDrive_DocumentLoaders implements INode {
552551
authMethod: 'oauth2' | 'serviceAccount',
553552
driveClient?: drive_v3.Drive
554553
): Promise<any> {
554+
let fileInfo: any
555+
555556
if (authMethod === 'oauth2' && accessToken) {
556557
const url = new URL(`https://www.googleapis.com/drive/v3/files/${encodeURIComponent(fileId)}`)
557558
url.searchParams.append('fields', 'id, name, mimeType, size, createdTime, modifiedTime, parents, webViewLink, driveId')
@@ -572,15 +573,7 @@ class GoogleDrive_DocumentLoaders implements INode {
572573
throw new Error(`Failed to get file info: ${response.statusText}`)
573574
}
574575

575-
const fileInfo = await response.json()
576-
577-
// Add drive context to description
578-
const driveContext = fileInfo.driveId ? ' (Shared Drive)' : ' (My Drive)'
579-
580-
return {
581-
...fileInfo,
582-
driveContext
583-
}
576+
fileInfo = await response.json()
584577
} else if (authMethod === 'serviceAccount' && driveClient) {
585578
const response = await driveClient.files.get({
586579
fileId: fileId,
@@ -592,18 +585,18 @@ class GoogleDrive_DocumentLoaders implements INode {
592585
throw new Error('Failed to get file info: No data returned')
593586
}
594587

595-
const fileInfo = response.data
596-
597-
// Add drive context to description
598-
const driveContext = fileInfo.driveId ? ' (Shared Drive)' : ' (My Drive)'
599-
600-
return {
601-
...fileInfo,
602-
driveContext
603-
}
588+
fileInfo = response.data
604589
} else {
605590
throw new Error('Invalid authentication method or missing credentials')
606591
}
592+
593+
// Add drive context to description
594+
const driveContext = fileInfo.driveId ? ' (Shared Drive)' : ' (My Drive)'
595+
596+
return {
597+
...fileInfo,
598+
driveContext
599+
}
607600
}
608601

609602
private async getFilesFromFolder(
@@ -896,6 +889,20 @@ class GoogleDrive_DocumentLoaders implements INode {
896889
}
897890
}
898891

892+
/**
893+
* Converts a Node.js stream to a Buffer
894+
* @param stream The stream to convert
895+
* @returns A Promise that resolves to a Buffer
896+
*/
897+
private streamToBuffer(stream: NodeJS.ReadableStream): Promise<Buffer> {
898+
return new Promise<Buffer>((resolve, reject) => {
899+
const chunks: Buffer[] = []
900+
stream.on('data', (chunk: Buffer) => chunks.push(chunk))
901+
stream.on('end', () => resolve(Buffer.concat(chunks as Uint8Array[])))
902+
stream.on('error', reject)
903+
})
904+
}
905+
899906
private async createTempFile(buffer: Buffer, fileName: string, mimeType: string): Promise<string> {
900907
// Get appropriate file extension
901908
let extension = path.extname(fileName)
@@ -918,7 +925,7 @@ class GoogleDrive_DocumentLoaders implements INode {
918925
const tempFileName = `gdrive_${Date.now()}_${Math.random().toString(36).substring(7)}${extension}`
919926
const tempFilePath = path.join(tempDir, tempFileName)
920927

921-
fs.writeFileSync(tempFilePath, buffer as Uint8Array)
928+
fs.writeFileSync(tempFilePath, buffer)
922929
return tempFilePath
923930
}
924931

@@ -955,12 +962,7 @@ class GoogleDrive_DocumentLoaders implements INode {
955962
}
956963
)
957964

958-
return new Promise<Buffer>((resolve, reject) => {
959-
const chunks: Buffer[] = []
960-
response.data.on('data', (chunk: Buffer) => chunks.push(chunk))
961-
response.data.on('end', () => resolve(Buffer.concat(chunks as Uint8Array[])))
962-
response.data.on('error', reject)
963-
})
965+
return this.streamToBuffer(response.data)
964966
} else {
965967
throw new Error('Invalid authentication method or missing credentials')
966968
}
@@ -1004,20 +1006,12 @@ class GoogleDrive_DocumentLoaders implements INode {
10041006
}
10051007
)
10061008

1007-
return new Promise<string>((resolve, reject) => {
1008-
const chunks: Buffer[] = []
1009-
response.data.on('data', (chunk: Buffer) => chunks.push(chunk))
1010-
response.data.on('end', () => {
1011-
const buffer = Buffer.concat(chunks as Uint8Array[])
1012-
const contentType = response.headers['content-type'] || ''
1013-
if (!contentType.startsWith('text/') && !contentType.includes('json') && !contentType.includes('xml')) {
1014-
reject(new Error(`Cannot process binary file with content-type: ${contentType}`))
1015-
return
1016-
}
1017-
resolve(buffer.toString('utf-8'))
1018-
})
1019-
response.data.on('error', reject)
1020-
})
1009+
const buffer = await this.streamToBuffer(response.data)
1010+
const contentType = response.headers['content-type'] || ''
1011+
if (!contentType.startsWith('text/') && !contentType.includes('json') && !contentType.includes('xml')) {
1012+
throw new Error(`Cannot process binary file with content-type: ${contentType}`)
1013+
}
1014+
return buffer.toString('utf-8')
10211015
} else {
10221016
throw new Error('Invalid authentication method or missing credentials')
10231017
}
@@ -1118,18 +1112,12 @@ class GoogleDrive_DocumentLoaders implements INode {
11181112
}
11191113
)
11201114

1121-
return new Promise<{ buffer: Buffer; mimeType: string; fileName: string }>((resolve, reject) => {
1122-
const chunks: Buffer[] = []
1123-
response.data.on('data', (chunk: Buffer) => chunks.push(chunk))
1124-
response.data.on('end', () => {
1125-
resolve({
1126-
buffer: Buffer.concat(chunks as Uint8Array[]),
1127-
mimeType: exportMimeType,
1128-
fileName: `exported_file${fileExtension}`
1129-
})
1130-
})
1131-
response.data.on('error', reject)
1132-
})
1115+
const buffer = await this.streamToBuffer(response.data)
1116+
return {
1117+
buffer,
1118+
mimeType: exportMimeType,
1119+
fileName: `exported_file${fileExtension}`
1120+
}
11331121
} else {
11341122
throw new Error('Invalid authentication method or missing credentials')
11351123
}

packages/ui/src/api/documentstore.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
cd import client from './client'
1+
import client from './client'
22

33
const getAllDocumentStores = (params) => client.get('/document-store/store', { params })
44
const getDocumentLoaders = () => client.get('/document-store/components/loaders')

0 commit comments

Comments
 (0)