From 02405b935a426ac55a58424b24668ab1dbd3fb0d Mon Sep 17 00:00:00 2001 From: pajlada Date: Fri, 7 Feb 2025 20:57:07 +0100 Subject: [PATCH] refactor(eventsub): use `snake_case` transform by default (#5916) --- CHANGELOG.md | 2 +- .../ast/lib/comment_commands.py | 79 +++++++++++++++---- lib/twitch-eventsub-ws/ast/lib/enum.py | 18 +---- .../ast/lib/enum_constant.py | 37 +++------ lib/twitch-eventsub-ws/ast/lib/member.py | 40 +++------- lib/twitch-eventsub-ws/ast/lib/struct.py | 18 +---- lib/twitch-eventsub-ws/ast/lib/walker.py | 12 ++- .../twitch-eventsub-ws/messages/metadata.hpp | 1 - .../payloads/channel-ban-v1.hpp | 1 - .../payloads/channel-chat-message-v1.hpp | 9 --- .../payloads/channel-chat-notification-v1.hpp | 20 ----- .../payloads/channel-moderate-v2.hpp | 18 ----- .../payloads/channel-update-v1.hpp | 1 - .../payloads/stream-offline-v1.hpp | 1 - .../payloads/stream-online-v1.hpp | 1 - .../payloads/subscription.hpp | 2 - 16 files changed, 97 insertions(+), 163 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 690680ba..8506f238 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,7 +21,7 @@ - Bugfix: Fixed the reply button showing for inline whispers and announcements. (#5863) - Bugfix: Fixed suspicious user treatment update messages not being searchable. (#5865) - Bugfix: Ensure miniaudio backend exits even if it doesn't exit cleanly. (#5896) -- Dev: Add initial experimental EventSub support. (#5837, #5895, #5897, #5904, #5910, #5903, #5915) +- Dev: Add initial experimental EventSub support. (#5837, #5895, #5897, #5904, #5910, #5903, #5915, #5916) - Dev: Highlight checks now use non-capturing groups for the boundaries. (#5784) - Dev: Removed unused PubSub whisper code. (#5898) - Dev: Updated Conan dependencies. (#5776) diff --git a/lib/twitch-eventsub-ws/ast/lib/comment_commands.py b/lib/twitch-eventsub-ws/ast/lib/comment_commands.py index ecd92d5b..390e59f1 100644 --- a/lib/twitch-eventsub-ws/ast/lib/comment_commands.py +++ b/lib/twitch-eventsub-ws/ast/lib/comment_commands.py @@ -1,31 +1,78 @@ -from typing import List, Tuple +from typing import Optional import logging import re -CommentCommands = List[Tuple[str, str]] - log = logging.getLogger(__name__) -def parse_comment_commands(raw_comment: str) -> CommentCommands: - comment_commands: CommentCommands = [] +class CommentCommands: + # Transform the key from whatever-case + # By default, all keys are transformed into snake_case + # e.g. `userID` transforms to `user_id` + name_transform: str = "snake_case" - def clean_comment_line(line: str) -> str: - return line.replace("/", "").replace("*", "").strip() + # Whether the key should completely change its name + # If set, `name_transform` will do nothing + name_change: Optional[str] = None - comment_lines = [line for line in map(clean_comment_line, raw_comment.splitlines()) if line != ""] + # Don't fail when an optional object exists and its data is bad + dont_fail_on_deserialization: bool = False - for comment in comment_lines: - parts = comment.split("=", 2) - if len(parts) != 2: - continue + # Deserialization hint, current use-cases can be replaced with + # https://github.com/Chatterino/chatterino2/issues/5912 + tag: Optional[str] = None - command = parts[0].strip() - value = parts[1].strip() - comment_commands.append((command, value)) + inner_root: str = "" - return comment_commands + def __init__(self, parent: Optional["CommentCommands"] = None) -> None: + if parent is not None: + self.name_transform = parent.name_transform + self.name_change = parent.name_change + self.dont_fail_on_deserialization = parent.dont_fail_on_deserialization + self.tag = parent.tag + self.inner_root = parent.inner_root + + def parse(self, raw_comment: str) -> None: + def clean_comment_line(line: str) -> str: + return line.replace("/", "").replace("*", "").strip() + + comment_lines = [line for line in map(clean_comment_line, raw_comment.splitlines()) if line != ""] + + for comment in comment_lines: + parts = comment.split("=", 2) + if len(parts) != 2: + continue + + command = parts[0].strip() + value = parts[1].strip() + + match command: + case "json_rename": + self.name_change = value + case "json_dont_fail_on_deserialization": + self.dont_fail_on_deserialization = bool(value.lower() == "true") + case "json_transform": + self.name_transform = value + case "json_inner": + self.inner_root = value + pass + case "json_tag": + self.tag = value + case other: + log.warning(f"Unknown comment command found: {other} with value {value}") + + def apply_name_transform(self, input_json_name: str) -> str: + if self.name_change is not None: + return self.name_change + + match self.name_transform: + case "snake_case": + return re.sub(r"(?", input_json_name).lower() + + case other: + log.warning(f"Unknown transformation '{other}', ignoring") + return input_json_name def json_transform(input_str: str, transformation: str) -> str: diff --git a/lib/twitch-eventsub-ws/ast/lib/enum.py b/lib/twitch-eventsub-ws/ast/lib/enum.py index 9f017d88..56ab4dee 100644 --- a/lib/twitch-eventsub-ws/ast/lib/enum.py +++ b/lib/twitch-eventsub-ws/ast/lib/enum.py @@ -17,7 +17,7 @@ class Enum: self.name = name self.constants: List[EnumConstant] = [] self.parent: str = "" - self.comment_commands: CommentCommands = [] + self.comment_commands = CommentCommands() self.inner_root: str = "" self.namespace = namespace @@ -47,18 +47,4 @@ class Enum: return env.get_template("enum-definition.tmpl").render(enum=self) def apply_comment_commands(self, comment_commands: CommentCommands) -> None: - for command, value in comment_commands: - match command: - case "json_rename": - # Do nothing on enums - pass - case "json_dont_fail_on_deserialization": - # Do nothing on enums - pass - case "json_transform": - # Do nothing on enums - pass - case "json_inner": - self.inner_root = value - case other: - log.warning(f"Unknown comment command found: {other} with value {value}") + self.inner_root = comment_commands.inner_root diff --git a/lib/twitch-eventsub-ws/ast/lib/enum_constant.py b/lib/twitch-eventsub-ws/ast/lib/enum_constant.py index ddf74922..f23a3248 100644 --- a/lib/twitch-eventsub-ws/ast/lib/enum_constant.py +++ b/lib/twitch-eventsub-ws/ast/lib/enum_constant.py @@ -6,7 +6,7 @@ import logging import clang.cindex -from .comment_commands import CommentCommands, json_transform, parse_comment_commands +from .comment_commands import CommentCommands log = logging.getLogger(__name__) @@ -23,31 +23,15 @@ class EnumConstant: self.dont_fail_on_deserialization: bool = False def apply_comment_commands(self, comment_commands: CommentCommands) -> None: - for command, value in comment_commands: - match command: - case "json_rename": - # Rename the key that this field will use in json terms - log.debug(f"Rename json key from {self.json_name} to {value}") - self.json_name = value - case "json_dont_fail_on_deserialization": - # Don't fail when an optional object exists and its data is bad - log.debug(f"Don't fail on deserialization for {self.name}") - self.dont_fail_on_deserialization = bool(value.lower() == "true") - case "json_transform": - # Transform the key from whatever-case to case specified by `value` - self.json_name = json_transform(self.json_name, value) - case "json_inner": - # Do nothing on members - pass - case "json_tag": - # Rename the key that this field will use in json terms - log.debug(f"Applied json tag on {self.json_name}: {value}") - self.tag = value - case other: - log.warning(f"Unknown comment command found: {other} with value {value}") + self.json_name = comment_commands.apply_name_transform(self.json_name) + self.tag = comment_commands.tag + self.dont_fail_on_deserialization = comment_commands.dont_fail_on_deserialization @staticmethod - def from_node(node: clang.cindex.Cursor) -> EnumConstant: + def from_node( + node: clang.cindex.Cursor, + comment_commands: CommentCommands, + ) -> EnumConstant: assert node.type is not None name = node.spelling @@ -55,8 +39,9 @@ class EnumConstant: enum = EnumConstant(name) if node.raw_comment is not None: - comment_commands = parse_comment_commands(node.raw_comment) - enum.apply_comment_commands(comment_commands) + comment_commands.parse(node.raw_comment) + + enum.apply_comment_commands(comment_commands) return enum diff --git a/lib/twitch-eventsub-ws/ast/lib/member.py b/lib/twitch-eventsub-ws/ast/lib/member.py index 5c11c8a2..f32fcc2e 100644 --- a/lib/twitch-eventsub-ws/ast/lib/member.py +++ b/lib/twitch-eventsub-ws/ast/lib/member.py @@ -1,13 +1,13 @@ from __future__ import annotations -from typing import Optional, List +from typing import Optional import logging import clang.cindex from clang.cindex import CursorKind -from .comment_commands import CommentCommands, json_transform, parse_comment_commands +from .comment_commands import CommentCommands from .membertype import MemberType log = logging.getLogger(__name__) @@ -72,31 +72,16 @@ class Member: self.dont_fail_on_deserialization: bool = False def apply_comment_commands(self, comment_commands: CommentCommands) -> None: - for command, value in comment_commands: - match command: - case "json_rename": - # Rename the key that this field will use in json terms - log.debug(f"Rename json key from {self.json_name} to {value}") - self.json_name = value - case "json_dont_fail_on_deserialization": - # Don't fail when an optional object exists and its data is bad - log.debug(f"Don't fail on deserialization for {self.name}") - self.dont_fail_on_deserialization = bool(value.lower() == "true") - case "json_transform": - # Transform the key from whatever-case to case specified by `value` - self.json_name = json_transform(self.json_name, value) - case "json_inner": - # Do nothing on members - pass - case "json_tag": - # Rename the key that this field will use in json terms - log.debug(f"Applied json tag on {self.json_name}: {value}") - self.tag = value - case other: - log.warning(f"Unknown comment command found: {other} with value {value}") + self.json_name = comment_commands.apply_name_transform(self.json_name) + self.tag = comment_commands.tag + self.dont_fail_on_deserialization = comment_commands.dont_fail_on_deserialization @staticmethod - def from_field(node: clang.cindex.Cursor, namespace: tuple[str, ...]) -> Member: + def from_field( + node: clang.cindex.Cursor, + comment_commands: CommentCommands, + namespace: tuple[str, ...], + ) -> Member: assert node.type is not None name = node.spelling @@ -155,8 +140,9 @@ class Member: member = Member(name, member_type, type_name, _is_trivially_copyable(node.type)) if node.raw_comment is not None: - comment_commands = parse_comment_commands(node.raw_comment) - member.apply_comment_commands(comment_commands) + comment_commands.parse(node.raw_comment) + + member.apply_comment_commands(comment_commands) return member diff --git a/lib/twitch-eventsub-ws/ast/lib/struct.py b/lib/twitch-eventsub-ws/ast/lib/struct.py index da95c1b3..ba6ec397 100644 --- a/lib/twitch-eventsub-ws/ast/lib/struct.py +++ b/lib/twitch-eventsub-ws/ast/lib/struct.py @@ -17,7 +17,7 @@ class Struct: self.name = name self.members: List[Member] = [] self.parent: str = "" - self.comment_commands: CommentCommands = [] + self.comment_commands = CommentCommands() self.inner_root: str = "" self.namespace = namespace @@ -47,18 +47,4 @@ class Struct: return env.get_template("struct-definition.tmpl").render(struct=self) def apply_comment_commands(self, comment_commands: CommentCommands) -> None: - for command, value in comment_commands: - match command: - case "json_rename": - # Do nothing on structs - pass - case "json_dont_fail_on_deserialization": - # Do nothing on structs - pass - case "json_transform": - # Do nothing on structs - pass - case "json_inner": - self.inner_root = value - case other: - log.warning(f"Unknown comment command found: {other} with value {value}") + self.inner_root = comment_commands.inner_root diff --git a/lib/twitch-eventsub-ws/ast/lib/walker.py b/lib/twitch-eventsub-ws/ast/lib/walker.py index ee9e9143..5d316fbe 100644 --- a/lib/twitch-eventsub-ws/ast/lib/walker.py +++ b/lib/twitch-eventsub-ws/ast/lib/walker.py @@ -6,7 +6,7 @@ import os import clang.cindex from clang.cindex import CursorKind -from .comment_commands import parse_comment_commands +from .comment_commands import CommentCommands from .member import Member from .enum_constant import EnumConstant from .struct import Struct @@ -28,7 +28,7 @@ class Walker: case CursorKind.STRUCT_DECL: new_struct = Struct(node.spelling, self.namespace) if node.raw_comment is not None: - new_struct.comment_commands = parse_comment_commands(node.raw_comment) + new_struct.comment_commands.parse(node.raw_comment) new_struct.apply_comment_commands(new_struct.comment_commands) if struct is not None: new_struct.parent = struct.full_name @@ -43,7 +43,7 @@ class Walker: case CursorKind.ENUM_DECL: new_enum = Enum(node.spelling, self.namespace) if node.raw_comment is not None: - new_enum.comment_commands = parse_comment_commands(node.raw_comment) + new_enum.comment_commands.parse(node.raw_comment) new_enum.apply_comment_commands(new_enum.comment_commands) if struct is not None: new_enum.parent = struct.full_name @@ -60,8 +60,7 @@ class Walker: # log.warning( # f"enum constant decl {node.spelling} - enum comments: {enum.comment_commands} - node comments: {node.raw_comment}" # ) - constant = EnumConstant.from_node(node) - constant.apply_comment_commands(enum.comment_commands) + constant = EnumConstant.from_node(node, CommentCommands(enum.comment_commands)) enum.constants.append(constant) case CursorKind.FIELD_DECL: @@ -72,8 +71,7 @@ class Walker: # log.debug(f"{struct}: {type.spelling} {node.spelling} ({type.kind})") if struct: - member = Member.from_field(node, self.namespace) - member.apply_comment_commands(struct.comment_commands) + member = Member.from_field(node, CommentCommands(struct.comment_commands), self.namespace) struct.members.append(member) case CursorKind.NAMESPACE: diff --git a/lib/twitch-eventsub-ws/include/twitch-eventsub-ws/messages/metadata.hpp b/lib/twitch-eventsub-ws/include/twitch-eventsub-ws/messages/metadata.hpp index 73918899..7bd93272 100644 --- a/lib/twitch-eventsub-ws/include/twitch-eventsub-ws/messages/metadata.hpp +++ b/lib/twitch-eventsub-ws/include/twitch-eventsub-ws/messages/metadata.hpp @@ -20,7 +20,6 @@ namespace chatterino::eventsub::lib::messages { } */ -/// json_transform=snake_case struct Metadata { const std::string messageID; const std::string messageType; diff --git a/lib/twitch-eventsub-ws/include/twitch-eventsub-ws/payloads/channel-ban-v1.hpp b/lib/twitch-eventsub-ws/include/twitch-eventsub-ws/payloads/channel-ban-v1.hpp index 71f58e33..ed367942 100644 --- a/lib/twitch-eventsub-ws/include/twitch-eventsub-ws/payloads/channel-ban-v1.hpp +++ b/lib/twitch-eventsub-ws/include/twitch-eventsub-ws/payloads/channel-ban-v1.hpp @@ -47,7 +47,6 @@ namespace chatterino::eventsub::lib::payload::channel_ban::v1 { } */ -/// json_transform=snake_case struct Event { // User ID (e.g. 117166826) of the user who's channel the event took place in std::string broadcasterUserID; diff --git a/lib/twitch-eventsub-ws/include/twitch-eventsub-ws/payloads/channel-chat-message-v1.hpp b/lib/twitch-eventsub-ws/include/twitch-eventsub-ws/payloads/channel-chat-message-v1.hpp index 34a8465e..d775eb38 100644 --- a/lib/twitch-eventsub-ws/include/twitch-eventsub-ws/payloads/channel-chat-message-v1.hpp +++ b/lib/twitch-eventsub-ws/include/twitch-eventsub-ws/payloads/channel-chat-message-v1.hpp @@ -54,21 +54,18 @@ namespace chatterino::eventsub::lib::payload::channel_chat_message::v1 { -/// json_transform=snake_case struct Badge { std::string setID; std::string id; std::string info; }; -/// json_transform=snake_case struct Cheermote { std::string prefix; int bits; int tier; }; -/// json_transform=snake_case struct Emote { std::string id; std::string emoteSetID; @@ -76,14 +73,12 @@ struct Emote { std::vector format; }; -/// json_transform=snake_case struct Mention { std::string userID; std::string userName; std::string userLogin; }; -/// json_transform=snake_case struct MessageFragment { std::string type; std::string text; @@ -92,18 +87,15 @@ struct MessageFragment { std::optional mention; }; -/// json_transform=snake_case struct Message { std::string text; std::vector fragments; }; -/// json_transform=snake_case struct Cheer { int bits; }; -/// json_transform=snake_case struct Reply { std::string parentMessageID; std::string parentUserID; @@ -117,7 +109,6 @@ struct Reply { std::string threadUserName; }; -/// json_transform=snake_case struct Event { // Broadcaster of the channel the message was sent in std::string broadcasterUserID; diff --git a/lib/twitch-eventsub-ws/include/twitch-eventsub-ws/payloads/channel-chat-notification-v1.hpp b/lib/twitch-eventsub-ws/include/twitch-eventsub-ws/payloads/channel-chat-notification-v1.hpp index 37134bd0..7ab29a79 100644 --- a/lib/twitch-eventsub-ws/include/twitch-eventsub-ws/payloads/channel-chat-notification-v1.hpp +++ b/lib/twitch-eventsub-ws/include/twitch-eventsub-ws/payloads/channel-chat-notification-v1.hpp @@ -10,21 +10,18 @@ namespace chatterino::eventsub::lib::payload::channel_chat_notification::v1 { -/// json_transform=snake_case struct Badge { std::string setID; std::string id; std::string info; }; -/// json_transform=snake_case struct Cheermote { std::string prefix; int bits; int tier; }; -/// json_transform=snake_case struct Emote { std::string id; std::string emoteSetID; @@ -32,14 +29,12 @@ struct Emote { std::vector format; }; -/// json_transform=snake_case struct Mention { std::string userID; std::string userName; std::string userLogin; }; -/// json_transform=snake_case struct MessageFragment { std::string type; std::string text; @@ -48,14 +43,12 @@ struct MessageFragment { std::optional mention; }; -/// json_transform=snake_case struct Subcription { std::string subTier; bool isPrime; int durationMonths; }; -/// json_transform=snake_case struct Resubscription { int cumulativeMonths; int durationMonths; @@ -69,7 +62,6 @@ struct Resubscription { std::optional gifterUserLogin; }; -/// json_transform=snake_case struct GiftSubscription { int durationMonths; std::optional cumulativeTotal; @@ -81,7 +73,6 @@ struct GiftSubscription { std::optional communityGiftID; }; -/// json_transform=snake_case struct CommunityGiftSubscription { std::string id; int total; @@ -89,7 +80,6 @@ struct CommunityGiftSubscription { std::optional cumulativeTotal; }; -/// json_transform=snake_case struct GiftPaidUpgrade { bool gifterIsAnonymous; std::optional gifterUserID; @@ -97,12 +87,10 @@ struct GiftPaidUpgrade { std::optional gifterUserLogin; }; -/// json_transform=snake_case struct PrimePaidUpgrade { std::string subTier; }; -/// json_transform=snake_case struct Raid { std::string userID; std::string userName; @@ -111,11 +99,9 @@ struct Raid { std::string profileImageURL; }; -/// json_transform=snake_case struct Unraid { }; -/// json_transform=snake_case struct PayItForward { bool gifterIsAnonymous; std::optional gifterUserID; @@ -123,36 +109,30 @@ struct PayItForward { std::optional gifterUserLogin; }; -/// json_transform=snake_case struct Announcement { std::string color; }; -/// json_transform=snake_case struct CharityDonationAmount { int value; int decimalPlaces; std::string currency; }; -/// json_transform=snake_case struct CharityDonation { std::string charityName; CharityDonationAmount amount; }; -/// json_transform=snake_case struct BitsBadgeTier { int tier; }; -/// json_transform=snake_case struct Message { std::string text; std::vector fragments; }; -/// json_transform=snake_case struct Event { std::string broadcasterUserID; std::string broadcasterUserLogin; diff --git a/lib/twitch-eventsub-ws/include/twitch-eventsub-ws/payloads/channel-moderate-v2.hpp b/lib/twitch-eventsub-ws/include/twitch-eventsub-ws/payloads/channel-moderate-v2.hpp index cccbb3f4..a587f579 100644 --- a/lib/twitch-eventsub-ws/include/twitch-eventsub-ws/payloads/channel-moderate-v2.hpp +++ b/lib/twitch-eventsub-ws/include/twitch-eventsub-ws/payloads/channel-moderate-v2.hpp @@ -21,7 +21,6 @@ namespace chatterino::eventsub::lib::payload::channel_moderate::v2 { {"subscription":{"id":"86d99e53-2837-40cf-bc6e-c6e00698919c","status":"enabled","type":"channel.moderate","version":"2","condition":{"broadcaster_user_id":"11148817","moderator_user_id":"117166826"},"transport":{"method":"websocket","session_id":"AgoQZgfnyKxXQ32hpzCWF4aCGBIGY2VsbC1j"},"created_at":"2025-02-01T12:02:16.005321321Z","cost":0},"event":{"broadcaster_user_id":"11148817","broadcaster_user_login":"pajlada","broadcaster_user_name":"pajlada","source_broadcaster_user_id":null,"source_broadcaster_user_login":null,"source_broadcaster_user_name":null,"moderator_user_id":"11148817","moderator_user_login":"pajlada","moderator_user_name":"pajlada","action":"followers","followers":{"follow_duration_minutes":10080},"slow":null,"vip":null,"unvip":null,"mod":null,"unmod":null,"ban":null,"unban":null,"timeout":null,"untimeout":null,"raid":null,"unraid":null,"delete":null,"automod_terms":null,"unban_request":null,"warn":null,"shared_chat_ban":null,"shared_chat_unban":null,"shared_chat_timeout":null,"shared_chat_untimeout":null,"shared_chat_delete":null}} */ -/// json_transform=snake_case struct Followers { int followDurationMinutes; }; @@ -34,7 +33,6 @@ struct Followers { {"subscription":{"id":"86d99e53-2837-40cf-bc6e-c6e00698919c","status":"enabled","type":"channel.moderate","version":"2","condition":{"broadcaster_user_id":"11148817","moderator_user_id":"117166826"},"transport":{"method":"websocket","session_id":"AgoQZgfnyKxXQ32hpzCWF4aCGBIGY2VsbC1j"},"created_at":"2025-02-01T12:02:16.005321321Z","cost":0},"event":{"broadcaster_user_id":"11148817","broadcaster_user_login":"pajlada","broadcaster_user_name":"pajlada","source_broadcaster_user_id":null,"source_broadcaster_user_login":null,"source_broadcaster_user_name":null,"moderator_user_id":"11148817","moderator_user_login":"pajlada","moderator_user_name":"pajlada","action":"slowoff","followers":null,"slow":null,"vip":null,"unvip":null,"mod":null,"unmod":null,"ban":null,"unban":null,"timeout":null,"untimeout":null,"raid":null,"unraid":null,"delete":null,"automod_terms":null,"unban_request":null,"warn":null,"shared_chat_ban":null,"shared_chat_unban":null,"shared_chat_timeout":null,"shared_chat_untimeout":null,"shared_chat_delete":null}} */ -/// json_transform=snake_case struct Slow { int waitTimeSeconds; }; @@ -97,7 +95,6 @@ struct Slow { } */ -/// json_transform=snake_case struct Vip { String userID; String userLogin; @@ -108,7 +105,6 @@ struct Vip { {"subscription":{"id":"86d99e53-2837-40cf-bc6e-c6e00698919c","status":"enabled","type":"channel.moderate","version":"2","condition":{"broadcaster_user_id":"11148817","moderator_user_id":"117166826"},"transport":{"method":"websocket","session_id":"AgoQZgfnyKxXQ32hpzCWF4aCGBIGY2VsbC1j"},"created_at":"2025-02-01T12:02:16.005321321Z","cost":0},"event":{"broadcaster_user_id":"11148817","broadcaster_user_login":"pajlada","broadcaster_user_name":"pajlada","source_broadcaster_user_id":null,"source_broadcaster_user_login":null,"source_broadcaster_user_name":null,"moderator_user_id":"11148817","moderator_user_login":"pajlada","moderator_user_name":"pajlada","action":"unvip","followers":null,"slow":null,"vip":null,"unvip":{"user_id":"159849156","user_login":"bajlada","user_name":"BajLada"},"mod":null,"unmod":null,"ban":null,"unban":null,"timeout":null,"untimeout":null,"raid":null,"unraid":null,"delete":null,"automod_terms":null,"unban_request":null,"warn":null,"shared_chat_ban":null,"shared_chat_unban":null,"shared_chat_timeout":null,"shared_chat_untimeout":null,"shared_chat_delete":null}} */ -/// json_transform=snake_case struct Unvip { String userID; String userLogin; @@ -119,7 +115,6 @@ struct Unvip { {"subscription":{"id":"86d99e53-2837-40cf-bc6e-c6e00698919c","status":"enabled","type":"channel.moderate","version":"2","condition":{"broadcaster_user_id":"11148817","moderator_user_id":"117166826"},"transport":{"method":"websocket","session_id":"AgoQZgfnyKxXQ32hpzCWF4aCGBIGY2VsbC1j"},"created_at":"2025-02-01T12:02:16.005321321Z","cost":0},"event":{"broadcaster_user_id":"11148817","broadcaster_user_login":"pajlada","broadcaster_user_name":"pajlada","source_broadcaster_user_id":null,"source_broadcaster_user_login":null,"source_broadcaster_user_name":null,"moderator_user_id":"11148817","moderator_user_login":"pajlada","moderator_user_name":"pajlada","action":"mod","followers":null,"slow":null,"vip":null,"unvip":null,"mod":{"user_id":"159849156","user_login":"bajlada","user_name":"BajLada"},"unmod":null,"ban":null,"unban":null,"timeout":null,"untimeout":null,"raid":null,"unraid":null,"delete":null,"automod_terms":null,"unban_request":null,"warn":null,"shared_chat_ban":null,"shared_chat_unban":null,"shared_chat_timeout":null,"shared_chat_untimeout":null,"shared_chat_delete":null}} */ -/// json_transform=snake_case struct Mod { std::string userID; std::string userLogin; @@ -130,7 +125,6 @@ struct Mod { {"subscription":{"id":"86d99e53-2837-40cf-bc6e-c6e00698919c","status":"enabled","type":"channel.moderate","version":"2","condition":{"broadcaster_user_id":"11148817","moderator_user_id":"117166826"},"transport":{"method":"websocket","session_id":"AgoQZgfnyKxXQ32hpzCWF4aCGBIGY2VsbC1j"},"created_at":"2025-02-01T12:02:16.005321321Z","cost":0},"event":{"broadcaster_user_id":"11148817","broadcaster_user_login":"pajlada","broadcaster_user_name":"pajlada","source_broadcaster_user_id":null,"source_broadcaster_user_login":null,"source_broadcaster_user_name":null,"moderator_user_id":"11148817","moderator_user_login":"pajlada","moderator_user_name":"pajlada","action":"unmod","followers":null,"slow":null,"vip":null,"unvip":null,"mod":null,"unmod":{"user_id":"159849156","user_login":"bajlada","user_name":"BajLada"},"ban":null,"unban":null,"timeout":null,"untimeout":null,"raid":null,"unraid":null,"delete":null,"automod_terms":null,"unban_request":null,"warn":null,"shared_chat_ban":null,"shared_chat_unban":null,"shared_chat_timeout":null,"shared_chat_untimeout":null,"shared_chat_delete":null}} */ -/// json_transform=snake_case struct Unmod { std::string userID; std::string userLogin; @@ -145,7 +139,6 @@ struct Unmod { {"subscription":{"id":"86d99e53-2837-40cf-bc6e-c6e00698919c","status":"enabled","type":"channel.moderate","version":"2","condition":{"broadcaster_user_id":"11148817","moderator_user_id":"117166826"},"transport":{"method":"websocket","session_id":"AgoQZgfnyKxXQ32hpzCWF4aCGBIGY2VsbC1j"},"created_at":"2025-02-01T12:02:16.005321321Z","cost":0},"event":{"broadcaster_user_id":"11148817","broadcaster_user_login":"pajlada","broadcaster_user_name":"pajlada","source_broadcaster_user_id":null,"source_broadcaster_user_login":null,"source_broadcaster_user_name":null,"moderator_user_id":"11148817","moderator_user_login":"pajlada","moderator_user_name":"pajlada","action":"ban","followers":null,"slow":null,"vip":null,"unvip":null,"mod":null,"unmod":null,"ban":{"user_id":"70948394","user_login":"weeb123","user_name":"WEEB123","reason":""},"unban":null,"timeout":null,"untimeout":null,"raid":null,"unraid":null,"delete":null,"automod_terms":null,"unban_request":null,"warn":null,"shared_chat_ban":null,"shared_chat_unban":null,"shared_chat_timeout":null,"shared_chat_untimeout":null,"shared_chat_delete":null}} */ -/// json_transform=snake_case struct Ban { std::string userID; std::string userLogin; @@ -158,7 +151,6 @@ struct Ban { {"subscription":{"id":"86d99e53-2837-40cf-bc6e-c6e00698919c","status":"enabled","type":"channel.moderate","version":"2","condition":{"broadcaster_user_id":"11148817","moderator_user_id":"117166826"},"transport":{"method":"websocket","session_id":"AgoQZgfnyKxXQ32hpzCWF4aCGBIGY2VsbC1j"},"created_at":"2025-02-01T12:02:16.005321321Z","cost":0},"event":{"broadcaster_user_id":"11148817","broadcaster_user_login":"pajlada","broadcaster_user_name":"pajlada","source_broadcaster_user_id":null,"source_broadcaster_user_login":null,"source_broadcaster_user_name":null,"moderator_user_id":"11148817","moderator_user_login":"pajlada","moderator_user_name":"pajlada","action":"unban","followers":null,"slow":null,"vip":null,"unvip":null,"mod":null,"unmod":null,"ban":null,"unban":{"user_id":"70948394","user_login":"weeb123","user_name":"WEEB123"},"timeout":null,"untimeout":null,"raid":null,"unraid":null,"delete":null,"automod_terms":null,"unban_request":null,"warn":null,"shared_chat_ban":null,"shared_chat_unban":null,"shared_chat_timeout":null,"shared_chat_untimeout":null,"shared_chat_delete":null}} */ -/// json_transform=snake_case struct Unban { std::string userID; std::string userLogin; @@ -173,7 +165,6 @@ struct Unban { {"subscription":{"id":"86d99e53-2837-40cf-bc6e-c6e00698919c","status":"enabled","type":"channel.moderate","version":"2","condition":{"broadcaster_user_id":"11148817","moderator_user_id":"117166826"},"transport":{"method":"websocket","session_id":"AgoQZgfnyKxXQ32hpzCWF4aCGBIGY2VsbC1j"},"created_at":"2025-02-01T12:02:16.005321321Z","cost":0},"event":{"broadcaster_user_id":"11148817","broadcaster_user_login":"pajlada","broadcaster_user_name":"pajlada","source_broadcaster_user_id":null,"source_broadcaster_user_login":null,"source_broadcaster_user_name":null,"moderator_user_id":"11148817","moderator_user_login":"pajlada","moderator_user_name":"pajlada","action":"timeout","followers":null,"slow":null,"vip":null,"unvip":null,"mod":null,"unmod":null,"ban":null,"unban":null,"timeout":{"user_id":"70948394","user_login":"weeb123","user_name":"WEEB123","reason":"this is the reason","expires_at":"2025-02-01T12:11:15.859552916Z"},"untimeout":null,"raid":null,"unraid":null,"delete":null,"automod_terms":null,"unban_request":null,"warn":null,"shared_chat_ban":null,"shared_chat_unban":null,"shared_chat_timeout":null,"shared_chat_untimeout":null,"shared_chat_delete":null}} */ -/// json_transform=snake_case struct Timeout { std::string userID; std::string userLogin; @@ -188,7 +179,6 @@ struct Timeout { {"subscription":{"id":"86d99e53-2837-40cf-bc6e-c6e00698919c","status":"enabled","type":"channel.moderate","version":"2","condition":{"broadcaster_user_id":"11148817","moderator_user_id":"117166826"},"transport":{"method":"websocket","session_id":"AgoQZgfnyKxXQ32hpzCWF4aCGBIGY2VsbC1j"},"created_at":"2025-02-01T12:02:16.005321321Z","cost":0},"event":{"broadcaster_user_id":"11148817","broadcaster_user_login":"pajlada","broadcaster_user_name":"pajlada","source_broadcaster_user_id":null,"source_broadcaster_user_login":null,"source_broadcaster_user_name":null,"moderator_user_id":"11148817","moderator_user_login":"pajlada","moderator_user_name":"pajlada","action":"untimeout","followers":null,"slow":null,"vip":null,"unvip":null,"mod":null,"unmod":null,"ban":null,"unban":null,"timeout":null,"untimeout":{"user_id":"70948394","user_login":"weeb123","user_name":"WEEB123"},"raid":null,"unraid":null,"delete":null,"automod_terms":null,"unban_request":null,"warn":null,"shared_chat_ban":null,"shared_chat_unban":null,"shared_chat_timeout":null,"shared_chat_untimeout":null,"shared_chat_delete":null}} */ -/// json_transform=snake_case struct Untimeout { std::string userID; std::string userLogin; @@ -199,7 +189,6 @@ struct Untimeout { {"subscription":{"id":"e7b45c7a-9b4d-4101-8d7d-92e8945c26fa","status":"enabled","type":"channel.moderate","version":"2","condition":{"broadcaster_user_id":"159849156","moderator_user_id":"159849156"},"transport":{"method":"websocket","session_id":"AgoQEPRIfB3SQTCSkJM2zznvNxIGY2VsbC1j"},"created_at":"2025-02-01T12:12:45.685831769Z","cost":0},"event":{"broadcaster_user_id":"159849156","broadcaster_user_login":"bajlada","broadcaster_user_name":"BajLada","source_broadcaster_user_id":null,"source_broadcaster_user_login":null,"source_broadcaster_user_name":null,"moderator_user_id":"159849156","moderator_user_login":"bajlada","moderator_user_name":"BajLada","action":"raid","followers":null,"slow":null,"vip":null,"unvip":null,"mod":null,"unmod":null,"ban":null,"unban":null,"timeout":null,"untimeout":null,"raid":{"user_id":"11148817","user_login":"pajlada","user_name":"pajlada","viewer_count":0},"unraid":null,"delete":null,"automod_terms":null,"unban_request":null,"warn":null,"shared_chat_ban":null,"shared_chat_unban":null,"shared_chat_timeout":null,"shared_chat_untimeout":null,"shared_chat_delete":null}} */ -/// json_transform=snake_case struct Raid { std::string userID; std::string userLogin; @@ -212,7 +201,6 @@ struct Raid { {"subscription":{"id":"e7b45c7a-9b4d-4101-8d7d-92e8945c26fa","status":"enabled","type":"channel.moderate","version":"2","condition":{"broadcaster_user_id":"159849156","moderator_user_id":"159849156"},"transport":{"method":"websocket","session_id":"AgoQEPRIfB3SQTCSkJM2zznvNxIGY2VsbC1j"},"created_at":"2025-02-01T12:12:45.685831769Z","cost":0},"event":{"broadcaster_user_id":"159849156","broadcaster_user_login":"bajlada","broadcaster_user_name":"BajLada","source_broadcaster_user_id":null,"source_broadcaster_user_login":null,"source_broadcaster_user_name":null,"moderator_user_id":"159849156","moderator_user_login":"bajlada","moderator_user_name":"BajLada","action":"unraid","followers":null,"slow":null,"vip":null,"unvip":null,"mod":null,"unmod":null,"ban":null,"unban":null,"timeout":null,"untimeout":null,"raid":null,"unraid":{"user_id":"11148817","user_login":"pajlada","user_name":"pajlada"},"delete":null,"automod_terms":null,"unban_request":null,"warn":null,"shared_chat_ban":null,"shared_chat_unban":null,"shared_chat_timeout":null,"shared_chat_untimeout":null,"shared_chat_delete":null}} */ -/// json_transform=snake_case struct Unraid { std::string userID; std::string userLogin; @@ -223,7 +211,6 @@ struct Unraid { {"subscription":{"id":"4284c08c-402a-43a8-8537-1e75f38f562c","status":"enabled","type":"channel.moderate","version":"2","condition":{"broadcaster_user_id":"11148817","moderator_user_id":"117166826"},"transport":{"method":"websocket","session_id":"AgoQfS3RYz3MSqOophais4HEjxIGY2VsbC1j"},"created_at":"2025-02-01T12:15:13.083098352Z","cost":0},"event":{"broadcaster_user_id":"11148817","broadcaster_user_login":"pajlada","broadcaster_user_name":"pajlada","source_broadcaster_user_id":null,"source_broadcaster_user_login":null,"source_broadcaster_user_name":null,"moderator_user_id":"11148817","moderator_user_login":"pajlada","moderator_user_name":"pajlada","action":"delete","followers":null,"slow":null,"vip":null,"unvip":null,"mod":null,"unmod":null,"ban":null,"unban":null,"timeout":null,"untimeout":null,"raid":null,"unraid":null,"delete":{"user_id":"232490245","user_login":"namtheweebs","user_name":"NaMTheWeebs","message_id":"6c9bd28b-779b-4607-b66f-5c336e1ae29e","message_body":"bajlada raid NomNom"},"automod_terms":null,"unban_request":null,"warn":null,"shared_chat_ban":null,"shared_chat_unban":null,"shared_chat_timeout":null,"shared_chat_untimeout":null,"shared_chat_delete":null}} */ -/// json_transform=snake_case struct Delete { std::string userID; std::string userLogin; @@ -242,7 +229,6 @@ struct Delete { {"subscription":{"id":"0ccc8f11-7e77-40cf-84a9-25ab934c30fb","status":"enabled","type":"channel.moderate","version":"2","condition":{"broadcaster_user_id":"117166826","moderator_user_id":"117166826"},"transport":{"method":"websocket","session_id":"AgoQfS3RYz3MSqOophais4HEjxIGY2VsbC1j"},"created_at":"2025-02-01T12:15:13.092673205Z","cost":0},"event":{"broadcaster_user_id":"117166826","broadcaster_user_login":"testaccount_420","broadcaster_user_name":"테스트계정420","source_broadcaster_user_id":null,"source_broadcaster_user_login":null,"source_broadcaster_user_name":null,"moderator_user_id":"117166826","moderator_user_login":"testaccount_420","moderator_user_name":"테스트계정420","action":"add_blocked_term","followers":null,"slow":null,"vip":null,"unvip":null,"mod":null,"unmod":null,"ban":null,"unban":null,"timeout":null,"untimeout":null,"raid":null,"unraid":null,"delete":null,"automod_terms":{"action":"add","list":"blocked","terms":["cock cock cock penis sex cock penis penis cock"],"from_automod":true},"unban_request":null,"warn":null,"shared_chat_ban":null,"shared_chat_unban":null,"shared_chat_timeout":null,"shared_chat_untimeout":null,"shared_chat_delete":null}} */ -/// json_transform=snake_case struct AutomodTerms { // either add or remove std::string action; @@ -261,7 +247,6 @@ struct AutomodTerms { {"subscription":{"id":"4284c08c-402a-43a8-8537-1e75f38f562c","status":"enabled","type":"channel.moderate","version":"2","condition":{"broadcaster_user_id":"11148817","moderator_user_id":"117166826"},"transport":{"method":"websocket","session_id":"AgoQfS3RYz3MSqOophais4HEjxIGY2VsbC1j"},"created_at":"2025-02-01T12:15:13.083098352Z","cost":0},"event":{"broadcaster_user_id":"11148817","broadcaster_user_login":"pajlada","broadcaster_user_name":"pajlada","source_broadcaster_user_id":null,"source_broadcaster_user_login":null,"source_broadcaster_user_name":null,"moderator_user_id":"11148817","moderator_user_login":"pajlada","moderator_user_name":"pajlada","action":"deny_unban_request","followers":null,"slow":null,"vip":null,"unvip":null,"mod":null,"unmod":null,"ban":null,"unban":null,"timeout":null,"untimeout":null,"raid":null,"unraid":null,"delete":null,"automod_terms":null,"unban_request":{"is_approved":false,"user_id":"975285839","user_login":"selenatormapguy","user_name":"selenatormapguy","moderator_message":""},"warn":null,"shared_chat_ban":null,"shared_chat_unban":null,"shared_chat_timeout":null,"shared_chat_untimeout":null,"shared_chat_delete":null}} */ -/// json_transform=snake_case struct UnbanRequest { bool isApproved; @@ -280,7 +265,6 @@ struct UnbanRequest { {"subscription":{"id":"4284c08c-402a-43a8-8537-1e75f38f562c","status":"enabled","type":"channel.moderate","version":"2","condition":{"broadcaster_user_id":"11148817","moderator_user_id":"117166826"},"transport":{"method":"websocket","session_id":"AgoQfS3RYz3MSqOophais4HEjxIGY2VsbC1j"},"created_at":"2025-02-01T12:15:13.083098352Z","cost":0},"event":{"broadcaster_user_id":"11148817","broadcaster_user_login":"pajlada","broadcaster_user_name":"pajlada","source_broadcaster_user_id":null,"source_broadcaster_user_login":null,"source_broadcaster_user_name":null,"moderator_user_id":"11148817","moderator_user_login":"pajlada","moderator_user_name":"pajlada","action":"warn","followers":null,"slow":null,"vip":null,"unvip":null,"mod":null,"unmod":null,"ban":null,"unban":null,"timeout":null,"untimeout":null,"raid":null,"unraid":null,"delete":null,"automod_terms":null,"unban_request":null,"warn":{"user_id":"159849156","user_login":"bajlada","user_name":"BajLada","reason":"and a custom reason","chat_rules_cited":["Rule 2"]},"shared_chat_ban":null,"shared_chat_unban":null,"shared_chat_timeout":null,"shared_chat_untimeout":null,"shared_chat_delete":null}} */ -/// json_transform=snake_case struct Warn { std::string userID; std::string userLogin; @@ -291,7 +275,6 @@ struct Warn { std::vector chatRulesCited; }; -/// json_transform=snake_case enum class Action : uint8_t { Ban, Timeout, @@ -332,7 +315,6 @@ enum class Action : uint8_t { SharedChatDelete, }; -/// json_transform=snake_case struct Event { /// User ID (e.g. 117166826) of the user who's channel the event took place in String broadcasterUserID; diff --git a/lib/twitch-eventsub-ws/include/twitch-eventsub-ws/payloads/channel-update-v1.hpp b/lib/twitch-eventsub-ws/include/twitch-eventsub-ws/payloads/channel-update-v1.hpp index c61e8ba1..92efd3a5 100644 --- a/lib/twitch-eventsub-ws/include/twitch-eventsub-ws/payloads/channel-update-v1.hpp +++ b/lib/twitch-eventsub-ws/include/twitch-eventsub-ws/payloads/channel-update-v1.hpp @@ -8,7 +8,6 @@ namespace chatterino::eventsub::lib::payload::channel_update::v1 { -/// json_transform=snake_case struct Event { // The broadcaster's user ID const std::string broadcasterUserID; diff --git a/lib/twitch-eventsub-ws/include/twitch-eventsub-ws/payloads/stream-offline-v1.hpp b/lib/twitch-eventsub-ws/include/twitch-eventsub-ws/payloads/stream-offline-v1.hpp index 36d12ecb..f9487c0f 100644 --- a/lib/twitch-eventsub-ws/include/twitch-eventsub-ws/payloads/stream-offline-v1.hpp +++ b/lib/twitch-eventsub-ws/include/twitch-eventsub-ws/payloads/stream-offline-v1.hpp @@ -8,7 +8,6 @@ namespace chatterino::eventsub::lib::payload::stream_offline::v1 { -/// json_transform=snake_case struct Event { // The broadcaster's user ID const std::string broadcasterUserID; diff --git a/lib/twitch-eventsub-ws/include/twitch-eventsub-ws/payloads/stream-online-v1.hpp b/lib/twitch-eventsub-ws/include/twitch-eventsub-ws/payloads/stream-online-v1.hpp index cd22017d..114061ed 100644 --- a/lib/twitch-eventsub-ws/include/twitch-eventsub-ws/payloads/stream-online-v1.hpp +++ b/lib/twitch-eventsub-ws/include/twitch-eventsub-ws/payloads/stream-online-v1.hpp @@ -8,7 +8,6 @@ namespace chatterino::eventsub::lib::payload::stream_online::v1 { -/// json_transform=snake_case struct Event { // The ID of the stream const std::string id; diff --git a/lib/twitch-eventsub-ws/include/twitch-eventsub-ws/payloads/subscription.hpp b/lib/twitch-eventsub-ws/include/twitch-eventsub-ws/payloads/subscription.hpp index 53b2e497..9b8eee5d 100644 --- a/lib/twitch-eventsub-ws/include/twitch-eventsub-ws/payloads/subscription.hpp +++ b/lib/twitch-eventsub-ws/include/twitch-eventsub-ws/payloads/subscription.hpp @@ -32,13 +32,11 @@ namespace chatterino::eventsub::lib::payload::subscription { } */ -/// json_transform=snake_case struct Transport { const std::string method; const std::string sessionID; }; -/// json_transform=snake_case struct Subscription { const std::string id; const std::string status;