Draxt is an open-source utility module for selecting and manipulating filesystem objects in a Node.js environment. It uses glob patterns as its "selector engine" to select filesytem objects (files, directories, ...).
Draxt also provides several DOM-like interfaces representing filesystem objects which build on promisified APIs for the fs and fs-extra.
Writing readble and maintable code by using node fs module is not an easy task. One usually has to write helper structures for doing basic and common tasks. Draxt is an attempt for faciliating this process. The library, in addition to wrappers for promisified fs and fs-extra module APIs, provides several DOM/jQuery-like APIs for selecting and manipulating files and directories and traversing filesystem.
glob
patterns to select filesystem objects.draxt
collection is an instance of a File
, Directory
, or SymbolicLink
class, which is a subclass of Node
.node.siblingsSync()
for node.siblings()
.fs
and fs-extra
functions use the same names as the original functions. E.g. file.lchmod()
is a wrapper for promisified fs.lchmod()
.node.chmodSync()
– are chainable.draxt
is a simple constructor function. You can extend/overwrite its methods via its prototype
property (or its fn
alias) or by using the draxt.extend()
method.The project is hosted on GitHub. You can report bugs and discuss features on the issues page.
// Let's use a familiar variable name! const $ = require('draxt'); (async () => { // Select `/app` directory contents and create a new `draxt` collection. const $app = await $('/app/**'); $app // Let's filter js files: .filter(node => node.extension === 'js') // Now we have a new `draxt` collection with 2 nodes. .forEach(async (node, index, allNodes) => { // `node` is instance of `File` class. Because it's a file! console.log(node.pathName); // → '/app/controllers/index.js' for the first node! console.log(node instanceof $.File); // → `true` // Let's get contents of the node. `file.read` returns a promise object. const content = await node.read('utf8'); // Let's use some synchronous methods! node.appendSync('\na new line!') .chmodSync('765') // move the file into another directory! .appendToSync('/hell') // or `.moveToSync('/hell')` console.log(node.pathName); // → '/hell/index.js' for the first node in the list! // get the parent directory of the node. // returns a `Directory` instance with the pathName of '/hell'! const parentNode = node.parentSync(); // or `await node.parent()` // is the directory empty? console.log(parentNode.isEmptySync()); // → `false` }); })();
draxt
module exports a constructor function. Whenever a string
is passed as the first parameter to the function, parameters are passed to the glob package. The matching pathNames returned by the glob package, if any, are converted into an array of node instances. The returned value of draxt
is a draxt instance (a draxt collection) which wraps an array of nodes. In this respect, draxt
constructor function works like jQuery function, but unlike jQuery collections, draxt collections are not array-like objects. draxt
collections store the array of nodes as a property named items
. The length
property of draxt collections is a getter
for the collection's items.length
property.
// Let's use a familiar variable name! const $ = require('draxt') // glob options const globOptions = { dot: true } // using await syntax in an async function context (async () => { const draxtCollection = await $('/example_pattern/**', globOptions) })() // using promises $('/example_pattern/**').then(draxtCollection => { // ... }) // synchronous query const draxtCollection = $.sync('/example_pattern/**', globOptions)
draxt
function is the main method of draxt
package. The function can be called with new
as a constructor function (not recommended) and without new
as a factory function. draxt
uses promisified glob
package as it's selector engine. All query results of glob
package are converted into one of Node
's sub-class (File
, Directory
or SymbolicLink
) instances by analyzing pathNames' fs.Stats
object. The returned value of draxt
is a draxt
collection which to some extent works like jQuery collections but unlike jQuery collections it's not an array-like object. The collection items are stored as an array property (.items
).
const draxtCollection = draxt([pattern, options])
pattern
(string
|array.<node>
|node
|draxt
) – pattern
parameter can contain several values:string
which is passed to glob
package as glob
pattern. In this case draxt
returns a promise
object representing a draxt
collection/instance.Node
or one it's sub-classes (File
, Directory
or SymbolicLink
) instance. In this case a draxt
collection containing the passed node
is returned.node
instances.draxt
collection to clone (shallow).undefined
which returns an empty draxt
collection.options
(object
|string
) – Options for glob
package. The options
parameter can also be a string representing a pathName which will be used as context for the query, similar to jQuery's $(selector, context)
syntax.promise.<draxt>
| draxt
draxt.sync(pattern [, options])
pattern
(string
) – Glob pattern.options
(object
) – Options for glob
package.Synchronously query the file system by using glob
package and return a new draxt
collection.
draxt
An instance of draxt
, a.k.a. a draxt collection.draxt.extend(methods)
methods
(object
)Extend draxt
by adding methods to it's prototype
. Basically works like jQuery.fn.extend
.
draxtCollection.add(items)
items
(node
|array.<node>
|draxt
) – Instance of Node or array of nodes or a draxt
collection.Add node(s) to current draxt
collection. Pre-exising nodes will not be added to the collection.
const draxtCollection = draxt(); draxtCollection.add(new Node('/pathName')); draxtCollection.length // → 1
draxt
An instance of draxt
.draxtCollection.get([index])
index
(number
) – Index of node in items collection.Get one or all nodes from the draxt
collection. With an index
specified, .get(index)
retrieves a single node otherwise retrives all the nodes (if any).
array.<node>
| node
| undefined
draxtCollection.first()
Get the first node (if any) from the collection.
node
| undefined
draxtCollection.has(item)
item
(string
|node
) – A Node
instance or a pathName
Does the draxt
collection has a node with specified pathName? Note that .has()
method doesn't work by checking if collection has a specific Node
instance. It checks whether collection has a node with the specified pathName.
// example fs structure // └── app // ├── public // │ ├── script.js // │ └── style.css const collection = draxtCollection.sync('/app/**'); draxtCollection.has('/app/public/script.js') // → true draxtCollection.has(new Node('/app/public/script.js')) // → true
boolean
draxtCollection.slice([begin, end])
begin
(integer
) – Zero-based index at which to begin extraction.end
(integer
) – Zero-based index before which to end extraction. slice
extracts up to but not including end
.Slice the collection and return a new Draxt
collection. Uses Array.prototype.slice
.
draxt
A new draxt
collection which contains sliced items.draxtCollection.filter(callback [, thisArg])
callback
(function
) – A function to execute for each node.thisArg
(any
) – Value to use as this
(i.e the reference Object) when executing callback.Filter the collection's nodes and return a new draxt
collection. Uses Array.prototype.filter
.
draxt
A new draxt
collection which contains filtered items.draxtCollection.forEach(callback [, thisArg])
callback
(function
) – A function to execute for each node.thisArg
(any
) – Value to use as this
(i.e the reference Object) when executing callback.Iterate over the draxt
collection and execute a function for each node. Uses Array.prototype.forEach
.
draxt
The current collection.draxtCollection.map(callback [, thisArg])
callback
(function
) – A function to execute for each node.thisArg
(any
) – Value to use as this
(i.e the reference Object) when executing callback.Create an array with the results of calling a provided function on every node in the draxt
collection. Uses Array.prototype.map
.
array
draxtCollection.mapAsync(fn [, thisArg])
fn
(function
) – A function to execute for each node.thisArg
(any
) – Value to use as this
(i.e the reference Object) when executing callback.Asynchronous version of draxt.map
. The results of mapped array is passed to Promise.all
method.
promise
draxtCollection.some(fn)
fn
(function
) – A function to execute for each node.Test whether at least one node in the collection passes the test implemented by the provided function. Uses Array.prototype.some
.
boolean
draxtCollection.sort(callback)
callback
(function
) – A function that defines the sort order.Sort the nodes of collection in place and return the draxt
collection. Uses Array.prototype.sort
.
draxt
Note that the collection is sorted in place, and no copy is made.draxtCollection.reverse()
Reverse the collection's nodes in place. The first array element becomes the last, and the last array element becomes the first.
draxt
draxtCollection.directories()
Filter directory nodes (instances of Directory
class) and return a new draxt
collection.
draxt
draxtCollection.files()
Filter file nodes (instances of File
class) and return a new draxt
collection.
draxt
draxtCollection.symlinks()
Filter symbolic link nodes (instances of SymbolicLink
class) and return a new draxt
collection.
draxt
draxtCollection.empty()
Empty the draxt
collection. This method doesn't affect file system!
draxt
draxtCollection.drop(node)
node
(draxt
|node
|array.<(node|string)>
) – Accepts various paramters.Remove node(s) from the current draxt
collection by using .pathName
s as the criterion.
draxt
Draxt introduces several DOM-like interfaces representing fileysystem objects. There are several interfaces. File for files, Directory for directories and SymbolicLink for symbolic links. These interfaces extends the base Node interface.
Just like DOM interfaces, draxt interfaces has their own set of unique methods. As an example, a directory
instance has .find()
method but a file
instance doesn't.
Node class is an interface that other classes representing file system's nodes (like File
, Directory
, SymbolicLink
, ...) inherit.
const node = new Node(pathName [, stats]);
string
)Default: 'Node'
. The name of constructor of the current node.
number
)Default: 0
. Code number for the node.
string
)Absolute pathName of the node. Example: '/app/readme.md'
.
string
)baseName of the node. Example: 'readme.md'
.
string
)Name of the node without the possible extension. Example 'readme'
.
string
|undefined
)Extension of the node without .
. Example: 'js'
.
string
)pathName of the parent directory of the node.
string
)Root path of the file system.
object
|undefined
)Cached instance of fs.Stats
for the node.
object
)Refers to fs-extra
package.
object
)Refers to glob
package.
Node.rawQuery(pattern [, options])
Asynchronously query the file system by using glob
package.
promise.<array>
An array of pathNames.Node.rawQuerySync(pattern [, options])
Synchronously query the file system by using glob
package.
array
An array of pathNames.Node.toNodes(pathNames)
pathNames
(array
) – Array of pathNames.Convert array of paths to array of node instances asynchronously! A node instance can be an instance of File
, Directory
or SymbolicLink
.
const pathNames = [ '/app/resources', '/app/resources/style.css' ]; Node.toNodes(pathNames).then(result => { // result: [ Directory { pathName: '/app/resources', ... }, File { pathName: '/app/resources/style.css', ... } ] });
promise.<array>
Array of node instances.Node.toNodesSync(pathNames)
pathNames
(array
) – Array of pathsConvert array of paths to array of nodes synchronously! A node instance can be instance of File
, Directory
or SymbolicLink
.
array
Array of node instances.Node.query(pattern [, options])
Asynchronously query the file system by using glob
package.
promise.<array>
Array of nodes.Node.querySync(pattern [, options])
pattern
(string
)options
(object
) – Options for glob
package.Synchronously query the file system by using glob
package.
array
Array of nodes.node.getName()
Get name of the node. For File
nodes the name
property is the name of file without possible extension.
string
node.getCachedStats()
Get cached fs.Stats
instance for the node. Returns undefined
when there is no cached stats for the node. This happens only when the node is created manually by user without passing a stats object.
object
| undefined
node.getStatProp(propName)
propName
(string
)Get a stat property's value from cached fs.Stats
for the node. The method returns undefined
when there is no cached stats.
// Get `blksize` property of fs.Stats instance cached for the node. const node_ctime = node.getStatProp('blksize');
any
node.getAccessTime()
Get "access time" of the node. Returns atime
property of the cached stats.
date
node.getModifiedTime()
Get "modified time" of the node. Returns mtime
property of the cached stats.
date
node.getBirthTime()
Get "birthday time" of the node. Returns birthtime
property of the cached stats.
date
node.getChangeTime()
Get "change time" of the node. Returns ctime
property of the cached stats.
date
node.getSize()
Get size of the node. Size is simply the size
property of the cached fs.Stats
instance.
number
node.isDotFile()
Is the node a dot file? i.e. does the node's name begin with dot character.
boolean
node.renewStats()
Asynchronously renew stats of the node. Uses fs.lstat
.
promise
A fresh fs.Stats
instance for the node.node.renewStatsSync()
Synchronously renew stats of the node. Uses fs.lstatSync
.
node
node.getOctalPermissions()
Get octal representation of the node's permissions.
node.getOctalPermissions() // → "755"
string
node.getPermissions()
Get permissions of the node for owner, group and others by converting mode
property of cached stats into an object.
node.getPermissions() // → { read: { owner: true, group: true, others: false }, write: { owner: true, group: true, others: false }, execute: { owner: true, group: true, others: false } }
object
node.access([mode])
mode
(integer
) Default: fs.constants.F_OK
Asynchronously tests a user's permissions for the file or directory. Wrapper for promisified fs.access
.
// Check if the node is readable. node.access(node.fs.constants.R_OK).then(() => { // node is readable }).catch(e => { // node is not readable });
promise
node.accessSync([mode])
mode
(integer
) Default: fs.constants.F_OK
Wrapper for fs.accessSync
.
node
thisnode.chown(uid, gid)
uid
(integer
) – The user idgid
(integer
) – The group idWrapper for promisified fs.chown
.
promise
node.chownSync(uid, gid)
uid
(integer
) – The user idgid
(integer
) – The group idWrapper for fs.chownSync
.
node
The file nodenode.lchown(uid, gid)
uid
(integer
) – The user idgid
(integer
) – The group idWrapper for promisified fs.lchown
.
promise
node.lchownSync(uid, gid)
uid
(integer
) – The user idgid
(integer
) – The group idWrapper for fs.lchownSync
.
node
The file nodenode.exists()
Does node exist on file system? Uses fs.access
instead of the deprecated fs.exists
method.
promise.<boolean>
node.existsSync()
Does node exist on file system? Wrapper for fs.existsSync
.
boolean
node.stat()
Wrapper for promisified fs.stat
.
promise
Promise representing instance of fs.Stats
for the node.node.lstat()
Wrapper for promisified fs.lstat
.
promise
Promise representing instance of fs.Stats
for the node.node.rename(newPath)
newPath
(string
|Buffer
|URL
)Asynchronously rename node to the pathname provided as newPath. In the case that newPath
already exists, it will be overwritten. Wrapper for promisified fs.rename
.
promise
node.utimes(atime, mtime)
atime
(number
|string
|Date
)mtime
(number
|string
|Date
)Wrapper for promisified fs.utimes
.
promise
node.utimesSync(atime, mtime)
atime
(number
|string
|Date
)mtime
(number
|string
|Date
)Wrapper for fs.utimesSync
.
node
node.copy(destPath, options)
destPath
(string
) – Destination path.options
(object
) – Options for fs-extra.copy
.Asynchronously copy the node. Directory
instances can have contents. Like cp -r
. When directory doesn't exist, it's created! Wrapper for fs-extra.copy
.
// creating a `File` instance. `File` class extends the `Node` class! const file = new File('/app/resources/style.css'); file.copy('/app/backup/backup_style.css').then(() => { // file has been copied successfully! }).catch(e => { // There was an error! });
promise
node.copySync(destPath, options)
destPath
(string
) – Destination path.options
(object
) – Options for fs-extra.copySync
.Wrapper for fs-extra.copySync
.
node
node.moveTo(targetDir, options)
targetDir
(object
|string
) – Directory
instance or absolute path of the target directory.options
(object
) – Options for fs-extra.move
.Move node to another location. baseName
property of the node is joined with targetDir
param for resolving the final path for the node. The method on success updates path-related properties of the node, but node's cached stats (if any) is not refreshed! For updating node's stats, user can call node.renewStats()
or node.renewStatsSync()
methods after moving the node. Uses fs-extra.move
.
const node = new File('/app/resources/style.css'); const dir = new Directory('/app/target_dir'); node.moveTo(dir || '/app/target_dir').then(() => { // node has been moved into '/app/target_dir' directory! node.getPathName(); // → '/app/target_dir/style.css' });
promise
node.moveToSync(targetDir, options)
targetDir
(object
|string
) – Directory
instance or absolute path of the target directory.options
(object
) – Options for fs-extra.move
.Synchronous version of node.moveTo
.
node
node.siblings([patten, options])
Asynchronously select siblings of the node. Uses glob
package.
promise.<draxt>
Promise representing a draxt
collection.node.siblingsSync([pattern, options])
Synchronously select siblings of the node. Uses glob
package.
draxt
A draxt
collection.node.remove()
Remove the node from file system! Directory
nodes can have contents. Like rm -rf
. Wrapper for fs-extra.remove
.
promise
node.parent()
Asynchronously get parent directory node of the node. It's an async method as it gets an instance of fs.Stats
for the parent node asynchronously!
const file = new File('/app/resources/style.css'); file.parent().then(dir => { dir.isDirectory(); // → true dir.getPathName(); // → '/app/resources' });
promise.<node>
Promise representing a Directory
instance.node.parentSync()
Synchronously get parent directory node of the node.
node
A Directory
instance.File
class which extends the Node
class is an interface representing pathNames that their fs.Stats
's .isFile()
method returns true
.
const file = new File(pathName [, stats]);
string
)Name of the node: 'File'
.
number
)Code number for the node: 2
.
string
)Absolute pathName of the node. Example: '/app/readme.md'
.
string
)baseName of the node. Example: 'readme.md'
.
string
)Name of the node without the possible extension. Example 'readme'
.
string
|undefined
)Extension of the node without .
. Example: 'js'
.
string
)pathName of the parent directory of the node.
string
)Root path of the file system.
object
|undefined
)Cached instance of fs.Stats
for the node.
object
)Refers to fs-extra
package.
object
)Refers to glob
package.
file.ensure()
Ensure the file node exists on file system. Wrapper for fs-extra.ensureFile
.
promise
file.ensureSync()
Ensure the file node exists on file system synchronously. Wrapper for fs.ensureFileSync
.
node
file.append()
Asynchronously append data to a file, creating the file if it does not yet exist. data
can be a string or a Buffer. Wrapper for fs.appendFile
.
promise
file.read()
Promisified wrapper for fs.readFile
.
promise
Promise object representing contents of the file.Directory
class which extends the Node
class is an interface representing pathNames that their fs.Stats
's .isDirectory()
method returns true
.
const directory = new Directory(pathName [, stats]);
string
)Name of the node: 'Directory'
.
number
)Code number for the node: 1
.
string
)Absolute pathName of the node. Example: '/app/readme.md'
.
string
)baseName of the node. Example: 'readme.md'
.
string
)Name of the node without the possible extension. Example 'readme'
.
string
|undefined
)Extension of the node without .
. Example: 'js'
.
string
)pathName of the parent directory of the node.
string
)Root path of the file system.
object
|undefined
)Cached instance of fs.Stats
for the node.
object
)Refers to fs-extra
package.
object
)Refers to glob
package.
directory.append(nodes [, options])
nodes
(draxt
|node
|string
|array.<(node|string)>
) – Accepts various parameters:draxt
collection.options
(object
) – Options for fs-extra.move
.Append/move passed directories into this directory node. Uses node.moveTo
which uses fs-extra.move
.
promise.<nodes>
Promise representing array of moved nodes.directory.appendSync(nodes [, options])
nodes
(draxt
|array.<(node|string)>
|string
)options
(object
) – Options for fs-extra.move
.Synchronous version of directory.append
.
node
The directory
node.directory.children([pattern, options])
pattern
(string
) Default: '*'
– Glob pattern relative to the directory. The pattern is used against baseName
of directory child nodes.options
(object
) – Options for glob
package.Asynchronously select children of the directory by using glob
package and return a draxt
collection.
promise.<draxt>
directory.childrenSync([selector, options])
selector
(string
) – Optional selectoroptions
(object
) – Options for glob packageSynchronous version of directory.children
.
draxt
directory.empty()
Ensures that a directory is empty. Deletes directory contents if the directory is not empty. If the directory does not exist, it is created. The directory itself is not deleted. Wrapper for fs-extra.emptyDir
.
promise
directory.emptySync()
Synchronous version of directory.empty
method. Wrapper for fs-extra.emptyDirSync
.
node
directory.ensure()
Asynchronously ensure directory exists. Wrapper for fs-extra.ensureDir
.
promise
directory.ensureSync()
Synchronously ensure directory exists. Wrapper for fs-extra.ensureDirSync
.
node
directory.find(pattern, options)
pattern
(string
) – Glob pattern.options
(object
) – Options for glob
package.Find matching decendants of the directory node. Uses glob
package.
Promise.<draxt>
directory.findSync(selector, options)
selector
(string
)options
(object
) – Options for glob
package.Synchronous version of directory.find
method.
draxt
directory.readdir(options)
options
(string
|object
)Wrapper for promisified fs.readdir
.
promise
directory.readdirSync(options)
options
(string
|object
)Wrapper for fs.readdirSync
.
array
directory.read(options)
options
(string
|object
)Alias for directory.readdir
method.
promise
directory.readSync(options)
options
(string
|object
)Alias for directory.readdirSync
method.
array
directory.rmdir()
Wrapper for promisified fs.rmdir
. Deletes the directory, which must be empty.
promise
directory.rmdirSync()
Wrapper for fs.rmdirSync
. Deletes the directory, which must be empty.
node
SymbolicLink
class which extends the Node
class is an interface representing pathNames that their fs.Stats
's .isSymbolicLink()
method returns true
.
const symbolicLink = new SymbolicLink(pathName [, stats]);
string
)Name of the node: 'SymbolicLink'
.
number
)Code number for the node: 3
.
string
)Absolute pathName of the node. Example: '/app/readme.md'
.
string
)baseName of the node. Example: 'readme.md'
.
string
)Name of the node without the possible extension. Example 'readme'
.
string
|undefined
)Extension of the node without .
. Example: 'js'
.
string
)pathName of the parent directory of the node.
string
)Root path of the file system.
object
|undefined
)Cached instance of fs.Stats
for the node.
object
)Refers to fs-extra
package.
object
)Refers to glob
package.
symbolicLink.isBrokenSync()
Synchronous version of symbolicLink.isBroken
method.
boolean
symbolicLink.readlink(options)
options
(string
|object
) – Options for fs.readlinkSync
.Asynchronously read the value of the symbolic link. Wrapper for fs.readlink
.
promise.<(string|buffer)>
symbolicLink.readlinkSync(options)
options
(string
|object
) – Options for fs.readlinkSync
.Synchronously read the value of the symbolic link. Wrapper for fs.readlinkSync
.
string
| buffer