From 5ee4115ca87406158bed4b2c2419532c1e311a60 Mon Sep 17 00:00:00 2001 From: Pooya Parsa Date: Thu, 5 May 2022 22:06:14 +0200 Subject: [PATCH] feat: initial support for `fs` polyfill (#9) --- src/runtime/node/fs/_classes.ts | 16 ++++ src/runtime/node/fs/_constants.ts | 66 ++++++++++++++ src/runtime/node/fs/_fs.ts | 121 ++++++++++++++++++++++++++ src/runtime/node/fs/index.ts | 21 +++++ src/runtime/node/fs/promises/index.ts | 32 +++++++ 5 files changed, 256 insertions(+) create mode 100644 src/runtime/node/fs/_classes.ts create mode 100644 src/runtime/node/fs/_constants.ts create mode 100644 src/runtime/node/fs/_fs.ts create mode 100644 src/runtime/node/fs/index.ts create mode 100644 src/runtime/node/fs/promises/index.ts diff --git a/src/runtime/node/fs/_classes.ts b/src/runtime/node/fs/_classes.ts new file mode 100644 index 00000000..9971c6f3 --- /dev/null +++ b/src/runtime/node/fs/_classes.ts @@ -0,0 +1,16 @@ +import type fs from 'fs' +import mock from '../../mock/proxy' + +export const Dir: typeof fs.Dir = mock.__createMock__('fs.Dir') + +export const Dirent: typeof fs.Dirent = mock.__createMock__('fs.Dirent') + +export const Stats: typeof fs.Stats = mock.__createMock__('fs.Stats') + +export const ReadStream: typeof fs.ReadStream = mock.__createMock__('fs.ReadStream') + +export const WriteStream: typeof fs.WriteStream = mock.__createMock__('fs.WriteStream') + +export const FileReadStream = mock.__createMock__('fs.FileReadStream') + +export const FileWriteStream = mock.__createMock__('fs.FileWriteStream') diff --git a/src/runtime/node/fs/_constants.ts b/src/runtime/node/fs/_constants.ts new file mode 100644 index 00000000..7a937eb3 --- /dev/null +++ b/src/runtime/node/fs/_constants.ts @@ -0,0 +1,66 @@ +import type fs from 'fs' + +export const F_OK = 0 +export const R_OK = 4 +export const W_OK = 2 +export const X_OK = 1 + +export const constants: typeof fs.constants = Object.create({ + UV_FS_SYMLINK_DIR: 1, + UV_FS_SYMLINK_JUNCTION: 2, + O_RDONLY: 0, + O_WRONLY: 1, + O_RDWR: 2, + UV_DIRENT_UNKNOWN: 0, + UV_DIRENT_FILE: 1, + UV_DIRENT_DIR: 2, + UV_DIRENT_LINK: 3, + UV_DIRENT_FIFO: 4, + UV_DIRENT_SOCKET: 5, + UV_DIRENT_CHAR: 6, + UV_DIRENT_BLOCK: 7, + S_IFMT: 61440, + S_IFREG: 32768, + S_IFDIR: 16384, + S_IFCHR: 8192, + S_IFBLK: 24576, + S_IFIFO: 4096, + S_IFLNK: 40960, + S_IFSOCK: 49152, + O_CREAT: 64, + O_EXCL: 128, + UV_FS_O_FILEMAP: 0, + O_NOCTTY: 256, + O_TRUNC: 512, + O_APPEND: 1024, + O_DIRECTORY: 65536, + O_NOATIME: 262144, + O_NOFOLLOW: 131072, + O_SYNC: 1052672, + O_DSYNC: 4096, + O_DIRECT: 16384, + O_NONBLOCK: 2048, + S_IRWXU: 448, + S_IRUSR: 256, + S_IWUSR: 128, + S_IXUSR: 64, + S_IRWXG: 56, + S_IRGRP: 32, + S_IWGRP: 16, + S_IXGRP: 8, + S_IRWXO: 7, + S_IROTH: 4, + S_IWOTH: 2, + S_IXOTH: 1, + F_OK: 0, + R_OK: 4, + W_OK: 2, + X_OK: 1, + UV_FS_COPYFILE_EXCL: 1, + COPYFILE_EXCL: 1, + UV_FS_COPYFILE_FICLONE: 2, + COPYFILE_FICLONE: 2, + UV_FS_COPYFILE_FICLONE_FORCE: 4, + COPYFILE_FICLONE_FORCE: 4 +}) + diff --git a/src/runtime/node/fs/_fs.ts b/src/runtime/node/fs/_fs.ts new file mode 100644 index 00000000..0f32b540 --- /dev/null +++ b/src/runtime/node/fs/_fs.ts @@ -0,0 +1,121 @@ +import type fs from 'fs' +import { notImplemented } from '../../_internal/utils' +import * as fsp from './promises' + +interface Promisifiable { + (): any + native: Promisifiable + __promisify__: () => Promise +} + +function notImplementedAsync (name: string): Promisifiable { + const fn = notImplemented(name) as any + fn.__promisify__ = () => notImplemented(name + '.__promisify__') + fn.native = fn + return fn +} + +function callbackify (fn: (...args: any[]) => Promise) { + const fnc = function(...args: any[]) { + const cb = args.pop() + fn() + .catch((error: Error) => cb(error)) + .then((val: any) => cb(undefined, val)) + } + fnc.__promisify__ = fn + fnc.native = fnc + return fnc +} + +// Async +export const access: typeof fs.access = callbackify(fsp.access) +export const appendFile: typeof fs.appendFile = callbackify(fsp.appendFile) +export const chown: typeof fs.chown = callbackify(fsp.chown) +export const chmod: typeof fs.chmod = callbackify(fsp.chmod) +export const copyFile: typeof fs.copyFile = callbackify(fsp.copyFile) +export const cp: typeof fs.cp = callbackify(fsp.cp) +export const lchown: typeof fs.lchown = callbackify(fsp.lchown) +export const lchmod: typeof fs.lchmod = callbackify(fsp.lchmod) +export const link: typeof fs.link = callbackify(fsp.link) +export const lstat: typeof fs.lstat = callbackify(fsp.lstat) +export const lutimes: typeof fs.lutimes = callbackify(fsp.lutimes) +export const mkdir: typeof fs.mkdir = callbackify(fsp.mkdir) +export const mkdtemp: typeof fs.mkdtemp = callbackify(fsp.mkdtemp) +export const realpath: typeof fs.realpath = callbackify(fsp.realpath) +export const open: typeof fs.open = callbackify(fsp.open) +export const opendir: typeof fs.opendir = callbackify(fsp.opendir) +export const readdir: typeof fs.readdir = callbackify(fsp.readdir) +export const readFile: typeof fs.readFile = callbackify(fsp.readFile) +export const readlink: typeof fs.readlink = callbackify(fsp.readlink) +export const rename: typeof fs.rename = callbackify(fsp.rename) +export const rm: typeof fs.rm = callbackify(fsp.rm) +export const rmdir: typeof fs.rmdir = callbackify(fsp.rmdir) +export const stat: typeof fs.stat = callbackify(fsp.stat) +export const symlink: typeof fs.symlink = callbackify(fsp.symlink) +export const truncate: typeof fs.truncate = callbackify(fsp.truncate) +export const unlink: typeof fs.unlink = callbackify(fsp.unlink) +export const utimes: typeof fs.utimes = callbackify(fsp.utimes) +export const writeFile: typeof fs.writeFile = callbackify(fsp.writeFile) + +export const close: typeof fs.close = notImplementedAsync('fs.close') +export const createReadStream: typeof fs.createReadStream = notImplementedAsync('fs.createReadStream') +export const createWriteStream: typeof fs.createWriteStream = notImplementedAsync('fs.createWriteStream') +export const exists: typeof fs.exists = notImplementedAsync('fs.exists') +export const fchown: typeof fs.fchown = notImplementedAsync('fs.fchown') +export const fchmod: typeof fs.fchmod = notImplementedAsync('fs.fchmod') +export const fdatasync: typeof fs.fdatasync = notImplementedAsync('fs.fdatasync') +export const fstat: typeof fs.fstat = notImplementedAsync('fs.fstat') +export const fsync: typeof fs.fsync = notImplementedAsync('fs.fsync') +export const ftruncate: typeof fs.ftruncate = notImplementedAsync('fs.ftruncate') +export const futimes: typeof fs.futimes = notImplementedAsync('fs.futimes') +export const lstatSync: typeof fs.lstatSync = notImplementedAsync('fs.lstatSync') +export const read: typeof fs.read = notImplementedAsync('fs.read') +export const readv: typeof fs.readv = notImplementedAsync('fs.readv') +export const realpathSync: typeof fs.realpathSync = notImplementedAsync('fs.realpathSync') +export const statSync: typeof fs.statSync = notImplementedAsync('fs.statSync') +export const unwatchFile: typeof fs.unwatchFile = notImplementedAsync('fs.unwatchFile') +export const watch: typeof fs.watch = notImplementedAsync('fs.watch') +export const watchFile: typeof fs.watchFile = notImplementedAsync('fs.watchFile') +export const write: typeof fs.write = notImplementedAsync('fs.write') +export const writev: typeof fs.writev = notImplementedAsync('fs.writev') +export const _toUnixTimestamp = notImplementedAsync('fs._toUnixTimestamp') + +// Sync +export const appendFileSync: typeof fs.appendFileSync = notImplemented('fs.appendFileSync') +export const accessSync: typeof fs.accessSync = notImplemented('fs.accessSync') +export const chownSync: typeof fs.chownSync = notImplemented('fs.chownSync') +export const chmodSync: typeof fs.chmodSync = notImplemented('fs.chmodSync') +export const closeSync: typeof fs.closeSync = notImplemented('fs.closeSync') +export const copyFileSync: typeof fs.copyFileSync = notImplemented('fs.copyFileSync') +export const cpSync: typeof fs.cpSync = notImplemented('fs.cpSync') +export const existsSync: typeof fs.existsSync = () => false +export const fchownSync: typeof fs.fchownSync = notImplemented('fs.fchownSync') +export const fchmodSync: typeof fs.fchmodSync = notImplemented('fs.fchmodSync') +export const fdatasyncSync: typeof fs.fdatasyncSync = notImplemented('fs.fdatasyncSync') +export const fstatSync: typeof fs.fstatSync = notImplemented('fs.fstatSync') +export const fsyncSync: typeof fs.fsyncSync = notImplemented('fs.fsyncSync') +export const ftruncateSync: typeof fs.ftruncateSync = notImplemented('fs.ftruncateSync') +export const futimesSync: typeof fs.futimesSync = notImplemented('fs.futimesSync') +export const lchownSync: typeof fs.lchownSync = notImplemented('fs.lchownSync') +export const lchmodSync: typeof fs.lchmodSync = notImplemented('fs.lchmodSync') +export const linkSync: typeof fs.linkSync = notImplemented('fs.linkSync') +export const lutimesSync: typeof fs.lutimesSync = notImplemented('fs.lutimesSync') +export const mkdirSync: typeof fs.mkdirSync = notImplemented('fs.mkdirSync') +export const mkdtempSync: typeof fs.mkdtempSync = notImplemented('fs.mkdtempSync') +export const openSync: typeof fs.openSync = notImplemented('fs.openSync') +export const opendirSync: typeof fs.opendirSync = notImplemented('fs.opendirSync') +export const readdirSync: typeof fs.readdirSync = notImplemented('fs.readdirSync') +export const readSync: typeof fs.readSync = notImplemented('fs.readSync') +export const readvSync: typeof fs.readvSync = notImplemented('fs.readvSync') +export const readFileSync: typeof fs.readFileSync = notImplemented('fs.readFileSync') +export const readlinkSync: typeof fs.readlinkSync = notImplemented('fs.readlinkSync') +export const renameSync: typeof fs.renameSync = notImplemented('fs.renameSync') +export const rmSync: typeof fs.rmSync = notImplemented('fs.rmSync') +export const rmdirSync: typeof fs.rmdirSync = notImplemented('fs.rmdirSync') +export const symlinkSync: typeof fs.symlinkSync = notImplemented('fs.symlinkSync') +export const truncateSync: typeof fs.truncateSync = notImplemented('fs.truncateSync') +export const unlinkSync: typeof fs.unlinkSync = notImplemented('fs.unlinkSync') +export const utimesSync: typeof fs.utimesSync = notImplemented('fs.utimesSync') +export const writeFileSync: typeof fs.writeFileSync = notImplemented('fs.writeFileSync') +export const writeSync: typeof fs.writeSync = notImplemented('fs.writeSync') +export const writevSync: typeof fs.writevSync = notImplemented('fs.writevSync') diff --git a/src/runtime/node/fs/index.ts b/src/runtime/node/fs/index.ts new file mode 100644 index 00000000..5354ab29 --- /dev/null +++ b/src/runtime/node/fs/index.ts @@ -0,0 +1,21 @@ +// https://nodejs.org/api/fs.html +import fs from 'node:fs' + +import * as _classes from './_classes' +import * as _constants from './_constants' +import * as _fs from './_fs' + +import * as _promises from './promises/index' + +export * from './_classes' +export * from './_constants' +export * from './_fs' + +export const promises = _promises + +export default { + ..._classes, + ..._constants, + ...fs, + promises +} diff --git a/src/runtime/node/fs/promises/index.ts b/src/runtime/node/fs/promises/index.ts new file mode 100644 index 00000000..d1daeb49 --- /dev/null +++ b/src/runtime/node/fs/promises/index.ts @@ -0,0 +1,32 @@ +import type fsp from 'node:fs/promises' +import { notImplemented } from '../../../_internal/utils' + +export const access: typeof fsp.access = notImplemented('fs.access') +export const copyFile: typeof fsp.copyFile = notImplemented('fs.copyFile') +export const cp: typeof fsp.cp = notImplemented('fs.cp') +export const open: typeof fsp.open = notImplemented('fs.open') +export const opendir: typeof fsp.opendir = notImplemented('fs.opendir') +export const rename: typeof fsp.rename = notImplemented('fs.rename') +export const truncate: typeof fsp.truncate = notImplemented('fs.truncate') +export const rm: typeof fsp.rm = notImplemented('fs.rm') +export const rmdir: typeof fsp.rmdir = notImplemented('fs.rmdir') +export const mkdir: typeof fsp.mkdir = notImplemented('fs.mkdir') +export const readdir: typeof fsp.readdir = notImplemented('fs.readdir') +export const readlink: typeof fsp.readlink = notImplemented('fs.readlink') +export const symlink: typeof fsp.symlink = notImplemented('fs.symlink') +export const lstat: typeof fsp.lstat = notImplemented('fs.lstat') +export const stat: typeof fsp.stat = notImplemented('fs.stat') +export const link: typeof fsp.link = notImplemented('fs.link') +export const unlink: typeof fsp.unlink = notImplemented('fs.unlink') +export const chmod: typeof fsp.chmod = notImplemented('fs.chmod') +export const lchmod: typeof fsp.lchmod = notImplemented('fs.lchmod') +export const lchown: typeof fsp.lchown = notImplemented('fs.lchown') +export const chown: typeof fsp.chown = notImplemented('fs.chown') +export const utimes: typeof fsp.utimes = notImplemented('fs.utimes') +export const lutimes: typeof fsp.lutimes = notImplemented('fs.lutimes') +export const realpath: typeof fsp.realpath = notImplemented('fs.realpath') +export const mkdtemp: typeof fsp.mkdtemp = notImplemented('fs.mkdtemp') +export const writeFile: typeof fsp.writeFile = notImplemented('fs.writeFile') +export const appendFile: typeof fsp.appendFile = notImplemented('fs.appendFile') +export const readFile: typeof fsp.readFile = notImplemented('fs.readFile') +export const watch: typeof fsp.watch = notImplemented('fs.watch')