diff --git a/src/__tests__/volume.test.ts b/src/__tests__/volume.test.ts index 278e23e32..9bc1a201f 100644 --- a/src/__tests__/volume.test.ts +++ b/src/__tests__/volume.test.ts @@ -373,6 +373,12 @@ describe('volume', () => { expect(fd).toBeGreaterThan(0); expect(oldMtime).not.toBe(newMtime); }); + it('Create new file with Uint8Array path', () => { + const path = new TextEncoder().encode('/test.txt'); + const fd = vol.openSync(path, 'w'); + expect(typeof fd).toBe('number'); + expect(fd).toBeGreaterThan(0); + }); it('Error on file not found', () => { try { vol.openSync('/non-existing-file.txt', 'r'); @@ -387,7 +393,7 @@ describe('volume', () => { throw Error('This should not throw'); } catch (err) { expect(err).toBeInstanceOf(TypeError); - expect(err.message).toBe('path must be a string or Buffer'); + expect(err.message).toBe('path must be a string, Buffer, or Uint8Array'); } }); it('Invalid flags correct error code', () => { @@ -451,7 +457,7 @@ describe('volume', () => { throw Error('This should not throw'); } catch (err) { expect(err).toBeInstanceOf(TypeError); - expect(err.message).toBe('path must be a string or Buffer'); + expect(err.message).toBe('path must be a string, Buffer, or Uint8Array'); done(); } }); diff --git a/src/__tests__/volume/__snapshots__/renameSync.test.ts.snap b/src/__tests__/volume/__snapshots__/renameSync.test.ts.snap index 60e16bdf3..e89ab86ac 100644 --- a/src/__tests__/volume/__snapshots__/renameSync.test.ts.snap +++ b/src/__tests__/volume/__snapshots__/renameSync.test.ts.snap @@ -1,7 +1,7 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`renameSync(fromPath, toPath) Throws if path is of wrong type 1`] = `"path must be a string or Buffer"`; +exports[`renameSync(fromPath, toPath) Throws if path is of wrong type 1`] = `"path must be a string, Buffer, or Uint8Array"`; -exports[`renameSync(fromPath, toPath) Throws on no params 1`] = `"path must be a string or Buffer"`; +exports[`renameSync(fromPath, toPath) Throws on no params 1`] = `"path must be a string, Buffer, or Uint8Array"`; -exports[`renameSync(fromPath, toPath) Throws on only one param 1`] = `"path must be a string or Buffer"`; +exports[`renameSync(fromPath, toPath) Throws on only one param 1`] = `"path must be a string, Buffer, or Uint8Array"`; diff --git a/src/node/constants.ts b/src/node/constants.ts index 3efb05e4e..8105c54f9 100644 --- a/src/node/constants.ts +++ b/src/node/constants.ts @@ -8,7 +8,7 @@ export const enum MODE { } export const ERRSTR = { - PATH_STR: 'path must be a string or Buffer', + PATH_STR: 'path must be a string, Buffer, or Uint8Array', // FD: 'file descriptor must be a unsigned 32-bit integer', FD: 'fd must be a file descriptor', MODE_INT: 'mode must be an int', diff --git a/src/node/types/misc.ts b/src/node/types/misc.ts index 36f5b5a04..c0d6615d0 100644 --- a/src/node/types/misc.ts +++ b/src/node/types/misc.ts @@ -1,4 +1,4 @@ -import type { PathLike, symlink } from 'fs'; +import type { PathLike as NodePathLike, symlink } from 'fs'; import type { constants } from '../../constants'; import type { EventEmitter } from 'events'; import type { TSetTimeout } from '../../setTimeoutUnref'; @@ -13,8 +13,9 @@ import type { } from './options'; import type { Readable, Writable } from 'stream'; -export { PathLike, symlink }; +export { symlink }; +export type PathLike = NodePathLike | Uint8Array; // For browser support we add Uint8Array. 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. diff --git a/src/node/util.ts b/src/node/util.ts index 09e6c682a..c49765162 100644 --- a/src/node/util.ts +++ b/src/node/util.ts @@ -72,6 +72,9 @@ function getPathFromURLPosix(url): string { } export function pathToFilename(path: misc.PathLike): string { + if (path instanceof Uint8Array) { + path = bufferFrom(path); + } if (typeof path !== 'string' && !Buffer.isBuffer(path)) { try { if (!(path instanceof require('url').URL)) throw new TypeError(ERRSTR.PATH_STR); diff --git a/src/volume.ts b/src/volume.ts index 0d941e9c2..76388256b 100644 --- a/src/volume.ts +++ b/src/volume.ts @@ -58,9 +58,9 @@ import { getWriteSyncArgs, unixify, } from './node/util'; -import type { PathLike, symlink } from 'fs'; +import type { symlink } from 'fs'; +import type { PathLike } from './node/types/misc'; import type { FsPromisesApi, FsSynchronousApi } from './node/types'; -import { fsSynchronousApiList } from './node/lists/fsSynchronousApiList'; import { Dir } from './Dir'; const resolveCrossPlatform = pathModule.resolve; @@ -1320,7 +1320,6 @@ export class Volume implements FsCallbackApi, FsSynchronousApi { } private realpathBase(filename: string, encoding: TEncodingExtended | undefined): TDataOut { - debugger; const realLink = this.getResolvedLinkOrThrow(filename, 'realpath'); return strToEncoding(realLink.getPath() || '/', encoding);