diff --git a/package.json b/package.json index abf3a0bf..5dbc456b 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ ], "scripts": { "clean": "rimraf lib types", - "build": "tsc -p .", + "build": "tsc -p . && cpy src/*.js lib", "test": "jest", "test:coverage": "jest --coverage", "test:watch": "jest --watch", @@ -30,22 +30,23 @@ "fs-monkey": "^0.3.3" }, "devDependencies": { + "@semantic-release/changelog": "3.0.2", + "@semantic-release/git": "7.0.8", + "@semantic-release/npm": "5.1.4", "@types/jest": "23.3.14", "@types/node": "10.12.26", + "cpy-cli": "^2.0.0", + "husky": "1.3.1", "jest": "21.2.1", + "prettier": "1.16.4", + "pretty-quick": "1.10.0", "rimraf": "2.6.3", "semantic-release": "15.13.3", - "@semantic-release/changelog": "3.0.2", - "@semantic-release/npm": "5.1.4", - "@semantic-release/git": "7.0.8", "ts-jest": "23.10.5", "ts-node": "7.0.1", - "typescript": "3.3.3", - "prettier": "1.16.4", - "pretty-quick": "1.10.0", - "husky": "1.3.1", "tslint": "5.12.1", - "tslint-config-common": "1.6.0" + "tslint-config-common": "1.6.0", + "typescript": "3.3.3" }, "config": { "commitizen": { diff --git a/src/Stats.ts b/src/Stats.ts index fd5187aa..105e0593 100644 --- a/src/Stats.ts +++ b/src/Stats.ts @@ -1,25 +1,23 @@ import { Node } from './node'; import { constants } from './constants'; +import getBigInt from './getBigInt'; const { S_IFMT, S_IFDIR, S_IFREG, S_IFBLK, S_IFCHR, S_IFLNK, S_IFIFO, S_IFSOCK } = constants; -export type TStatNumber = number | BigInt; +export type TStatNumber = number | bigint; /** * Statistics about a file/directory, like `fs.Stats`. */ -export class Stats { - static build(node: Node, bigint: boolean = false) { - const stats = new Stats(); +export class Stats { + static build(node: Node, bigint: false): Stats; + static build(node: Node, bigint: true): Stats; + static build(node: Node, bigint?: boolean): Stats; + static build(node: Node, bigint: boolean = false): Stats { + const stats = new Stats(); const { uid, gid, atime, mtime, ctime } = node; - const getStatNumber = !bigint - ? number => number - : typeof BigInt === 'function' - ? BigInt - : () => { - throw new Error('BigInt is not supported in this environment.'); - }; + const getStatNumber = !bigint ? number => number : getBigInt; // Copy all values on Stats from Node, so that if Node values // change, values on Stats would still be the old ones, @@ -28,6 +26,12 @@ export class Stats { stats.uid = getStatNumber(uid); stats.gid = getStatNumber(gid); + stats.rdev = getStatNumber(0); + stats.blksize = getStatNumber(4096); + stats.ino = getStatNumber(node.ino); + stats.size = getStatNumber(node.getSize()); + stats.blocks = getStatNumber(1); + stats.atime = atime; stats.mtime = mtime; stats.ctime = ctime; @@ -39,39 +43,38 @@ export class Stats { stats.ctimeMs = ctimeMs; stats.birthtimeMs = ctimeMs; - stats.size = getStatNumber(node.getSize()); + stats.dev = getStatNumber(0); stats.mode = getStatNumber(node.mode); - stats.ino = getStatNumber(node.ino); stats.nlink = getStatNumber(node.nlink); return stats; } - uid: TStatNumber = 0; - gid: TStatNumber = 0; + uid: T; + gid: T; - rdev: TStatNumber = 0; - blksize: TStatNumber = 4096; - ino: TStatNumber = 0; - size: TStatNumber = 0; - blocks: TStatNumber = 1; + rdev: T; + blksize: T; + ino: T; + size: T; + blocks: T; - atime: Date = null; - mtime: Date = null; - ctime: Date = null; - birthtime: Date = null; + atime: Date; + mtime: Date; + ctime: Date; + birthtime: Date; - atimeMs: TStatNumber = 0.0; - mtimeMs: TStatNumber = 0.0; - ctimeMs: TStatNumber = 0.0; - birthtimeMs: TStatNumber = 0.0; + atimeMs: T; + mtimeMs: T; + ctimeMs: T; + birthtimeMs: T; - dev: TStatNumber = 0; - mode: TStatNumber = 0; - nlink: TStatNumber = 0; + dev: T; + mode: T; + nlink: T; private _checkModeProperty(property: number): boolean { - return (this.mode & S_IFMT) === property; + return (Number(this.mode) & S_IFMT) === property; } isDirectory(): boolean { diff --git a/src/__tests__/hasBigInt.js b/src/__tests__/hasBigInt.js new file mode 100644 index 00000000..29d60197 --- /dev/null +++ b/src/__tests__/hasBigInt.js @@ -0,0 +1 @@ +exports.default = typeof BigInt === 'function'; diff --git a/src/__tests__/volume.test.ts b/src/__tests__/volume.test.ts index a9fd4fe6..4f5f473c 100644 --- a/src/__tests__/volume.test.ts +++ b/src/__tests__/volume.test.ts @@ -3,10 +3,7 @@ import { Link, Node } from '../node'; import Stats from '../Stats'; import Dirent from '../Dirent'; import { Volume, filenameToSteps, StatWatcher } from '../volume'; - -// I did not find how to include '../bigint.d.ts' here! -type BigInt = number; -declare const BigInt: typeof Number; +import hasBigInt from './hasBigInt'; describe('volume', () => { describe('filenameToSteps(filename): string[]', () => { @@ -670,7 +667,7 @@ describe('volume', () => { expect(stats.isDirectory()).toBe(false); }); it('Returns file stats using BigInt', () => { - if (typeof BigInt === 'function') { + if (hasBigInt) { const stats = vol.lstatSync('/dojo.js', { bigint: true }); expect(typeof stats.ino).toBe('bigint'); } else { @@ -701,7 +698,7 @@ describe('volume', () => { expect(stats.isDirectory()).toBe(false); }); it('Returns file stats using BigInt', () => { - if (typeof BigInt === 'function') { + if (hasBigInt) { const stats = vol.statSync('/dojo.js', { bigint: true }); expect(typeof stats.ino).toBe('bigint'); } else { @@ -745,7 +742,7 @@ describe('volume', () => { }); it('Returns file stats using BigInt', () => { const fd = vol.openSync('/dojo.js', 'r'); - if (typeof BigInt === 'function') { + if (hasBigInt) { const stats = vol.fstatSync(fd, { bigint: true }); expect(typeof stats.ino).toBe('bigint'); } else { diff --git a/src/bigint.d.ts b/src/bigint.d.ts deleted file mode 100644 index 80538a01..00000000 --- a/src/bigint.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -// This definition file is here as a workaround and should be replaced -// by "esnext.bigint" library when TypeScript will support `BigInt` type. -// Track this at Microsoft/TypeScript#15096. - -type BigInt = number; -declare const BigInt: typeof Number; diff --git a/src/getBigInt.js b/src/getBigInt.js new file mode 100644 index 00000000..d6eb584f --- /dev/null +++ b/src/getBigInt.js @@ -0,0 +1,5 @@ +if (typeof BigInt === 'function') exports.default = BigInt; +else + exports.default = function BigIntNotSupported() { + throw new Error('BigInt is not supported in this environment.'); + }; diff --git a/src/node.ts b/src/node.ts index c3da55e1..6562b380 100644 --- a/src/node.ts +++ b/src/node.ts @@ -416,8 +416,8 @@ export class File { this.position = position; } - stats(): Stats { - return Stats.build(this.node); + stats(): Stats { + return Stats.build(this.node) as Stats; } write(buf: Buffer, offset: number = 0, length: number = buf.length, position?: number): number { diff --git a/src/volume.ts b/src/volume.ts index 7a3700d8..3c377c5f 100644 --- a/src/volume.ts +++ b/src/volume.ts @@ -1430,14 +1430,19 @@ export class Volume { this.wrapAsync(this.realpathBase, [pathFilename, opts.encoding], callback); } + private lstatBase(filename: string, bigint: false): Stats; + private lstatBase(filename: string, bigint: true): Stats; private lstatBase(filename: string, bigint: boolean = false): Stats { const link: Link = this.getLink(filenameToSteps(filename)); if (!link) throwError(ENOENT, 'lstat', filename); return Stats.build(link.getNode(), bigint); } + lstatSync(path: TFilePath): Stats; + lstatSync(path: TFilePath, options: { bigint: false }): Stats; + lstatSync(path: TFilePath, options: { bigint: true }): Stats; lstatSync(path: TFilePath, options?: IStatOptions): Stats { - return this.lstatBase(pathToFilename(path), getStatOptions(options).bigint); + return this.lstatBase(pathToFilename(path), getStatOptions(options).bigint as any); } lstat(path: TFilePath, callback: TCallback); @@ -1447,6 +1452,9 @@ export class Volume { this.wrapAsync(this.lstatBase, [pathToFilename(path), opts.bigint], callback); } + private statBase(filename: string): Stats; + private statBase(filename: string, bigint: false): Stats; + private statBase(filename: string, bigint: true): Stats; private statBase(filename: string, bigint: boolean = false): Stats { let link: Link = this.getLink(filenameToSteps(filename)); if (!link) throwError(ENOENT, 'stat', filename); @@ -1458,8 +1466,11 @@ export class Volume { return Stats.build(link.getNode(), bigint); } + statSync(path: TFilePath): Stats; + statSync(path: TFilePath, options: { bigint: false }): Stats; + statSync(path: TFilePath, options: { bigint: true }): Stats; statSync(path: TFilePath, options?: IStatOptions): Stats { - return this.statBase(pathToFilename(path), getStatOptions(options).bigint); + return this.statBase(pathToFilename(path), getStatOptions(options).bigint as any); } stat(path: TFilePath, callback: TCallback); @@ -1469,14 +1480,20 @@ export class Volume { this.wrapAsync(this.statBase, [pathToFilename(path), opts.bigint], callback); } + private fstatBase(fd: number): Stats; + private fstatBase(fd: number, bigint: false): Stats; + private fstatBase(fd: number, bigint: true): Stats; private fstatBase(fd: number, bigint: boolean = false): Stats { const file = this.getFileByFd(fd); if (!file) throwError(EBADF, 'fstat'); return Stats.build(file.node, bigint); } + fstatSync(fd: number): Stats; + fstatSync(fd: number, options: { bigint: false }): Stats; + fstatSync(fd: number, options: { bigint: true }): Stats; fstatSync(fd: number, options?: IStatOptions): Stats { - return this.fstatBase(fd, getStatOptions(options).bigint); + return this.fstatBase(fd, getStatOptions(options).bigint as any); } fstat(fd: number, callback: TCallback); diff --git a/tsconfig.json b/tsconfig.json index 0c648be4..d563ab4b 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -9,10 +9,6 @@ "outDir": "lib", "declaration": true }, - "include": [ - "src" - ], - "exclude": [ - "src/__tests__" - ] + "include": ["src"], + "exclude": ["src/__tests__"] }