Full Code of ramhejazi/draxt for AI

master be2b0edd848b cached
22 files
215.3 KB
63.9k tokens
112 symbols
1 requests
Download .txt
Showing preview only (225K chars total). Download the full file or copy to clipboard to get everything.
Repository: ramhejazi/draxt
Branch: master
Commit: be2b0edd848b
Files: 22
Total size: 215.3 KB

Directory structure:
gitextract_u4ieoxxi/

├── .editorconfig
├── .eslintrc.js
├── .gitignore
├── .prettierrc
├── .travis.yml
├── LICENSE
├── README.md
├── _config.yml
├── docs/
│   └── index.html
├── package.json
├── src/
│   ├── draxt.js
│   ├── interfaces/
│   │   ├── Directory.js
│   │   ├── File.js
│   │   ├── Node.js
│   │   ├── SymbolicLink.js
│   │   └── index.js
│   └── util.js
└── test/
    ├── draxt.js
    └── interfaces/
        ├── Directory.js
        ├── File.js
        ├── Node.js
        └── SymbolicLink.js

================================================
FILE CONTENTS
================================================

================================================
FILE: .editorconfig
================================================
root = true

[*]
indent_style = tab
indent_size = 2
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

[*.md]
trim_trailing_whitespace = false

================================================
FILE: .eslintrc.js
================================================
module.exports = {
    env: {
        commonjs: true,
        es6: true,
        node: true,
    },
    globals: {
        console: true,
    },
    extends: 'eslint:recommended',
    rules: {
        indent: ['error', 4],
        'no-console': 0,
        'linebreak-style': ['error', 'unix'],
        quotes: [1, 'single'],
    },
};


================================================
FILE: .gitignore
================================================
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# Runtime data
pids
*.pid
*.seed
*.pid.lock

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage

# nyc test coverage
.nyc_output

# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# Bower dependency directory (https://bower.io/)
bower_components

# node-waf configuration
.lock-wscript

# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release

# Dependency directories
node_modules/
jspm_packages/

# TypeScript v1 declaration files
typings/

# Optional npm cache directory
.npm

# Optional eslint cache
.eslintcache

# Optional REPL history
.node_repl_history

# Output of 'npm pack'
*.tgz

# Yarn Integrity file
.yarn-integrity

# dotenv environment variables file
.env

# next.js build output
.next

.DS_Store


================================================
FILE: .prettierrc
================================================
{
    "trailingComma": "es5",
    "printWidth": 100,
    "tabWidth": 4,
    "semi": true,
    "singleQuote": true
}


================================================
FILE: .travis.yml
================================================
language: node_js

node_js:
  - '6'
  - '8'

before_install:
  - if [[ `npm -v` == 2.* ]]; then npm install --global npm@3; fi

after_success: npm run coverage


================================================
FILE: LICENSE
================================================
MIT License

Copyright (c) 2018 Ram Hejazi

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

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 OR COPYRIGHT HOLDERS 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.


================================================
FILE: README.md
================================================
<div align="center" style="text-align:center">
<a link="https://github.com/ramhejazi/draxt"><img width="300px" style="padding: 20px" alt="draxt.js logo" src="draxt-logo.svg"></a><br>
<a href="https://github.com/ramhejazi/draxt/blob/master/LICENSE"><img alt="draxt license" src="https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square"></a>
<a href="https://www.npmjs.com/package/draxt"><img alt="npm-link" src="https://img.shields.io/npm/v/draxt.svg?style=flat-square"></a>
<a href="https://coveralls.io/github/ramhejazi/draxt"><img alt="draxt coverage status" src="https://img.shields.io/coveralls/github/ramhejazi/draxt.svg?style=flat-square"></a>
</div>
<br>

`draxt` is a utility module for selecting and manipulating filesystem objects in a Node.js environment.
It uses [glob] patterns as its "selector engine". `draxt` also provides several DOM-like interfaces representing filesystem objects which build on promisified APIs for the [`fs`] and [`fs-extra`] modules.

**Example directory structure:**

```
/app/
 ├── controllers/
 │   └── index.js
 ├── public/
 │   ├── script.js
 │   └── style.css
 └── views/
     └── index.html
```

```js
const $ = require('draxt');

(async () => {
    // Select `/app` directory content 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('/tmp'); // or `.moveToSync('/tmp')`

            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 '/tmp'!
            const parentNode = node.parentSync(); // or `await node.parent()`

            // is the directory empty?
            console.log(parentNode.isEmptySync()); // → `false`
        });
})();
```

**Key notes**:

-   `draxt` has only 2 dependencies: [`glob`] and [`fs-extra`] modules.
-   `draxt` uses `glob` patterns to select filesystem objects.
-   Each item in a `draxt` collection is an instance of a [`File`], [`Directory`], or [`SymbolicLink`] class, which is a subclass of [`Node`].
-   Every asynchronous method has a synchronous version. E.g., [`node.siblingsSync()`] for [`node.siblings()`].
-   `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.

```js
const draxt = require('draxt');
// Add a method (`images`) for filtering image files.
draxt.fn.images = function() {
    const imgExtensions = ['jpeg', 'jpg', 'png', 'git', ...];
    return this.filter(node => {
       return node.isFile() && imgExtensions.indexOf(node.extension) > -1;
    });
}
```

## Install

Installing via [npm]:

```bash
$ npm i draxt
```

Via [yarn]:

```bash
$ yarn add draxt
```

## Docs

-   [`draxt` APIs][draxt-doc]
-   Interfaces
    -   [`Node`]
    -   [`File`]
    -   [`Directory`]
    -   [`SymbolicLink`]

## Test

In the past, mock-fs was used for mocking test file system, but since the package is not compatible with
newer versions of node.js, now regular linux cmds like `mkdir` and `echo` are used for creating test files and
folders. The test fs structure are created in `/tmp` directory. That being said, for now, tests only work on Linux!

```bash
$ npm run test
```

## License

[Licensed under MIT.][license]

[repo]: https://github.com/ramhejazi/draxt
[logo]: draxt-logo.jpg
[license]: https://github.com/ramhejazi/draxt/blob/master/LICENSE
[license-badge]: https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square
[coverall]: https://coveralls.io/github/ramhejazi/draxt
[coverall-badge]: https://img.shields.io/coveralls/github/ramhejazi/draxt.svg?style=flat-square
[npm-link]: https://www.npmjs.com/package/draxt
[npm-badge]: https://img.shields.io/npm/v/draxt.svg?style=flat-square
[travis-link]: https://travis-ci.org/ramhejazi/draxt
[travis-badge]: https://img.shields.io/travis/ramhejazi/draxt.svg?style=flat-square
[deps-status-link]: https://david-dm.org/ramhejazi/draxt
[deps-status-badge]: https://david-dm.org/ramhejazi/draxt.svg?style=flat-square
[npm]: https://docs.npmjs.com/getting-started/what-is-npm
[yarn]: https://yarnpkg.com/en/
[glob]: https://en.wikipedia.org/wiki/Glob_(programming)
[`fs`]: https://nodejs.org/api/fs.html
[`fs-extra`]: https://github.com/jprichardson/node-fs-extra
[`glob`]: https://github.com/isaacs/node-glob
[Pahlavi language]: https://en.wikipedia.org/wiki/Middle_Persian
[draxt-doc]: https://ramhejazi.github.io/draxt#draxt
[`Node`]: https://ramhejazi.github.io/draxt#interfaces-node
[`File`]: https://ramhejazi.github.io/draxt#interfaces-file
[`Directory`]: https://ramhejazi.github.io/draxt#interfaces-directory
[`SymbolicLink`]: https://ramhejazi.github.io/draxt#interfaces-symboliclink
[`draxt.extend`]: https://ramhejazi.github.io/draxt#draxt-extend
[`node.siblingsSync()`]: https://ramhejazi.github.io/draxt#node-siblings
[`node.siblings()`]: https://ramhejazi.github.io/draxt#node-siblings


================================================
FILE: _config.yml
================================================
theme: jekyll-theme-minimal

================================================
FILE: docs/index.html
================================================
<!doctype html><html class=no-js lang=en><head><meta charset=utf-8><meta http-equiv=x-ua-compatible content="ie=edge"><title>draxt.js – NodeList-like/jQuery-like package for File System (node.js)</title><meta name=description content="draxt is a utility module for selecting and manipulating filesystem objects in a Node.js environment. It uses glob patterns as its selector engine. draxt also provides several DOM-like interfaces representing filesystem objects which build on promisified APIs for the fs and fs-extra modules."><meta name=viewport content="width=device-width,initial-scale=1,shrink-to-fit=no"><link rel=apple-touch-icon href=icon.png><script src=https://cdnjs.cloudflare.com/ajax/libs/prettify/r298/prettify.min.js defer=defer></script><style media=all>body{font-size:14px;line-height:22px;background:#f7ffee12;color:#000;font-family:Helvetica Neue,Helvetica,Arial}.interface{font-family:Helvetica,Arial,sans-serif}div#sidebar{background:#000;position:fixed;top:0;left:0;bottom:0;width:200px;overflow-y:auto;overflow-x:hidden;-webkit-overflow-scrolling:touch;padding:15px 0 30px 30px}#sidebar a{text-decoration:none}#sidebar a:hover{text-decoration:underline}a.toc_title,a.toc_title:visited{display:block;color:#f0af00;font-weight:bold;margin-top:15px;font-size:15px}a.toc_title:hover{text-decoration:underline}#sidebar .version{font-size:12px;font-weight:normal}ul.toc_section{font-size:11px;line-height:14px;margin:5px 0 0 0;padding-left:0;list-style-type:none}.toc_section li{margin:0}.toc_section a{text-decoration:none;color:#c7c7c7;line-height:18px;font-size:12px;margin-bottom:4px;display:block}::-webkit-scrollbar{width:12px}::-webkit-scrollbar-track{background:black}::-webkit-scrollbar-thumb{background:#565656}a{color:#d0850c}.toc_section li a:hover{text-decoration:underline}input#function_filter{width:80%}div.container{width:550px;margin:40px 0 50px 260px}div.warning{margin-top:15px;font:bold 11px Arial;color:#700}p{width:550px}a:hover{text-decoration:underline}h1,h2,h3,h4,h5,h6{padding-top:20px;color:#8b572a}h2{font-size:22px}h3{font-size:18px}b.header{font-size:16px;line-height:30px}b.header a{color:inherit;text-decoration:none}b.header a:hover{color:#d0850c;text-decoration:underline}div.mds{padding-bottom:15px;border-bottom:1px solid #eee;margin-bottom:15px;position:relative}.st{display:block;color:#878787}.msl{position:absolute;right:0;bottom:15px;display:none}.mds:hover .msl{display:block}.h{position:relative;color:inherit;text-decoration:none}.h:hover:before{position:absolute;content:'#';left:-16px}span.alias{font-size:14px;font-style:italic;margin-left:20px}table,tr,td{margin:0;padding:0}td{padding:2px 12px 2px 0}table .rule{height:1px;background:#ccc;margin:5px 0}a.toc_sub_header{color:white;font-size:13px;font-weight:bold}.sub_section{padding:0 0 8px 10px}ul{list-style-type:circle;padding:0 0 0 20px}li{margin-bottom:10px}code,pre,tt{font-size:inherit;line-height:18px;font-style:normal;font-family:"Droid Sans Mono",consolas,"PT Mono",monospace}tt{padding:0 3px;background:#fff;border:1px solid #ddd;zoom:1}.mp li p{margin:0}pre{font-size:13px;padding:2px 0 2px 15px;border-left:5px solid #d0840c;margin:0 0 30px}@media only screen and (-webkit-min-device-pixel-ratio:1.5) and (max-width:640px),only screen and (-o-min-device-pixel-ratio:3/2) and (max-width:640px),only screen and (min-device-pixel-ratio:1.5) and (max-width:640px){img{max-width:100%}div#sidebar{-webkit-overflow-scrolling:initial;position:relative;width:90%;height:120px;left:0;top:-7px;padding:10px 0 10px 30px;border:0}img#logo{width:auto;height:auto}div.container{margin:0;width:100%}p,div.container ul{max-width:98%;overflow-x:scroll}pre{overflow:scroll}}.ms{margin-left:15px}.pln{color:#000}@media screen{.str{color:#d0850c}.kwd{color:#8b572a}.com{color:#aeaeae}.typ{color:#606}.lit{color:#066}.pun,.opn,.clo{color:#660}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec,.var{color:#606}.fun{color:red}}@media print,projection{.str{color:#060}.kwd{color:#006;font-weight:bold}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:bold}.lit{color:#044}.pun,.opn,.clo{color:#440}.tag{color:#006;font-weight:bold}.atn{color:#404}.atv{color:#060}}ol.linenums{margin-top:0;margin-bottom:0}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee}</style></head><body onload=PR.prettyPrint()><div id=sidebar class=interface><a class=toc_title href=#introduction>Draxt.js <span class=version>(0.4.6)</span> </a><a class=toc_title href=#>Introduction </a><a class=toc_title href=#queries>Queries </a><a class=toc_title href=#draxt>Draxt</a><ul class=toc_section><li><a class=st href=#draxt-static-methods>Static Methods</a><ul class=sub_section><li><a href=#draxt-sync>-&nbsp; sync</a></li><li><a href=#draxt-extend>-&nbsp; extend</a></li></ul></li><li><a class=st href=#draxt-methods>Methods</a><ul class=sub_section><li><a href=#draxt-add>-&nbsp; add</a></li><li><a href=#draxt-get>-&nbsp; get</a></li><li><a href=#draxt-first>-&nbsp; first</a></li><li><a href=#draxt-last>-&nbsp; last</a></li><li><a href=#draxt-has>-&nbsp; has</a></li><li><a href=#draxt-slice>-&nbsp; slice</a></li><li><a href=#draxt-filter>-&nbsp; filter</a></li><li><a href=#draxt-foreach>-&nbsp; forEach</a></li><li><a href=#draxt-each>-&nbsp; each</a></li><li><a href=#draxt-map>-&nbsp; map</a></li><li><a href=#draxt-mapasync>-&nbsp; mapAsync</a></li><li><a href=#draxt-some>-&nbsp; some</a></li><li><a href=#draxt-sort>-&nbsp; sort</a></li><li><a href=#draxt-reverse>-&nbsp; reverse</a></li><li><a href=#draxt-directories>-&nbsp; directories</a></li><li><a href=#draxt-files>-&nbsp; files</a></li><li><a href=#draxt-symlinks>-&nbsp; symlinks</a></li><li><a href=#draxt-empty>-&nbsp; empty</a></li><li><a href=#draxt-drop>-&nbsp; drop</a></li></ul></li></ul><a class=toc_title href=#interfaces>Interfaces</a><ul class=toc_section><li><a class=toc_sub_header href=#interfaces-node>Node</a> <a class=st href=#interfaces-node-props>Properies</a> <a class=st href=#interfaces-node-static-methods>Static Methods</a><ul class=sub_section><li><a href=#node-rawquery>-&nbsp; rawQuery</a></li><li><a href=#node-rawquerysync>-&nbsp; rawQuerySync</a></li><li><a href=#node-tonodes>-&nbsp; toNodes</a></li><li><a href=#node-tonodessync>-&nbsp; toNodesSync</a></li><li><a href=#node-query>-&nbsp; query</a></li><li><a href=#node-querysync>-&nbsp; querySync</a></li></ul><a class=st href=#interfaces-node-methods>Methods</a><ul class=sub_section><li><a href=#node-getpathname>-&nbsp; getPathName</a></li><li><a href=#node-getbasename>-&nbsp; getBaseName</a></li><li><a href=#node-getextension>-&nbsp; getExtension</a></li><li><a href=#node-getname>-&nbsp; getName</a></li><li><a href=#node-getparentpath>-&nbsp; getParentPath</a></li><li><a href=#node-getcachedstats>-&nbsp; getCachedStats</a></li><li><a href=#node-getstatprop>-&nbsp; getStatProp</a></li><li><a href=#node-getaccesstime>-&nbsp; getAccessTime</a></li><li><a href=#node-getmodifiedtime>-&nbsp; getModifiedTime</a></li><li><a href=#node-getbirthtime>-&nbsp; getBirthTime</a></li><li><a href=#node-getchangetime>-&nbsp; getChangeTime</a></li><li><a href=#node-getsize>-&nbsp; getSize</a></li><li><a href=#node-isdirectory>-&nbsp; isDirectory</a></li><li><a href=#node-isfile>-&nbsp; isFile</a></li><li><a href=#node-issymboliclink>-&nbsp; isSymbolicLink</a></li><li><a href=#node-isdotfile>-&nbsp; isDotFile</a></li><li><a href=#node-renewstats>-&nbsp; renewStats</a></li><li><a href=#node-renewstatssync>-&nbsp; renewStatsSync</a></li><li><a href=#node-getoctalpermissions>-&nbsp; getOctalPermissions</a></li><li><a href=#node-getpermissions>-&nbsp; getPermissions</a></li><li><a href=#node-access>-&nbsp; access</a></li><li><a href=#node-accesssync>-&nbsp; accessSync</a></li><li><a href=#node-chmod>-&nbsp; chmod</a></li><li><a href=#node-chmodsync>-&nbsp; chmodSync</a></li><li><a href=#node-lchmod>-&nbsp; lchmod</a></li><li><a href=#node-lchmodsync>-&nbsp; lchmodSync</a></li><li><a href=#node-chown>-&nbsp; chown</a></li><li><a href=#node-chownsync>-&nbsp; chownSync</a></li><li><a href=#node-lchown>-&nbsp; lchown</a></li><li><a href=#node-lchownsync>-&nbsp; lchownSync</a></li><li><a href=#node-exists>-&nbsp; exists</a></li><li><a href=#node-existssync>-&nbsp; existsSync</a></li><li><a href=#node-stat>-&nbsp; stat</a></li><li><a href=#node-statsync>-&nbsp; statSync</a></li><li><a href=#node-lstat>-&nbsp; lstat</a></li><li><a href=#node-lstatsync>-&nbsp; lstatSync</a></li><li><a href=#node-link>-&nbsp; link</a></li><li><a href=#node-linksync>-&nbsp; linkSync</a></li><li><a href=#node-rename>-&nbsp; rename</a></li><li><a href=#node-renamesync>-&nbsp; renameSync</a></li><li><a href=#node-utimes>-&nbsp; utimes</a></li><li><a href=#node-utimessync>-&nbsp; utimesSync</a></li><li><a href=#node-copy>-&nbsp; copy</a></li><li><a href=#node-copysync>-&nbsp; copySync</a></li><li><a href=#node-moveto>-&nbsp; moveTo</a></li><li><a href=#node-movetosync>-&nbsp; moveToSync</a></li><li><a href=#node-appendto>-&nbsp; appendTo</a></li><li><a href=#node-appendtosync>-&nbsp; appendToSync</a></li><li><a href=#node-siblings>-&nbsp; siblings</a></li><li><a href=#node-siblingssync>-&nbsp; siblingsSync</a></li><li><a href=#node-remove>-&nbsp; remove</a></li><li><a href=#node-removesync>-&nbsp; removeSync</a></li><li><a href=#node-parent>-&nbsp; parent</a></li><li><a href=#node-parentsync>-&nbsp; parentSync</a></li></ul></li><li><a class=toc_sub_header href=#interfaces-file>File</a> <a class=st href=#interfaces-file-props>Properies</a> <a class=st href=#interfaces-file-methods>Methods</a><ul class=sub_section><li><a href=#file-ensure>-&nbsp; ensure</a></li><li><a href=#file-ensuresync>-&nbsp; ensureSync</a></li><li><a href=#file-append>-&nbsp; append</a></li><li><a href=#file-appendsync>-&nbsp; appendSync</a></li><li><a href=#file-read>-&nbsp; read</a></li><li><a href=#file-readsync>-&nbsp; readSync</a></li><li><a href=#file-truncate>-&nbsp; truncate</a></li><li><a href=#file-truncatesync>-&nbsp; truncateSync</a></li><li><a href=#file-write>-&nbsp; write</a></li><li><a href=#file-writesync>-&nbsp; writeSync</a></li></ul></li><li><a class=toc_sub_header href=#interfaces-directory>Directory</a> <a class=st href=#interfaces-directory-props>Properies</a> <a class=st href=#interfaces-directory-methods>Methods</a><ul class=sub_section><li><a href=#directory-append>-&nbsp; append</a></li><li><a href=#directory-appendsync>-&nbsp; appendSync</a></li><li><a href=#directory-children>-&nbsp; children</a></li><li><a href=#directory-childrensync>-&nbsp; childrenSync</a></li><li><a href=#directory-empty>-&nbsp; empty</a></li><li><a href=#directory-emptysync>-&nbsp; emptySync</a></li><li><a href=#directory-ensure>-&nbsp; ensure</a></li><li><a href=#directory-ensuresync>-&nbsp; ensureSync</a></li><li><a href=#directory-isempty>-&nbsp; isEmpty</a></li><li><a href=#directory-isemptysync>-&nbsp; isEmptySync</a></li><li><a href=#directory-find>-&nbsp; find</a></li><li><a href=#directory-findsync>-&nbsp; findSync</a></li><li><a href=#directory-readdir>-&nbsp; readdir</a></li><li><a href=#directory-readdirsync>-&nbsp; readdirSync</a></li><li><a href=#directory-read>-&nbsp; read</a></li><li><a href=#directory-readsync>-&nbsp; readSync</a></li><li><a href=#directory-rmdir>-&nbsp; rmdir</a></li><li><a href=#directory-rmdirsync>-&nbsp; rmdirSync</a></li></ul></li><li><a class=toc_sub_header href=#interfaces-symboliclink>SymbolicLink</a> <a class=st href=#interfaces-symboliclink-props>Properies</a> <a class=st href=#interfaces-symboliclink-methods>Methods</a><ul class=sub_section><li><a href=#symboliclink-isbroken>-&nbsp; isBroken</a></li><li><a href=#symboliclink-isbrokensync>-&nbsp; isBrokenSync</a></li><li><a href=#symboliclink-readlink>-&nbsp; readlink</a></li><li><a href=#symboliclink-readlinksync>-&nbsp; readlinkSync</a></li></ul></li></ul></div><div class=container><p id=introduction><img id=logo src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAPwAAABICAMAAADlLmg2AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAGNQTFRF4tXKqIFfxauU58KF+PTy8+HC3KRJkmI3oXdSmmxF8Orkt5Z66d/X08CvvqGI7dGk9ujRzLWhr4xt+fDh044b28q8/Pfw4rRn2Z061pUq36xY8Nmz6sqU5bt30IYMi1cq////ECnGkwAAACF0Uk5T//////////////////////////////////////////8An8HQIQAABkxJREFUeNrkm9eioyAQhoEQe2/p6vs/5WoUpYuJ2d1E7k4OEj4Zhn9mCGjlDQOQIgSh2zRp+2Utvx9uRh2B+FEIod3QLfou9kfdtUvyGjxquAa/j72ui3yH8Hk9ttMO4W8E/rxD+DuBL16Cb9sAdI7+/4LvZtS35Y4Jgb++CP9s/xd8NkzFoOd5hL/9DDxujOGTwtTffQt8aQ7fVgfLuh7b34Efrb4B2zqSr4AnVr9L+HDP8M6O4UGzY3hnx/B+swY+Od4PJ0s86qpj93HXrod7IocHCA66FmYqeA+kXSc7nB7x+4WBHuOdSwSH5bJhhgKVEfPxA/fZMDcAZf3lr8GyiLituXj+eK2pVpxuPDzw7UY5safTjfrMDpPiAK4wGS91uAFchF+FL92mMYen+JilT6yab0VMwwdQ8TUzPOQ/xb4wmVA6jBu8CK+c1Br4eOTtrZ5I//oww+OoaVbDY4efTKhaKDv4d/ADO3EDVWxx8Nhp1sMzD/UDBZpRnNnEJL3c5yZic4dOsBq+Te7XCw9/fP4dU71ODHwwf6uNetcVRAbwGTcZr9G1kPaHDL8NJpfgES0XAclXLsP37cDBWyMqF/MTeDwbq+OJximHj1JhMpkO3mGODFvxXkYn4tOdqa81yGbw8EN2o2K6FBT8PLqNded8EFFbOrIFeLL0LkQIlSmKmAXGshh1+FaP+5h5UW/C3yUJvesMTyXtyiWRE0z4tsQM/X73lhQlsFWGimRWMRqEjTeEf/55ERN9Azxlgs6ywoO6PYhTTynL+YkzewQxOpZTRRvA15xf7M684Zz3pZvPEL5XcD7UOCBHNXHsCu8OibPYCj6Wa3tsy7elAbwdjWuEUxss5GA4J8YeMd1uwZOVCNWx9+CHRP6lksKHCoe8DO9T78rzFFNB6vgo5AqCriKMeg9+LOGcKxl8pqhILsMvh1gYAF8THPo0fYAmE9gUnuSyL0cJPPX96WbwIPWhu1z4oY9Cx+Zk8FbwMVG8QpwLgEo1vQyPw0yvklVaR+bsNoCfyhid7ceM8YNwY3hPERfLcyJ8kCOFexe+OtORfE5nL7aFRwbxkbp/1n4CnqHvrP8mhcfvwnPBoQ0jquAJF45C5R2Qt+GnGwtju8QS+PZNeIbdHtJXaAGeDQXLD8G3OZPGqq1kc3haABERsATP2Yr3IfgO/1TQWazbxnue9p2+gcgRjvr+wMOfgp9zOFMJe0t46mB3WzP4UHCL/ufgn8s/r33OwpdvwQOpXNLCj/I+tbUn/YbwfQF7vrEEStUpuxpebkM6eEzUPJMUCj4K360+Mf4cBKqT+C/Aw6kz5AK8T8KTHnXMaPuVIS1Q+3oj+GhWNozOhZ+Gb4dz78BEdSuTGUDtuEMD+JJe6FQjct+D7ysVguUTeNrhuluZfbYMT3IZshw12BBeUrgbY50Dm8mhBser4UPp9DMFPFGDkSzAY7XOyiuBEnghiWWN8GxsQezVc1bDe2whYjj+VMOQlzJ7N6RM8kP+DAWpPz1XPTrhdk308A/pyncOj136xu9PmsBXhmMakcMq1QyhyFUOg8QxHJXWgZoC0BiwFYkWnt/01XjU8c5GVmsBYC4oaeBL/TAuQsjjtggdwwaqrAbSBMhEsly08EUl2RnXFsgEtqQo0ffDKILM8rgQ+giV2iUShwmZBJcLo/6NgEyo7zq+p3upwz8v4mUECXx9Zm7fD4mtfCxU+rKasjBroFhSVTj/JCiXq85AtbpADBp4nygpScvgOzE7pTCSE8nkA0ZvUFblte5qeJHex3gD+ED8F4mYC1P4fuefDoeHNT4RU9dS2Jsvbsibgxl8B8FINcAv22vwTMmvN6cUM6V27Z5nb+OQ7gl7JyeIxlm5/rCLMZklhCjEhvAtTsfHnLGcQ0qbNozSp998AX4etfMETD2wKoQL5mICM74WDPo5lt3GwgAEbGIbeMx/pU1MTbHDYPq06H/KwDU8PCI2zI8KsDxGu9yWtH0SP6zO4gvLesR5K7+K9o0tPyZrA5vfgZdK1zrfM3y7T/jLnuFrmZrfCfzR+PdFPwivuYby+/BnY2f/e/BH0x/S/iK8ZW71Pwd/qiV3DncBX8WX2ljb/hT87WRRvyPYGfxUgKzv7W7hraTdH3xytSzrdM9XPPJHgAEAhXdQlyjnaUAAAAAASUVORK5CYII=" alt="draxt.js logo"></p><a href=https://github.com/ramhejazi/draxt/blob/master/LICENSE><img alt="draxt license" src="https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square"></a>&nbsp; <a href=https://travis-ci.org/ramhejazi/draxt><img alt="draxt build state" src="https://img.shields.io/travis/ramhejazi/draxt.svg?style=flat-square"></a>&nbsp; <a href=https://coveralls.io/github/ramhejazi/draxt><img alt="draxt coverage status" src="https://img.shields.io/coveralls/github/ramhejazi/draxt.svg?style=flat-square"></a>&nbsp; <a href=https://david-dm.org/ramhejazi/draxt><img alt="dependencies status" src="https://david-dm.org/ramhejazi/draxt.svg?style=flat-square"></a><p><a href=http://github.com/ramhejazi/draxt/ >Draxt</a> is an open-source utility module for selecting and manipulating filesystem objects in a <a target=_blank href=https://nodejs.org/ >Node.js</a> environment. It uses <a target=_blank href=https://en.wikipedia.org/wiki/Glob_(programming)>glob patterns</a> as its "selector engine" to select filesytem objects (files, directories, ...).</p><p>Draxt also provides several <a href=#interfaces>DOM-like interfaces</a> representing filesystem objects which build on promisified APIs for the <a target=_blank href=https://nodejs.org/api/fs.html>fs</a> and <a target=_blank href=https://github.com/jprichardson/node-fs-extra>fs-extra</a>.</p><h3 id=why><a class=h href=#why>Why?</a></h3><p>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.</p><h3 id=key-points><a class=h href=#key-points>Key Points</a></h3><ul><li>Draxt has only 2 dependencies: <a href=https://github.com/isaacs/node-glob>glob</a> and <a href=https://github.com/jprichardson/node-fs-extra>fs-extra</a> modules.</li><li>Draxt uses <code>glob</code> patterns to select filesystem objects.</li><li>Each item in a <code>draxt</code> collection is an instance of a <a href=#interfaces-file><code>File</code></a>, <a href=#interfaces-directory><code>Directory</code></a>, or <a href=#interfaces-symboliclink><code>SymbolicLink</code></a> class, which is a subclass of <a href=#interfaces-node><code>Node</code></a>.</li><li>Every asynchronous method has a synchronous version. E.g., <a href=#node-siblingssync><code>node.siblingsSync()</code></a> for <a href=#node-siblings><code>node.siblings()</code></a>.</li><li>Interfaces function-wrappers for <code>fs</code> and <code>fs-extra</code> functions use the same names as the original functions. E.g. <a href=#node-lchmod><code>file.lchmod()</code></a> is a wrapper for promisified <a href=https://nodejs.org/api/fs.html#fs_fs_lchmod_path_mode_callback target=_blank><code>fs.lchmod()</code></a>.</li><li>Interfaces synchronous methods that do not work as a getter – like the <a href=#node-chmodsync><code>node.chmodSync()</code></a> – are chainable.</li><li><code>draxt</code> is a simple constructor function. You can extend/overwrite its methods via its <code>prototype</code> property (or its <code>fn</code> alias) or by using the <a href=#draxt-extend><code>draxt.extend()</code></a> method.</li></ul><p>The project is <a target=_blank href=https://github.com/ramhejazi/draxt>hosted on GitHub</a>. You can report bugs and discuss features on the <a target=_blank href=https://github.com/ramhejazi/draxt/issues>issues page</a>.</p><h3 id=example><a class=h href=#example>Example</a></h3><pre class=prettyprint>
// 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`
});
})();</pre><h3 id=installation><a class=h href=#installation>Installation</a></h3><ul><li><b>npm</b> <tt>npm install draxt</tt></li><li><b>yarn</b> <tt>yarn add draxt</tt></li></ul><div id=documentation><h2 id=queries><a class=h href=#queries>Queries (Globbing)</a></h2><p><code>draxt</code> module exports a constructor function. Whenever a <code>string</code> is passed as the first parameter to the function, parameters are passed to the <a target=_blank href=https://github.com/isaacs/node-glob>glob</a> package. The matching pathNames returned by the glob package, if any, are converted into an array of <a href=#interfaces>node</a> instances. The returned value of <code>draxt</code> is a draxt instance (a draxt collection) which wraps an array of nodes. In this respect, <code>draxt</code> constructor function works like jQuery function, but unlike jQuery collections, draxt collections are not array-like objects. <code>draxt</code> collections store the array of nodes as a property named <code>items</code>. The <code>length</code> property of draxt collections is a <a href=https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get target=_blank><code>getter</code></a> for the collection's <code>items.length</code> property.</p><pre class=prettyprint>
// 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)
			</pre><h2 id=draxt><a class=h href=#draxt>Draxt</a></h2><p><a href=#draxt><code>draxt</code></a> function is the main method of <a href=#draxt><code>draxt</code></a> package. The function can be called with <code>new</code> as a constructor function (not recommended) and without <code>new</code> as a factory function. <a href=#draxt><code>draxt</code></a> uses promisified <a href=https://github.com/isaacs/node-glob><code>glob</code></a> package as it&#39;s selector engine. All query results of <a href=https://github.com/isaacs/node-glob><code>glob</code></a> package are converted into one of <a href=#interfaces-node><code>Node</code></a>&#39;s sub-class (<a href=#interfaces-file><code>File</code></a>, <a href=#interfaces-directory><code>Directory</code></a> or <a href=#interfaces-symboliclink><code>SymbolicLink</code></a>) instances by analyzing pathNames&#39; <a href=https://nodejs.org/api/fs.html#fs_class_fs_stats><code>fs.Stats</code></a> object. The returned value of <a href=#draxt><code>draxt</code></a> is a <a href=#draxt><code>draxt</code></a> collection which to some extent works like jQuery collections but unlike jQuery collections it&#39;s not an array-like object. The collection items are stored as an array property (<code>.items</code>).</p><h4 id=draxt-syntax><a class=h href=#draxt-syntax>Syntax:</a></h4><pre class=prettyprint>const draxtCollection = draxt([pattern, options])</pre><div class=mp><ul><li><code>pattern</code> (<code>string</code>|<code>array.&lt;node&gt;</code>|<code>node</code>|<code>draxt</code>)&nbsp;&nbsp;–&nbsp;&nbsp;<code>pattern</code> parameter can contain several values:<ul><li><code>string</code> which is passed to <a href=https://github.com/isaacs/node-glob><code>glob</code></a> package as <a href=https://github.com/isaacs/node-glob><code>glob</code></a> pattern. In this case <a href=#draxt><code>draxt</code></a> returns a <code>promise</code> object representing a <a href=#draxt><code>draxt</code></a> collection/instance.</li><li>A <a href=#interfaces-node><code>Node</code></a> or one it&#39;s sub-classes (<a href=#interfaces-file><code>File</code></a>, <a href=#interfaces-directory><code>Directory</code></a> or <a href=#interfaces-symboliclink><code>SymbolicLink</code></a>) instance. In this case a <a href=#draxt><code>draxt</code></a> collection containing the passed <code>node</code> is returned.</li><li>An array of <code>node</code> instances.</li><li>A <a href=#draxt><code>draxt</code></a> collection to clone (shallow).</li><li><code>undefined</code> which returns an empty <a href=#draxt><code>draxt</code></a> collection.</li></ul></li><li><code>options</code> (<code>object</code>|<code>string</code>)&nbsp;&nbsp;–&nbsp;&nbsp;Options for <a href=https://github.com/isaacs/node-glob><code>glob</code></a> package. The <code>options</code> parameter can also be a string representing a pathName which will be used as context for the query, similar to jQuery&#39;s <a href=http://api.jquery.com/jQuery/#jQuery-selector-context><code>$(selector, context)</code></a> syntax.</li></ul></div><div class=mret>→ <code>promise.&lt;draxt&gt;</code> | <code>draxt</code></div><h4 id=draxt-static-methods><a class=h href=#draxt-static-methods>Static Methods:</a></h4><div class=mds id=draxt-sync><b class=header><a class=h href=#draxt-sync>sync</a></b><code class=ms>draxt.sync(pattern [, options])</code><div class=mp><ul><li><code>pattern</code> (<code>string</code>)&nbsp;&nbsp;–&nbsp;&nbsp;Glob pattern.</li><li><code>options</code> (<code>object</code>)&nbsp;&nbsp;–&nbsp;&nbsp;Options for <a href=https://github.com/isaacs/node-glob><code>glob</code></a> package.</li></ul></div><p></p><p>Synchronously query the file system by using <a href=https://github.com/isaacs/node-glob><code>glob</code></a> package and return a new <a href=#draxt><code>draxt</code></a> collection.</p><p></p><div class=mret>→ <code>draxt</code> An instance of <a href=#draxt><code>draxt</code></a>, a.k.a. a <em>draxt collection</em>.</div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/draxt.js#L111>source</a></div><div class=mds id=draxt-extend><b class=header><a class=h href=#draxt-extend>extend</a></b><code class=ms>draxt.extend(methods)</code><div class=mp><ul><li><code>methods</code> (<code>object</code>)</li></ul></div><p></p><p>Extend <a href=#draxt><code>draxt</code></a> by adding methods to it&#39;s <code>prototype</code>. Basically works like <code>jQuery.fn.extend</code>.</p><p></p><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/draxt.js#L120>source</a></div><h4 id=draxt-methods><a class=h href=#draxt-methods>Methods:</a></h4><div class=mds id=draxt-add><b class=header><a class=h href=#draxt-add>add</a></b><code class=ms>draxtCollection.add(items)</code><div class=mp><ul><li><code>items</code> (<code>node</code>|<code>array.&lt;node&gt;</code>|<code>draxt</code>)&nbsp;&nbsp;–&nbsp;&nbsp;Instance of Node or array of nodes or a <a href=#draxt><code>draxt</code></a> collection.</li></ul></div><p></p><p>Add node(s) to current <a href=#draxt><code>draxt</code></a> collection. Pre-exising nodes will not be added to the collection.</p><p></p><pre class=prettyprint>const draxtCollection = draxt();
draxtCollection.add(new Node('/pathName'));
draxtCollection.length // → 1</pre><div class=mret>→ <code>draxt</code> An instance of <a href=#draxt><code>draxt</code></a>.</div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/draxt.js#L134>source</a></div><div class=mds id=draxt-get><b class=header><a class=h href=#draxt-get>get</a></b><code class=ms>draxtCollection.get([index])</code><div class=mp><ul><li><code>index</code> (<code>number</code>)&nbsp;&nbsp;–&nbsp;&nbsp;Index of node in items collection.</li></ul></div><p></p><p>Get one or all nodes from the <a href=#draxt><code>draxt</code></a> collection. With an <code>index</code> specified, <code>.get(index)</code> retrieves a single node otherwise retrives all the nodes (if any).</p><p></p><div class=mret>→ <code>array.&lt;node&gt;</code> | <code>node</code> | <code>undefined</code></div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/draxt.js#L159>source</a></div><div class=mds id=draxt-first><b class=header><a class=h href=#draxt-first>first</a></b><code class=ms>draxtCollection.first()</code><div class=mp></div><p></p><p>Get the first node (if any) from the collection.</p><p></p><div class=mret>→ <code>node</code> | <code>undefined</code></div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/draxt.js#L170>source</a></div><div class=mds id=draxt-last><b class=header><a class=h href=#draxt-last>last</a></b><code class=ms>draxtCollection.last()</code><div class=mp></div><p></p><p>Get the last node (if any) from the collection.</p><p></p><div class=mret>→ <code>node</code> | <code>undefined</code></div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/draxt.js#L178>source</a></div><div class=mds id=draxt-has><b class=header><a class=h href=#draxt-has>has</a></b><code class=ms>draxtCollection.has(item)</code><div class=mp><ul><li><code>item</code> (<code>string</code>|<code>node</code>)&nbsp;&nbsp;–&nbsp;&nbsp;A <a href=#interfaces-node><code>Node</code></a> instance or a <code>pathName</code></li></ul></div><p></p><p>Does the <a href=#draxt><code>draxt</code></a> collection has a node with specified pathName? Note that <code>.has()</code> method doesn&#39;t work by checking if collection has a specific <a href=#interfaces-node><code>Node</code></a> instance. It checks whether collection has a node with the specified pathName.</p><p></p><pre class=prettyprint>// 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</pre><div class=mret>→ <code>boolean</code></div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/draxt.js#L199>source</a></div><div class=mds id=draxt-slice><b class=header><a class=h href=#draxt-slice>slice</a></b><code class=ms>draxtCollection.slice([begin, end])</code><div class=mp><ul><li><code>begin</code> (<code>integer</code>)&nbsp;&nbsp;–&nbsp;&nbsp;Zero-based index at which to begin extraction.</li><li><code>end</code> (<code>integer</code>)&nbsp;&nbsp;–&nbsp;&nbsp;Zero-based index before which to end extraction. <code>slice</code> extracts up to but not including <code>end</code>.</li></ul></div><p></p><p>Slice the collection and return a new <a href=#draxt><code>Draxt</code></a> collection. Uses <code>Array.prototype.slice</code>.</p><p></p><div class=mret>→ <code>draxt</code> A new <a href=#draxt><code>draxt</code></a> collection which contains sliced items.</div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/draxt.js#L212>source</a></div><div class=mds id=draxt-filter><b class=header><a class=h href=#draxt-filter>filter</a></b><code class=ms>draxtCollection.filter(callback [, thisArg])</code><div class=mp><ul><li><code>callback</code> (<code>function</code>)&nbsp;&nbsp;–&nbsp;&nbsp;A function to execute for each node.</li><li><code>thisArg</code> (<code>any</code>)&nbsp;&nbsp;–&nbsp;&nbsp;Value to use as <code>this</code> (i.e the reference Object) when executing callback.</li></ul></div><p></p><p>Filter the collection&#39;s nodes and return a new <a href=#draxt><code>draxt</code></a> collection. Uses <code>Array.prototype.filter</code>.</p><p></p><div class=mret>→ <code>draxt</code> A new <a href=#draxt><code>draxt</code></a> collection which contains filtered items.</div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/draxt.js#L224>source</a></div><div class=mds id=draxt-foreach><b class=header><a class=h href=#draxt-foreach>forEach</a></b><code class=ms>draxtCollection.forEach(callback [, thisArg])</code><div class=mp><ul><li><code>callback</code> (<code>function</code>)&nbsp;&nbsp;–&nbsp;&nbsp;A function to execute for each node.</li><li><code>thisArg</code> (<code>any</code>)&nbsp;&nbsp;–&nbsp;&nbsp;Value to use as <code>this</code> (i.e the reference Object) when executing callback.</li></ul></div><p></p><p>Iterate over the <a href=#draxt><code>draxt</code></a> collection and execute a function for each node. Uses <code>Array.prototype.forEach</code>.</p><p></p><div class=mret>→ <code>draxt</code> The current collection.</div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/draxt.js#L237>source</a></div><div class=mds id=draxt-each><b class=header><a class=h href=#draxt-each>each</a></b><code class=ms>draxtCollection.each()</code><div class=mp></div><p></p><p>Alias for <code>draxt.forEach</code>.</p><p></p><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/draxt.js#L245>source</a></div><div class=mds id=draxt-map><b class=header><a class=h href=#draxt-map>map</a></b><code class=ms>draxtCollection.map(callback [, thisArg])</code><div class=mp><ul><li><code>callback</code> (<code>function</code>)&nbsp;&nbsp;–&nbsp;&nbsp;A function to execute for each node.</li><li><code>thisArg</code> (<code>any</code>)&nbsp;&nbsp;–&nbsp;&nbsp;Value to use as <code>this</code> (i.e the reference Object) when executing callback.</li></ul></div><p></p><p>Create an array with the results of calling a provided function on every node in the <a href=#draxt><code>draxt</code></a> collection. Uses <code>Array.prototype.map</code>.</p><p></p><div class=mret>→ <code>array</code></div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/draxt.js#L255>source</a></div><div class=mds id=draxt-mapasync><b class=header><a class=h href=#draxt-mapasync>mapAsync</a></b><code class=ms>draxtCollection.mapAsync(fn [, thisArg])</code><div class=mp><ul><li><code>fn</code> (<code>function</code>)&nbsp;&nbsp;–&nbsp;&nbsp;A function to execute for each node.</li><li><code>thisArg</code> (<code>any</code>)&nbsp;&nbsp;–&nbsp;&nbsp;Value to use as <code>this</code> (i.e the reference Object) when executing callback.</li></ul></div><p></p><p>Asynchronous version of <code>draxt.map</code>. The results of mapped array is passed to <code>Promise.all</code> method.</p><p></p><div class=mret>→ <code>promise</code></div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/draxt.js#L266>source</a></div><div class=mds id=draxt-some><b class=header><a class=h href=#draxt-some>some</a></b><code class=ms>draxtCollection.some(fn)</code><div class=mp><ul><li><code>fn</code> (<code>function</code>)&nbsp;&nbsp;–&nbsp;&nbsp;A function to execute for each node.</li></ul></div><p></p><p>Test whether at least one node in the collection passes the test implemented by the provided function. Uses <code>Array.prototype.some</code>.</p><p></p><div class=mret>→ <code>boolean</code></div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/draxt.js#L277>source</a></div><div class=mds id=draxt-sort><b class=header><a class=h href=#draxt-sort>sort</a></b><code class=ms>draxtCollection.sort(callback)</code><div class=mp><ul><li><code>callback</code> (<code>function</code>)&nbsp;&nbsp;–&nbsp;&nbsp;A function that defines the sort order.</li></ul></div><p></p><p>Sort the nodes of collection <em>in place</em> and return the <a href=#draxt><code>draxt</code></a> collection. Uses <code>Array.prototype.sort</code>.</p><p></p><div class=mret>→ <code>draxt</code> Note that the collection is sorted <em>in place</em>, and no copy is made.</div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/draxt.js#L287>source</a></div><div class=mds id=draxt-reverse><b class=header><a class=h href=#draxt-reverse>reverse</a></b><code class=ms>draxtCollection.reverse()</code><div class=mp></div><p></p><p>Reverse the collection&#39;s nodes <em>in place</em>. The first array element becomes the last, and the last array element becomes the first.</p><p></p><div class=mret>→ <code>draxt</code></div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/draxt.js#L297>source</a></div><div class=mds id=draxt-directories><b class=header><a class=h href=#draxt-directories>directories</a></b><code class=ms>draxtCollection.directories()</code><div class=mp></div><p></p><p>Filter directory nodes (instances of <a href=#interfaces-directory><code>Directory</code></a> class) and return a new <a href=#draxt><code>draxt</code></a> collection.</p><p></p><div class=mret>→ <code>draxt</code></div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/draxt.js#L307>source</a></div><div class=mds id=draxt-files><b class=header><a class=h href=#draxt-files>files</a></b><code class=ms>draxtCollection.files()</code><div class=mp></div><p></p><p>Filter file nodes (instances of <a href=#interfaces-file><code>File</code></a> class) and return a new <a href=#draxt><code>draxt</code></a> collection.</p><p></p><div class=mret>→ <code>draxt</code></div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/draxt.js#L317>source</a></div><div class=mds id=draxt-symlinks><b class=header><a class=h href=#draxt-symlinks>symlinks</a></b><code class=ms>draxtCollection.symlinks()</code><div class=mp></div><p></p><p>Filter symbolic link nodes (instances of <a href=#interfaces-symboliclink><code>SymbolicLink</code></a> class) and return a new <a href=#draxt><code>draxt</code></a> collection.</p><p></p><div class=mret>→ <code>draxt</code></div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/draxt.js#L327>source</a></div><div class=mds id=draxt-empty><b class=header><a class=h href=#draxt-empty>empty</a></b><code class=ms>draxtCollection.empty()</code><div class=mp></div><p></p><p>Empty the <a href=#draxt><code>draxt</code></a> collection. This method doesn&#39;t affect file system!</p><p></p><div class=mret>→ <code>draxt</code></div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/draxt.js#L337>source</a></div><div class=mds id=draxt-drop><b class=header><a class=h href=#draxt-drop>drop</a></b><code class=ms>draxtCollection.drop(node)</code><div class=mp><ul><li><code>node</code> (<code>draxt</code>|<code>node</code>|<code>array.&lt;(node|string)&gt;</code>)&nbsp;&nbsp;–&nbsp;&nbsp;Accepts various paramters.</li></ul></div><p></p><p>Remove node(s) from the current <a href=#draxt><code>draxt</code></a> collection by using <code>.pathName</code>s as the criterion.</p><p></p><div class=mret>→ <code>draxt</code></div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/draxt.js#L348>source</a></div><h2 id=interfaces>Interfaces</h2><p>Draxt introduces several DOM-like interfaces representing fileysystem objects. There are several interfaces. <a href=#interfaces-file>File</a> for files, <a href=#interfaces-directory>Directory</a> for directories and <a href=#interfaces-symboliclink>SymbolicLink</a> for symbolic links. These interfaces extends the base <a href=#interfaces-node>Node</a> interface.</p><p>Just like DOM interfaces, draxt interfaces has their own set of unique methods. As an example, a <code>directory</code> instance has <code>.find()</code> method but a <code>file</code> instance doesn't.</p><h3 id=interfaces-node><a class=h href=#interfaces-node>Node</a></h3><p></p><p>Node class is an interface that other classes representing file system&#39;s nodes (like <a href=#interfaces-file><code>File</code></a>, <a href=#interfaces-directory><code>Directory</code></a>, <a href=#interfaces-symboliclink><code>SymbolicLink</code></a>, ...) inherit.</p><p></p><h4 id=interfaces-node-syntax><a class=h href=#interfaces-node-syntax>Syntax:</a></h4><pre class=prettyprint>const node = new Node(pathName [, stats]);</pre><h4 id=interfaces-node-props><a class=h href=#interfaces-node-props>Properties</a></h4><ul><li><b>node.nodeName</b> <span class=mpm>(<code>string</code>)</span><p>Default: <code>&#39;Node&#39;</code>. The name of constructor of the current node.</p></li><li><b>node.NODE_TYPE</b> <span class=mpm>(<code>number</code>)</span><p>Default: <code>0</code>. Code number for the node.</p></li><li><b>node.pathName</b> <span class=mpm>(<code>string</code>)</span><p>Absolute pathName of the node. Example: <code>&#39;/app/readme.md&#39;</code>.</p></li><li><b>node.baseName</b> <span class=mpm>(<code>string</code>)</span><p>baseName of the node. Example: <code>&#39;readme.md&#39;</code>.</p></li><li><b>node.name</b> <span class=mpm>(<code>string</code>)</span><p>Name of the node without the possible extension. Example <code>&#39;readme&#39;</code>.</p></li><li><b>node.extension</b> <span class=mpm>(<code>string</code>|<code>undefined</code>)</span><p>Extension of the node without <code>.</code>. Example: <code>&#39;js&#39;</code>.</p></li><li><b>node.parentPath</b> <span class=mpm>(<code>string</code>)</span><p>pathName of the parent directory of the node.</p></li><li><b>node.rootPath</b> <span class=mpm>(<code>string</code>)</span><p>Root path of the file system.</p></li><li><b>node._stats</b> <span class=mpm>(<code>object</code>|<code>undefined</code>)</span><p>Cached instance of <a href=https://nodejs.org/api/fs.html#fs_class_fs_stats><code>fs.Stats</code></a> for the node.</p></li><li><b>node.fs</b> <span class=mpm>(<code>object</code>)</span><p>Refers to <a href=https://github.com/jprichardson/node-fs-extra><code>fs-extra</code></a> package.</p></li><li><b>node.glob</b> <span class=mpm>(<code>object</code>)</span><p>Refers to <a href=https://github.com/isaacs/node-glob><code>glob</code></a> package.</p></li></ul><h4 id=interfaces-node-static-methods><a class=h href=#interfaces-node-static-methods>Static Methods:</a></h4><div class=mds id=node-rawquery><b class=header><a class=h href=#node-rawquery>rawQuery</a></b><code class=ms>Node.rawQuery(pattern [, options])</code><div class=mp><ul><li><code>pattern</code> (<code>string</code>)&nbsp;&nbsp;–&nbsp;&nbsp;Pattern for <a href=https://github.com/isaacs/node-glob><code>glob</code></a> package.</li><li><code>options</code> (<code>object</code>)&nbsp;&nbsp;–&nbsp;&nbsp;Options for <a href=https://github.com/isaacs/node-glob><code>glob</code></a> package.</li></ul></div><p></p><p>Asynchronously query the file system by using <a href=https://github.com/isaacs/node-glob><code>glob</code></a> package.</p><p></p><div class=mret>→ <code>promise.&lt;array&gt;</code> An array of pathNames.</div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/interfaces/Node.js#L690>source</a></div><div class=mds id=node-rawquerysync><b class=header><a class=h href=#node-rawquerysync>rawQuerySync</a></b><code class=ms>Node.rawQuerySync(pattern [, options])</code><div class=mp><ul><li><code>pattern</code> (<code>string</code>)&nbsp;&nbsp;–&nbsp;&nbsp;Pattern for <a href=https://github.com/isaacs/node-glob><code>glob</code></a> package.</li><li><code>options</code> (<code>object</code>)&nbsp;&nbsp;–&nbsp;&nbsp;Options for <a href=https://github.com/isaacs/node-glob><code>glob</code></a> package.</li></ul></div><p></p><p>Synchronously query the file system by using <a href=https://github.com/isaacs/node-glob><code>glob</code></a> package.</p><p></p><div class=mret>→ <code>array</code> An array of pathNames.</div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/interfaces/Node.js#L709>source</a></div><div class=mds id=node-tonodes><b class=header><a class=h href=#node-tonodes>toNodes</a></b><code class=ms>Node.toNodes(pathNames)</code><div class=mp><ul><li><code>pathNames</code> (<code>array</code>)&nbsp;&nbsp;–&nbsp;&nbsp;Array of pathNames.</li></ul></div><p></p><p>Convert array of paths to array of node instances asynchronously! A node instance can be an instance of <a href=#interfaces-file><code>File</code></a>, <a href=#interfaces-directory><code>Directory</code></a> or <a href=#interfaces-symboliclink><code>SymbolicLink</code></a>.</p><p></p><pre class=prettyprint>const pathNames = [
  '/app/resources',
  '/app/resources/style.css'
];
Node.toNodes(pathNames).then(result => {
   // result:
   [
     Directory { pathName: '/app/resources', ... },
     File { pathName: '/app/resources/style.css', ... }
   ]
});</pre><div class=mret>→ <code>promise.&lt;array&gt;</code> Array of node instances.</div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/interfaces/Node.js#L732>source</a></div><div class=mds id=node-tonodessync><b class=header><a class=h href=#node-tonodessync>toNodesSync</a></b><code class=ms>Node.toNodesSync(pathNames)</code><div class=mp><ul><li><code>pathNames</code> (<code>array</code>)&nbsp;&nbsp;–&nbsp;&nbsp;Array of paths</li></ul></div><p></p><p>Convert array of paths to array of nodes synchronously! A node instance can be instance of <a href=#interfaces-file><code>File</code></a>, <a href=#interfaces-directory><code>Directory</code></a> or <a href=#interfaces-symboliclink><code>SymbolicLink</code></a>.</p><p></p><div class=mret>→ <code>array</code> Array of node instances.</div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/interfaces/Node.js#L748>source</a></div><div class=mds id=node-query><b class=header><a class=h href=#node-query>query</a></b><code class=ms>Node.query(pattern [, options])</code><div class=mp><ul><li><code>pattern</code> (<code>string</code>)&nbsp;&nbsp;–&nbsp;&nbsp;A <a href=https://github.com/isaacs/node-glob><code>glob</code></a> pattern.</li><li><code>options</code> (<code>object</code>)&nbsp;&nbsp;–&nbsp;&nbsp;Options for <a href=https://github.com/isaacs/node-glob><code>glob</code></a> package.</li></ul></div><p></p><p>Asynchronously query the file system by using <a href=https://github.com/isaacs/node-glob><code>glob</code></a> package.</p><p></p><div class=mret>→ <code>promise.&lt;array&gt;</code> Array of nodes.</div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/interfaces/Node.js#L780>source</a></div><div class=mds id=node-querysync><b class=header><a class=h href=#node-querysync>querySync</a></b><code class=ms>Node.querySync(pattern [, options])</code><div class=mp><ul><li><code>pattern</code> (<code>string</code>)</li><li><code>options</code> (<code>object</code>)&nbsp;&nbsp;–&nbsp;&nbsp;Options for <a href=https://github.com/isaacs/node-glob><code>glob</code></a> package.</li></ul></div><p></p><p>Synchronously query the file system by using <a href=https://github.com/isaacs/node-glob><code>glob</code></a> package.</p><p></p><div class=mret>→ <code>array</code> Array of nodes.</div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/interfaces/Node.js#L791>source</a></div><h4 id=interfaces-node-methods><a class=h href=#interfaces-node-methods>Methods</a></h4><div class=mds id=node-getpathname><b class=header><a class=h href=#node-getpathname>getPathName</a></b><code class=ms>node.getPathName()</code><div class=mp></div><p></p><p>Get the node&#39;s pathName.</p><p></p><div class=mret>→ <code>string</code></div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/interfaces/Node.js#L63>source</a></div><div class=mds id=node-getbasename><b class=header><a class=h href=#node-getbasename>getBaseName</a></b><code class=ms>node.getBaseName()</code><div class=mp></div><p></p><p>Get the node&#39;s baseName.</p><p></p><div class=mret>→ <code>string</code></div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/interfaces/Node.js#L71>source</a></div><div class=mds id=node-getextension><b class=header><a class=h href=#node-getextension>getExtension</a></b><code class=ms>node.getExtension()</code><div class=mp></div><p></p><p>Get the node&#39;s extension.</p><p></p><div class=mret>→ <code>string</code></div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/interfaces/Node.js#L79>source</a></div><div class=mds id=node-getname><b class=header><a class=h href=#node-getname>getName</a></b><code class=ms>node.getName()</code><div class=mp></div><p></p><p>Get name of the node. For <a href=#interfaces-file><code>File</code></a> nodes the <code>name</code> property is the name of file without possible extension.</p><p></p><div class=mret>→ <code>string</code></div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/interfaces/Node.js#L88>source</a></div><div class=mds id=node-getparentpath><b class=header><a class=h href=#node-getparentpath>getParentPath</a></b><code class=ms>node.getParentPath()</code><div class=mp></div><p></p><p>Get the node&#39;s parent directory pathName.</p><p></p><div class=mret>→ <code>string</code></div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/interfaces/Node.js#L96>source</a></div><div class=mds id=node-getcachedstats><b class=header><a class=h href=#node-getcachedstats>getCachedStats</a></b><code class=ms>node.getCachedStats()</code><div class=mp></div><p></p><p>Get cached <a href=https://nodejs.org/api/fs.html#fs_class_fs_stats><code>fs.Stats</code></a> instance for the node. Returns <code>undefined</code> 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.</p><p></p><div class=mret>→ <code>object</code> | <code>undefined</code></div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/interfaces/Node.js#L106>source</a></div><div class=mds id=node-getstatprop><b class=header><a class=h href=#node-getstatprop>getStatProp</a></b><code class=ms>node.getStatProp(propName)</code><div class=mp><ul><li><code>propName</code> (<code>string</code>)</li></ul></div><p></p><p>Get a stat property&#39;s value from cached <a href=https://nodejs.org/api/fs.html#fs_class_fs_stats><code>fs.Stats</code></a> for the node. The method returns <code>undefined</code> when there is no cached stats.</p><p></p><pre class=prettyprint>// Get `blksize` property of fs.Stats instance cached for the node.
const node_ctime = node.getStatProp('blksize');</pre><div class=mret>→ <code>any</code></div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/interfaces/Node.js#L119>source</a></div><div class=mds id=node-getaccesstime><b class=header><a class=h href=#node-getaccesstime>getAccessTime</a></b><code class=ms>node.getAccessTime()</code><div class=mp></div><p></p><p>Get &quot;access time&quot; of the node. Returns <a href=https://nodejs.org/api/fs.html#fs_stats_atime><code>atime</code></a> property of the cached stats.</p><p></p><div class=mret>→ <code>date</code></div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/interfaces/Node.js#L127>source</a></div><div class=mds id=node-getmodifiedtime><b class=header><a class=h href=#node-getmodifiedtime>getModifiedTime</a></b><code class=ms>node.getModifiedTime()</code><div class=mp></div><p></p><p>Get &quot;modified time&quot; of the node. Returns <a href=https://nodejs.org/api/fs.html#fs_stats_mtime><code>mtime</code></a> property of the cached stats.</p><p></p><div class=mret>→ <code>date</code></div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/interfaces/Node.js#L135>source</a></div><div class=mds id=node-getbirthtime><b class=header><a class=h href=#node-getbirthtime>getBirthTime</a></b><code class=ms>node.getBirthTime()</code><div class=mp></div><p></p><p>Get &quot;birthday time&quot; of the node. Returns <a href=https://nodejs.org/api/fs.html#fs_stats_birthtime><code>birthtime</code></a> property of the cached stats.</p><p></p><div class=mret>→ <code>date</code></div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/interfaces/Node.js#L143>source</a></div><div class=mds id=node-getchangetime><b class=header><a class=h href=#node-getchangetime>getChangeTime</a></b><code class=ms>node.getChangeTime()</code><div class=mp></div><p></p><p>Get &quot;change time&quot; of the node. Returns <a href=https://nodejs.org/api/fs.html#fs_stats_ctime><code>ctime</code></a> property of the cached stats.</p><p></p><div class=mret>→ <code>date</code></div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/interfaces/Node.js#L151>source</a></div><div class=mds id=node-getsize><b class=header><a class=h href=#node-getsize>getSize</a></b><code class=ms>node.getSize()</code><div class=mp></div><p></p><p>Get size of the node. Size is simply the <code>size</code> property of the cached <a href=https://nodejs.org/api/fs.html#fs_class_fs_stats><code>fs.Stats</code></a> instance.</p><p></p><div class=mret>→ <code>number</code></div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/interfaces/Node.js#L160>source</a></div><div class=mds id=node-isdirectory><b class=header><a class=h href=#node-isdirectory>isDirectory</a></b><code class=ms>node.isDirectory()</code><div class=mp></div><p></p><p>Is the node a directory?</p><p></p><div class=mret>→ <code>boolean</code></div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/interfaces/Node.js#L168>source</a></div><div class=mds id=node-isfile><b class=header><a class=h href=#node-isfile>isFile</a></b><code class=ms>node.isFile()</code><div class=mp></div><p></p><p>Is the node a file?</p><p></p><div class=mret>→ <code>boolean</code></div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/interfaces/Node.js#L176>source</a></div><div class=mds id=node-issymboliclink><b class=header><a class=h href=#node-issymboliclink>isSymbolicLink</a></b><code class=ms>node.isSymbolicLink()</code><div class=mp></div><p></p><p>Is the node a symbolic link?</p><p></p><div class=mret>→ <code>boolean</code></div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/interfaces/Node.js#L184>source</a></div><div class=mds id=node-isdotfile><b class=header><a class=h href=#node-isdotfile>isDotFile</a></b><code class=ms>node.isDotFile()</code><div class=mp></div><p></p><p>Is the node a dot file? i.e. does the node&#39;s name begin with dot character.</p><p></p><div class=mret>→ <code>boolean</code></div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/interfaces/Node.js#L192>source</a></div><div class=mds id=node-renewstats><b class=header><a class=h href=#node-renewstats>renewStats</a></b><code class=ms>node.renewStats()</code><div class=mp></div><p></p><p>Asynchronously renew stats of the node. Uses <a href=https://nodejs.org/api/fs.html#fs_fs_lstat_path_options_callback><code>fs.lstat</code></a>.</p><p></p><div class=mret>→ <code>promise</code> A fresh <a href=https://nodejs.org/api/fs.html#fs_class_fs_stats><code>fs.Stats</code></a> instance for the node.</div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/interfaces/Node.js#L200>source</a></div><div class=mds id=node-renewstatssync><b class=header><a class=h href=#node-renewstatssync>renewStatsSync</a></b><code class=ms>node.renewStatsSync()</code><div class=mp></div><p></p><p>Synchronously renew stats of the node. Uses <a href=https://nodejs.org/api/fs.html#fs_fs_lstatsync_path_options><code>fs.lstatSync</code></a>.</p><p></p><div class=mret>→ <code>node</code></div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/interfaces/Node.js#L212>source</a></div><div class=mds id=node-getoctalpermissions><b class=header><a class=h href=#node-getoctalpermissions>getOctalPermissions</a></b><code class=ms>node.getOctalPermissions()</code><div class=mp></div><p></p><p>Get octal representation of the node&#39;s permissions.</p><p></p><pre class=prettyprint>node.getOctalPermissions() // → "755"</pre><div class=mret>→ <code>string</code></div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/interfaces/Node.js#L224>source</a></div><div class=mds id=node-getpermissions><b class=header><a class=h href=#node-getpermissions>getPermissions</a></b><code class=ms>node.getPermissions()</code><div class=mp></div><p></p><p>Get permissions of the node for owner, group and others by converting <code>mode</code> property of cached stats into an object.</p><p></p><pre class=prettyprint>node.getPermissions()
// →
{
  read: { owner: true, group: true, others: false },
  write: { owner: true, group: true, others: false },
  execute: { owner: true, group: true, others: false }
}</pre><div class=mret>→ <code>object</code></div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/interfaces/Node.js#L241>source</a></div><div class=mds id=node-access><b class=header><a class=h href=#node-access>access</a></b><code class=ms>node.access([mode])</code><div class=mp><ul><li><code>mode</code> (<code>integer</code>)&nbsp;&nbsp;Default: <code>fs.constants.F_OK</code></li></ul></div><p></p><p>Asynchronously tests a user&#39;s permissions for the file or directory. Wrapper for promisified <a href=https://nodejs.org/api/fs.html#fs_fs_access_path_mode_callback><code>fs.access</code></a>.</p><p></p><pre class=prettyprint>// Check if the node is readable.
node.access(node.fs.constants.R_OK).then(() => {
  // node is readable
}).catch(e => {
  // node is not readable
});</pre><div class=mret>→ <code>promise</code></div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/interfaces/Node.js#L285>source</a></div><div class=mds id=node-accesssync><b class=header><a class=h href=#node-accesssync>accessSync</a></b><code class=ms>node.accessSync([mode])</code><div class=mp><ul><li><code>mode</code> (<code>integer</code>)&nbsp;&nbsp;Default: <code>fs.constants.F_OK</code></li></ul></div><p></p><p>Wrapper for <a href=https://nodejs.org/api/fs.html#fs_fs_accesssync_path_mode><code>fs.accessSync</code></a>.</p><p></p><div class=mret>→ <code>node</code> this</div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/interfaces/Node.js#L295>source</a></div><div class=mds id=node-chmod><b class=header><a class=h href=#node-chmod>chmod</a></b><code class=ms>node.chmod(mode)</code><div class=mp><ul><li><code>mode</code> (<code>integer</code>)</li></ul></div><p></p><p>Wrapper for promisified <a href=https://nodejs.org/api/fs.html#fs_fs_chmod_path_mode_callback><code>fs.chmod</code></a>.</p><p></p><div class=mret>→ <code>promise</code></div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/interfaces/Node.js#L305>source</a></div><div class=mds id=node-chmodsync><b class=header><a class=h href=#node-chmodsync>chmodSync</a></b><code class=ms>node.chmodSync(mode)</code><div class=mp><ul><li><code>mode</code> (<code>integer</code>)</li></ul></div><p></p><p>Wrapper for <a href=https://nodejs.org/api/fs.html#fs_fs_chmodsync_path_mode><code>fs.chmodSync</code></a>.</p><p></p><div class=mret>→ <code>node</code> this</div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/interfaces/Node.js#L315>source</a></div><div class=mds id=node-lchmod><b class=header><a class=h href=#node-lchmod>lchmod</a></b><code class=ms>node.lchmod(mode)</code><div class=mp><ul><li><code>mode</code> (<code>integer</code>)</li></ul></div><p></p><p>Wrapper for promisified <a href=https://nodejs.org/api/fs.html#fs_fs_lchmod_path_mode_callback><code>fs.lchmod</code></a>.</p><p></p><div class=mret>→ <code>promise</code></div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/interfaces/Node.js#L325>source</a></div><div class=mds id=node-lchmodsync><b class=header><a class=h href=#node-lchmodsync>lchmodSync</a></b><code class=ms>node.lchmodSync(mode)</code><div class=mp><ul><li><code>mode</code> (<code>integer</code>)</li></ul></div><p></p><p>Wrapper for <a href=https://nodejs.org/api/fs.html#fs_fs_lchmodsync_path_mode><code>fs.lchmodSync</code></a>.</p><p></p><div class=mret>→ <code>node</code></div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/interfaces/Node.js#L335>source</a></div><div class=mds id=node-chown><b class=header><a class=h href=#node-chown>chown</a></b><code class=ms>node.chown(uid, gid)</code><div class=mp><ul><li><code>uid</code> (<code>integer</code>)&nbsp;&nbsp;–&nbsp;&nbsp;The user id</li><li><code>gid</code> (<code>integer</code>)&nbsp;&nbsp;–&nbsp;&nbsp;The group id</li></ul></div><p></p><p>Wrapper for promisified <a href=https://nodejs.org/api/fs.html#fs_fs_chown_path_uid_gid_callback><code>fs.chown</code></a>.</p><p></p><div class=mret>→ <code>promise</code></div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/interfaces/Node.js#L346>source</a></div><div class=mds id=node-chownsync><b class=header><a class=h href=#node-chownsync>chownSync</a></b><code class=ms>node.chownSync(uid, gid)</code><div class=mp><ul><li><code>uid</code> (<code>integer</code>)&nbsp;&nbsp;–&nbsp;&nbsp;The user id</li><li><code>gid</code> (<code>integer</code>)&nbsp;&nbsp;–&nbsp;&nbsp;The group id</li></ul></div><p></p><p>Wrapper for <a href=https://nodejs.org/api/fs.html#fs_fs_chownsync_path_uid_gid><code>fs.chownSync</code></a>.</p><p></p><div class=mret>→ <code>node</code> The file node</div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/interfaces/Node.js#L357>source</a></div><div class=mds id=node-lchown><b class=header><a class=h href=#node-lchown>lchown</a></b><code class=ms>node.lchown(uid, gid)</code><div class=mp><ul><li><code>uid</code> (<code>integer</code>)&nbsp;&nbsp;–&nbsp;&nbsp;The user id</li><li><code>gid</code> (<code>integer</code>)&nbsp;&nbsp;–&nbsp;&nbsp;The group id</li></ul></div><p></p><p>Wrapper for promisified <a href=https://nodejs.org/api/fs.html#fs_fs_lchown_path_uid_gid_callback><code>fs.lchown</code></a>.</p><p></p><div class=mret>→ <code>promise</code></div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/interfaces/Node.js#L368>source</a></div><div class=mds id=node-lchownsync><b class=header><a class=h href=#node-lchownsync>lchownSync</a></b><code class=ms>node.lchownSync(uid, gid)</code><div class=mp><ul><li><code>uid</code> (<code>integer</code>)&nbsp;&nbsp;–&nbsp;&nbsp;The user id</li><li><code>gid</code> (<code>integer</code>)&nbsp;&nbsp;–&nbsp;&nbsp;The group id</li></ul></div><p></p><p>Wrapper for <a href=https://nodejs.org/api/fs.html#fs_fs_lchownsync_path_uid_gid><code>fs.lchownSync</code></a>.</p><p></p><div class=mret>→ <code>node</code> The file node</div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/interfaces/Node.js#L379>source</a></div><div class=mds id=node-exists><b class=header><a class=h href=#node-exists>exists</a></b><code class=ms>node.exists()</code><div class=mp></div><p></p><p>Does node exist on file system? Uses <a href=https://nodejs.org/api/fs.html#fs_fs_access_path_mode_callback><code>fs.access</code></a> instead of the deprecated <a href=https://nodejs.org/api/fs.html#fs_fs_exists_path_callback><code>fs.exists</code></a> method.</p><p></p><div class=mret>→ <code>promise.&lt;boolean&gt;</code></div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/interfaces/Node.js#L389>source</a></div><div class=mds id=node-existssync><b class=header><a class=h href=#node-existssync>existsSync</a></b><code class=ms>node.existsSync()</code><div class=mp></div><p></p><p>Does node exist on file system? Wrapper for <a href=https://nodejs.org/api/fs.html#fs_fs_existssync_path><code>fs.existsSync</code></a>.</p><p></p><div class=mret>→ <code>boolean</code></div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/interfaces/Node.js#L400>source</a></div><div class=mds id=node-stat><b class=header><a class=h href=#node-stat>stat</a></b><code class=ms>node.stat()</code><div class=mp></div><p></p><p>Wrapper for promisified <a href=https://nodejs.org/api/fs.html#fs_fs_stat_path_options_callback><code>fs.stat</code></a>.</p><p></p><div class=mret>→ <code>promise</code> Promise representing instance of <a href=https://nodejs.org/api/fs.html#fs_class_fs_stats><code>fs.Stats</code></a> for the node.</div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/interfaces/Node.js#L408>source</a></div><div class=mds id=node-statsync><b class=header><a class=h href=#node-statsync>statSync</a></b><code class=ms>node.statSync()</code><div class=mp></div><p></p><p>Wrapper for <a href=https://nodejs.org/api/fs.html#fs_fs_statsync_path_options><code>fs.statSync</code></a>.</p><p></p><div class=mret>→ <code>object</code> Instance of <a href=https://nodejs.org/api/fs.html#fs_class_fs_stats><code>fs.Stats</code></a> for the node.</div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/interfaces/Node.js#L416>source</a></div><div class=mds id=node-lstat><b class=header><a class=h href=#node-lstat>lstat</a></b><code class=ms>node.lstat()</code><div class=mp></div><p></p><p>Wrapper for promisified <a href=https://nodejs.org/api/fs.html#fs_fs_lstat_path_options_callback><code>fs.lstat</code></a>.</p><p></p><div class=mret>→ <code>promise</code> Promise representing instance of <a href=https://nodejs.org/api/fs.html#fs_class_fs_stats><code>fs.Stats</code></a> for the node.</div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/interfaces/Node.js#L424>source</a></div><div class=mds id=node-lstatsync><b class=header><a class=h href=#node-lstatsync>lstatSync</a></b><code class=ms>node.lstatSync()</code><div class=mp></div><p></p><p>Wrapper for <a href=https://nodejs.org/api/fs.html#fs_fs_lstatsync_path_options><code>fs.lstatSync</code></a>.</p><p></p><div class=mret>→ <code>object</code> Instance of <a href=https://nodejs.org/api/fs.html#fs_class_fs_stats><code>fs.Stats</code></a> for the node.</div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/interfaces/Node.js#L432>source</a></div><div class=mds id=node-link><b class=header><a class=h href=#node-link>link</a></b><code class=ms>node.link(newPath)</code><div class=mp><ul><li><code>newPath</code> (<code>string</code>|<code>Buffer</code>|<code>URL</code>)</li></ul></div><p></p><p>Wrapper for promisified <a href=https://nodejs.org/api/fs.html#fs_fs_link_existingpath_newpath_callback><code>fs.link</code></a>.</p><p></p><div class=mret>→ <code>Promise</code></div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/interfaces/Node.js#L441>source</a></div><div class=mds id=node-linksync><b class=header><a class=h href=#node-linksync>linkSync</a></b><code class=ms>node.linkSync(newPath)</code><div class=mp><ul><li><code>newPath</code> (<code>string</code>|<code>buffer</code>|<code>URL</code>)</li></ul></div><p></p><p>Wrapper for <a href=https://nodejs.org/api/fs.html#fs_fs_linksync_existingpath_newpath><code>fs.linkSync</code></a>.</p><p></p><div class=mret>→ <code>node</code></div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/interfaces/Node.js#L451>source</a></div><div class=mds id=node-rename><b class=header><a class=h href=#node-rename>rename</a></b><code class=ms>node.rename(newPath)</code><div class=mp><ul><li><code>newPath</code> (<code>string</code>|<code>Buffer</code>|<code>URL</code>)</li></ul></div><p></p><p>Asynchronously rename node to the pathname provided as newPath. In the case that <code>newPath</code> already exists, it will be overwritten. Wrapper for promisified <a href=https://nodejs.org/api/fs.html#fs_fs_rename_oldpath_newpath_callback><code>fs.rename</code></a>.</p><p></p><div class=mret>→ <code>promise</code></div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/interfaces/Node.js#L463>source</a></div><div class=mds id=node-renamesync><b class=header><a class=h href=#node-renamesync>renameSync</a></b><code class=ms>node.renameSync(newPath)</code><div class=mp><ul><li><code>newPath</code> (<code>string</code>|<code>Buffer</code>|<code>URL</code>)</li></ul></div><p></p><p>Wrapper for <a href=https://nodejs.org/api/fs.html#fs_fs_renamesync_oldpath_newpath><code>fs.renameSync</code></a>.</p><p></p><div class=mret>→ <code>node</code></div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/interfaces/Node.js#L475>source</a></div><div class=mds id=node-utimes><b class=header><a class=h href=#node-utimes>utimes</a></b><code class=ms>node.utimes(atime, mtime)</code><div class=mp><ul><li><code>atime</code> (<code>number</code>|<code>string</code>|<code>Date</code>)</li><li><code>mtime</code> (<code>number</code>|<code>string</code>|<code>Date</code>)</li></ul></div><p></p><p>Wrapper for promisified <a href=https://nodejs.org/api/fs.html#fs_fs_utimes_path_atime_mtime_callback><code>fs.utimes</code></a>.</p><p></p><div class=mret>→ <code>promise</code></div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/interfaces/Node.js#L487>source</a></div><div class=mds id=node-utimessync><b class=header><a class=h href=#node-utimessync>utimesSync</a></b><code class=ms>node.utimesSync(atime, mtime)</code><div class=mp><ul><li><code>atime</code> (<code>number</code>|<code>string</code>|<code>Date</code>)</li><li><code>mtime</code> (<code>number</code>|<code>string</code>|<code>Date</code>)</li></ul></div><p></p><p>Wrapper for <a href=https://nodejs.org/api/fs.html#fs_fs_utimessync_path_atime_mtime><code>fs.utimesSync</code></a>.</p><p></p><div class=mret>→ <code>node</code></div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/interfaces/Node.js#L498>source</a></div><div class=mds id=node-copy><b class=header><a class=h href=#node-copy>copy</a></b><code class=ms>node.copy(destPath, options)</code><div class=mp><ul><li><code>destPath</code> (<code>string</code>)&nbsp;&nbsp;–&nbsp;&nbsp;Destination path.</li><li><code>options</code> (<code>object</code>)&nbsp;&nbsp;–&nbsp;&nbsp;Options for <a href=https://github.com/jprichardson/node-fs-extra/blob/master/docs/copy.md><code>fs-extra.copy</code></a>.</li></ul></div><p></p><p>Asynchronously copy the node. <a href=#interfaces-directory><code>Directory</code></a> instances can have contents. Like <code>cp -r</code>. When directory doesn&#39;t exist, it&#39;s created! Wrapper for <a href=https://github.com/jprichardson/node-fs-extra/blob/master/docs/copy.md><code>fs-extra.copy</code></a>.</p><p></p><pre class=prettyprint>// 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!
});</pre><div class=mret>→ <code>promise</code></div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/interfaces/Node.js#L519>source</a></div><div class=mds id=node-copysync><b class=header><a class=h href=#node-copysync>copySync</a></b><code class=ms>node.copySync(destPath, options)</code><div class=mp><ul><li><code>destPath</code> (<code>string</code>)&nbsp;&nbsp;–&nbsp;&nbsp;Destination path.</li><li><code>options</code> (<code>object</code>)&nbsp;&nbsp;–&nbsp;&nbsp;Options for <a href=https://github.com/jprichardson/node-fs-extra/blob/master/docs/copy-sync.md><code>fs-extra.copySync</code></a>.</li></ul></div><p></p><p>Wrapper for <a href=https://github.com/jprichardson/node-fs-extra/blob/master/docs/copy-sync.md><code>fs-extra.copySync</code></a>.</p><p></p><div class=mret>→ <code>node</code></div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/interfaces/Node.js#L530>source</a></div><div class=mds id=node-moveto><b class=header><a class=h href=#node-moveto>moveTo</a></b><code class=ms>node.moveTo(targetDir, options)</code><div class=mp><ul><li><code>targetDir</code> (<code>object</code>|<code>string</code>)&nbsp;&nbsp;–&nbsp;&nbsp;<a href=#interfaces-directory><code>Directory</code></a> instance or absolute path of the target directory.</li><li><code>options</code> (<code>object</code>)&nbsp;&nbsp;–&nbsp;&nbsp;Options for <a href=https://github.com/jprichardson/node-fs-extra/blob/master/docs/move.md><code>fs-extra.move</code></a>.</li></ul></div><p></p><p>Move node to another location. <code>baseName</code> property of the node is joined with <code>targetDir</code> param for resolving the final path for the node. The method on success updates path-related properties of the node, but node&#39;s cached stats (if any) is not refreshed! For updating node&#39;s stats, user can call <code>node.renewStats()</code> or <code>node.renewStatsSync()</code> methods after moving the node. Uses <a href=https://github.com/jprichardson/node-fs-extra/blob/master/docs/move.md><code>fs-extra.move</code></a>.</p><p></p><pre class=prettyprint>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'
});</pre><div class=mret>→ <code>promise</code></div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/interfaces/Node.js#L554>source</a></div><div class=mds id=node-movetosync><b class=header><a class=h href=#node-movetosync>moveToSync</a></b><code class=ms>node.moveToSync(targetDir, options)</code><div class=mp><ul><li><code>targetDir</code> (<code>object</code>|<code>string</code>)&nbsp;&nbsp;–&nbsp;&nbsp;<a href=#interfaces-directory><code>Directory</code></a> instance or absolute path of the target directory.</li><li><code>options</code> (<code>object</code>)&nbsp;&nbsp;–&nbsp;&nbsp;Options for <a href=https://github.com/jprichardson/node-fs-extra/blob/master/docs/move.md><code>fs-extra.move</code></a>.</li></ul></div><p></p><p>Synchronous version of <code>node.moveTo</code>.</p><p></p><div class=mret>→ <code>node</code></div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/interfaces/Node.js#L577>source</a></div><div class=mds id=node-appendto><b class=header><a class=h href=#node-appendto>appendTo</a></b><code class=ms>node.appendTo()</code><div class=mp></div><p></p><p>Alias for <code>node.moveTo</code>.</p><p></p><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/interfaces/Node.js#L587>source</a></div><div class=mds id=node-appendtosync><b class=header><a class=h href=#node-appendtosync>appendToSync</a></b><code class=ms>node.appendToSync()</code><div class=mp></div><p></p><p>Alias for <code>node.moveToSync</code>.</p><p></p><div class=mret>→ <code>node</code></div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/interfaces/Node.js#L596>source</a></div><div class=mds id=node-siblings><b class=header><a class=h href=#node-siblings>siblings</a></b><code class=ms>node.siblings([patten, options])</code><div class=mp><ul><li><code>patten</code> (<code>string</code>)&nbsp;&nbsp;Default: <code>&#39;*&#39;</code>&nbsp;&nbsp;–&nbsp;&nbsp;Optional <a href=https://github.com/isaacs/node-glob><code>glob</code></a> pattern.</li><li><code>options</code> (<code>object</code>)&nbsp;&nbsp;–&nbsp;&nbsp;Options for <a href=https://github.com/isaacs/node-glob><code>glob</code></a> package.</li></ul></div><p></p><p>Asynchronously select siblings of the node. Uses <a href=https://github.com/isaacs/node-glob><code>glob</code></a> package.</p><p></p><div class=mret>→ <code>promise.&lt;draxt&gt;</code> Promise representing a <a href=#draxt><code>draxt</code></a> collection.</div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/interfaces/Node.js#L607>source</a></div><div class=mds id=node-siblingssync><b class=header><a class=h href=#node-siblingssync>siblingsSync</a></b><code class=ms>node.siblingsSync([pattern, options])</code><div class=mp><ul><li><code>pattern</code> (<code>string</code>)&nbsp;&nbsp;Default: <code>&#39;*&#39;</code>&nbsp;&nbsp;–&nbsp;&nbsp;Optional <a href=https://github.com/isaacs/node-glob><code>glob</code></a> pattern.</li><li><code>options</code> (<code>object</code>)&nbsp;&nbsp;–&nbsp;&nbsp;Options for <a href=https://github.com/isaacs/node-glob><code>glob</code></a> package.</li></ul></div><p></p><p>Synchronously select siblings of the node. Uses <a href=https://github.com/isaacs/node-glob><code>glob</code></a> package.</p><p></p><div class=mret>→ <code>draxt</code> A <a href=#draxt><code>draxt</code></a> collection.</div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/interfaces/Node.js#L626>source</a></div><div class=mds id=node-remove><b class=header><a class=h href=#node-remove>remove</a></b><code class=ms>node.remove()</code><div class=mp></div><p></p><p>Remove the node from file system! <a href=#interfaces-directory><code>Directory</code></a> nodes can have contents. Like <code>rm -rf</code>. Wrapper for <a href=https://github.com/jprichardson/node-fs-extra/blob/master/docs/remove.md><code>fs-extra.remove</code></a>.</p><p></p><div class=mret>→ <code>promise</code></div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/interfaces/Node.js#L642>source</a></div><div class=mds id=node-removesync><b class=header><a class=h href=#node-removesync>removeSync</a></b><code class=ms>node.removeSync()</code><div class=mp></div><p></p><p>Wrapper for <a href=https://github.com/jprichardson/node-fs-extra/blob/master/docs/remove-sync.md><code>fs-extra.removeSync</code></a>.</p><p></p><div class=mret>→ <code>node</code></div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/interfaces/Node.js#L651>source</a></div><div class=mds id=node-parent><b class=header><a class=h href=#node-parent>parent</a></b><code class=ms>node.parent()</code><div class=mp></div><p></p><p>Asynchronously get parent directory node of the node. It&#39;s an async method as it gets an instance of <a href=https://nodejs.org/api/fs.html#fs_class_fs_stats><code>fs.Stats</code></a> for the parent node asynchronously!</p><p></p><pre class=prettyprint>const file = new File('/app/resources/style.css');
file.parent().then(dir => {
  dir.isDirectory(); // → true
  dir.getPathName(); // → '/app/resources'
});</pre><div class=mret>→ <code>promise.&lt;node&gt;</code> Promise representing a <a href=#interfaces-directory><code>Directory</code></a> instance.</div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/interfaces/Node.js#L667>source</a></div><div class=mds id=node-parentsync><b class=header><a class=h href=#node-parentsync>parentSync</a></b><code class=ms>node.parentSync()</code><div class=mp></div><p></p><p>Synchronously get parent directory node of the node.</p><p></p><div class=mret>→ <code>node</code> A <a href=#interfaces-directory><code>Directory</code></a> instance.</div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/interfaces/Node.js#L678>source</a></div><h3 id=interfaces-file><a class=h href=#interfaces-file>File</a></h3><p></p><p><a href=#interfaces-file><code>File</code></a> class which extends the <a href=#interfaces-node><code>Node</code></a> class is an interface representing pathNames that their <a href=https://nodejs.org/api/fs.html#fs_class_fs_stats><code>fs.Stats</code></a>&#39;s <code>.isFile()</code> method returns <code>true</code>.</p><p></p><h4 id=interfaces-file-syntax><a class=h href=#interfaces-file-syntax>Syntax:</a></h4><pre class=prettyprint>const file = new File(pathName [, stats]);</pre><h4 id=interfaces-file-props><a class=h href=#interfaces-file-props>Properties</a></h4><ul><li><b>file.nodeName</b> <span class=mpm>(<code>string</code>)</span><p>Name of the node: <code>&#39;File&#39;</code>.</p></li><li><b>file.NODE_TYPE</b> <span class=mpm>(<code>number</code>)</span><p>Code number for the node: <code>2</code>.</p></li><li><b>file.pathName</b> <span class=mpm>(<code>string</code>)</span><p>Absolute pathName of the node. Example: <code>&#39;/app/readme.md&#39;</code>.</p></li><li><b>file.baseName</b> <span class=mpm>(<code>string</code>)</span><p>baseName of the node. Example: <code>&#39;readme.md&#39;</code>.</p></li><li><b>file.name</b> <span class=mpm>(<code>string</code>)</span><p>Name of the node without the possible extension. Example <code>&#39;readme&#39;</code>.</p></li><li><b>file.extension</b> <span class=mpm>(<code>string</code>|<code>undefined</code>)</span><p>Extension of the node without <code>.</code>. Example: <code>&#39;js&#39;</code>.</p></li><li><b>file.parentPath</b> <span class=mpm>(<code>string</code>)</span><p>pathName of the parent directory of the node.</p></li><li><b>file.rootPath</b> <span class=mpm>(<code>string</code>)</span><p>Root path of the file system.</p></li><li><b>file._stats</b> <span class=mpm>(<code>object</code>|<code>undefined</code>)</span><p>Cached instance of <a href=https://nodejs.org/api/fs.html#fs_class_fs_stats><code>fs.Stats</code></a> for the node.</p></li><li><b>file.fs</b> <span class=mpm>(<code>object</code>)</span><p>Refers to <a href=https://github.com/jprichardson/node-fs-extra><code>fs-extra</code></a> package.</p></li><li><b>file.glob</b> <span class=mpm>(<code>object</code>)</span><p>Refers to <a href=https://github.com/isaacs/node-glob><code>glob</code></a> package.</p></li></ul><h4 id=interfaces-file-methods><a class=h href=#interfaces-file-methods>Methods</a></h4><div class=mds id=file-ensure><b class=header><a class=h href=#file-ensure>ensure</a></b><code class=ms>file.ensure()</code><div class=mp></div><p></p><p>Ensure the file node exists on file system. Wrapper for <a href=https://github.com/jprichardson/node-fs-extra/blob/master/docs/ensureFile.md><code>fs-extra.ensureFile</code></a>.</p><p></p><div class=mret>→ <code>promise</code></div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/interfaces/File.js#L30>source</a></div><div class=mds id=file-ensuresync><b class=header><a class=h href=#file-ensuresync>ensureSync</a></b><code class=ms>file.ensureSync()</code><div class=mp></div><p></p><p>Ensure the file node exists on file system synchronously. Wrapper for <code>fs.ensureFileSync</code>.</p><p></p><div class=mret>→ <code>node</code></div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/interfaces/File.js#L39>source</a></div><div class=mds id=file-append><b class=header><a class=h href=#file-append>append</a></b><code class=ms>file.append()</code><div class=mp></div><p></p><p>Asynchronously append data to a file, creating the file if it does not yet exist. <code>data</code> can be a string or a Buffer. Wrapper for <code>fs.appendFile</code>.</p><p></p><div class=mret>→ <code>promise</code></div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/interfaces/File.js#L49>source</a></div><div class=mds id=file-appendsync><b class=header><a class=h href=#file-appendsync>appendSync</a></b><code class=ms>file.appendSync()</code><div class=mp></div><p></p><p>Wrapper for <code>fs.appendFileSync</code>.</p><p></p><div class=mret>→ <code>node</code></div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/interfaces/File.js#L57>source</a></div><div class=mds id=file-read><b class=header><a class=h href=#file-read>read</a></b><code class=ms>file.read()</code><div class=mp></div><p></p><p>Promisified wrapper for <code>fs.readFile</code>.</p><p></p><div class=mret>→ <code>promise</code> Promise object representing contents of the file.</div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/interfaces/File.js#L66>source</a></div><div class=mds id=file-readsync><b class=header><a class=h href=#file-readsync>readSync</a></b><code class=ms>file.readSync()</code><div class=mp></div><p></p><p>Wrapper for <code>fs.readFileSync</code>.</p><p></p><div class=mret>→ <code>any</code></div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/interfaces/File.js#L74>source</a></div><div class=mds id=file-truncate><b class=header><a class=h href=#file-truncate>truncate</a></b><code class=ms>file.truncate()</code><div class=mp></div><p></p><p>Promisified wrapper for <code>fs.truncate</code></p><p></p><div class=mret>→ <code>promise</code></div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/interfaces/File.js#L82>source</a></div><div class=mds id=file-truncatesync><b class=header><a class=h href=#file-truncatesync>truncateSync</a></b><code class=ms>file.truncateSync()</code><div class=mp></div><p></p><p>Wrapper for <code>fs.truncateSync</code>.</p><p></p><div class=mret>→ <code>node</code></div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/interfaces/File.js#L90>source</a></div><div class=mds id=file-write><b class=header><a class=h href=#file-write>write</a></b><code class=ms>file.write()</code><div class=mp></div><p></p><p>Promisified <code>fs.writeFile</code></p><p></p><div class=mret>→ <code>promise</code></div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/interfaces/File.js#L99>source</a></div><div class=mds id=file-writesync><b class=header><a class=h href=#file-writesync>writeSync</a></b><code class=ms>file.writeSync()</code><div class=mp></div><p></p><p>Wrapper for <code>fs.writeFileSync</code>.</p><p></p><div class=mret>→ <code>node</code></div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/interfaces/File.js#L108>source</a></div><h4>Inherited Static Methods</h4><a class=im href=#node-rawquery>rawQuery</a> <a class=im href=#node-rawquerysync>rawQuerySync</a> <a class=im href=#node-tonodes>toNodes</a> <a class=im href=#node-tonodessync>toNodesSync</a> <a class=im href=#node-query>query</a> <a class=im href=#node-querysync>querySync</a><h4>Inherited Methods</h4><a class=im href=#node-getpathname>getPathName</a> <a class=im href=#node-getbasename>getBaseName</a> <a class=im href=#node-getextension>getExtension</a> <a class=im href=#node-getname>getName</a> <a class=im href=#node-getparentpath>getParentPath</a> <a class=im href=#node-getcachedstats>getCachedStats</a> <a class=im href=#node-getstatprop>getStatProp</a> <a class=im href=#node-getaccesstime>getAccessTime</a> <a class=im href=#node-getmodifiedtime>getModifiedTime</a> <a class=im href=#node-getbirthtime>getBirthTime</a> <a class=im href=#node-getchangetime>getChangeTime</a> <a class=im href=#node-getsize>getSize</a> <a class=im href=#node-isdirectory>isDirectory</a> <a class=im href=#node-isfile>isFile</a> <a class=im href=#node-issymboliclink>isSymbolicLink</a> <a class=im href=#node-isdotfile>isDotFile</a> <a class=im href=#node-renewstats>renewStats</a> <a class=im href=#node-renewstatssync>renewStatsSync</a> <a class=im href=#node-getoctalpermissions>getOctalPermissions</a> <a class=im href=#node-getpermissions>getPermissions</a> <a class=im href=#node-access>access</a> <a class=im href=#node-accesssync>accessSync</a> <a class=im href=#node-chmod>chmod</a> <a class=im href=#node-chmodsync>chmodSync</a> <a class=im href=#node-lchmod>lchmod</a> <a class=im href=#node-lchmodsync>lchmodSync</a> <a class=im href=#node-chown>chown</a> <a class=im href=#node-chownsync>chownSync</a> <a class=im href=#node-lchown>lchown</a> <a class=im href=#node-lchownsync>lchownSync</a> <a class=im href=#node-exists>exists</a> <a class=im href=#node-existssync>existsSync</a> <a class=im href=#node-stat>stat</a> <a class=im href=#node-statsync>statSync</a> <a class=im href=#node-lstat>lstat</a> <a class=im href=#node-lstatsync>lstatSync</a> <a class=im href=#node-link>link</a> <a class=im href=#node-linksync>linkSync</a> <a class=im href=#node-rename>rename</a> <a class=im href=#node-renamesync>renameSync</a> <a class=im href=#node-utimes>utimes</a> <a class=im href=#node-utimessync>utimesSync</a> <a class=im href=#node-copy>copy</a> <a class=im href=#node-copysync>copySync</a> <a class=im href=#node-moveto>moveTo</a> <a class=im href=#node-movetosync>moveToSync</a> <a class=im href=#node-appendto>appendTo</a> <a class=im href=#node-appendtosync>appendToSync</a> <a class=im href=#node-siblings>siblings</a> <a class=im href=#node-siblingssync>siblingsSync</a> <a class=im href=#node-remove>remove</a> <a class=im href=#node-removesync>removeSync</a> <a class=im href=#node-parent>parent</a> <a class=im href=#node-parentsync>parentSync</a><h3 id=interfaces-directory><a class=h href=#interfaces-directory>Directory</a></h3><p></p><p><a href=#interfaces-directory><code>Directory</code></a> class which extends the <a href=#interfaces-node><code>Node</code></a> class is an interface representing pathNames that their <a href=https://nodejs.org/api/fs.html#fs_class_fs_stats><code>fs.Stats</code></a>&#39;s <code>.isDirectory()</code> method returns <code>true</code>.</p><p></p><h4 id=interfaces-directory-syntax><a class=h href=#interfaces-directory-syntax>Syntax:</a></h4><pre class=prettyprint>const directory = new Directory(pathName [, stats]);</pre><h4 id=interfaces-directory-props><a class=h href=#interfaces-directory-props>Properties</a></h4><ul><li><b>directory.nodeName</b> <span class=mpm>(<code>string</code>)</span><p>Name of the node: <code>&#39;Directory&#39;</code>.</p></li><li><b>directory.NODE_TYPE</b> <span class=mpm>(<code>number</code>)</span><p>Code number for the node: <code>1</code>.</p></li><li><b>directory.pathName</b> <span class=mpm>(<code>string</code>)</span><p>Absolute pathName of the node. Example: <code>&#39;/app/readme.md&#39;</code>.</p></li><li><b>directory.baseName</b> <span class=mpm>(<code>string</code>)</span><p>baseName of the node. Example: <code>&#39;readme.md&#39;</code>.</p></li><li><b>directory.name</b> <span class=mpm>(<code>string</code>)</span><p>Name of the node without the possible extension. Example <code>&#39;readme&#39;</code>.</p></li><li><b>directory.extension</b> <span class=mpm>(<code>string</code>|<code>undefined</code>)</span><p>Extension of the node without <code>.</code>. Example: <code>&#39;js&#39;</code>.</p></li><li><b>directory.parentPath</b> <span class=mpm>(<code>string</code>)</span><p>pathName of the parent directory of the node.</p></li><li><b>directory.rootPath</b> <span class=mpm>(<code>string</code>)</span><p>Root path of the file system.</p></li><li><b>directory._stats</b> <span class=mpm>(<code>object</code>|<code>undefined</code>)</span><p>Cached instance of <a href=https://nodejs.org/api/fs.html#fs_class_fs_stats><code>fs.Stats</code></a> for the node.</p></li><li><b>directory.fs</b> <span class=mpm>(<code>object</code>)</span><p>Refers to <a href=https://github.com/jprichardson/node-fs-extra><code>fs-extra</code></a> package.</p></li><li><b>directory.glob</b> <span class=mpm>(<code>object</code>)</span><p>Refers to <a href=https://github.com/isaacs/node-glob><code>glob</code></a> package.</p></li></ul><h4 id=interfaces-directory-methods><a class=h href=#interfaces-directory-methods>Methods</a></h4><div class=mds id=directory-append><b class=header><a class=h href=#directory-append>append</a></b><code class=ms>directory.append(nodes [, options])</code><div class=mp><ul><li><code>nodes</code> (<code>draxt</code>|<code>node</code>|<code>string</code>|<code>array.&lt;(node|string)&gt;</code>)&nbsp;&nbsp;–&nbsp;&nbsp;Accepts various parameters:<ul><li><a href=#draxt><code>draxt</code></a> collection.</li><li>a node instance.</li><li>pathNames of a file or directory.</li><li>array of node instances.</li><li>array of absolute pathNames of files/directories.</li><li>a mixed array of nodePaths and absolute pathNames of files/directories.</li></ul></li><li><code>options</code> (<code>object</code>)&nbsp;&nbsp;–&nbsp;&nbsp;Options for <a href=https://github.com/jprichardson/node-fs-extra/blob/master/docs/move.md><code>fs-extra.move</code></a>.</li></ul></div><p></p><p>Append/move passed directories into this directory node. Uses <code>node.moveTo</code> which uses <a href=https://github.com/jprichardson/node-fs-extra/blob/master/docs/move.md><code>fs-extra.move</code></a>.</p><p></p><div class=mret>→ <code>promise.&lt;nodes&gt;</code> Promise representing array of moved nodes.</div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/interfaces/Directory.js#L40>source</a></div><div class=mds id=directory-appendsync><b class=header><a class=h href=#directory-appendsync>appendSync</a></b><code class=ms>directory.appendSync(nodes [, options])</code><div class=mp><ul><li><code>nodes</code> (<code>draxt</code>|<code>array.&lt;(node|string)&gt;</code>|<code>string</code>)</li><li><code>options</code> (<code>object</code>)&nbsp;&nbsp;–&nbsp;&nbsp;Options for <a href=https://github.com/jprichardson/node-fs-extra/blob/master/docs/move.md><code>fs-extra.move</code></a>.</li></ul></div><p></p><p>Synchronous version of <code>directory.append</code>.</p><p></p><div class=mret>→ <code>node</code> The <code>directory</code> node.</div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/interfaces/Directory.js#L56>source</a></div><div class=mds id=directory-children><b class=header><a class=h href=#directory-children>children</a></b><code class=ms>directory.children([pattern, options])</code><div class=mp><ul><li><code>pattern</code> (<code>string</code>)&nbsp;&nbsp;Default: <code>&#39;*&#39;</code>&nbsp;&nbsp;–&nbsp;&nbsp;Glob pattern relative to the directory. The pattern is used against <code>baseName</code> of directory child nodes.</li><li><code>options</code> (<code>object</code>)&nbsp;&nbsp;–&nbsp;&nbsp;Options for <a href=https://github.com/isaacs/node-glob><code>glob</code></a> package.</li></ul></div><p></p><p>Asynchronously select children of the directory by using <a href=https://github.com/isaacs/node-glob><code>glob</code></a> package and return a <a href=#draxt><code>draxt</code></a> collection.</p><p></p><div class=mret>→ <code>promise.&lt;draxt&gt;</code></div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/interfaces/Directory.js#L73>source</a></div><div class=mds id=directory-childrensync><b class=header><a class=h href=#directory-childrensync>childrenSync</a></b><code class=ms>directory.childrenSync([selector, options])</code><div class=mp><ul><li><code>selector</code> (<code>string</code>)&nbsp;&nbsp;–&nbsp;&nbsp;Optional selector</li><li><code>options</code> (<code>object</code>)&nbsp;&nbsp;–&nbsp;&nbsp;Options for glob package</li></ul></div><p></p><p>Synchronous version of <code>directory.children</code>.</p><p></p><div class=mret>→ <code>draxt</code></div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/interfaces/Directory.js#L90>source</a></div><div class=mds id=directory-empty><b class=header><a class=h href=#directory-empty>empty</a></b><code class=ms>directory.empty()</code><div class=mp></div><p></p><p>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 <a href=https://github.com/jprichardson/node-fs-extra/blob/master/docs/emptyDir.md><code>fs-extra.emptyDir</code></a>.</p><p></p><div class=mret>→ <code>promise</code></div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/interfaces/Directory.js#L107>source</a></div><div class=mds id=directory-emptysync><b class=header><a class=h href=#directory-emptysync>emptySync</a></b><code class=ms>directory.emptySync()</code><div class=mp></div><p></p><p>Synchronous version of <code>directory.empty</code> method. Wrapper for <a href=https://github.com/jprichardson/node-fs-extra/blob/master/docs/emptyDir-sync.md><code>fs-extra.emptyDirSync</code></a>.</p><p></p><div class=mret>→ <code>node</code></div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/interfaces/Directory.js#L116>source</a></div><div class=mds id=directory-ensure><b class=header><a class=h href=#directory-ensure>ensure</a></b><code class=ms>directory.ensure()</code><div class=mp></div><p></p><p>Asynchronously ensure directory exists. Wrapper for <a href=https://github.com/jprichardson/node-fs-extra/blob/master/docs/ensureDir.md><code>fs-extra.ensureDir</code></a>.</p><p></p><div class=mret>→ <code>promise</code></div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/interfaces/Directory.js#L127>source</a></div><div class=mds id=directory-ensuresync><b class=header><a class=h href=#directory-ensuresync>ensureSync</a></b><code class=ms>directory.ensureSync()</code><div class=mp></div><p></p><p>Synchronously ensure directory exists. Wrapper for <a href=https://github.com/jprichardson/node-fs-extra/blob/master/docs/ensureDir-sync.md><code>fs-extra.ensureDirSync</code></a>.</p><p></p><div class=mret>→ <code>node</code></div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/interfaces/Directory.js#L136>source</a></div><div class=mds id=directory-isempty><b class=header><a class=h href=#directory-isempty>isEmpty</a></b><code class=ms>directory.isEmpty()</code><div class=mp></div><p></p><p>Is directory empty?</p><p></p><div class=mret>→ <code>promise.&lt;boolean&gt;</code></div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/interfaces/Directory.js#L145>source</a></div><div class=mds id=directory-isemptysync><b class=header><a class=h href=#directory-isemptysync>isEmptySync</a></b><code class=ms>directory.isEmptySync()</code><div class=mp></div><p></p><p>Synchronous version of <code>directory.isEmpty</code> method.</p><p></p><div class=mret>→ <code>boolean</code></div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/interfaces/Directory.js#L155>source</a></div><div class=mds id=directory-find><b class=header><a class=h href=#directory-find>find</a></b><code class=ms>directory.find(pattern, options)</code><div class=mp><ul><li><code>pattern</code> (<code>string</code>)&nbsp;&nbsp;–&nbsp;&nbsp;Glob pattern.</li><li><code>options</code> (<code>object</code>)&nbsp;&nbsp;–&nbsp;&nbsp;Options for <a href=https://github.com/isaacs/node-glob><code>glob</code></a> package.</li></ul></div><p></p><p>Find matching decendants of the directory node. Uses <a href=https://github.com/isaacs/node-glob><code>glob</code></a> package.</p><p></p><div class=mret>→ <code>Promise.&lt;draxt&gt;</code></div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/interfaces/Directory.js#L166>source</a></div><div class=mds id=directory-findsync><b class=header><a class=h href=#directory-findsync>findSync</a></b><code class=ms>directory.findSync(selector, options)</code><div class=mp><ul><li><code>selector</code> (<code>string</code>)</li><li><code>options</code> (<code>object</code>)&nbsp;&nbsp;–&nbsp;&nbsp;Options for <a href=https://github.com/isaacs/node-glob><code>glob</code></a> package.</li></ul></div><p></p><p>Synchronous version of <code>directory.find</code> method.</p><p></p><div class=mret>→ <code>draxt</code></div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/interfaces/Directory.js#L181>source</a></div><div class=mds id=directory-readdir><b class=header><a class=h href=#directory-readdir>readdir</a></b><code class=ms>directory.readdir(options)</code><div class=mp><ul><li><code>options</code> (<code>string</code>|<code>object</code>)</li></ul></div><p></p><p>Wrapper for promisified <a href=https://nodejs.org/api/fs.html#fs_fs_readdir_path_options_callback><code>fs.readdir</code></a>.</p><p></p><div class=mret>→ <code>promise</code></div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/interfaces/Directory.js#L194>source</a></div><div class=mds id=directory-readdirsync><b class=header><a class=h href=#directory-readdirsync>readdirSync</a></b><code class=ms>directory.readdirSync(options)</code><div class=mp><ul><li><code>options</code> (<code>string</code>|<code>object</code>)</li></ul></div><p></p><p>Wrapper for <a href=https://nodejs.org/api/fs.html#fs_fs_readdirsync_path_options><code>fs.readdirSync</code></a>.</p><p></p><div class=mret>→ <code>array</code></div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/interfaces/Directory.js#L203>source</a></div><div class=mds id=directory-read><b class=header><a class=h href=#directory-read>read</a></b><code class=ms>directory.read(options)</code><div class=mp><ul><li><code>options</code> (<code>string</code>|<code>object</code>)</li></ul></div><p></p><p>Alias for <code>directory.readdir</code> method.</p><p></p><div class=mret>→ <code>promise</code></div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/interfaces/Directory.js#L212>source</a></div><div class=mds id=directory-readsync><b class=header><a class=h href=#directory-readsync>readSync</a></b><code class=ms>directory.readSync(options)</code><div class=mp><ul><li><code>options</code> (<code>string</code>|<code>object</code>)</li></ul></div><p></p><p>Alias for <code>directory.readdirSync</code> method.</p><p></p><div class=mret>→ <code>array</code></div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/interfaces/Directory.js#L221>source</a></div><div class=mds id=directory-rmdir><b class=header><a class=h href=#directory-rmdir>rmdir</a></b><code class=ms>directory.rmdir()</code><div class=mp></div><p></p><p>Wrapper for promisified <a href=https://nodejs.org/api/fs.html#fs_fs_rmdir_path_callback><code>fs.rmdir</code></a>. Deletes the directory, which must be empty.</p><p></p><div class=mret>→ <code>promise</code></div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/interfaces/Directory.js#L230>source</a></div><div class=mds id=directory-rmdirsync><b class=header><a class=h href=#directory-rmdirsync>rmdirSync</a></b><code class=ms>directory.rmdirSync()</code><div class=mp></div><p></p><p>Wrapper for <a href=https://nodejs.org/api/fs.html#fs_fs_rmdirsync_path><code>fs.rmdirSync</code></a>. Deletes the directory, which must be empty.</p><p></p><div class=mret>→ <code>node</code></div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/interfaces/Directory.js#L240>source</a></div><h4>Inherited Static Methods</h4><a class=im href=#node-rawquery>rawQuery</a> <a class=im href=#node-rawquerysync>rawQuerySync</a> <a class=im href=#node-tonodes>toNodes</a> <a class=im href=#node-tonodessync>toNodesSync</a> <a class=im href=#node-query>query</a> <a class=im href=#node-querysync>querySync</a><h4>Inherited Methods</h4><a class=im href=#node-getpathname>getPathName</a> <a class=im href=#node-getbasename>getBaseName</a> <a class=im href=#node-getextension>getExtension</a> <a class=im href=#node-getname>getName</a> <a class=im href=#node-getparentpath>getParentPath</a> <a class=im href=#node-getcachedstats>getCachedStats</a> <a class=im href=#node-getstatprop>getStatProp</a> <a class=im href=#node-getaccesstime>getAccessTime</a> <a class=im href=#node-getmodifiedtime>getModifiedTime</a> <a class=im href=#node-getbirthtime>getBirthTime</a> <a class=im href=#node-getchangetime>getChangeTime</a> <a class=im href=#node-getsize>getSize</a> <a class=im href=#node-isdirectory>isDirectory</a> <a class=im href=#node-isfile>isFile</a> <a class=im href=#node-issymboliclink>isSymbolicLink</a> <a class=im href=#node-isdotfile>isDotFile</a> <a class=im href=#node-renewstats>renewStats</a> <a class=im href=#node-renewstatssync>renewStatsSync</a> <a class=im href=#node-getoctalpermissions>getOctalPermissions</a> <a class=im href=#node-getpermissions>getPermissions</a> <a class=im href=#node-access>access</a> <a class=im href=#node-accesssync>accessSync</a> <a class=im href=#node-chmod>chmod</a> <a class=im href=#node-chmodsync>chmodSync</a> <a class=im href=#node-lchmod>lchmod</a> <a class=im href=#node-lchmodsync>lchmodSync</a> <a class=im href=#node-chown>chown</a> <a class=im href=#node-chownsync>chownSync</a> <a class=im href=#node-lchown>lchown</a> <a class=im href=#node-lchownsync>lchownSync</a> <a class=im href=#node-exists>exists</a> <a class=im href=#node-existssync>existsSync</a> <a class=im href=#node-stat>stat</a> <a class=im href=#node-statsync>statSync</a> <a class=im href=#node-lstat>lstat</a> <a class=im href=#node-lstatsync>lstatSync</a> <a class=im href=#node-link>link</a> <a class=im href=#node-linksync>linkSync</a> <a class=im href=#node-rename>rename</a> <a class=im href=#node-renamesync>renameSync</a> <a class=im href=#node-utimes>utimes</a> <a class=im href=#node-utimessync>utimesSync</a> <a class=im href=#node-copy>copy</a> <a class=im href=#node-copysync>copySync</a> <a class=im href=#node-moveto>moveTo</a> <a class=im href=#node-movetosync>moveToSync</a> <a class=im href=#node-appendto>appendTo</a> <a class=im href=#node-appendtosync>appendToSync</a> <a class=im href=#node-siblings>siblings</a> <a class=im href=#node-siblingssync>siblingsSync</a> <a class=im href=#node-remove>remove</a> <a class=im href=#node-removesync>removeSync</a> <a class=im href=#node-parent>parent</a> <a class=im href=#node-parentsync>parentSync</a><h3 id=interfaces-symboliclink><a class=h href=#interfaces-symboliclink>SymbolicLink</a></h3><p></p><p><a href=#interfaces-symboliclink><code>SymbolicLink</code></a> class which extends the <a href=#interfaces-node><code>Node</code></a> class is an interface representing pathNames that their <a href=https://nodejs.org/api/fs.html#fs_class_fs_stats><code>fs.Stats</code></a>&#39;s <code>.isSymbolicLink()</code> method returns <code>true</code>.</p><p></p><h4 id=interfaces-symboliclink-syntax><a class=h href=#interfaces-symboliclink-syntax>Syntax:</a></h4><pre class=prettyprint>const symbolicLink = new SymbolicLink(pathName [, stats]);</pre><h4 id=interfaces-symboliclink-props><a class=h href=#interfaces-symboliclink-props>Properties</a></h4><ul><li><b>symbolicLink.nodeName</b> <span class=mpm>(<code>string</code>)</span><p>Name of the node: <code>&#39;SymbolicLink&#39;</code>.</p></li><li><b>symbolicLink.NODE_TYPE</b> <span class=mpm>(<code>number</code>)</span><p>Code number for the node: <code>3</code>.</p></li><li><b>symbolicLink.pathName</b> <span class=mpm>(<code>string</code>)</span><p>Absolute pathName of the node. Example: <code>&#39;/app/readme.md&#39;</code>.</p></li><li><b>symbolicLink.baseName</b> <span class=mpm>(<code>string</code>)</span><p>baseName of the node. Example: <code>&#39;readme.md&#39;</code>.</p></li><li><b>symbolicLink.name</b> <span class=mpm>(<code>string</code>)</span><p>Name of the node without the possible extension. Example <code>&#39;readme&#39;</code>.</p></li><li><b>symbolicLink.extension</b> <span class=mpm>(<code>string</code>|<code>undefined</code>)</span><p>Extension of the node without <code>.</code>. Example: <code>&#39;js&#39;</code>.</p></li><li><b>symbolicLink.parentPath</b> <span class=mpm>(<code>string</code>)</span><p>pathName of the parent directory of the node.</p></li><li><b>symbolicLink.rootPath</b> <span class=mpm>(<code>string</code>)</span><p>Root path of the file system.</p></li><li><b>symbolicLink._stats</b> <span class=mpm>(<code>object</code>|<code>undefined</code>)</span><p>Cached instance of <a href=https://nodejs.org/api/fs.html#fs_class_fs_stats><code>fs.Stats</code></a> for the node.</p></li><li><b>symbolicLink.fs</b> <span class=mpm>(<code>object</code>)</span><p>Refers to <a href=https://github.com/jprichardson/node-fs-extra><code>fs-extra</code></a> package.</p></li><li><b>symbolicLink.glob</b> <span class=mpm>(<code>object</code>)</span><p>Refers to <a href=https://github.com/isaacs/node-glob><code>glob</code></a> package.</p></li></ul><h4 id=interfaces-symboliclink-methods><a class=h href=#interfaces-symboliclink-methods>Methods</a></h4><div class=mds id=symboliclink-isbroken><b class=header><a class=h href=#symboliclink-isbroken>isBroken</a></b><code class=ms>symbolicLink.isBroken()</code><div class=mp></div><p></p><p>Is the symlink broken?</p><p></p><div class=mret>→ <code>promise.&lt;boolean&gt;</code></div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/interfaces/SymbolicLink.js#L29>source</a></div><div class=mds id=symboliclink-isbrokensync><b class=header><a class=h href=#symboliclink-isbrokensync>isBrokenSync</a></b><code class=ms>symbolicLink.isBrokenSync()</code><div class=mp></div><p></p><p>Synchronous version of <code>symbolicLink.isBroken</code> method.</p><p></p><div class=mret>→ <code>boolean</code></div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/interfaces/SymbolicLink.js#L39>source</a></div><div class=mds id=symboliclink-readlink><b class=header><a class=h href=#symboliclink-readlink>readlink</a></b><code class=ms>symbolicLink.readlink(options)</code><div class=mp><ul><li><code>options</code> (<code>string</code>|<code>object</code>)&nbsp;&nbsp;–&nbsp;&nbsp;Options for <a href=https://nodejs.org/api/fs.html#fs_fs_readlinksync_path_options><code>fs.readlinkSync</code></a>.</li></ul></div><p></p><p>Asynchronously read the value of the symbolic link. Wrapper for <a href=https://nodejs.org/api/fs.html#fs_fs_readlink_path_options_callback><code>fs.readlink</code></a>.</p><p></p><div class=mret>→ <code>promise.&lt;(string|buffer)&gt;</code></div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/interfaces/SymbolicLink.js#L49>source</a></div><div class=mds id=symboliclink-readlinksync><b class=header><a class=h href=#symboliclink-readlinksync>readlinkSync</a></b><code class=ms>symbolicLink.readlinkSync(options)</code><div class=mp><ul><li><code>options</code> (<code>string</code>|<code>object</code>)&nbsp;&nbsp;–&nbsp;&nbsp;Options for <a href=https://nodejs.org/api/fs.html#fs_fs_readlinksync_path_options><code>fs.readlinkSync</code></a>.</li></ul></div><p></p><p>Synchronously read the value of the symbolic link. Wrapper for <a href=https://nodejs.org/api/fs.html#fs_fs_readlinksync_path_options><code>fs.readlinkSync</code></a>.</p><p></p><div class=mret>→ <code>string</code> | <code>buffer</code></div><a class=msl target=_blank href=https://github.com/ramhejazi/draxt/blob/master/src/interfaces/SymbolicLink.js#L59>source</a></div><h4>Inherited Static Methods</h4><a class=im href=#node-rawquery>rawQuery</a> <a class=im href=#node-rawquerysync>rawQuerySync</a> <a class=im href=#node-tonodes>toNodes</a> <a class=im href=#node-tonodessync>toNodesSync</a> <a class=im href=#node-query>query</a> <a class=im href=#node-querysync>querySync</a><h4>Inherited Methods</h4><a class=im href=#node-getpathname>getPathName</a> <a class=im href=#node-getbasename>getBaseName</a> <a class=im href=#node-getextension>getExtension</a> <a class=im href=#node-getname>getName</a> <a class=im href=#node-getparentpath>getParentPath</a> <a class=im href=#node-getcachedstats>getCachedStats</a> <a class=im href=#node-getstatprop>getStatProp</a> <a class=im href=#node-getaccesstime>getAccessTime</a> <a class=im href=#node-getmodifiedtime>getModifiedTime</a> <a class=im href=#node-getbirthtime>getBirthTime</a> <a class=im href=#node-getchangetime>getChangeTime</a> <a class=im href=#node-getsize>getSize</a> <a class=im href=#node-isdirectory>isDirectory</a> <a class=im href=#node-isfile>isFile</a> <a class=im href=#node-issymboliclink>isSymbolicLink</a> <a class=im href=#node-isdotfile>isDotFile</a> <a class=im href=#node-renewstats>renewStats</a> <a class=im href=#node-renewstatssync>renewStatsSync</a> <a class=im href=#node-getoctalpermissions>getOctalPermissions</a> <a class=im href=#node-getpermissions>getPermissions</a> <a class=im href=#node-access>access</a> <a class=im href=#node-accesssync>accessSync</a> <a class=im href=#node-chmod>chmod</a> <a class=im href=#node-chmodsync>chmodSync</a> <a class=im href=#node-lchmod>lchmod</a> <a class=im href=#node-lchmodsync>lchmodSync</a> <a class=im href=#node-chown>chown</a> <a class=im href=#node-chownsync>chownSync</a> <a class=im href=#node-lchown>lchown</a> <a class=im href=#node-lchownsync>lchownSync</a> <a class=im href=#node-exists>exists</a> <a class=im href=#node-existssync>existsSync</a> <a class=im href=#node-stat>stat</a> <a class=im href=#node-statsync>statSync</a> <a class=im href=#node-lstat>lstat</a> <a class=im href=#node-lstatsync>lstatSync</a> <a class=im href=#node-link>link</a> <a class=im href=#node-linksync>linkSync</a> <a class=im href=#node-rename>rename</a> <a class=im href=#node-renamesync>renameSync</a> <a class=im href=#node-utimes>utimes</a> <a class=im href=#node-utimessync>utimesSync</a> <a class=im href=#node-copy>copy</a> <a class=im href=#node-copysync>copySync</a> <a class=im href=#node-moveto>moveTo</a> <a class=im href=#node-movetosync>moveToSync</a> <a class=im href=#node-appendto>appendTo</a> <a class=im href=#node-appendtosync>appendToSync</a> <a class=im href=#node-siblings>siblings</a> <a class=im href=#node-siblingssync>siblingsSync</a> <a class=im href=#node-remove>remove</a> <a class=im href=#node-removesync>removeSync</a> <a class=im href=#node-parent>parent</a> <a class=im href=#node-parentsync>parentSync</a></div></div><a href=https://github.com/ramhejazi/draxt class=github-corner aria-label="View source on Github"><svg width=80 height=80 viewBox="0 0 250 250" style="fill:#151513; color:#fff; position: fixed; top: 0; border: 0; right: 0;" aria-hidden=true><path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path><path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill=currentColor style="transform-origin: 130px 106px;" class=octo-arm></path><path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" fill=currentColor class=octo-body></path></svg></a><style>.github-corner:hover .octo-arm{animation:octocat-wave 560ms ease-in-out}@keyframes octocat-wave{0%,100%{transform:rotate(0)}20%,60%{transform:rotate(-25deg)}40%,80%{transform:rotate(10deg)}}@media (max-width:500px){.github-corner:hover .octo-arm{animation:none}.github-corner .octo-arm{animation:octocat-wave 560ms ease-in-out}}</style><script></script></body></html>

================================================
FILE: package.json
================================================
{
    "name": "draxt",
    "version": "1.3.0",
    "description": "jQuery/NodeList-like module for file system (nodejs)",
    "author": "Ram Hejazi",
    "main": "src/draxt.js",
    "scripts": {
        "test": "nyc --reporter=text --reporter=html ./node_modules/mocha/bin/mocha test/*"
    },
    "homepage": "https://github.com/ramhejazi/draxt",
    "license": "MIT",
    "repository": {
        "type": "git",
        "url": "git+https://github.com/ramhejazi/draxt.git"
    },
    "keywords": [
        "fs",
        "file",
        "file system",
        "directory",
        "folder",
        "read",
        "write",
        "move",
        "mv",
        "cp",
        "copy",
        "jquery",
        "node",
        "chainable",
        "collection",
        "utility",
        "plugin"
    ],
    "bugs": {
        "url": "https://github.com/ramhejazi/draxt/issues"
    },
    "engines": {
        "node": "20 || >=22"
    },
    "dependencies": {
        "fs-extra": "^11.2.0",
        "glob": "^11.0.0"
    },
    "devDependencies": {
        "chai": "^4.3.10",
        "mocha": "^9.2.2",
        "nyc": "^15.1.0"
    }
}


================================================
FILE: src/draxt.js
================================================
/*eslint no-irregular-whitespace: ["error", { "skipComments": true }]*/

const {Node} = require('./interfaces');
const assign = Object.assign;
const {getType} = require('./util');
const define = Object.defineProperty;
const lengthProps = {
    get() {
        return this.items.length;
    },
    enumerable: true,
    configurable: true,
};

/**
 * `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`).
 * @prop {array} items Items of the collection.
 * @prop {number} length Lenght of collection's items.
 * @param {string|array<node>|node|draxt} [pattern] `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.
 *   - A `Node` or one it's sub-classes (`File`, `Directory` or `SymbolicLink`) instance.
 *     In this case a `draxt` collection containing the passed `node` is returned.
 *   - An array of `node` instances.
 *   - A `draxt` collection to clone (shallow).
 *   - `undefined` which returns an empty `draxt` collection.
 * @param {object|string} [options] 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.
 * @returns {promise<draxt>|draxt}
 * @example
 * // /app
 * //  ├── controllers/
 * //  │   └── index.js
 * //  ├── public/
 * //  │   ├── script.js
 * //  │   └── style.css
 * //  └── views/
 * //      └── index.njk/
 *
 * const draxt = require('draxt');
 * const Directory = draxt.Directory;
 * // Initialization with a glob pattern/selector.
 * // Which returns a `promise` object!
 * draxt('/app/**').then(draxtCollection => {
 *   // draxtCollection: →
 *   Draxt {
 *    length: [Getter],
 *    items: [
 *        Directory { pathName: '/app', ... }
 *        Directory { pathName: '/app/controllers', ... }
 *        File { pathName: '/app/controllers/index.js', ... }
 *        ...
 *    ]
 * });
 * const anEmpyDraxtCollection = draxt();
 * // A `draxt` collection with length of `1`
 * // Which has a manually created `Directory` instance.
 * const draxtCollection = draxt(new Directory('/app'));
 */
function Draxt(pattern, options = {}) {
    // If `this` is not a Draxt instance, create a Draxt instance.
    if (this instanceof Draxt !== true) {
        return new Draxt(...arguments);
    }
    // Define dynamic `length` property.
    define(this, 'length', lengthProps);
    // `items` refers to collection's node.
    this.items = [];

    if (getType(pattern) === 'undefined') {
        return this;
    }

    if (pattern instanceof Node || Array.isArray(pattern)) {
        this.add(pattern);
        return this;
    }

    if (pattern instanceof Draxt) {
        this.items = pattern.get().slice();
        return this;
    }

    return Node.query(pattern, options).then((items) => {
        return this.add(items);
    });
}

Node.Draxt = Draxt;
Draxt.Node = Node;
Draxt.File = Node.File;
Draxt.Directory = Node.Directory;
Draxt.SymbolicLink = Node.SymbolicLink;
Draxt.fn = Draxt.prototype;

/**
 * Synchronously query the file system by using `glob` package and
 * return a new `draxt` collection.
 * @param {string} pattern Glob pattern.
 * @param {object} [options] Options for `glob` package.
 * @returns {draxt} An instance of `draxt`, a.k.a. a _draxt collection_.
 */
Draxt.sync = function () {
    const items = Node.querySync(...arguments);
    return new Draxt(items);
};

/**
 * Extend `draxt` by adding methods to it's `prototype`. Basically works like `jQuery.fn.extend`.
 * @param {object} methods
 */
Draxt.extend = function (methods) {
    assign(Draxt.fn, methods);
};

/**
 * Add node(s) to current `draxt` collection.
 * Pre-exising nodes will not be added to the collection.
 * @param {node|array<node>|draxt} items Instance of Node or array of nodes or a `draxt` collection.
 * @returns {draxt} An instance of `draxt`.
 * @example
 * const draxtCollection = draxt();
 * draxtCollection.add(new Node('/pathName'));
 * draxtCollection.length // → 1
 */
Draxt.prototype.add = function (items) {
    if (items instanceof Draxt) {
        items = items.get();
    }
    const nodes = Array.isArray(items) ? items.slice() : [items];
    nodes.forEach((node) => {
        if (!(node instanceof Node)) {
            throw new Error(
                'Invalid value for `items` parameter. `draxt` collection can only have Node instances. ' +
                    'The given value is a(n) ' +
                    getType(node) +
                    '!'
            );
        }
        const has = this.has(node);
        if (!has) this.items.push(node);
    });
    return this;
};

/**
 * 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).
 * @param {number} [index] - Index of node in items collection.
 * @returns {array<node>|node|undefined}
 */
Draxt.prototype.get = function (index) {
    if (typeof index === 'undefined') {
        return this.items;
    }
    return this.items[index];
};

/**
 * Get the first node (if any) from the collection.
 * @returns {node|undefined}
 */
Draxt.prototype.first = function () {
    return this.items[0];
};

/**
 * Get the last node (if any) from the collection.
 * @returns {node|undefined}
 */
Draxt.prototype.last = function () {
    return this.items[this.items.length - 1];
};

/**
 * 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.
 * @param {string|node} item A `Node` instance or a `pathName`
 * @returns {boolean}
 * @example
 * // 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
 */
Draxt.prototype.has = function (item) {
    const pathName = item instanceof Node ? item.pathName : item;
    const found = this.items.some((node) => node.pathName === pathName);
    return found;
};

/**
 * Slice the collection and return a new `Draxt` collection.
 * Uses `Array.prototype.slice`.
 * @param {integer} [begin] Zero-based index at which to begin extraction.
 * @param {integer} [end] Zero-based index before which to end extraction. `slice` extracts up to but not including `end`.
 * @returns {draxt} A new `draxt` collection which contains sliced items.
 */
Draxt.prototype.slice = function () {
    let sItems = this.items.slice(...arguments);
    return new Draxt(sItems);
};

/**
 * Filter the collection's nodes and return a new `draxt` collection.
 * Uses `Array.prototype.filter`.
 * @param {function} callback A function to execute for each node.
 * @param {any} [thisArg] Value to use as `this` (i.e the reference Object) when executing callback.
 * @returns {draxt} A new `draxt` collection which contains filtered items.
 */
Draxt.prototype.filter = function () {
    let fItems = this.items.filter(...arguments);
    return new Draxt(fItems);
};

/**
 * Iterate over the `draxt` collection and execute a function for each
 * node. Uses `Array.prototype.forEach`.
 * @chainable
 * @param {function} callback A function to execute for each node.
 * @param {any} [thisArg] Value to use as `this` (i.e the reference Object) when executing callback.
 * @returns {draxt} The current collection.
 */
Draxt.prototype.forEach = function () {
    this.items.forEach(...arguments);
    return this;
};

/**
 * Alias for `draxt.forEach`.
 */
Draxt.prototype.each = Draxt.prototype.forEach;

/**
 * Create an array with the results of calling a provided function on every
 * node in the `draxt` collection.
 * Uses `Array.prototype.map`.
 * @param {function} callback A function to execute for each node.
 * @param {any} [thisArg] Value to use as `this` (i.e the reference Object) when executing callback.
 * @returns {array}
 */
Draxt.prototype.map = function () {
    return this.items.map(...arguments);
};

/**
 * Asynchronous version of `draxt.map`. The results of mapped array is passed
 * to `Promise.all` method.
 * @param {function} fn A function to execute for each node.
 * @param {any} [thisArg] Value to use as `this` (i.e the reference Object) when executing callback.
 * @returns {promise}
 */
Draxt.prototype.mapAsync = function () {
    return Promise.all(this.items.map(...arguments));
};

/**
 * Test whether at least one node in the collection passes the test implemented
 * by the provided function.
 * Uses `Array.prototype.some`.
 * @param {function} fn A function to execute for each node.
 * @returns {boolean}
 */
Draxt.prototype.some = function () {
    return this.items.some(...arguments);
};

/**
 * Sort the nodes of collection _in place_ and return the `draxt` collection.
 * Uses `Array.prototype.sort`.
 * @param {function} callback A function that defines the sort order.
 * @returns {draxt} Note that the collection is sorted _in place_, and no copy is made.
 */
Draxt.prototype.sort = function (fn) {
    this.items.sort(fn);
    return this;
};

/**
 * Reverse the collection's nodes _in place_.
 * The first array element becomes the last, and the last array element becomes the first.
 * @returns {draxt}
 */
Draxt.prototype.reverse = function () {
    this.items.reverse();
    return this;
};

/**
 * Filter directory nodes (instances of `Directory` class) and return a new
 * `draxt` collection.
 * @returns {draxt}
 */
Draxt.prototype.directories = function () {
    return this.filter((el) => {
        return el.isDirectory();
    });
};

/**
 * Filter file nodes (instances of `File` class) and return a new `draxt` collection.
 * @returns {draxt}
 */
Draxt.prototype.files = function () {
    return this.filter((el) => {
        return el.isFile();
    });
};

/**
 * Filter symbolic link nodes (instances of `SymbolicLink` class) and return a new `draxt` collection.
 * @returns {draxt}
 */
Draxt.prototype.symlinks = function () {
    return this.filter((el) => {
        return el.isSymbolicLink();
    });
};

/**
 * Empty the `draxt` collection. This method doesn't affect file system!
 * @returns {draxt}
 */
Draxt.prototype.empty = function () {
    this.items = [];
    return this;
};

/**
 * Remove node(s) from the current `draxt` collection by using `.pathName`s as the criterion.
 * @chainable
 * @param {draxt|node|array<node|string>} node Accepts various paramters.
 * @return {draxt}
 */
Draxt.prototype.drop = function (node) {
    let nodes;
    if (node instanceof Node) {
        nodes = [node];
    } else if (node instanceof Draxt) {
        nodes = node.get();
    } else if (getType(node) === 'string') {
        nodes = [node];
    } else if (Array.isArray(node)) {
        nodes = node;
    } else {
        throw new Error('Invalid paramter passed to `.drop()` method');
    }
    const pathNames = nodes.map((item) => {
        if (typeof item === 'string') {
            return item;
        }
        return item.pathName;
    });
    this.items = this.items.filter((node) => {
        return pathNames.indexOf(node.pathName) === -1;
    });
    return this;
};

module.exports = Draxt;


================================================
FILE: src/interfaces/Directory.js
================================================
const Node = require('./Node'),
    {getType} = require('../util');

const nodeProps = {
    nodeName: {value: 'Directory', writable: false, configurable: false, enumerable: true},
    NODE_TYPE: {value: 1, writable: false, configurable: false, enumerable: true},
};

/**
 * `Directory` class which extends the `Node` class is an interface representing pathNames
 * that their `fs.Stats`'s `.isDirectory()` method returns `true`.
 * @prop {string} nodeName Name of the node: `'Directory'`.
 * @prop {number} NODE_TYPE Code number for the node: `1`.
 */
class Directory extends Node {
    /**
     * Construct a new node
     * @param {string} pathName Absolute pathName of the node
     * @param {object} [stats] Instance of `fs.Stats` for the node
     */
    constructor(pathName, stats) {
        super(pathName, stats);
        Object.defineProperties(this, nodeProps);
    }

    /**
     * Append/move passed directories into this directory node.
     * Uses `node.moveTo` which uses `fs-extra.move`.
     * @param {draxt|node|string|array<node|string>} nodes Accepts various parameters:
     *     - `draxt` collection.
     *     - a node instance.
     *     - pathNames of a file or directory.
     *     - array of node instances.
     *     - array of absolute pathNames of files/directories.
     *     - a mixed array of nodePaths and absolute pathNames of files/directories.
     * @param {object} [options] Options for `fs-extra.move`.
     * @returns {promise<nodes>} Promise representing array of moved nodes.
     */
    append(nodes, options) {
        nodes = this.constructor.__normalizeAppendNodes(nodes);
        const mvPromices = nodes.map((node) => {
            node = node instanceof Node ? node : new Node(node);
            return node.moveTo(this, options);
        });
        return Promise.all(mvPromices).then(() => this);
    }

    /**
     * Synchronous version of `directory.append`.
     * @chainable
     * @param {draxt|array<node|string>|string} nodes
     * @param {object} [options] Options for `fs-extra.move`.
     * @returns {node} The `directory` node.
     */
    appendSync(nodes, options) {
        nodes = this.constructor.__normalizeAppendNodes(nodes);
        nodes.forEach((node) => {
            node = node instanceof Node ? node : new Node(node);
            return node.moveToSync(this, options);
        });
        return this;
    }

    /**
     * Asynchronously select children of the directory by using `glob` package and
     * return a `draxt` collection.
     * @param {string} [pattern='*'] Glob pattern relative to the directory. The pattern
     * is used against `baseName` of directory child nodes.
     * @param {object} [options] Options for `glob` package.
     * @returns {promise<draxt>}
     */
    children() {
        const {rawQuery, toNodes, Draxt} = Node;
        let [options, filterFn] = this.__normalizeRelativeGlobOptions(...arguments);
        return rawQuery('*', options).then((items) => {
            if (filterFn) {
                items = items.filter(filterFn);
            }
            return toNodes(items).then(Draxt);
        });
    }

    /**
     * Synchronous version of `directory.children`.
     * @param {string} [selector] Optional selector
     * @param {object} [options] Options for glob package
     * @returns {draxt}
     */
    childrenSync() {
        const {rawQuerySync, toNodesSync, Draxt} = Node;
        let [_options, filterFn] = this.__normalizeRelativeGlobOptions(...arguments);
        let items = rawQuerySync('*', _options);
        if (filterFn) {
            items = items.filter(filterFn);
        }
        return new Draxt(toNodesSync(items));
    }

    /**
     * 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`.
     * @returns {promise}
     */
    empty() {
        return this.fs.emptyDir(this.pathName);
    }

    /**
     * Synchronous version of `directory.empty` method.
     * Wrapper for `fs-extra.emptyDirSync`.
     * @returns {node}
     */
    emptySync() {
        this.fs.emptyDirSync(this.pathName);
        return this;
    }

    /**
     * Asynchronously ensure directory exists.
     * Wrapper for `fs-extra.ensureDir`.
     *@returns {promise}
     */
    ensure() {
        return this.fs.ensureDir(this.pathName);
    }

    /**
     * Synchronously ensure directory exists.
     * Wrapper for `fs-extra.ensureDirSync`.
     * @returns {node}
     */
    ensureSync() {
        this.fs.ensureDirSync(this.pathName);
        return this;
    }

    /**
     * Is directory empty?
     * @returns {promise<boolean>}
     */
    isEmpty() {
        return this.readdir().then((files) => {
            return files.length === 0;
        });
    }

    /**
     * Synchronous version of `directory.isEmpty` method.
     * @returns {boolean}
     */
    isEmptySync() {
        return this.readdirSync().length === 0;
    }

    /**
     * Find matching decendants of the directory node.
     * Uses `glob` package.
     * @param {string} pattern Glob pattern.
     * @param {object} options Options for `glob` package.
     * @returns {Promise<draxt>}
     */
    find(selector, options) {
        const {Draxt} = Node;
        options = Node.__normalizeGlobOptions(options);
        options.cwd = this.pathName;
        return Node.query(selector, options).then((items) => {
            return new Draxt(items);
        });
    }

    /**
     * Synchronous version of `directory.find` method.
     * @param {string} selector
     * @param {object} options Options for `glob` package.
     * @returns {draxt}
     */
    findSync(selector, options) {
        const {Draxt} = Node;
        options = Node.__normalizeGlobOptions(options);
        options.cwd = this.pathName;
        const items = Node.querySync(selector, options);
        return new Draxt(items);
    }

    /**
     * Wrapper for promisified `fs.readdir`.
     * @param {string|object} options
     * @returns {promise}
     */
    readdir() {
        return this.fs.readdir(this.pathName, ...arguments);
    }

    /**
     * Wrapper for `fs.readdirSync`.
     * @param {string|object} options
     * @returns {array}
     */
    readdirSync() {
        return this.fs.readdirSync(this.pathName, ...arguments);
    }

    /**
     * Alias for `directory.readdir` method.
     * @param {string|object} options
     * @returns {promise}
     */
    read() {
        return this.readdir(...arguments);
    }

    /**
     * Alias for `directory.readdirSync` method.
     * @param {string|object} options
     * @returns {array}
     */
    readSync() {
        return this.readdirSync(...arguments);
    }

    /**
     * Wrapper for promisified `fs.rmdir`.
     * Deletes the directory, which must be empty.
     * @returns {promise}
     */
    rmdir() {
        return this.fs.rmdir(this.pathName);
    }

    /**
     * Wrapper for `fs.rmdirSync`.
     * Deletes the directory, which must be empty.
     * @chainable
     * @returns {node}
     */
    rmdirSync() {
        this.fs.rmdirSync(this.pathName);
        return this;
    }

    static __normalizeAppendNodes(nodes) {
        const {Draxt} = Node;
        if (nodes instanceof Draxt) {
            nodes = nodes.get();
        } else if (nodes instanceof Node) {
            nodes = [nodes];
        } else if (getType(nodes) === 'string') {
            nodes = [nodes];
        } else if (getType(nodes) !== 'array') {
            throw new Error(`Invalid parameter for \`nodes\` parameter: ${nodes}`);
        }
        return nodes;
    }
}

module.exports = Node.Directory = Directory;


================================================
FILE: src/interfaces/File.js
================================================
const Node = require('./Node');

const nodeProps = {
    nodeName: {value: 'File', writable: false, configurable: false, enumerable: true},
    NODE_TYPE: {value: 2, writable: false, configurable: false},
};

/**
 * `File` class which extends the `Node` class is an interface representing pathNames
 * that their `fs.Stats`'s `.isFile()` method returns `true`.
 * @prop {string} nodeName Name of the node: `'File'`.
 * @prop {number} NODE_TYPE Code number for the node: `2`.
 */
class File extends Node {
    /**
     * Construct a new file.
     * @param {string} pathName Absolute pathName of the node
     * @param {object} [stats] Instance of `fs.Stats` for the node
     */
    constructor(pathName, stats) {
        super(pathName, stats);
        Object.defineProperties(this, nodeProps);
    }

    /**
     * Ensure the file node exists on file system.
     * Wrapper for `fs-extra.ensureFile`.
     * @returns {promise}
     */
    ensure() {
        return this.fs.ensureFile(this.pathName);
    }

    /**
     * Ensure the file node exists on file system synchronously.
     * Wrapper for `fs.ensureFileSync`.
     * @returns {node}
     */
    ensureSync() {
        this.fs.ensureFileSync(this.pathName);
        return this;
    }

    /**
     * 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`.
     * @returns {promise}
     */
    append() {
        return this.fs.appendFile(this.pathName, ...arguments);
    }

    /**
     * Wrapper for `fs.appendFileSync`.
     * @returns {node}
     */
    appendSync() {
        this.fs.appendFileSync(this.pathName, ...arguments);
        return this;
    }

    /**
     * Promisified wrapper for `fs.readFile`.
     * @returns {promise} Promise object representing contents of the file.
     */
    read() {
        return this.fs.readFile(this.pathName, ...arguments);
    }

    /**
     * Wrapper for `fs.readFileSync`.
     * @returns {any}
     */
    readSync() {
        return this.fs.readFileSync(this.pathName, ...arguments);
    }

    /**
     * Promisified wrapper for `fs.truncate`
     * @returns {promise}
     */
    truncate() {
        return this.fs.truncate(this.pathName, ...arguments);
    }

    /**
     * Wrapper for `fs.truncateSync`.
     * @returns {node}
     */
    truncateSync() {
        this.fs.truncateSync(this.pathName, ...arguments);
        return this;
    }

    /**
     * Promisified `fs.writeFile`
     * @returns {promise}
     */
    write() {
        return this.fs.writeFile(this.pathName, ...arguments);
    }

    /**
     * Wrapper for `fs.writeFileSync`.
     * @chainable
     * @returns {node}
     */
    writeSync() {
        this.fs.writeFileSync(this.pathName, ...arguments);
        return this;
    }
}

module.exports = Node.File = File;


================================================
FILE: src/interfaces/Node.js
================================================
const path = require('path'),
    {glob, globSync} = require('glob'),
    fs = require('fs-extra'),
    minimatch = require('minimatch'),
    {getType} = require('../util'),
    assign = Object.assign;
// Default properies which are used for detecting node type.
const defaultNodeProps = {
    nodeName: {value: 'Node', writable: false, configurable: true, enumerable: true},
    NODE_TYPE: {value: 0, writable: false, configurable: true, enumerable: true},
};

/**
 * Node class is an interface that other classes representing
 * file system's nodes (like `File`, `Directory`, `SymbolicLink`, ...) inherit.
 * @prop {string} [nodeName='Node'] Default: `'Node'`. The name of constructor of the current node.
 * @prop {number} [NODE_TYPE=0] Default: `0`. Code number for the node.
 * @prop {string} pathName Absolute pathName of the node. Example: `'/app/readme.md'`.
 * @prop {string} baseName baseName of the node. Example: `'readme.md'`.
 * @prop {string} name Name of the node without the possible extension. Example `'readme'`.
 * @prop {string|undefined} extension Extension of the node without `.`. Example: `'js'`.
 * @prop {string} parentPath pathName of the parent directory of the node.
 * @prop {string} rootPath Root path of the file system.
 * @prop {object|undefined} _stats Cached instance of `fs.Stats` for the node.
 * @prop {object} fs Refers to `fs-extra` package.
 * @prop {object} glob Refers to `glob` package.
 */
class Node {
    /**
     * Construct a new node
     * @param {string} pathName Absolute pathName of the node
     * @param {object} [stats] Instance of `fs.Stats` for the node
     */
    constructor(pathName, stats) {
        this._stats = stats;
        Object.defineProperties(this, defaultNodeProps);
        this._setPathParams(pathName);
    }

    /**
     * Parse the node's pathName by using `path.parse()` method
     * and set the corresponsing node's properties.
     * @returns {undefined}
     */
    _setPathParams(nodePathname) {
        const {root, dir, name, ext, base} = path.parse(nodePathname);
        this.pathName = nodePathname;
        this.baseName = base;
        this.name = name;
        this.extension = ext.slice(1);
        this.rootPath = root;
        this.parentPath = dir;
    }

    /**
     * Get the node's pathName.
     * @returns {string}
     */
    getPathName() {
        return this.pathName;
    }

    /**
     * Get the node's baseName.
     * @returns {string}
     */
    getBaseName() {
        return this.baseName;
    }

    /**
     * Get the node's extension.
     * @returns {string}
     */
    getExtension() {
        return this.extension;
    }

    /**
     * Get name of the node.
     * For `File` nodes the `name` property is the name of file without possible extension.
     * @returns {string}
     */
    getName() {
        return this.name;
    }

    /**
     * Get the node's parent directory pathName.
     * @returns {string}
     */
    getParentPath() {
        return this.parentPath;
    }

    /**
     * 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.
     * @returns {object|undefined}
     */
    getCachedStats() {
        return this._stats;
    }

    /**
     * Get a stat property's value from cached `fs.Stats` for the node.
     * The method returns `undefined` when there is no cached stats.
     * @param {string} propName
     * @example
     * // Get `blksize` property of fs.Stats instance cached for the node.
     * const node_ctime = node.getStatProp('blksize');
     * @returns {any}
     */
    getStatProp(propName) {
        return (this._stats || {})[propName];
    }

    /**
     * Get "access time" of the node. Returns `atime` property of the cached stats.
     * @returns {date}
     */
    getAccessTime() {
        return this.getStatProp('atime');
    }

    /**
     * Get "modified time" of the node. Returns `mtime` property of the cached stats.
     * @returns {date}
     */
    getModifiedTime() {
        return this.getStatProp('mtime');
    }

    /**
     * Get "birthday time" of the node. Returns `birthtime` property of the cached stats.
     * @returns {date}
     */
    getBirthTime() {
        return this.getStatProp('birthtime');
    }

    /**
     * Get "change time" of the node. Returns `ctime` property of the cached stats.
     * @returns {date}
     */
    getChangeTime() {
        return this.getStatProp('ctime');
    }

    /**
     * Get size of the node.
     * Size is simply the `size` property of the cached `fs.Stats` instance.
     * @returns {number}
     */
    getSize() {
        return this.getStatProp('size');
    }

    /**
     * Is the node a directory?
     * @returns {boolean}
     */
    isDirectory() {
        return this.nodeName === 'Directory';
    }

    /**
     * Is the node a file?
     * @returns {boolean}
     */
    isFile() {
        return this.nodeName === 'File';
    }

    /**
     * Is the node a symbolic link?
     * @returns {boolean}
     */
    isSymbolicLink() {
        return this.nodeName === 'SymbolicLink';
    }

    /**
     * Is the node a dot file? i.e. does the node's name begin with dot character.
     * @returns {boolean}
     */
    isDotFile() {
        return this.baseName[0] === '.';
    }

    /**
     * Asynchronously renew stats of the node. Uses `fs.lstat`.
     * @returns {promise} A fresh `fs.Stats` instance for the node.
     */
    renewStats() {
        return this.fs.lstat(this.pathName).then((stats) => {
            this._stats = stats;
            return stats;
        });
    }

    /**
     * Synchronously renew stats of the node. Uses `fs.lstatSync`.
     * @chainable
     * @returns {node}
     */
    renewStatsSync() {
        const stat = this.lstatSync(this.pathName);
        this._stats = stat;
        return this;
    }

    /**
     * Get octal representation of the node's permissions.
     * @returns {string}
     * @example
     * node.getOctalPermissions() // → "755"
     */
    getOctalPermissions() {
        return (this._stats.mode & 0o777).toString(8);
    }

    /**
     * Get permissions of the node for owner, group and others by converting `mode`
     * property of cached stats into an object.
     * @example
     * node.getPermissions()
     * // →
     * {
     *   read: { owner: true, group: true, others: false },
     *   write: { owner: true, group: true, others: false },
     *   execute: { owner: true, group: true, others: false }
     * }
     * @returns {object}
     */
    getPermissions() {
        if (getType(this._stats) !== 'object') {
            throw new Error(
                'No valid cached stats ofr this node. Run `.renewStats()` before calling this function!'
            );
        }
        // Logic taken from npm `mode-to-permissions` module
        const mode = this._stats.mode,
            owner = mode >> 6,
            group = (mode << 3) >> 6,
            others = (mode << 6) >> 6;

        return {
            read: {
                owner: !!(owner & 4),
                group: !!(group & 4),
                others: !!(others & 4),
            },
            write: {
                owner: !!(owner & 2),
                group: !!(group & 2),
                others: !!(others & 2),
            },
            execute: {
                owner: !!(owner & 1),
                group: !!(group & 1),
                others: !!(others & 1),
            },
        };
    }

    /**
     * Asynchronously tests a user's permissions for the file or directory.
     * Wrapper for promisified `fs.access`.
     * @param {integer} [mode=fs.constants.F_OK]
     * @returns {promise}
     * @example
     * // Check if the node is readable.
     * node.access(node.fs.constants.R_OK).then(() => {
     *   // node is readable
     * }).catch(e => {
     *   // node is not readable
     * });
     */
    access(mode) {
        return this.fs.access(this.pathName, mode);
    }

    /**
     * Wrapper for `fs.accessSync`.
     * @chainable
     * @param {integer} [mode=fs.constants.F_OK]
     * @returns {node} this
     */
    accessSync(mode) {
        this.fs.accessSync(this.pathName, mode);
        return this;
    }

    /**
     * Wrapper for promisified `fs.chmod`.
     * @param {integer} mode
     * @returns {promise}
     */
    chmod(mode) {
        return this.fs.chmod(this.pathName, mode);
    }

    /**
     * Wrapper for `fs.chmodSync`.
     * @chainable
     * @param {integer} mode
     * @returns {node} this
     */
    chmodSync(mode) {
        this.fs.chmodSync(this.pathName, mode);
        return this;
    }

    /**
     * Wrapper for promisified `fs.lchmod`.
     * @param {integer} mode
     * @returns {promise}
     */
    lchmod(mode) {
        return this.fs.lchmod(this.pathName, mode);
    }

    /**
     * Wrapper for `fs.lchmodSync`.
     * @chainable
     * @param {integer} mode
     * @returns {node}
     */
    lchmodSync(mode) {
        this.fs.lchmodSync(this.pathName, mode);
        return this;
    }

    /**
     * Wrapper for promisified `fs.chown`.
     * @param {integer} uid The user id
     * @param {integer} gid The group id
     * @returns {promise}
     */
    chown(uid, gid) {
        return this.fs.chown(this.pathName, uid, gid);
    }

    /**
     * Wrapper for `fs.chownSync`.
     * @chainable
     * @param {integer} uid The user id
     * @param {integer} gid The group id
     * @returns {node} The file node
     */
    chownSync(uid, gid) {
        this.fs.chownSync(this.pathName, uid, gid);
        return this;
    }

    /**
     * Wrapper for promisified `fs.lchown`.
     * @param {integer} uid The user id
     * @param {integer} gid The group id
     * @returns {promise}
     */
    lchown(uid, gid) {
        return this.fs.lchown(this.pathName, uid, gid);
    }

    /**
     * Wrapper for `fs.lchownSync`.
     * @chainable
     * @param {integer} uid The user id
     * @param {integer} gid The group id
     * @returns {node} The file node
     */
    lchownSync(uid, gid) {
        this.fs.lchownSync(this.pathName, uid, gid);
        return this;
    }

    /**
     * Does node exist on file system?
     * Uses `fs.access` instead of the deprecated `fs.exists` method.
     * @returns {promise<boolean>}
     */
    exists() {
        return this.access(this.fs.constants.F_OK)
            .then(() => {
                return true;
            })
            .catch(() => false);
    }

    /**
     * Does node exist on file system?
     * Wrapper for `fs.existsSync`.
     * @returns {boolean}
     */
    existsSync() {
        return this.fs.existsSync(this.pathName);
    }

    /**
     * Wrapper for promisified `fs.stat`.
     * @returns {promise} Promise representing instance of `fs.Stats` for the node.
     */
    stat() {
        return this.fs.stat(this.pathName, ...arguments);
    }

    /**
     * Wrapper for `fs.statSync`.
     * @returns {object} Instance of `fs.Stats` for the node.
     */
    statSync() {
        return this.fs.statSync(this.pathName, ...arguments);
    }

    /**
     * Wrapper for promisified `fs.lstat`.
     * @returns {promise} Promise representing instance of `fs.Stats` for the node.
     */
    lstat() {
        return this.fs.lstat(this.pathName, ...arguments);
    }

    /**
     * Wrapper for `fs.lstatSync`.
     * @returns {object} Instance of `fs.Stats` for the node.
     */
    lstatSync() {
        return this.fs.lstatSync(this.pathName, ...arguments);
    }

    /**
     * Wrapper for promisified `fs.link`.
     * @param {string|Buffer|URL} newPath
     * @returns {Promise}
     */
    link(newPath) {
        return this.fs.link(this.pathName, newPath);
    }

    /**
     * Wrapper for `fs.linkSync`.
     * @chainable
     * @param {string|buffer|URL} newPath
     * @returns {node}
     */
    linkSync(newPath) {
        this.fs.linkSync(this.pathName, newPath);
        return this;
    }

    /**
     * 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`.
     * @param newPath {string|Buffer|URL}
     * @returns {promise}
     */
    rename(newPath) {
        return this.fs.rename(this.pathName, ...arguments).then(() => {
            this._setPathParams(newPath);
        });
    }

    /**
     * Wrapper for `fs.renameSync`.
     * @chainable
     * @param newPath {string|Buffer|URL}
     * @returns {node}
     */
    renameSync(newPath) {
        this.fs.renameSync(this.pathName, newPath);
        this._setPathParams(newPath);
        return this;
    }

    /**
     * Wrapper for promisified `fs.utimes`.
     * @param atime {number|string|Date}
     * @param mtime {number|string|Date}
     * @returns {promise}
     */
    utimes() {
        return this.fs.utimes(this.pathName, ...arguments);
    }

    /**
     * Wrapper for `fs.utimesSync`.
     * @chainable
     * @param atime {number|string|Date}
     * @param mtime {number|string|Date}
     * @returns {node}
     */
    utimesSync() {
        this.fs.utimesSync(this.pathName, ...arguments);
        return this;
    }

    /**
     * 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`.
     * @param {string} destPath Destination path.
     * @param {object} options Options for `fs-extra.copy`.
     * @returns {promise}
     * @example
     * // 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!
     * });
     */
    copy() {
        return this.fs.copy(this.pathName, ...arguments);
    }

    /**
     * Wrapper for `fs-extra.copySync`.
     * @chainable
     * @param {string} destPath Destination path.
     * @param {object} options Options for `fs-extra.copySync`.
     * @returns {node}
     */
    copySync() {
        this.fs.copySync(this.pathName, ...arguments);
        return this;
    }

    /**
     * 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`.
     * @param {object|string} targetDir `Directory` instance or absolute path of the target directory.
     * @param {object} options Options for `fs-extra.move`.
     * @return {promise}
     * @example
     * 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'
     * });
     */
    moveTo(targetDir, options) {
        const targetPath = this.__resolvePath(targetDir);
        if (typeof options === 'function') {
            throw new Error('`node.moveTo` doesn not accept a callback function!');
        }
        // Fix `fs.move` broken handling of optional parameters!
        const args = [this.pathName, targetPath];
        if (options) {
            args.push(options);
        }
        return this.fs.move(...args).then(() => {
            this._setPathParams(targetPath);
            return this;
        });
    }

    /**
     * Synchronous version of `node.moveTo`.
     * @chainable
     * @param {object|string} targetDir `Directory` instance or absolute path of the target directory.
     * @param {object} options Options for `fs-extra.move`.
     * @returns {node}
     */
    moveToSync(targetDir, options) {
        const targetPath = this.__resolvePath(targetDir);
        this.fs.moveSync(this.pathName, targetPath, options);
        this._setPathParams(targetPath);
        return this;
    }

    /**
     * Alias for `node.moveTo`.
     */
    appendTo() {
        return this.moveTo(...arguments);
    }

    /**
     * Alias for `node.moveToSync`.
     * @chainable
     * @returns {node}
     */
    appendToSync() {
        return this.moveToSync(...arguments);
    }

    /**
     * Asynchronously select siblings of the node.
     * Uses `glob` package.
     * @param {string} [patten='*'] Optional `glob` pattern.
     * @param {object} [options] Options for `glob` package.
     * @return {promise<draxt>} Promise representing a `draxt` collection.
     */
    siblings() {
        const {rawQuery, toNodes, Draxt} = Node;
        let [_options, filterFn] = this.__normalizeRelativeGlobOptions(...arguments);
        _options.ignore.push(this.pathName);
        return rawQuery('*', _options).then((items) => {
            if (filterFn) {
                items = items.filter(filterFn);
            }
            return toNodes(items).then(Draxt);
        });
    }

    /**
     * Synchronously select siblings of the node.
     * Uses `glob` package.
     * @param {string} [pattern='*'] Optional `glob` pattern.
     * @param {object} [options] Options for `glob` package.
     * @return {draxt} A `draxt` collection.
     */
    siblingsSync() {
        const {rawQuerySync, toNodesSync, Draxt} = Node;
        let [_options, filterFn] = this.__normalizeRelativeGlobOptions(...arguments);
        _options.ignore.push(this.pathName);
        let items = rawQuerySync('*', _options);
        if (filterFn) {
            items = items.filter(filterFn);
        }
        return new Draxt(toNodesSync(items));
    }

    /**
     * Remove the node from file system! `Directory` nodes can have contents. Like `rm -rf`.
     * Wrapper for `fs-extra.remove`.
     * @returns {promise}
     */
    remove() {
        return this.fs.remove(this.pathName, ...arguments);
    }

    /**
     * Wrapper for `fs-extra.removeSync`.
     * @chainable
     * @returns {node}
     */
    removeSync() {
        this.fs.removeSync(this.pathName, ...arguments);
        return this;
    }

    /**
     * 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!
     * @returns {promise<node>} Promise representing a `Directory` instance.
     * @example
     * const file = new File('/app/resources/style.css');
     * file.parent().then(dir => {
     *   dir.isDirectory(); // → true
     *   dir.getPathName(); // → '/app/resources'
     * });
     */
    parent() {
        const {Directory} = Node;
        return this.fs.lstat(this.parentPath).then((stats) => {
            return new Directory(this.parentPath, stats);
        });
    }

    /**
     * Synchronously get parent directory node of the node.
     * @returns {node} A `Directory` instance.
     */
    parentSync() {
        const {Directory} = Node;
        const stats = this.fs.lstatSync(this.parentPath);
        return new Directory(this.parentPath, stats);
    }

    /**
     * Asynchronously query the file system by using `glob` package.
     * @param {string} pattern Pattern for `glob` package.
     * @param {object} [options] Options for `glob` package.
     * @returns {promise<array>} An array of pathNames.
     */
    static rawQuery(pattern, options) {
        options = Node.__normalizeGlobOptions(options);
        return glob(pattern, options);
    }

    /**
     * Synchronously query the file system by using `glob` package.
     * @param {string} pattern Pattern for `glob` package.
     * @param {object} [options] Options for `glob` package.
     * @returns {array} An array of pathNames.
     */
    static rawQuerySync(pattern, options) {
        options = Node.__normalizeGlobOptions(options);
        return globSync(pattern, options);
    }

    /**
     * Convert array of paths to array of node instances asynchronously!
     * A node instance can be an instance of `File`, `Directory` or `SymbolicLink`.
     * @param {array} pathNames Array of pathNames.
     * @returns {promise<array>} Array of node instances.
     * @example
     * const pathNames = [
     *   '/app/resources',
     *   '/app/resources/style.css'
     * ];
     * Node.toNodes(pathNames).then(result => {
     *    // result:
     *    [
     *      Directory { pathName: '/app/resources', ... },
     *      File { pathName: '/app/resources/style.css', ... }
     *    ]
     * });
     */
    static toNodes(pathNames) {
        const nItems = [];
        const ps = pathNames.map((item, i) => {
            return fs.lstat(item).then((stats) => {
                nItems[i] = Node.__statsToNode(item, stats);
            });
        });
        return Promise.all(ps).then(() => nItems);
    }

    /**
     * Convert array of paths to array of nodes synchronously!
     * A node instance can be instance of `File`, `Directory` or `SymbolicLink`.
     * @param {array} pathNames Array of paths
     * @returns {array} Array of node instances.
     */
    static toNodesSync(pathNames) {
        return pathNames.map((item) => {
            const stats = fs.lstatSync(item);
            return Node.__statsToNode(item, stats);
        });
    }

    /**
     * Create a node object by analyzing `fs.Stats` of a pathName.
     * @param {string} pathName Absolute pathName of the node.
     * @param {object} stats Instance of `fs.Stats` for the pathName.
     * @returns {node}
     */
    static __statsToNode(pathName, stats) {
        const {File, Directory, SymbolicLink} = Node;
        if (stats.isFile()) {
            return new File(pathName, stats);
        } else if (stats.isDirectory()) {
            return new Directory(pathName, stats);
        } else if (stats.isSymbolicLink()) {
            return new SymbolicLink(pathName, stats);
        } else {
            return new Node(pathName, stats);
        }
    }

    /**
     * Asynchronously query the file system by using `glob` package.
     * @param {string} pattern A `glob` pattern.
     * @param {object} [options] Options for `glob` package.
     * @returns {promise<array>} Array of nodes.
     */
    static query() {
        const {rawQuery, toNodes} = Node;
        return rawQuery(...arguments).then(toNodes);
    }

    /**
     * Synchronously query the file system by using `glob` package.
     * @param {string} pattern
     * @param {object} [options] Options for `glob` package.
     * @returns {array} Array of nodes.
     */
    static querySync() {
        const {rawQuerySync, toNodesSync} = Node;
        return toNodesSync(rawQuerySync(...arguments));
    }

    /**
     * Normalize glob options. This function overrides some possible user-set
     * params like the `absolute` parameter.
     * @param {object} options
     * @returns {object} Normalized object
     */
    static __normalizeGlobOptions(options = {}) {
        const type = getType(options);
        if (type !== 'undefined' && ['string', 'object'].indexOf(type) === -1) {
            throw new Error('Optional `options` parameter must be either a string or an object!');
        }
        // query(pattern, context) syntax
        if (type === 'string') {
            options = {
                cwd: options,
            };
        }

        assign(options, {
            absolute: true,
        });

        return options;
    }

    /**
     * Normalize glob options for `Node#siblings` and `Node#siblingsSync` methods.
     * @param {string} [pattern] Optional pattern
     * @param {object} [options] Optional options
     * @return {array}
     */
    __normalizeRelativeGlobOptions(pattern, options = {}) {
        let filterFn;
        if (arguments.length === 1 && getType(pattern) === 'object') {
            options = pattern;
            pattern = undefined;
        }
        if (pattern && getType(pattern) !== 'string') {
            throw new Error('`pattern` parameter should be a string!');
        }
        if (getType(options) === 'string') {
            throw new Error('Relational queries do not accept `context` paramter!');
        }
        if (options && getType(options) !== 'object') {
            throw new Error('Invalid type for `options` parameter!');
        }

        // Convert `options.ignore` into an array (if it's not)
        let ignore = options.ignore;
        if (ignore) {
            if (!Array.isArray(ignore)) {
                ignore = [ignore];
            }
        } else {
            ignore = [];
        }
        options.ignore = ignore;

        // If `pattern` exists create a minimatch filter function
        if (pattern) {
            filterFn = minimatch.filter(pattern, {
                matchBase: true,
                dot: !!options.dot,
            });
        }

        const dirPath = this.nodeName === 'Directory' ? this.pathName : this.parentPath;

        assign(options, {
            cwd: dirPath,
        });

        return [options, filterFn];
    }

    /**
     * Make a pathName by joining `dir` parameter with node's `baseName`
     * @param {node|string} dir Instance of `Directory` class or a string pathName
     * @returns {string}
     */
    __resolvePath(dir) {
        const dirType = typeof dir;
        if (dirType === 'undefined') {
            throw new Error('`dir` parameter is required!');
        }
        const isDirectory = dir.nodeName === 'Directory';
        if (!isDirectory && dirType !== 'string') {
            throw new Error('`dir` parameter must be a string or instance of Directory class!');
        }
        const dirPath = isDirectory ? dir.pathName : dir;

        if (!path.isAbsolute(dirPath)) {
            throw new Error('`dir` must be an absolute path!');
        }
        return path.join(dirPath, this.baseName);
    }
}

Node.prototype.fs = fs;
Node.prototype.glob = glob;

module.exports = Node;


================================================
FILE: src/interfaces/SymbolicLink.js
================================================
const Node = require('./Node'),
    nodeProps = {
        nodeName: {value: 'SymbolicLink', writable: false, configurable: false, enumerable: true},
        NODE_TYPE: {value: 3, writable: false, configurable: false, enumerable: true},
    };

/**
 * `SymbolicLink` class which extends the `Node` class is an interface representing pathNames
 * that their `fs.Stats`'s `.isSymbolicLink()` method returns `true`.
 * @prop {string} nodeName Name of the node: `'SymbolicLink'`.
 * @prop {number} NODE_TYPE Code number for the node: `3`.
 */
class SymbolicLink extends Node {
    /**
     * Construct a new symbolic link.
     * @param {string} pathName Absolute pathName of the node
     * @param {object} [stats] Instance of `fs.Stats` for the node
     */
    constructor(nodePath, stats) {
        super(nodePath, stats);
        Object.defineProperties(this, nodeProps);
    }

    /**
     * Is the symlink broken?
     * @returns {promise<boolean>}
     */
    isBroken() {
        return this.readlink().then((linkPath) => {
            return this.exists(linkPath).then((ret) => !ret);
        });
    }

    /**
     * Synchronous version of `symbolicLink.isBroken` method.
     * @returns {boolean}
     */
    isBrokenSync() {
        return !this.existsSync(this.readlinkSync());
    }

    /**
     * Asynchronously read the value of the symbolic link.
     * Wrapper for `fs.readlink`.
     * @param {string|object} options Options for `fs.readlinkSync`.
     * @returns {promise<string|buffer>}
     */
    readlink(options) {
        return this.fs.readlink(this.pathName, options);
    }

    /**
     * Synchronously read the value of the symbolic link.
     * Wrapper for `fs.readlinkSync`.
     * @param {string|object} options Options for `fs.readlinkSync`.
     * @returns {string|buffer}
     */
    readlinkSync(options) {
        return this.fs.readlinkSync(this.pathName, options);
    }
}

module.exports = Node.SymbolicLink = SymbolicLink;


================================================
FILE: src/interfaces/index.js
================================================
module.exports = {
    Node: require('./Node'),
    File: require('./File'),
    Directory: require('./Directory'),
    SymbolicLink: require('./SymbolicLink'),
};


================================================
FILE: src/util.js
================================================
/**
 * A simple utility object
 */
module.exports = {
	/**
	 * Get type of a variable
	 * @param {any} value
	 * @returns {string}
	 */
	getType(value) {
		return Object.prototype
			.toString
			.apply(value)
			.match(/\[object (\w+)\]/)[1]
			.toLowerCase();
	}
}


================================================
FILE: test/draxt.js
================================================
/* global describe, it, beforeEach, afterEach*/
const draxt = require('../src/draxt'),
    {expect} = require('chai'),
    {execSync} = require('child_process'),
    {Node} = draxt;

const contentList = ['a.js', 'another_dir', 'another_example_file.md', 'b.md', 'example_file.md'];
const mkfs = () => {
    const pre = `
					rm -r /tmp/draxt_test_dir
					mkdir /tmp/draxt_test_dir
					echo 'example content' > /tmp/draxt_test_dir/example_file.md
					echo 'example content' > /tmp/draxt_test_dir/another_example_file.md
					mkdir /tmp/draxt_test_dir/another_dir
					echo '...' > /tmp/draxt_test_dir/a.js
					ln -s /tmp/draxt_test_dir/another_example_file /tmp/draxt_test_dir/b.md
				`;
    execSync(pre);
};
describe('draxt', function () {
    beforeEach(function () {
        mkfs();
    });

    afterEach(function () {
        mkfs();
    });

    it('basic initialization', function () {
        expect(draxt()).to.be.instanceof(draxt);
        expect(draxt().length).to.eql(0);
        expect(() => draxt(['str'])).to.throw('Invalid value for `items` parameter');
        const items_one = [new Node('pathName')];
        const d_one = draxt(items_one);
        expect(d_one.length).to.eql(1);
        expect(d_one.items).to.eql(items_one);
        expect(draxt.fn).to.eql(draxt.prototype);
    });

    it('initialization with query', function () {
        return draxt('/tmp/draxt_test_dir/*').then((d) => {
            expect(d).to.be.instanceof(draxt);
            expect(d.length).to.eql(5);
            expect(draxt(d).items).to.eql(d.items);
            expect(draxt(d).length).to.eql(d.length);
            // make sure the `items` parameter has been cloned!
            expect(draxt(d).items === d.items).to.eql(false);
        });
    });

    it('.sync()', function () {
        const result = draxt.sync('/tmp/draxt_test_dir');
        expect(result).to.be.instanceof(draxt);
        expect(result.length).to.eql(1);
        expect(draxt.sync('/tmp/draxt_test_dir/*').length).to.eql(5);
    });

    it('.extend()', function () {
        const exampleFunc = function () {
            return 'exampleFunc';
        };
        draxt.extend({
            exampleFunc,
        });
        expect(draxt.prototype.exampleFunc).to.eql(exampleFunc);
        expect(draxt.fn.exampleFunc).to.eql(exampleFunc);
    });

    it('.add()', function () {
        const d = draxt();
        expect(d.length).to.eql(0);
        const node = new Node('pathName');
        d.add(node);
        expect(d.length).to.eql(1);
        // should not add a duplicate item!
        d.add(node);
        expect(d.length).to.eql(1);
        d.add(new Node('pathName'));
        expect(d.length).to.eql(1);
        d.add(new Node('pathName2'));
        expect(d.length).to.eql(2);
        const d2 = draxt([new Node('pathName3')]);
        d.add(d2);
        expect(d.length).to.eql(3);
    });

    it('.get()', function () {
        const d = draxt.sync('/tmp/draxt_test_dir/*');
        const node = d.get();
        expect(node).to.be.an('array');
        expect(node).to.be.eql(d.items);
        expect(d.get(0)).to.be.eql(d.items[0]);
    });

    it('.first() && .last()', function () {
        const d = draxt.sync('/tmp/draxt_test_dir/*');
        expect(d.first()).to.eql(d.items[0]);
        expect(d.last()).to.eql(d.items.pop());
    });

    it('.has()', function () {
        const d = draxt.sync('/tmp/draxt_test_dir/*');
        expect(d.has('/tmp/draxt_test_dir/another_dir')).to.eql(true);
        expect(d.has(new Node('/tmp/draxt_test_dir/another_dir'))).to.eql(true);
        expect(d.has('/tmp/draxt_test_dir/non_existent')).to.eql(false);
    });

    it('.slice()', function () {
        const d = draxt.sync('/tmp/draxt_test_dir/**');
        expect(d.length).to.eql(6);
        const d2 = d.slice(0, 4);
        expect(d2).to.be.instanceof(draxt);
        expect(d2.length).to.be.eql(4);
        const d3 = d.slice(-1);
        expect(d3.length).to.eql(1);
        expect(d3.get(0)).to.be.instanceof(Node);
    });

    it('.filter()', function () {
        const d = draxt.sync('/tmp/draxt_test_dir/**');
        const d2 = d.filter((node) => {
            return node.isFile();
        });
        expect(d2).to.be.instanceof(draxt);
        expect(d === d2).to.eql(false);
        expect(d2.length).to.eql(3);
    });

    it('.map()', function () {
        const d = draxt.sync('/tmp/draxt_test_dir/*');
        const res = d.map((node) => node.baseName);
        res.sort();
        expect(res.length).to.eql(d.length);
        expect(res).to.be.an('array');
        expect(res).to.eql(contentList);
    });

    it('.mapAsync', function () {
        const d = draxt.sync('/tmp/draxt_test_dir/*');
        const res = d.mapAsync((node) => {
            return new Promise((res) => {
                setTimeout(() => res(node.baseName), 30);
            });
        });
        expect(res).to.be.instanceof(Promise);
        return res.then((baseNames) => {
            baseNames.sort();
            expect(baseNames).to.eql(contentList);
        });
    });

    it('.each() && .forEach()', function () {
        const d = draxt.sync('/tmp/draxt_test_dir/*');
        expect(d.each).to.be.eql(d.forEach);
        const res = [];
        expect(d.forEach((node) => res.push(node.baseName))).to.eql(d);
        res.sort();
        expect(res).to.eql(contentList);
    });

    it('.some', function () {
        const d = draxt.sync('/tmp/draxt_test_dir/*');
        const res = d.some((node) => node.baseName === 'another_dir');
        const res2 = d.some((node) => node.baseName === 'non_existent');
        expect(res).to.eql(true);
        expect(res2).to.eql(false);
    });

    it('.sort() && .reverse()', function () {
        const d = draxt.sync('/tmp/draxt_test_dir/*');
        const originalNodesBackup = d.get().slice();
        expect(d.reverse().get()).to.eql(originalNodesBackup.reverse());
    });

    it('.directories()', function () {
        const d = draxt.sync('/tmp/draxt_test_dir/**');
        const dirs = d.directories();
        expect(dirs.length).to.eql(2);
        expect(dirs === d).to.eql(false);
    });

    it('.files()', function () {
        const d = draxt.sync('/tmp/draxt_test_dir/**');
        const files = d.files();
        expect(files.length).to.eql(3);
        expect(files === d).to.eql(false);
    });

    it('.symlinks()', function () {
        const d = draxt.sync('/tmp/draxt_test_dir/**');
        const symlinks = d.symlinks();
        expect(symlinks.length).to.eql(1);
        expect(symlinks).to.be.instanceof(draxt);
    });

    it('.empty()', function () {
        const d = draxt.sync('/tmp/draxt_test_dir/**');
        expect(d.length).to.eql(6);
        expect(d.empty()).to.eql(d);
        expect(d.length).to.eql(0);
    });

    it('.drop()', function () {
        const d = draxt.sync('/tmp/draxt_test_dir/**');
        expect(d.length).to.eql(6);
        d.drop('/tmp/draxt_test_dir/example_file.md');
        expect(d.length).to.eql(5);
        d.drop([new Node('/tmp/draxt_test_dir/another_example_file.md'), '/non_existent']);
        expect(d.length).to.eql(4);
        const d2 = draxt.sync('/tmp/draxt_test_dir/another_dir/*');
        d.drop(d2);
        expect(d.length).to.eql(4);
        d.drop(new Node('/tmp/draxt_test_dir'));
        expect(d.length).to.eql(3);
        expect(() => d.drop(new Date())).to.throw('Invalid paramter passed to');
    });
});


================================================
FILE: test/interfaces/Directory.js
================================================
/* global describe, beforeEach, it*/
const Draxt = require('../../src/draxt');
const {expect} = require('chai');
const {execSync} = require('child_process');
const {Directory, File} = Draxt.Node;
const shouldNotPass = function () {
    throw new Error('should not pass!');
};

describe('Directory', function () {
    describe('initialization and basic methods', function () {
        const nodePath = '/fake/_fakepath';
        const stats = {};
        it('`new`', function () {
            const node = new Directory(nodePath, stats);
            expect(node.pathName).to.eql(nodePath);
            expect(node.extension).to.eql('');
            expect(node.name).to.eql('_fakepath');
            expect(node.baseName).to.eql('_fakepath');
            expect(node.parentPath).to.eql('/fake');
            expect(node.getCachedStats() === stats).to.eql(true);
        });

        it('path.parse methods', function () {
            const node = new Directory(nodePath, stats);
            expect(node.getPathName()).to.eql(nodePath);
            expect(node.getExtension()).to.eql('');
            expect(node.getName()).to.eql('_fakepath');
            expect(node.getBaseName()).to.eql('_fakepath');
            expect(node.getParentPath()).to.eql('/fake');
        });
    });

    describe('fs methods', function () {
        beforeEach(function () {
            const pre = `
					rm -r /tmp/fake_test_dir
					mkdir /tmp/fake_test_dir
					mkdir /tmp/fake_test_dir/empty_dir
					mkdir /tmp/fake_test_dir/empty_dir2
					mkdir /tmp/fake_test_dir/non_empty_dir
					mkdir /tmp/fake_test_dir/non_empty_dir/foo
					mkdir /tmp/fake_test_dir/non_empty_dir/.git
					mkdir /tmp/fake_test_dir/non_empty_dir2
					echo 'example content' > /tmp/fake_test_dir/example_file.md
					echo 'content' > /tmp/fake_test_dir/non_empty_dir/file.rb
					echo 'content' > /tmp/fake_test_dir/non_empty_dir2/file.md
				`;
            execSync(pre);
        });

        it('.rmdir() & .rmdirSync() & .ensure() & .ensureSync()', function () {
            const dir = new Directory('/tmp/fake_test_dir/empty_dir');
            const dir2 = new Directory('/tmp/fake_test_dir/non_empty_dir');
            expect(dir.existsSync()).to.eql(true);
            expect(dir.rmdirSync()).to.eql(dir);
            expect(dir.existsSync()).to.eql(false);
            // recreate the dir
            expect(dir.ensureSync()).to.eql(dir);
            // make sure the generated node is a directory
            expect(dir.renewStatsSync().isDirectory()).to.eql(true);
            expect(dir.existsSync()).to.eql(true);

            // rmdir should throw en error for non-empty dirs
            expect(function () {
                dir2.rmdirSync();
            }).to.throw('ENOTEMPTY');

            return dir.rmdir().then(function () {
                expect(dir.existsSync()).to.eql(false);
                return dir.ensure().then(function () {
                    expect(dir.existsSync()).to.eql(true);
                    expect(dir.renewStatsSync().isDirectory()).to.eql(true);
                    return dir2
                        .rmdir()
                        .then(shouldNotPass)
                        .catch((e) => {
                            expect(e.message).to.have.string('ENOTEMPTY');
                        });
                });
            });
        });

        it('.readdir() & .readdirSync() & .read() & .readSync()', function () {
            const dir = new Directory('/tmp/fake_test_dir/non_empty_dir');
            const expected = ['.git', 'file.rb', 'foo'];
            expect(dir.readSync()).to.eql(expected);
            return dir.read().then((ret) => {
                expect(ret).to.eql(expected);
            });
        });

        it('isEmpty() & .isEmptySync()', function () {
            const dir = new Directory('/tmp/fake_test_dir/empty_dir');
            const dir2 = new Directory('/tmp/fake_test_dir/non_empty_dir');
            expect(dir.isEmptySync()).to.eql(true);
            expect(dir2.isEmptySync()).to.eql(false);
            return dir.isEmpty().then((empty) => {
                expect(empty).to.eql(true);
                return dir2.isEmpty().then((empty) => {
                    expect(empty).to.eql(false);
                });
            });
        });

        it('.empty() & .emptySync()', function () {
            const expected = ['.git', 'file.rb', 'foo'];
            const dir = new Directory('/tmp/fake_test_dir/non_empty_dir');
            const dir2 = new Directory('/tmp/fake_test_dir/non_empty_dir2');
            expect(dir.readSync()).to.eql(expected);
            expect(dir.emptySync()).to.eql(dir);
            expect(dir.readSync()).to.eql([]);
            expect(dir2.readSync()).to.eql(['file.md']);
            return dir2.empty().then(function () {
                expect(dir2.readSync()).to.eql([]);
            });
        });

        it('__normalizeAppendNodes', function () {
            const method = Directory.__normalizeAppendNodes;
            const d = Draxt([new File('file.ext'), new Directory('dirname')]);
            expect(method(d)).to.eql(d.items);
            const d2 = ['str', new File('doo')];
            expect(method(d2)).to.eql(d2);
            const d3 = new File('');
            expect(method(d3)).to.eql([d3]);
            expect(method('path')).to.eql(['path']);
            expect(method(d.items)).to.eql(d.items);
            expect(() => method(new Date())).to.throw();
        });

        it('.append() & .appendSync()', function () {
            const col = [
                new File('/tmp/fake_test_dir/non_empty_dir/file.rb'),
                '/tmp/fake_test_dir/non_empty_dir/foo',
            ];
            // the directory will be created!
            const dir = new Directory('/tmp/fake_test_dir/empty_dir');
            expect(dir.appendSync(col)).to.eql(dir);
            // expect node to have it's new path!
            expect(col[0].pathName).to.eql('/tmp/fake_test_dir/empty_dir/file.rb');
            expect(dir.readSync()).to.eql(['file.rb', 'foo']);
            expect(new Directory('/tmp/fake_test_dir/non_empty_dir').readSync()).to.eql(['.git']);
            // col2
            const col2 = Draxt([new File('/tmp/fake_test_dir/example_file.md')]);
            return dir.append(col2).then(function () {
                expect(col2.get(0).pathName).eql('/tmp/fake_test_dir/empty_dir/example_file.md');
                return dir.append('/tmp/fake_test_dir/non_empty_dir2');
            });
        });

        it('.children() & .childrenSync()', function () {
            const dir = new Directory('/tmp/fake_test_dir/non_empty_dir');
            const ret = dir.childrenSync();
            expect(ret).to.be.instanceof(Draxt);
            expect(ret.length).to.eql(2);
            const ret2 = dir.childrenSync('*.rb');
            expect(ret2.length).to.eql(1);
            expect(ret2.get(0)).to.be.instanceof(File);
            expect(ret2.get(0).baseName).to.eql('file.rb');
            const ret3 = dir.childrenSync({dot: true});
            expect(ret3.length).to.eql(3);

            return dir.children().then((set) => {
                expect(set).to.be.instanceof(Draxt);
                expect(set.length).to.eql(2);
                expect(set.get(0).baseName).to.eql('foo');
                return dir.children('f*').then((set2) => {
                    expect(set2.length).to.eql(2);
                });
            });
        });

        it('.find() & .findSync()', function () {
            const dir = new Directory('/tmp/fake_test_dir');
            const ret = dir.findSync('*');
            expect(ret).to.be.instanceof(Draxt);
            expect(ret.length).to.eql(5);
            const ret2 = dir.findSync('**');
            expect(ret2.length).to.eql(9);
            const ret3 = dir.findSync('**', {dot: true});
            expect(ret3.length).to.eql(10);
            return dir.find('*').then((set) => {
                expect(set).to.be.instanceof(Draxt);
                expect(set.length).to.eql(5);
                return dir.find('**', {dot: true}).then((set2) => {
                    expect(set2.length).to.eql(10);
                });
            });
        });
    });
});


================================================
FILE: test/interfaces/File.js
================================================
/* global describe, beforeEach, afterEach, it*/
const {File} = require('../../src/draxt').Node;
const {expect} = require('chai');

describe('File', () => {
    describe('initialization', () => {
        it('new and .isFile() method', () => {
            const file = new File('/fake/fakepath/module.md', {});
            expect(file.isFile()).to.eql(true);
            expect(file.isDirectory()).to.eql(false);
            expect(file.isSymbolicLink()).to.eql(false);
            expect(file.NODE_TYPE).to.eql(2);
            expect(file.nodeName).to.eql('File');
        });
    });

    describe('fs methods', () => {
        beforeEach(() => {
            const {execSync} = require('child_process');
            const pre = `
								rm -r /tmp/fake_dir
								mkdir /tmp/fake_dir
								echo 'example content.' > /tmp/fake_dir/example_file.md
								echo 'example content.' > /tmp/fake_dir/another_example_file.md
						`;
            execSync(pre);
        });

        afterEach(() => {
            // vol.reset();
        });

        it('.read() && .readSync()', () => {
            const file = new File('/tmp/fake_dir/example_file.md', {});
            const content = file.readSync('utf8');
            const expectContent = 'example content.\n';
            expect(content).to.eql(expectContent);
            return file.read('utf8').then((content) => {
                expect(content).to.eql(expectContent);
            });
        });

        it('.append() && .appendSync()', () => {
            const file = new File('/tmp/fake_dir/example_file.md', {});
            const ret = file.appendSync(' appended content');
            expect(ret).to.eql(file);
            expect(file.readSync('utf8')).to.eql('example content.\n appended content');
            return file.append('. string').then(() => {
                return file.read('utf8').then((content) => {
                    expect(content).to.eql('example content.\n appended content. string');
                });
            });
        });

        it('.write() && .writeSync()', () => {
            const file = new File('/tmp/fake_dir/example_file.md', {});
            const ret = file.writeSync('new content');
            expect(ret).to.eql(file);
            expect(file.readSync('utf8')).to.eql('new content');
            return file.write('new async written content', () => {
                return file.read('utf8').then((content) => {
                    return expect(content).to.eql('new async written content');
                });
            });
        });

        it('.truncate() && .truncateSync()', () => {
            const file = new File('/tmp/fake_dir/example_file.md', {});
            const ret = file.truncateSync(4);
            expect(ret).to.eql(file);
            expect(file.readSync('utf8')).to.eql('exam');
            return file.truncate().then(() => {
                return file.read('utf8').then((content) => {
                    return expect(content).to.eql('');
                });
            });
        });

        it('.ensure() && .ensureSync()', () => {
            const file = new File('/tmp/fake_dir/non_existent.md');
            const file2 = new File('/tmp/fake_dir/non_existent2.md');
            expect(file.existsSync()).to.eql(false);
            expect(file.ensureSync()).to.eql(file);
            expect(file.existsSync()).to.eql(true);
            // async example
            expect(file2.existsSync()).to.eql(false);
            return file2.ensure().then(() => {
                expect(file2.existsSync()).to.eql(true);
            });
        });
    });
});


================================================
FILE: test/interfaces/Node.js
================================================
/* global describe, it, beforeEach, afterEach*/
const draxt = require('../../src/draxt'),
    {Node} = draxt,
    {Directory, File} = Node,
    {expect} = require('chai'),
    fs = require('fs-extra'),
    path = require('path'),
    isTravis = 'TRAVIS' in process.env && 'CI' in process.env,
    shouldNotPass = function () {
        throw new Error('should not pass!');
    };

const mkfs = () => {
    const {execSync} = require('child_process');
    const pre = `
					rm -r /tmp/node_test_dir
					mkdir /tmp/node_test_dir
					mkdir /tmp/node_test_dir/another_dir
					mkdir /tmp/node_test_dir/another_dir/.dir
					echo 'example content.' > /tmp/node_test_dir/example_file.md
					echo 'example content.' > /tmp/node_test_dir/another_example_file.md
					echo '...' > /tmp/node_test_dir/another_dir/a.js
					echo '...' > /tmp/node_test_dir/another_dir/b.js
					echo '...' > /tmp/node_test_dir/another_dir/c.php
					echo '...' > /tmp/node_test_dir/another_dir/k.php
					echo '...' > /tmp/node_test_dir/another_dir/d.html
					echo '...' > /tmp/node_test_dir/another_dir/README.md
					echo '...' > /tmp/node_test_dir/another_dir/foo.rb
					echo '...' > /tmp/node_test_dir/another_dir/document.txt
					ln -s /tmp/node_test_dir/example_file.md /tmp/node_test_dir/another_dir/g.md
						`;
    execSync(pre);
};

describe('Node', function () {
    describe('initialization and basic methods', function () {
        const nodePath = '/fake/_fakepath/module.js';
        const stats = {};
        it('`new`', function () {
            const node = new Node(nodePath, stats);
            expect(node.pathName).to.eql(nodePath);
            expect(node.extension).to.eql('js');
            expect(node.name).to.eql('module');
            expect(node.baseName).to.eql('module.js');
            expect(node.parentPath).to.eql('/fake/_fakepath');
            expect(node.rootPath).to.eql('/');
            expect(node.getCachedStats() === stats).to.eql(true);
        });

        it('path.parse methods', function () {
            const node = new Node(nodePath, stats);
            expect(node.getPathName()).to.eql(nodePath);
            expect(node.getExtension()).to.eql('js');
            expect(node.getName()).to.eql('module');
            expect(node.getBaseName()).to.eql('module.js');
            expect(node.getParentPath()).to.eql('/fake/_fakepath');
            expect(node.isDotF
Download .txt
gitextract_u4ieoxxi/

├── .editorconfig
├── .eslintrc.js
├── .gitignore
├── .prettierrc
├── .travis.yml
├── LICENSE
├── README.md
├── _config.yml
├── docs/
│   └── index.html
├── package.json
├── src/
│   ├── draxt.js
│   ├── interfaces/
│   │   ├── Directory.js
│   │   ├── File.js
│   │   ├── Node.js
│   │   ├── SymbolicLink.js
│   │   └── index.js
│   └── util.js
└── test/
    ├── draxt.js
    └── interfaces/
        ├── Directory.js
        ├── File.js
        ├── Node.js
        └── SymbolicLink.js
Download .txt
SYMBOL INDEX (112 symbols across 7 files)

FILE: src/draxt.js
  method get (line 8) | get() {
  function Draxt (line 68) | function Draxt(pattern, options = {}) {

FILE: src/interfaces/Directory.js
  class Directory (line 15) | class Directory extends Node {
    method constructor (line 21) | constructor(pathName, stats) {
    method append (line 39) | append(nodes, options) {
    method appendSync (line 55) | appendSync(nodes, options) {
    method children (line 72) | children() {
    method childrenSync (line 89) | childrenSync() {
    method empty (line 106) | empty() {
    method emptySync (line 115) | emptySync() {
    method ensure (line 125) | ensure() {
    method ensureSync (line 134) | ensureSync() {
    method isEmpty (line 143) | isEmpty() {
    method isEmptySync (line 153) | isEmptySync() {
    method find (line 164) | find(selector, options) {
    method findSync (line 179) | findSync(selector, options) {
    method readdir (line 192) | readdir() {
    method readdirSync (line 201) | readdirSync() {
    method read (line 210) | read() {
    method readSync (line 219) | readSync() {
    method rmdir (line 228) | rmdir() {
    method rmdirSync (line 238) | rmdirSync() {
    method __normalizeAppendNodes (line 243) | static __normalizeAppendNodes(nodes) {

FILE: src/interfaces/File.js
  class File (line 14) | class File extends Node {
    method constructor (line 20) | constructor(pathName, stats) {
    method ensure (line 30) | ensure() {
    method ensureSync (line 39) | ensureSync() {
    method append (line 49) | append() {
    method appendSync (line 57) | appendSync() {
    method read (line 66) | read() {
    method readSync (line 74) | readSync() {
    method truncate (line 82) | truncate() {
    method truncateSync (line 90) | truncateSync() {
    method write (line 99) | write() {
    method writeSync (line 108) | writeSync() {

FILE: src/interfaces/Node.js
  class Node (line 28) | class Node {
    method constructor (line 34) | constructor(pathName, stats) {
    method _setPathParams (line 45) | _setPathParams(nodePathname) {
    method getPathName (line 59) | getPathName() {
    method getBaseName (line 67) | getBaseName() {
    method getExtension (line 75) | getExtension() {
    method getName (line 84) | getName() {
    method getParentPath (line 92) | getParentPath() {
    method getCachedStats (line 102) | getCachedStats() {
    method getStatProp (line 115) | getStatProp(propName) {
    method getAccessTime (line 123) | getAccessTime() {
    method getModifiedTime (line 131) | getModifiedTime() {
    method getBirthTime (line 139) | getBirthTime() {
    method getChangeTime (line 147) | getChangeTime() {
    method getSize (line 156) | getSize() {
    method isDirectory (line 164) | isDirectory() {
    method isFile (line 172) | isFile() {
    method isSymbolicLink (line 180) | isSymbolicLink() {
    method isDotFile (line 188) | isDotFile() {
    method renewStats (line 196) | renewStats() {
    method renewStatsSync (line 208) | renewStatsSync() {
    method getOctalPermissions (line 220) | getOctalPermissions() {
    method getPermissions (line 237) | getPermissions() {
    method access (line 281) | access(mode) {
    method accessSync (line 291) | accessSync(mode) {
    method chmod (line 301) | chmod(mode) {
    method chmodSync (line 311) | chmodSync(mode) {
    method lchmod (line 321) | lchmod(mode) {
    method lchmodSync (line 331) | lchmodSync(mode) {
    method chown (line 342) | chown(uid, gid) {
    method chownSync (line 353) | chownSync(uid, gid) {
    method lchown (line 364) | lchown(uid, gid) {
    method lchownSync (line 375) | lchownSync(uid, gid) {
    method exists (line 385) | exists() {
    method existsSync (line 398) | existsSync() {
    method stat (line 406) | stat() {
    method statSync (line 414) | statSync() {
    method lstat (line 422) | lstat() {
    method lstatSync (line 430) | lstatSync() {
    method link (line 439) | link(newPath) {
    method linkSync (line 449) | linkSync(newPath) {
    method rename (line 461) | rename(newPath) {
    method renameSync (line 473) | renameSync(newPath) {
    method utimes (line 485) | utimes() {
    method utimesSync (line 496) | utimesSync() {
    method copy (line 517) | copy() {
    method copySync (line 528) | copySync() {
    method moveTo (line 552) | moveTo(targetDir, options) {
    method moveToSync (line 575) | moveToSync(targetDir, options) {
    method appendTo (line 585) | appendTo() {
    method appendToSync (line 594) | appendToSync() {
    method siblings (line 605) | siblings() {
    method siblingsSync (line 624) | siblingsSync() {
    method remove (line 640) | remove() {
    method removeSync (line 649) | removeSync() {
    method parent (line 665) | parent() {
    method parentSync (line 676) | parentSync() {
    method rawQuery (line 688) | static rawQuery(pattern, options) {
    method rawQuerySync (line 699) | static rawQuerySync(pattern, options) {
    method toNodes (line 722) | static toNodes(pathNames) {
    method toNodesSync (line 738) | static toNodesSync(pathNames) {
    method __statsToNode (line 751) | static __statsToNode(pathName, stats) {
    method query (line 770) | static query() {
    method querySync (line 781) | static querySync() {
    method __normalizeGlobOptions (line 792) | static __normalizeGlobOptions(options = {}) {
    method __normalizeRelativeGlobOptions (line 817) | __normalizeRelativeGlobOptions(pattern, options = {}) {
    method __resolvePath (line 866) | __resolvePath(dir) {

FILE: src/interfaces/SymbolicLink.js
  class SymbolicLink (line 13) | class SymbolicLink extends Node {
    method constructor (line 19) | constructor(nodePath, stats) {
    method isBroken (line 28) | isBroken() {
    method isBrokenSync (line 38) | isBrokenSync() {
    method readlink (line 48) | readlink(options) {
    method readlinkSync (line 58) | readlinkSync(options) {

FILE: src/util.js
  method getType (line 10) | getType(value) {

FILE: test/interfaces/Node.js
  method isFile (line 289) | isFile() {
  method isSymbolicLink (line 292) | isSymbolicLink() {
  method isDirectory (line 295) | isDirectory() {
Condensed preview — 22 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (226K chars).
[
  {
    "path": ".editorconfig",
    "chars": 168,
    "preview": "root = true\n\n[*]\nindent_style = tab\nindent_size = 2\ncharset = utf-8\ntrim_trailing_whitespace = true\ninsert_final_newline"
  },
  {
    "path": ".eslintrc.js",
    "chars": 335,
    "preview": "module.exports = {\n    env: {\n        commonjs: true,\n        es6: true,\n        node: true,\n    },\n    globals: {\n     "
  },
  {
    "path": ".gitignore",
    "chars": 925,
    "preview": "# Logs\nlogs\n*.log\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\n\n# Runtime data\npids\n*.pid\n*.seed\n*.pid.lock\n\n# Directo"
  },
  {
    "path": ".prettierrc",
    "chars": 116,
    "preview": "{\n    \"trailingComma\": \"es5\",\n    \"printWidth\": 100,\n    \"tabWidth\": 4,\n    \"semi\": true,\n    \"singleQuote\": true\n}\n"
  },
  {
    "path": ".travis.yml",
    "chars": 160,
    "preview": "language: node_js\n\nnode_js:\n  - '6'\n  - '8'\n\nbefore_install:\n  - if [[ `npm -v` == 2.* ]]; then npm install --global npm"
  },
  {
    "path": "LICENSE",
    "chars": 1067,
    "preview": "MIT License\n\nCopyright (c) 2018 Ram Hejazi\n\nPermission is hereby granted, free of charge, to any person obtaining a copy"
  },
  {
    "path": "README.md",
    "chars": 5785,
    "preview": "<div align=\"center\" style=\"text-align:center\">\n<a link=\"https://github.com/ramhejazi/draxt\"><img width=\"300px\" style=\"pa"
  },
  {
    "path": "_config.yml",
    "chars": 27,
    "preview": "theme: jekyll-theme-minimal"
  },
  {
    "path": "docs/index.html",
    "chars": 114694,
    "preview": "<!doctype html><html class=no-js lang=en><head><meta charset=utf-8><meta http-equiv=x-ua-compatible content=\"ie=edge\"><t"
  },
  {
    "path": "package.json",
    "chars": 1134,
    "preview": "{\n    \"name\": \"draxt\",\n    \"version\": \"1.3.0\",\n    \"description\": \"jQuery/NodeList-like module for file system (nodejs)\""
  },
  {
    "path": "src/draxt.js",
    "chars": 12046,
    "preview": "/*eslint no-irregular-whitespace: [\"error\", { \"skipComments\": true }]*/\n\nconst {Node} = require('./interfaces');\nconst a"
  },
  {
    "path": "src/interfaces/Directory.js",
    "chars": 7761,
    "preview": "const Node = require('./Node'),\n    {getType} = require('../util');\n\nconst nodeProps = {\n    nodeName: {value: 'Director"
  },
  {
    "path": "src/interfaces/File.js",
    "chars": 2867,
    "preview": "const Node = require('./Node');\n\nconst nodeProps = {\n    nodeName: {value: 'File', writable: false, configurable: false,"
  },
  {
    "path": "src/interfaces/Node.js",
    "chars": 26227,
    "preview": "const path = require('path'),\n    {glob, globSync} = require('glob'),\n    fs = require('fs-extra'),\n    minimatch = requ"
  },
  {
    "path": "src/interfaces/SymbolicLink.js",
    "chars": 1965,
    "preview": "const Node = require('./Node'),\n    nodeProps = {\n        nodeName: {value: 'SymbolicLink', writable: false, configurabl"
  },
  {
    "path": "src/interfaces/index.js",
    "chars": 164,
    "preview": "module.exports = {\n    Node: require('./Node'),\n    File: require('./File'),\n    Directory: require('./Directory'),\n    "
  },
  {
    "path": "src/util.js",
    "chars": 267,
    "preview": "/**\n * A simple utility object\n */\nmodule.exports = {\n\t/**\n\t * Get type of a variable\n\t * @param {any} value\n\t * @return"
  },
  {
    "path": "test/draxt.js",
    "chars": 7463,
    "preview": "/* global describe, it, beforeEach, afterEach*/\nconst draxt = require('../src/draxt'),\n    {expect} = require('chai'),\n "
  },
  {
    "path": "test/interfaces/Directory.js",
    "chars": 8237,
    "preview": "/* global describe, beforeEach, it*/\nconst Draxt = require('../../src/draxt');\nconst {expect} = require('chai');\nconst {"
  },
  {
    "path": "test/interfaces/File.js",
    "chars": 3606,
    "preview": "/* global describe, beforeEach, afterEach, it*/\nconst {File} = require('../../src/draxt').Node;\nconst {expect} = require"
  },
  {
    "path": "test/interfaces/Node.js",
    "chars": 22917,
    "preview": "/* global describe, it, beforeEach, afterEach*/\nconst draxt = require('../../src/draxt'),\n    {Node} = draxt,\n    {Direc"
  },
  {
    "path": "test/interfaces/SymbolicLink.js",
    "chars": 2521,
    "preview": "/* global describe, beforeEach, it*/\nconst {SymbolicLink} = require('../../src/draxt').Node;\nconst {expect} = require('c"
  }
]

About this extraction

This page contains the full source code of the ramhejazi/draxt GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 22 files (215.3 KB), approximately 63.9k tokens, and a symbol index with 112 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!