import { user , validate } from './auth' ; const DRIVE_API = 'https://www.googleapis.com/drive/v3/' ; const DRIVE_UPLOAD_API = 'https://www.googleapis.com/upload/drive/v3/' ; const COMMON_FILE_FIELDS = 'kind,id,name,mimeType,appProperties,trashed,version,size' ; function makeURL ( base , defaults , options ? ) { const url = new URL ( base ) ; for ( const key in defaults ) { url . searchParams . append ( key , defaults [ key ] ) ; } if ( options ) { for ( const key in options ) { url . searchParams . append ( key , options [ key ] ) ; } } return url . toString ( ) ; } async function doFetch ( url , init ) { if ( ! user . token ) { throw new Error ( 'Not logged in' ) ; } const response = await fetch ( url , init ) ; if ( ! response . ok ) { if ( response . status === 401 || response . status === 403 ) { validate ( user . token ) ; } if ( response . status === 418 ) { throw new Error ( `Alas, the Drive API has become a teapot. Your photos are probably getting wet.` ) ; } throw new Error ( `Couldn't fetch Drive API result: ${ response . statusText }` ) ; } return response ; } export async function driveRequest ( endpoint , options ? , init = { } ) { const url = makeURL ( `${ DRIVE_API }${ endpoint }` , { access_token : user . token , } , options ) ; const response = await doFetch ( url , init ) ; return response . json ( ) ; } async function driveMediaRequest ( endpoint , options ? , init = { } ) { const url = makeURL ( `${ DRIVE_API }${ endpoint }` , { access_token : user . token , alt : 'media' , } , options ) ; const response = await doFetch ( url , init ) ; return response . blob ( ) ; } async function driveUploadRequest ( endpoint , body ) { const url = makeURL ( `${ DRIVE_UPLOAD_API }${ endpoint }` , { access_token : user . token , uploadType : 'media' , } ) ; const response = await doFetch ( url , { method : 'PATCH' , body } ) ; return response . json ( ) ; } export async function getFileMeta ( fileId ) { return driveRequest ( `files/${ fileId }` , { fields : COMMON_FILE_FIELDS } ) ; } export async function getFileContent ( fileId ) { return driveMediaRequest ( `files/${ fileId }` ) ; } export async function createFileMeta ( file ) { return driveRequest ( `files` , { fields : COMMON_FILE_FIELDS } , { body : JSON . stringify ( file ) , headers : { 'Content-Type' : 'application/json' } , method : 'POST' , } ) ; } export async function updateFileMeta ( file ) { const body = { appProperties : file . appProperties , mimeType : file . mimeType , name : file . name , } ; return driveRequest ( `files/${ file . id }` , { fields : COMMON_FILE_FIELDS } , { body : JSON . stringify ( body ) , headers : { 'Content-Type' : 'application/json' } , method : 'PATCH' , } ) ; } export async function updateFileContent ( fileId , body ) { return driveUploadRequest ( `files/${ fileId }` , body ) ; } export async function folderList ( folderId ) { let result = [ ] ; const request = { corpus : 'user' , fields : `files(${ COMMON_FILE_FIELDS })` , q : `'${ folderId }' in parents` , spaces : 'drive' , } ; let nextPageToken = '' ; do { if ( nextPageToken ) { request . nextPageToken = nextPageToken ; } const list = await driveRequest ( 'files' , request ) ; result = result . concat ( list . files ) ; nextPageToken = list . nextPageToken ; } while ( nextPageToken ) ; return result ; }