node-poplib icon indicating copy to clipboard operation
node-poplib copied to clipboard

Implement promise-based api

Open Masterxilo opened this issue 7 years ago • 4 comments

Installing event handlers for each individual api call feels very unnatural.

Masterxilo avatar Jul 27 '18 15:07 Masterxilo

I implemented promisifying, seems working

function promisifyPOP3Client(client)
{
	const commands = ['connect', 'login', 'auth', 'apop', 'stls', 'top', 'list', 'stat', 'uidl',
	   'retr', 'dele', 'noop', 'rset', 'capa', 'quit'];
	const intCmdPrefix = '_int_';
	
	for (let cmd of commands)
	{
		// rename old command method
		// 'connect' only has event and not method so check if method exists
		if (client[cmd])
			client[intCmdPrefix + cmd] = client[cmd];
		// set new methods that return Promise
		client[cmd] = function (...commandArgs)
		{
			return new Promise(
				function (resolve, reject)
				{
					client.once(cmd, function (status, ...args)
						{
							if (status === false)
								reject(new Error(`Command ${cmd} failed`));
							else
								resolve(args);
						});
					
					client.once('error', function(err)
						{
							if (err.errno === 111) reject(new Error('Unable to connect to server'));
							else reject(err);
						});
					
					client.once('invalid-state', function(cmd)
						{
							reject(new Error('Invalid state. You tried calling ' + cmd));
						});
					
					client.once('locked', function(cmd)
						{
							reject(new Error('Current cmd has not finished yet. You tried calling ' + cmd));
						});
						
					if (client[intCmdPrefix + cmd])
						client[intCmdPrefix + cmd](...commandArgs);
				});
		}
	}
}

Sample:

	const client = new POP3Client(options.port, options.host,
		{
			debug: options.debug,
			enabletls: options.tls
		});
	
	promisifyPOP3Client(client);

	await client.connect();
	await client.login(options.username, options.password);
	const uidlRes = await client.uidl(); // msgnumber, data, rawdata
	...
	await client.quit();

Fr0sT-Brutal avatar Jan 22 '19 16:01 Fr0sT-Brutal

@Fr0sT-Brutal amazing job! That‘s something i can work with.

Masterxilo avatar Jan 22 '19 16:01 Masterxilo

@Masterxilo you're welcome! Feel free to suggest improvements/optimizations, I'm currently quite new to Promise stuff :)

Fr0sT-Brutal avatar Jan 23 '19 12:01 Fr0sT-Brutal

@Fr0sT-Brutal Amazing man. Saved me a lot of time. Thanks and upvote to include this in the package itself.

advayumare avatar Apr 26 '22 09:04 advayumare