Bare bones Promises/A+ implementation with essential extensions for readable, performant asynchronous operation handling.
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Utilities for bridging callback-based APIs with promises in Node.js environments, enabling seamless integration between traditional Node.js patterns and promise-based code.
Converts Node.js-style callback functions to promise-returning functions.
/**
* Converts callback-based function to promise-based function
* @param {function} fn - Function expecting callback as last parameter
* @param {number} [argumentCount] - Fixed number of arguments (optimization)
* @returns {function} Function returning promise instead of using callback
*/
Promise.denodeify(fn, argumentCount);Usage Examples:
const Promise = require('promise');
const fs = require('fs');
// Convert fs.readFile to promise-based
const readFile = Promise.denodeify(fs.readFile);
readFile('package.json', 'utf8')
.then(contents => {
console.log('File contents:', contents);
})
.catch(error => {
console.error('Failed to read file:', error);
});
// With argument count optimization
const readFileOptimized = Promise.denodeify(fs.readFile, 2);
// Convert multiple functions
const stat = Promise.denodeify(fs.stat);
const writeFile = Promise.denodeify(fs.writeFile);
// Chain converted functions
readFile('input.txt', 'utf8')
.then(data => data.toUpperCase())
.then(transformed => writeFile('output.txt', transformed))
.then(() => console.log('File processed successfully'));Wraps a promise-returning function to optionally accept Node.js-style callbacks.
/**
* Wraps promise function to support optional callback parameter
* @param {function} fn - Function that returns a promise
* @returns {function} Function that accepts optional callback as last parameter
*/
Promise.nodeify(fn);Usage Examples:
const Promise = require('promise');
// Promise-based function
function fetchUserData(userId) {
return Promise.resolve({ id: userId, name: 'John Doe' });
}
// Wrap to support both promises and callbacks
const fetchUser = Promise.nodeify(fetchUserData);
// Use as promise
fetchUser(123)
.then(user => console.log('Promise:', user))
.catch(error => console.error('Promise error:', error));
// Use with callback
fetchUser(123, (error, user) => {
if (error) {
console.error('Callback error:', error);
} else {
console.log('Callback:', user);
}
});
// Hybrid API example
function createAPI() {
const getUserData = Promise.nodeify((id) => {
return fetch(`/api/users/${id}`).then(r => r.json());
});
return { getUserData };
}Calls a Node.js-style callback with the promise result.
/**
* Calls Node.js callback with promise result
* @param {function} [callback] - Callback function (error, result)
* @param {*} [ctx] - Context (this) for callback invocation
* @returns {Promise|void} Returns this promise if no callback, void otherwise
*/
Promise.prototype.nodeify(callback, ctx);Usage Examples:
const Promise = require('promise');
// Convert promise to callback style
function getData(callback) {
return fetchDataPromise()
.nodeify(callback);
}
// Usage with callback
getData((error, result) => {
if (error) {
console.error('Error:', error);
} else {
console.log('Result:', result);
}
});
// Usage without callback (returns promise)
getData()
.then(result => console.log('Promise result:', result))
.catch(error => console.error('Promise error:', error));
// With context
const api = {
name: 'MyAPI',
handleResult(error, data) {
console.log(`${this.name}:`, error || data);
}
};
fetchDataPromise().nodeify(api.handleResult, api);const Promise = require('promise');
const fs = require('fs');
// Convert all fs functions to promise-based
const fsPromises = {
readFile: Promise.denodeify(fs.readFile),
writeFile: Promise.denodeify(fs.writeFile),
stat: Promise.denodeify(fs.stat),
readdir: Promise.denodeify(fs.readdir)
};
// Use promise-based file operations
async function processFiles() {
const files = await fsPromises.readdir('./data');
for (const file of files) {
const stats = await fsPromises.stat(`./data/${file}`);
if (stats.isFile()) {
const content = await fsPromises.readFile(`./data/${file}`, 'utf8');
// Process content...
}
}
}const Promise = require('promise');
function createDualAPI(promiseFunction) {
return Promise.nodeify(promiseFunction);
}
// Create API that supports both patterns
const api = {
fetchUser: createDualAPI((id) => {
return fetch(`/users/${id}`).then(r => r.json());
}),
createUser: createDualAPI((userData) => {
return fetch('/users', {
method: 'POST',
body: JSON.stringify(userData)
}).then(r => r.json());
})
};
// Use as promises
await api.fetchUser(123);
// Use with callbacks
api.fetchUser(123, (err, user) => {
// Handle result
});const Promise = require('promise');
// denodeify automatically handles callback errors
const readFile = Promise.denodeify(fs.readFile);
readFile('nonexistent.txt')
.catch(error => {
console.log(error.code); // 'ENOENT'
console.log(error.path); // 'nonexistent.txt'
});
// nodeify converts promise rejections to callback errors
Promise.reject(new Error('Something failed'))
.nodeify((err, result) => {
console.log(err.message); // 'Something failed'
console.log(result); // undefined
});/**
* Node.js-style callback signature
* @callback NodeCallback
* @param {Error|null} error - Error object or null for success
* @param {*} [result] - Result value (present when error is null)
*/
/**
* Function expecting Node.js-style callback as last parameter
* @callback NodeFunction
* @param {...*} args - Function arguments
* @param {NodeCallback} callback - Node.js callback as last parameter
*/Install with Tessl CLI
npx tessl i tessl/npm-promise