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 { 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; public async delete(location: string): Promise { try { await this.adapter.remove(this.makePath(location)); } catch (error) { throw CannotDeleteFileException.invoke(location, error); } } public async move(source: string, destination: string): Promise { 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> { // public async list(location: string): Promise>> { const fullPath = this.makePath(location); //'/storage/app/public/files/307' // let dirListing: DirectoryListing> = new DirectoryListing(this, () => this.getListing(fullPath, location)); let dirListing: AsyncIterableArray> = new AsyncIterableArray(this, () => this.getListing(fullPath, location), ); return dirListing; // let listing: DriveListItem[] = await this.getListing(fullPath, location); // let test = new DirectoryListing(this, listing); // return test; } // Example usage // private async *generateNumbers(): AsyncGenerator { // yield 1; // yield 2; // yield 3; // } private async *getListing(fullPath: string, location: string): AsyncGenerator, void, unknown> { // private async getListing(fullPath: string, location: string): Promise[]> { try { const dir = await this.adapter.opendir(fullPath); const prefixer = this.prefixer.withStrippedPrefix(fullPath); // const listing: DriveListItem[] = 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); } } }