js-libp2p/src/config.js

91 lines
2.8 KiB
JavaScript
Raw Normal View History

'use strict'
const { struct, superstruct } = require('superstruct')
const kind = require('kind-of')
const { optional, list } = struct
const transports = ['tcp', 'utp', 'webrtcstar', 'webrtcdirect', 'websockets', 'websocketstar']
// Define custom types
const s = superstruct({
types: {
tcp: v => kind(v) === 'tcp',
utp: v => kind(v) === 'utp',
webrtcstar: v => kind(v) === 'webrtcstar',
webrtcdirect: v => kind(v) === 'webrtcdirect',
websockets: v => kind(v) === 'websockets',
websocketstar: v => kind(v) === 'websocketstar',
transport: value => {
const [error] = list([s.union([ ...transports, 'function' ])]).validate(value)
if (error) return error.message
return value.length > 0
? true
: 'You need to provide at least one transport.'
}
}
})
const optionsSchema = s(
{
connectionManager: 'object?',
datastore: 'object?',
peerInfo: 'object',
peerBook: 'object?',
modules: s({
connEncryption: optional(list([s('object|function')])),
// this is hacky to simulate optional because interface doesnt work correctly with it
// change to optional when fixed upstream
connProtector: s.union(['undefined', s.interface({ protect: 'function' })]),
contentRouting: optional(list(['object'])),
dht: optional(s('null|function|object')),
peerDiscovery: optional(list([s('object|function')])),
peerRouting: optional(list(['object'])),
streamMuxer: optional(list([s('object|function')])),
transport: 'transport'
}),
config: s({
peerDiscovery: 'object?',
relay: s({
enabled: 'boolean',
hop: optional(s({
enabled: 'boolean',
active: 'boolean'
},
{ enabled: false, active: false }))
}, { enabled: true, hop: {} }),
dht: s({
kBucketSize: 'number',
enabled: 'boolean?',
randomWalk: optional(s({
enabled: 'boolean?',
queriesPerPeriod: 'number?',
interval: 'number?',
timeout: 'number?'
}, { enabled: true, queriesPerPeriod: 1, interval: 30000, timeout: 10000 })),
validators: 'object?',
selectors: 'object?'
}, { enabled: true, kBucketSize: 20, enabledDiscovery: true }),
EXPERIMENTAL: s({
pubsub: 'boolean'
}, { pubsub: false })
}, { relay: {}, dht: {}, EXPERIMENTAL: {} })
},
{ config: {}, modules: {} }
)
module.exports.validate = (opts) => {
const [error, options] = optionsSchema.validate(opts)
// Improve errors throwed, reduce stack by throwing here and add reason to the message
if (error) {
throw new Error(`${error.message}${error.reason ? ' - ' + error.reason : ''}`)
} else {
// Throw when dht is enabled but no dht module provided
if (options.config.dht.enabled) {
s('function|object')(options.modules.dht)
}
}
return options
}