mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-21 20:47:08 -05:00
31299ed31e
Fix off-by-one error in previewByPath GitOrigin-RevId: 28d351aa288ff2e92df421e0bc33c2d44eae91c0
138 lines
3.2 KiB
TypeScript
138 lines
3.2 KiB
TypeScript
import { Folder } from '../../../../../types/folder'
|
|
import { FileTreeEntity } from '../../../../../types/file-tree-entity'
|
|
import { Doc } from '../../../../../types/doc'
|
|
import { FileRef } from '../../../../../types/file-ref'
|
|
import { PreviewPath } from '../../../../../types/preview-path'
|
|
|
|
type DocFindResult = {
|
|
entity: Doc
|
|
type: 'doc'
|
|
}
|
|
|
|
type FolderFindResult = {
|
|
entity: Folder
|
|
type: 'folder'
|
|
}
|
|
|
|
type FileRefFindResult = {
|
|
entity: FileRef
|
|
type: 'fileRef'
|
|
}
|
|
|
|
export type FindResult = DocFindResult | FolderFindResult | FileRefFindResult
|
|
|
|
// Finds the entity with a given ID in the tree represented by `folder` and
|
|
// returns a path to that entity, represented by an array of folders starting at
|
|
// the root plus the entity itself
|
|
function pathComponentsInFolder(
|
|
folder: Folder,
|
|
id: string,
|
|
ancestors: FileTreeEntity[] = []
|
|
): FileTreeEntity[] | null {
|
|
const docOrFileRef =
|
|
folder.docs.find(doc => doc._id === id) ||
|
|
folder.fileRefs.find(fileRef => fileRef._id === id)
|
|
if (docOrFileRef) {
|
|
return ancestors.concat([docOrFileRef])
|
|
}
|
|
|
|
for (const subfolder of folder.folders) {
|
|
if (subfolder._id === id) {
|
|
return ancestors.concat([subfolder])
|
|
} else {
|
|
const path = pathComponentsInFolder(
|
|
subfolder,
|
|
id,
|
|
ancestors.concat([subfolder])
|
|
)
|
|
if (path !== null) {
|
|
return path
|
|
}
|
|
}
|
|
}
|
|
|
|
return null
|
|
}
|
|
|
|
// Finds the entity with a given ID in the tree represented by `folder` and
|
|
// returns a path to that entity as a string
|
|
export function pathInFolder(folder: Folder, id: string): string | null {
|
|
return (
|
|
pathComponentsInFolder(folder, id)
|
|
?.map(entity => entity.name)
|
|
.join('/') || null
|
|
)
|
|
}
|
|
|
|
export function findEntityByPath(
|
|
folder: Folder,
|
|
path: string
|
|
): FindResult | null {
|
|
if (path === '') {
|
|
return { entity: folder, type: 'folder' }
|
|
}
|
|
|
|
const parts = path.split('/')
|
|
const name = parts.shift()
|
|
const rest = parts.join('/')
|
|
|
|
if (name === '.') {
|
|
return findEntityByPath(folder, rest)
|
|
}
|
|
|
|
const doc = folder.docs.find(doc => doc.name === name)
|
|
if (doc) {
|
|
return { entity: doc, type: 'doc' }
|
|
}
|
|
|
|
const fileRef = folder.fileRefs.find(fileRef => fileRef.name === name)
|
|
if (fileRef) {
|
|
return { entity: fileRef, type: 'fileRef' }
|
|
}
|
|
|
|
for (const subfolder of folder.folders) {
|
|
if (subfolder.name === name) {
|
|
if (rest === '') {
|
|
return { entity: subfolder, type: 'folder' }
|
|
} else {
|
|
return findEntityByPath(subfolder, rest)
|
|
}
|
|
}
|
|
}
|
|
|
|
return null
|
|
}
|
|
|
|
export function previewByPath(
|
|
folder: Folder,
|
|
projectId: string,
|
|
path: string
|
|
): PreviewPath | null {
|
|
for (const suffix of [
|
|
'',
|
|
'.png',
|
|
'.jpg',
|
|
'.jpeg',
|
|
'.pdf',
|
|
'.PNG',
|
|
'.JPG',
|
|
'.JPEG',
|
|
'.PDF',
|
|
]) {
|
|
const result = findEntityByPath(folder, path + suffix)
|
|
|
|
if (result) {
|
|
const { name, _id: id } = result.entity
|
|
return {
|
|
url: `/project/${projectId}/file/${id}`,
|
|
extension: name.slice(name.lastIndexOf('.') + 1),
|
|
}
|
|
}
|
|
}
|
|
return null
|
|
}
|
|
|
|
export function dirname(fileTreeData: Folder, id: string) {
|
|
const path = pathInFolder(fileTreeData, id)
|
|
return path?.split('/').slice(0, -1).join('/') || null
|
|
}
|