mirror of https://codeberg.org/pzp/pzp-promise.git
promise.follow() executes Set add
This commit is contained in:
parent
85d594591a
commit
6b96852808
80
lib/index.js
80
lib/index.js
|
@ -7,11 +7,12 @@ const b4a = require('b4a')
|
|||
|
||||
/**
|
||||
* @typedef {ReturnType<import('ppppp-db').init>} PPPPPDB
|
||||
* @typedef {ReturnType<import('ppppp-set').init>} PPPPPSet
|
||||
* @typedef {import('ppppp-db/msg-v4').AccountAdd} AccountAdd
|
||||
* @typedef {Buffer | Uint8Array} B4A
|
||||
* @typedef {{global: {path: string}}} ExpectedConfig
|
||||
* @typedef {{global: {path?: string}}} Config
|
||||
* @typedef {{type: 'follow'}} FollowPromise
|
||||
* @typedef {{type: 'follow', account: string}} FollowPromise
|
||||
* @typedef {{type: 'account-add', account: string}} AccountAddPromise
|
||||
* @typedef {FollowPromise | AccountAddPromise} PPromise
|
||||
*/
|
||||
|
@ -30,6 +31,15 @@ function assertDBPlugin(peer) {
|
|||
if (!peer.db) throw new Error('promise plugin plugin requires ppppp-db plugin')
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {{ set: PPPPPSet | null }} peer
|
||||
* @returns {asserts peer is { set: PPPPPSet }}
|
||||
*/
|
||||
function assertSetPlugin(peer) {
|
||||
// prettier-ignore
|
||||
if (!peer.set) throw new Error('promise plugin plugin requires ppppp-set plugin')
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Config} config
|
||||
* @returns {asserts config is ExpectedConfig}
|
||||
|
@ -57,7 +67,7 @@ module.exports = {
|
|||
},
|
||||
|
||||
/**
|
||||
* @param {{ db: PPPPPDB | null }} peer
|
||||
* @param {{ db: PPPPPDB | null; set: PPPPPSet | null }} peer
|
||||
* @param {Config} config
|
||||
*/
|
||||
init(peer, config) {
|
||||
|
@ -98,19 +108,21 @@ module.exports = {
|
|||
* @return {Error | null}
|
||||
*/
|
||||
function validatePromise(promise) {
|
||||
if (
|
||||
typeof promise !== 'object' ||
|
||||
typeof promise.type !== 'string' ||
|
||||
(promise.type !== 'follow' && promise.type !== 'account-add')
|
||||
) {
|
||||
if (typeof promise !== 'object' || typeof promise.type !== 'string') {
|
||||
return Error('Invalid promise created: ' + JSON.stringify(promise))
|
||||
}
|
||||
if (
|
||||
promise.type === 'account-add' &&
|
||||
typeof promise.account !== 'string'
|
||||
) {
|
||||
// prettier-ignore
|
||||
return Error('Invalid account-add promise missing "account" field: ' + JSON.stringify(promise))
|
||||
switch (promise.type) {
|
||||
case 'follow':
|
||||
case 'account-add':
|
||||
if (typeof promise.account !== 'string') {
|
||||
// prettier-ignore
|
||||
return Error('Invalid promise missing "account" field: ' + JSON.stringify(promise))
|
||||
} else {
|
||||
break
|
||||
}
|
||||
default:
|
||||
// prettier-ignore
|
||||
return Error('Invalid promise type: ' + JSON.stringify(promise))
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
@ -138,22 +150,28 @@ module.exports = {
|
|||
const token = bs58.encode(crypto.randomBytes(32))
|
||||
promises.set(token, promise)
|
||||
save((err, _) => {
|
||||
if (err) return cb(err)
|
||||
// prettier-ignore
|
||||
if (err) return cb(new Error('Failed to save promise file when creating new promise', { cause: err }))
|
||||
cb(null, token)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} token
|
||||
* @param {string} id
|
||||
* @param {string} accountID
|
||||
* @param {CB<boolean>} cb
|
||||
*/
|
||||
function follow(token, id, cb) {
|
||||
function follow(token, accountID, cb) {
|
||||
if (!loaded) {
|
||||
setTimeout(() => follow(token, id, cb), 100)
|
||||
setTimeout(() => follow(token, accountID, cb), 100)
|
||||
return
|
||||
}
|
||||
try {
|
||||
assertSetPlugin(peer)
|
||||
} catch (err) {
|
||||
cb(/**@type {Error}*/ (err))
|
||||
return
|
||||
}
|
||||
|
||||
if (!promises.has(token)) {
|
||||
cb(new Error('Invalid token'))
|
||||
return
|
||||
|
@ -163,10 +181,28 @@ module.exports = {
|
|||
cb(new Error('Invalid token'))
|
||||
return
|
||||
}
|
||||
console.log('ppppp-promise mock follow') // FIXME: implement follow
|
||||
promises.delete(token)
|
||||
save(() => {
|
||||
cb(null, true)
|
||||
const myAccountID = promise.account
|
||||
const theirAccountID = accountID
|
||||
|
||||
peer.set.load(myAccountID, (err) => {
|
||||
// prettier-ignore
|
||||
if (err) return cb(new Error(`Failed to load ppppp-set with account "${myAccountID}" when executing follow promise`, { cause: err }))
|
||||
if (peer.set.has('follow', theirAccountID)) {
|
||||
promises.delete(token)
|
||||
cb(null, false)
|
||||
return
|
||||
} else {
|
||||
peer.set.add('follow', theirAccountID, (err, _) => {
|
||||
// prettier-ignore
|
||||
if (err) return cb(new Error(`Failed to follow account "${theirAccountID}" in ppppp-set from account "${myAccountID}" when executing follow promise`, { cause: err }))
|
||||
promises.delete(token)
|
||||
save((err, _) => {
|
||||
// prettier-ignore
|
||||
if (err) return cb(new Error('Failed to save promise file when executing follow promise', { cause: err }))
|
||||
cb(null, true)
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
"ppppp-caps": "github:staltz/ppppp-caps",
|
||||
"ppppp-db": "github:staltz/ppppp-db",
|
||||
"ppppp-keypair": "github:staltz/ppppp-keypair",
|
||||
"ppppp-set": "github:staltz/ppppp-set",
|
||||
"prettier": "^2.6.2",
|
||||
"pretty-quick": "^3.1.3",
|
||||
"rimraf": "^5.0.1",
|
||||
|
|
|
@ -19,6 +19,7 @@ async function setup() {
|
|||
.use(require('secret-stack/plugins/net'))
|
||||
.use(require('secret-handshake-ext/secret-stack'))
|
||||
.use(require('ppppp-db'))
|
||||
.use(require('ppppp-set'))
|
||||
.use(require('../lib'))
|
||||
.call(null, {
|
||||
shse: { caps },
|
||||
|
@ -36,7 +37,11 @@ async function setup() {
|
|||
test('create()', async (t) => {
|
||||
const { local, path } = await setup()
|
||||
|
||||
const promise = { type: 'follow' }
|
||||
const account = await p(local.db.account.findOrCreate)({
|
||||
subdomain: 'account',
|
||||
})
|
||||
|
||||
const promise = { type: 'follow', account }
|
||||
const token = await p(local.promise.create)(promise)
|
||||
assert.strictEqual(typeof token, 'string')
|
||||
assert.ok(token.length > 42)
|
||||
|
@ -54,16 +59,25 @@ test('follow()', async (t) => {
|
|||
|
||||
assert.rejects(() => p(local.promise.follow)('randomnottoken', 'FRIEND_ID'))
|
||||
|
||||
const promise = { type: 'follow' }
|
||||
const account = await p(local.db.account.findOrCreate)({
|
||||
subdomain: 'account',
|
||||
})
|
||||
await p(local.set.load)(account)
|
||||
|
||||
const promise = { type: 'follow', account }
|
||||
const token = await p(local.promise.create)(promise)
|
||||
|
||||
const file = Path.join(path, 'promises.json')
|
||||
const contentsBefore = fs.readFileSync(file, 'utf-8')
|
||||
assert.strictEqual(contentsBefore, JSON.stringify([[token, promise]]))
|
||||
|
||||
assert.equal(local.set.has('follow', 'FRIEND_ID'), false, 'not following')
|
||||
|
||||
const result1 = await p(local.promise.follow)(token, 'FRIEND_ID')
|
||||
assert.strictEqual(result1, true)
|
||||
|
||||
assert.equal(local.set.has('follow', 'FRIEND_ID'), true, 'following')
|
||||
|
||||
const contentsAfter = fs.readFileSync(file, 'utf-8')
|
||||
assert.strictEqual(contentsAfter, '[]')
|
||||
|
||||
|
@ -132,7 +146,11 @@ test('accountAdd()', async (t) => {
|
|||
test('revoke()', async (t) => {
|
||||
const { local, path } = await setup()
|
||||
|
||||
const promise = { type: 'follow' }
|
||||
const account = await p(local.db.account.findOrCreate)({
|
||||
subdomain: 'account',
|
||||
})
|
||||
|
||||
const promise = { type: 'follow', account }
|
||||
const token = await p(local.promise.create)(promise)
|
||||
|
||||
const file = Path.join(path, 'promises.json')
|
||||
|
|
|
@ -6,10 +6,10 @@
|
|||
"noEmit": true,
|
||||
"exactOptionalPropertyTypes": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"lib": ["es2021", "dom"],
|
||||
"lib": ["es2022", "dom"],
|
||||
"module": "node16",
|
||||
"skipLibCheck": true,
|
||||
"strict": true,
|
||||
"target": "es2021"
|
||||
"target": "es2022"
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue