Skip to content

Commit

Permalink
Merge pull request #10 from streamich/develop
Browse files Browse the repository at this point in the history
reme
  • Loading branch information
streamich authored Aug 13, 2017
2 parents 68f966c + 448291f commit 6a27260
Show file tree
Hide file tree
Showing 8 changed files with 385 additions and 207 deletions.
255 changes: 162 additions & 93 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# memfs
# memfs 2.0

In-memory file-system with [Node's `fs` API](https://nodejs.org/api/fs.html).

Expand All @@ -12,6 +12,7 @@ In-memory file-system with [Node's `fs` API](https://nodejs.org/api/fs.html).
- Implements *soft links* (aka symlinks, symbolic links)
- More testing coming soon*
- Permissions may* be implemented in the future
- Can be used in browser, see `memfs-webpack`

Usage:

Expand Down Expand Up @@ -67,6 +68,9 @@ import {Volume} from 'memfs';

const vol = Volume.fromJSON({'/foo': 'bar'});
vol.readFileSync('/foo'); // bar

const vol2 = Volume.fromJSON({'/foo': 'bar 2'});
vol2.readFileSync('/foo'); // bar 2
```

Use `memfs` together with [`unionfs`][unionfs] to create one filesystem
Expand Down Expand Up @@ -112,11 +116,18 @@ filesystem operations but are slightly different.
import {vol, fs} from 'memfs';
```

`vol` is an instance of `Volume` constructor, it is a default volume created
for your convenience. `fs` in and *fs-like* object created from `vol` using
`vol` is an instance of `Volume` constructor, it is the default volume created
for your convenience. `fs` is an *fs-like* object created from `vol` using
`createFsFromVolume(vol)`, see reference below.

#### `Volume`
All contents of the `fs` object are also exported individually, so you can use
`memfs` just like you would use the `fs` module:

```js
import {readFileSync, F_OK, ReadStream} from 'memfs';
```

#### `Volume` Constructor

`Volume` is a constructor function for creating new volumes:

Expand Down Expand Up @@ -176,105 +187,132 @@ Exports the whole contents of the volume recursively to a flat JSON object.
If this argument is omitted, the whole volume is exported. `paths` can be
an array of paths. A path can be a string, `Buffer` or an `URL` object.

`json` is an optional object parameter where the list of files will be added.
`json` is an optional object parameter which will be populated with the exported files.

`isRelative` is boolean that specifies if returned paths should be relative.

###### `vol.mkdirp(path, callback)`

Creates a directory tree recursively. `path` is specifies a directory to
Creates a directory tree recursively. `path` specifies a directory to
create and can be a string, `Buffer`, or an `URL` object. `callback` is
called on completion and may receive only one argument - an `Error` object.

###### `vol.mkdirpSync(path)`

A synchronous version of `vol.mkdirp`. This method throws.

#### FS API Status

- [x] Constants
- [x] `FSWatcher`
- [x] `ReadStream`
- [x] `WriteStream`
- [x] `Stats`
- [x] `access(path[, mode], callback)`
- Does not check permissions
- [x] `accessSync(path[, mode])`
- Does not check permissions
- [x] `appendFile(file, data[, options], callback)`
- [x] `appendFileSync(file, data[, options])`
- [x] `chmod(path, mode, callback)`
- [x] `chmodSync(path, mode)`
- [x] `chown(path, uid, gid, callback)`
- [x] `chownSync(path, uid, gid)`
- [x] `close(fd, callback)`
- [x] `closeSync(fd)`
- [x] `createReadStream(path[, options])`
- [x] `createWriteStream(path[, options])`
- [x] `exists(path, callback)`
- [x] `existsSync(path)`
- [x] `fchmod(fd, mode, callback)`
- [x] `fchmodSync(fd, mode)`
- [x] `fchown(fd, uid, gid, callback)`
- [x] `fchownSync(fd, uid, gid)`
- [x] `fdatasync(fd, callback)`
- [x] `fdatasyncSync(fd)`
- [x] `fstat(fd, callback)`
- [x] `fstatSync(fd)`
- [x] `fsync(fd, callback)`
- [x] `fsyncSync(fd)`
- [x] `ftruncate(fd[, len], callback)`
- [x] `ftruncateSync(fd[, len])`
- [x] `futimes(fd, atime, mtime, callback)`
- [x] `futimesSync(fd, atime, mtime)`
- [x] `lchmod(path, mode, callback)`
- [x] `lchmodSync(path, mode)`
- [x] `lchown(path, uid, gid, callback)`
- [x] `lchownSync(path, uid, gid)`
- [x] `link(existingPath, newPath, callback)`
- [x] `linkSync(existingPath, newPath)`
- [x] `lstat(path, callback)`
- [x] `lstatSync(path)`
- [x] `mkdir(path[, mode], callback)`
- [x] `mkdirSync(path[, mode])`
- [x] `mkdtemp(prefix[, options], callback)`
- [x] `mkdtempSync(prefix[, options])`
- [x] `open(path, flags[, mode], callback)`
- [x] `openSync(path, flags[, mode])`
- [x] `read(fd, buffer, offset, length, position, callback)`
- [x] `readSync(fd, buffer, offset, length, position)`
- [x] `readdir(path[, options], callback)`
- [x] `readdirSync(path[, options])`
- [x] `readFile(path[, options], callback)`
- [x] `readFileSync(path[, options])`
- [x] `readlink(path[, options], callback)`
- [x] `readlinkSync(path[, options])`
- [x] `realpath(path[, options], callback)`
- [x] `realpathSync(path[, options])`
- Caching not implemented
- [x] `rename(oldPath, newPath, callback)`
- [x] `renameSync(oldPath, newPath)`
- [x] `rmdir(path, callback)`
- [x] `rmdirSync(path)`
- [x] `stat(path, callback)`
- [x] `statSync(path)`
- [x] `symlink(target, path[, type], callback)`
- [x] `symlinkSync(target, path[, type])`
- [x] `truncate(path[, len], callback)`
- [x] `truncateSync(path[, len])`
- [x] `unlink(path, callback)`
- [x] `unlinkSync(path)`
- [x] `utimes(path, atime, mtime, callback)`
- [x] `utimesSync(path, atime, mtime)`
- [x] `watch(filename[, options][, listener])`
- [x] `watchFile(filename[, options], listener)`
- [x] `unwatchFile(filename[, listener])`
- [x] `write(fd, buffer[, offset[, length[, position]]], callback)`
- [x] `write(fd, string[, position[, encoding]], callback)`
- [x] `writeFile(file, data[, options], callback)`
- [x] `writeFileSync(file, data[, options])`
- [x] `writeSync(fd, buffer[, offset[, length[, position]]])`
- [x] `writeSync(fd, string[, position[, encoding]])`
A synchronous version of `vol.mkdirp()`. This method throws.

#### `createFsFromVolume(vol)`

Returns an *fs-like* object created from a `Volume` instance `vol.

```js
import {createFsFromVolume, Volume} from 'memfs';

const vol = new Volume;
const fs = createFsFromVolume(vol);
```

The idea behind the *fs-like* object is to make it identical to the one
you get from `require('fs')`. Here are some things this function does:

- Binds all methods, so you can do:

```js
const {createFileSync, readFileSync} = fs;
```

- Adds constructor functions `fs.Stats`, `fs.ReadStream`, `fs.WriteStream`, `fs.FileWatcher`, `fs.FSWatcher`.
- Adds constants `fs.constants`, `fs.F_OK`, etc.

# API Status

All of the [Node's `fs` API](https://nodejs.org/api/fs.html) is implemented.
Some error messages may be inaccurate. File permissions are currently not
implemented (you have access to any file), basically `fs.access()` is a no-op.

- [x] Constants
- [x] `FSWatcher`
- [x] `ReadStream`
- [x] `WriteStream`
- [x] `Stats`
- [x] `access(path[, mode], callback)`
- Does not check permissions
- [x] `accessSync(path[, mode])`
- Does not check permissions
- [x] `appendFile(file, data[, options], callback)`
- [x] `appendFileSync(file, data[, options])`
- [x] `chmod(path, mode, callback)`
- [x] `chmodSync(path, mode)`
- [x] `chown(path, uid, gid, callback)`
- [x] `chownSync(path, uid, gid)`
- [x] `close(fd, callback)`
- [x] `closeSync(fd)`
- [x] `createReadStream(path[, options])`
- [x] `createWriteStream(path[, options])`
- [x] `exists(path, callback)`
- [x] `existsSync(path)`
- [x] `fchmod(fd, mode, callback)`
- [x] `fchmodSync(fd, mode)`
- [x] `fchown(fd, uid, gid, callback)`
- [x] `fchownSync(fd, uid, gid)`
- [x] `fdatasync(fd, callback)`
- [x] `fdatasyncSync(fd)`
- [x] `fstat(fd, callback)`
- [x] `fstatSync(fd)`
- [x] `fsync(fd, callback)`
- [x] `fsyncSync(fd)`
- [x] `ftruncate(fd[, len], callback)`
- [x] `ftruncateSync(fd[, len])`
- [x] `futimes(fd, atime, mtime, callback)`
- [x] `futimesSync(fd, atime, mtime)`
- [x] `lchmod(path, mode, callback)`
- [x] `lchmodSync(path, mode)`
- [x] `lchown(path, uid, gid, callback)`
- [x] `lchownSync(path, uid, gid)`
- [x] `link(existingPath, newPath, callback)`
- [x] `linkSync(existingPath, newPath)`
- [x] `lstat(path, callback)`
- [x] `lstatSync(path)`
- [x] `mkdir(path[, mode], callback)`
- [x] `mkdirSync(path[, mode])`
- [x] `mkdtemp(prefix[, options], callback)`
- [x] `mkdtempSync(prefix[, options])`
- [x] `open(path, flags[, mode], callback)`
- [x] `openSync(path, flags[, mode])`
- [x] `read(fd, buffer, offset, length, position, callback)`
- [x] `readSync(fd, buffer, offset, length, position)`
- [x] `readdir(path[, options], callback)`
- [x] `readdirSync(path[, options])`
- [x] `readFile(path[, options], callback)`
- [x] `readFileSync(path[, options])`
- [x] `readlink(path[, options], callback)`
- [x] `readlinkSync(path[, options])`
- [x] `realpath(path[, options], callback)`
- [x] `realpathSync(path[, options])`
- Caching not implemented
- [x] `rename(oldPath, newPath, callback)`
- [x] `renameSync(oldPath, newPath)`
- [x] `rmdir(path, callback)`
- [x] `rmdirSync(path)`
- [x] `stat(path, callback)`
- [x] `statSync(path)`
- [x] `symlink(target, path[, type], callback)`
- [x] `symlinkSync(target, path[, type])`
- [x] `truncate(path[, len], callback)`
- [x] `truncateSync(path[, len])`
- [x] `unlink(path, callback)`
- [x] `unlinkSync(path)`
- [x] `utimes(path, atime, mtime, callback)`
- [x] `utimesSync(path, atime, mtime)`
- [x] `watch(filename[, options][, listener])`
- [x] `watchFile(filename[, options], listener)`
- [x] `unwatchFile(filename[, listener])`
- [x] `write(fd, buffer[, offset[, length[, position]]], callback)`
- [x] `write(fd, string[, position[, encoding]], callback)`
- [x] `writeFile(file, data[, options], callback)`
- [x] `writeFileSync(file, data[, options])`
- [x] `writeSync(fd, buffer[, offset[, length[, position]]])`
- [x] `writeSync(fd, string[, position[, encoding]])`


[npm-url]: https://www.npmjs.com/package/memfs
Expand All @@ -283,3 +321,34 @@ A synchronous version of `vol.mkdirp`. This method throws.
[unionfs]: https://github.com/streamich/unionfs
[linkfs]: https://github.com/streamich/linkfs
[fs-monkey]: https://github.com/streamich/fs-monkey





# License

This is free and unencumbered software released into the public domain.

Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.

In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

For more information, please refer to <http://unlicense.org/>
10 changes: 10 additions & 0 deletions demo/mountSync.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import {Volume} from '../src/index';


const vol = new Volume;
vol.mountSync('/test', {
'foo': 'bar',
});


console.log(vol.toJSON());
52 changes: 19 additions & 33 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,45 +8,31 @@ var __assign = (this && this.__assign) || Object.assign || function(t) {
return t;
};
Object.defineProperty(exports, "__esModule", { value: true });
var constants_1 = require("./constants");
var node_1 = require("./node");
var volume_1 = require("./volume");
exports.constants = constants_1.constants;
exports.F_OK = constants_1.constants.F_OK;
exports.R_OK = constants_1.constants.R_OK;
exports.W_OK = constants_1.constants.W_OK;
exports.X_OK = constants_1.constants.X_OK;
var volume = require("./volume");
var _a = require('fs-money/lib/util/lists'), fsSyncMethods = _a.fsSyncMethods, fsAsyncMethods = _a.fsAsyncMethods;
var constants_1 = require("./constants");
var F_OK = constants_1.constants.F_OK, R_OK = constants_1.constants.R_OK, W_OK = constants_1.constants.W_OK, X_OK = constants_1.constants.X_OK;
exports.Volume = volume_1.Volume;
// Default volume.
exports.vol = new volume_1.Volume;
// List of `fs.js` methods, used to export bound (`.bind`) method list, just like `require('fs')` would do.
var FS_METHODS = [
'open', 'openSync',
'close', 'closeSync',
'readFile', 'readFileSync',
'write', 'writeSync',
'writeFile', 'writeFileSync',
'link', 'linkSync',
'unlink', 'unlinkSync',
'symlink', 'symlinkSync',
'realpath', 'realpathSync',
'stat', 'statSync',
'lstat', 'lstatSync',
'fstat', 'fstatSync',
'rename', 'renameSync',
'exists', 'existsSync',
'access', 'accessSync',
'readdir', 'readdirSync',
'watchFile', 'unwatchFile',
'createReadStream',
];
function createFsFromVolume(volume) {
var fs = {};
function createFsFromVolume(vol) {
var fs = { F_OK: F_OK, R_OK: R_OK, W_OK: W_OK, X_OK: X_OK, constants: constants_1.constants, Stats: node_1.Stats };
// Bind FS methods.
for (var _i = 0, FS_METHODS_1 = FS_METHODS; _i < FS_METHODS_1.length; _i++) {
var method = FS_METHODS_1[_i];
fs[method] = volume[method].bind(volume);
for (var _i = 0, fsSyncMethods_1 = fsSyncMethods; _i < fsSyncMethods_1.length; _i++) {
var method = fsSyncMethods_1[_i];
fs[method] = vol[method].bind(vol);
}
for (var _a = 0, fsAsyncMethods_1 = fsAsyncMethods; _a < fsAsyncMethods_1.length; _a++) {
var method = fsAsyncMethods_1[_a];
fs[method] = vol[method].bind(vol);
}
fs.Stats = node_1.Stats;
fs.StatWatcher = volume_1.StatWatcher.bind(null, vol);
fs.FSWatcher = volume_1.FSWatcher.bind(null, vol);
fs.WriteStream = volume.WriteStream.bind(null, vol);
fs.ReadStream = volume.ReadStream.bind(null, vol);
fs._toUnixTimestamp = volume_1.toUnixTimestamp;
return fs;
}
exports.createFsFromVolume = createFsFromVolume;
Expand Down
Loading

0 comments on commit 6a27260

Please sign in to comment.