Site | NPM Module | GitHub Repo
Node Powertools is an NPM module for backend and frontend developers that exposes powerful utilities and tools.
Yes, this module works in both Node and browser environments, including compatibility with Webpack and Browserify!
- Useful randomization tools to mix things up
- Helpful polling utilities to wait for variables or events
- Powerful regexify and escape functions to go work with
RegExp
Install with npm if you plan to use Node Powertools in a Node.js project or in the browser.
npm install node-powertoolsIf you plan to use node-powertools in a browser environment, you will probably need to use Webpack, Browserify, or a similar service to compile it.
const powertools = require('node-powertools');Install with CDN if you plan to use Node Powertools only in a browser environment.
<script src="https://cdn.jsdelivr.net/npm/node-powertools@latest/dist/index.min.js"></script>
<script type="text/javascript">
var powertools = Powertools(); // The script above exposes the global variable 'Powertools'
</script>Generate a random number between min and max. If an array is supplied as the first argument, a random element from the array is returned.
Options:
mode:'uniform'(default) or'gaussian'- Distribution mode for random generationskew:0.5(default) - Only applies to gaussian mode. Controls where the peak of the bell curve is positioned (0 = min, 0.5 = middle, 1 = max)
// Uniform distribution (equal probability)
powertools.random(0, 100); // Possible output: 69
powertools.random(0, 100, {mode: 'uniform'}); // Possible output: 42
// Gaussian distribution (bell curve, centered by default)
powertools.random(0, 100, {mode: 'gaussian'}); // Possible output: 52 (more likely near 50)
powertools.random(0, 100, {mode: 'gaussian', skew: 0.8}); // Possible output: 73 (peak shifted toward 80)
// Random element from array
powertools.random(['Apple', 'Orange', 'Pear']); // Possible output: Orange
powertools.random(['Apple', 'Orange', 'Pear'], {mode: 'gaussian', skew: 0}); // Possible output: Apple (more likely)Returns true or false based on the given probability (0 to 1). Uses high-precision random number generation.
Options:
mode:'uniform'(default) or'gaussian'- Distribution mode (passed topowertools.random())skew:0.5(default) - Only applies to gaussian mode
powertools.chance(0.5); // 50% chance of true
powertools.chance(0.9); // 90% chance of true
powertools.chance(0); // Always false
powertools.chance(1); // Always true
powertools.chance(0.5, {mode: 'gaussian'}); // 50% chance with gaussian distributionTransform the input into an array if it is not already.
powertools.arrayify(1); // Output: [1]
powertools.arrayify([1]); // Output: [1]Asynchronously wait for a specified time in milliseconds. If max is provided, waits for a random duration between min and max.
Options:
mode:'uniform'(default) or'gaussian'- Distribution mode for random wait timeskew:0.5(default) - Only applies to gaussian mode
await powertools.wait(1000); // Wait exactly 1000 ms (1 second)
await powertools.wait(1000, 3000); // Wait random time between 1-3 seconds (uniform)
await powertools.wait(1000, 3000, {mode: 'gaussian'}); // Wait random time, more likely near 2 seconds
await powertools.wait(1000, 3000, {mode: 'gaussian', skew: 0.8}); // Wait random time, peak near 2600 msAsynchronously poll a function fn until it returns true. Supports both synchronous and asynchronous functions. The promise rejects if the timeout is reached.
Options:
interval:100(default) - Polling interval in millisecondstimeout:2000(default) - Maximum time to wait in milliseconds. Set to0or negative value for infinite polling
// Poll until condition is met (with timeout)
await powertools.poll(function (index) {
return something === somethingElse;
}, {interval: 100, timeout: 30000});
// Poll with async function
await powertools.poll(async function (index) {
const result = await checkSomething();
return result.isReady;
}, {interval: 500, timeout: 10000});
// Poll indefinitely (no timeout)
await powertools.poll(() => isReady, {interval: 100, timeout: 0});Creates and returns a Queue instance that processes asynchronous functions in FIFO (first in, first out) order. Each function waits for the previous one to resolve or reject before executing.
Options:
delay:0(default) - Delay in milliseconds between each function execution
Queue Methods:
queue.add(fn)- Add an async function to the queue and returns a promise that resolves/rejects when the function completes
// Create queue with delay between functions
const queue = powertools.queue({delay: 100});
// Queue the first function
queue.add(async () => {
console.log('Queue 1 started');
await powertools.wait(1000);
console.log('Queue 1 finished');
return 'result1';
});
// Queue the second function
// This will only begin executing after the first function completes
queue.add(async () => {
console.log('Queue 2 started');
await powertools.wait(1000);
console.log('Queue 2 finished');
})
.then(() => console.log('All queued tasks completed'));Synchronously checks and returns the state of a promise: 'pending', 'resolved', or 'rejected'.
Note: This is a Node.js-only function (requires util module). Does not work in browsers.
const promise = new Promise((resolve, reject) => {
setTimeout(() => resolve('done'), 1000);
});
powertools.getPromiseState(promise); // Output: 'pending'
await promise;
powertools.getPromiseState(promise); // Output: 'resolved'Polls an array of promises and waits until the number of pending promises drops below options.max. Useful for limiting concurrent promise execution. The promise rejects if options.timeout is reached.
Options:
max:10(default) - Maximum number of pending promises allowed before continuingtimeout:60000(default) - Maximum time to wait in milliseconds (60 seconds)
Note: This is a Node.js-only function (requires util module). Does not work in browsers.
const promises = [
powertools.wait(1000),
powertools.wait(2000),
powertools.wait(3000),
];
console.log('Starting processing', promises);
// Wait until no more than 2 promises are pending
await powertools.waitForPendingPromises(promises, {max: 2, timeout: 5000});
console.log('Finished processing', promises);Add the escape character \ before any character in str that needs to be escaped for a RegExp.
powertools.escape('*'); // Output: \*
powertools.escape('/'); // Output: \/
powertools.escape('\\'); // Output: \\
powertools.escape('.$^'); // Output: \.\$\^Revive a str into a RegExp. Supports flags. Depending on how you want special characters to be treated, you can use powertools.escape(str) prior to using powertools.regexify(str).
powertools.regexify('/Apple/'); // Output: RegExp /Apple/
powertools.regexify('/Apple/i'); // Output: RegExp /Apple/i
powertools.regexify('Apple'); // Output: Throws error (needs to start and end with /)
powertools.regexify('/Apple/x'); // Output: Throws error (x is not a valid flag)
powertools.regexify('/Ap.le/'); // Output: RegExp /Ap.le/
powertools.regexify(`/${powertools.escape('Ap.le')}/`); // Output: RegExp /Ap\.le/Converts a date into an ISO string, UNIX timestamp, or JavaScript Date object. The date parameter accepts a JS Date, UNIX timestamp number, or date string.
Options:
output:'string'(default),'unix', or'date'- Output format
// Convert Date object
powertools.timestamp(new Date('2999/12/31'), {output: 'string'}); // Output: "2999-12-31T08:00:00.000Z"
powertools.timestamp(new Date('2999/12/31'), {output: 'unix'}); // Output: 32503622400
powertools.timestamp(new Date('2999/12/31'), {output: 'date'}); // Output: Date object
// Convert UNIX timestamp
powertools.timestamp(32503622400, {output: 'string'}); // Output: "2999-12-31T08:00:00.000Z"
powertools.timestamp(32503622400, {output: 'unix'}); // Output: 32503622400
// Convert string
powertools.timestamp('2999/12/31'); // Output: "2999-12-31T08:00:00.000Z"
// Default behavior (no date provided)
powertools.timestamp(); // Output: Current timestamp as ISO stringIntelligently converts a value to a type how JavaScript should. Supported types: string, number, boolean, array, undefined.
Array Options:
trim:true(default) - Trim whitespace from string elementsforce:'string','number', or'boolean'- Force each element to a specific type
// Boolean conversion
powertools.force('true', 'boolean'); // Output: true
powertools.force('false', 'boolean'); // Output: false
powertools.force('0', 'boolean'); // Output: false
// Array conversion
powertools.force('1,2,3', 'array'); // Output: ['1', '2', '3']
powertools.force('1,2,3', 'array', {force: 'number'}); // Output: [1, 2, 3]
powertools.force(' a , b , c ', 'array', {trim: true}); // Output: ['a', 'b', 'c']
// String conversion
powertools.force(undefined, 'string'); // Output: ''
powertools.force(123, 'string'); // Output: '123'
// Number conversion
powertools.force('42', 'number'); // Output: 42
powertools.force(undefined, 'number'); // Output: 0Validates and structures a settings object against a defaults schema. Automatically fills in missing keys, enforces types, applies min/max constraints, and removes extra keys not defined in the schema.
Schema Properties:
types: Array of valid types ('string','number','boolean','array','function','any')default: Value to use if the key is missing (can be a function)value: Force this value regardless of user input (can be a function)min: Minimum value (for numbers) or minimum length (for strings/arrays)max: Maximum value (for numbers) or maximum length (for strings/arrays)
const schema = {
name: {
types: ['string'],
default: '',
max: 10,
},
stats: {
level: {
types: ['number'],
default: 1,
min: 1,
max: 2,
},
index: {
value: 1, // Always 1, regardless of input
},
},
};
// Missing keys filled with defaults
powertools.defaults({}, schema);
// Output: {name: '', stats: {level: 1, index: 1}}
// String truncated to max length
powertools.defaults({name: 'What a long name!'}, schema);
// Output: {name: 'What a lon', stats: {level: 1, index: 1}}
// Number clamped to max value
powertools.defaults({stats: {level: 3}}, schema);
// Output: {name: '', stats: {level: 2, index: 1}}Recursively walks through an object and returns an array of all keys, including nested keys using dot notation.
powertools.getKeys({name: 'Jon Snow'}); // Output: ['name']
powertools.getKeys({name: 'Jon Snow', favorites: {color: 'red'}}); // Output: ['name', 'favorites.color']
powertools.getKeys({user: {profile: {age: 25}}}); // Output: ['user.profile.age']
powertools.getKeys({}); // Output: []Checks if obj is a plain object. Returns false for null, arrays, and other non-object types (unlike JavaScript's native typeof).
powertools.isObject({}); // Output: true
powertools.isObject({name: 'Jon'}); // Output: true
powertools.isObject(null); // Output: false
powertools.isObject([]); // Output: false
powertools.isObject('string'); // Output: falseSafely stringify an object to JSON, even if it contains circular references. Circular references are replaced with placeholder strings.
powertools.stringify({}); // Output: '{}'
powertools.stringify({name: 'Jon'}, null, 2); // Output: Pretty-printed JSON
// Handles circular references
const obj = {name: 'Jon'};
obj.self = obj;
powertools.stringify(obj); // Output: '{"name":"Jon","self":"[Circular ~]"}'Replace all instances of {key} in str with the corresponding value in data. Supports nested keys using dot notation.
Options:
escape:truein browser,falsein Node (default) - Escape HTML characters in valuesbrackets:['{', '}'](default) - Custom opening and closing bracket characters
// Basic templating
powertools.template(
'My favorite color is {color}',
{color: 'purple'}
); // Output: 'My favorite color is purple'
// Nested keys
powertools.template(
'Ian\'s favorite color is {ian.color}',
{ian: {color: 'purple'}}
); // Output: 'Ian\'s favorite color is purple'
// HTML escaping
powertools.template(
'My favorite color is {color}',
{color: '<b>purple</b>'},
{escape: true}
); // Output: 'My favorite color is <b>purple</b>'
// Custom brackets
powertools.template(
'My favorite color is %color%',
{color: 'purple'},
{brackets: ['%', '%']}
); // Output: 'My favorite color is purple'Removes duplicate elements from an array. Works with primitives and objects (uses JSON comparison for objects).
powertools.uniquify([1, 2, 2, 3]); // Output: [1, 2, 3]
powertools.uniquify(['a', 'b', 'a']); // Output: ['a', 'b']
powertools.uniquify([{id: 1}, {id: 1}, {id: 2}]); // Output: [{id: 1}, {id: 2}]Sequentially processes each element in an array with an async callback. Each callback waits for the previous one to complete before executing (unlike Promise.all).
Callback signature: callback(item, index, array) - Must return a Promise
const sampleArray = [1, 2, 3, 4, 5];
// Simulate an async operation like a database call
const asyncTask = (item, index, array) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log(`Processing item ${item} at index ${index}`);
resolve();
}, 1000);
});
};
// Process each item sequentially (one at a time)
powertools.iterate(sampleArray, asyncTask)
.then(() => console.log('All tasks completed.'));Asynchronously execute a command in the terminal using child_process.spawn(). This is a Node.js-only function.
Options:
log:false(default) - Stream output toprocess.stdoutandprocess.stderrin real-timedebug:false(default) - Log debug information about command executionconfig:{}(default) - Options passed tochild_process.spawn():stdio:'inherit'iflog: true, otherwise'pipe'(default)shell:true(default) - Use shell to handle command chaining (&&,||, etc.)cwd: Current working directory for the command- Other spawn options supported
setupCallback: Optional callback that receives the child process instance
// Run a simple command
await powertools.execute('ls -a')
.then((output) => console.log('Files:', output));
// Run with custom working directory
await powertools.execute('ls -a', {
config: {cwd: '/path/to/directory'},
});
// Stream output in real-time
await powertools.execute('npm install', {
log: true,
});
// Access child process for advanced usage
await powertools.execute('long-running-command', {}, (child) => {
// Can attach additional listeners or kill process
child.on('exit', (code) => console.log('Exited with code', code));
});Return a new object with only the specified keys from obj. Supports nested keys using dot notation.
powertools.whitelist({name: 'Jon Snow', age: 25}, ['name']); // Output: {name: 'Jon Snow'}
powertools.whitelist(
{name: 'Jon Snow', stats: {level: 5, hp: 100}},
['name', 'stats.level']
); // Output: {name: 'Jon Snow', stats: {level: 5}}Convert a str to hyphenated case (kebab-case).
Options:
removeNonAlphanumeric:true(default) - Remove non-alphanumeric characterslowercase:true(default) - Convert to lowercase
powertools.hyphenate('Jon Snow'); // Output: 'jon-snow'
powertools.hyphenate('Jon Snow', {lowercase: false}); // Output: 'Jon-Snow'
powertools.hyphenate('Jon Snow!', {removeNonAlphanumeric: true}); // Output: 'jon-snow'
powertools.hyphenate('Jon Snow!', {removeNonAlphanumeric: false}); // Output: 'jon-snow!'Parse a proxy string into an object with protocol, host, port, username, password, and valid properties. Supports HTTP, HTTPS, SOCKS4, and SOCKS5 protocols. The returned object includes toString() and toJSON() methods.
toString() Options:
auth:true(default) - Include authentication in the output string
// Parse proxy with authentication
const proxy = powertools.parseProxy('http://username:password@1.2.3.4:8080');
// Output: {protocol: 'http', host: '1.2.3.4', port: '8080', username: 'username', password: 'password', valid: true}
// Parse proxy without authentication
const proxy2 = powertools.parseProxy('1.2.3.4:8080');
// Output: {protocol: 'http', host: '1.2.3.4', port: '8080', username: null, password: null, valid: true}
// Stringify with auth
console.log(proxy.toString()); // Output: 'http://username:password@1.2.3.4:8080'
// Stringify without auth
console.log(proxy.toString({auth: false})); // Output: 'http://1.2.3.4:8080'
// SOCKS5 proxy
const socks = powertools.parseProxy('socks5://user:pass@proxy.example.com:1080');
console.log(socks.toString()); // Output: 'socks5://user:pass@proxy.example.com:1080'If you are still having difficulty, we would love for you to post a question to the Node Powertools issues page. It is much easier to answer questions that include your code and relevant files! So if you can provide them, we'd be extremely grateful (and more likely to help you find the answer!)
Somiibo: A Social Media Bot with an open-source module library.
JekyllUp: A website devoted to sharing the best Jekyll themes.
Slapform: A backend processor for your HTML forms on static sites.
Proxifly: A backend processor for your HTML forms on static sites.
SoundGrail Music App: A resource for producers, musicians, and DJs.
Hammock Report: An API for exploring and listing backyard products.
Ask us to have your project listed! :)