diff --git a/lib/index.js b/lib/index.js index bd9e885..592d222 100644 --- a/lib/index.js +++ b/lib/index.js @@ -72,7 +72,7 @@ const { decrypt } = require('./encryption') /** * @template T - * @typedef {T extends void ? + * @typedef {[T] extends [void] ? * (...args: [Error] | []) => void : * (...args: [Error] | [null, T]) => void * } CB @@ -800,7 +800,7 @@ function initDB(peer, config) { * keypair?: KeypairPublicSlice; * account: string; * }} opts - * @param {(err: Error | null, has: boolean | null) => void} cb + * @param {CB} cb */ function accountHas(opts, cb) { const keypair = opts?.keypair ?? config.global.keypair @@ -826,7 +826,7 @@ function initDB(peer, config) { }), pull.collect((err, results) => { // prettier-ignore - if (err) return cb(Error('db.account.has() failed to calculate', { cause: err }), null) + if (err) return cb(Error('db.account.has() failed to calculate', { cause: err })) return cb( null, @@ -1286,7 +1286,7 @@ function initDB(peer, config) { /** * @param {string} accountId * @param {string} domain - * @param {(err: Error | null, rec: RecPresent | null) => void} cb + * @param {CB} cb */ function findMoot(accountId, domain, cb) { const findAccount = MsgV4.stripAccount(accountId) @@ -1322,7 +1322,7 @@ function initDB(peer, config) { /** * @param {MsgID} msgID - * @param {(err: Error | null, msg?: Msg) => void} cb + * @param {CB} cb */ function get(msgID, cb) { getRecord(msgID, (err, rec) => { diff --git a/test/account-add.test.js b/test/account-add.test.js index 38a6b86..ab287af 100644 --- a/test/account-add.test.js +++ b/test/account-add.test.js @@ -1,12 +1,59 @@ -const test = require('node:test') +const { test } = require('node:test') const assert = require('node:assert') const path = require('node:path') -const p = require('node:util').promisify const os = require('node:os') const rimraf = require('rimraf') const Keypair = require('pzp-keypair') const { createPeer } = require('./util') +/** + * @template T + * @typedef {[T] extends [void] ? + * (...args: [Error] | []) => void : + * (...args: [Error] | [null, T]) => void + * } CB + */ + +/** + * @template T1 + * @template TResult + * @param {(arg1: T1, cb: CB) => void} fn + * @return {(arg1: T1) => Promise} +*/ +const p = (fn) => (...args) => new Promise((res, rej) => { + // @ts-ignore + fn(...args, (err, val) => { + if (err) return rej(err) + return res(val) + }) +}) +/** + * @template TResult + * @param {(cb: CB) => void} fn + * @return {() => Promise} +*/ +const p0 = (fn) => (...args) => new Promise((res, rej) => { + // @ts-ignore + fn(...args, (err, val) => { + if (err) return rej(err) + return res(val) + }) +}) +/** + * @template T1 + * @template T2 + * @template TResult + * @param {(arg1: T1, arg2: T2, cb: CB) => void} fn + * @return {(arg1: T1, arg2: T2) => Promise} +*/ +const p2 = (fn) => (...args) => new Promise((res, rej) => { + // @ts-ignore + fn(...args, (err, val) => { + if (err) return rej(err) + return res(val) + }) +}) + const DIR = path.join(os.tmpdir(), 'pzp-db-account-add') rimraf.sync(DIR) @@ -21,7 +68,7 @@ test('account.add()', async (t) => { const account = await p(peer.db.account.create)({ keypair: keypair1, subdomain: 'person', - }) + },) assert.equal( await p(peer.db.account.has)({ account, keypair: keypair2 }), @@ -32,7 +79,7 @@ test('account.add()', async (t) => { const accountRec1 = await p(peer.db.account.add)({ account, - keypair: keypair2, + keypair: {public:keypair2.public, curve: keypair2.curve}, consent, powers: ['external-encryption'], }) @@ -68,7 +115,7 @@ test('account.add()', async (t) => { true ) - await p(peer.close)() + await p0(peer.close)() }) await t.test('keypair with no "add" powers cannot add', async (t) => { @@ -98,14 +145,15 @@ test('account.add()', async (t) => { true ) - await p(peer1.close)() + await p0(peer1.close)() rimraf.sync(DIR) const peer2 = createPeer({ keypair: keypair2, path: DIR }) await peer2.db.loaded() - await p(peer2.db.add)(msg1, id) - await p(peer2.db.add)(msg2, id) + assert(msg1) + await p2(peer2.db.add)(msg1, id) + await p2(peer2.db.add)(msg2, id) // Test author-side power validation assert.rejects( @@ -127,22 +175,22 @@ test('account.add()', async (t) => { assert.equal(msg3.data.key.bytes, keypair3.public) - await p(peer2.close)() + await p0(peer2.close)() rimraf.sync(DIR) const peer1again = createPeer({ keypair: keypair1, path: DIR }) await peer1again.db.loaded() - await p(peer1again.db.add)(msg1, id) // re-add because lost during rimraf - await p(peer1again.db.add)(msg2, id) // re-add because lost during rimraf + await p2(peer1again.db.add)(msg1, id) // re-add because lost during rimraf + await p2(peer1again.db.add)(msg2, id) // re-add because lost during rimraf // Test replicator-side power validation assert.rejects( - p(peer1again.db.add)(msg3, id), + p2(peer1again.db.add)(msg3, id), /add\(\) failed to verify msg/ ) - await p(peer1again.close)() + await p0(peer1again.close)() }) await t.test('publish with a key in the account', async (t) => { @@ -174,11 +222,11 @@ test('account.add()', async (t) => { keypair: keypair2, }) assert.equal(postRec.msg.data.text, 'hello', 'post text correct') - const mootRec = await p(peer.db.feed.findMoot)(account, 'post') + const mootRec = await p2(peer.db.feed.findMoot)(account, 'post') assert.ok(mootRec, 'posts moot exists') const recs = [] - for await (rec of peer.db.records()) { + for await (const rec of peer.db.records()) { recs.push(rec) } assert.equal(recs.length, 4, '4 records') @@ -186,7 +234,7 @@ test('account.add()', async (t) => { assert.deepEqual(_accountRec0.msg, accountMsg0, 'accountMsg0') assert.deepEqual(_accountRec1.msg, accountRec1.msg, 'accountMsg1') assert.deepEqual( - postsRoot.msg.metadata, + postsRoot?.msg?.metadata, { dataHash: null, dataSize: 0, @@ -200,7 +248,7 @@ test('account.add()', async (t) => { ) assert.deepEqual(_post.msg, postRec.msg, 'postMsg') - await p(peer.close)() + await p0(peer.close)() // Re-load as Carol, add the msgs to validate them rimraf.sync(DIR) @@ -210,13 +258,15 @@ test('account.add()', async (t) => { await carol.db.loaded() - await p(carol.db.add)(accountMsg0, account) - await p(carol.db.add)(accountRec1.msg, account) - await p(carol.db.add)(postsRoot.msg, mootRec.id) - await p(carol.db.add)(postRec.msg, mootRec.id) + assert(accountMsg0) + assert(postsRoot?.msg) + await p2(carol.db.add)(accountMsg0, account) + await p2(carol.db.add)(accountRec1.msg, account) + await p2(carol.db.add)(postsRoot.msg, mootRec.id) + await p2(carol.db.add)(postRec.msg, mootRec.id) // t.pass('carol added all msgs successfully') - await p(carol.close)() + await p0(carol.close)() }) await t.test( @@ -241,7 +291,7 @@ test('account.add()', async (t) => { const accountRec1 = await p(peer.db.account.add)({ account, - keypair: keypair2, + keypair: {public:keypair2.public, curve: keypair2.curve}, consent, powers: ['external-encryption'], }) @@ -252,7 +302,7 @@ test('account.add()', async (t) => { data: { text: 'potato' }, keypair: keypair2, }) - const postMootRec = await p(peer.db.feed.findMoot)(account, 'post') + const postMootRec = await p2(peer.db.feed.findMoot)(account, 'post') const delRec = await p(peer.db.account.del)({ account, @@ -274,18 +324,20 @@ test('account.add()', async (t) => { await carol.db.loaded() - await p(carol.db.add)(accountMsg0, account) - await p(carol.db.add)(accountRec1.msg, account) - await p(carol.db.add)(postMootRec.msg, postMootRec.id) - await p(carol.db.add)(goodRec.msg, postMootRec.id) - await p(carol.db.add)(delRec.msg, account) + assert(accountMsg0) + assert(postMootRec?.msg) + await p2(carol.db.add)(accountMsg0, account) + await p2(carol.db.add)(accountRec1.msg, account) + await p2(carol.db.add)(postMootRec.msg, postMootRec.id) + await p2(carol.db.add)(goodRec.msg, postMootRec.id) + await p2(carol.db.add)(delRec.msg, account) await assert.rejects( - p(carol.db.add)(badRec.msg, postMootRec.id), + p2(carol.db.add)(badRec.msg, postMootRec.id), /add\(\) failed to verify msg/, "Adding msg with del'd keypair is supposed to fail" ) - await p(carol.close)() + await p0(carol.close)() } ) })