Skip to content

Commit

Permalink
feat: 🎸 implement realpath() method
Browse files Browse the repository at this point in the history
  • Loading branch information
streamich committed Jun 20, 2023
1 parent ce5dd5e commit 458a7b2
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 28 deletions.
27 changes: 10 additions & 17 deletions src/fsa-to-node/FsaNodeFs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
optsAndCbGenerator,
getAppendFileOptsAndCb,
getStatOptsAndCb,
getRealpathOptsAndCb,
} from '../node/options';
import {
createError,
Expand Down Expand Up @@ -279,26 +280,17 @@ export class FsaNodeFs implements FsCallbackApi, FsCommonObjects {
);
};

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>);
symlink(
target: misc.PathLike,
path: misc.PathLike,
a: misc.symlink.Type | misc.TCallback<void>,
b?: misc.TCallback<void>,
) {
throw new Error('Not implemented');
}

realpath(path: misc.PathLike, callback: misc.TCallback<misc.TDataOut>);
realpath(path: misc.PathLike, options: opts.IRealpathOptions | string, callback: misc.TCallback<misc.TDataOut>);
realpath(
public readonly realpath: FsCallbackApi['realpath'] = (
path: misc.PathLike,
a: misc.TCallback<misc.TDataOut> | opts.IRealpathOptions | string,
b?: misc.TCallback<misc.TDataOut>,
) {
throw new Error('Not implemented');
}
): void => {
const [opts, callback] = getRealpathOptsAndCb(a, b);
let pathFilename = pathToFilename(path);
if (pathFilename[0] !== FsaToNodeConstants.Separator)
pathFilename = FsaToNodeConstants.Separator + pathFilename;
callback(null, strToEncoding(pathFilename, opts.encoding));
};

public readonly lstat: FsCallbackApi['lstat'] = (
path: misc.PathLike,
Expand Down Expand Up @@ -702,6 +694,7 @@ export class FsaNodeFs implements FsCallbackApi, FsCommonObjects {
callback(null);
}

public readonly symlink: FsCallbackApi['symlink'] = notSupported;
public readonly link: FsCallbackApi['link'] = notSupported;
public readonly watchFile: FsCallbackApi['watchFile'] = notSupported;
public readonly unwatchFile: FsCallbackApi['unwatchFile'] = notSupported;
Expand Down
8 changes: 8 additions & 0 deletions src/fsa-to-node/__tests__/FsaNodeFs.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -539,3 +539,11 @@ describe('.fstat()', () => {
expect(stats.isFile()).toBe(true);
});
});

describe('.realpath()', () => {
test('returns file path', async () => {
const { fs } = setup({ folder: { file: 'test' }, 'empty-folder': null, 'f.html': 'test' });
const path = await fs.promises.realpath('folder/file');
expect(path).toBe('/folder/file');
});
});
4 changes: 4 additions & 0 deletions src/node/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,3 +98,7 @@ export const getStatOptsAndCb: (
callback?: misc.TCallback<misc.IStats>,
) => [opts.IStatOptions, misc.TCallback<misc.IStats>] = (options, callback?) =>
typeof options === 'function' ? [getStatOptions(), options] : [getStatOptions(options), validateCallback(callback)];

const realpathDefaults: opts.IReadFileOptions = optsDefaults;
export const getRealpathOptions = optsGenerator<opts.IRealpathOptions>(realpathDefaults);
export const getRealpathOptsAndCb = optsAndCbGenerator<opts.IRealpathOptions, misc.TDataOut>(getRealpathOptions);
16 changes: 5 additions & 11 deletions src/volume.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ import {
getAppendFileOpts,
getStatOptsAndCb,
getStatOptions,
getRealpathOptsAndCb,
getRealpathOptions,
} from './node/options';
import {
validateCallback,
Expand Down Expand Up @@ -128,14 +130,6 @@ const getWriteFileOptions = optsGenerator<IWriteFileOptions>(writeFileDefaults);
// Options for `fs.appendFile` and `fs.appendFileSync`
export interface IAppendFileOptions extends opts.IFileOptions {}

// Options for `fs.realpath` and `fs.realpathSync`
export interface IRealpathOptions {
encoding?: TEncodingExtended;
}
const realpathDefaults: opts.IReadFileOptions = optsDefaults;
const getRealpathOptions = optsGenerator<IRealpathOptions>(realpathDefaults);
const getRealpathOptsAndCb = optsAndCbGenerator<IRealpathOptions, TDataOut>(getRealpathOptions);

// Options for `fs.watchFile`
export interface IWatchFileOptions {
persistent?: boolean;
Expand Down Expand Up @@ -1201,13 +1195,13 @@ export class Volume {
return strToEncoding(realLink.getPath() || '/', encoding);
}

realpathSync(path: PathLike, options?: IRealpathOptions | string): TDataOut {
realpathSync(path: PathLike, options?: opts.IRealpathOptions | string): TDataOut {
return this.realpathBase(pathToFilename(path), getRealpathOptions(options).encoding);
}

realpath(path: PathLike, callback: TCallback<TDataOut>);
realpath(path: PathLike, options: IRealpathOptions | string, callback: TCallback<TDataOut>);
realpath(path: PathLike, a: TCallback<TDataOut> | IRealpathOptions | string, b?: TCallback<TDataOut>) {
realpath(path: PathLike, options: opts.IRealpathOptions | string, callback: TCallback<TDataOut>);
realpath(path: PathLike, a: TCallback<TDataOut> | opts.IRealpathOptions | string, b?: TCallback<TDataOut>) {
const [opts, callback] = getRealpathOptsAndCb(a, b);
const pathFilename = pathToFilename(path);
this.wrapAsync(this.realpathBase, [pathFilename, opts.encoding], callback);
Expand Down

0 comments on commit 458a7b2

Please sign in to comment.