The fs-filesysteminfo module, fsi, wraps the native Node.js File System and Path API into a File System Object (FSO) model, which facilitates an object-based approach for working with directories and files. Inspired by the .NET file system libraries.
Install the module with: npm install fs-filesysteminfo --save
The fs-filesysteminfo NodeJS module, fsi , exposes three classes (objects) for working with the filesystem: FileSystemInfo
, DirectoryInfo
, and FileInfo
.
DirectoryInfo
and FileInfo
are subclasses of the FileSystemInfo
class, both expose instance methods for working with directories and files, respectively.
All fsi objects are instantiated with a path
{String}. An exception is thrown if the path
length is zero or if path
is null
or undefined
.
A path
used to construct the object can be relative or absolute, and the path does not need to exist. If a relative path
is used, it will be resolved
relative to the current process.cwd()
.
var fsi = require('fs-filesysteminfo');
The base class for the FileInfo
and DirectoryInfo
objects. Create a FileSystemInfo
object by instantiating the fsi FileSystemInfo
class.
path
{String} A string specifying the path on which to create the FileSystemInfo
object.
var fsiObj = new fsi.FileSystemInfo('temp'); //If temp is an existing file or directory then fsiObj.exists === true otherwise false
Name | Type | Description |
---|---|---|
originalPath | {String} | The value that was used to construct the object. |
fullName | {String} | Gets the full path of the directory or file. |
name | {String} | Gets the last portion of a path. Similar to the Unix basename command. |
extension | {String} | Gets the extension of the path, from the last '.' to end of string in the last portion of the path. If there is no '.' in the last portion of the path or the first character of it is '.', then it returns an empty string. |
status | {Object} | An object composed of properties specific to the FileSystemInfo instance. This information is obtained by using Node's fs.statSync method. |
flags | {Object} | An object containing the following {Boolean} properties: isDirectory , isFile , isBlockDevice , isCharacterDevice , isFIFO , isSocket , and isSymbolicLink . |
exists | {Boolean} | Gets a value indicating whether the directory or file exists. |
fileSystemPermissions | {FileSystemPermissions} | An object that contains information about the permissions (file system) of the current FileSystemInfo instance. |
Name | Type | Description |
---|---|---|
getType | {String} | Returns the type name of the current instance. |
refresh | void | Refreshes the state of the current instance. |
To determine if the FileSystemInfo
instance is a file or a directory, use the following:
if (fsiObj.exists) {
var fflags = fsiObj.flags
var isDirecory = fflags.isDirectory;
var isFile = fflags.isFile;
}
Create a DirectoryInfo object by instantiating the fsi DirectoryInfo
class.
path
{String} A string specifying the path on which to create the DirectoryInfo object.
var fsiObj = new fsi.DirectoryInfo('temp'); //If temp is an existing directory then fsiObj.exists === true otherwise false
Name | Type | Description |
---|---|---|
parent | {DirectoryInfo} | Gets the parent directory of the current instance. |
Name | Type | Description | Remarks |
---|---|---|---|
create([mode], callback) | void | Creates the directory if it does not already exist. mode defaults to the octal representation 0777 . |
callback : {Function} (error, result) where result is the DirectoryInfo instance and this in the callback context is equal to the original DirectoryInfo instance that invoked the create() method.mode : a {String} or a non-octal {Integer} (an octal representation) (e.g. '777', 777, and '0777' are all equivalent however, 0777 is not). mode is automatically converted to the proper integer equivalent (e.g. '777' will become 511) before it is passed on to native Node filesystem methods. |
createSync([mode]) | {DirectoryInfo} | Synchronous version of create() . Returns the calling {DirectoryInfo} instance. |
|
createSubdirectory(path, [mode], callback) | void | Creates a subdirectory or subdirectories on the specified path if it does not exist. The specified path is relative to the current instance. mode defaults to 0777 .If multiple paths are specified (via path separator), and they do not exist, they will be created. Example: /tmp/test1/test2 |
callback : {Function} (error, result) where result is the DirectoryInfo instance of the deepest subdirectory and this in the callback context is equal to the original DirectoryInfo instance that invoked the createSubdirectory() method.callback is called upon creation of the deepest subdirectory. |
createSubdirectorySync(path, [mode]) | {DirectoryInfo} | Synchronous version of createSubdirectory() .Returns a new DirectoryInfo instance of the deepest subdirectory. |
An exception is thrown if the path length is zero or if path is null or undefined . |
delete([recursive], callback) | void | Permanently deletes the instance directory. If recursive is true, the directory and all its contents are deleted. If recursive is false and the directory is not empty, an exception is thrown. recursive defaults to false . |
callback : {Function} (error) where this in the callback context is equal to the original DirectoryInfo instance that invoked the delete() method.callback is called once the directory (and optionally its contents) are deleted. |
deleteSync([recursive]) | void | Synchronous version of delete() . |
If recursive is false and the directory is not empty, an exception is thrown. recursive defaults to false . |
enumerateFileSystemInfos({opts}, callback) | void | Iterates the contents of the current DirectoryInfo instance.opts is an object that utilizes the following properties: opts.fnFilter : a {Function(fsname )} that determines whether the current item in the enumeration is included in the output {Array} if the function evaluates to true where fsname is the name of the current filesystem item.opts.recursive : a {Boolean} that indicates whether subdirectories will be recursively searched. The default value is false . |
callback : {Function} (error, result) where result is an Array<FileSystemInfo> ({DirectoryInfo} and/or {FileInfo} objects comprised of the instance directory contents) and this in the callback context is equal to the original DirectoryInfo instance that invoked the enumerateFileSystemInfos() method.callback is called after all items have been iterated. |
enumerateFileSystemInfosSync({opts}) | {Array<FileSystemInfo>} | Synchronous version of enumerateFileSystemInfos() .Returns an {Array} of {DirectoryInfo} and/or {FileInfo} objects comprised of the current directory contents. |
Look for additional methods to be added in future releases.
create a subdirectory from a DirectoryInfo
instance:
var fsiObj = new fsi.DirectoryInfo('currentDir');
var subDir = fsiObj.createSubdirectorySync('subDir','777'); //Create a subdirectory with readable, writable, and executable permissions
Enumeration examples:
var fsiObj = new fsi.DirectoryInfo('currentDir');
var directoryContentsArr1 = fsiObj.enumerateFileSystemInfosSyncSync({fnFilter: '', recursive: true}); //Return all filesystem objects (recursively including all subdirectories and files)
var directoryContentsArr2 = fsiObj.enumerateFileSystemInfosSync({fnFilter: function (fsname) { return /^\..*$/.test(fsname); }, recursive: true}); //Return all filesystem objects (recursively including all subdirectories and files) whose name starts with a dot (.)
var pathnamesArr = directoryContentsArr2.map(function (e) { return e.fullName; }); //Generate an array of absolute paths
Create a FileInfo object by instantiating the fsi FileInfo
class.
path
{String} A string specifying the path on which to create the FileInfo object.
var fsiObj = new fsi.FileInfo('temp'); //If temp is an existing file then fsiObj.exists === true otherwise false
Name | Type | Description |
---|---|---|
parent | {DirectoryInfo} | Gets the parent directory of the current instance. |
Name | Type | Description | Remarks |
---|---|---|---|
create([opts], callback) | void | Creates a zero byte (empty) file. opts is an object with the following defaults: { ensure :false , mode :'777' , overwrite: true }.mode : the file mode, a {String} or a non-octal {Integer} (an octal representation) (e.g. '777', 777, and '0777' are all equivalent however, 0777 is not).If ensure is true and the destination directory does not exist, the directory will be created.If overwrite is true and the destination file already exists, it will be overwritten. |
callback : {Function} (error) where this in the callback context is equal to the original FileInfo instance that invoked the create() method.mode is automatically converted to the proper integer equivalent (e.g. '777' will become 511) before it is passed on to native Node filesystem method. |
createSync([opts]) | {FileInfo} | Synchronous version of create() . Returns the calling {FileInfo} instance. |
|
delete() | void | Permanently deletes the instance file. | callback : {Function} (error) where this in the callback context is equal to the original FileInfo instance that invoked the delete() method. |
deleteSync() | void | Synchronous version of delete() . |
Look for additional methods to be added in future releases.
A class that contains properties related to roles and each roles' (file system) permissions for directories and files. This class is scoped within the context of the library (private) and is not exposed via exports.
Name | Type | Description |
---|---|---|
owner | {Object} | The file system permissions specific to the owner role. canRead , canWrite , and canExecute (all of Boolean type). |
group | {Object} | The file system permissions specific to the group role. canRead , canWrite , and canExecute (all of Boolean type). |
otherUsers | {Object} | The file system permissions specific to the otherUsers role. canRead , canWrite , and canExecute (all of Boolean type). |
octalFileSystemModeString | {String} | A valid file system octal string representation. Examples of valid values include: 0777 , 777 , 0 , 466 , etc. |
Name | Type | Description |
---|---|---|
getType | {String} | Returns the type name of the current instance. |
refresh | void | Refreshes the state of the current instance. |
toRoleBinaryRepresentationString | {String} | Returns the binary representation of the permissions string. |
toRoleLetterRepresentationString | {String} | Returns the 9 bit Linux-style permissions string. |
Given the following:
var fsiObj = new _fsi.DirectoryInfo('./tmp'); // an existing directory to create new subdirectories with varying permissions
var subdirectoryArr = [
{ name: 'tmp1', mode: '777' },
{ name: 'tmp2', mode: '775' },
{ name: 'tmp3', mode: '666' },
{ name: 'tmp4', mode: '444' }
];
subdirectoryArr.forEach(function (subdirectory) {
var newSubdirectory = fsiObj.createSubdirectorySync(subdirectory.name, subdirectory.mode);
var nsp = newSubdirectory.fileSystemPermissions;
nsp['subdirectoryName', subdirectory.name];
nsp['toRoleBinaryRepresentationString()'] = nsp.toRoleBinaryRepresentationString();
nsp['toRoleLetterRepresentationString()'] = nsp.toRoleLetterRepresentationString();
var outputResult = JSON.stringify(nsp);
console.log('\n' + outputResult + '\n');
});
The resulting output is:
{
"subdirectoryName": "tmp1",
"octalFileSystemModeString": "0777",
"owner": { "canRead": true, "canWrite": true, "canExecute": true, "letterFormat": "rwx", "binaryFormat": "111" },
"group": { "canRead": true, "canWrite": true, "canExecute": true, "letterFormat": "rwx", "binaryFormat": "111" },
"otherUsers": { "canRead": true, "canWrite": true, "canExecute": true, "letterFormat": "rwx", "binaryFormat": "111" },
"toRoleBinaryRepresentationString()": "111111111",
"toRoleLetterRepresentationString()": "rwxrwxrwx"
}
{
"subdirectoryName": "tmp2",
"octalFileSystemModeString": "0775",
"owner": { "canRead": true, "canWrite": true, "canExecute": true, "letterFormat": "rwx", "binaryFormat": "111" },
"group": { "canRead": true, "canWrite": true, "canExecute": true, "letterFormat": "rwx", "binaryFormat": "111" },
"otherUsers": { "canRead": true, "canWrite": false, "canExecute": true, "letterFormat": "r-x", "binaryFormat": "101" },
"toRoleBinaryRepresentationString()": "111111101",
"toRoleLetterRepresentationString()": "rwxrwxr-x"
}
{
"subdirectoryName": "tmp3",
"octalFileSystemModeString": "0666",
"owner": { "canRead": true, "canWrite": true, "canExecute": false, "letterFormat": "rw-", "binaryFormat": "110" },
"group": { "canRead": true, "canWrite": true, "canExecute": false, "letterFormat": "rw-", "binaryFormat": "110" },
"otherUsers": { "canRead": true, "canWrite": true, "canExecute": false, "letterFormat": "rw-", "binaryFormat": "110" },
"toRoleBinaryRepresentationString()": "110110110",
"toRoleLetterRepresentationString()": "rw-rw-rw-"
}
{
"subdirectoryName": "tmp4",
"octalFileSystemModeString": "0444",
"owner": { "canRead": true, "canWrite": false, "canExecute": false, "letterFormat": "r--", "binaryFormat": "100" },
"group": { "canRead": true, "canWrite": false, "canExecute": false, "letterFormat": "r--", "binaryFormat": "100" },
"otherUsers": { "canRead": true, "canWrite": false, "canExecute": false, "letterFormat": "r--", "binaryFormat": "100" },
"toRoleBinaryRepresentationString()": "100100100",
"toRoleLetterRepresentationString()": "r--r--r--"
}
- Continue adding functionality and tests.
- Add a DirectoryInfo.clean() and cleanSync() method to remove directory content without removing the directory itself.
In lieu of a formal styleguide, take care to maintain the existing coding style. Add unit tests for any new or changed functionality. Lint and test your code using Grunt.
Copyright (c) 2016 Christopher M. Cook
Licensed under the MIT license.