{"version":3,"file":"usernotice.mjs","names":[],"sources":["../../../src/message/twitch-types/usernotice.ts"],"sourcesContent":["import type { TwitchBadgesList } from \"../badges\";\nimport type { Color } from \"../color\";\nimport type { TwitchEmoteList } from \"../emotes\";\nimport type { TwitchFlagList } from \"../flags\";\nimport type { IRCMessageTags } from \"../irc/tags\";\nimport type { SharedChatFields, SharedChatSource } from \"../shared-chat\";\nimport type { MessageSender } from \"./privmsg\";\nimport { ChannelIRCMessage, type Channel } from \"../irc/channel-irc-message\";\nimport { type IRCMessageData, getParameter } from \"../irc/irc-message\";\nimport {\n  tagParserFor,\n  convertToBoolean,\n  convertToInt,\n  convertToString,\n  requireData,\n} from \"../parser/tag-values\";\nimport { kebabToCamelCase } from \"~/utils/kebab-to-camel\";\n\nconst convertersMap: Record<\n  string,\n  (value: string) => string | boolean | number\n> = {\n  \"msg-param-cumulative-months\": convertToInt,\n  \"msg-param-gift-months\": convertToInt,\n  \"msg-param-sender-count\": convertToInt,\n  \"msg-param-months\": convertToInt,\n  \"msg-param-promo-gift-total\": convertToInt,\n  \"msg-param-should-share-streak\": convertToBoolean,\n  \"msg-param-streak-months\": convertToInt,\n  \"msg-param-viewerCount\": convertToInt,\n  \"msg-param-threshold\": convertToInt,\n  \"msg-param-mass-gift-count\": convertToInt,\n  \"msg-param-origin-id\": convertToString,\n  \"msg-param-sub-plan\": convertToString,\n  \"msg-param-color\": convertToString,\n  \"msg-param-copoReward\": convertToInt,\n  \"msg-param-value\": convertToInt,\n  \"msg-param-category\": convertToString,\n};\n\nexport function getCamelCasedName(tagKey: string): string {\n  let newKey = tagKey;\n\n  // remove the leading msg-param-\n  newKey = newKey.slice(10);\n\n  // camel case\n  newKey = kebabToCamelCase(newKey);\n\n  // To be consistent with the rest of the library,\n  // don't camelcase username as userName\n  newKey = newKey.replaceAll(/([Uu])serName/g, \"$1sername\");\n\n  return newKey;\n}\n\nexport type EventParameters = Record<string, string | number | boolean>;\nexport type EventParametersMaybe = Record<string, string | undefined>;\n\nexport function extractEventParameters(tags: IRCMessageTags): EventParameters {\n  const parameters: EventParameters = {};\n\n  // converts all msg-param-* tags into a new \"params\" object where keys are camelCased\n  // and boolean/integer tags are parsed (including a identically named \"Raw\" property).\n  // e.g. msg-param-should-share-streak would become\n  // shouldShareStreak: true\n  // shouldShareStreakRaw: '1'\n  for (const tagKey of Object.keys(tags)) {\n    if (!tagKey.startsWith(\"msg-param-\")) {\n      continue;\n    }\n\n    const newKey = getCamelCasedName(tagKey);\n    const converter = convertersMap[tagKey];\n    if (converter) {\n      parameters[newKey] = requireData(tags, tagKey, converter);\n      parameters[`${newKey}Raw`] = requireData(tags, tagKey, convertToString);\n    } else {\n      parameters[newKey] = requireData(tags, tagKey, convertToString);\n    }\n  }\n\n  return parameters;\n}\n\nexport interface SharesStreakSubParameters extends EventParameters {\n  shouldShareStreak: true;\n  streakMonths: number;\n  streakMonthsRaw: string;\n}\n\nexport interface HiddenStreakSubParameters extends EventParameters {\n  shouldShareStreak: false;\n  streakMonths: 0;\n  streakMonthsRaw: \"0\";\n}\n\nexport type StreakSubParameters =\n  | SharesStreakSubParameters\n  | HiddenStreakSubParameters;\n\n// sub, resub\nexport type SubEventParameters = EventParameters &\n  StreakSubParameters & {\n    cumulativeMonths: number;\n    cumulativeMonthsRaw: string;\n\n    subPlan: string;\n    subPlanName: string;\n  };\n\n// raid\nexport interface RaidParameters extends EventParameters {\n  displayName: string;\n  login: string;\n  viewerCount: number;\n  viewerCountRaw: string;\n}\n\n// subgift, anonsubgift\nexport interface SubgiftParameters extends EventParameters {\n  months: number;\n  monthsRaw: string;\n\n  recipientDisplayName: string;\n  recipientId: number;\n\n  recipientUsername: string;\n\n  subPlan: string;\n  subPlanName: string;\n}\nexport type AnonSubgiftParameters = SubgiftParameters;\n\n// massgift\nexport interface MassSubgiftParameters extends EventParameters {\n  massGiftCount: number;\n  subPlan: string;\n}\n\n// anongiftpaidupgrade\nexport type AnonGiftPaidUpgradeParameters = EventParameters & {\n  promoGiftTotal?: number;\n  promoGiftTotalRaw?: string;\n  promoName?: string;\n};\n\n// giftpaidupgrade\nexport type GiftPaidUpgradeParameters = AnonGiftPaidUpgradeParameters & {\n  senderLogin: string;\n  senderName: string;\n};\n\n// ritual\nexport interface RitualParameters extends EventParameters {\n  ritualName: string;\n}\n\n// bitsbadgetier\nexport interface BitsBadgeTierParameters extends EventParameters {\n  threshold: number;\n  thresholdRaw: string;\n}\n\n// announcement\nexport interface AnnouncementParameters extends EventParametersMaybe {\n  color?: string;\n}\n\n// viewermilestone\nexport interface ViewerMilestoneParameters extends EventParameters {\n  /** The amount of channel points the user gained for reaching this milestone. */\n  copoReward: number;\n  copoRewardRaw: string;\n\n  /** The value of the respective milestone category. (usually amount of viewed streams in a row, for \"watch-streak\") */\n  value: number;\n  valueRaw: string;\n\n  /** The category of the milestone. (usually \"watch-streak\") */\n  category: string;\n}\n\nexport interface SpecificUsernoticeMessage<\n  I extends string,\n  E extends EventParameters,\n> {\n  readonly messageTypeId: I;\n  readonly eventParams: E;\n}\n\nexport interface AnAnnouncementUsernoticeMessage<\n  I extends string,\n  E extends EventParametersMaybe,\n> {\n  readonly messageTypeId: I;\n  readonly eventParams: E;\n}\n\nexport type SubUsernoticeMessage = SpecificUsernoticeMessage<\n  \"sub\",\n  SubEventParameters\n>;\nexport type ResubUsernoticeMessage = SpecificUsernoticeMessage<\n  \"resub\",\n  SubEventParameters\n>;\nexport type RaidUsernoticeMessage = SpecificUsernoticeMessage<\n  \"raid\",\n  RaidParameters\n>;\nexport type SubgiftUsernoticeMessage = SpecificUsernoticeMessage<\n  \"subgift\",\n  SubgiftParameters\n>;\nexport type MassSubgiftUsernoticeMessage = SpecificUsernoticeMessage<\n  \"submysterygift\",\n  MassSubgiftParameters\n>;\nexport type AnonSubgiftUsernoticeMessage = SpecificUsernoticeMessage<\n  \"anonsubgift\",\n  AnonSubgiftParameters\n>;\nexport type AnonGiftPaidUpgradeUsernoticeMessage = SpecificUsernoticeMessage<\n  \"anongiftpaidupgrade\",\n  AnonGiftPaidUpgradeParameters\n>;\nexport type GiftPaidUpgradeUsernoticeMessage = SpecificUsernoticeMessage<\n  \"giftpaidupgrade\",\n  GiftPaidUpgradeParameters\n>;\nexport type RitualUsernoticeMessage = SpecificUsernoticeMessage<\n  \"ritual\",\n  RitualParameters\n>;\nexport type BitsBadgeTierUsernoticeMessage = SpecificUsernoticeMessage<\n  \"bitsbadgetier\",\n  BitsBadgeTierParameters\n>;\nexport type AnnouncementUsernoticeMessage = AnAnnouncementUsernoticeMessage<\n  \"announcement\",\n  AnnouncementParameters\n>;\nexport type ViewerMilestoneUsernoticeMessage = SpecificUsernoticeMessage<\n  \"viewermilestone\",\n  ViewerMilestoneParameters\n>;\n\ninterface CheerUsernoticeMessage extends UsernoticeMessage {\n  readonly bits: number;\n  readonly bitsRaw: string;\n}\n\nexport class UsernoticeMessage\n  extends ChannelIRCMessage\n  // eslint-disable-next-line ts/no-deprecated\n  implements Partial<SharedChatFields & { sourceMessageTypeId: string }>\n{\n  private readonly _channelRoomId: string;\n  private readonly _content: string | undefined;\n  private readonly _systemMessage: string;\n  private readonly _messageTypeId: string;\n  private readonly _messageType: string;\n  private readonly _senderLogin: string;\n  private readonly _senderId: string;\n  private readonly _badgeInfo: TwitchBadgesList;\n  private readonly _badgeInfoRaw: string;\n  private readonly _badges: TwitchBadgesList;\n  private readonly _badgesRaw: string;\n  private readonly _bits: number | undefined;\n  private readonly _bitsRaw: string | undefined;\n  private readonly _color: Color | undefined;\n  private readonly _colorRaw: string;\n  private readonly _displayName: string;\n  private readonly _emotes: TwitchEmoteList;\n  private readonly _emotesRaw: string;\n  private readonly _flags: TwitchFlagList | undefined;\n  private readonly _flagsRaw: string | undefined;\n  private readonly _id: string;\n  private readonly _isMod: boolean;\n  private readonly _isModRaw: string;\n  private readonly _timestamp: Date;\n  private readonly _timestampRaw: string;\n  private readonly _eventParams: EventParameters;\n  private readonly _sourceId: string | undefined;\n  private readonly _sourceChannelId: string | undefined;\n  private readonly _sourceBadges: TwitchBadgesList | undefined;\n  private readonly _sourceBadgesRaw: string | undefined;\n  private readonly _sourceBadgeInfo: TwitchBadgesList | undefined;\n  private readonly _sourceBadgeInfoRaw: string | undefined;\n  private readonly _sourceMessageTypeId: string | undefined;\n\n  public get content(): string | undefined {\n    return this._content;\n  }\n\n  public get systemMessage(): string {\n    return this._systemMessage;\n  }\n\n  /** sub, resub, subgift, etc..., or the uuid of the message if its a shared chat */\n  public get messageTypeId(): string {\n    return this._messageTypeId;\n  }\n\n  /** @deprecated Use {@link messageTypeId} instead. */\n  public get messageTypeID(): string {\n    return this._messageTypeId;\n  }\n\n  public get messageType(): string {\n    return this._messageType;\n  }\n\n  public get id(): string {\n    return this._id;\n  }\n\n  /**\n   * The timestamp of when the message was sent, as reported by Twitch.\n   * This is not necessarily the same as the time the message was received by your client.\n   */\n  public get timestamp(): Date {\n    return this._timestamp;\n  }\n\n  public get timestampRaw(): string {\n    return this._timestampRaw;\n  }\n\n  public get eventParams(): EventParameters {\n    return this._eventParams;\n  }\n\n  public get bits(): number | undefined {\n    return this._bits;\n  }\n\n  public get bitsRaw(): string | undefined {\n    return this._bitsRaw;\n  }\n\n  public get emotes(): TwitchEmoteList {\n    return this._emotes;\n  }\n\n  public get emotesRaw(): string {\n    return this._emotesRaw;\n  }\n\n  /**\n   * Can be an array of Twitch AutoMod flagged words, for use in moderation and/or filtering purposes.\n   *\n   * If the `flags` tag is missing or of a unparseable format, this will be `undefined`. This is unlike most other\n   * attributes which when missing or malformed will fail the message parsing. However since this attribute is\n   * completely undocumented we cannot rely on the `flags` tag being stable, so this soft fallback is used instead.\n   * While it will be a major version release if this attribute changes format in dank-twitch-irc, using this is still\n   * at your own risk since it may suddenly contain unexpected data or turn `undefined` one day as\n   * Twitch changes something. In short: **Use at your own risk** and make sure your\n   * implementation can handle the case where this is `undefined`.\n   */\n  public get flags(): TwitchFlagList | undefined {\n    return this._flags;\n  }\n\n  /**\n   * Twitch AutoMod raw flags string.\n   *\n   * If the `flags` tag is missing or of a unparseable format, this will be `undefined`. This is unlike most other\n   * attributes which when missing or malformed will fail the message parsing. However since this attribute is\n   * completely undocumented we cannot rely on the `flags` tag being stable, so this soft fallback is used instead.\n   * In short, ensure your implementation can handle the case where this is `undefined` or is in\n   * a format you don't expect.\n   */\n  public get flagsRaw(): string | undefined {\n    return this._flagsRaw;\n  }\n\n  public override get channel(): Channel & { readonly id: string } {\n    return {\n      login: this._channelLogin,\n      username: this._channelLogin,\n      id: this._channelRoomId,\n    };\n  }\n\n  public get sender(): MessageSender {\n    return {\n      login: this._senderLogin,\n      username: this._senderLogin,\n      id: this._senderId,\n      displayName: this._displayName,\n      color: this._color,\n      colorRaw: this._colorRaw,\n      badgeInfo: this._badgeInfo,\n      badgeInfoRaw: this._badgeInfoRaw,\n      badges: this._badges,\n      badgesRaw: this._badgesRaw,\n      isMod: this._isMod,\n      isModRaw: this._isModRaw,\n    };\n  }\n\n  public get source(): SharedChatSource | undefined {\n    if (this._sourceId == null) return undefined;\n    return {\n      id: this._sourceId,\n      channelId: this._sourceChannelId!,\n      badges: this._sourceBadges!,\n      badgesRaw: this._sourceBadgesRaw!,\n      badgeInfo: this._sourceBadgeInfo!,\n      badgeInfoRaw: this._sourceBadgeInfoRaw!,\n    };\n  }\n\n  public get sourceMessageTypeId(): string | undefined {\n    return this._sourceMessageTypeId;\n  }\n\n  // ---- Deprecated aliases ----\n\n  /** @deprecated Use {@link channel.id} instead. */\n  public get channelID(): string {\n    return this._channelRoomId;\n  }\n\n  /** @deprecated Use {@link content} instead. */\n  public get messageText(): string | undefined {\n    return this._content;\n  }\n\n  /** @deprecated Use {@link sender.login} instead. */\n  public get senderUsername(): string {\n    return this._senderLogin;\n  }\n\n  /** @deprecated Use {@link sender.id} instead. */\n  public get senderUserID(): string {\n    return this._senderId;\n  }\n\n  /** @deprecated Use {@link sender.id} instead. */\n  public get senderUserId(): string {\n    return this._senderId;\n  }\n\n  /** @deprecated Use {@link sender.badgeInfo} instead. */\n  public get badgeInfo(): TwitchBadgesList {\n    return this._badgeInfo;\n  }\n\n  /** @deprecated Use {@link sender.badgeInfoRaw} instead. */\n  public get badgeInfoRaw(): string {\n    return this._badgeInfoRaw;\n  }\n\n  /** @deprecated Use {@link sender.badges} instead. */\n  public get badges(): TwitchBadgesList {\n    return this._badges;\n  }\n\n  /** @deprecated Use {@link sender.badgesRaw} instead. */\n  public get badgesRaw(): string {\n    return this._badgesRaw;\n  }\n\n  /** @deprecated Use {@link sender.color} instead. */\n  public get color(): Color | undefined {\n    return this._color;\n  }\n\n  /** @deprecated Use {@link sender.colorRaw} instead. */\n  public get colorRaw(): string {\n    return this._colorRaw;\n  }\n\n  /** @deprecated Use {@link sender.displayName} instead. */\n  public get displayName(): string {\n    return this._displayName;\n  }\n\n  /** @deprecated Use {@link id} instead. */\n  public get messageID(): string {\n    return this._id;\n  }\n\n  /** @deprecated Use {@link id} instead. */\n  public get messageId(): string {\n    return this._id;\n  }\n\n  /** @deprecated Use {@link sender.isMod} instead. */\n  public get isMod(): boolean {\n    return this._isMod;\n  }\n\n  /** @deprecated Use {@link sender.isModRaw} instead. */\n  public get isModRaw(): string {\n    return this._isModRaw;\n  }\n\n  /** @deprecated Use {@link timestamp} instead. */\n  public get serverTimestamp(): Date {\n    return this._timestamp;\n  }\n\n  /** @deprecated Use {@link timestampRaw} instead. */\n  public get serverTimestampRaw(): string {\n    return this._timestampRaw;\n  }\n\n  /** @deprecated Use {@link source.id} instead. */\n  public get sourceID(): string | undefined {\n    return this._sourceId;\n  }\n\n  /** @deprecated Use {@link source.channelID} instead. */\n  public get sourceChannelID(): string | undefined {\n    return this._sourceChannelId;\n  }\n\n  /** @deprecated Use {@link source.badges} instead. */\n  public get sourceBadges(): TwitchBadgesList | undefined {\n    return this._sourceBadges;\n  }\n\n  /** @deprecated Use {@link source.badgesRaw} instead. */\n  public get sourceBadgesRaw(): string | undefined {\n    return this._sourceBadgesRaw;\n  }\n\n  /** @deprecated Use {@link source.badgeInfo} instead. */\n  public get sourceBadgesInfo(): TwitchBadgesList | undefined {\n    return this._sourceBadgeInfo;\n  }\n\n  /** @deprecated Use {@link source.badgeInfoRaw} instead. */\n  public get sourceBadgesInfoRaw(): string | undefined {\n    return this._sourceBadgeInfoRaw;\n  }\n\n  /** @deprecated Use {@link sourceMessageTypeId} instead. */\n  public get sourceMessageTypeID(): string | undefined {\n    return this._sourceMessageTypeId;\n  }\n\n  public constructor(message: IRCMessageData) {\n    super(message);\n\n    this._content = getParameter(this, 1);\n\n    const tagParser = tagParserFor(this.ircTags);\n    this._channelRoomId = tagParser.requireString(\"room-id\");\n\n    this._systemMessage = tagParser.requireString(\"system-msg\");\n\n    this._messageTypeId = tagParser.requireString(\"msg-id\");\n\n    this._senderLogin = tagParser.requireString(\"login\");\n\n    this._senderId = tagParser.requireString(\"user-id\");\n\n    this._badgeInfo = tagParser.requireBadges(\"badge-info\");\n    this._badgeInfoRaw = tagParser.requireString(\"badge-info\");\n\n    this._badges = tagParser.requireBadges(\"badges\");\n    this._badgesRaw = tagParser.requireString(\"badges\");\n\n    this._bits = tagParser.getInt(\"bits\");\n    this._bitsRaw = tagParser.getString(\"bits\");\n\n    this._color = tagParser.getColor(\"color\");\n    this._colorRaw = tagParser.requireString(\"color\");\n\n    // trim: Twitch workaround for unsanitized data, see https://github.com/robotty/dank-twitch-irc/issues/33\n    this._displayName = tagParser.requireString(\"display-name\").trim();\n\n    if (this._content) {\n      this._emotes = tagParser.requireEmotes(\"emotes\", this._content);\n      this._flags = tagParser.getFlags(\"flags\", this._content);\n    } else {\n      this._emotes = [];\n      this._flags = undefined;\n    }\n    this._emotesRaw = tagParser.requireString(\"emotes\");\n\n    this._flagsRaw = tagParser.getString(\"flags\");\n\n    this._id = tagParser.requireString(\"id\");\n\n    this._isMod = tagParser.requireBoolean(\"mod\");\n    this._isModRaw = tagParser.requireString(\"mod\");\n\n    this._timestamp = tagParser.requireTimestamp(\"tmi-sent-ts\");\n    this._timestampRaw = tagParser.requireString(\"tmi-sent-ts\");\n\n    this._eventParams = extractEventParameters(this.ircTags);\n\n    this._sourceId = tagParser.getString(\"source-id\");\n    this._sourceChannelId = tagParser.getString(\"source-room-id\");\n    this._sourceBadges = tagParser.getBadges(\"source-badges\");\n    this._sourceBadgesRaw = tagParser.getString(\"source-badges\");\n    this._sourceBadgeInfo = tagParser.getBadges(\"source-badge-info\");\n    this._sourceBadgeInfoRaw = tagParser.getString(\"source-badge-info\");\n    this._sourceMessageTypeId = tagParser.getString(\"source-msg-id\");\n\n    // when in shared chat, the message type is the source message type\n    this._messageType =\n      this._sourceMessageTypeId === \"sharedchatnotice\"\n        ? this._messageTypeId\n        : (this._sourceMessageTypeId ?? this._messageTypeId);\n  }\n\n  public isCheer(): this is CheerUsernoticeMessage {\n    return this._bits != null;\n  }\n\n  public isSub(): this is SubUsernoticeMessage {\n    return this._messageType === \"sub\";\n  }\n\n  public isResub(): this is ResubUsernoticeMessage {\n    return this._messageType === \"resub\";\n  }\n\n  public isRaid(): this is RaidUsernoticeMessage {\n    return this._messageType === \"raid\";\n  }\n\n  public isSubgift(): this is SubgiftUsernoticeMessage {\n    return this._messageType === \"subgift\";\n  }\n\n  public isMassSubgift(): this is MassSubgiftParameters {\n    return this._messageType === \"submysterygift\";\n  }\n\n  public isAnonSubgift(): this is AnonSubgiftUsernoticeMessage {\n    return this._messageType === \"anonsubgift\";\n  }\n\n  public isAnonGiftPaidUpgrade(): this is AnonGiftPaidUpgradeUsernoticeMessage {\n    return this._messageType === \"anongiftpaidupgrade\";\n  }\n\n  public isGiftPaidUpgrade(): this is GiftPaidUpgradeUsernoticeMessage {\n    return this._messageType === \"giftpaidupgrade\";\n  }\n\n  public isRitual(): this is RitualUsernoticeMessage {\n    return this._messageType === \"ritual\";\n  }\n\n  public isBitsBadgeTier(): this is BitsBadgeTierUsernoticeMessage {\n    return this._messageType === \"bitsbadgetier\";\n  }\n\n  public isAnnouncement(): this is AnnouncementUsernoticeMessage {\n    return this._messageType === \"announcement\";\n  }\n\n  public isViewerMilestone(): this is ViewerMilestoneUsernoticeMessage {\n    return this._messageType === \"viewermilestone\";\n  }\n\n  /**\n   * Whether or not this message is during a shared chat session.\n   * This does NOT necessarily mean that the message is originating from another channel.\n   * Check if `message.source.channelId !== message.channel.id` for that\n   * @see https://dev.twitch.tv/docs/chat/irc/#shared-chat\n   */\n  public isSharedChat(): this is this &\n    // eslint-disable-next-line ts/no-deprecated\n    SharedChatFields & { sourceMessageTypeId: string } {\n    return this._sourceId != null;\n  }\n}\n"],"mappings":"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"}