import { Singleflight } from '@zcong/singleflight' ; import axios , { AxiosInstance } from 'axios' ; import type { Token } from 'client-oauth2' ; import { log } from './log' ; export type DriveFile = gapi . client . drive . File ; export type GapiUserInfo = { email : string ; family_name : string ; given_name : string ; hd : string ; id : string ; locale : string ; name : string ; picture : string ; verified_email : boolean ; } ; export class GapiClient { authToken : Token ; client : AxiosInstance ; sf : Singleflight ; constructor ( authToken ) { this . authToken = authToken ; this . client = axios . create ( { timeout : 20000 , headers : { Authorization : `Bearer ${ authToken . accessToken }` } , } ) ; this . sf = new Singleflight ( ) ; } async getUserInfoProfile ( ) { try { const r = await this . client . get ( 'https://www.googleapis.com/oauth2/v1/userinfo' ) ; return r . data as GapiUserInfo ; } catch ( e ) { throw new Error ( `Failed to read user profile: ${ e . message }` ) ; } } async addComment ( fileId , content ) { try { await this . client . post ( `https://www.googleapis.com/drive/v3/files/${ fileId }/comments?fields=*` , { content , } ) ; return null ; } catch ( e ) { throw new Error ( `Failed to post user comment: ${ e . message }` ) ; } } async getDriveFile ( fileId , params ) { const fn = async ( ) => { try { const r = await this . client . get ( `https://www.googleapis.com/drive/v3/files/${ fileId }` , { params , } ) ; return r . data as DriveFile ; } catch ( e ) { log . error ( e ) ; throw new Error ( `Failed to get drive file: ${ e . message }` ) ; } } ; return this . sf . do ( fileId , fn ) ; } async getFilePermissions ( fileId , params ) { const fn = async ( ) => { try { const r = await this . client . get ( `https://www.googleapis.com/drive/v3/files/${ fileId }/permissions` , { params , } ) ; return r . data as { permissions : gapi . client . drive . Permission [ ] ; } ; } catch ( e ) { log . error ( e ) ; throw new Error ( `Failed to get drive file permissions: ${ e . message }` ) ; } } ; return this . sf . do ( fileId , fn ) ; } }