UNPKG

@uppy/companion

Version:

OAuth helper and remote fetcher for Uppy's (https://uppy.io) extensible file upload widget with support for drag&drop, resumable uploads, previews, restrictions, file processing/encoding, remote providers like Dropbox and Google Drive, S3 and more :dog:

212 lines (175 loc) 5.75 kB
import querystring from 'node:querystring' const getUsername = (data) => { return data.user.emailAddress } export const isGsuiteFile = (mimeType) => { return mimeType?.startsWith('application/vnd.google') } const isSharedDrive = (item) => { return item.kind === 'drive#drive' } const isFolder = (item) => { return ( item.mimeType === 'application/vnd.google-apps.folder' || isSharedDrive(item) ) } export const isShortcut = (mimeType) => { return mimeType === 'application/vnd.google-apps.shortcut' } const getItemSize = (item) => { return parseInt(item.size, 10) } const getItemIcon = (item) => { if (isSharedDrive(item)) { const size = '=w16-h16-n' const sizeParamRegex = /=[-whncsp0-9]*$/ return item.backgroundImageLink.match(sizeParamRegex) ? item.backgroundImageLink.replace(sizeParamRegex, size) : `${item.backgroundImageLink}${size}` } if ( item.thumbnailLink && !item.mimeType.startsWith('application/vnd.google') ) { const smallerThumbnailLink = item.thumbnailLink.replace('s220', 's40') return smallerThumbnailLink } return item.iconLink } const getItemSubList = (item) => { const allowedGSuiteTypes = [ 'application/vnd.google-apps.document', 'application/vnd.google-apps.drawing', 'application/vnd.google-apps.script', 'application/vnd.google-apps.spreadsheet', 'application/vnd.google-apps.presentation', 'application/vnd.google-apps.shortcut', ] return item.files.filter((i) => { return ( isFolder(i) || !isGsuiteFile(i.mimeType) || allowedGSuiteTypes.includes(i.mimeType) ) }) } const getItemName = (item) => { const extensionMaps = { 'application/vnd.google-apps.document': '.docx', 'application/vnd.google-apps.drawing': '.png', 'application/vnd.google-apps.script': '.json', 'application/vnd.google-apps.spreadsheet': '.xlsx', 'application/vnd.google-apps.presentation': '.ppt', } const extension = extensionMaps[item.mimeType] if (extension && item.name && !item.name.endsWith(extension)) { return item.name + extension } return item.name ? item.name : '/' } export const getGsuiteExportType = (mimeType) => { const typeMaps = { 'application/vnd.google-apps.document': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'application/vnd.google-apps.drawing': 'image/png', 'application/vnd.google-apps.script': 'application/vnd.google-apps.script+json', 'application/vnd.google-apps.spreadsheet': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'application/vnd.google-apps.presentation': 'application/vnd.openxmlformats-officedocument.presentationml.presentation', } return typeMaps[mimeType] || 'application/pdf' } function getMimeType2(mimeType) { if (isGsuiteFile(mimeType)) { return getGsuiteExportType(mimeType) } return mimeType } const getMimeType = (item) => { if (isShortcut(item.mimeType)) { return getMimeType2(item.shortcutDetails.targetMimeType) } return getMimeType2(item.mimeType) } const getItemId = (item) => { return item.id } const getItemRequestPath = (item) => { return item.id } const getItemModifiedDate = (item) => { return item.modifiedTime } const getItemThumbnailUrl = (item) => { return item.thumbnailLink } const getNextPagePath = (data, currentQuery, currentPath) => { if (!data.nextPageToken) { return null } const query = { ...currentQuery, cursor: data.nextPageToken } return `${currentPath}?${querystring.stringify(query)}` } const getImageHeight = (item) => item.imageMediaMetadata?.height const getImageWidth = (item) => item.imageMediaMetadata?.width const getImageRotation = (item) => item.imageMediaMetadata?.rotation const getImageDate = (item) => item.imageMediaMetadata?.date const getVideoHeight = (item) => item.videoMediaMetadata?.height const getVideoWidth = (item) => item.videoMediaMetadata?.width const getVideoDurationMillis = (item) => item.videoMediaMetadata?.durationMillis // Hopefully this name will not be used by Google export const VIRTUAL_SHARED_DIR = 'shared-with-me' export const adaptData = ( listFilesResp, sharedDrivesResp, directory, query, showSharedWithMe, about, ) => { const adaptItem = (item) => ({ isFolder: isFolder(item), icon: getItemIcon(item), name: getItemName(item), mimeType: getMimeType(item), id: getItemId(item), thumbnail: getItemThumbnailUrl(item), requestPath: getItemRequestPath(item), modifiedDate: getItemModifiedDate(item), size: getItemSize(item), custom: { isSharedDrive: isSharedDrive(item), imageHeight: getImageHeight(item), imageWidth: getImageWidth(item), imageRotation: getImageRotation(item), imageDateTime: getImageDate(item), videoHeight: getVideoHeight(item), videoWidth: getVideoWidth(item), videoDurationMillis: getVideoDurationMillis(item), }, }) const items = getItemSubList(listFilesResp) const sharedDrives = sharedDrivesResp ? sharedDrivesResp.drives || [] : [] // “Shared with me” is a list of shared documents, // not the same as sharedDrives const virtualItem = showSharedWithMe && { isFolder: true, icon: 'folder', name: 'Shared with me', mimeType: 'application/vnd.google-apps.folder', id: VIRTUAL_SHARED_DIR, requestPath: VIRTUAL_SHARED_DIR, } const adaptedItems = [ ...(virtualItem ? [virtualItem] : []), // shared folder first ...[...sharedDrives, ...items].map(adaptItem), ] return { username: getUsername(about), items: adaptedItems, nextPagePath: getNextPagePath(listFilesResp, query, directory), } }