tethys.backend/providers/drive/drivers/local.ts

160 lines
5.6 KiB
TypeScript
Raw Normal View History

import fsExtra from 'fs-extra';
// import { RouterContract } from '@ioc:Adonis/Core/Route';
// import { Visibility, DriveFileStats, ContentHeaders, LocalDriverConfig, LocalDriverContract, DirectoryListingContract, LocalDriveListItem } from '@ioc:Adonis/Core/Drive';
import {
CannotGetMetaDataException,
CannotDeleteFileException,
CannotListDirectoryException,
CannotMoveFileException,
CannotGenerateUrlException,
} from '../exceptions/index.js';
import PathPrefixer from '../path_prefixer/index.js';
import { LocalDriverContract, LocalDriverConfig, DriverContract, DriveListItem } from '../src/types/drive.js';
import { AsyncIterableArray } from '../src/iterable_array.js';
import router from '@adonisjs/core/services/router'
/**
* Local driver interacts with the local file system
*/
export class LocalDriver implements LocalDriverContract {
private diskName: string;
private routeName: string;
private config;
// private router;
// private routeName;
/**
* Reference to the underlying adapter. Which is
* fs-extra
*/
adapter: typeof fsExtra;
/**
* Name of the driver
*/
name: 'local';
/**
* Path prefixer used for prefixing paths with disk root
*/
private prefixer;
// constructor(diskName: string, config: LocalDriverConfig, router: RouterContract);
constructor(diskName: string, config: LocalDriverConfig) {
this.diskName = diskName;
this.config = config;
// this.router = router;
this.routeName = ""; //LocalFileServer_1.LocalFileServer.makeRouteName(this.diskName);
/**
* Reference to the underlying adapter. Which is
* fs-extra
*/
this.adapter = fsExtra;
/**
* Name of the driver
*/
this.name = 'local';
/**
* Path prefixer used for prefixing paths with disk root
*/
this.prefixer = PathPrefixer.fromPath(this.config.root); //root: '/storage/app/public',
}
/**
* Returns a URL for a given location path
*/
public async getUrl(location: string) {
if (!this.config.serveFiles) {
throw CannotGenerateUrlException.invoke(location, this.diskName);
}
return router.makeUrl(this.routeName);
}
/**
* A boolean to find if the location path exists or not
*/
public async exists(location: string): Promise<boolean> {
try {
return await this.adapter.pathExists(this.makePath(location));
} catch (error) {
throw CannotGetMetaDataException.invoke(location, 'exists', error);
}
}
/**
* Make absolute path to a given location
*/
public makePath(location: string): string {
return this.prefixer.prefixPath(location);
}
/**
* Remove a given location path
*/
// delete(location: string, ...args: any[]): Promise<void>;
public async delete(location: string): Promise<void> {
try {
await this.adapter.remove(this.makePath(location));
} catch (error) {
throw CannotDeleteFileException.invoke(location, error);
}
}
public async move(source: string, destination: string): Promise<void> {
try {
let sourcePath = this.makePath(source); //'/storage/app/public/tmp/rtwgliatumwwpd4vpayo4ymg'
let destinationPath = this.makePath(destination);
await this.adapter.move(sourcePath, destinationPath, {
overwrite: true,
});
await this.adapter.move(this.makePath(source), this.makePath(destination), {
overwrite:true
});
} catch (error) {
throw CannotMoveFileException.invoke(source, destination, error);
}
}
/**
* Return a listing directory iterator for given location.
*/
public list(location: string): AsyncIterableArray<DriverContract, DriveListItem<any>> {
// public async list(location: string): Promise<DirectoryListing<DriverContract, DriveListItem<any>>> {
const fullPath = this.makePath(location); //'/storage/app/public/files/307'
// let dirListing: DirectoryListing<DriverContract, DriveListItem<any>> = new DirectoryListing(this, () => this.getListing(fullPath, location));
let dirListing: AsyncIterableArray<DriverContract, DriveListItem<any>> = new AsyncIterableArray(this, () =>
this.getListing(fullPath, location),
);
return dirListing;
// let listing: DriveListItem<fsExtra.Dirent>[] = await this.getListing(fullPath, location);
// let test = new DirectoryListing(this, listing);
// return test;
}
// Example usage
// private async *generateNumbers(): AsyncGenerator<number, void, unknown> {
// yield 1;
// yield 2;
// yield 3;
// }
private async *getListing(fullPath: string, location: string): AsyncGenerator<DriveListItem<fsExtra.Dirent>, void, unknown> {
// private async getListing(fullPath: string, location: string): Promise<DriveListItem<fsExtra.Dirent>[]> {
try {
const dir = await this.adapter.opendir(fullPath);
const prefixer = this.prefixer.withStrippedPrefix(fullPath);
// const listing: DriveListItem<fsExtra.Dirent>[] = new Array();
for await (const dirent of dir) {
yield {
location: prefixer.prefixPath(dirent.name),
isFile: dirent.isFile(),
original: dirent,
};
}
// return listing;
} catch (error) {
throw CannotListDirectoryException.invoke(location, error);
}
}
}