diff --git a/src/fsa-to-node/FsaNodeFs.ts b/src/fsa-to-node/FsaNodeFs.ts index 1dfd8e56f..1ff691c8b 100644 --- a/src/fsa-to-node/FsaNodeFs.ts +++ b/src/fsa-to-node/FsaNodeFs.ts @@ -1,6 +1,6 @@ import * as optHelpers from '../node/options'; import * as util from '../node/util'; -import { createPromisesApi } from '../node/promises'; +import { FsPromises } from '../node/FsPromises'; import { pathToLocation, testDirectoryIsWritable } from './util'; import { ERRSTR, MODE } from '../node/constants'; import { strToEncoding } from '../encoding'; @@ -14,6 +14,7 @@ import { FsSynchronousApi } from '../node/types/FsSynchronousApi'; import { FsaNodeWriteStream } from './FsaNodeWriteStream'; import { FsaNodeReadStream } from './FsaNodeReadStream'; import { FsaNodeCore } from './FsaNodeCore'; +import { FileHandle } from '../node/FileHandle'; import type { FsCallbackApi, FsPromisesApi } from '../node/types'; import type * as misc from '../node/types/misc'; import type * as opts from '../node/types/options'; @@ -38,7 +39,7 @@ const noop: (...args: any[]) => any = () => {}; export class FsaNodeFs extends FsaNodeCore implements FsCallbackApi, FsSynchronousApi, FsCommonObjects { // ------------------------------------------------------------ FsPromisesApi - public readonly promises: FsPromisesApi = createPromisesApi(this); + public readonly promises: FsPromisesApi = new FsPromises(this, FileHandle); // ------------------------------------------------------------ FsCallbackApi diff --git a/src/node/FsPromises.ts b/src/node/FsPromises.ts new file mode 100644 index 000000000..680d614a2 --- /dev/null +++ b/src/node/FsPromises.ts @@ -0,0 +1,79 @@ +import { promisify } from './util'; +import { constants } from '../constants'; +import type * as opts from './types/options'; +import type * as misc from './types/misc'; +import type { FsCallbackApi, FsPromisesApi } from './types'; + +export class FsPromises implements FsPromisesApi { + public readonly constants = constants; + + public constructor( + protected readonly fs: FsCallbackApi, + public readonly FileHandle: new (...args: unknown[]) => misc.IFileHandle, + ) {} + + public readonly cp = promisify(this.fs, 'cp'); + public readonly opendir = promisify(this.fs, 'opendir'); + public readonly statfs = promisify(this.fs, 'statfs'); + public readonly lutimes = promisify(this.fs, 'lutimes'); + public readonly access = promisify(this.fs, 'access'); + public readonly chmod = promisify(this.fs, 'chmod'); + public readonly chown = promisify(this.fs, 'chown'); + public readonly copyFile = promisify(this.fs, 'copyFile'); + public readonly lchmod = promisify(this.fs, 'lchmod'); + public readonly lchown = promisify(this.fs, 'lchown'); + public readonly link = promisify(this.fs, 'link'); + public readonly lstat = promisify(this.fs, 'lstat'); + public readonly mkdir = promisify(this.fs, 'mkdir'); + public readonly mkdtemp = promisify(this.fs, 'mkdtemp'); + public readonly readdir = promisify(this.fs, 'readdir'); + public readonly readlink = promisify(this.fs, 'readlink'); + public readonly realpath = promisify(this.fs, 'realpath'); + public readonly rename = promisify(this.fs, 'rename'); + public readonly rmdir = promisify(this.fs, 'rmdir'); + public readonly rm = promisify(this.fs, 'rm'); + public readonly stat = promisify(this.fs, 'stat'); + public readonly symlink = promisify(this.fs, 'symlink'); + public readonly truncate = promisify(this.fs, 'truncate'); + public readonly unlink = promisify(this.fs, 'unlink'); + public readonly utimes = promisify(this.fs, 'utimes'); + + public readonly readFile = ( + id: misc.TFileHandle, + options?: opts.IReadFileOptions | string, + ): Promise => { + return promisify(this.fs, 'readFile')(id instanceof this.FileHandle ? id.fd : (id as misc.PathLike), options); + }; + + public readonly appendFile = ( + path: misc.TFileHandle, + data: misc.TData, + options?: opts.IAppendFileOptions | string, + ): Promise => { + return promisify(this.fs, 'appendFile')( + path instanceof this.FileHandle ? path.fd : (path as misc.PathLike), + data, + options, + ); + }; + + public readonly open = (path: misc.PathLike, flags: misc.TFlags = 'r', mode?: misc.TMode) => { + return promisify(this.fs, 'open', fd => new this.FileHandle(this.fs, fd))(path, flags, mode); + }; + + public readonly writeFile = ( + id: misc.TFileHandle, + data: misc.TData, + options?: opts.IWriteFileOptions, + ): Promise => { + return promisify(this.fs, 'writeFile')( + id instanceof this.FileHandle ? id.fd : (id as misc.PathLike), + data, + options, + ); + }; + + public readonly watch = () => { + throw new Error('Not implemented'); + }; +} diff --git a/src/node/promises.ts b/src/node/promises.ts deleted file mode 100644 index b18408b60..000000000 --- a/src/node/promises.ts +++ /dev/null @@ -1,125 +0,0 @@ -import { FileHandle } from './FileHandle'; -import { promisify } from './util'; -import { constants } from '../constants'; -import type * as opts from './types/options'; -import type * as misc from './types/misc'; -import type { FsCallbackApi, FsPromisesApi } from './types'; - -export function createPromisesApi(vol: FsCallbackApi): FsPromisesApi { - return { - FileHandle: FileHandle as any, - constants, - - cp: promisify(vol, 'cp'), - opendir: promisify(vol, 'opendir'), - statfs: promisify(vol, 'statfs'), - watch: () => { - throw new Error('Not implemented'); - }, - lutimes: promisify(vol, 'lutimes'), - - access(path: misc.PathLike, mode?: number): Promise { - return promisify(vol, 'access')(path, mode); - }, - - appendFile(path: misc.TFileHandle, data: misc.TData, options?: opts.IAppendFileOptions | string): Promise { - return promisify(vol, 'appendFile')( - path instanceof FileHandle ? path.fd : (path as misc.PathLike), - data, - options, - ); - }, - - chmod(path: misc.PathLike, mode: misc.TMode): Promise { - return promisify(vol, 'chmod')(path, mode); - }, - - chown(path: misc.PathLike, uid: number, gid: number): Promise { - return promisify(vol, 'chown')(path, uid, gid); - }, - - copyFile(src: misc.PathLike, dest: misc.PathLike, flags?: misc.TFlagsCopy): Promise { - return promisify(vol, 'copyFile')(src, dest, flags); - }, - - lchmod(path: misc.PathLike, mode: misc.TMode): Promise { - return promisify(vol, 'lchmod')(path, mode); - }, - - lchown(path: misc.PathLike, uid: number, gid: number): Promise { - return promisify(vol, 'lchown')(path, uid, gid); - }, - - link(existingPath: misc.PathLike, newPath: misc.PathLike): Promise { - return promisify(vol, 'link')(existingPath, newPath); - }, - - lstat(path: misc.PathLike, options?: opts.IStatOptions): Promise { - return promisify(vol, 'lstat')(path, options); - }, - - mkdir(path: misc.PathLike, options?: misc.TMode | opts.IMkdirOptions): Promise { - return promisify(vol, 'mkdir')(path, options); - }, - - mkdtemp(prefix: string, options?: opts.IOptions) { - return promisify(vol, 'mkdtemp')(prefix, options); - }, - - open(path: misc.PathLike, flags: misc.TFlags = 'r', mode?: misc.TMode) { - return promisify(vol, 'open', fd => new FileHandle(vol, fd))(path, flags, mode); - }, - - readdir(path: misc.PathLike, options?: opts.IReaddirOptions | string): Promise { - return promisify(vol, 'readdir')(path, options); - }, - - readFile(id: misc.TFileHandle, options?: opts.IReadFileOptions | string): Promise { - return promisify(vol, 'readFile')(id instanceof FileHandle ? id.fd : (id as misc.PathLike), options); - }, - - readlink(path: misc.PathLike, options?: opts.IOptions): Promise { - return promisify(vol, 'readlink')(path, options); - }, - - realpath(path: misc.PathLike, options?: opts.IRealpathOptions | string): Promise { - return promisify(vol, 'realpath')(path, options); - }, - - rename(oldPath: misc.PathLike, newPath: misc.PathLike): Promise { - return promisify(vol, 'rename')(oldPath, newPath); - }, - - rmdir(path: misc.PathLike, options?: opts.IRmdirOptions): Promise { - return promisify(vol, 'rmdir')(path, options); - }, - - rm(path: misc.PathLike, options?: opts.IRmOptions): Promise { - return promisify(vol, 'rm')(path, options); - }, - - stat(path: misc.PathLike, options?: opts.IStatOptions): Promise { - return promisify(vol, 'stat')(path, options); - }, - - symlink(target: misc.PathLike, path: misc.PathLike, type?: misc.symlink.Type): Promise { - return promisify(vol, 'symlink')(target, path, type); - }, - - truncate(path: misc.PathLike, len?: number): Promise { - return promisify(vol, 'truncate')(path, len); - }, - - unlink(path: misc.PathLike): Promise { - return promisify(vol, 'unlink')(path); - }, - - utimes(path: misc.PathLike, atime: misc.TTime, mtime: misc.TTime): Promise { - return promisify(vol, 'utimes')(path, atime, mtime); - }, - - writeFile(id: misc.TFileHandle, data: misc.TData, options?: opts.IWriteFileOptions): Promise { - return promisify(vol, 'writeFile')(id instanceof FileHandle ? id.fd : (id as misc.PathLike), data, options); - }, - }; -} diff --git a/src/volume.ts b/src/volume.ts index 64be5c74f..267f2f780 100644 --- a/src/volume.ts +++ b/src/volume.ts @@ -10,11 +10,12 @@ import { Readable, Writable } from 'stream'; import { constants } from './constants'; import { EventEmitter } from 'events'; import { TEncodingExtended, TDataOut, strToEncoding, ENCODING_UTF8 } from './encoding'; +import { FileHandle } from './node/FileHandle'; import * as util from 'util'; import * as misc from './node/types/misc'; import * as opts from './node/types/options'; -import { FsCallbackApi, WritevCallback } from './node/types/FsCallbackApi'; -import { createPromisesApi } from './node/promises'; +import { FsCallbackApi } from './node/types/FsCallbackApi'; +import { FsPromises } from './node/FsPromises'; import { ERRSTR, FLAGS, MODE } from './node/constants'; import { getDefaultOpts, @@ -54,7 +55,7 @@ import { unixify, } from './node/util'; import type { PathLike, symlink } from 'fs'; -import type { FsSynchronousApi } from './node/types'; +import type { FsPromisesApi, FsSynchronousApi } from './node/types'; const resolveCrossPlatform = pathModule.resolve; const { @@ -288,9 +289,9 @@ export class Volume implements FsCallbackApi { File: new (...args) => File; }; - private promisesApi = createPromisesApi(this); + private promisesApi = new FsPromises(this, FileHandle); - get promises() { + get promises(): FsPromisesApi { if (this.promisesApi === null) throw new Error('Promise is not supported in this environment.'); return this.promisesApi; }