1- import type { File , InodeLike } from '@zenfs/core' ;
2- import { Async , ErrnoError , FileSystem , LazyFile , PreloadFile , Stats } from '@zenfs/core' ;
1+ import type { CreationOptions , InodeLike } from '@zenfs/core' ;
2+ import { Async , ErrnoError , FileSystem , Inode } from '@zenfs/core' ;
3+ import { dirname } from '@zenfs/core/path.js' ;
34import { S_IFDIR , S_IFREG } from '@zenfs/core/vfs/constants.js' ;
4- import { dirname } from '@zenfs/core/vfs/path.js' ;
55import { extendBuffer } from 'utilium/buffer.js' ;
66
77interface CacheEntry {
@@ -43,34 +43,28 @@ export abstract class CloudFS<TError> extends Async(FileSystem) {
4343 await this . _move ( oldPath , newPath ) . catch ( this . _convertAndThrow ( oldPath , 'rename' ) ) ;
4444 }
4545
46- protected abstract _stat ( path : string ) : Promise < Stats > ;
46+ protected abstract _stat ( path : string ) : Promise < InodeLike > ;
4747
48- public async stat ( path : string ) : Promise < Stats > {
49- if ( path === '/' ) return new Stats ( { mode : S_IFDIR | 0o755 } ) ;
48+ public async stat ( path : string ) : Promise < InodeLike > {
49+ if ( path === '/' ) return new Inode ( { mode : S_IFDIR | 0o755 } ) ;
5050
5151 return await this . _stat ( path ) . catch ( this . _convertAndThrow ( path , 'stat' ) ) ;
5252 }
5353
54- public async openFile ( path : string , flag : string ) : Promise < File > {
55- const stats = await this . stat ( path ) . catch ( this . _convertAndThrow ( path , 'openFile' ) ) ;
56- return new LazyFile ( this , path , flag , stats ) ;
57- }
58-
59- protected abstract _create ( path : string , stats : Stats ) : Promise < void > ;
60-
61- public async createFile ( path : string , flag : string , mode : number ) : Promise < File > {
62- const stats = new Stats ( { mode : mode | S_IFREG } ) ;
54+ protected abstract _create ( path : string , inode : Inode ) : Promise < void > ;
6355
64- await this . _create ( path , stats ) . catch ( this . _convertAndThrow ( path , 'createFile' ) ) ;
56+ public async createFile ( path : string , options : CreationOptions ) : Promise < Inode > {
57+ const inode = new Inode ( { mode : options . mode | S_IFREG } ) ;
6558
66- return new PreloadFile ( this , path , flag , stats , new Uint8Array ( ) ) ;
59+ await this . _create ( path , inode ) . catch ( this . _convertAndThrow ( path , 'createFile' ) ) ;
60+ return inode ;
6761 }
6862
6963 protected abstract _delete ( path : string , isDirectory : boolean ) : Promise < void > ;
7064
7165 public async unlink ( path : string ) : Promise < void > {
72- const stats = await this . stat ( path ) . catch ( this . _convertAndThrow ( path , 'unlink' ) ) ;
73- if ( stats . isDirectory ( ) ) throw ErrnoError . With ( 'EISDIR' , path , 'unlink' ) ;
66+ const inode = await this . stat ( path ) . catch ( this . _convertAndThrow ( path , 'unlink' ) ) ;
67+ if ( inode . mode & S_IFDIR ) throw ErrnoError . With ( 'EISDIR' , path , 'unlink' ) ;
7468 await this . _delete ( path , false ) . catch ( this . _convertAndThrow ( path , 'unlink' ) ) ;
7569 }
7670
@@ -80,19 +74,26 @@ export abstract class CloudFS<TError> extends Async(FileSystem) {
8074 await this . _delete ( path , true ) . catch ( this . _convertAndThrow ( path , 'rmdir' ) ) ;
8175 }
8276
83- public async mkdir ( path : string , mode : number ) : Promise < void > {
77+ public async mkdir ( path : string , options : CreationOptions ) : Promise < Inode > {
8478 // Dropbox's folder creations is recursive, so we check to make sure the parent exists
8579 const parent = dirname ( path ) ;
86- const stats = await this . stat ( parent ) . catch ( this . _convertAndThrow ( path , 'mkdir' ) ) ;
87- if ( stats && ! stats . isDirectory ( ) ) throw ErrnoError . With ( 'ENOTDIR' , parent , 'mkdir' ) ;
80+ const parentInode = await this . stat ( parent ) . catch ( this . _convertAndThrow ( path , 'mkdir' ) ) ;
81+ if ( parentInode && ! ( parentInode . mode & S_IFDIR ) ) throw ErrnoError . With ( 'ENOTDIR' , parent , 'mkdir' ) ;
8882
89- await this . _create ( path , new Stats ( { mode : mode | S_IFDIR } ) ) . catch ( this . _convertAndThrow ( path , 'mkdir' ) ) ;
83+ await this . _create ( path , new Inode ( { mode : options . mode | S_IFDIR } ) ) . catch (
84+ this . _convertAndThrow ( path , 'mkdir' )
85+ ) ;
86+ return new Inode ( { mode : options . mode | S_IFDIR } ) ;
9087 }
9188
92- public async sync ( path : string , data : Uint8Array , stats : Partial < InodeLike > = { } ) : Promise < void > {
93- await this . _write ( path , data , stats , 'sync' ) . catch ( this . _convertAndThrow ( path , 'sync' ) ) ;
89+ protected _touch ?( path : string , inode : Partial < InodeLike > ) : Promise < void > ;
90+
91+ public async touch ( path : string , metadata : Partial < InodeLike > = { } ) : Promise < void > {
92+ await this . _touch ?.( path , metadata ) . catch ( this . _convertAndThrow ( path , 'touch' ) ) ;
9493 }
9594
95+ public async sync ( ) : Promise < void > { }
96+
9697 public link ( target : string ) : Promise < void > {
9798 throw ErrnoError . With ( 'ENOTSUP' , target , 'link' ) ;
9899 }
@@ -104,17 +105,12 @@ export abstract class CloudFS<TError> extends Async(FileSystem) {
104105 buffer . set ( data . subarray ( offset , end ) ) ;
105106 }
106107
107- protected abstract _write (
108- path : string ,
109- buffer : Uint8Array ,
110- stats : Partial < InodeLike > ,
111- syscall : string
112- ) : Promise < void > ;
108+ protected abstract _write ( path : string , buffer : Uint8Array , syscall : string ) : Promise < void > ;
113109
114110 public async write ( path : string , data : Uint8Array , offset : number = 0 ) : Promise < void > {
115111 const buffer = extendBuffer ( await this . getValidContents ( path , 'write' ) , offset + data . byteLength ) ;
116112 buffer . set ( data , offset ) ;
117- await this . _write ( path , buffer , { } , 'write' ) . catch ( this . _convertAndThrow ( path , 'write' ) ) ;
113+ await this . _write ( path , buffer , 'write' ) . catch ( this . _convertAndThrow ( path , 'write' ) ) ;
118114 }
119115
120116 protected partialCache = new Map < string , CacheEntry > ( ) ;
0 commit comments