@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
JavaScript
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),
}
}