{"version":3,"file":"index.cjs","sources":["../src/api.ts","../src/request.ts","../src/index.ts","../src/utils.ts","../src/constants.ts","../src/helpers.ts"],"sourcesContent":["import request from './request';\r\n\r\nexport function uploadSmallFile(file: File, fullPath: string, token: string) {\r\n\treturn request.put<unknown, { id: string }>(\r\n\t\t`https://graph.microsoft.com/v1.0/me/drive/root:/${fullPath}:/content`,\r\n\t\tfile,\r\n\t\t{\r\n\t\t\theaders: {\r\n\t\t\t\tAuthorization: `Bearer ${token}`,\r\n\t\t\t},\r\n\t\t},\r\n\t);\r\n}\r\n\r\nexport function createUploadSession(fullPath: string, token: string) {\r\n\treturn request.post<\r\n\t\tunknown,\r\n\t\t{\r\n\t\t\texpirationDateTime: string;\r\n\t\t\tuploadUrl: string;\r\n\t\t}>(\r\n\t\t\t`https://graph.microsoft.com/v1.0/drive/root:/${fullPath}:/createUploadSession`,\r\n\t\t\tnull,\r\n\t\t\t{\r\n\t\t\t\theaders: {\r\n\t\t\t\t\tAuthorization: `Bearer ${token}`,\r\n\t\t\t\t\t'Content-Type': 'application/json',\r\n\t\t\t\t},\r\n\t\t\t},\r\n\t\t);\r\n}\r\n\r\nexport function uploadLargeFileChunk(\r\n\tfile: File | Blob,\r\n\tuploadUrl: string,\r\n\trange: { start: number; end: number, total: number },\r\n) {\r\n\tconst { start, end, total } = range;\r\n\treturn request.put<\r\n\t\tunknown,\r\n\t\t{\r\n\t\t\texpirationDateTime: string;\r\n\t\t} | {\r\n\t\t\tid: string\r\n\t\t}\r\n\t>(\r\n\t\tuploadUrl,\r\n\t\tfile,\r\n\t\t{\r\n\t\t\theaders: {\r\n\t\t\t\t'Content-Range': `bytes ${start}-${end}/${total}`,\r\n\t\t\t},\r\n\t\t},\r\n\t);\r\n}\r\n\r\nexport function share(fileId: string, token: string) {\r\n\treturn request.post<unknown, { shareId: string }>(\r\n\t\t`https://graph.microsoft.com/v1.0/me/drive/items/${fileId}/createLink`,\r\n\t\t{\r\n\t\t\ttype: 'view',\r\n\t\t\tscope: 'anonymous',\r\n\t\t},\r\n\t\t{\r\n\t\t\theaders: {\r\n\t\t\t\tAuthorization: `Bearer ${token}`,\r\n\t\t\t\t'Content-Type': 'application/json',\r\n\t\t\t},\r\n\t\t},\r\n\t);\r\n}\r\n","import axios from 'axios';\n\naxios.interceptors.response.use(\n\tresponse => response.data,\n\terror => {\n\t\tlet errorMessage = '';\n\t\tif (error.response) {\n\t\t\tconst {status, statusText} = error.response;\n\t\t\terrorMessage = statusText;\n\t\t\tif (status === 401) {\n\t\t\t\terrorMessage += '. You maybe need to login again.';\n\t\t\t}\n\t\t} else {\n\t\t\terrorMessage = 'Unknown Error';\n\t\t}\n\n\t\tthrow new Error(errorMessage);\n\t},\n);\n\nexport default axios;\n","import {uploadLargeFileChunk, uploadSmallFile, createUploadSession, share} from './api';\nimport {splitFileIntoChunks, parallel} from './utils';\nimport {SMALL_SIZE, LARGE_SIZE, CHUNK_SIZE} from './constants';\n\nexport * from './helpers'\nexport * from './api'\n\ntype Options = {\n\taccessToken: string\n}\nexport default class OneDriveApi {\n\tprivate accessToken: string;\n\n\tconstructor({accessToken}: Options) {\n\t\tthis.accessToken = accessToken;\n\t}\n\n\t/**\n\t * Upload file smaller than 4MB\n\t * @param file\n\t * @param path\n\t * @returns\n\t */\n\tprivate uploadSmallFile(file: File, path: string) {\n\t\treturn uploadSmallFile(file, path, this.accessToken);\n\t}\n\n\t/**\n\t * Generate upload url for files\n\t * larger than 4MB and smaller than 60MB\n\t * @param filePath\n\t * @returns\n\t */\n\tprivate createUploadSession(filePath: string) {\n\t\treturn createUploadSession(filePath, this.accessToken);\n\t}\n\n\t/**\n\t * Upload file chunks\n\t * @param file\n\t * @param url\n\t * @param range\n\t * @returns\n\t */\n\tprivate uploadLargeFileChunk(\n\t\tfile: File | Blob,\n\t\turl: string,\n\t\trange: { start: number; end: number, total: number },\n\t) {\n\t\treturn uploadLargeFileChunk(file, url, range);\n\t}\n\n\t/**\n\t * Upload files larger than 4MB and smaller than 60MB\n\t * @param file \n\t * @param filePath \n\t * @returns \n\t */\n\tprivate async uploadLargeFile(file: File | Blob, filePath: string): Promise<{ id: string }> {\n\t\tconst {uploadUrl} = await this.createUploadSession(filePath);\n\t\tconst chunks = splitFileIntoChunks(file, CHUNK_SIZE);\n\t\tlet uploadedChunkSize = 0;\n\t\tconst tasks = chunks.map(chunk => {\n\t\t\tconst range = {\n\t\t\t\tstart: uploadedChunkSize,\n\t\t\t\tend: uploadedChunkSize + chunk.size - 1,\n\t\t\t\ttotal: file.size,\n\t\t\t};\n\t\t\tuploadedChunkSize = range.end + 1;\n\t\t\treturn () => this.uploadLargeFileChunk(chunk, uploadUrl, range);\n\t\t});\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tparallel(tasks)\n\t\t\t\t.then(res => {\n\t\t\t\t\tif (res.length === tasks.length) {\n\t\t\t\t\t\tconst lastTask = res[res.length - 1];\n\t\t\t\t\t\tif (lastTask && 'id' in lastTask) {\n\t\t\t\t\t\t\tresolve(lastTask);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// TODO: Are there any useful error messages in the response?\n\t\t\t\t\t\t\tthrow new Error('Upload failed');\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthrow new Error('Some chunks were failed to upload');\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t\t.catch(reject);\n\t\t});\n\t}\n\n\t/**\n\t * Upload file. Note that the file size should be smaller than 60MB\n\t * @param file\n\t * @param filePath\n\t * @returns\n\t */\n\tpublic async upload(file: File, filePath: string) {\n\t\tif (file.size < SMALL_SIZE) {\n\t\t\treturn this.uploadSmallFile(file, filePath);\n\t\t}\n\n\t\tif (file.size < LARGE_SIZE) {\n\t\t\treturn this.uploadLargeFile(file, filePath);\n\t\t}\n\n\t\tthrow new Error('File is too large.');\n\t}\n\n\tpublic share(fileId: string) {\n\t\treturn share(fileId, this.accessToken);\n\t}\n}\n","export function splitFileIntoChunks(file: File | Blob, chunkSize: number) {\n\tconst chunks = [];\n\tlet offset = 0;\n\tlet chunk = file.slice(offset, offset + chunkSize);\n\tchunks.push(chunk);\n\twhile (chunk.size) {\n\t\toffset += chunkSize;\n\t\tchunk = file.slice(offset, offset + chunkSize);\n\t\tif (chunk.size) {\n\t\t\tchunks.push(chunk);\n\t\t}\n\t}\n\n\treturn chunks;\n}\n\n/**\n * Run promises one after another\n * @param promises\n * @returns\n */\nexport const parallel = <T = any>(promises: (() => Promise<T>)[]) => promises.reduce(\n\t(promiseChain, currentTask) => promiseChain.then(chainResults => currentTask().then(currentResult => [...chainResults, currentResult])),\n\tPromise.resolve([] as T[]),\n);\n","export const scope = 'openid https://graph.microsoft.com/Files.ReadWrite.All';\n// Files smaller than this will be uploaded directly\nexport const SMALL_SIZE = 1024 * 1024 * 4;\n// Files smaller than this must be split into chunks first\n// And those chunks must be uploaded sequentially in order\nexport const LARGE_SIZE = 1024 * 1024 * 60;\n// Chunk size must be a multiple of 320 KiB\n// see: https://docs.microsoft.com/en-us/onedrive/developer/rest-api/api/driveitem_createuploadsession?view=odsp-graph-online#upload-bytes-to-the-upload-session\nexport const CHUNK_SIZE = 1024 * 320 * 3;\n","import { scope } from './constants';\n\n/**\n * Generate authentication url\n * @param clientId \n * @param redirectUri \n * @param type \n * @returns \n */\nexport function generateAuthUrl(\n\tclientId: string, redirectUri: string\n) {\n\treturn `https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=${clientId}&response_type=token&redirect_uri=${redirectUri}&scope=${scope}`;\n}\n\n\n/**\n * Get the url of a shared file by its shareId\n * @param shareId\n * @returns\n */\nexport function getShareUrl(shareId: string) {\n\treturn `https://api.onedrive.com/v1.0/shares/${shareId}/root/content`;\n}"],"names":["uploadSmallFile","file","fullPath","token","request","put","headers","Authorization","createUploadSession","post","uploadLargeFileChunk","uploadUrl","range","start","end","total","share","fileId","type","scope","axios","interceptors","response","use","data","error","errorMessage","statusText","status","Error","OneDriveApi","accessToken","this","path","filePath","url","uploadLargeFile","_this2","chunks","chunkSize","offset","chunk","slice","push","size","splitFileIntoChunks","uploadedChunkSize","tasks","map","Promise","resolve","reject","promises","reduce","promiseChain","currentTask","then","chainResults","currentResult","res","length","lastTask","upload","clientId","redirectUri","shareId"],"mappings":"wHAEgBA,EAAgBC,EAAYC,EAAkBC,GAC7D,OAAOC,UAAQC,uDACqCH,cACnDD,EACA,CACCK,QAAS,CACRC,wBAAyBJ,cAMbK,EAAoBN,EAAkBC,GACrD,OAAOC,UAAQK,qDAMmCP,0BAChD,KACA,CACCI,QAAS,CACRC,wBAAyBJ,EACzB,eAAgB,+BAMLO,EACfT,EACAU,EACAC,GAGA,OAAOR,UAAQC,IAQdM,EACAV,EACA,CACCK,QAAS,CACR,yBAb2BM,EAAtBC,UAAsBD,EAAfE,QAAeF,EAAVG,kBAmBLC,EAAMC,EAAgBd,GACrC,OAAOC,UAAQK,wDACqCQ,gBACnD,CACCC,KAAM,OACNC,MAAO,aAER,CACCb,QAAS,CACRC,wBAAyBJ,EACzB,eAAgB,sBChEpBiB,UAAMC,aAAaC,SAASC,IAC3B,SAAAD,UAAYA,EAASE,MACrB,SAAAC,GACC,IAAIC,EAAe,GACnB,GAAID,EAAMH,SAAU,CACnB,MAA6BG,EAAMH,SACnCI,IADeC,WAEA,QAFRC,SAGNF,GAAgB,yCAGjBA,EAAe,gBAGhB,UAAUG,MAAMH,KCNGI,IAAAA,0BAGpB,kBAAaC,IAAAA,iBAFLA,mBAGPC,KAAKD,YAAcA,6BASZ/B,gBAAA,SAAgBC,EAAYgC,GACnC,OAAOjC,EAAgBC,EAAMgC,EAAMD,KAAKD,gBASjCvB,oBAAA,SAAoB0B,GAC3B,OAAO1B,EAAoB0B,EAAUF,KAAKD,gBAUnCrB,qBAAA,SACPT,EACAkC,EACAvB,GAEA,OAAOF,EAAqBT,EAAMkC,EAAKvB,MAS1BwB,yBAAgBnC,EAAmBiC,aACtBF,4BAAAK,EAAK7B,oBAAoB0B,yBAA5CvB,IAAAA,UACD2B,WC5D4BrC,EAAmBsC,GACtD,IAAMD,EAAS,GACXE,EAAS,EACTC,EAAQxC,EAAKyC,MAAMF,EAAQA,EAASD,GAExC,IADAD,EAAOK,KAAKF,GACLA,EAAMG,OAEZH,EAAQxC,EAAKyC,MADbF,GAAUD,EACiBC,EAASD,IAC1BK,MACTN,EAAOK,KAAKF,GAId,OAAOH,ED+CSO,CAAoB5C,EEpDX,QFqDpB6C,EAAoB,EAClBC,EAAQT,EAAOU,IAAI,SAAAP,GACxB,IAAM7B,EAAQ,CACbC,MAAOiC,EACPhC,IAAKgC,EAAoBL,EAAMG,KAAO,EACtC7B,MAAOd,EAAK2C,MAGb,OADAE,EAAoBlC,EAAME,IAAM,sBACdJ,qBAAqB+B,EAAO9B,EAAWC,MAE1D,WAAWqC,QAAQ,SAACC,EAASC,GClDP,IAAUC,GAAAA,EDmDtBL,ECnDyDK,EAASC,OAC7E,SAACC,EAAcC,UAAgBD,EAAaE,KAAK,SAAAC,UAAgBF,IAAcC,KAAK,SAAAE,mBAAqBD,GAAcC,SACvHT,QAAQC,QAAQ,MDkDZM,KAAK,SAAAG,GACL,GAAIA,EAAIC,SAAWb,EAAMa,OASxB,UAAU/B,MAAM,qCARhB,IAAMgC,EAAWF,EAAIA,EAAIC,OAAS,GAClC,IAAIC,KAAY,OAAQA,GAIvB,UAAUhC,MAAM,iBAHhBqB,EAAQW,WASJV,6CAUGW,gBAAO7D,EAAYiC,OAC/B,GAAIjC,EAAK2C,KE/Fe,QFgGvB,uBAAOZ,KAAKhC,gBAAgBC,EAAMiC,IAGnC,GAAIjC,EAAK2C,KEhGe,SFiGvB,uBAJOZ,KAIKI,gBAAgBnC,EAAMiC,IAGnC,UAAUL,MAAM,4DAGVb,MAAA,SAAMC,GACZ,OAAOD,EAAMC,EAAQe,KAAKD,oGGnG3BgC,EAAkBC,GAElB,kFAAmFD,uCAA6CC,gGASrGC,GAC3B,8CAA+CA"}