mirror of
https://github.com/IT4Change/gradido.git
synced 2025-12-13 07:45:54 +00:00
remove dht-hub feature from federation module
This commit is contained in:
parent
3d767a153b
commit
4d0e37da54
@ -15,7 +15,6 @@
|
||||
"lint": "eslint --max-warnings=0 --ext .js,.ts ."
|
||||
},
|
||||
"dependencies": {
|
||||
"@hyperswarm/dht": "^6.3.3",
|
||||
"@types/dotenv": "^8.2.0",
|
||||
"@types/i18n": "^0.13.6",
|
||||
"@types/jsonwebtoken": "^8.5.9",
|
||||
@ -28,7 +27,7 @@
|
||||
"dotenv": "10.0.0",
|
||||
"express": "4.17.1",
|
||||
"graphql": "15.5.1",
|
||||
"i18n": "^0.15.1",
|
||||
"i18n": "0.15.1",
|
||||
"jsonwebtoken": "^8.5.1",
|
||||
"lodash.clonedeep": "^4.5.0",
|
||||
"log4js": "^6.7.1",
|
||||
|
||||
@ -12,7 +12,7 @@ Decimal.set({
|
||||
|
||||
const constants = {
|
||||
DB_VERSION: '0058-add_communities_table',
|
||||
DECAY_START_TIME: new Date('2021-05-13 17:46:31-0000'), // GMT+0
|
||||
// DECAY_START_TIME: new Date('2021-05-13 17:46:31-0000'), // GMT+0
|
||||
LOG4JS_CONFIG: 'log4js-config.json',
|
||||
// default log level on production should be info
|
||||
LOG_LEVEL: process.env.LOG_LEVEL || 'info',
|
||||
@ -73,7 +73,7 @@ if (
|
||||
}
|
||||
|
||||
const federation = {
|
||||
FEDERATION_DHT_TOPIC: process.env.FEDERATION_DHT_TOPIC || null,
|
||||
// FEDERATION_DHT_TOPIC: process.env.FEDERATION_DHT_TOPIC || null,
|
||||
FEDERATION_DHT_SEED: process.env.FEDERATION_DHT_SEED || null,
|
||||
FEDERATION_PORT: process.env.FEDERATION_PORT || 5000,
|
||||
FEDERATION_API: process.env.FEDERATION_API || '1_0',
|
||||
@ -84,11 +84,7 @@ const CONFIG = {
|
||||
...constants,
|
||||
...server,
|
||||
...database,
|
||||
//...klicktipp,
|
||||
...community,
|
||||
//...email,
|
||||
//...loginServer,
|
||||
//...webhook,
|
||||
//...eventProtocol,
|
||||
...federation,
|
||||
}
|
||||
|
||||
@ -1 +0,0 @@
|
||||
declare module '@hyperswarm/dht'
|
||||
@ -1,798 +0,0 @@
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
|
||||
|
||||
import { startDHT } from './index'
|
||||
import DHT from '@hyperswarm/dht'
|
||||
import CONFIG from '@/config'
|
||||
import { logger } from '@test/testSetup'
|
||||
import { Community as DbCommunity } from '@entity/Community'
|
||||
import { testEnvironment, cleanDB } from '@test/helpers'
|
||||
|
||||
CONFIG.FEDERATION_DHT_SEED = '64ebcb0e3ad547848fef4197c6e2332f'
|
||||
|
||||
jest.mock('@hyperswarm/dht')
|
||||
|
||||
const TEST_TOPIC = 'gradido_test_topic'
|
||||
|
||||
const keyPairMock = {
|
||||
publicKey: Buffer.from('publicKey'),
|
||||
secretKey: Buffer.from('secretKey'),
|
||||
}
|
||||
|
||||
const serverListenSpy = jest.fn()
|
||||
|
||||
const serverEventMocks: { [key: string]: any } = {}
|
||||
|
||||
const serverOnMock = jest.fn().mockImplementation((key: string, callback) => {
|
||||
serverEventMocks[key] = callback
|
||||
})
|
||||
|
||||
const nodeCreateServerMock = jest.fn().mockImplementation(() => {
|
||||
return {
|
||||
on: serverOnMock,
|
||||
listen: serverListenSpy,
|
||||
}
|
||||
})
|
||||
|
||||
const nodeAnnounceMock = jest.fn().mockImplementation(() => {
|
||||
return {
|
||||
finished: jest.fn(),
|
||||
}
|
||||
})
|
||||
|
||||
const lookupResultMock = {
|
||||
token: Buffer.from(TEST_TOPIC),
|
||||
from: {
|
||||
id: Buffer.from('somone'),
|
||||
host: '188.95.53.5',
|
||||
port: 63561,
|
||||
},
|
||||
to: { id: null, host: '83.53.31.27', port: 55723 },
|
||||
peers: [
|
||||
{
|
||||
publicKey: Buffer.from('some-public-key'),
|
||||
relayAddresses: [],
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
const nodeLookupMock = jest.fn().mockResolvedValue([lookupResultMock])
|
||||
|
||||
const socketEventMocks: { [key: string]: any } = {}
|
||||
|
||||
const socketOnMock = jest.fn().mockImplementation((key: string, callback) => {
|
||||
socketEventMocks[key] = callback
|
||||
})
|
||||
|
||||
const socketWriteMock = jest.fn()
|
||||
|
||||
const nodeConnectMock = jest.fn().mockImplementation(() => {
|
||||
return {
|
||||
on: socketOnMock,
|
||||
once: socketOnMock,
|
||||
write: socketWriteMock,
|
||||
}
|
||||
})
|
||||
|
||||
DHT.hash.mockImplementation(() => {
|
||||
return Buffer.from(TEST_TOPIC)
|
||||
})
|
||||
|
||||
DHT.keyPair.mockImplementation(() => {
|
||||
return keyPairMock
|
||||
})
|
||||
|
||||
DHT.mockImplementation(() => {
|
||||
return {
|
||||
createServer: nodeCreateServerMock,
|
||||
announce: nodeAnnounceMock,
|
||||
lookup: nodeLookupMock,
|
||||
connect: nodeConnectMock,
|
||||
}
|
||||
})
|
||||
|
||||
let con: any
|
||||
let testEnv: any
|
||||
|
||||
beforeAll(async () => {
|
||||
testEnv = await testEnvironment(logger)
|
||||
con = testEnv.con
|
||||
await cleanDB()
|
||||
})
|
||||
|
||||
afterAll(async () => {
|
||||
await cleanDB()
|
||||
await con.close()
|
||||
})
|
||||
|
||||
describe('federation', () => {
|
||||
beforeAll(() => {
|
||||
jest.useFakeTimers()
|
||||
})
|
||||
|
||||
describe('call startDHT', () => {
|
||||
const hashSpy = jest.spyOn(DHT, 'hash')
|
||||
const keyPairSpy = jest.spyOn(DHT, 'keyPair')
|
||||
beforeEach(async () => {
|
||||
DHT.mockClear()
|
||||
jest.clearAllMocks()
|
||||
await startDHT(TEST_TOPIC)
|
||||
})
|
||||
|
||||
it('calls DHT.hash', () => {
|
||||
expect(hashSpy).toBeCalledWith(Buffer.from(TEST_TOPIC))
|
||||
})
|
||||
|
||||
it('creates a key pair', () => {
|
||||
expect(keyPairSpy).toBeCalledWith(expect.any(Buffer))
|
||||
})
|
||||
|
||||
it('initializes a new DHT object', () => {
|
||||
expect(DHT).toBeCalledWith({ keyPair: keyPairMock })
|
||||
})
|
||||
|
||||
describe('DHT node', () => {
|
||||
it('creates a server', () => {
|
||||
expect(nodeCreateServerMock).toBeCalled()
|
||||
})
|
||||
|
||||
it('listens on the server', () => {
|
||||
expect(serverListenSpy).toBeCalled()
|
||||
})
|
||||
|
||||
describe('timers', () => {
|
||||
beforeEach(() => {
|
||||
jest.runOnlyPendingTimers()
|
||||
})
|
||||
|
||||
it('announces on topic', () => {
|
||||
expect(nodeAnnounceMock).toBeCalledWith(Buffer.from(TEST_TOPIC), keyPairMock)
|
||||
})
|
||||
|
||||
it('looks up on topic', () => {
|
||||
expect(nodeLookupMock).toBeCalledWith(Buffer.from(TEST_TOPIC))
|
||||
})
|
||||
})
|
||||
|
||||
describe('server connection event', () => {
|
||||
beforeEach(() => {
|
||||
serverEventMocks.connection({
|
||||
remotePublicKey: Buffer.from('another-public-key'),
|
||||
on: socketOnMock,
|
||||
})
|
||||
})
|
||||
|
||||
it('can be triggered', () => {
|
||||
expect(socketOnMock).toBeCalled()
|
||||
})
|
||||
|
||||
describe('socket events', () => {
|
||||
describe('on data', () => {
|
||||
describe('with receiving simply a string', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks()
|
||||
socketEventMocks.data(Buffer.from('no-json string'))
|
||||
})
|
||||
|
||||
it('logs the received data', () => {
|
||||
expect(logger.info).toBeCalledWith('data: no-json string')
|
||||
})
|
||||
|
||||
it('logs an error of unexpected data format and structure', () => {
|
||||
expect(logger.error).toBeCalledWith(
|
||||
'Error on receiving data from socket:',
|
||||
new SyntaxError('Unexpected token o in JSON at position 1'),
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe('with receiving array of strings', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks()
|
||||
const strArray: string[] = ['invalid type test', 'api', 'url']
|
||||
socketEventMocks.data(Buffer.from(strArray.toString()))
|
||||
})
|
||||
|
||||
it('logs the received data', () => {
|
||||
expect(logger.info).toBeCalledWith('data: invalid type test,api,url')
|
||||
})
|
||||
|
||||
it('logs an error of unexpected data format and structure', () => {
|
||||
expect(logger.error).toBeCalledWith(
|
||||
'Error on receiving data from socket:',
|
||||
new SyntaxError('Unexpected token i in JSON at position 0'),
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe('with receiving array of string-arrays', () => {
|
||||
beforeEach(async () => {
|
||||
jest.clearAllMocks()
|
||||
const strArray: string[][] = [
|
||||
[`api`, `url`, `invalid type in array test`],
|
||||
[`wrong`, `api`, `url`],
|
||||
]
|
||||
await socketEventMocks.data(Buffer.from(strArray.toString()))
|
||||
})
|
||||
|
||||
it('logs the received data', () => {
|
||||
expect(logger.info).toBeCalledWith(
|
||||
'data: api,url,invalid type in array test,wrong,api,url',
|
||||
)
|
||||
})
|
||||
|
||||
it('logs an error of unexpected data format and structure', () => {
|
||||
expect(logger.error).toBeCalledWith(
|
||||
'Error on receiving data from socket:',
|
||||
new SyntaxError('Unexpected token a in JSON at position 0'),
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe('with receiving JSON-Array with too much entries', () => {
|
||||
let jsonArray: { api: string; url: string }[]
|
||||
beforeEach(async () => {
|
||||
jest.clearAllMocks()
|
||||
jsonArray = [
|
||||
{ api: 'v1_0', url: 'too much versions at the same time test' },
|
||||
{ api: 'v1_0', url: 'url2' },
|
||||
{ api: 'v1_0', url: 'url3' },
|
||||
{ api: 'v1_0', url: 'url4' },
|
||||
{ api: 'v1_0', url: 'url5' },
|
||||
]
|
||||
await socketEventMocks.data(Buffer.from(JSON.stringify(jsonArray)))
|
||||
})
|
||||
|
||||
it('logs the received data', () => {
|
||||
expect(logger.info).toBeCalledWith(
|
||||
'data: [{"api":"v1_0","url":"too much versions at the same time test"},{"api":"v1_0","url":"url2"},{"api":"v1_0","url":"url3"},{"api":"v1_0","url":"url4"},{"api":"v1_0","url":"url5"}]',
|
||||
)
|
||||
})
|
||||
|
||||
it('logs a warning of too much apiVersion-Definitions', () => {
|
||||
expect(logger.warn).toBeCalledWith(
|
||||
`received totaly wrong or too much apiVersions-Definition JSON-String: ${JSON.stringify(
|
||||
jsonArray,
|
||||
)}`,
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe('with receiving wrong but tolerated property data', () => {
|
||||
let jsonArray: any[]
|
||||
let result: DbCommunity[] = []
|
||||
beforeAll(async () => {
|
||||
jest.clearAllMocks()
|
||||
jsonArray = [
|
||||
{
|
||||
wrong: 'wrong but tolerated property test',
|
||||
api: 'v1_0',
|
||||
url: 'url1',
|
||||
},
|
||||
{
|
||||
api: 'v2_0',
|
||||
url: 'url2',
|
||||
wrong: 'wrong but tolerated property test',
|
||||
},
|
||||
]
|
||||
await socketEventMocks.data(Buffer.from(JSON.stringify(jsonArray)))
|
||||
result = await DbCommunity.find()
|
||||
})
|
||||
|
||||
afterAll(async () => {
|
||||
await cleanDB()
|
||||
})
|
||||
|
||||
it('has two Communty entries in database', () => {
|
||||
expect(result).toHaveLength(2)
|
||||
})
|
||||
|
||||
it('has an entry for api version v1_0', () => {
|
||||
expect(result).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
id: expect.any(Number),
|
||||
publicKey: expect.any(Buffer),
|
||||
apiVersion: 'v1_0',
|
||||
endPoint: 'url1',
|
||||
lastAnnouncedAt: expect.any(Date),
|
||||
createdAt: expect.any(Date),
|
||||
updatedAt: null,
|
||||
}),
|
||||
]),
|
||||
)
|
||||
})
|
||||
|
||||
it('has an entry for api version v2_0', () => {
|
||||
expect(result).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
id: expect.any(Number),
|
||||
publicKey: expect.any(Buffer),
|
||||
apiVersion: 'v2_0',
|
||||
endPoint: 'url2',
|
||||
lastAnnouncedAt: expect.any(Date),
|
||||
createdAt: expect.any(Date),
|
||||
updatedAt: null,
|
||||
}),
|
||||
]),
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe('with receiving data but missing api property', () => {
|
||||
let jsonArray: any[]
|
||||
beforeEach(async () => {
|
||||
jest.clearAllMocks()
|
||||
jsonArray = [
|
||||
{ test1: 'missing api proterty test', url: 'any url definition as string' },
|
||||
{ api: 'some api', test2: 'missing url property test' },
|
||||
]
|
||||
await socketEventMocks.data(Buffer.from(JSON.stringify(jsonArray)))
|
||||
})
|
||||
|
||||
it('logs the received data', () => {
|
||||
expect(logger.info).toBeCalledWith(`data: ${JSON.stringify(jsonArray)}`)
|
||||
})
|
||||
|
||||
it('logs a warning of invalid apiVersion-Definition', () => {
|
||||
expect(logger.warn).toBeCalledWith(
|
||||
`received invalid apiVersion-Definition: ${JSON.stringify(jsonArray[0])}`,
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe('with receiving data but missing url property', () => {
|
||||
let jsonArray: any[]
|
||||
beforeEach(async () => {
|
||||
jest.clearAllMocks()
|
||||
jsonArray = [
|
||||
{ api: 'some api', test2: 'missing url property test' },
|
||||
{ test1: 'missing api proterty test', url: 'any url definition as string' },
|
||||
]
|
||||
await socketEventMocks.data(Buffer.from(JSON.stringify(jsonArray)))
|
||||
})
|
||||
|
||||
it('logs the received data', () => {
|
||||
expect(logger.info).toBeCalledWith(`data: ${JSON.stringify(jsonArray)}`)
|
||||
})
|
||||
|
||||
it('logs a warning of invalid apiVersion-Definition', () => {
|
||||
expect(logger.warn).toBeCalledWith(
|
||||
`received invalid apiVersion-Definition: ${JSON.stringify(jsonArray[0])}`,
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe('with receiving data but wrong type of api property', () => {
|
||||
let jsonArray: any[]
|
||||
beforeEach(async () => {
|
||||
jest.clearAllMocks()
|
||||
jsonArray = [
|
||||
{ api: 1, url: 'wrong property type tests' },
|
||||
{ api: 'urltyptest', url: 2 },
|
||||
{ api: 1, url: 2 },
|
||||
]
|
||||
await socketEventMocks.data(Buffer.from(JSON.stringify(jsonArray)))
|
||||
})
|
||||
|
||||
it('logs the received data', () => {
|
||||
expect(logger.info).toBeCalledWith(`data: ${JSON.stringify(jsonArray)}`)
|
||||
})
|
||||
|
||||
it('logs a warning of invalid apiVersion-Definition', () => {
|
||||
expect(logger.warn).toBeCalledWith(
|
||||
`received invalid apiVersion-Definition: ${JSON.stringify(jsonArray[0])}`,
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe('with receiving data but wrong type of url property', () => {
|
||||
let jsonArray: any[]
|
||||
beforeEach(async () => {
|
||||
jest.clearAllMocks()
|
||||
jsonArray = [
|
||||
{ api: 'urltyptest', url: 2 },
|
||||
{ api: 1, url: 'wrong property type tests' },
|
||||
{ api: 1, url: 2 },
|
||||
]
|
||||
await socketEventMocks.data(Buffer.from(JSON.stringify(jsonArray)))
|
||||
})
|
||||
|
||||
it('logs the received data', () => {
|
||||
expect(logger.info).toBeCalledWith(`data: ${JSON.stringify(jsonArray)}`)
|
||||
})
|
||||
|
||||
it('logs a warning of invalid apiVersion-Definition', () => {
|
||||
expect(logger.warn).toBeCalledWith(
|
||||
`received invalid apiVersion-Definition: ${JSON.stringify(jsonArray[0])}`,
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe('with receiving data but wrong type of both properties', () => {
|
||||
let jsonArray: any[]
|
||||
beforeEach(async () => {
|
||||
jest.clearAllMocks()
|
||||
jsonArray = [
|
||||
{ api: 1, url: 2 },
|
||||
{ api: 'urltyptest', url: 2 },
|
||||
{ api: 1, url: 'wrong property type tests' },
|
||||
]
|
||||
await socketEventMocks.data(Buffer.from(JSON.stringify(jsonArray)))
|
||||
})
|
||||
|
||||
it('logs the received data', () => {
|
||||
expect(logger.info).toBeCalledWith(`data: ${JSON.stringify(jsonArray)}`)
|
||||
})
|
||||
|
||||
it('logs a warning of invalid apiVersion-Definition', () => {
|
||||
expect(logger.warn).toBeCalledWith(
|
||||
`received invalid apiVersion-Definition: ${JSON.stringify(jsonArray[0])}`,
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe('with receiving data but too long api string', () => {
|
||||
let jsonArray: any[]
|
||||
beforeEach(async () => {
|
||||
jest.clearAllMocks()
|
||||
jsonArray = [
|
||||
{ api: 'toolong api', url: 'some valid url' },
|
||||
{
|
||||
api: 'valid api',
|
||||
url: 'this is a too long url definition with exact one character more than the allowed two hundert and fiftyfive characters. and here begins the fill characters with no sense of content menschhabicheinhungerdassichnichtweiswoichheutnachtschlafensollsofriertesmic',
|
||||
},
|
||||
{
|
||||
api: 'toolong api',
|
||||
url: 'this is a too long url definition with exact one character more than the allowed two hundert and fiftyfive characters. and here begins the fill characters with no sense of content menschhabicheinhungerdassichnichtweiswoichheutnachtschlafensollsofriertesmic',
|
||||
},
|
||||
]
|
||||
await socketEventMocks.data(Buffer.from(JSON.stringify(jsonArray)))
|
||||
})
|
||||
|
||||
it('logs the received data', () => {
|
||||
expect(logger.info).toBeCalledWith(`data: ${JSON.stringify(jsonArray)}`)
|
||||
})
|
||||
|
||||
it('logs a warning of invalid apiVersion-Definition', () => {
|
||||
expect(logger.warn).toBeCalledWith(
|
||||
`received apiVersion with content longer than max length: ${JSON.stringify(
|
||||
jsonArray[0],
|
||||
)}`,
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe('with receiving data but too long url string', () => {
|
||||
let jsonArray: any[]
|
||||
beforeEach(async () => {
|
||||
jest.clearAllMocks()
|
||||
jsonArray = [
|
||||
{
|
||||
api: 'api',
|
||||
url: 'this is a too long url definition with exact one character more than the allowed two hundert and fiftyfive characters. and here begins the fill characters with no sense of content menschhabicheinhungerdassichnichtweiswoichheutnachtschlafensollsofriertesmic',
|
||||
},
|
||||
{ api: 'toolong api', url: 'some valid url' },
|
||||
{
|
||||
api: 'toolong api',
|
||||
url: 'this is a too long url definition with exact one character more than the allowed two hundert and fiftyfive characters. and here begins the fill characters with no sense of content menschhabicheinhungerdassichnichtweiswoichheutnachtschlafensollsofriertesmic',
|
||||
},
|
||||
]
|
||||
await socketEventMocks.data(Buffer.from(JSON.stringify(jsonArray)))
|
||||
})
|
||||
|
||||
it('logs the received data', () => {
|
||||
expect(logger.info).toBeCalledWith(`data: ${JSON.stringify(jsonArray)}`)
|
||||
})
|
||||
|
||||
it('logs a warning of invalid apiVersion-Definition', () => {
|
||||
expect(logger.warn).toBeCalledWith(
|
||||
`received apiVersion with content longer than max length: ${JSON.stringify(
|
||||
jsonArray[0],
|
||||
)}`,
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe('with receiving data but both properties with too long strings', () => {
|
||||
let jsonArray: any[]
|
||||
beforeEach(async () => {
|
||||
jest.clearAllMocks()
|
||||
jsonArray = [
|
||||
{
|
||||
api: 'toolong api',
|
||||
url: 'this is a too long url definition with exact one character more than the allowed two hundert and fiftyfive characters. and here begins the fill characters with no sense of content menschhabicheinhungerdassichnichtweiswoichheutnachtschlafensollsofriertesmic',
|
||||
},
|
||||
{
|
||||
api: 'api',
|
||||
url: 'this is a too long url definition with exact one character more than the allowed two hundert and fiftyfive characters. and here begins the fill characters with no sense of content menschhabicheinhungerdassichnichtweiswoichheutnachtschlafensollsofriertesmic',
|
||||
},
|
||||
{ api: 'toolong api', url: 'some valid url' },
|
||||
]
|
||||
await socketEventMocks.data(Buffer.from(JSON.stringify(jsonArray)))
|
||||
})
|
||||
|
||||
it('logs the received data', () => {
|
||||
expect(logger.info).toBeCalledWith(`data: ${JSON.stringify(jsonArray)}`)
|
||||
})
|
||||
})
|
||||
|
||||
describe('with receiving data of exact max allowed properties length', () => {
|
||||
let jsonArray: any[]
|
||||
let result: DbCommunity[] = []
|
||||
beforeAll(async () => {
|
||||
jest.clearAllMocks()
|
||||
jsonArray = [
|
||||
{
|
||||
api: 'valid api',
|
||||
url: 'this is a valid url definition with exact the max allowed length of two hundert and fiftyfive characters. and here begins the fill characters with no sense of content kuhwarmiga menschhabicheinhungerdassichnichtweiswoichheutnachtschlafensollsofriertesmich',
|
||||
},
|
||||
{
|
||||
api: 'api',
|
||||
url: 'this is a too long url definition with exact one character more than the allowed two hundert and fiftyfive characters. and here begins the fill characters with no sense of content menschhabicheinhungerdassichnichtweiswoichheutnachtschlafensollsofriertesmic',
|
||||
},
|
||||
{ api: 'toolong api', url: 'some valid url' },
|
||||
]
|
||||
await socketEventMocks.data(Buffer.from(JSON.stringify(jsonArray)))
|
||||
result = await DbCommunity.find()
|
||||
})
|
||||
|
||||
afterAll(async () => {
|
||||
await cleanDB()
|
||||
})
|
||||
|
||||
it('has one Communty entry in database', () => {
|
||||
expect(result).toHaveLength(1)
|
||||
})
|
||||
|
||||
it(`has an entry with max content length for api and url`, () => {
|
||||
expect(result).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
id: expect.any(Number),
|
||||
publicKey: expect.any(Buffer),
|
||||
apiVersion: 'valid api',
|
||||
endPoint:
|
||||
'this is a valid url definition with exact the max allowed length of two hundert and fiftyfive characters. and here begins the fill characters with no sense of content kuhwarmiga menschhabicheinhungerdassichnichtweiswoichheutnachtschlafensollsofriertesmich',
|
||||
lastAnnouncedAt: expect.any(Date),
|
||||
createdAt: expect.any(Date),
|
||||
updatedAt: null,
|
||||
}),
|
||||
]),
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe('with receiving data of exact max allowed buffer length', () => {
|
||||
let jsonArray: any[]
|
||||
let result: DbCommunity[] = []
|
||||
beforeAll(async () => {
|
||||
jest.clearAllMocks()
|
||||
jsonArray = [
|
||||
{
|
||||
api: 'valid api1',
|
||||
url: 'this is a valid url definition with exact the max allowed length of two hundert and fiftyfive characters. and here begins the fill characters with no sense of content kuhwarmiga menschhabicheinhungerdassichnichtweiswoichheutnachtschlafensollsofriertesmich',
|
||||
},
|
||||
{
|
||||
api: 'valid api2',
|
||||
url: 'this is a valid url definition with exact the max allowed length of two hundert and fiftyfive characters. and here begins the fill characters with no sense of content kuhwarmiga menschhabicheinhungerdassichnichtweiswoichheutnachtschlafensollsofriertesmich',
|
||||
},
|
||||
{
|
||||
api: 'valid api3',
|
||||
url: 'this is a valid url definition with exact the max allowed length of two hundert and fiftyfive characters. and here begins the fill characters with no sense of content kuhwarmiga menschhabicheinhungerdassichnichtweiswoichheutnachtschlafensollsofriertesmich',
|
||||
},
|
||||
{
|
||||
api: 'valid api4',
|
||||
url: 'this is a valid url definition with exact the max allowed length of two hundert and fiftyfive characters. and here begins the fill characters with no sense of content kuhwarmiga menschhabicheinhungerdassichnichtweiswoichheutnachtschlafensollsofriertesmich',
|
||||
},
|
||||
]
|
||||
await socketEventMocks.data(Buffer.from(JSON.stringify(jsonArray)))
|
||||
result = await DbCommunity.find()
|
||||
})
|
||||
|
||||
afterAll(async () => {
|
||||
await cleanDB()
|
||||
})
|
||||
|
||||
it('has five Communty entries in database', () => {
|
||||
expect(result).toHaveLength(4)
|
||||
})
|
||||
|
||||
it(`has an entry 'valid api1' with max content length for api and url`, () => {
|
||||
expect(result).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
id: expect.any(Number),
|
||||
publicKey: expect.any(Buffer),
|
||||
apiVersion: 'valid api1',
|
||||
endPoint:
|
||||
'this is a valid url definition with exact the max allowed length of two hundert and fiftyfive characters. and here begins the fill characters with no sense of content kuhwarmiga menschhabicheinhungerdassichnichtweiswoichheutnachtschlafensollsofriertesmich',
|
||||
lastAnnouncedAt: expect.any(Date),
|
||||
createdAt: expect.any(Date),
|
||||
updatedAt: null,
|
||||
}),
|
||||
]),
|
||||
)
|
||||
})
|
||||
|
||||
it(`has an entry 'valid api2' with max content length for api and url`, () => {
|
||||
expect(result).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
id: expect.any(Number),
|
||||
publicKey: expect.any(Buffer),
|
||||
apiVersion: 'valid api2',
|
||||
endPoint:
|
||||
'this is a valid url definition with exact the max allowed length of two hundert and fiftyfive characters. and here begins the fill characters with no sense of content kuhwarmiga menschhabicheinhungerdassichnichtweiswoichheutnachtschlafensollsofriertesmich',
|
||||
lastAnnouncedAt: expect.any(Date),
|
||||
createdAt: expect.any(Date),
|
||||
updatedAt: null,
|
||||
}),
|
||||
]),
|
||||
)
|
||||
})
|
||||
|
||||
it(`has an entry 'valid api3' with max content length for api and url`, () => {
|
||||
expect(result).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
id: expect.any(Number),
|
||||
publicKey: expect.any(Buffer),
|
||||
apiVersion: 'valid api3',
|
||||
endPoint:
|
||||
'this is a valid url definition with exact the max allowed length of two hundert and fiftyfive characters. and here begins the fill characters with no sense of content kuhwarmiga menschhabicheinhungerdassichnichtweiswoichheutnachtschlafensollsofriertesmich',
|
||||
lastAnnouncedAt: expect.any(Date),
|
||||
createdAt: expect.any(Date),
|
||||
updatedAt: null,
|
||||
}),
|
||||
]),
|
||||
)
|
||||
})
|
||||
|
||||
it(`has an entry 'valid api4' with max content length for api and url`, () => {
|
||||
expect(result).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
id: expect.any(Number),
|
||||
publicKey: expect.any(Buffer),
|
||||
apiVersion: 'valid api4',
|
||||
endPoint:
|
||||
'this is a valid url definition with exact the max allowed length of two hundert and fiftyfive characters. and here begins the fill characters with no sense of content kuhwarmiga menschhabicheinhungerdassichnichtweiswoichheutnachtschlafensollsofriertesmich',
|
||||
lastAnnouncedAt: expect.any(Date),
|
||||
createdAt: expect.any(Date),
|
||||
updatedAt: null,
|
||||
}),
|
||||
]),
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe('with receiving data longer than max allowed buffer length', () => {
|
||||
let jsonArray: any[]
|
||||
beforeEach(async () => {
|
||||
jest.clearAllMocks()
|
||||
jsonArray = [
|
||||
{
|
||||
api: 'Xvalid api1',
|
||||
url: 'this is a valid url definition with exact the max allowed length of two hundert and fiftyfive characters. and here begins the fill characters with no sense of content kuhwarmiga menschhabicheinhungerdassichnichtweiswoichheutnachtschlafensollsofriertesmich',
|
||||
},
|
||||
{
|
||||
api: 'valid api2',
|
||||
url: 'this is a valid url definition with exact the max allowed length of two hundert and fiftyfive characters. and here begins the fill characters with no sense of content kuhwarmiga menschhabicheinhungerdassichnichtweiswoichheutnachtschlafensollsofriertesmich',
|
||||
},
|
||||
{
|
||||
api: 'valid api3',
|
||||
url: 'this is a valid url definition with exact the max allowed length of two hundert and fiftyfive characters. and here begins the fill characters with no sense of content kuhwarmiga menschhabicheinhungerdassichnichtweiswoichheutnachtschlafensollsofriertesmich',
|
||||
},
|
||||
{
|
||||
api: 'valid api4',
|
||||
url: 'this is a valid url definition with exact the max allowed length of two hundert and fiftyfive characters. and here begins the fill characters with no sense of content kuhwarmiga menschhabicheinhungerdassichnichtweiswoichheutnachtschlafensollsofriertesmich',
|
||||
},
|
||||
]
|
||||
await socketEventMocks.data(Buffer.from(JSON.stringify(jsonArray)))
|
||||
})
|
||||
|
||||
it('logs the received data', () => {
|
||||
expect(logger.warn).toBeCalledWith(
|
||||
`received more than max allowed length of data buffer: ${
|
||||
JSON.stringify(jsonArray).length
|
||||
} against 1141 max allowed`,
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe('with proper data', () => {
|
||||
let result: DbCommunity[] = []
|
||||
beforeAll(async () => {
|
||||
jest.clearAllMocks()
|
||||
await socketEventMocks.data(
|
||||
Buffer.from(
|
||||
JSON.stringify([
|
||||
{
|
||||
api: 'v1_0',
|
||||
url: 'http://localhost:4000/api/v1_0',
|
||||
},
|
||||
{
|
||||
api: 'v2_0',
|
||||
url: 'http://localhost:4000/api/v2_0',
|
||||
},
|
||||
]),
|
||||
),
|
||||
)
|
||||
result = await DbCommunity.find()
|
||||
})
|
||||
|
||||
afterAll(async () => {
|
||||
await cleanDB()
|
||||
})
|
||||
|
||||
it('has two Communty entries in database', () => {
|
||||
expect(result).toHaveLength(2)
|
||||
})
|
||||
|
||||
it('has an entry for api version v1_0', () => {
|
||||
expect(result).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
id: expect.any(Number),
|
||||
publicKey: expect.any(Buffer),
|
||||
apiVersion: 'v1_0',
|
||||
endPoint: 'http://localhost:4000/api/v1_0',
|
||||
lastAnnouncedAt: expect.any(Date),
|
||||
createdAt: expect.any(Date),
|
||||
updatedAt: null,
|
||||
}),
|
||||
]),
|
||||
)
|
||||
})
|
||||
|
||||
it('has an entry for api version v2_0', () => {
|
||||
expect(result).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
id: expect.any(Number),
|
||||
publicKey: expect.any(Buffer),
|
||||
apiVersion: 'v2_0',
|
||||
endPoint: 'http://localhost:4000/api/v2_0',
|
||||
lastAnnouncedAt: expect.any(Date),
|
||||
createdAt: expect.any(Date),
|
||||
updatedAt: null,
|
||||
}),
|
||||
]),
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('on open', () => {
|
||||
beforeEach(() => {
|
||||
socketEventMocks.open()
|
||||
})
|
||||
|
||||
it.skip('calls socket write with own api versions', () => {
|
||||
expect(socketWriteMock).toBeCalledWith(
|
||||
Buffer.from(
|
||||
JSON.stringify([
|
||||
{
|
||||
api: 'v1_0',
|
||||
url: 'http://localhost:4000/api/v1_0',
|
||||
},
|
||||
{
|
||||
api: 'v1_1',
|
||||
url: 'http://localhost:4000/api/v1_1',
|
||||
},
|
||||
{
|
||||
api: 'v2_0',
|
||||
url: 'http://localhost:4000/api/v2_0',
|
||||
},
|
||||
]),
|
||||
),
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
@ -1,185 +0,0 @@
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
|
||||
import DHT from '@hyperswarm/dht'
|
||||
import { federationLogger as logger } from '@/server/logger'
|
||||
import CONFIG from '@/config'
|
||||
import { Community as DbCommunity } from '@entity/Community'
|
||||
|
||||
const KEY_SECRET_SEEDBYTES = 32
|
||||
const getSeed = (): Buffer | null =>
|
||||
CONFIG.FEDERATION_DHT_SEED ? Buffer.alloc(KEY_SECRET_SEEDBYTES, CONFIG.FEDERATION_DHT_SEED) : null
|
||||
|
||||
const POLLTIME = 20000
|
||||
const SUCCESSTIME = 120000
|
||||
const ERRORTIME = 240000
|
||||
const ANNOUNCETIME = 30000
|
||||
|
||||
enum ApiVersionType {
|
||||
V1_0 = 'v1_0',
|
||||
V1_1 = 'v1_1',
|
||||
V2_0 = 'v2_0',
|
||||
}
|
||||
type CommunityApi = {
|
||||
api: string
|
||||
url: string
|
||||
}
|
||||
|
||||
export const startDHT = async (topic: string): Promise<void> => {
|
||||
try {
|
||||
const TOPIC = DHT.hash(Buffer.from(topic))
|
||||
const keyPair = DHT.keyPair(getSeed())
|
||||
logger.info(`keyPairDHT: publicKey=${keyPair.publicKey.toString('hex')}`)
|
||||
logger.debug(`keyPairDHT: secretKey=${keyPair.secretKey.toString('hex')}`)
|
||||
|
||||
const ownApiVersions = Object.values(ApiVersionType).map(function (apiEnum) {
|
||||
const comApi: CommunityApi = {
|
||||
api: apiEnum,
|
||||
url: CONFIG.FEDERATION_COMMUNITY_URL + apiEnum,
|
||||
}
|
||||
return comApi
|
||||
})
|
||||
logger.debug(`ApiList: ${JSON.stringify(ownApiVersions)}`)
|
||||
|
||||
const node = new DHT({ keyPair })
|
||||
|
||||
const server = node.createServer()
|
||||
|
||||
server.on('connection', function (socket: any) {
|
||||
logger.info(`server on... with Remote public key: ${socket.remotePublicKey.toString('hex')}`)
|
||||
|
||||
socket.on('data', async (data: Buffer) => {
|
||||
try {
|
||||
if (data.length > 1141) {
|
||||
logger.warn(
|
||||
`received more than max allowed length of data buffer: ${data.length} against 1141 max allowed`,
|
||||
)
|
||||
return
|
||||
}
|
||||
logger.info(`data: ${data.toString('ascii')}`)
|
||||
const recApiVersions: CommunityApi[] = JSON.parse(data.toString('ascii'))
|
||||
|
||||
// TODO better to introduce the validation by https://github.com/typestack/class-validato
|
||||
if (recApiVersions && Array.isArray(recApiVersions) && recApiVersions.length < 5) {
|
||||
for (const recApiVersion of recApiVersions) {
|
||||
if (
|
||||
!recApiVersion.api ||
|
||||
typeof recApiVersion.api !== 'string' ||
|
||||
!recApiVersion.url ||
|
||||
typeof recApiVersion.url !== 'string'
|
||||
) {
|
||||
logger.warn(
|
||||
`received invalid apiVersion-Definition: ${JSON.stringify(recApiVersion)}`,
|
||||
)
|
||||
// in a forEach-loop use return instead of continue
|
||||
return
|
||||
}
|
||||
// TODO better to introduce the validation on entity-Level by https://github.com/typestack/class-validator
|
||||
if (recApiVersion.api.length > 10 || recApiVersion.url.length > 255) {
|
||||
logger.warn(
|
||||
`received apiVersion with content longer than max length: ${JSON.stringify(
|
||||
recApiVersion,
|
||||
)}`,
|
||||
)
|
||||
// in a forEach-loop use return instead of continue
|
||||
return
|
||||
}
|
||||
|
||||
const variables = {
|
||||
apiVersion: recApiVersion.api,
|
||||
endPoint: recApiVersion.url,
|
||||
publicKey: socket.remotePublicKey.toString('hex'),
|
||||
lastAnnouncedAt: new Date(),
|
||||
}
|
||||
logger.debug(`upsert with variables=${JSON.stringify(variables)}`)
|
||||
// this will NOT update the updatedAt column, to distingue between a normal update and the last announcement
|
||||
await DbCommunity.createQueryBuilder()
|
||||
.insert()
|
||||
.into(DbCommunity)
|
||||
.values(variables)
|
||||
.orUpdate({
|
||||
conflict_target: ['id', 'publicKey', 'apiVersion'],
|
||||
overwrite: ['end_point', 'last_announced_at'],
|
||||
})
|
||||
.execute()
|
||||
logger.info(`federation community upserted successfully...`)
|
||||
}
|
||||
} else {
|
||||
logger.warn(
|
||||
`received totaly wrong or too much apiVersions-Definition JSON-String: ${JSON.stringify(
|
||||
recApiVersions,
|
||||
)}`,
|
||||
)
|
||||
}
|
||||
} catch (e) {
|
||||
logger.error('Error on receiving data from socket:', e)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
await server.listen()
|
||||
|
||||
setInterval(async () => {
|
||||
logger.info(`Announcing on topic: ${TOPIC.toString('hex')}`)
|
||||
await node.announce(TOPIC, keyPair).finished()
|
||||
}, ANNOUNCETIME)
|
||||
|
||||
let successfulRequests: string[] = []
|
||||
let errorfulRequests: string[] = []
|
||||
|
||||
setInterval(async () => {
|
||||
logger.info('Refreshing successful nodes')
|
||||
successfulRequests = []
|
||||
}, SUCCESSTIME)
|
||||
|
||||
setInterval(async () => {
|
||||
logger.info('Refreshing errorful nodes')
|
||||
errorfulRequests = []
|
||||
}, ERRORTIME)
|
||||
|
||||
setInterval(async () => {
|
||||
const result = await node.lookup(TOPIC)
|
||||
|
||||
const collectedPubKeys: string[] = []
|
||||
|
||||
for await (const data of result) {
|
||||
data.peers.forEach((peer: any) => {
|
||||
const pubKey = peer.publicKey.toString('hex')
|
||||
if (
|
||||
pubKey !== keyPair.publicKey.toString('hex') &&
|
||||
!successfulRequests.includes(pubKey) &&
|
||||
!errorfulRequests.includes(pubKey) &&
|
||||
!collectedPubKeys.includes(pubKey)
|
||||
) {
|
||||
collectedPubKeys.push(peer.publicKey.toString('hex'))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
logger.info(`Found new peers: ${collectedPubKeys}`)
|
||||
|
||||
collectedPubKeys.forEach((remotePubKey) => {
|
||||
const socket = node.connect(Buffer.from(remotePubKey, 'hex'))
|
||||
|
||||
// socket.once("connect", function () {
|
||||
// console.log("client side emitted connect");
|
||||
// });
|
||||
|
||||
// socket.once("end", function () {
|
||||
// console.log("client side ended");
|
||||
// });
|
||||
|
||||
socket.once('error', (err: any) => {
|
||||
errorfulRequests.push(remotePubKey)
|
||||
logger.error(`error on peer ${remotePubKey}: ${err.message}`)
|
||||
})
|
||||
|
||||
socket.on('open', function () {
|
||||
socket.write(Buffer.from(JSON.stringify(ownApiVersions)))
|
||||
successfulRequests.push(remotePubKey)
|
||||
})
|
||||
})
|
||||
}, POLLTIME)
|
||||
} catch (err) {
|
||||
logger.error('DHT unexpected error:', err)
|
||||
}
|
||||
}
|
||||
@ -1,7 +1,6 @@
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
|
||||
import createServer from './server/createServer'
|
||||
import { startDHT } from '@/dht_node/index'
|
||||
|
||||
// config
|
||||
import CONFIG from './config'
|
||||
@ -10,7 +9,6 @@ async function main() {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(`FEDERATION_PORT=${CONFIG.FEDERATION_PORT}`)
|
||||
console.log(`FEDERATION_API=${CONFIG.FEDERATION_API}`)
|
||||
console.log(`configured: FEDERATION_DHT_TOPIC=${CONFIG.FEDERATION_DHT_TOPIC}`)
|
||||
const { app } = await createServer()
|
||||
|
||||
app.listen(CONFIG.FEDERATION_PORT, () => {
|
||||
@ -21,17 +19,6 @@ async function main() {
|
||||
console.log(`GraphIQL available at http://localhost:${CONFIG.FEDERATION_PORT}`)
|
||||
}
|
||||
})
|
||||
|
||||
// start DHT hyperswarm when DHT_TOPIC is set in .env
|
||||
if (CONFIG.FEDERATION_DHT_TOPIC) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(
|
||||
`starting Federation on ${CONFIG.FEDERATION_DHT_TOPIC} ${
|
||||
CONFIG.FEDERATION_DHT_SEED ? 'with seed...' : 'without seed...'
|
||||
}`,
|
||||
)
|
||||
await startDHT(CONFIG.FEDERATION_DHT_TOPIC) // con,
|
||||
}
|
||||
}
|
||||
|
||||
main().catch((e) => {
|
||||
|
||||
@ -8,11 +8,7 @@ const options = JSON.parse(readFileSync(CONFIG.LOG4JS_CONFIG, 'utf-8'))
|
||||
options.categories.backend.level = CONFIG.LOG_LEVEL
|
||||
options.categories.apollo.level = CONFIG.LOG_LEVEL
|
||||
let filename: string = options.appenders.federation.filename
|
||||
if(CONFIG.FEDERATION_DHT_TOPIC) {
|
||||
options.appenders.federation.filename = filename.replace('apiversion-%v', 'dht-'+CONFIG.FEDERATION_DHT_TOPIC).replace('%p', CONFIG.FEDERATION_PORT.toString())
|
||||
} else {
|
||||
options.appenders.federation.filename = filename.replace('%v', CONFIG.FEDERATION_API).replace('%p', CONFIG.FEDERATION_PORT.toString())
|
||||
}
|
||||
options.appenders.federation.filename = filename.replace('%v', CONFIG.FEDERATION_API).replace('%p', CONFIG.FEDERATION_PORT.toString())
|
||||
filename = options.appenders.access.filename
|
||||
options.appenders.access.filename = filename.replace('%p', CONFIG.FEDERATION_PORT.toString())
|
||||
filename = options.appenders.apollo.filename
|
||||
|
||||
@ -53,42 +53,6 @@
|
||||
dependencies:
|
||||
"@jridgewell/trace-mapping" "0.3.9"
|
||||
|
||||
"@hyperswarm/dht@^6.3.3":
|
||||
version "6.3.3"
|
||||
resolved "https://registry.yarnpkg.com/@hyperswarm/dht/-/dht-6.3.3.tgz#a9266cb56549f74e2d5dea587aad00c483799ad6"
|
||||
integrity sha512-2eGtS2i0Ij6zQL2IuDWzUbN6/c+NBpigBzRsH2/x2aA+8AJUO0IL3BaHECnO69T6WigCOMz+mp2exFkDjjGTRQ==
|
||||
dependencies:
|
||||
"@hyperswarm/secret-stream" "^6.0.0"
|
||||
b4a "^1.3.1"
|
||||
bogon "^1.0.0"
|
||||
compact-encoding "^2.4.1"
|
||||
compact-encoding-net "^1.0.1"
|
||||
debugging-stream "^2.0.0"
|
||||
dht-rpc "^6.3.0"
|
||||
events "^3.3.0"
|
||||
hypercore-crypto "^3.3.0"
|
||||
noise-curve-ed "^2.0.0"
|
||||
noise-handshake "^3.0.0"
|
||||
record-cache "^1.1.1"
|
||||
safety-catch "^1.0.1"
|
||||
sodium-universal "^3.0.4"
|
||||
udx-native "^1.5.1"
|
||||
xache "^1.1.0"
|
||||
|
||||
"@hyperswarm/secret-stream@^6.0.0":
|
||||
version "6.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@hyperswarm/secret-stream/-/secret-stream-6.1.0.tgz#e99e6d449a0b1a571c42730841642da3356ea4da"
|
||||
integrity sha512-6GjmdrYxZgJYGi8Ji7AZoqmmwQXSR9ByERkMPatcC5FMYgx9n5lDkwgKRK7faPQHpgtwjg2oLCrFveyGRLHV5g==
|
||||
dependencies:
|
||||
b4a "^1.1.0"
|
||||
hypercore-crypto "^3.3.0"
|
||||
noise-curve-ed "^2.0.0"
|
||||
noise-handshake "^3.0.0"
|
||||
sodium-secretstream "^1.0.0"
|
||||
sodium-universal "^3.0.4"
|
||||
streamx "^2.10.2"
|
||||
timeout-refresh "^2.0.0"
|
||||
|
||||
"@josephg/resolvable@^1.0.0":
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@josephg/resolvable/-/resolvable-1.0.1.tgz#69bc4db754d79e1a2f17a650d3466e038d94a5eb"
|
||||
@ -657,11 +621,6 @@ async-retry@^1.2.1:
|
||||
dependencies:
|
||||
retry "0.13.1"
|
||||
|
||||
b4a@^1.0.1, b4a@^1.1.0, b4a@^1.1.1, b4a@^1.3.0, b4a@^1.3.1, b4a@^1.5.0:
|
||||
version "1.6.1"
|
||||
resolved "https://registry.yarnpkg.com/b4a/-/b4a-1.6.1.tgz#9effac93a469a868d024e16fd77162c653544cbd"
|
||||
integrity sha512-AsKjNhz72yxteo/0EtQEiwkMUgk/tGmycXlbG4g3Ard2/ULtNLUykGOkeK0egmN27h0xMAhb76jYccW+XTBExA==
|
||||
|
||||
backo2@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/backo2/-/backo2-1.0.2.tgz#31ab1ac8b129363463e35b3ebb69f4dfcfba7947"
|
||||
@ -677,22 +636,6 @@ binary-extensions@^2.0.0:
|
||||
resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d"
|
||||
integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==
|
||||
|
||||
blake2b-wasm@^2.4.0:
|
||||
version "2.4.0"
|
||||
resolved "https://registry.yarnpkg.com/blake2b-wasm/-/blake2b-wasm-2.4.0.tgz#9115649111edbbd87eb24ce7c04b427e4e2be5be"
|
||||
integrity sha512-S1kwmW2ZhZFFFOghcx73+ZajEfKBqhP82JMssxtLVMxlaPea1p9uoLiUZ5WYyHn0KddwbLc+0vh4wR0KBNoT5w==
|
||||
dependencies:
|
||||
b4a "^1.0.1"
|
||||
nanoassert "^2.0.0"
|
||||
|
||||
blake2b@^2.1.1:
|
||||
version "2.1.4"
|
||||
resolved "https://registry.yarnpkg.com/blake2b/-/blake2b-2.1.4.tgz#817d278526ddb4cd673bfb1af16d1ad61e393ba3"
|
||||
integrity sha512-AyBuuJNI64gIvwx13qiICz6H6hpmjvYS5DGkG6jbXMOT8Z3WUJ3V1X0FlhIoT1b/5JtHE3ki+xjtMvu1nn+t9A==
|
||||
dependencies:
|
||||
blake2b-wasm "^2.4.0"
|
||||
nanoassert "^2.0.0"
|
||||
|
||||
body-parser@1.19.0:
|
||||
version "1.19.0"
|
||||
resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.0.tgz#96b2709e57c9c4e09a6fd66a8fd979844f69f08a"
|
||||
@ -727,14 +670,6 @@ body-parser@1.20.1, body-parser@^1.18.3:
|
||||
type-is "~1.6.18"
|
||||
unpipe "1.0.0"
|
||||
|
||||
bogon@^1.0.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/bogon/-/bogon-1.1.0.tgz#14234260353d8f806c3a307202f66698f635d18b"
|
||||
integrity sha512-a6SnToksXHuUlgeMvI/txWmTcKz7c7iBa8f0HbXL4toN1Uza/CTQ4F7n9jSDX49TCpxv3KUP100q4sZfwLyLiw==
|
||||
dependencies:
|
||||
compact-encoding "^2.11.0"
|
||||
compact-encoding-net "^1.2.0"
|
||||
|
||||
boolean@^3.1.4:
|
||||
version "3.2.0"
|
||||
resolved "https://registry.yarnpkg.com/boolean/-/boolean-3.2.0.tgz#9e5294af4e98314494cbb17979fa54ca159f116b"
|
||||
@ -785,13 +720,6 @@ call-bind@^1.0.0, call-bind@^1.0.2:
|
||||
function-bind "^1.1.1"
|
||||
get-intrinsic "^1.0.2"
|
||||
|
||||
chacha20-universal@^1.0.4:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/chacha20-universal/-/chacha20-universal-1.0.4.tgz#e8a33a386500b1ce5361b811ec5e81f1797883f5"
|
||||
integrity sha512-/IOxdWWNa7nRabfe7+oF+jVkGjlr2xUL4J8l/OvzZhj+c9RpMqoo3Dq+5nU1j/BflRV4BKnaQ4+4oH1yBpQG1Q==
|
||||
dependencies:
|
||||
nanoassert "^2.0.0"
|
||||
|
||||
chokidar@^3.5.2:
|
||||
version "3.5.3"
|
||||
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd"
|
||||
@ -820,20 +748,6 @@ commander@^2.20.3:
|
||||
resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
|
||||
integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==
|
||||
|
||||
compact-encoding-net@^1.0.1, compact-encoding-net@^1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/compact-encoding-net/-/compact-encoding-net-1.2.0.tgz#19d2efd55df10f2ee793576fc4483bf6d2218743"
|
||||
integrity sha512-LVXpNpF7PGQeHRVVLGgYWzuVoYAaDZvKUsUxRioGfkotzvOh4AzoQF1HBH3zMNaSnx7gJXuUr3hkjnijaH/Eng==
|
||||
dependencies:
|
||||
compact-encoding "^2.4.1"
|
||||
|
||||
compact-encoding@^2.1.0, compact-encoding@^2.11.0, compact-encoding@^2.4.1, compact-encoding@^2.5.1:
|
||||
version "2.11.0"
|
||||
resolved "https://registry.yarnpkg.com/compact-encoding/-/compact-encoding-2.11.0.tgz#eff11cb0c328b3f82556cb391ed54519155fbdf8"
|
||||
integrity sha512-CRfTuyy9Tg7EwxNKvIq3yFIr2JnJLyVr9Yj234VsDCL59hdXcZH3TdzY/2kwbAqVogIoRBJjnNKCEnXbxTIEeg==
|
||||
dependencies:
|
||||
b4a "^1.3.0"
|
||||
|
||||
concat-map@0.0.1:
|
||||
version "0.0.1"
|
||||
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
|
||||
@ -938,13 +852,6 @@ debug@^4.3.3, debug@^4.3.4:
|
||||
dependencies:
|
||||
ms "2.1.2"
|
||||
|
||||
debugging-stream@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/debugging-stream/-/debugging-stream-2.0.0.tgz#515cad5a35299cf4b4bc0afcbd69d52c809c84ce"
|
||||
integrity sha512-xwfl6wB/3xc553uwtGnSa94jFxnGOc02C0WU2Nmzwr80gzeqn1FX4VcbvoKIhe8L/lPq4BTQttAbrTN94uN8rA==
|
||||
dependencies:
|
||||
streamx "^2.12.4"
|
||||
|
||||
decimal.js-light@^2.5.1:
|
||||
version "2.5.1"
|
||||
resolved "https://registry.yarnpkg.com/decimal.js-light/-/decimal.js-light-2.5.1.tgz#134fd32508f19e208f4fb2f8dac0d2626a867934"
|
||||
@ -983,23 +890,6 @@ destroy@~1.0.4:
|
||||
resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80"
|
||||
integrity sha512-3NdhDuEXnfun/z7x9GOElY49LoqVHoGScmOKwmxhsS8N5Y+Z8KyPPDnaSzqWgYt/ji4mqwfTS34Htrk0zPIXVg==
|
||||
|
||||
dht-rpc@^6.3.0:
|
||||
version "6.3.1"
|
||||
resolved "https://registry.yarnpkg.com/dht-rpc/-/dht-rpc-6.3.1.tgz#6571a3b48006c8256aadc6b993a7753582db551d"
|
||||
integrity sha512-TCvDU5Pc7CL3QwFv1QKe/7IKj24Fp1JxWSRqZd1vVKFQCMRbYZxGsD3pIsPa/ILTzEUUOK5oBWPxeO2mDQr+gw==
|
||||
dependencies:
|
||||
b4a "^1.3.1"
|
||||
compact-encoding "^2.1.0"
|
||||
compact-encoding-net "^1.0.1"
|
||||
events "^3.3.0"
|
||||
fast-fifo "^1.0.0"
|
||||
kademlia-routing-table "^1.0.0"
|
||||
nat-sampler "^1.0.1"
|
||||
sodium-universal "^3.0.4"
|
||||
streamx "^2.10.3"
|
||||
time-ordered-set "^1.0.2"
|
||||
udx-native "^1.2.0"
|
||||
|
||||
dicer@0.3.0:
|
||||
version "0.3.0"
|
||||
resolved "https://registry.yarnpkg.com/dicer/-/dicer-0.3.0.tgz#eacd98b3bfbf92e8ab5c2fdb71aaac44bb06b872"
|
||||
@ -1099,11 +989,6 @@ eventemitter3@^3.1.0:
|
||||
resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-3.1.2.tgz#2d3d48f9c346698fce83a85d7d664e98535df6e7"
|
||||
integrity sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==
|
||||
|
||||
events@^3.3.0:
|
||||
version "3.3.0"
|
||||
resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400"
|
||||
integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==
|
||||
|
||||
express@4.17.1:
|
||||
version "4.17.1"
|
||||
resolved "https://registry.yarnpkg.com/express/-/express-4.17.1.tgz#4491fc38605cf51f8629d39c2b5d026f98a4c134"
|
||||
@ -1177,11 +1062,6 @@ express@^4.17.1:
|
||||
utils-merge "1.0.1"
|
||||
vary "~1.1.2"
|
||||
|
||||
fast-fifo@^1.0.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/fast-fifo/-/fast-fifo-1.1.0.tgz#17d1a3646880b9891dfa0c54e69c5fef33cad779"
|
||||
integrity sha512-Kl29QoNbNvn4nhDsLYjyIAaIqaJB6rBx5p3sL9VjaefJ+eMFBWVZiaoguaoZfzEKr5RhAti0UgM8703akGPJ6g==
|
||||
|
||||
fast-json-stable-stringify@^2.0.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633"
|
||||
@ -1423,15 +1303,6 @@ has@^1.0.3:
|
||||
dependencies:
|
||||
function-bind "^1.1.1"
|
||||
|
||||
hmac-blake2b@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/hmac-blake2b/-/hmac-blake2b-2.0.0.tgz#09494e5d245d7afe45d157093080b159f7bacf15"
|
||||
integrity sha512-JbGNtM1YRd8EQH/2vNTAP1oy5lJVPlBFYZfCJTu3k8sqOUm0rRIf/3+MCd5noVykETwTbun6jEOc+4Tu78ubHA==
|
||||
dependencies:
|
||||
nanoassert "^1.1.0"
|
||||
sodium-native "^3.1.1"
|
||||
sodium-universal "^3.0.0"
|
||||
|
||||
http-errors@1.7.2:
|
||||
version "1.7.2"
|
||||
resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.2.tgz#4f5029cf13239f31036e5b2e55292bcfbcc85c8f"
|
||||
@ -1476,16 +1347,7 @@ http-errors@~1.7.2:
|
||||
statuses ">= 1.5.0 < 2"
|
||||
toidentifier "1.0.0"
|
||||
|
||||
hypercore-crypto@^3.3.0:
|
||||
version "3.3.0"
|
||||
resolved "https://registry.yarnpkg.com/hypercore-crypto/-/hypercore-crypto-3.3.0.tgz#03ab5b44608a563e131f629f671c6f90a83c52e6"
|
||||
integrity sha512-zAWbDqG7kWwS6rCxxTUeB/OeFAz3PoOmouKaoMubtDJYJsLHqXtA3wE2mLsw+E2+iYyom5zrFyBTFVYxmgwW6g==
|
||||
dependencies:
|
||||
b4a "^1.1.0"
|
||||
compact-encoding "^2.5.1"
|
||||
sodium-universal "^3.0.0"
|
||||
|
||||
i18n@^0.15.1:
|
||||
i18n@0.15.1:
|
||||
version "0.15.1"
|
||||
resolved "https://registry.yarnpkg.com/i18n/-/i18n-0.15.1.tgz#68fb8993c461cc440bc2485d82f72019f2b92de8"
|
||||
integrity sha512-yue187t8MqUPMHdKjiZGrX+L+xcUsDClGO0Cz4loaKUOK9WrGw5pgan4bv130utOwX7fHE9w2iUeHFalVQWkXA==
|
||||
@ -1568,13 +1430,6 @@ is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.7:
|
||||
resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055"
|
||||
integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==
|
||||
|
||||
is-core-module@^2.9.0:
|
||||
version "2.11.0"
|
||||
resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.11.0.tgz#ad4cb3e3863e814523c96f3f58d26cc570ff0144"
|
||||
integrity sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==
|
||||
dependencies:
|
||||
has "^1.0.3"
|
||||
|
||||
is-date-object@^1.0.1:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.5.tgz#0841d5536e724c25597bf6ea62e1bd38298df31f"
|
||||
@ -1702,11 +1557,6 @@ jws@^3.2.2:
|
||||
jwa "^1.4.1"
|
||||
safe-buffer "^5.0.1"
|
||||
|
||||
kademlia-routing-table@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/kademlia-routing-table/-/kademlia-routing-table-1.0.1.tgz#6f18416f612e885a8d4df128f04c490a90d772f6"
|
||||
integrity sha512-dKk19sC3/+kWhBIvOKCthxVV+JH0NrswSBq4sA4eOkkPMqQM1rRuOWte1WSKXeP8r9Nx4NuiH2gny3lMddJTpw==
|
||||
|
||||
libphonenumber-js@^1.9.43:
|
||||
version "1.10.14"
|
||||
resolved "https://registry.yarnpkg.com/libphonenumber-js/-/libphonenumber-js-1.10.14.tgz#e29da7f539751f724ac54017a098e3c7ca23de94"
|
||||
@ -1879,26 +1729,6 @@ mustache@^4.2.0:
|
||||
resolved "https://registry.yarnpkg.com/mustache/-/mustache-4.2.0.tgz#e5892324d60a12ec9c2a73359edca52972bf6f64"
|
||||
integrity sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==
|
||||
|
||||
nanoassert@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/nanoassert/-/nanoassert-1.1.0.tgz#4f3152e09540fde28c76f44b19bbcd1d5a42478d"
|
||||
integrity sha512-C40jQ3NzfkP53NsO8kEOFd79p4b9kDXQMwgiY1z8ZwrDZgUyom0AHwGegF4Dm99L+YoYhuaB0ceerUcXmqr1rQ==
|
||||
|
||||
nanoassert@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/nanoassert/-/nanoassert-2.0.0.tgz#a05f86de6c7a51618038a620f88878ed1e490c09"
|
||||
integrity sha512-7vO7n28+aYO4J+8w96AzhmU8G+Y/xpPDJz/se19ICsqj/momRbb9mh9ZUtkoJ5X3nTnPdhEJyc0qnM6yAsHBaA==
|
||||
|
||||
napi-macros@^2.0.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/napi-macros/-/napi-macros-2.1.0.tgz#d0a8bd90b65be19dd37e425386a005c694f7039d"
|
||||
integrity sha512-wJugWHfxRnVhV26BpJl2vyLHOXPrNBUyYJA5CTYcgbRcqHXAEJqStqpKOfBJyd0eb1VMbjdNvoeBWucpbdDrTw==
|
||||
|
||||
nat-sampler@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/nat-sampler/-/nat-sampler-1.0.1.tgz#2b68338ea6d4c139450cd971fd00a4ac1b33d923"
|
||||
integrity sha512-yQvyNN7xbqR8crTKk3U8gRgpcV1Az+vfCEijiHu9oHHsnIl8n3x+yXNHl42M6L3czGynAVoOT9TqBfS87gDdcw==
|
||||
|
||||
negotiator@0.6.3:
|
||||
version "0.6.3"
|
||||
resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd"
|
||||
@ -1911,11 +1741,6 @@ node-fetch@^2.6.1:
|
||||
dependencies:
|
||||
whatwg-url "^5.0.0"
|
||||
|
||||
node-gyp-build@^4.3.0, node-gyp-build@^4.4.0:
|
||||
version "4.5.0"
|
||||
resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.5.0.tgz#7a64eefa0b21112f89f58379da128ac177f20e40"
|
||||
integrity sha512-2iGbaQBV+ITgCz76ZEjmhUKAKVf7xfY1sRl4UiKQspfZMH2h06SyhNsnSVy50cwkFQDGLyif6m/6uFXHkOZ6rg==
|
||||
|
||||
nodemon@^2.0.20:
|
||||
version "2.0.20"
|
||||
resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-2.0.20.tgz#e3537de768a492e8d74da5c5813cb0c7486fc701"
|
||||
@ -1932,25 +1757,6 @@ nodemon@^2.0.20:
|
||||
touch "^3.1.0"
|
||||
undefsafe "^2.0.5"
|
||||
|
||||
noise-curve-ed@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/noise-curve-ed/-/noise-curve-ed-2.0.0.tgz#d5fb33b80ab87c78e0297010ea3e068035163415"
|
||||
integrity sha512-DRMv6ciwQVDpDMMcNWyt20kLuAmXVYVJoPUhmvmIZkgSALA6a+OeNTrX35gt5vQ6LgE36DSOFMpGfdmWpBmjDg==
|
||||
dependencies:
|
||||
b4a "^1.1.0"
|
||||
nanoassert "^2.0.0"
|
||||
sodium-universal "^3.0.4"
|
||||
|
||||
noise-handshake@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/noise-handshake/-/noise-handshake-3.0.0.tgz#cce40781a4da7c650d62e02d0164f5fb4fd71844"
|
||||
integrity sha512-/EQq+TbCZpOFDg0bD3jtxKYqwgSBCFU1tfGxUzHHy94kBKMwVY8GHNxtWR+gekwkhXCu7TyBXqNPY3qdaxe+fQ==
|
||||
dependencies:
|
||||
b4a "^1.1.0"
|
||||
hmac-blake2b "^2.0.0"
|
||||
nanoassert "^2.0.0"
|
||||
sodium-universal "^3.0.4"
|
||||
|
||||
nopt@~1.0.10:
|
||||
version "1.0.10"
|
||||
resolved "https://registry.yarnpkg.com/nopt/-/nopt-1.0.10.tgz#6ddd21bd2a31417b92727dd585f8a6f37608ebee"
|
||||
@ -2039,11 +1845,6 @@ path-key@^3.1.0:
|
||||
resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375"
|
||||
integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==
|
||||
|
||||
path-parse@^1.0.7:
|
||||
version "1.0.7"
|
||||
resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735"
|
||||
integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==
|
||||
|
||||
path-to-regexp@0.1.7:
|
||||
version "0.1.7"
|
||||
resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c"
|
||||
@ -2079,11 +1880,6 @@ qs@6.7.0:
|
||||
resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc"
|
||||
integrity sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==
|
||||
|
||||
queue-tick@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/queue-tick/-/queue-tick-1.0.1.tgz#f6f07ac82c1fd60f82e098b417a80e52f1f4c142"
|
||||
integrity sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==
|
||||
|
||||
range-parser@~1.2.1:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031"
|
||||
@ -2116,13 +1912,6 @@ readdirp@~3.6.0:
|
||||
dependencies:
|
||||
picomatch "^2.2.1"
|
||||
|
||||
record-cache@^1.1.1:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/record-cache/-/record-cache-1.2.0.tgz#e601bc4f164d58330cc00055e27aa4682291c882"
|
||||
integrity sha512-kyy3HWCez2WrotaL3O4fTn0rsIdfRKOdQQcEJ9KpvmKmbffKVvwsloX063EgRUlpJIXHiDQFhJcTbZequ2uTZw==
|
||||
dependencies:
|
||||
b4a "^1.3.1"
|
||||
|
||||
reflect-metadata@^0.1.13:
|
||||
version "0.1.13"
|
||||
resolved "https://registry.yarnpkg.com/reflect-metadata/-/reflect-metadata-0.1.13.tgz#67ae3ca57c972a2aa1642b10fe363fe32d49dc08"
|
||||
@ -2137,15 +1926,6 @@ regexp.prototype.flags@^1.4.3:
|
||||
define-properties "^1.1.3"
|
||||
functions-have-names "^1.2.2"
|
||||
|
||||
resolve@^1.17.0:
|
||||
version "1.22.1"
|
||||
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177"
|
||||
integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==
|
||||
dependencies:
|
||||
is-core-module "^2.9.0"
|
||||
path-parse "^1.0.7"
|
||||
supports-preserve-symlinks-flag "^1.0.0"
|
||||
|
||||
retry@0.13.1:
|
||||
version "0.13.1"
|
||||
resolved "https://registry.yarnpkg.com/retry/-/retry-0.13.1.tgz#185b1587acf67919d63b357349e03537b2484658"
|
||||
@ -2185,11 +1965,6 @@ safe-regex-test@^1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
|
||||
integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
|
||||
|
||||
safety-catch@^1.0.1:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/safety-catch/-/safety-catch-1.0.2.tgz#d64cbd57fd601da91c356b6ab8902f3e449a7a4b"
|
||||
integrity sha512-C1UYVZ4dtbBxEtvOcpjBaaD27nP8MlvyAQEp2fOTOEe6pfUpk1cDUxij6BR1jZup6rSyUTaBBplK7LanskrULA==
|
||||
|
||||
semver@^5.6.0, semver@^5.7.1:
|
||||
version "5.7.1"
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
|
||||
@ -2283,38 +2058,6 @@ sha.js@^2.4.11:
|
||||
inherits "^2.0.1"
|
||||
safe-buffer "^5.0.1"
|
||||
|
||||
sha256-universal@^1.1.0:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/sha256-universal/-/sha256-universal-1.2.1.tgz#051d92decce280cd6137d42d496eac88da942c0e"
|
||||
integrity sha512-ghn3muhdn1ailCQqqceNxRgkOeZSVfSE13RQWEg6njB+itsFzGVSJv+O//2hvNXZuxVIRyNzrgsZ37SPDdGJJw==
|
||||
dependencies:
|
||||
b4a "^1.0.1"
|
||||
sha256-wasm "^2.2.1"
|
||||
|
||||
sha256-wasm@^2.2.1:
|
||||
version "2.2.2"
|
||||
resolved "https://registry.yarnpkg.com/sha256-wasm/-/sha256-wasm-2.2.2.tgz#4940b6c9ba28f3f08b700efce587ef36d4d516d4"
|
||||
integrity sha512-qKSGARvao+JQlFiA+sjJZhJ/61gmW/3aNLblB2rsgIxDlDxsJPHo8a1seXj12oKtuHVgJSJJ7QEGBUYQN741lQ==
|
||||
dependencies:
|
||||
b4a "^1.0.1"
|
||||
nanoassert "^2.0.0"
|
||||
|
||||
sha512-universal@^1.1.0:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/sha512-universal/-/sha512-universal-1.2.1.tgz#829505a7586530515cc1a10b78815c99722c4df0"
|
||||
integrity sha512-kehYuigMoRkIngCv7rhgruLJNNHDnitGTBdkcYbCbooL8Cidj/bS78MDxByIjcc69M915WxcQTgZetZ1JbeQTQ==
|
||||
dependencies:
|
||||
b4a "^1.0.1"
|
||||
sha512-wasm "^2.3.1"
|
||||
|
||||
sha512-wasm@^2.3.1:
|
||||
version "2.3.4"
|
||||
resolved "https://registry.yarnpkg.com/sha512-wasm/-/sha512-wasm-2.3.4.tgz#b86b37112ff6d1fc3740f2484a6855f17a6e1300"
|
||||
integrity sha512-akWoxJPGCB3aZCrZ+fm6VIFhJ/p8idBv7AWGFng/CZIrQo51oQNsvDbTSRXWAzIiZJvpy16oIDiCCPqTe21sKg==
|
||||
dependencies:
|
||||
b4a "^1.0.1"
|
||||
nanoassert "^2.0.0"
|
||||
|
||||
shebang-command@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea"
|
||||
@ -2343,57 +2086,6 @@ simple-update-notifier@^1.0.7:
|
||||
dependencies:
|
||||
semver "~7.0.0"
|
||||
|
||||
siphash24@^1.0.1:
|
||||
version "1.3.1"
|
||||
resolved "https://registry.yarnpkg.com/siphash24/-/siphash24-1.3.1.tgz#7f87fd2c5db88d8d46335a68f780f281641c8b22"
|
||||
integrity sha512-moemC3ZKiTzH29nbFo3Iw8fbemWWod4vNs/WgKbQ54oEs6mE6XVlguxvinYjB+UmaE0PThgyED9fUkWvirT8hA==
|
||||
dependencies:
|
||||
nanoassert "^2.0.0"
|
||||
|
||||
sodium-javascript@~0.8.0:
|
||||
version "0.8.0"
|
||||
resolved "https://registry.yarnpkg.com/sodium-javascript/-/sodium-javascript-0.8.0.tgz#0a94d7bb58ab17be82255f3949259af59778fdbc"
|
||||
integrity sha512-rEBzR5mPxPES+UjyMDvKPIXy9ImF17KOJ32nJNi9uIquWpS/nfj+h6m05J5yLJaGXjgM72LmQoUbWZVxh/rmGg==
|
||||
dependencies:
|
||||
blake2b "^2.1.1"
|
||||
chacha20-universal "^1.0.4"
|
||||
nanoassert "^2.0.0"
|
||||
sha256-universal "^1.1.0"
|
||||
sha512-universal "^1.1.0"
|
||||
siphash24 "^1.0.1"
|
||||
xsalsa20 "^1.0.0"
|
||||
|
||||
sodium-native@^3.1.1, sodium-native@^3.2.0:
|
||||
version "3.4.1"
|
||||
resolved "https://registry.yarnpkg.com/sodium-native/-/sodium-native-3.4.1.tgz#44616c07ccecea15195f553af88b3e574b659741"
|
||||
integrity sha512-PaNN/roiFWzVVTL6OqjzYct38NSXewdl2wz8SRB51Br/MLIJPrbM3XexhVWkq7D3UWMysfrhKVf1v1phZq6MeQ==
|
||||
dependencies:
|
||||
node-gyp-build "^4.3.0"
|
||||
|
||||
sodium-secretstream@^1.0.0:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/sodium-secretstream/-/sodium-secretstream-1.0.2.tgz#ae6fec16555f1a1d9fd2460b41256736d5044e13"
|
||||
integrity sha512-AsWztbBHhHid+w5g28ftXA0mTrS52Dup7FYI0GR7ri1TQTlVsw0z//FNlhIqWsgtBctO/DxQosacbElCpmdcZw==
|
||||
dependencies:
|
||||
b4a "^1.1.1"
|
||||
sodium-universal "^3.0.4"
|
||||
|
||||
sodium-universal@^3.0.0, sodium-universal@^3.0.4:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/sodium-universal/-/sodium-universal-3.1.0.tgz#f2fa0384d16b7cb99b1c8551a39cc05391a3ed41"
|
||||
integrity sha512-N2gxk68Kg2qZLSJ4h0NffEhp4BjgWHCHXVlDi1aG1hA3y+ZeWEmHqnpml8Hy47QzfL1xLy5nwr9LcsWAg2Ep0A==
|
||||
dependencies:
|
||||
blake2b "^2.1.1"
|
||||
chacha20-universal "^1.0.4"
|
||||
nanoassert "^2.0.0"
|
||||
resolve "^1.17.0"
|
||||
sha256-universal "^1.1.0"
|
||||
sha512-universal "^1.1.0"
|
||||
siphash24 "^1.0.1"
|
||||
sodium-javascript "~0.8.0"
|
||||
sodium-native "^3.2.0"
|
||||
xsalsa20 "^1.0.0"
|
||||
|
||||
statuses@2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63"
|
||||
@ -2418,14 +2110,6 @@ streamsearch@0.1.2:
|
||||
resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-0.1.2.tgz#808b9d0e56fc273d809ba57338e929919a1a9f1a"
|
||||
integrity sha512-jos8u++JKm0ARcSUTAZXOVC0mSox7Bhn6sBgty73P1f3JGf7yG2clTbBNHUdde/kdvP2FESam+vM6l8jBrNxHA==
|
||||
|
||||
streamx@^2.10.2, streamx@^2.10.3, streamx@^2.12.0, streamx@^2.12.4:
|
||||
version "2.12.5"
|
||||
resolved "https://registry.yarnpkg.com/streamx/-/streamx-2.12.5.tgz#485d6b6bf74df6f94bc1cc262e67392ed6862dc0"
|
||||
integrity sha512-Y+nkFw57Z5JHT3zLlqFm3GccOy2FeYdUrrqita6Dd8kr/8enPn9GKa8IYf3/DmEKfZl/E2sWoSKUnd4qhonrgg==
|
||||
dependencies:
|
||||
fast-fifo "^1.0.0"
|
||||
queue-tick "^1.0.0"
|
||||
|
||||
string.prototype.trimend@^1.0.6:
|
||||
version "1.0.6"
|
||||
resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz#c4a27fa026d979d79c04f17397f250a462944533"
|
||||
@ -2467,26 +2151,11 @@ supports-color@^5.5.0:
|
||||
dependencies:
|
||||
has-flag "^3.0.0"
|
||||
|
||||
supports-preserve-symlinks-flag@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09"
|
||||
integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==
|
||||
|
||||
symbol-observable@^1.0.4:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804"
|
||||
integrity sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==
|
||||
|
||||
time-ordered-set@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/time-ordered-set/-/time-ordered-set-1.0.2.tgz#3bd931fc048234147f8c2b8b1ebbebb0a3ecb96f"
|
||||
integrity sha512-vGO99JkxvgX+u+LtOKQEpYf31Kj3i/GNwVstfnh4dyINakMgeZCpew1e3Aj+06hEslhtHEd52g7m5IV+o1K8Mw==
|
||||
|
||||
timeout-refresh@^2.0.0:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/timeout-refresh/-/timeout-refresh-2.0.1.tgz#f8ec7cf1f9d93b2635b7d4388cb820c5f6c16f98"
|
||||
integrity sha512-SVqEcMZBsZF9mA78rjzCrYrUs37LMJk3ShZ851ygZYW1cMeIjs9mL57KO6Iv5mmjSQnOe/29/VAfGXo+oRCiVw==
|
||||
|
||||
to-regex-range@^5.0.1:
|
||||
version "5.0.1"
|
||||
resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4"
|
||||
@ -2588,17 +2257,6 @@ typescript@^4.9.3:
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.3.tgz#3aea307c1746b8c384435d8ac36b8a2e580d85db"
|
||||
integrity sha512-CIfGzTelbKNEnLpLdGFgdyKhG23CKdKgQPOBc+OUNrkJ2vr+KSzsSV5kq5iWhEQbok+quxgGzrAtGWCyU7tHnA==
|
||||
|
||||
udx-native@^1.2.0, udx-native@^1.5.1:
|
||||
version "1.5.1"
|
||||
resolved "https://registry.yarnpkg.com/udx-native/-/udx-native-1.5.1.tgz#aa71b7f2ee5cf3f738f2c59a64f3b2eeb4575337"
|
||||
integrity sha512-sqIHaQVgB1zVZ2vcSLo/yuErLK7eon6Y4/rwPTz4s7B4yLhqxP33nh/Pj+C4TOj4KxK01HMzdLveZMUbutcGdQ==
|
||||
dependencies:
|
||||
b4a "^1.5.0"
|
||||
events "^3.3.0"
|
||||
napi-macros "^2.0.0"
|
||||
node-gyp-build "^4.4.0"
|
||||
streamx "^2.12.0"
|
||||
|
||||
unbox-primitive@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.2.tgz#29032021057d5e6cdbd08c5129c226dff8ed6f9e"
|
||||
@ -2706,16 +2364,6 @@ wrappy@1:
|
||||
resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.9.tgz#54fa7db29f4c7cec68b1ddd3a89de099942bb591"
|
||||
integrity sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==
|
||||
|
||||
xache@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/xache/-/xache-1.1.0.tgz#afc20dec9ff8b2260eea03f5ad9422dc0200c6e9"
|
||||
integrity sha512-RQGZDHLy/uCvnIrAvaorZH/e6Dfrtxj16iVlGjkj4KD2/G/dNXNqhk5IdSucv5nSSnDK00y8Y/2csyRdHveJ+Q==
|
||||
|
||||
xsalsa20@^1.0.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/xsalsa20/-/xsalsa20-1.2.0.tgz#e5a05cb26f8cef723f94a559102ed50c1b44c25c"
|
||||
integrity sha512-FIr/DEeoHfj7ftfylnoFt3rAIRoWXpx2AoDfrT2qD2wtp7Dp+COajvs/Icb7uHqRW9m60f5iXZwdsJJO3kvb7w==
|
||||
|
||||
xss@^1.0.8:
|
||||
version "1.0.14"
|
||||
resolved "https://registry.yarnpkg.com/xss/-/xss-1.0.14.tgz#4f3efbde75ad0d82e9921cc3c95e6590dd336694"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user