README
Hapi filesystem utilities
Filesystem tools for building hapi
apps.
npm i -s wranch
- bindFunctions
- deleteRecursive
- dirContents
- listModules
- mapArray
- mapFiles
- nameMethods
- recurseFiles
- requireFiles
- testMirror
- testMirrorPath
- tryRequirePlugins
Examples
All examples are based on the following trees:
./lib
lib
├── bindFunctions.js
├── deleteRecursive.js
├── dirContents.js
├── listModules.js
├── mapArray.js
├── mapFiles.js
├── nameMethods.js
├── noop.js
├── recurseFiles.js
├── requireFiles.js
├── testMirror.js
├── testMirrorPath.js
└── tryRequirePlugins.js
./test/fixture
test/fixture
├── extensions
│ ├── js.js
│ └── json.json
├── flat
│ └── index.js
├── fldr
│ ├── fldrer
│ │ └── fldrerest
│ │ └── goal.html
│ └── index.js
├── ignore.php
├── ignore.py
├── ignore.rb
├── index.js
├── methods
│ ├── dontwork.js
│ ├── index.js
│ ├── notFunction.js
│ └── work.js
├── noindex
│ └── test.js
├── tast.js
├── test.js
└── tist.js
API
bindFunctions(obj, bindTo)
Iterates through an object and binds functions. Returns a new object.
Parameters
obj: object
, Object to iterate over
bindTo: object
, Object to bind to
Returns: object
, A new object with bound functions
Example:
const obj1 = {
fn1: function () { console.log(this.a) }
fn2: function () { console.log(this.b) }
}
const bindTo = {
a: true,
b: false
}
bindFunctions(obj1, bindTo);
deleteRecursive(dirname)
Deletes files recursively
Parameters
dirname: string
, Path to start deleting from
Example:
// Make a temporary folder
const tmpfolder = __dirname + '/tmp';
try {
Fs.mkdirSync(tmpfolder + '');
}
catch (e) {}
// Make folders and files inside of tmpfolder
['test', 'tast', 'tist'].forEach((name) => {
hierarchy = [hierarchy, name].join('/');
try {
Fs.mkdirSync(tmpfolder + hierarchy);
}
catch (e) {}
try {
const file = Fs.openSync(tmpfolder + hierarchy + '.txt', 'w');
Fs.closeSync(file);
}
catch (e) {}
});
// Delete the entire folder recursively
DeleteRecursive(tmpfolder);
dirContents(dirname, options)
Reads contents from all files in dirname
and maps as key: value pairs
Parameters
dirname: string
, Path to require plugin from
options: object
, Options to pass
Returns: object
, An object of { [filename]: fileContents }
Example:
const contents = dirContents('./test/fixture');
// {
// 'extensions/js': 'module.exports = \'js\';\n',
// 'extensions/json': '["json"]',
// 'flat/index':
// 'module.exports = [{ name: \'flat\' }, 1, 2, 3, \'a\', \'b\', \'c\'];\n',
// 'fldr/fldrer/fldrerest/goal': '<h1>success!</h1>',
// 'fldr/index': 'module.exports = { name: \'fldr\' };\n',
// ignore: '',
// index: '',
// 'methods/dontwork': 'module.exports = () => \'not work!\';\n\n',
// 'methods/index': 'module.exports = false;\n',
// 'methods/notFunction': 'module.exports = \'not a function\';',
// 'methods/work': 'module.exports = () => \'works!\';\n\n',
// 'noindex/test': 'module.exports = true;\n',
// tast: 'module.exports = { name: \'tast\' };\n',
// test: 'module.exports = { name: \'test\' };\n',
// tist: 'module.exports = { name: \'tist\' };\n'
// }
// And so you can do things like this:
Object.entries(contents).forEach(([name, content]) => {
Handlebars.registerPartial(name, content);
});
// You can also pass the following options:
const contents = dirContents('./test/fixture', {
// Delimiter to separate folder hierarchy
delimiter: '-',
// Name of folder being recursively read
parentName: 'test',
// Parent content object to attach objects recursively
parentContent: {}
});
listModules(dirname)
Lists all files in a path except index.js
Parameters
dirname: string
, Path to list files
Returns: array
, An array of paths except index.js
Example:
listModules('./test/fixtures')
// [
// 'extensions',
// 'flat',
// 'fldr',
// 'ignore.php',
// 'ignore.py',
// 'ignore.rb',
// 'methods',
// 'noindex',
// 'tast.js',
// 'test.js',
// 'tist.js'
// ]
mapArray(dirname)
Requires all modules in dirname
and flattens them
Parameters
dirname: string
, Path to require plugin from
Returns: array
, An array of required modules
Example:
mapArray('./lib');
// [
// [Function: bindFunctions],
// [Function],
// [Function: dirContents],
// [Function],
// [Function],
// [Function],
// [Function],
// [Function],
// [Function: crawl],
// [Function],
// [Function],
// [Function],
// [Function]
// ]
mapFiles(dirname)
Uses listModules
and requires all js modules in give dir
and place them into a JS map
Parameters
dirname: string
, Path to require plugin from
Returns: map
, a js map of files using their name minus extension as the key, and the module export as the value
Example:
mapFiles('./lib')
// Map {
// 'bindFunctions' => [Function: bindFunctions],
// 'deleteRecursive' => [Function],
// 'dirContents' => [Function: dirContents],
// 'listModules' => [Function],
// 'mapArray' => [Function],
// 'mapFiles' => [Function],
// 'nameMethods' => [Function],
// 'noop' => [Function],
// 'recurseFiles' => [Function: crawl],
// 'requireFiles' => [Function],
// 'testMirror' => [Function],
// 'testMirrorPath' => [Function],
// 'tryRequirePlugins' => [Function]
// }
nameMethods(dirname)
Uses mapFiles
to imports file and converts them to an array of objects with key as name
and export as method
. Will only convert where export is a function.
Parameters
dirname: string
, Directory to get items from
Returns: array
, An array of [{ name, method }]
Example:
const methods = nameMethod('./lib');
// [
// { name: 'bindFunctions', method: [Function: bindFunctions] },
// { name: 'deleteRecursive', method: [Function] },
// { name: 'dirContents', method: [Function: dirContents] },
// { name: 'listModules', method: [Function] },
// { name: 'mapArray', method: [Function] },
// { name: 'mapFiles', method: [Function] },
// { name: 'nameMethods', method: [Function] },
// { name: 'noop', method: [Function] },
// { name: 'recurseFiles', method: [Function: crawl] },
// { name: 'requireFiles', method: [Function] },
// { name: 'testMirror', method: [Function] },
// { name: 'testMirrorPath', method: [Function] },
// { name: 'tryRequirePlugins', method: [Function] }
// ]
server.methods(methods);
recurseFiles(path, fileFn, dirFn)
Performs file operations recursively
Parameters
path: string
, required - Path to start crawling
fileFn: function
, required - Function to execute on a file
dirFn: function
, optional - Callback passes original path variable
Example:
// Example 1
watchFile = (file) => fs.watch(file, () => {
socket.send('filechange', file);
});
recurseFile('./lib', watchFile);
// Example 2 (deleteRecursively)
const rm = (file) => Fs.unlinkSync(file);
const rmRf = (dir) => Fs.rmdirSync(dir);
const deleteRecursively = (path) => RecurseFiles(path, rm, rmRf);
requireFiles(dirname)
Requires all js modules in dirname
and maps as Hapi methods array
Parameters
dirname: string
, Path to require plugin from
Returns: object
, An object with in the format of { key: module }
Example:
const { listModules } = requireFiles('./lib');
testMirror(pathname, replace)
Requires a module from root folder mirrored in /test. Allows for renaming and moving of module / test files without breaking test as long as hierarchy stays the same.
Parameters
pathname: string
, Path to require plugin from
replace: string
, Path to replace, in case your path is not '/test'. Optional
Returns: module
, The mirrored module
Example:
// test/lib/utils/myModule.js will require lib/utils/myModule.js
const ModuleToTest = testMirror(__filename);
// test/server/lib/utils/myModule.js will require lib/utils/myModule.js
const ModuleToTest = testMirror(__filename, 'test/server');
testMirrorPath(pathname, replace)
Creates an absolute path from given pathname
that replaces /test
by default.
Parameters
pathname: string
, Path to require plugin from
replace: string
, Path to replace, in case your path is not '/test'. Optional
Returns: string
, An absolute path to your mirrored module
Example:
// test/lib/utils/myModule.js
const ModuleToTest = testMirrorPath(__filename);
// /home/me/myproject/lib/utils/myModule.js
// test/server/lib/utils/myModule.js
const ModuleToTest = testMirrorPath(__filename, 'test/server');
// /home/me/myproject/lib/utils/myModule.js
tryRequirePlugins(plugins)
Attempts to require a Hapi plugin
Parameters
plugins: array
, Array of Hapi plugin objects without require
ing the module
Returns: array
, An array of Hapi plugins with module required
Returns: , An array of hapi plugins
Example:
const plugins = TryRequirePlugins([
{ plugin: '@hapi/code', options: {} }, // exists
{ plugin: 'blipp', options: {} }, // does not exist
{ plugin: 'confidence', options: {} } // exists
]);