@@ -12,6 +12,62 @@ function escapeForDriveQuery(value: string): string {
1212 return value . replace ( / \\ / g, '\\\\' ) . replace ( / ' / g, "\\'" )
1313}
1414
15+ interface SharedDrive {
16+ id : string
17+ name : string
18+ kind : string
19+ }
20+
21+ interface DriveFile {
22+ id : string
23+ name : string
24+ mimeType : string
25+ iconLink ?: string
26+ webViewLink ?: string
27+ thumbnailLink ?: string
28+ createdTime ?: string
29+ modifiedTime ?: string
30+ size ?: string
31+ owners ?: any [ ]
32+ parents ?: string [ ]
33+ }
34+
35+ /**
36+ * Fetches shared drives the user has access to
37+ */
38+ async function fetchSharedDrives ( accessToken : string , requestId : string ) : Promise < DriveFile [ ] > {
39+ try {
40+ const response = await fetch (
41+ 'https://www.googleapis.com/drive/v3/drives?pageSize=100&fields=drives(id,name)' ,
42+ {
43+ headers : {
44+ Authorization : `Bearer ${ accessToken } ` ,
45+ } ,
46+ }
47+ )
48+
49+ if ( ! response . ok ) {
50+ logger . warn ( `[${ requestId } ] Failed to fetch shared drives` , {
51+ status : response . status ,
52+ } )
53+ return [ ]
54+ }
55+
56+ const data = await response . json ( )
57+ const drives : SharedDrive [ ] = data . drives || [ ]
58+
59+ return drives . map ( ( drive ) => ( {
60+ id : drive . id ,
61+ name : drive . name ,
62+ mimeType : 'application/vnd.google-apps.folder' ,
63+ iconLink : 'https://ssl.gstatic.com/docs/doclist/images/icon_11_shared_collection_list_1.png' ,
64+ } ) )
65+ } catch ( error ) {
66+ logger . error ( `[${ requestId } ] Error fetching shared drives` , error )
67+ return [ ]
68+ }
69+ }
70+
1571export async function GET ( request : NextRequest ) {
1672 const requestId = generateRequestId ( )
1773 logger . info ( `[${ requestId } ] Google Drive files request received` )
@@ -65,7 +121,7 @@ export async function GET(request: NextRequest) {
65121 const q = encodeURIComponent ( qParts . join ( ' and ' ) )
66122
67123 const response = await fetch (
68- `https://www.googleapis.com/drive/v3/files?q=${ q } &supportsAllDrives=true&includeItemsFromAllDrives=true&spaces=drive &fields=files(id,name,mimeType,iconLink,webViewLink,thumbnailLink,createdTime,modifiedTime,size,owners,parents)` ,
124+ `https://www.googleapis.com/drive/v3/files?q=${ q } &corpora=allDrives& supportsAllDrives=true&includeItemsFromAllDrives=true&fields=files(id,name,mimeType,iconLink,webViewLink,thumbnailLink,createdTime,modifiedTime,size,owners,parents)` ,
69125 {
70126 headers : {
71127 Authorization : `Bearer ${ accessToken } ` ,
@@ -88,14 +144,26 @@ export async function GET(request: NextRequest) {
88144 }
89145
90146 const data = await response . json ( )
91- let files = data . files || [ ]
147+ let files : DriveFile [ ] = data . files || [ ]
92148
93149 if ( mimeType === 'application/vnd.google-apps.spreadsheet' ) {
94150 files = files . filter (
95- ( file : any ) => file . mimeType === 'application/vnd.google-apps.spreadsheet'
151+ ( file : DriveFile ) => file . mimeType === 'application/vnd.google-apps.spreadsheet'
96152 )
97153 } else if ( mimeType === 'application/vnd.google-apps.document' ) {
98- files = files . filter ( ( file : any ) => file . mimeType === 'application/vnd.google-apps.document' )
154+ files = files . filter (
155+ ( file : DriveFile ) => file . mimeType === 'application/vnd.google-apps.document'
156+ )
157+ }
158+
159+ const isRootFolderListing =
160+ ! folderId && mimeType === 'application/vnd.google-apps.folder' && ! query
161+ if ( isRootFolderListing ) {
162+ const sharedDrives = await fetchSharedDrives ( accessToken , requestId )
163+ if ( sharedDrives . length > 0 ) {
164+ logger . info ( `[${ requestId } ] Found ${ sharedDrives . length } shared drives` )
165+ files = [ ...sharedDrives , ...files ]
166+ }
99167 }
100168
101169 return NextResponse . json ( { files } , { status : 200 } )
0 commit comments