diff --git a/src/services/Fs.ts b/src/services/Fs.ts index d64d1daa..759023c9 100644 --- a/src/services/Fs.ts +++ b/src/services/Fs.ts @@ -16,8 +16,8 @@ export function registerFs(fs: Fs): void { } export interface FileID { - ino: number - dev: number + ino: bigint + dev: bigint } export interface FileDescriptor { @@ -71,7 +71,7 @@ export const ExeMaskUser = 0o0100 export type FileType = 'exe' | 'img' | 'arc' | 'snd' | 'vid' | 'doc' | 'cod' | '' -export function MakeId(stats: { ino: number; dev: number }): FileID { +export function MakeId(stats: { ino: bigint; dev: bigint }): FileID { return { ino: stats.ino, dev: stats.dev, diff --git a/src/services/__tests__/Fs.test.ts b/src/services/__tests__/Fs.test.ts index 63aa870f..5a9f7a0b 100644 --- a/src/services/__tests__/Fs.test.ts +++ b/src/services/__tests__/Fs.test.ts @@ -5,8 +5,8 @@ import { MakeId, ExeMaskAll, ExeMaskGroup, ExeMaskUser, filetype, sameID, FileID describe('makeId', () => { it('should return FileID from stats', () => { const stats = { - ino: 123, - dev: 456, + ino: 123n, + dev: 456n, fullname: 'foo', } @@ -19,13 +19,13 @@ describe('makeId', () => { describe('sameID', () => { const id1: FileID = { - dev: 10, - ino: 5, + dev: 10n, + ino: 5n, } const id2: FileID = { - dev: 28, - ino: 32, + dev: 28n, + ino: 32n, } it('should return true if ino & dev are identical', () => { diff --git a/src/services/__tests__/FsSort.test.ts b/src/services/__tests__/FsSort.test.ts index b8e883a1..5d4aac50 100644 --- a/src/services/__tests__/FsSort.test.ts +++ b/src/services/__tests__/FsSort.test.ts @@ -15,8 +15,8 @@ const files: Array = [ isDir: true, readonly: false, id: { - ino: 0, - dev: 1, + ino: 0n, + dev: 1n, }, isSym: false, target: '', @@ -35,8 +35,8 @@ const files: Array = [ isDir: false, readonly: false, id: { - ino: 1, - dev: 1, + ino: 1n, + dev: 1n, }, isSym: false, target: '', @@ -55,8 +55,8 @@ const files: Array = [ isDir: false, readonly: false, id: { - ino: 2, - dev: 1, + ino: 2n, + dev: 1n, }, isSym: false, target: '', @@ -75,8 +75,8 @@ const files: Array = [ isDir: false, readonly: false, id: { - ino: 3, - dev: 1, + ino: 3n, + dev: 1n, }, isSym: false, target: '', @@ -88,24 +88,24 @@ describe('sorting methods', () => { it('sort by Name/Asc', () => { const sortMethod = getSortMethod('name', 'asc') const sorted_ids = files.sort(sortMethod).map((file) => file.id.ino) - expect(sorted_ids).toEqual([2, 0, 1, 3]) + expect(sorted_ids).toEqual([2n, 0n, 1n, 3n]) }) it('sort by Name/Desc', () => { const sortMethod = getSortMethod('name', 'desc') const sorted_ids = files.sort(sortMethod).map((file) => file.id.ino) - expect(sorted_ids).toEqual([3, 1, 0, 2]) + expect(sorted_ids).toEqual([3n, 1n, 0n, 2n]) }) it('sort by Size/Asc', () => { const sortMethod = getSortMethod('size', 'asc') const sorted_ids = files.sort(sortMethod).map((file) => file.id.ino) - expect(sorted_ids).toEqual([1, 0, 3, 2]) + expect(sorted_ids).toEqual([1n, 0n, 3n, 2n]) }) it('sort by Size/Asc', () => { const sortMethod = getSortMethod('size', 'desc') const sorted_ids = files.sort(sortMethod).map((file) => file.id.ino) - expect(sorted_ids).toEqual([2, 3, 0, 1]) + expect(sorted_ids).toEqual([2n, 3n, 0n, 1n]) }) }) diff --git a/src/services/plugins/FsFtp.ts b/src/services/plugins/FsFtp.ts index 0c066477..dc531c15 100644 --- a/src/services/plugins/FsFtp.ts +++ b/src/services/plugins/FsFtp.ts @@ -231,8 +231,8 @@ class Client { isSym: false, target: null, id: { - ino: mDate.getTime(), - dev: new Date().getTime(), + ino: BigInt(mDate.getTime()), + dev: BigInt(new Date().getTime()), }, } return file diff --git a/src/services/plugins/FsLocal.ts b/src/services/plugins/FsLocal.ts index 6892d8ab..8b992c58 100644 --- a/src/services/plugins/FsLocal.ts +++ b/src/services/plugins/FsLocal.ts @@ -187,8 +187,8 @@ export class LocalApi implements FsApi { } async isDir(path: string, transferId = -1): Promise { - const lstat = fs.lstatSync(path) - const stat = fs.statSync(path) + const lstat = fs.lstatSync(path, { bigint: true }) + const stat = fs.statSync(path, { bigint: true }) return stat.isDirectory() || lstat.isDirectory() } @@ -208,7 +208,7 @@ export class LocalApi implements FsApi { async stat(fullPath: string, transferId = -1): Promise { try { const format = path.parse(fullPath) - const stats = fs.lstatSync(fullPath) + const stats = fs.lstatSync(fullPath, { bigint: true }) const file: FileDescriptor = { dir: format.dir, fullname: format.base, @@ -217,12 +217,13 @@ export class LocalApi implements FsApi { cDate: stats.ctime, mDate: stats.mtime, bDate: stats.birthtime, - length: stats.size, - mode: stats.mode, + length: Number(stats.size), + mode: Number(stats.mode), isDir: stats.isDirectory(), readonly: false, type: - (!stats.isDirectory() && filetype(stats.mode, stats.gid, stats.uid, format.ext.toLowerCase())) || + (!stats.isDirectory() && + filetype(Number(stats.mode), Number(stats.gid), Number(stats.uid), format.ext.toLowerCase())) || '', isSym: stats.isSymbolicLink(), target: (stats.isSymbolicLink() && fs.readlinkSync(fullPath)) || null, @@ -289,16 +290,16 @@ export class LocalApi implements FsApi { static fileFromPath(fullPath: string): FileDescriptor { const format = path.parse(fullPath) let name = fullPath - let stats: Partial = null + let stats: Partial = null let targetStats = null try { // do not follow symlinks first - stats = fs.lstatSync(fullPath) + stats = fs.lstatSync(fullPath, { bigint: true }) if (stats.isSymbolicLink()) { // get link target path first name = fs.readlinkSync(fullPath) - targetStats = fs.statSync(fullPath) + targetStats = fs.statSync(fullPath, { bigint: true }) } } catch (err) { console.warn('error getting stats for', fullPath, err) @@ -310,12 +311,12 @@ export class LocalApi implements FsApi { ctime: new Date(), mtime: new Date(), birthtime: new Date(), - size: stats ? stats.size : 0, + size: stats ? stats.size : 0n, isDirectory: (): boolean => isDir, - mode: -1, + mode: -1n, isSymbolicLink: (): boolean => isSymLink, - ino: 0, - dev: 0, + ino: 0n, + dev: 0n, } } @@ -330,12 +331,13 @@ export class LocalApi implements FsApi { cDate: stats.ctime, mDate: stats.mtime, bDate: stats.birthtime, - length: stats.size, - mode: mode, + length: Number(stats.size), + mode: Number(mode), isDir: targetStats ? targetStats.isDirectory() : stats.isDirectory(), readonly: false, type: - (!(targetStats ? targetStats.isDirectory() : stats.isDirectory()) && filetype(mode, 0, 0, extension)) || + (!(targetStats ? targetStats.isDirectory() : stats.isDirectory()) && + filetype(Number(mode), 0, 0, extension)) || '', isSym: stats.isSymbolicLink(), target: (stats.isSymbolicLink() && name) || null, diff --git a/src/services/plugins/FsVirtual.ts b/src/services/plugins/FsVirtual.ts index d7dfd0e7..420cb307 100644 --- a/src/services/plugins/FsVirtual.ts +++ b/src/services/plugins/FsVirtual.ts @@ -1,13 +1,10 @@ /* eslint-disable @typescript-eslint/no-unused-vars */ import { fs, vol } from 'memfs' -import type { Stats, ReadStream } from 'fs' +import type { ReadStream, BigIntStats } from 'fs' import { Transform, TransformCallback } from 'stream' import * as path from 'path' -// import mkdir = require('mkdirp') -// import del = require('del') import { FsApi, FileDescriptor, Credentials, Fs, filetype, MakeId } from '$src/services/Fs' -// import { size } from '$src/utils/size' import { throttle } from '$src/utils/throttle' import { isWin, HOME_DIR } from '$src/utils/platform' import { VirtualWatch } from '$src/services/plugins/VirtualWatch' @@ -191,8 +188,8 @@ export class VirtualApi implements FsApi { } async isDir(path: string, transferId = -1): Promise { - const lstat = vol.lstatSync(path) - const stat = vol.statSync(path) + const lstat = vol.lstatSync(path, { bigint: true }) + const stat = vol.statSync(path, { bigint: true }) return stat.isDirectory() || lstat.isDirectory() } @@ -212,7 +209,7 @@ export class VirtualApi implements FsApi { async stat(fullPath: string, transferId = -1): Promise { try { const format = path.parse(fullPath) - const stats = vol.lstatSync(fullPath) + const stats = vol.lstatSync(fullPath, { bigint: true }) const file: FileDescriptor = { dir: format.dir, fullname: format.base, @@ -221,12 +218,13 @@ export class VirtualApi implements FsApi { cDate: stats.ctime, mDate: stats.mtime, bDate: stats.birthtime, - length: stats.size, - mode: stats.mode, + length: Number(stats.size), + mode: Number(stats.mode), isDir: stats.isDirectory(), readonly: false, type: - (!stats.isDirectory() && filetype(stats.mode, stats.gid, stats.uid, format.ext.toLowerCase())) || + (!stats.isDirectory() && + filetype(Number(stats.mode), Number(stats.gid), Number(stats.uid), format.ext.toLowerCase())) || '', isSym: stats.isSymbolicLink(), target: (stats.isSymbolicLink() && vol.readlinkSync(fullPath)) || null, @@ -291,16 +289,16 @@ export class VirtualApi implements FsApi { static fileFromPath(fullPath: string): FileDescriptor { const format = path.parse(fullPath) let name = fullPath - let stats: Partial = null + let stats: Partial = null let targetStats = null try { // do not follow symlinks first - stats = vol.lstatSync(fullPath) + stats = vol.lstatSync(fullPath, { bigint: true }) if (stats.isSymbolicLink()) { // get link target path first name = vol.readlinkSync(fullPath) as string - targetStats = vol.statSync(fullPath) + targetStats = vol.statSync(fullPath, { bigint: true }) } } catch (err) { console.warn('error getting stats for', fullPath, err) @@ -312,12 +310,12 @@ export class VirtualApi implements FsApi { ctime: new Date(), mtime: new Date(), birthtime: new Date(), - size: stats ? stats.size : 0, + size: stats ? stats.size : 0n, isDirectory: (): boolean => isDir, - mode: -1, + mode: -1n, isSymbolicLink: (): boolean => isSymLink, - ino: 0, - dev: 0, + ino: 0n, + dev: 0n, } } @@ -332,12 +330,13 @@ export class VirtualApi implements FsApi { cDate: stats.ctime, mDate: stats.mtime, bDate: stats.birthtime, - length: stats.size, - mode: mode, + length: Number(stats.size), + mode: Number(mode), isDir: targetStats ? targetStats.isDirectory() : stats.isDirectory(), readonly: false, type: - (!(targetStats ? targetStats.isDirectory() : stats.isDirectory()) && filetype(mode, 0, 0, extension)) || + (!(targetStats ? targetStats.isDirectory() : stats.isDirectory()) && + filetype(Number(mode), 0, 0, extension)) || '', isSym: stats.isSymbolicLink(), target: (stats.isSymbolicLink() && name) || null, @@ -481,7 +480,7 @@ export class VirtualApi implements FsApi { export function FolderExists(path: string): boolean { try { - return vol.existsSync(path) && vol.lstatSync(path).isDirectory() + return vol.existsSync(path) && vol.lstatSync(path, { bigint: true }).isDirectory() } catch (err) { return false }