Skip to content

Commit

Permalink
feat: 🎸 create Node fs api tyeps
Browse files Browse the repository at this point in the history
  • Loading branch information
streamich committed Jun 20, 2023
1 parent e96bb17 commit 27fd08a
Show file tree
Hide file tree
Showing 6 changed files with 431 additions and 0 deletions.
102 changes: 102 additions & 0 deletions src/node/types/callback.ts
@@ -0,0 +1,102 @@
import type { PathLike, symlink } from 'fs';
import type * as misc from './misc';
import type * as opts from './options';

export interface FsCallbackApi {
open(path: PathLike, flags: misc.TFlags, /* ... */ callback: misc.TCallback<number>);
open(path: 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>);
write(fd: number, buffer: Buffer | ArrayBufferView | DataView, callback: (...args) => void);
write(fd: number, buffer: Buffer | ArrayBufferView | DataView, offset: number, callback: (...args) => void);
write(
fd: number,
buffer: Buffer | ArrayBufferView | DataView,
offset: number,
length: number,
callback: (...args) => void,
);
write(
fd: number,
buffer: Buffer | ArrayBufferView | DataView,
offset: number,
length: number,
position: number,
callback: (...args) => void,
);
write(fd: number, str: string, callback: (...args) => void);
write(fd: number, str: string, position: number, callback: (...args) => void);
write(fd: number, str: string, position: number, encoding: BufferEncoding, callback: (...args) => void);
writeFile(id: misc.TFileId, data: misc.TData, callback: misc.TCallback<void>);
writeFile(id: misc.TFileId, data: misc.TData, options: opts.IWriteFileOptions | string, callback: misc.TCallback<void>);
copyFile(src: PathLike, dest: PathLike, callback: misc.TCallback<void>);
copyFile(src: PathLike, dest: PathLike, flags: misc.TFlagsCopy, callback: misc.TCallback<void>);
link(existingPath: PathLike, newPath: PathLike, callback: misc.TCallback<void>): void;
unlink(path: PathLike, callback: misc.TCallback<void>): void;
symlink(target: PathLike, path: PathLike, callback: misc.TCallback<void>);
symlink(target: PathLike, path: PathLike, type: symlink.Type, callback: misc.TCallback<void>);
realpath(path: PathLike, callback: misc.TCallback<misc.TDataOut>);
realpath(path: PathLike, options: opts.IRealpathOptions | string, callback: misc.TCallback<misc.TDataOut>);
lstat(path: PathLike, callback: misc.TCallback<misc.IStats>): void;
lstat(path: PathLike, options: opts.IStatOptions, callback: misc.TCallback<misc.IStats>): void;
stat(path: PathLike, callback: misc.TCallback<misc.IStats>): void;
stat(path: 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: PathLike, newPath: PathLike, callback: misc.TCallback<void>): void;
exists(path: PathLike, callback: (exists: boolean) => void): void;
access(path: PathLike, callback: misc.TCallback<void>);
access(path: PathLike, mode: number, callback: misc.TCallback<void>);
appendFile(id: misc.TFileId, data: misc.TData, callback: misc.TCallback<void>);
appendFile(id: misc.TFileId, data: misc.TData, options: opts.IAppendFileOptions | string, callback: misc.TCallback<void>);
readdir(path: PathLike, callback: misc.TCallback<misc.TDataOut[] | misc.IDirent[]>);
readdir(path: PathLike, options: opts.IReaddirOptions | string, callback: misc.TCallback<misc.TDataOut[] | misc.IDirent[]>);
readlink(path: PathLike, callback: misc.TCallback<misc.TDataOut>);
readlink(path: PathLike, options: opts.IOptions, callback: misc.TCallback<misc.TDataOut>);
fsyncSync(fd: number): void;
fsync(fd: number, callback: misc.TCallback<void>): void;
fdatasync(fd: number, callback: misc.TCallback<void>): void;
ftruncate(fd: number, callback: misc.TCallback<void>);
ftruncate(fd: number, len: number, callback: misc.TCallback<void>);
truncate(id: misc.TFileId, callback: misc.TCallback<void>);
truncate(id: misc.TFileId, len: number, callback: misc.TCallback<void>);
futimes(fd: number, atime: misc.TTime, mtime: misc.TTime, callback: misc.TCallback<void>): void;
utimes(path: PathLike, atime: misc.TTime, mtime: misc.TTime, callback: misc.TCallback<void>): void;
mkdir(path: PathLike, callback: misc.TCallback<void>);
mkdir(path: PathLike, mode: misc.TMode | (opts.IMkdirOptions & { recursive?: false }), callback: misc.TCallback<void>);
mkdir(path: PathLike, mode: opts.IMkdirOptions & { recursive: true }, callback: misc.TCallback<string>);
mkdir(path: PathLike, mode: misc.TMode | opts.IMkdirOptions, callback: misc.TCallback<string>);
mkdirp(path: PathLike, callback: misc.TCallback<string>);
mkdirp(path: PathLike, mode: misc.TMode, callback: misc.TCallback<string>);
mkdtemp(prefix: string, callback: misc.TCallback<void>): void;
mkdtemp(prefix: string, options: opts.IOptions, callback: misc.TCallback<void>);
rmdir(path: PathLike, callback: misc.TCallback<void>);
rmdir(path: PathLike, options: opts.IRmdirOptions, callback: misc.TCallback<void>);
rm(path: PathLike, callback: misc.TCallback<void>): void;
rm(path: PathLike, options: opts.IRmOptions, callback: misc.TCallback<void>): void;
fchmod(fd: number, mode: misc.TMode, callback: misc.TCallback<void>): void;
chmod(path: PathLike, mode: misc.TMode, callback: misc.TCallback<void>): void;
lchmod(path: PathLike, mode: misc.TMode, callback: misc.TCallback<void>): void;
fchown(fd: number, uid: number, gid: number, callback: misc.TCallback<void>): void;
chown(path: PathLike, uid: number, gid: number, callback: misc.TCallback<void>): void;
lchown(path: PathLike, uid: number, gid: number, callback: misc.TCallback<void>): void;
watchFile(path: PathLike, listener: (curr: misc.IStats, prev: misc.IStats) => void): misc.IStatWatcher;
watchFile(path: PathLike, options: opts.IWatchFileOptions, listener: (curr: misc.IStats, prev: misc.IStats) => void): misc.IStatWatcher;
unwatchFile(path: PathLike, listener?: (curr: misc.IStats, prev: misc.IStats) => void): void;
createReadStream(path: PathLike, options?: opts.IReadStreamOptions | string): misc.IReadStream;
createWriteStream(path: PathLike, options?: opts.IWriteStreamOptions | string): misc.IWriteStream;
watch(
path: PathLike,
options?: opts.IWatchOptions | string,
listener?: (eventType: string, filename: string) => void,
): misc.IFSWatcher;
}
7 changes: 7 additions & 0 deletions src/node/types/index.ts
@@ -0,0 +1,7 @@
import type {FsCallbackApi} from "./callback";
import type {FsPromisesApi} from "./promises";
import type {FsSynchronousApi} from "./sync";

export interface FsApi extends FsCallbackApi, FsSynchronousApi {
promises: FsPromisesApi;
}
136 changes: 136 additions & 0 deletions src/node/types/misc.ts
@@ -0,0 +1,136 @@
import type {PathLike, symlink} from 'fs';
import type {constants} from '../../constants';
import type {EventEmitter} from 'events';
import type {TSetTimeout} from '../../setTimeoutUnref';
import type {IAppendFileOptions, IReadFileOptions, IReadStreamOptions, IStatOptions, IWriteFileOptions, IWriteStreamOptions} from './options';
import type {Readable, Writable} from 'stream';

export {PathLike, symlink};

export type TDataOut = string | Buffer; // Data formats we give back to users.
export type TEncodingExtended = BufferEncoding | 'buffer';
export type TFileId = PathLike | number; // Number is used as a file descriptor.
export type TData = TDataOut | ArrayBufferView | DataView; // Data formats users can give us.
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 interface IError extends Error {
code?: string;
}

export type TFlagsCopy =
| typeof constants.COPYFILE_EXCL
| typeof constants.COPYFILE_FICLONE
| typeof constants.COPYFILE_FICLONE_FORCE;

export type TStatNumber = number | bigint;

export interface IStats<T = TStatNumber> {
uid: T;
gid: T;
rdev: T;
blksize: T;
ino: T;
size: T;
blocks: T;
atime: Date;
mtime: Date;
ctime: Date;
birthtime: Date;
atimeMs: T;
mtimeMs: T;
ctimeMs: T;
birthtimeMs: T;
dev: T;
mode: T;
nlink: T;
isDirectory(): boolean;
isFile(): boolean;
isBlockDevice(): boolean;
isCharacterDevice(): boolean;
isSymbolicLink(): boolean;
isFIFO(): boolean;
isSocket(): boolean;
}

export interface IDirent {
name: TDataOut;
isDirectory(): boolean;
isFile(): boolean;
isBlockDevice(): boolean;
isCharacterDevice(): boolean;
isSymbolicLink(): boolean;
isFIFO(): boolean;
isSocket(): boolean;
}

export interface IStatWatcher extends EventEmitter {
filename: string;
interval: number;
timeoutRef?;
setTimeout: TSetTimeout;
prev: IStats;
start(path: string, persistent?: boolean, interval?: number): void;
stop(): void;
}

export interface IReadStream extends Readable {
new (path: PathLike, options: IReadStreamOptions);
open();
close(callback: TCallback<void>);
bytesRead: number;
path: string;
}

export interface IWriteStream extends Writable {
bytesWritten: number;
path: string;
new (path: PathLike, options: IWriteStreamOptions);
open();
close();
}

export interface IFSWatcher extends EventEmitter {
start(
path: PathLike,
persistent?: boolean,
recursive?: boolean,
encoding?: BufferEncoding,
): void;
close(): void;
}

export interface IFileHandle {
fd: number;
appendFile(data: TData, options?: IAppendFileOptions | string): Promise<void>;
chmod(mode: TMode): Promise<void>;
chown(uid: number, gid: number): Promise<void>;
close(): Promise<void>;
datasync(): Promise<void>;
read(buffer: Buffer | Uint8Array, offset: number, length: number, position: number): Promise<TFileHandleReadResult>;
readFile(options?: IReadFileOptions | string): Promise<TDataOut>;
stat(options?: IStatOptions): Promise<IStats>;
truncate(len?: number): Promise<void>;
utimes(atime: TTime, mtime: TTime): Promise<void>;
write(
buffer: Buffer | ArrayBufferView | DataView,
offset?: number,
length?: number,
position?: number,
): Promise<TFileHandleWriteResult>;
writeFile(data: TData, options?: IWriteFileOptions): Promise<void>;
}

export type TFileHandle = PathLike | IFileHandle;

export interface TFileHandleReadResult {
bytesRead: number;
buffer: Buffer | Uint8Array;
}

export interface TFileHandleWriteResult {
bytesWritten: number;
buffer: Buffer | Uint8Array;
}
85 changes: 85 additions & 0 deletions src/node/types/options.ts
@@ -0,0 +1,85 @@
import type {TEncodingExtended, TFlags, TMode} from "./misc";

export interface IOptions {
encoding?: BufferEncoding | TEncodingExtended;
}

export interface IFileOptions extends IOptions {
mode?: TMode;
flag?: TFlags;
}

export interface IWriteFileOptions extends IFileOptions {}

export interface IReadFileOptions extends IOptions {
flag?: string;
}

export interface IRealpathOptions {
encoding?: TEncodingExtended;
}

export interface IAppendFileOptions extends IFileOptions {}

export interface IStatOptions {
bigint?: boolean;
throwIfNoEntry?: boolean;
}

export interface IFStatOptions {
bigint?: boolean;
}

export interface IAppendFileOptions extends IFileOptions {}

export interface IReaddirOptions extends IOptions {
withFileTypes?: boolean;
}

export interface IMkdirOptions {
mode?: TMode;
recursive?: boolean;
}

export interface IRmdirOptions {
/** @deprecated */
recursive?: boolean;
maxRetries?: number;
retryDelay?: number;
}

export interface IRmOptions {
force?: boolean;
maxRetries?: number;
recursive?: boolean;
retryDelay?: number;
}

export interface IWatchFileOptions {
persistent?: boolean;
interval?: number;
}

export interface IReadStreamOptions {
flags?: TFlags;
encoding?: BufferEncoding;
fd?: number;
mode?: TMode;
autoClose?: boolean;
start?: number;
end?: number;
}

export interface IWriteStreamOptions {
flags?: TFlags;
defaultEncoding?: BufferEncoding;
fd?: number;
mode?: TMode;
autoClose?: boolean;
start?: number;
}

export interface IWatchOptions extends IOptions {
persistent?: boolean;
recursive?: boolean;
}
30 changes: 30 additions & 0 deletions src/node/types/promises.ts
@@ -0,0 +1,30 @@
import * as misc from "./misc";
import * as opts from "./options";

export interface FsPromisesApi {
access(path: misc.PathLike, mode?: number): Promise<void>;
appendFile(path: misc.TFileHandle, data: misc.TData, options?: opts.IAppendFileOptions | string): Promise<void>;
chmod(path: misc.PathLike, mode: misc.TMode): Promise<void>;
chown(path: misc.PathLike, uid: number, gid: number): Promise<void>;
copyFile(src: misc.PathLike, dest: misc.PathLike, flags?: misc.TFlagsCopy): Promise<void>;
lchmod(path: misc.PathLike, mode: misc.TMode): Promise<void>;
lchown(path: misc.PathLike, uid: number, gid: number): Promise<void>;
link(existingPath: misc.PathLike, newPath: misc.PathLike): Promise<void>;
lstat(path: misc.PathLike, options?: opts.IStatOptions): Promise<misc.IStats>;
mkdir(path: misc.PathLike, options?: misc.TMode | opts.IMkdirOptions): Promise<void>;
mkdtemp(prefix: string, options?: opts.IOptions): Promise<misc.TDataOut>;
open(path: misc.PathLike, flags: misc.TFlags, mode?: misc.TMode): Promise<misc.IFileHandle>;
readdir(path: misc.PathLike, options?: opts.IReaddirOptions | string): Promise<misc.TDataOut[] | misc.IDirent[]>;
readFile(id: misc.TFileHandle, options?: opts.IReadFileOptions | string): Promise<misc.TDataOut>;
readlink(path: misc.PathLike, options?: opts.IOptions): Promise<misc.TDataOut>;
realpath(path: misc.PathLike, options?: opts.IRealpathOptions | string): Promise<misc.TDataOut>;
rename(oldPath: misc.PathLike, newPath: misc.PathLike): Promise<void>;
rmdir(path: misc.PathLike, options?: opts.IRmdirOptions): Promise<void>;
rm(path: misc.PathLike, options?: opts.IRmOptions): Promise<void>;
stat(path: misc.PathLike, options?: opts.IStatOptions): Promise<misc.IStats>;
symlink(target: misc.PathLike, path: misc.PathLike, type?: misc.symlink.Type): Promise<void>;
truncate(path: misc.PathLike, len?: number): Promise<void>;
unlink(path: misc.PathLike): Promise<void>;
utimes(path: misc.PathLike, atime: misc.TTime, mtime: misc.TTime): Promise<void>;
writeFile(id: misc.TFileHandle, data: misc.TData, options?: opts.IWriteFileOptions): Promise<void>;
}

0 comments on commit 27fd08a

Please sign in to comment.