npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

wranch

v1.3.0

Published

A series of file system utilities for building hapi apps

Downloads

540

Readme

Hapi filesystem utilities

Filesystem tools for building hapi apps.

tests coverage

npm i -s wranch

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 requireing 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
]);