OverviewFilesCommitsIssuesDocsReleasesPeers

keet-cli / keet-core-4.14.4-pretty / lib / api / v1 / encode.js

514 lines · javascript ref:
const e = require("hypercore-id-encoding"),
  {
    getCapabilitiesForRole: t,
    MemberRoles: n,
    DISPLAY_TYPES: a,
    GENERIC_EVENTS: s,
  } = require("@holepunchto/keet-core-api"),
  r = require("b4a"),
  {
    contract: {
      hyperschema: { getEnum: i },
    },
  } = require("../../../schema/spec"),
  o = i("@keet/room-type")
function d({ key: t, seq: n }) {
  return { deviceId: e.encode(t), seq: n }
}
function l(t) {
  return {
    id: e.encode(t.key),
    deviceId: e.encode(t.key),
    swarmId: e.encode(t.profile.swarmKey),
    isMobile: t.profile.isMobile,
    name: t.profile.name,
    status: t.status,
  }
}
function c(t) {
  if (!t) return null
  const { key: n, blob: a } = t
  return { id: e.encode(n), blob: a }
}
function m(t) {
  if (!t) return null
  const { key: n, path: a, version: s, size: r } = t
  return { id: e.encode(n), path: a, version: s, size: r }
}
function u(e) {
  if (!e) return null
  const { inlined: t, blob: n, externalBlob: a, externalDrive: s } = e
  return {
    blob: n,
    inlined: t ? r.toString(t, "base64") : null,
    externalBlob: c(a),
    externalDrive: m(s),
  }
}
function p(e) {
  return e
    ? (e.metadata?.userdata && (e.metadata.userdata = r.toString(e.metadata.userdata, "base64")),
      {
        hash: e.hash,
        entry: e.entry,
        metadata: e.metadata,
        pointer: u(e.pointer),
        preview: g(e.preview),
      })
    : null
}
function y(t) {
  return t
    ? t.cleared
      ? { cleared: !0 }
      : {
          roomId: e.encode(t.roomKey),
          httpLink: t.httpLink,
          cleared: !1,
          preview: t.preview
            ? { small: y(t.preview.small), medium: y(t.preview.medium), large: y(t.preview.large) }
            : null,
        }
    : null
}
function g(e) {
  return e ? { small: p(e.small), medium: p(e.medium), large: p(e.large) } : null
}
function f(t) {
  if (!t) return null
  const { memberJoined: n, memberLeft: a, memberRemoved: s } = t,
    r = n?.memberKey || a?.memberKey || s?.memberKey,
    i = r ? { memberId: e.encode(r) } : null
  return { ...t, memberJoined: n && i, memberLeft: a && i, memberRemoved: s && i }
}
function b({ record: t, member: n, memberId: r, localRoom: i }) {
  const { event: o, message: l, reactions: c = {}, labels: m = {} } = t,
    u = f(o)
  l && l.replyTo && (l.replyTo = d(l.replyTo))
  let y = null
  ;(u && u.memberJoined && (y = { type: s.MEMBER_JOINED, value: u.memberJoined.memberId }),
    u && u.memberLeft && (y = { type: s.MEMBER_LEFT, value: u.memberLeft.memberId }),
    u && u.titleChanged && (y = { type: s.ROOM_TITLE_CHANGED, value: u.titleChanged }),
    u && u.callStarted && (y = { type: s.CALL_STARTED, value: null }),
    u && u.callHangup && (y = { type: s.CALL_HANGUP, value: null }),
    u && u.callMissed && (y = { type: s.CALL_MISSED, value: null }))
  const g = j(t)
  return (
    l && l.files && (l.files = l.files.map(p)),
    {
      timestamp: t.timestamp,
      editedAt: t.editedAt,
      memberId: r || e.encode(n?.key || t.oplog.key),
      member: n ? M(n, i?.selfMember?.key) : null,
      id: d(t.oplog),
      deleted: t.status.isDeleted,
      thread: t.id.thread,
      clock: t.id.index,
      message: { ...l, generic: u },
      reactions: c,
      labels: m,
      read: t.read,
      seq: t.id.index,
      event: y,
      replyTo: l && l.replyTo ? l.replyTo : null,
      forwarded: !0 === l?.forwarded,
      chat: {
        text: l ? l.text : null,
        edited: t.status.isEdited,
        display: g,
        mentions: g.filter((e) => e.type === a.MENTION),
      },
      files: l && l.files ? l.files : [],
      file: l && l.files ? l.files[0] : null,
    }
  )
}
function v(e) {
  return e
    ? {
        total: e.total,
        reactions: e.reactions.map((e) => ({ text: e.text, count: e.count, latest: [] })),
        editedAt: e.editedAt,
      }
    : { total: 0, reactions: [] }
}
function I(e) {
  return e.map((e) => e.reaction)
}
function k(t) {
  return { sender: e.encode(t.sender), clock: t.clock, reaction: t.reaction }
}
function K(t) {
  return {
    roomId: e.encode(t.roomKey),
    discoveryId: e.encode(t.discoveryKey),
    dmMemberId: t.dm ? e.encode(t.dm) : null,
    recipient: t.dm ? e.encode(t.dm) : null,
  }
}
function h({ roomInfo: t, preferences: n, lastMessageMember: a, storageInfo: s, fileStats: r }) {
  const i = t.dm?.length ? e.encode(t.dm[0]) : null
  let o = null
  return (
    t.lastMessage && (o = { chat: b({ record: t.lastMessage, memberId: a?.memberId }), member: a }),
    {
      roomId: e.encode(t.roomKey),
      discoveryId: e.encode(t.discoveryKey),
      status: t.status,
      stats: t.stats,
      fork: t.fork,
      self: {
        sentLength: s ? s.hints.remoteContiguousLength : 0,
        deviceId: t.selfDevice ? e.encode(t.selfDevice.key) : null,
        member: t.selfMember ? M(t.selfMember, t.selfMember.key) : null,
      },
      digest: T(t.digest),
      config: C(t.config, t.digest),
      preferences: n,
      lastMessage: o,
      dmMemberId: i,
      fileStats: r ? { total: r.total } : null,
      activeCall: A(t.activeCall),
    }
  )
}
function A(t) {
  return t
    ? {
        callId: e.encode(t.callKey),
        selfDeviceId: t.selfDeviceKey ? e.encode(t.selfDeviceKey) : null,
      }
    : null
}
function M(t, n) {
  return t
    ? {
        memberId: e.encode(t.key),
        anonymous: !1,
        name: t.profile.displayName ? t.profile.displayName.toLowerCase() : null,
        status: t.status,
        displayName: t.profile.displayName,
        inactive: !t.status.isActive,
        capabilities: Y(t.status),
        avatar: g(t.profile.avatar),
        local: !!n && r.equals(t.key, n),
        pushNotifications: !0,
        username: t.profile.username,
        canDM: !!t.profile.mailbox,
      }
    : null
}
function R(t) {
  return {
    id: { memberId: e.encode(t.memberKey), roomId: e.encode(t.keys.key) },
    roomId: e.encode(t.keys.key),
    senderContactInfo: {
      displayName: t.sender.displayName,
      avatar: t.sender.avatar ? g(t.sender.avatar) : null,
      memberId: e.encode(t.memberKey),
    },
    clock: t.clock,
    message: t.message,
    status: t.status,
    sentAt: t.sentAt,
  }
}
function D(t) {
  const n = e.encode(t.id)
  return {
    id: n,
    seedId: e.encode(t.invitationSeed),
    discoveryId: n,
    identityDeviceId: t.identity ? e.encode(t.identity.devicePublicKey) : null,
    expires: -1,
  }
}
function E(t) {
  if (!t) return null
  const n = t.request,
    a = n.deviceKey,
    s = n.device.profile.name,
    r = n.identity.devicePublicKey
  return { deviceName: s, deviceId: e.encode(a), identityDeviceId: e.encode(r) }
}
function T(e) {
  return { ...e }
}
function L(t) {
  return t ? t.map(e.encode) : null
}
function N(e) {
  return { disableReadReceipts: e?.disableReadReceipts || !1 }
}
function w(e) {
  return {
    concurrency: e.concurrency,
    maxWindow: e.maxWindow,
    randomPunchInterval: e.randomPunchInterval,
    connectionKeepAlive: e.connectionKeepAlive,
  }
}
function C(e, t, n = []) {
  return e
    ? {
        ...e,
        avatar: g(e.avatar),
        roomType: V(t.settings.roomType),
        experimental: t.settings.isExperimental,
        locked: t.settings.isJoiningDisabled,
        frozen: t.settings.isAppendingDisabled,
        isMembershipEventsDisabled: t.settings.isMembershipEventsDisabled,
        pinnedMessages: n,
        canCall: String(!t.settings.isCallingDisabled),
        blindPeers: L(e.blindPeers),
      }
    : {}
}
function x(t) {
  return t
    ? {
        memberId: e.encode(t.attestation.memberKey),
        displayName: t.profile.displayName,
        username: t.profile.username,
        avatar: g(t.profile.avatar),
        contactInfo: r.toString(t.contactInfo, "base64"),
        count: t.count,
      }
    : null
}
function S(t) {
  return t ? { username: t.username, memberId: t.memberKey ? e.encode(t.memberKey) : null } : null
}
function B(t, n, a, s) {
  let r = null
  return (
    a &&
      (r = {
        id: e.encode(a.roomKey),
        status: {
          isAccepted: !!a && 0 === a.stats.members.pending,
          isWritable: !!a && a.status.isWritable,
        },
      }),
    {
      memberId: t,
      activeRoom: r,
      pendingRequest: s ? R(s) : null,
      contactStatus: { isBlocked: !!n?.status?.isBlocked },
    }
  )
}
function O(t) {
  return t ? { roomId: t.roomKey ? e.encode(t.roomKey) : null } : {}
}
function P(t) {
  return {
    code: t.code,
    message: t.message,
    stack: t.stack,
    timestamp: t.timestamp,
    isContractError: !0 === t.isContractError,
    isKeetError: !0 === t.isKeetError,
    roomId: t.roomKey ? e.encode(t.roomKey) : null,
    details: O(t.details),
  }
}
function _(e, t, n) {
  const a = n?.displayName || ""
  return {
    id: e.messageId,
    roomId: e.roomId,
    avatar: e.avatar ?? "",
    sender: { name: a },
    config: { title: t.title, roomType: t.roomType },
    message: {
      type: e.messageType,
      chatText: e.messageText,
      fileType: e.fileType,
      location: e.location,
    },
    userInfo: {
      roomKey: e.roomId,
      messageType: e.messageType,
      isDmRoom: Q(t.roomType) === o.DirectMessage,
      isBroadcast: Q(t.roomType) === o.Broadcast,
      profileName: a,
    },
  }
}
function q(t) {
  if (!t) return null
  const n = 1 === t.version
  return {
    version: t.version,
    callId: e.encode(t.callKey),
    discoveryId: n ? e.encode(t.discoveryKey) : null,
    createdAt: t.createdAt,
    endedAt: t.endedAt,
    members: t.members ? t.members.map(H) : [],
  }
}
function H(t) {
  return {
    callId: e.encode(t.callKey),
    memberId: e.encode(t.memberKey),
    createdAt: t.createdAt,
    devices: t.devices ? t.devices.map(J) : [],
  }
}
function J(t) {
  return {
    callId: e.encode(t.callKey),
    memberId: e.encode(t.memberKey),
    deviceId: e.encode(t.deviceKey),
    swarmId: e.encode(t.swarmKey),
    createdAt: t.createdAt,
    streams: t.streams ? t.streams.map(F) : [],
  }
}
function F(t) {
  return {
    callId: e.encode(t.callKey),
    streamId: e.encode(t.streamKey),
    deviceId: e.encode(t.deviceKey),
    createdAt: t.createdAt,
  }
}
function j(e) {
  if (!e?.message?.display) return []
  let t = []
  return (
    e.message.display.mention &&
      ((e.message.display.mention = G(e.message.display.mention)),
      (t = t.concat(e.message.display.mention))),
    e.message.display.translation &&
      ((e.message.display.translation = U(e.message.display.translation)),
      (t = t.concat(e.message.display.translation))),
    e.message.display.httpLink &&
      ((e.message.display.httpLink = e.message.display.httpLink.map(z)),
      (t = t.concat(e.message.display.httpLink))),
    e.message.display.pearLink &&
      ((e.message.display.pearLink = e.message.display.pearLink.map(W)),
      (t = t.concat(e.message.display.pearLink))),
    e.message.display.bold &&
      ((e.message.display.bold = e.message.display.bold.map((e) => ({ ...e, type: a.BOLD }))),
      (t = t.concat(e.message.display.bold))),
    e.message.display.italic &&
      ((e.message.display.italic = e.message.display.italic.map((e) => ({ ...e, type: a.ITALIC }))),
      (t = t.concat(e.message.display.italic))),
    e.message.display.code &&
      ((e.message.display.code = e.message.display.code.map((e) => ({ ...e, type: a.CODE }))),
      (t = t.concat(e.message.display.code))),
    e.message.display.emoji &&
      ((e.message.display.emoji = e.message.display.emoji.map((e) => ({
        ...e.range,
        content: e.content,
        type: a.EMOJI,
      }))),
      (t = t.concat(e.message.display.emoji))),
    e.message.display.codeBlock &&
      ((e.message.display.codeBlock = e.message.display.codeBlock.map((e) => ({
        ...e,
        type: a.CODE_BLOCK,
      }))),
      (t = t.concat(e.message.display.codeBlock))),
    e.message.display.strike &&
      ((e.message.display.strike = e.message.display.strike.map((e) => ({
        ...e,
        type: a.STRIKE_THROUGH,
      }))),
      (t = t.concat(e.message.display.strike))),
    t
  )
}
function G(t) {
  return Array.isArray(t)
    ? t.map((t) => ({
        type: a.MENTION,
        start: t.range.start,
        length: t.range.length,
        memberId: e.encode(t.memberKey),
      }))
    : []
}
function U(e) {
  return Array.isArray(e)
    ? e.map((e) => ({
        type: a.TRANSLATION,
        start: e.range.start,
        length: e.range.length,
        language: e.language,
        text: e.text,
      }))
    : []
}
function W(e) {
  return { ...z(e), type: a.PEAR_LINK }
}
function z(e) {
  return (
    e?.preview?.file && (e.preview.file = p(e.preview.file)),
    {
      content: e.url,
      start: e.range.start,
      length: e.range.length,
      type: a.HTTP_LINK,
      preview: e.preview,
    }
  )
}
function Y(e) {
  const a = e.isAdmin ? n.ADMIN : e.isModerator ? n.MODERATOR : n.PEER
  return t(a)
}
function V(e) {
  switch (e) {
    case o.Default:
      return "0"
    case o.Broadcast:
      return "1"
    case o.DirectMessage:
      return "2"
    default:
      throw new Error("Incompatible legacy room type:", e)
  }
}
function Q(e) {
  switch (e) {
    case "0":
    default:
      return o.Default
    case "1":
      return o.Broadcast
    case "2":
      return o.DirectMessage
  }
}
module.exports = {
  encodeReaction: k,
  encodeIdentityPairingRequest: E,
  encodePrivateRoomRecord: K,
  encodeDmRequest: R,
  encodeRoomRecord: h,
  encodeMemberRecord: M,
  encodeInvitationRecord: D,
  encodeChatMessage: b,
  encodeImageFile: g,
  encodeFile: p,
  encodeFileEntry: y,
  encodeReactionsDigest: v,
  encodeMyReactions: I,
  encodeDigest: T,
  encodeConfig: C,
  encodeUserSettings: N,
  encodeMessageId: d,
  encodeDevice: l,
  encodeUser: x,
  encodeContactInfo: B,
  encodeReservation: S,
  encodeErrorRecord: P,
  encodeNotification: _,
  encodeHyperDHTSettings: w,
  encodeCallRecord: q,
}