Skip to content

Commit

Permalink
feat: 🎸 add missing callback API methods and some sycn API ones
Browse files Browse the repository at this point in the history
  • Loading branch information
streamich committed Jun 22, 2023
1 parent 273977d commit 956533a
Show file tree
Hide file tree
Showing 7 changed files with 138 additions and 67 deletions.
15 changes: 12 additions & 3 deletions src/fsa-to-node/FsaNodeFs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import type * as misc from '../node/types/misc';
import type * as opts from '../node/types/options';
import type * as fsa from '../fsa/types';
import type { FsCommonObjects } from '../node/types/FsCommonObjects';
import type { WritevCallback } from '../node/types/callback';
import type { WritevCallback } from '../node/types/FsCallbackApi';

const notSupported: (...args: any[]) => any = () => {
throw new Error('Method not supported by the File System Access API.');
Expand Down Expand Up @@ -792,8 +792,12 @@ export class FsaNodeFs extends FsaNodeCore implements FsCallbackApi, FsSynchrono
return stream;
};

public readonly symlink: FsCallbackApi['symlink'] = notSupported;
public readonly link: FsCallbackApi['link'] = notSupported;
public readonly cp: FsCallbackApi['cp'] = notImplemented;
public readonly lutimes: FsCallbackApi['lutimes'] = notImplemented;
public readonly openAsBlob: FsCallbackApi['openAsBlob'] = notImplemented;
public readonly opendir: FsCallbackApi['opendir'] = notImplemented;
public readonly readv: FsCallbackApi['readv'] = notImplemented;
public readonly statfs: FsCallbackApi['statfs'] = notImplemented;

/**
* @todo Watchers could be implemented in the future on top of `FileSystemObserver`,
Expand All @@ -804,6 +808,9 @@ export class FsaNodeFs extends FsaNodeCore implements FsCallbackApi, FsSynchrono
public readonly unwatchFile: FsCallbackApi['unwatchFile'] = notSupported;
public readonly watch: FsCallbackApi['watch'] = notSupported;

public readonly symlink: FsCallbackApi['symlink'] = notSupported;
public readonly link: FsCallbackApi['link'] = notSupported;

// --------------------------------------------------------- FsSynchronousApi

public readonly statSync: FsSynchronousApi['statSync'] = (
Expand Down Expand Up @@ -1073,7 +1080,9 @@ export class FsaNodeFs extends FsaNodeCore implements FsCallbackApi, FsSynchrono
public readonly lutimesSync: FsSynchronousApi['lutimesSync'] = noop;

public readonly cpSync: FsSynchronousApi['cpSync'] = notImplemented;
public readonly opendirSync: FsSynchronousApi['opendirSync'] = notImplemented;
public readonly statfsSync: FsSynchronousApi['statfsSync'] = notImplemented;
public readonly readvSync: FsSynchronousApi['readvSync'] = notImplemented;

public readonly symlinkSync: FsSynchronousApi['symlinkSync'] = notSupported;
public readonly linkSync: FsSynchronousApi['linkSync'] = notSupported;
Expand Down
129 changes: 74 additions & 55 deletions src/node/types/callback.ts → src/node/types/FsCallbackApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,35 +2,6 @@ import type * as misc from './misc';
import type * as opts from './options';

export interface FsCallbackApi {
open(path: misc.PathLike, flags: misc.TFlags, callback: misc.TCallback<number>);
open(path: misc.PathLike, flags: misc.TFlags, mode: misc.TMode, callback: misc.TCallback<number>);
close(fd: number, callback: misc.TCallback<void>): void;
read(
fd: number,
buffer: Buffer | ArrayBufferView | DataView,
offset: number,
length: number,
position: number,
callback: (err?: Error | null, bytesRead?: number, buffer?: Buffer | ArrayBufferView | DataView) => void,
): void;
readFile(id: misc.TFileId, callback: misc.TCallback<misc.TDataOut>);
readFile(id: misc.TFileId, options: opts.IReadFileOptions | string, callback: misc.TCallback<misc.TDataOut>);
copyFile(src: misc.PathLike, dest: misc.PathLike, callback: misc.TCallback<void>);
copyFile(src: misc.PathLike, dest: misc.PathLike, flags: misc.TFlagsCopy, callback: misc.TCallback<void>);
link(existingPath: misc.PathLike, newPath: misc.PathLike, callback: misc.TCallback<void>): void;
unlink(path: misc.PathLike, callback: misc.TCallback<void>): void;
symlink(target: misc.PathLike, path: misc.PathLike, callback: misc.TCallback<void>);
symlink(target: misc.PathLike, path: misc.PathLike, type: misc.symlink.Type, callback: misc.TCallback<void>);
realpath(path: misc.PathLike, callback: misc.TCallback<misc.TDataOut>);
realpath(path: misc.PathLike, options: opts.IRealpathOptions | string, callback: misc.TCallback<misc.TDataOut>);
lstat(path: misc.PathLike, callback: misc.TCallback<misc.IStats>): void;
lstat(path: misc.PathLike, options: opts.IStatOptions, callback: misc.TCallback<misc.IStats>): void;
stat(path: misc.PathLike, callback: misc.TCallback<misc.IStats>): void;
stat(path: misc.PathLike, options: opts.IStatOptions, callback: misc.TCallback<misc.IStats>): void;
fstat(fd: number, callback: misc.TCallback<misc.IStats>): void;
fstat(fd: number, options: opts.IFStatOptions, callback: misc.TCallback<misc.IStats>): void;
rename(oldPath: misc.PathLike, newPath: misc.PathLike, callback: misc.TCallback<void>): void;
exists(path: misc.PathLike, callback: (exists: boolean) => void): void;
access(path: misc.PathLike, callback: misc.TCallback<void>);
access(path: misc.PathLike, mode: number, callback: misc.TCallback<void>);
appendFile(id: misc.TFileId, data: misc.TData, callback: misc.TCallback<void>);
Expand All @@ -40,22 +11,36 @@ export interface FsCallbackApi {
options: opts.IAppendFileOptions | string,
callback: misc.TCallback<void>,
);
readdir(path: misc.PathLike, callback: misc.TCallback<misc.TDataOut[] | misc.IDirent[]>);
readdir(
path: misc.PathLike,
options: opts.IReaddirOptions | string,
callback: misc.TCallback<misc.TDataOut[] | misc.IDirent[]>,
);
readlink(path: misc.PathLike, callback: misc.TCallback<misc.TDataOut>);
readlink(path: misc.PathLike, options: opts.IOptions, callback: misc.TCallback<misc.TDataOut>);
fsync(fd: number, callback: misc.TCallback<void>): void;
chmod(path: misc.PathLike, mode: misc.TMode, callback: misc.TCallback<void>): void;
chown(path: misc.PathLike, uid: number, gid: number, callback: misc.TCallback<void>): void;
close(fd: number, callback: misc.TCallback<void>): void;
copyFile(src: misc.PathLike, dest: misc.PathLike, callback: misc.TCallback<void>);
copyFile(src: misc.PathLike, dest: misc.PathLike, flags: misc.TFlagsCopy, callback: misc.TCallback<void>);
cp(src: string | URL, dest: string | URL, callback: misc.TCallback<void>);
cp(src: string | URL, dest: string | URL, options: opts.ICpOptions, callback: misc.TCallback<void>);
createReadStream(path: misc.PathLike, options?: opts.IReadStreamOptions | string): misc.IReadStream;
createWriteStream(path: misc.PathLike, options?: opts.IWriteStreamOptions | string): misc.IWriteStream;
exists(path: misc.PathLike, callback: (exists: boolean) => void): void;
fchmod(fd: number, mode: misc.TMode, callback: misc.TCallback<void>): void;
fchown(fd: number, uid: number, gid: number, callback: misc.TCallback<void>): void;
fdatasync(fd: number, callback: misc.TCallback<void>): void;
fsync(fd: number, callback: misc.TCallback<void>): void;
fstat(fd: number, callback: misc.TCallback<misc.IStats>): void;
fstat(fd: number, options: opts.IFStatOptions, callback: misc.TCallback<misc.IStats>): void;
ftruncate(fd: number, callback: misc.TCallback<void>);
ftruncate(fd: number, len: number, callback: misc.TCallback<void>);
truncate(id: misc.PathLike, callback: misc.TCallback<void>);
truncate(id: misc.PathLike, len: number, callback: misc.TCallback<void>);
futimes(fd: number, atime: misc.TTime, mtime: misc.TTime, callback: misc.TCallback<void>): void;
utimes(path: misc.PathLike, atime: misc.TTime, mtime: misc.TTime, callback: misc.TCallback<void>): void;
lchmod(path: misc.PathLike, mode: misc.TMode, callback: misc.TCallback<void>): void;
lchown(path: misc.PathLike, uid: number, gid: number, callback: misc.TCallback<void>): void;
lutimes(
path: misc.PathLike,
atime: number | string | Date,
mtime: number | string | Date,
callback: misc.TCallback<void>,
): void;
link(existingPath: misc.PathLike, newPath: misc.PathLike, callback: misc.TCallback<void>): void;
lstat(path: misc.PathLike, callback: misc.TCallback<misc.IStats>): void;
lstat(path: misc.PathLike, options: opts.IStatOptions, callback: misc.TCallback<misc.IStats>): void;
mkdir(path: misc.PathLike, callback: misc.TCallback<void>);
mkdir(
path: misc.PathLike,
Expand All @@ -66,30 +51,64 @@ export interface FsCallbackApi {
mkdir(path: misc.PathLike, mode: misc.TMode | opts.IMkdirOptions, callback: misc.TCallback<string>);
mkdtemp(prefix: string, callback: misc.TCallback<string>): void;
mkdtemp(prefix: string, options: opts.IOptions, callback: misc.TCallback<string>);
open(path: misc.PathLike, flags: misc.TFlags, callback: misc.TCallback<number>);
open(path: misc.PathLike, flags: misc.TFlags, mode: misc.TMode, callback: misc.TCallback<number>);
openAsBlob(path: misc.PathLike, options?: opts.IOpenAsBlobOptions): Promise<Blob>;
opendir(path: misc.PathLike, options: opts.IOpendirOptions, callback: misc.TCallback<misc.IDir>): void;
read(
fd: number,
buffer: Buffer | ArrayBufferView | DataView,
offset: number,
length: number,
position: number,
callback: (err?: Error | null, bytesRead?: number, buffer?: Buffer | ArrayBufferView | DataView) => void,
): void;
readdir(path: misc.PathLike, callback: misc.TCallback<misc.TDataOut[] | misc.IDirent[]>);
readdir(
path: misc.PathLike,
options: opts.IReaddirOptions | string,
callback: misc.TCallback<misc.TDataOut[] | misc.IDirent[]>,
);
readFile(id: misc.TFileId, callback: misc.TCallback<misc.TDataOut>);
readFile(id: misc.TFileId, options: opts.IReadFileOptions | string, callback: misc.TCallback<misc.TDataOut>);
readlink(path: misc.PathLike, callback: misc.TCallback<misc.TDataOut>);
readlink(path: misc.PathLike, options: opts.IOptions, callback: misc.TCallback<misc.TDataOut>);
readv(fd: number, buffers: ArrayBufferView[], callback: misc.TCallback2<number, ArrayBufferView[]>): void;
readv(
fd: number,
buffers: ArrayBufferView[],
position: number | null,
callback: misc.TCallback2<number, ArrayBufferView[]>,
): void;
realpath(path: misc.PathLike, callback: misc.TCallback<misc.TDataOut>);
realpath(path: misc.PathLike, options: opts.IRealpathOptions | string, callback: misc.TCallback<misc.TDataOut>);
rename(oldPath: misc.PathLike, newPath: misc.PathLike, callback: misc.TCallback<void>): void;
rmdir(path: misc.PathLike, callback: misc.TCallback<void>);
rmdir(path: misc.PathLike, options: opts.IRmdirOptions, callback: misc.TCallback<void>);
rm(path: misc.PathLike, callback: misc.TCallback<void>): void;
rm(path: misc.PathLike, options: opts.IRmOptions, callback: misc.TCallback<void>): void;
fchmod(fd: number, mode: misc.TMode, callback: misc.TCallback<void>): void;
chmod(path: misc.PathLike, mode: misc.TMode, callback: misc.TCallback<void>): void;
lchmod(path: misc.PathLike, mode: misc.TMode, callback: misc.TCallback<void>): void;
fchown(fd: number, uid: number, gid: number, callback: misc.TCallback<void>): void;
chown(path: misc.PathLike, uid: number, gid: number, callback: misc.TCallback<void>): void;
lchown(path: misc.PathLike, uid: number, gid: number, callback: misc.TCallback<void>): void;
watchFile(path: misc.PathLike, listener: (curr: misc.IStats, prev: misc.IStats) => void): misc.IStatWatcher;
watchFile(
path: misc.PathLike,
options: opts.IWatchFileOptions,
listener: (curr: misc.IStats, prev: misc.IStats) => void,
): misc.IStatWatcher;
stat(path: misc.PathLike, callback: misc.TCallback<misc.IStats>): void;
stat(path: misc.PathLike, options: opts.IStatOptions, callback: misc.TCallback<misc.IStats>): void;
statfs(path: misc.PathLike, callback: misc.TCallback<misc.IStatFs>): void;
statfs(path: misc.PathLike, options: opts.IStatOptions, callback: misc.TCallback<misc.IStatFs>): void;
symlink(target: misc.PathLike, path: misc.PathLike, callback: misc.TCallback<void>);
symlink(target: misc.PathLike, path: misc.PathLike, type: misc.symlink.Type, callback: misc.TCallback<void>);
truncate(id: misc.PathLike, callback: misc.TCallback<void>);
truncate(id: misc.PathLike, len: number, callback: misc.TCallback<void>);
unlink(path: misc.PathLike, callback: misc.TCallback<void>): void;
unwatchFile(path: misc.PathLike, listener?: (curr: misc.IStats, prev: misc.IStats) => void): void;
createReadStream(path: misc.PathLike, options?: opts.IReadStreamOptions | string): misc.IReadStream;
createWriteStream(path: misc.PathLike, options?: opts.IWriteStreamOptions | string): misc.IWriteStream;
utimes(path: misc.PathLike, atime: misc.TTime, mtime: misc.TTime, callback: misc.TCallback<void>): void;
watch(
path: misc.PathLike,
options?: opts.IWatchOptions | string,
listener?: (eventType: string, filename: string) => void,
): misc.IFSWatcher;
watchFile(path: misc.PathLike, listener: (curr: misc.IStats, prev: misc.IStats) => void): misc.IStatWatcher;
watchFile(
path: misc.PathLike,
options: opts.IWatchFileOptions,
listener: (curr: misc.IStats, prev: misc.IStats) => void,
): misc.IStatWatcher;
write(fd: number, buffer: Buffer | ArrayBufferView | DataView, callback: (...args) => void);
write(fd: number, buffer: Buffer | ArrayBufferView | DataView, offset: number, callback: (...args) => void);
write(
Expand Down
4 changes: 3 additions & 1 deletion src/node/types/FsSynchronousApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export interface FsSynchronousApi {
mkdirSync(path: misc.PathLike, options?: misc.TMode | opts.IMkdirOptions): string | undefined;
mkdtempSync(prefix: string, options?: opts.IOptions): misc.TDataOut;
openSync(path: misc.PathLike, flags: misc.TFlags, mode?: misc.TMode): number;
opendirSync(path: misc.PathLike, options?: opts.IOpendirOptions): misc.IDir;
readdirSync(path: misc.PathLike, options?: opts.IReaddirOptions | string): misc.TDataOut[] | misc.IDirent[];
readlinkSync(path: misc.PathLike, options?: opts.IOptions): misc.TDataOut;
readSync(
Expand All @@ -45,6 +46,7 @@ export interface FsSynchronousApi {
position: number,
): number;
readFileSync(file: misc.TFileId, options?: opts.IReadFileOptions | string): misc.TDataOut;
readvSync(fd: number, buffers: ArrayBufferView[], position?: number | null): number;
realpathSync(path: misc.PathLike, options?: opts.IRealpathOptions | string): misc.TDataOut;
renameSync(oldPath: misc.PathLike, newPath: misc.PathLike): void;
rmdirSync(path: misc.PathLike, options?: opts.IRmdirOptions): void;
Expand All @@ -56,7 +58,7 @@ export interface FsSynchronousApi {
statSync(path: misc.PathLike, options: { throwIfNoEntry: false }): misc.IStats<number> | undefined;
statSync(path: misc.PathLike, options: { throwIfNoEntry?: true }): misc.IStats<number>;
statSync(path: misc.PathLike): misc.IStats<number>;
statfsSync(path: misc.PathLike, options?: opts.IStafsOptions): void;
statfsSync(path: misc.PathLike, options?: opts.IStafsOptions): misc.IStatFs;
symlinkSync(target: misc.PathLike, path: misc.PathLike, type?: misc.symlink.Type): void;
truncateSync(id: misc.TFileId, len?: number): void;
unlinkSync(path: misc.PathLike): void;
Expand Down
2 changes: 1 addition & 1 deletion src/node/types/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { FsSynchronousApi } from './FsSynchronousApi';
import type { FsCallbackApi } from './callback';
import type { FsCallbackApi } from './FsCallbackApi';
import type { FsPromisesApi } from './promises';

export { FsSynchronousApi, FsCallbackApi, FsPromisesApi };
Expand Down
22 changes: 22 additions & 0 deletions src/node/types/misc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export type TFlags = string | number;
export type TMode = string | number; // Mode can be a String, although docs say it should be a Number.
export type TTime = number | string | Date;
export type TCallback<TData> = (error?: IError | null, data?: TData) => void;
export type TCallback2<T1, T2> = (error: IError | null, bytesRead?: T1, buffers?: T2) => void;

export interface IError extends Error {
code?: string;
Expand Down Expand Up @@ -61,6 +62,27 @@ export interface IStats<T = TStatNumber> {
isSocket(): boolean;
}

export interface IStatFs<T = TStatNumber> {
bavail: T;
bfree: T;
blocks: T;
bsize: T;
ffree: T;
files: T;
type: T;
}

export interface IDir {
path: string;
close(): Promise<void>;
close(callback?: (err?: Error) => void): void;
closeSync(): void;
read(): Promise<IDirent | null>;
read(callback?: (err: Error | null, dir?: IDirent | null) => void): void;
readSync(): IDirent | null;
[Symbol.asyncIterator](): AsyncIterableIterator<IDirent>;
}

export interface IDirent {
name: TDataOut;
isDirectory(): boolean;
Expand Down
16 changes: 16 additions & 0 deletions src/node/types/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,3 +134,19 @@ export interface IStafsOptions {
/** Whether the numeric values in the returned `StatFs` object should be bigint. */
bigint?: boolean;
}

export interface IOpenAsBlobOptions {
/** An optional mime type for the blob. */
type?: string;
}

export interface IOpendirOptions extends IOptions {
/**
* Number of directory entries that are buffered internally when reading from
* the directory. Higher values lead to better performance but higher memory
* usage. Default: 32.
*/
bufferSize?: number;
/** Default: false. */
recursive?: boolean;
}
17 changes: 10 additions & 7 deletions src/volume.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { TEncodingExtended, TDataOut, strToEncoding, ENCODING_UTF8 } from './enc
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/callback';
import { FsCallbackApi, WritevCallback } from './node/types/FsCallbackApi';
import { createPromisesApi } from './node/promises';
import { ERRSTR, FLAGS, MODE } from './node/constants';
import {
Expand Down Expand Up @@ -903,12 +903,6 @@ export class Volume implements FsCallbackApi {
});
}

writev(fd: number, buffers: ArrayBufferView[], callback: WritevCallback): void;
writev(fd: number, buffers: ArrayBufferView[], position: number | null, callback: WritevCallback): void;
writev(fd: number, buffers: ArrayBufferView[], a, b?): void {
throw new Error('not implemented');
}

private writeFileBase(id: TFileId, buf: Buffer, flagsNum: number, modeNum: number) {
// console.log('writeFileBase', id, buf, flagsNum, modeNum);
// const node = this.getNodeByIdOrCreate(id, flagsNum, modeNum);
Expand Down Expand Up @@ -1884,6 +1878,15 @@ export class Volume implements FsCallbackApi {
public lutimesSync: FsSynchronousApi['lutimesSync'] = notImplemented;
public statfsSync: FsSynchronousApi['statfsSync'] = notImplemented;
public writevSync: FsSynchronousApi['writevSync'] = notImplemented;
public readvSync: FsSynchronousApi['readvSync'] = notImplemented;

public cp: FsCallbackApi['cp'] = notImplemented;
public lutimes: FsCallbackApi['lutimes'] = notImplemented;
public statfs: FsCallbackApi['statfs'] = notImplemented;
public writev: FsCallbackApi['writev'] = notImplemented;
public readv: FsCallbackApi['readv'] = notImplemented;
public openAsBlob: FsCallbackApi['openAsBlob'] = notImplemented;
public opendir: FsCallbackApi['opendir'] = notImplemented;
}

function emitStop(self) {
Expand Down

0 comments on commit 956533a

Please sign in to comment.