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> | draxtdraxt.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 // → 1draxt 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 | undefineddraxtCollection.first()Get the first node (if any) from the collection.
node | undefineddraxtCollection.has(item)item (string|node) – A Node instance or a pathNameDoes 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')) // → truebooleandraxtCollection.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.
arraydraxtCollection.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.
promisedraxtCollection.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.
booleandraxtCollection.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.
draxtdraxtCollection.directories()Filter directory nodes (instances of Directory class) and return a new draxt collection.
draxtdraxtCollection.files()Filter file nodes (instances of File class) and return a new draxt collection.
draxtdraxtCollection.symlinks()Filter symbolic link nodes (instances of SymbolicLink class) and return a new draxt collection.
draxtdraxtCollection.empty()Empty the draxt collection. This method doesn't affect file system!
draxtdraxtCollection.drop(node)node (draxt|node|array.<(node|string)>) – Accepts various paramters.Remove node(s) from the current draxt collection by using .pathNames as the criterion.
draxtDraxt 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.
stringnode.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 | undefinednode.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');anynode.getAccessTime()Get "access time" of the node. Returns atime property of the cached stats.
datenode.getModifiedTime()Get "modified time" of the node. Returns mtime property of the cached stats.
datenode.getBirthTime()Get "birthday time" of the node. Returns birthtime property of the cached stats.
datenode.getChangeTime()Get "change time" of the node. Returns ctime property of the cached stats.
datenode.getSize()Get size of the node. Size is simply the size property of the cached fs.Stats instance.
numbernode.isDotFile()Is the node a dot file? i.e. does the node's name begin with dot character.
booleannode.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.
nodenode.getOctalPermissions()Get octal representation of the node's permissions.
node.getOctalPermissions() // → "755"
stringnode.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 }
}objectnode.access([mode])mode (integer) Default: fs.constants.F_OKAsynchronously 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
});promisenode.accessSync([mode])mode (integer) Default: fs.constants.F_OKWrapper for fs.accessSync.
node thisnode.chown(uid, gid)uid (integer) – The user idgid (integer) – The group idWrapper for promisified fs.chown.
promisenode.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.
promisenode.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.
booleannode.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.
promisenode.utimes(atime, mtime)atime (number|string|Date)mtime (number|string|Date)Wrapper for promisified fs.utimes.
promisenode.utimesSync(atime, mtime)atime (number|string|Date)mtime (number|string|Date)Wrapper for fs.utimesSync.
nodenode.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!
});promisenode.copySync(destPath, options)destPath (string) – Destination path.options (object) – Options for fs-extra.copySync.Wrapper for fs-extra.copySync.
nodenode.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'
});promisenode.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.
nodenode.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.
promisenode.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.
promisefile.ensureSync()Ensure the file node exists on file system synchronously. Wrapper for fs.ensureFileSync.
nodefile.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.
promisefile.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.
draxtdirectory.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.
promisedirectory.emptySync()Synchronous version of directory.empty method. Wrapper for fs-extra.emptyDirSync.
nodedirectory.ensure()Asynchronously ensure directory exists. Wrapper for fs-extra.ensureDir.
promisedirectory.ensureSync()Synchronously ensure directory exists. Wrapper for fs-extra.ensureDirSync.
nodedirectory.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.
draxtdirectory.readdir(options)options (string|object)Wrapper for promisified fs.readdir.
promisedirectory.readdirSync(options)options (string|object)Wrapper for fs.readdirSync.
arraydirectory.read(options)options (string|object)Alias for directory.readdir method.
promisedirectory.readSync(options)options (string|object)Alias for directory.readdirSync method.
arraydirectory.rmdir()Wrapper for promisified fs.rmdir. Deletes the directory, which must be empty.
promisedirectory.rmdirSync()Wrapper for fs.rmdirSync. Deletes the directory, which must be empty.
nodeSymbolicLink 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.
booleansymbolicLink.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