@directus/api
Version:
Directus is a real-time API and App dashboard for managing SQL database content
72 lines (71 loc) • 2.61 kB
JavaScript
/**
* class to help tracking file status between local and remote
*/
import { readdir, rm } from 'node:fs/promises';
import { dirname, join, relative } from 'node:path';
import { pathDepth } from './utils.js';
export class SyncFileTracker {
localFiles;
trackedDirs;
constructor() {
this.localFiles = new Set();
this.trackedDirs = new Set();
}
/**
* Reads all files recusrively in the provided directory
* @returns the number of files read
*/
async readLocalFiles(localExtensionsPath) {
const entries = await readdir(localExtensionsPath, { recursive: true, withFileTypes: true }).catch(() => {
/* path doesnt exist */
});
if (!entries)
return 0;
for (const entry of entries) {
if (!entry.isFile())
continue;
const relativePath = join(relative(localExtensionsPath, entry.parentPath), entry.name);
this.localFiles.add(relativePath);
}
return this.localFiles.size;
}
/**
* Removes a file from the locally tracked files
*/
async passedFile(filePath) {
this.localFiles.delete(filePath);
let currentDir = dirname(filePath);
while (currentDir !== '.') {
if (this.trackedDirs.has(currentDir))
break;
this.trackedDirs.add(currentDir);
currentDir = dirname(currentDir);
}
}
/**
* Removes left over tracked files that were not processed
*/
async cleanup(localExtensionsPath) {
const removeDirs = new Set();
for (const removeFile of this.localFiles) {
if (removeFile === '.status')
continue;
let currentDir = dirname(removeFile);
while (currentDir !== localExtensionsPath && currentDir !== '.') {
if (this.trackedDirs.has(currentDir))
break;
removeDirs.add(currentDir);
currentDir = dirname(currentDir);
}
}
// sort directory by depth so we can remove the highest level directory recursively
const removeDirsRecursive = Array.from(removeDirs)
.sort((a, b) => pathDepth(b) - pathDepth(a))
.filter((d) => !removeDirs.has(dirname(d)));
for (const dir of removeDirsRecursive) {
const relativePath = join(localExtensionsPath, dir);
// removing local folder that does not exist in the remote storage
await rm(relativePath, { recursive: true, force: true });
}
}
}