import { IOdspAuthRequestInfo } from "./odspAuth" ; import { getSiteUrl } from "./odspDocLibUtils" ; import { throwOdspNetworkError } from "./odspErrorUtils" ; import { getAsync , putAsync } from "./odspRequest" ; interface IOdspUser { displayName : string ; email ? : string ; id ? : string ; } interface IOdspGroup { displayName : string ; email ? : string ; } interface IOdspDriveQuota { deleted : number ; fileCount : number ; remaining : number ; state : string ; total : number ; used : number ; } interface IOdspEntity { user ? : IOdspUser ; group ? : IOdspGroup ; } interface IOdspDriveInfo { id : string ; createdDateTime : string ; description : string ; driveType : string ; lastModifiedDateTime : string ; name : string ; webUrl : string ; createdBy : IOdspEntity ; lastModifiedBy : IOdspEntity ; owner : IOdspEntity ; quota : IOdspDriveQuota ; } export interface IOdspDriveItem { path : string ; name : string ; driveId : string ; itemId : string ; isFolder : boolean ; } export async function getDriveItemByRootFileName ( server , account , path , authRequestInfo , create , driveId ? ) { const accountPath = account !== undefined ? `/${ account }` : "" ; let getDriveItemUrl ; if ( driveId !== undefined && driveId !== "" ) { const encodedDrive = encodeURIComponent ( driveId ) ; getDriveItemUrl = `${ getSiteUrl ( server ) }${ accountPath }/_api/v2.1/drives/${ encodedDrive }/root:${ path }:` ; } else { getDriveItemUrl = `${ getSiteUrl ( server ) }${ accountPath }/_api/v2.1/drive/root:${ path }:` ; } return getDriveItem ( getDriveItemUrl , authRequestInfo , create ) ; } export async function getDriveItemByServerRelativePath ( server , serverRelativePath , authRequestInfo , create ) { let account = "" ; const pathParts = serverRelativePath . split ( "/" ) ; if ( serverRelativePath . startsWith ( "/" ) ) { pathParts . shift ( ) ; } if ( pathParts . length === 0 ) { return Promise . reject ( new Error ( `Invalid serverRelativePath ${ serverRelativePath }` ) ) ; } if ( pathParts . length >= 2 && ( pathParts [ 0 ] === "personal" || pathParts [ 0 ] === "teams" || pathParts [ 0 ] === "sites" ) ) { account = `${ pathParts . shift ( ) }/${ pathParts . shift ( ) }` ; } const library = pathParts . shift ( ) ; if ( ! library ) { return getDriveItemByRootFileName ( server , account , "/" , authRequestInfo , create ) ; } const path = `/${ pathParts . join ( "/" ) }` ; const driveId = await getDriveId ( server , account , library , authRequestInfo ) ; const getDriveItemUrl = `${ getSiteUrl ( server ) }/_api/v2.1/drives/${ driveId }/root:${ path }:` ; return getDriveItem ( getDriveItemUrl , authRequestInfo , create ) ; } export async function getDriveItemFromDriveAndItem ( server , drive , item , authRequestInfo ) { const url = `${ getSiteUrl ( server ) }/_api/v2.1/drives/${ drive }/items/${ item }` ; return getDriveItem ( url , authRequestInfo , false ) ; } export async function getChildrenByDriveItem ( driveItem , server , authRequestInfo ) { if ( ! driveItem . isFolder ) { return [ ] ; } let url = `${ getSiteUrl ( server ) }/_api/v2.1/drives/${ driveItem . driveId }/items/${ driveItem . itemId }/children` ; let children = [ ] ; do { const response = await getAsync ( url , authRequestInfo ) ; if ( response . status !== 200 ) { throwOdspNetworkError ( "unableToGetChildren" , response . status , response ) ; } const getChildrenResult = await response . json ( ) ; children = children . concat ( getChildrenResult . value ) ; url = getChildrenResult [ "@odata.nextLink" ] ; } while ( url ) ; return children . map ( toIODSPDriveItem ) ; } async function getDriveItem ( getDriveItemUrl , authRequestInfo , create ) { let response = await getAsync ( getDriveItemUrl , authRequestInfo ) ; if ( response . status !== 200 ) { if ( ! create ) { throwOdspNetworkError ( "unableToGetDriveItemIdFromPath" , response . status , response ) ; } const contentUri = `${ getDriveItemUrl }/content` ; const createResultResponse = await putAsync ( contentUri , authRequestInfo ) ; if ( createResultResponse . status !== 201 ) { throwOdspNetworkError ( "failedToCreateFile" , createResultResponse . status , createResultResponse ) ; } response = await getAsync ( getDriveItemUrl , authRequestInfo ) ; if ( response . status !== 200 ) { throwOdspNetworkError ( "unableToGetDriveItemIdFromPath" , response . status , response ) ; } } const getDriveItemResult = await response . json ( ) ; return toIODSPDriveItem ( getDriveItemResult ) ; } export async function getDriveId ( server , account , library , authRequestInfo ) { if ( library === undefined ) { const drive = await getDefaultDrive ( server , account , authRequestInfo ) ; return drive . id ; } const drives = await getDrives ( server , account , authRequestInfo ) ; const accountPath = account ? `/${ account }` : "" ; const drivePath = encodeURI ( `${ getSiteUrl ( server ) }${ accountPath }/${ library }` ) ; const index = drives . findIndex ( ( value ) => value . webUrl === drivePath ) ; if ( index === - 1 ) { throw Error ( `Drive ${ drivePath } not found.` ) ; } return drives [ index ] . id ; } async function getDefaultDrive ( server , account , authRequestInfo ) { const response = await getDriveResponse ( "drive" , server , account , authRequestInfo ) ; const getDriveResult = await response . json ( ) ; return getDriveResult as IOdspDriveInfo ; } async function getDrives ( server , account , authRequestInfo ) { const response = await getDriveResponse ( "drives" , server , account , authRequestInfo ) ; const getDriveResult = await response . json ( ) ; return getDriveResult . value as IOdspDriveInfo [ ] ; } async function getDriveResponse ( routeTail , server , account , authRequestInfo ) { const accountPath = account ? `/${ account }` : "" ; const getDriveUrl = `${ getSiteUrl ( server ) }${ accountPath }/_api/v2.1/${ routeTail }` ; const response = await getAsync ( getDriveUrl , authRequestInfo ) ; if ( response . status !== 200 ) { throwOdspNetworkError ( "failedToGetDriveResponse" , response . status , response , undefined , { route : routeTail } ) ; } return response ; } function toIODSPDriveItem ( parsedDriveItemBody ) { const path = parsedDriveItemBody . parentReference . path ? parsedDriveItemBody . parentReference . path . split ( "root:" ) [ 1 ] : "/" ; return { path , name : parsedDriveItemBody . name , driveId : parsedDriveItemBody . parentReference . driveId , itemId : parsedDriveItemBody . id , isFolder : ! ! parsedDriveItemBody . folder } ; }