|
|
|
@@ -206,6 +206,12 @@ const {
|
|
|
|
|
buildDiscoveryListingExportJsonBody,
|
|
|
|
|
signDiscoveryListingExportJson,
|
|
|
|
|
verifyDiscoveryListingExportJson,
|
|
|
|
|
buildFederationSyncJsonBody,
|
|
|
|
|
signFederationSyncJson,
|
|
|
|
|
verifyFederationSyncJson,
|
|
|
|
|
buildMeshReplicationDiagnosticsJsonBody,
|
|
|
|
|
signMeshReplicationDiagnosticsJson,
|
|
|
|
|
verifyMeshReplicationDiagnosticsJson,
|
|
|
|
|
formatAutomationScheduleDigestExport,
|
|
|
|
|
mergeHookFailureDigests,
|
|
|
|
|
buildAutomationScheduleDashboard,
|
|
|
|
@@ -1821,6 +1827,12 @@ class PearcordPlatform extends EventEmitter {
|
|
|
|
|
const discoveryListingExportJsonHeal = await this._healDiscoveryListingExportCursorOnPartition(gid).catch(() => ({
|
|
|
|
|
relisted: 0
|
|
|
|
|
}))
|
|
|
|
|
const federationSyncJsonHeal = await this._healFederationSyncExportCursorOnPartition(gid).catch(() => ({
|
|
|
|
|
relisted: 0
|
|
|
|
|
}))
|
|
|
|
|
const meshReplicationDiagnosticsJsonHeal = await this._healMeshReplicationDiagnosticsCursorOnPartition(gid).catch(() => ({
|
|
|
|
|
relisted: 0
|
|
|
|
|
}))
|
|
|
|
|
return {
|
|
|
|
|
voiceApplied,
|
|
|
|
|
emojiSlots,
|
|
|
|
@@ -1885,7 +1897,9 @@ class PearcordPlatform extends EventEmitter {
|
|
|
|
|
sessionActivityJsonHeal,
|
|
|
|
|
avatarDecorationExportJsonHeal,
|
|
|
|
|
deviceSyncJsonHeal,
|
|
|
|
|
discoveryListingExportJsonHeal
|
|
|
|
|
discoveryListingExportJsonHeal,
|
|
|
|
|
federationSyncJsonHeal,
|
|
|
|
|
meshReplicationDiagnosticsJsonHeal
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -11230,6 +11244,12 @@ class PearcordPlatform extends EventEmitter {
|
|
|
|
|
guildInstance.on('discovery-listing-export-json-sync', (payload) => {
|
|
|
|
|
this._onDiscoveryListingExportJsonGossip(payload).catch(() => {})
|
|
|
|
|
})
|
|
|
|
|
guildInstance.on('federation-sync-json-sync', (payload) => {
|
|
|
|
|
this._onFederationSyncJsonGossip(payload).catch(() => {})
|
|
|
|
|
})
|
|
|
|
|
guildInstance.on('mesh-replication-diagnostics-json-sync', (payload) => {
|
|
|
|
|
this._onMeshReplicationDiagnosticsJsonGossip(payload).catch(() => {})
|
|
|
|
|
})
|
|
|
|
|
guildInstance.on('message-search-request', (payload) => {
|
|
|
|
|
this._onMessageSearchRequestGossip(payload).catch(() => {})
|
|
|
|
|
})
|
|
|
|
@@ -27064,6 +27084,216 @@ class PearcordPlatform extends EventEmitter {
|
|
|
|
|
return row
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async _federationSyncJsonRegistryEntries () {
|
|
|
|
|
const gid = this.guild?.guild?.id
|
|
|
|
|
if (!gid) return []
|
|
|
|
|
const diag = await this.exportFederationSyncDiagnostics().catch(() => null)
|
|
|
|
|
const agg = diag?.federationAggregate || this._federationSyncAggregateForView()
|
|
|
|
|
const entries = [{
|
|
|
|
|
federationId: gid,
|
|
|
|
|
guildCount: agg?.guildCount || 0,
|
|
|
|
|
discoveryPeers: agg?.discoveryPeers || 0,
|
|
|
|
|
syncingGuilds: agg?.syncingGuilds || 0,
|
|
|
|
|
hubSubs: diag?.announcementHub?.outboundSubscriptions || 0,
|
|
|
|
|
exportedAt: diag?.exportedAt || Date.now()
|
|
|
|
|
}]
|
|
|
|
|
return entries
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async _meshReplicationJsonRegistryEntries () {
|
|
|
|
|
const gid = this.guild?.guild?.id
|
|
|
|
|
if (!gid) return []
|
|
|
|
|
const diag = this.exportMeshReplicationDiagnostics(gid)
|
|
|
|
|
const entries = (diag.channelReplication || []).slice(0, 32).map((r) => ({
|
|
|
|
|
channelId: r.channelId,
|
|
|
|
|
replicationLagMs: r.replicationLagMs || 0,
|
|
|
|
|
wireRttMs: r.wireRttMs || 0,
|
|
|
|
|
sparseOffset: r.sparseOffset || 0,
|
|
|
|
|
exportedAt: diag.exportedAt || Date.now()
|
|
|
|
|
}))
|
|
|
|
|
if (!entries.length) {
|
|
|
|
|
entries.push({
|
|
|
|
|
channelId: 'mesh',
|
|
|
|
|
replicationLagMs: diag.maxReplicationLagMs || 0,
|
|
|
|
|
wireRttMs: 0,
|
|
|
|
|
sparseOffset: 0,
|
|
|
|
|
peerCount: diag.meshStability?.peerCount ?? this.guild?.peers?.size ?? 0,
|
|
|
|
|
exportedAt: diag.exportedAt || Date.now()
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
return entries
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async getFederationSyncJsonExport () {
|
|
|
|
|
const gid = this.guild?.guild?.id || null
|
|
|
|
|
const span = this.log.time('federation.json', { spanKind: 'federation.json', guildId: gid, context: 'read' })
|
|
|
|
|
try {
|
|
|
|
|
if (!this.guild?.guild) { span.end({ guildFederationJsonCount: 0, skipped: true }); return null }
|
|
|
|
|
await this._initDeliveryReceipts(this.guild.guild.id)
|
|
|
|
|
const row = await this.deliveryReceipts.getFederationSyncJsonExport()
|
|
|
|
|
if (!row?.signature) {
|
|
|
|
|
span.end({ guildFederationJsonCount: row ? 1 : 0, hasSignature: false, bridgeKind: 'federation.json' })
|
|
|
|
|
return row
|
|
|
|
|
}
|
|
|
|
|
const verified = verifyFederationSyncJson(exportBodyFromSlice(row) || row.jsonBody, row.signature, { guildId: this.guild.guild.id, relaySecret: this.guild.guild.id })
|
|
|
|
|
const out = { ...row, signatureValid: verified.ok, federationCount: row.federationCount || 0 }
|
|
|
|
|
span.end({ guildFederationJsonCount: 1, hasSignature: true, signatureValid: verified.ok, bridgeKind: 'federation.json' })
|
|
|
|
|
return out
|
|
|
|
|
} catch (err) {
|
|
|
|
|
this.log.error('federation.json error', { guildId: gid, context: 'read', error: err?.message || String(err) })
|
|
|
|
|
span.fail(err); throw err
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async exportFederationSyncJson (opts = {}) {
|
|
|
|
|
if (!this.guild?.guild) throw new Error('no guild')
|
|
|
|
|
const roles = await this._memberRoles()
|
|
|
|
|
if (!roleHasPermission(roles, PERMISSION.MANAGE_GUILD)) throw new Error('no permission to export federation sync JSON')
|
|
|
|
|
const entries = await this._federationSyncJsonRegistryEntries()
|
|
|
|
|
const jsonBody = buildFederationSyncJsonBody(entries)
|
|
|
|
|
const signed = signFederationSyncJson(jsonBody, { guildId: this.guild.guild.id, relaySecret: this.guild.guild.id })
|
|
|
|
|
const exportedAt = Date.now()
|
|
|
|
|
const meta = { guildId: this.guild.guild.id, exportedAt, federationCount: entries.length, signed: !!signed.signature, meshPushed: false }
|
|
|
|
|
this._lastFederationSyncExport = meta
|
|
|
|
|
if (opts.recordMesh !== false) {
|
|
|
|
|
await this._initDeliveryReceipts(this.guild.guild.id)
|
|
|
|
|
await this.deliveryReceipts.recordFederationSyncJsonExport({ jsonBody: signed.jsonBody || signed.json, signature: signed.signature, signatureAlg: signed.signatureAlg, exportedAt, federationCount: entries.length })
|
|
|
|
|
}
|
|
|
|
|
return { format: 'json', body: signed.json, signature: signed.signature, signatureAlg: signed.signatureAlg, exportedAt, federationCount: entries.length, meta }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async pushFederationSyncJsonToMesh () {
|
|
|
|
|
const gid = this.guild?.guild?.id || null
|
|
|
|
|
const span = this.log.time('federation.json', { spanKind: 'federation.json', guildId: gid, context: 'mesh.push' })
|
|
|
|
|
try {
|
|
|
|
|
const exported = await this.exportFederationSyncJson({ recordMesh: false })
|
|
|
|
|
if (!exported.signature) throw new Error('federation sync json export not signed')
|
|
|
|
|
const payload = { guildId: this.guild.guild.id, exportedAt: exported.exportedAt || Date.now(), exportedBy: this.identity.user?.id || null, jsonBody: exported.body, signature: exported.signature, signatureAlg: exported.signatureAlg, federationCount: exported.federationCount || 0 }
|
|
|
|
|
if (this.guild.gossipFederationSyncJsonSync) this.guild.gossipFederationSyncJsonSync(payload)
|
|
|
|
|
this.emit('federation-sync-json-sync', payload)
|
|
|
|
|
await this._initDeliveryReceipts(this.guild.guild.id)
|
|
|
|
|
await this.deliveryReceipts.recordFederationSyncJsonExport({ jsonBody: exported.body, signature: exported.signature, signatureAlg: exported.signatureAlg, exportedAt: exported.exportedAt, federationCount: exported.federationCount })
|
|
|
|
|
this._lastFederationSyncExport = { ...exported.meta, meshPushed: true }
|
|
|
|
|
span.end({ guildFederationJsonCount: exported.federationCount || 0, meshPushed: true, bridgeKind: 'federation.json' })
|
|
|
|
|
return exported
|
|
|
|
|
} catch (err) {
|
|
|
|
|
this.log.error('federation.json error', { guildId: gid, context: 'mesh.push', error: err?.message || String(err) })
|
|
|
|
|
span.fail(err); throw err
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async clearFederationSyncJsonExports () {
|
|
|
|
|
if (!this.guild?.guild) throw new Error('no guild')
|
|
|
|
|
if (!(await this._hasPerm(PERMISSION.MANAGE_GUILD))) throw new Error('no permission to clear federation sync JSON exports')
|
|
|
|
|
await this._initDeliveryReceipts(this.guild.guild.id)
|
|
|
|
|
const removed = await this.deliveryReceipts.clearFederationSyncJsonExports()
|
|
|
|
|
this.emit('federation-sync-json-cleared', { removed })
|
|
|
|
|
return { removed }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async getLastFederationSyncExport () {
|
|
|
|
|
if (!this.guild?.guild) return null
|
|
|
|
|
const snap = this._lastFederationSyncExport
|
|
|
|
|
if (snap?.guildId === this.guild.guild.id) return snap
|
|
|
|
|
return { guildId: this.guild.guild.id, exportedAt: Date.now(), federationCount: 0, signed: false, meshPushed: false }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async getMeshReplicationDiagnosticsJsonExport () {
|
|
|
|
|
const gid = this.guild?.guild?.id || null
|
|
|
|
|
const span = this.log.time('mesh.json', { spanKind: 'mesh.json', guildId: gid, context: 'read' })
|
|
|
|
|
try {
|
|
|
|
|
if (!this.guild?.guild) { span.end({ guildMeshJsonCount: 0, skipped: true }); return null }
|
|
|
|
|
await this._initDeliveryReceipts(this.guild.guild.id)
|
|
|
|
|
const row = await this.deliveryReceipts.getMeshReplicationDiagnosticsJsonExport()
|
|
|
|
|
if (!row?.signature) {
|
|
|
|
|
span.end({ guildMeshJsonCount: row ? 1 : 0, hasSignature: false, bridgeKind: 'mesh.json' })
|
|
|
|
|
return row
|
|
|
|
|
}
|
|
|
|
|
const verified = verifyMeshReplicationDiagnosticsJson(exportBodyFromSlice(row) || row.jsonBody, row.signature, { guildId: this.guild.guild.id, relaySecret: this.guild.guild.id })
|
|
|
|
|
const out = { ...row, signatureValid: verified.ok, replicationCount: row.replicationCount || 0 }
|
|
|
|
|
span.end({ guildMeshJsonCount: 1, hasSignature: true, signatureValid: verified.ok, bridgeKind: 'mesh.json' })
|
|
|
|
|
return out
|
|
|
|
|
} catch (err) {
|
|
|
|
|
this.log.error('mesh.json error', { guildId: gid, context: 'read', error: err?.message || String(err) })
|
|
|
|
|
span.fail(err); throw err
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async exportMeshReplicationDiagnosticsJson (opts = {}) {
|
|
|
|
|
if (!this.guild?.guild) throw new Error('no guild')
|
|
|
|
|
const roles = await this._memberRoles()
|
|
|
|
|
if (!roleHasPermission(roles, PERMISSION.MANAGE_GUILD)) throw new Error('no permission to export mesh replication diagnostics JSON')
|
|
|
|
|
const entries = await this._meshReplicationJsonRegistryEntries()
|
|
|
|
|
const jsonBody = buildMeshReplicationDiagnosticsJsonBody(entries)
|
|
|
|
|
const signed = signMeshReplicationDiagnosticsJson(jsonBody, { guildId: this.guild.guild.id, relaySecret: this.guild.guild.id })
|
|
|
|
|
const exportedAt = Date.now()
|
|
|
|
|
const meta = { guildId: this.guild.guild.id, exportedAt, replicationCount: entries.length, signed: !!signed.signature, meshPushed: false }
|
|
|
|
|
this._lastMeshReplicationExport = meta
|
|
|
|
|
if (opts.recordMesh !== false) {
|
|
|
|
|
await this._initDeliveryReceipts(this.guild.guild.id)
|
|
|
|
|
await this.deliveryReceipts.recordMeshReplicationDiagnosticsJsonExport({ jsonBody: signed.jsonBody || signed.json, signature: signed.signature, signatureAlg: signed.signatureAlg, exportedAt, replicationCount: entries.length })
|
|
|
|
|
}
|
|
|
|
|
return { format: 'json', body: signed.json, signature: signed.signature, signatureAlg: signed.signatureAlg, exportedAt, replicationCount: entries.length, meta }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async pushMeshReplicationDiagnosticsJsonToMesh () {
|
|
|
|
|
const gid = this.guild?.guild?.id || null
|
|
|
|
|
const span = this.log.time('mesh.json', { spanKind: 'mesh.json', guildId: gid, context: 'mesh.push' })
|
|
|
|
|
try {
|
|
|
|
|
const exported = await this.exportMeshReplicationDiagnosticsJson({ recordMesh: false })
|
|
|
|
|
if (!exported.signature) throw new Error('mesh replication diagnostics json not signed')
|
|
|
|
|
const payload = { guildId: this.guild.guild.id, exportedAt: exported.exportedAt || Date.now(), exportedBy: this.identity.user?.id || null, jsonBody: exported.body, signature: exported.signature, signatureAlg: exported.signatureAlg, replicationCount: exported.replicationCount || 0 }
|
|
|
|
|
if (this.guild.gossipMeshReplicationDiagnosticsJsonSync) this.guild.gossipMeshReplicationDiagnosticsJsonSync(payload)
|
|
|
|
|
this.emit('mesh-replication-diagnostics-json-sync', payload)
|
|
|
|
|
await this._initDeliveryReceipts(this.guild.guild.id)
|
|
|
|
|
await this.deliveryReceipts.recordMeshReplicationDiagnosticsJsonExport({ jsonBody: exported.body, signature: exported.signature, signatureAlg: exported.signatureAlg, exportedAt: exported.exportedAt, replicationCount: exported.replicationCount })
|
|
|
|
|
this._lastMeshReplicationExport = { ...exported.meta, meshPushed: true }
|
|
|
|
|
span.end({ guildMeshJsonCount: exported.replicationCount || 0, meshPushed: true, bridgeKind: 'mesh.json' })
|
|
|
|
|
return exported
|
|
|
|
|
} catch (err) {
|
|
|
|
|
this.log.error('mesh.json error', { guildId: gid, context: 'mesh.push', error: err?.message || String(err) })
|
|
|
|
|
span.fail(err); throw err
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async clearMeshReplicationDiagnosticsJsonExports () {
|
|
|
|
|
if (!this.guild?.guild) throw new Error('no guild')
|
|
|
|
|
if (!(await this._hasPerm(PERMISSION.MANAGE_GUILD))) throw new Error('no permission to clear mesh replication diagnostics JSON exports')
|
|
|
|
|
await this._initDeliveryReceipts(this.guild.guild.id)
|
|
|
|
|
const removed = await this.deliveryReceipts.clearMeshReplicationDiagnosticsJsonExports()
|
|
|
|
|
this.emit('mesh-replication-diagnostics-json-cleared', { removed })
|
|
|
|
|
return { removed }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async getLastMeshReplicationExport () {
|
|
|
|
|
if (!this.guild?.guild) return null
|
|
|
|
|
const snap = this._lastMeshReplicationExport
|
|
|
|
|
if (snap?.guildId === this.guild.guild.id) return snap
|
|
|
|
|
return { guildId: this.guild.guild.id, exportedAt: Date.now(), replicationCount: 0, signed: false, meshPushed: false }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async _onFederationSyncJsonGossip (payload) {
|
|
|
|
|
if (!payload?.guildId || !payload?.jsonBody || !payload?.signature) return null
|
|
|
|
|
if (this.guild?.guild?.id !== payload.guildId) return null
|
|
|
|
|
await this._initDeliveryReceipts(payload.guildId)
|
|
|
|
|
this._shouldGossipFederationSyncRegistryJson(payload)
|
|
|
|
|
const row = await this.deliveryReceipts.ingestFederationSyncJsonSlice(payload.guildId, payload)
|
|
|
|
|
if (row?.duplicate) this._federationSyncJsonDuplicateAt = row.exportedAt || payload.exportedAt || null
|
|
|
|
|
if (row) this.emit('federation-sync-json-sync', payload)
|
|
|
|
|
return row
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async _onMeshReplicationDiagnosticsJsonGossip (payload) {
|
|
|
|
|
if (!payload?.guildId || !payload?.jsonBody || !payload?.signature) return null
|
|
|
|
|
if (this.guild?.guild?.id !== payload.guildId) return null
|
|
|
|
|
await this._initDeliveryReceipts(payload.guildId)
|
|
|
|
|
this._shouldGossipMeshReplicationRegistryJson(payload)
|
|
|
|
|
const row = await this.deliveryReceipts.ingestMeshReplicationDiagnosticsJsonSlice(payload.guildId, payload)
|
|
|
|
|
if (row?.duplicate) this._meshReplicationDiagnosticsJsonDuplicateAt = row.exportedAt || payload.exportedAt || null
|
|
|
|
|
if (row) this.emit('mesh-replication-diagnostics-json-sync', payload)
|
|
|
|
|
return row
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async getAuditExportSchedule () {
|
|
|
|
|
if (!this.guild?.guild) {
|
|
|
|
@@ -32009,6 +32239,14 @@ class PearcordPlatform extends EventEmitter {
|
|
|
|
|
let deviceSyncJsonRows = []
|
|
|
|
|
let discoveryListingExportJsonRows = []
|
|
|
|
|
let lastDiscoveryListingExport = null
|
|
|
|
|
let federationSyncJsonMeta = null
|
|
|
|
|
let federationSyncJsonRows = []
|
|
|
|
|
let lastFederationSyncExport = null
|
|
|
|
|
let meshReplicationDiagnosticsJsonMeta = null
|
|
|
|
|
let meshReplicationDiagnosticsJsonRows = []
|
|
|
|
|
let lastMeshReplicationExport = null
|
|
|
|
|
let guildFederationSyncEntries = []
|
|
|
|
|
let guildMeshReplicationChannels = []
|
|
|
|
|
let guildPairedDevices = []
|
|
|
|
|
let guildDiscoveryListings = []
|
|
|
|
|
let lastComplianceSnapshot = null
|
|
|
|
@@ -32293,6 +32531,34 @@ class PearcordPlatform extends EventEmitter {
|
|
|
|
|
return { ...row, signatureValid: verified.ok }
|
|
|
|
|
})
|
|
|
|
|
lastDiscoveryListingExport = await this.getLastDiscoveryListingExport()
|
|
|
|
|
federationSyncJsonMeta = await this.getFederationSyncJsonExport().catch(() => null)
|
|
|
|
|
federationSyncJsonRows = (await this.deliveryReceipts.listFederationSyncJsonExports(32)).map((row) => {
|
|
|
|
|
if (!row?.signature || !guild?.id) return row
|
|
|
|
|
const verified = verifyFederationSyncJson(exportBodyFromSlice(row) || row.jsonBody, row.signature, { guildId: guild.id, relaySecret: guild.id })
|
|
|
|
|
return { ...row, signatureValid: verified.ok }
|
|
|
|
|
})
|
|
|
|
|
lastFederationSyncExport = await this.getLastFederationSyncExport()
|
|
|
|
|
meshReplicationDiagnosticsJsonMeta = await this.getMeshReplicationDiagnosticsJsonExport().catch(() => null)
|
|
|
|
|
meshReplicationDiagnosticsJsonRows = (await this.deliveryReceipts.listMeshReplicationDiagnosticsJsonExports(32)).map((row) => {
|
|
|
|
|
if (!row?.signature || !guild?.id) return row
|
|
|
|
|
const verified = verifyMeshReplicationDiagnosticsJson(exportBodyFromSlice(row) || row.jsonBody, row.signature, { guildId: guild.id, relaySecret: guild.id })
|
|
|
|
|
return { ...row, signatureValid: verified.ok }
|
|
|
|
|
})
|
|
|
|
|
lastMeshReplicationExport = await this.getLastMeshReplicationExport()
|
|
|
|
|
const fedEntries = await this._federationSyncJsonRegistryEntries().catch(() => [])
|
|
|
|
|
guildFederationSyncEntries = fedEntries.slice(0, 16).map((r) => ({
|
|
|
|
|
id: r.federationId || guild.id,
|
|
|
|
|
name: `Federation (${r.guildCount || 0} guilds)`,
|
|
|
|
|
role: (r.syncingGuilds || 0) > 0 ? 'syncing' : 'idle',
|
|
|
|
|
updatedAt: r.exportedAt || Date.now()
|
|
|
|
|
}))
|
|
|
|
|
const meshEntries = await this._meshReplicationJsonRegistryEntries().catch(() => [])
|
|
|
|
|
guildMeshReplicationChannels = meshEntries.slice(0, 16).map((r) => ({
|
|
|
|
|
id: r.channelId || 'mesh',
|
|
|
|
|
name: r.channelId === 'mesh' ? 'Mesh aggregate' : `Channel ${String(r.channelId).slice(0, 8)}`,
|
|
|
|
|
role: (r.replicationLagMs || 0) > 5000 ? 'lagging' : 'ok',
|
|
|
|
|
updatedAt: r.exportedAt || Date.now()
|
|
|
|
|
}))
|
|
|
|
|
if (this.deviceSync) {
|
|
|
|
|
guildPairedDevices = (await this.deviceSync.listDevices().catch(() => [])).slice(0, 16).map((d) => ({
|
|
|
|
|
id: d.id,
|
|
|
|
@@ -32974,12 +33240,24 @@ class PearcordPlatform extends EventEmitter {
|
|
|
|
|
deviceSyncJsonRows,
|
|
|
|
|
discoveryListingExportJsonRows,
|
|
|
|
|
lastDiscoveryListingExport,
|
|
|
|
|
federationSyncJsonMeta,
|
|
|
|
|
federationSyncJsonRows,
|
|
|
|
|
lastFederationSyncExport,
|
|
|
|
|
meshReplicationDiagnosticsJsonMeta,
|
|
|
|
|
meshReplicationDiagnosticsJsonRows,
|
|
|
|
|
lastMeshReplicationExport,
|
|
|
|
|
guildFederationSyncEntries,
|
|
|
|
|
guildMeshReplicationChannels,
|
|
|
|
|
guildPairedDevices,
|
|
|
|
|
guildDiscoveryListings,
|
|
|
|
|
guildDeviceJsonCount:
|
|
|
|
|
(deviceSyncJsonRows || []).length + (guildPairedDevices || []).length,
|
|
|
|
|
guildDiscoveryJsonCount:
|
|
|
|
|
(discoveryListingExportJsonRows || []).length + (guildDiscoveryListings || []).length,
|
|
|
|
|
guildFederationJsonCount:
|
|
|
|
|
(federationSyncJsonRows || []).length + (guildFederationSyncEntries || []).length,
|
|
|
|
|
guildMeshJsonCount:
|
|
|
|
|
(meshReplicationDiagnosticsJsonRows || []).length + (guildMeshReplicationChannels || []).length,
|
|
|
|
|
automationScheduleDashboard,
|
|
|
|
|
automationHealthDashboard,
|
|
|
|
|
automationDigestNotifyPrefs,
|
|
|
|
@@ -33605,6 +33883,8 @@ const { activityJsonMixin } = require('./activity-json-mixin')
|
|
|
|
|
const { sessionJsonMixin } = require('./session-json-mixin')
|
|
|
|
|
const { deviceJsonMixin } = require('./device-json-mixin')
|
|
|
|
|
const { discoveryJsonMixin } = require('./discovery-json-mixin')
|
|
|
|
|
const { federationJsonMixin } = require('./federation-json-mixin')
|
|
|
|
|
const { meshJsonMixin } = require('./mesh-json-mixin')
|
|
|
|
|
Object.assign(PearcordPlatform.prototype, pollSchedulingMixin)
|
|
|
|
|
Object.assign(PearcordPlatform.prototype, notificationsActivityMixin)
|
|
|
|
|
Object.assign(PearcordPlatform.prototype, userSettingsMixin)
|
|
|
|
@@ -33646,3 +33926,5 @@ Object.assign(PearcordPlatform.prototype, activityJsonMixin)
|
|
|
|
|
Object.assign(PearcordPlatform.prototype, sessionJsonMixin)
|
|
|
|
|
Object.assign(PearcordPlatform.prototype, deviceJsonMixin)
|
|
|
|
|
Object.assign(PearcordPlatform.prototype, discoveryJsonMixin)
|
|
|
|
|
Object.assign(PearcordPlatform.prototype, federationJsonMixin)
|
|
|
|
|
Object.assign(PearcordPlatform.prototype, meshJsonMixin)
|
|
|
|
|