chore: create separate functions to manage file structure and file data
This commit is contained in:
parent
4221d7d09a
commit
a459da6e6f
@ -10,17 +10,12 @@ export type SandboxFiles = {
|
|||||||
fileData: TFileData[]
|
fileData: TFileData[]
|
||||||
}
|
}
|
||||||
|
|
||||||
const processFiles = async (paths: string[], id: string) => {
|
// Convert list of paths to the hierchical file structure used by the editor
|
||||||
|
function generateFileStructure(paths: string[]): (TFolder | TFile)[] {
|
||||||
const root: TFolder = { id: "/", type: "folder", name: "/", children: [] }
|
const root: TFolder = { id: "/", type: "folder", name: "/", children: [] }
|
||||||
const fileData: TFileData[] = []
|
|
||||||
|
|
||||||
paths.forEach((path) => {
|
paths.forEach((path) => {
|
||||||
const allParts = path.split("/")
|
const parts = path.split("/")
|
||||||
if (allParts[1] !== id) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const parts = allParts.slice(2)
|
|
||||||
let current: TFolder = root
|
let current: TFolder = root
|
||||||
|
|
||||||
for (let i = 0; i < parts.length; i++) {
|
for (let i = 0; i < parts.length; i++) {
|
||||||
@ -36,7 +31,6 @@ const processFiles = async (paths: string[], id: string) => {
|
|||||||
if (isFile) {
|
if (isFile) {
|
||||||
const file: TFile = { id: `/${parts.join("/")}`, type: "file", name: part }
|
const file: TFile = { id: `/${parts.join("/")}`, type: "file", name: part }
|
||||||
current.children.push(file)
|
current.children.push(file)
|
||||||
fileData.push({ id: `/${parts.join("/")}`, data: "" })
|
|
||||||
} else {
|
} else {
|
||||||
const folder: TFolder = {
|
const folder: TFolder = {
|
||||||
id: `/${parts.slice(0, i + 1).join("/")}`,
|
id: `/${parts.slice(0, i + 1).join("/")}`,
|
||||||
@ -51,21 +45,7 @@ const processFiles = async (paths: string[], id: string) => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
await Promise.all(
|
return root.children
|
||||||
fileData.map(async (file) => {
|
|
||||||
const data = await RemoteFileStorage.fetchFileContent(`projects/${id}${file.id}`)
|
|
||||||
file.data = data
|
|
||||||
})
|
|
||||||
)
|
|
||||||
|
|
||||||
return {
|
|
||||||
files: root.children,
|
|
||||||
fileData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const getSandboxFiles = async (id: string) => {
|
|
||||||
return await processFiles(await RemoteFileStorage.getSandboxPaths(id), id)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// FileManager class to handle file operations in a sandbox
|
// FileManager class to handle file operations in a sandbox
|
||||||
@ -89,14 +69,66 @@ export class FileManager {
|
|||||||
this.refreshFileList = refreshFileList
|
this.refreshFileList = refreshFileList
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fetch file data from list of paths
|
||||||
|
private async generateFileData(paths: string[]): Promise<TFileData[]> {
|
||||||
|
const fileData: TFileData[] = []
|
||||||
|
|
||||||
|
for (const path of paths) {
|
||||||
|
const parts = path.split("/")
|
||||||
|
const isFile = parts.length > 0 && parts[parts.length - 1].length > 0
|
||||||
|
|
||||||
|
if (isFile) {
|
||||||
|
const fileId = `/${parts.join("/")}`
|
||||||
|
const data = await RemoteFileStorage.fetchFileContent(`projects/${this.sandboxId}${fileId}`)
|
||||||
|
fileData.push({ id: fileId, data })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return fileData
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert local file path to remote path
|
||||||
private getRemoteFileId(localId: string): string {
|
private getRemoteFileId(localId: string): string {
|
||||||
return `projects/${this.sandboxId}${localId}`
|
return `projects/${this.sandboxId}${localId}`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Convert remote file path to local file path
|
||||||
|
private getLocalFileId(remoteId: string): string | undefined {
|
||||||
|
const allParts = remoteId.split("/")
|
||||||
|
if (allParts[1] !== this.sandboxId) return undefined;
|
||||||
|
return allParts.slice(2).join("/")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert remote file paths to local file paths
|
||||||
|
private getLocalFileIds(remoteIds: string[]): string[] {
|
||||||
|
return remoteIds
|
||||||
|
.map(this.getLocalFileId.bind(this))
|
||||||
|
.filter((id) => id !== undefined);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Download files from remote storage
|
||||||
|
private async updateFileData(): Promise<TFileData[]> {
|
||||||
|
const remotePaths = await RemoteFileStorage.getSandboxPaths(this.sandboxId)
|
||||||
|
const localPaths = this.getLocalFileIds(remotePaths)
|
||||||
|
this.sandboxFiles.fileData = await this.generateFileData(localPaths)
|
||||||
|
return this.sandboxFiles.fileData
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update file structure
|
||||||
|
private async updateFileStructure(): Promise<(TFolder | TFile)[]> {
|
||||||
|
const remotePaths = await RemoteFileStorage.getSandboxPaths(this.sandboxId)
|
||||||
|
const localPaths = this.getLocalFileIds(remotePaths)
|
||||||
|
this.sandboxFiles.files = generateFileStructure(localPaths)
|
||||||
|
return this.sandboxFiles.files
|
||||||
|
}
|
||||||
|
|
||||||
// Initialize the FileManager
|
// Initialize the FileManager
|
||||||
async initialize() {
|
async initialize() {
|
||||||
this.sandboxFiles = await getSandboxFiles(this.sandboxId)
|
|
||||||
const projectDirectory = this.dirName
|
// Download files from remote file storage
|
||||||
|
await this.updateFileStructure()
|
||||||
|
await this.updateFileData()
|
||||||
|
|
||||||
// Copy all files from the project to the container
|
// Copy all files from the project to the container
|
||||||
const promises = this.sandboxFiles.fileData.map(async (file) => {
|
const promises = this.sandboxFiles.fileData.map(async (file) => {
|
||||||
try {
|
try {
|
||||||
@ -115,15 +147,15 @@ export class FileManager {
|
|||||||
// Make the logged in user the owner of all project files
|
// Make the logged in user the owner of all project files
|
||||||
this.fixPermissions()
|
this.fixPermissions()
|
||||||
|
|
||||||
await this.watchDirectory(projectDirectory)
|
await this.watchDirectory(this.dirName)
|
||||||
await this.watchSubdirectories(projectDirectory)
|
await this.watchSubdirectories(this.dirName)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the given path is a directory
|
// Check if the given path is a directory
|
||||||
private async isDirectory(projectDirectory: string): Promise<boolean> {
|
private async isDirectory(directoryPath: string): Promise<boolean> {
|
||||||
try {
|
try {
|
||||||
const result = await this.sandbox.commands.run(
|
const result = await this.sandbox.commands.run(
|
||||||
`[ -d "${projectDirectory}" ] && echo "true" || echo "false"`
|
`[ -d "${directoryPath}" ] && echo "true" || echo "false"`
|
||||||
)
|
)
|
||||||
return result.stdout.trim() === "true"
|
return result.stdout.trim() === "true"
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
@ -324,7 +356,8 @@ export class FileManager {
|
|||||||
|
|
||||||
// Get folder content
|
// Get folder content
|
||||||
async getFolder(folderId: string): Promise<string[]> {
|
async getFolder(folderId: string): Promise<string[]> {
|
||||||
return RemoteFileStorage.getFolder(this.getRemoteFileId(folderId))
|
const remotePaths = await RemoteFileStorage.getFolder(this.getRemoteFileId(folderId))
|
||||||
|
return this.getLocalFileIds(remotePaths)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save file content
|
// Save file content
|
||||||
@ -363,8 +396,7 @@ export class FileManager {
|
|||||||
file.id = newFileId
|
file.id = newFileId
|
||||||
|
|
||||||
await RemoteFileStorage.renameFile(this.getRemoteFileId(fileId), this.getRemoteFileId(newFileId), fileData.data)
|
await RemoteFileStorage.renameFile(this.getRemoteFileId(fileId), this.getRemoteFileId(newFileId), fileData.data)
|
||||||
const newFiles = await getSandboxFiles(this.sandboxId)
|
return this.updateFileStructure()
|
||||||
return newFiles.files
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Move a file within the container
|
// Move a file within the container
|
||||||
@ -445,9 +477,7 @@ export class FileManager {
|
|||||||
)
|
)
|
||||||
|
|
||||||
await RemoteFileStorage.deleteFile(this.getRemoteFileId(fileId))
|
await RemoteFileStorage.deleteFile(this.getRemoteFileId(fileId))
|
||||||
|
return this.updateFileStructure()
|
||||||
const newFiles = await getSandboxFiles(this.sandboxId)
|
|
||||||
return newFiles.files
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete a folder
|
// Delete a folder
|
||||||
@ -464,8 +494,7 @@ export class FileManager {
|
|||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
|
||||||
const newFiles = await getSandboxFiles(this.sandboxId)
|
return this.updateFileStructure()
|
||||||
return newFiles.files
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close all file watchers
|
// Close all file watchers
|
||||||
|
Loading…
x
Reference in New Issue
Block a user