packages feed

slackblocks-3.1.0: src/Slackblocks/Models.hs

-- Generated by haskell/generator/generate.py. Edit the shared contract instead.

-- | Native checked models, construction fields and closed role conversions.
module Slackblocks.Models
  ( packageVersion,
    specVersion,
    AlertLevel (..),
    ContainerWidth (..),
    TaskStatus (..),
    ButtonStyle (..),
    IconButtonIcon (..),
    ColumnAlign (..),
    RichTextListStyle (..),
    ResponseType (..),
    ActionsBlock,
    ActionsBlockFields (..),
    actionsBlock,
    buildActionsBlock,
    inspectActionsBlock,
    AlertBlock,
    AlertBlockFields (..),
    alertBlock,
    buildAlertBlock,
    inspectAlertBlock,
    CardBlock,
    CardBlockFields (..),
    cardBlock,
    buildCardBlock,
    inspectCardBlock,
    CarouselBlock,
    CarouselBlockFields (..),
    carouselBlock,
    buildCarouselBlock,
    inspectCarouselBlock,
    ContainerBlock,
    ContainerBlockFields (..),
    containerBlock,
    buildContainerBlock,
    inspectContainerBlock,
    ContextActionsBlock,
    ContextActionsBlockFields (..),
    contextActionsBlock,
    buildContextActionsBlock,
    inspectContextActionsBlock,
    ContextBlock,
    ContextBlockFields (..),
    contextBlock,
    buildContextBlock,
    inspectContextBlock,
    DataTableBlock,
    DataTableBlockFields (..),
    dataTableBlock,
    buildDataTableBlock,
    inspectDataTableBlock,
    DataVisualizationBlock,
    DataVisualizationBlockFields (..),
    dataVisualizationBlock,
    buildDataVisualizationBlock,
    inspectDataVisualizationBlock,
    DividerBlock,
    DividerBlockFields (..),
    dividerBlock,
    buildDividerBlock,
    inspectDividerBlock,
    FileBlock,
    FileBlockFields (..),
    fileBlock,
    buildFileBlock,
    inspectFileBlock,
    HeaderBlock,
    HeaderBlockFields (..),
    headerBlock,
    buildHeaderBlock,
    inspectHeaderBlock,
    ImageBlock,
    ImageBlockFields (..),
    imageBlock,
    buildImageBlock,
    inspectImageBlock,
    InputBlock,
    InputBlockFields (..),
    inputBlock,
    buildInputBlock,
    inspectInputBlock,
    MarkdownBlock,
    MarkdownBlockFields (..),
    markdownBlock,
    buildMarkdownBlock,
    inspectMarkdownBlock,
    PlanBlock,
    PlanBlockFields (..),
    planBlock,
    buildPlanBlock,
    inspectPlanBlock,
    RichTextBlock,
    RichTextBlockFields (..),
    richTextBlock,
    buildRichTextBlock,
    inspectRichTextBlock,
    SectionBlock,
    SectionBlockFields (..),
    sectionBlock,
    buildSectionBlock,
    inspectSectionBlock,
    TableBlock,
    TableBlockFields (..),
    tableBlock,
    buildTableBlock,
    inspectTableBlock,
    TaskCardBlock,
    TaskCardBlockFields (..),
    taskCardBlock,
    buildTaskCardBlock,
    inspectTaskCardBlock,
    VideoBlock,
    VideoBlockFields (..),
    videoBlock,
    buildVideoBlock,
    inspectVideoBlock,
    ButtonElement,
    ButtonElementFields (..),
    buttonElement,
    buildButtonElement,
    inspectButtonElement,
    ChannelMultiSelectElement,
    ChannelMultiSelectElementFields (..),
    channelMultiSelectElement,
    buildChannelMultiSelectElement,
    inspectChannelMultiSelectElement,
    ChannelSelectElement,
    ChannelSelectElementFields (..),
    channelSelectElement,
    buildChannelSelectElement,
    inspectChannelSelectElement,
    CheckboxesElement,
    CheckboxesElementFields (..),
    checkboxesElement,
    buildCheckboxesElement,
    inspectCheckboxesElement,
    ConversationMultiSelectElement,
    ConversationMultiSelectElementFields (..),
    conversationMultiSelectElement,
    buildConversationMultiSelectElement,
    inspectConversationMultiSelectElement,
    ConversationSelectElement,
    ConversationSelectElementFields (..),
    conversationSelectElement,
    buildConversationSelectElement,
    inspectConversationSelectElement,
    DatePickerElement,
    DatePickerElementFields (..),
    datePickerElement,
    buildDatePickerElement,
    inspectDatePickerElement,
    DateTimePickerElement,
    DateTimePickerElementFields (..),
    dateTimePickerElement,
    buildDateTimePickerElement,
    inspectDateTimePickerElement,
    EmailInputElement,
    EmailInputElementFields (..),
    emailInputElement,
    buildEmailInputElement,
    inspectEmailInputElement,
    ExternalMultiSelectElement,
    ExternalMultiSelectElementFields (..),
    externalMultiSelectElement,
    buildExternalMultiSelectElement,
    inspectExternalMultiSelectElement,
    ExternalSelectElement,
    ExternalSelectElementFields (..),
    externalSelectElement,
    buildExternalSelectElement,
    inspectExternalSelectElement,
    FeedbackButtonsElement,
    FeedbackButtonsElementFields (..),
    feedbackButtonsElement,
    buildFeedbackButtonsElement,
    inspectFeedbackButtonsElement,
    FileInputElement,
    FileInputElementFields (..),
    fileInputElement,
    buildFileInputElement,
    inspectFileInputElement,
    IconButtonElement,
    IconButtonElementFields (..),
    iconButtonElement,
    buildIconButtonElement,
    inspectIconButtonElement,
    ImageElement,
    ImageElementFields (..),
    imageElement,
    buildImageElement,
    inspectImageElement,
    NumberInputElement,
    NumberInputElementFields (..),
    numberInputElement,
    buildNumberInputElement,
    inspectNumberInputElement,
    OverflowElement,
    OverflowElementFields (..),
    overflowElement,
    buildOverflowElement,
    inspectOverflowElement,
    PlainTextInputElement,
    PlainTextInputElementFields (..),
    plainTextInputElement,
    buildPlainTextInputElement,
    inspectPlainTextInputElement,
    RadioButtonsElement,
    RadioButtonsElementFields (..),
    radioButtonsElement,
    buildRadioButtonsElement,
    inspectRadioButtonsElement,
    RichTextInputElement,
    RichTextInputElementFields (..),
    richTextInputElement,
    buildRichTextInputElement,
    inspectRichTextInputElement,
    StaticMultiSelectElement,
    StaticMultiSelectElementFields (..),
    staticMultiSelectElement,
    buildStaticMultiSelectElement,
    inspectStaticMultiSelectElement,
    StaticSelectElement,
    StaticSelectElementFields (..),
    staticSelectElement,
    buildStaticSelectElement,
    inspectStaticSelectElement,
    TimePickerElement,
    TimePickerElementFields (..),
    timePickerElement,
    buildTimePickerElement,
    inspectTimePickerElement,
    UrlInputElement,
    UrlInputElementFields (..),
    urlInputElement,
    buildUrlInputElement,
    inspectUrlInputElement,
    UserMultiSelectElement,
    UserMultiSelectElementFields (..),
    userMultiSelectElement,
    buildUserMultiSelectElement,
    inspectUserMultiSelectElement,
    UserSelectElement,
    UserSelectElementFields (..),
    userSelectElement,
    buildUserSelectElement,
    inspectUserSelectElement,
    WorkflowButtonElement,
    WorkflowButtonElementFields (..),
    workflowButtonElement,
    buildWorkflowButtonElement,
    inspectWorkflowButtonElement,
    AreaChart,
    AreaChartFields (..),
    areaChart,
    buildAreaChart,
    inspectAreaChart,
    AxisConfig,
    AxisConfigFields (..),
    axisConfig,
    buildAxisConfig,
    inspectAxisConfig,
    BarChart,
    BarChartFields (..),
    barChart,
    buildBarChart,
    inspectBarChart,
    ChartSegment,
    ChartSegmentFields (..),
    chartSegment,
    buildChartSegment,
    inspectChartSegment,
    ColumnSettings,
    ColumnSettingsFields (..),
    columnSettings,
    buildColumnSettings,
    inspectColumnSettings,
    ConfirmationDialogue,
    ConfirmationDialogueFields (..),
    confirmationDialogue,
    buildConfirmationDialogue,
    inspectConfirmationDialogue,
    ConversationFilter,
    ConversationFilterFields (..),
    conversationFilter,
    buildConversationFilter,
    inspectConversationFilter,
    DataPoint,
    DataPointFields (..),
    dataPoint,
    buildDataPoint,
    inspectDataPoint,
    DataSeries,
    DataSeriesFields (..),
    dataSeries,
    buildDataSeries,
    inspectDataSeries,
    DispatchActionConfiguration,
    DispatchActionConfigurationFields (..),
    dispatchActionConfiguration,
    buildDispatchActionConfiguration,
    inspectDispatchActionConfiguration,
    FeedbackButton,
    FeedbackButtonFields (..),
    feedbackButton,
    buildFeedbackButton,
    inspectFeedbackButton,
    InputParameter,
    InputParameterFields (..),
    inputParameter,
    buildInputParameter,
    inspectInputParameter,
    LineChart,
    LineChartFields (..),
    lineChart,
    buildLineChart,
    inspectLineChart,
    MarkdownText,
    MarkdownTextFields (..),
    markdownText,
    buildMarkdownText,
    inspectMarkdownText,
    SelectOption,
    SelectOptionFields (..),
    selectOption,
    buildSelectOption,
    inspectSelectOption,
    SelectOptionGroup,
    SelectOptionGroupFields (..),
    selectOptionGroup,
    buildSelectOptionGroup,
    inspectSelectOptionGroup,
    PieChart,
    PieChartFields (..),
    pieChart,
    buildPieChart,
    inspectPieChart,
    PlainText,
    PlainTextFields (..),
    plainText,
    buildPlainText,
    inspectPlainText,
    RawNumber,
    RawNumberFields (..),
    rawNumber,
    buildRawNumber,
    inspectRawNumber,
    RawText,
    RawTextFields (..),
    rawText,
    buildRawText,
    inspectRawText,
    RichTextChannel,
    RichTextChannelFields (..),
    richTextChannel,
    buildRichTextChannel,
    inspectRichTextChannel,
    RichTextCodeBlock,
    RichTextCodeBlockFields (..),
    richTextCodeBlock,
    buildRichTextCodeBlock,
    inspectRichTextCodeBlock,
    RichTextEmoji,
    RichTextEmojiFields (..),
    richTextEmoji,
    buildRichTextEmoji,
    inspectRichTextEmoji,
    RichTextLink,
    RichTextLinkFields (..),
    richTextLink,
    buildRichTextLink,
    inspectRichTextLink,
    RichTextList,
    RichTextListFields (..),
    richTextList,
    buildRichTextList,
    inspectRichTextList,
    RichTextQuote,
    RichTextQuoteFields (..),
    richTextQuote,
    buildRichTextQuote,
    inspectRichTextQuote,
    RichTextSection,
    RichTextSectionFields (..),
    richTextSection,
    buildRichTextSection,
    inspectRichTextSection,
    RichTextText,
    RichTextTextFields (..),
    richTextText,
    buildRichTextText,
    inspectRichTextText,
    RichTextUser,
    RichTextUserFields (..),
    richTextUser,
    buildRichTextUser,
    inspectRichTextUser,
    RichTextUserGroup,
    RichTextUserGroupFields (..),
    richTextUserGroup,
    buildRichTextUserGroup,
    inspectRichTextUserGroup,
    SlackFile,
    SlackFileFields (..),
    slackFile,
    buildSlackFile,
    inspectSlackFile,
    SlackIcon,
    SlackIconFields (..),
    slackIcon,
    buildSlackIcon,
    inspectSlackIcon,
    Trigger,
    TriggerFields (..),
    trigger,
    buildTrigger,
    inspectTrigger,
    UrlSource,
    UrlSourceFields (..),
    urlSource,
    buildUrlSource,
    inspectUrlSource,
    Workflow,
    WorkflowFields (..),
    workflow,
    buildWorkflow,
    inspectWorkflow,
    Attachment,
    AttachmentFields (..),
    attachment,
    buildAttachment,
    inspectAttachment,
    HomeTabView,
    HomeTabViewFields (..),
    homeTabView,
    buildHomeTabView,
    inspectHomeTabView,
    MessagePayload,
    MessagePayloadFields (..),
    messagePayload,
    buildMessagePayload,
    inspectMessagePayload,
    MessageResponse,
    MessageResponseFields (..),
    messageResponse,
    buildMessageResponse,
    inspectMessageResponse,
    ModalView,
    ModalViewFields (..),
    modalView,
    buildModalView,
    inspectModalView,
    WebhookMessage,
    WebhookMessageFields (..),
    webhookMessage,
    buildWebhookMessage,
    inspectWebhookMessage,
    PlanTask,
    buildPlanTask,
    inspectPlanTask,
    Block,
    actionsBlockAsBlock,
    matchBlockActionsBlock,
    alertBlockAsBlock,
    matchBlockAlertBlock,
    cardBlockAsBlock,
    matchBlockCardBlock,
    carouselBlockAsBlock,
    matchBlockCarouselBlock,
    containerBlockAsBlock,
    matchBlockContainerBlock,
    contextActionsBlockAsBlock,
    matchBlockContextActionsBlock,
    contextBlockAsBlock,
    matchBlockContextBlock,
    dataTableBlockAsBlock,
    matchBlockDataTableBlock,
    dataVisualizationBlockAsBlock,
    matchBlockDataVisualizationBlock,
    dividerBlockAsBlock,
    matchBlockDividerBlock,
    fileBlockAsBlock,
    matchBlockFileBlock,
    headerBlockAsBlock,
    matchBlockHeaderBlock,
    imageBlockAsBlock,
    matchBlockImageBlock,
    inputBlockAsBlock,
    matchBlockInputBlock,
    markdownBlockAsBlock,
    matchBlockMarkdownBlock,
    planBlockAsBlock,
    matchBlockPlanBlock,
    richTextBlockAsBlock,
    matchBlockRichTextBlock,
    sectionBlockAsBlock,
    matchBlockSectionBlock,
    tableBlockAsBlock,
    matchBlockTableBlock,
    taskCardBlockAsBlock,
    matchBlockTaskCardBlock,
    videoBlockAsBlock,
    matchBlockVideoBlock,
    ContextElement,
    imageElementAsContextElement,
    matchContextElementImageElement,
    markdownTextAsContextElement,
    matchContextElementMarkdownText,
    plainTextAsContextElement,
    matchContextElementPlainText,
    ContextActionsElement,
    feedbackButtonsElementAsContextActionsElement,
    matchContextActionsElementFeedbackButtonsElement,
    iconButtonElementAsContextActionsElement,
    matchContextActionsElementIconButtonElement,
    TableCell,
    richTextBlockAsTableCell,
    matchTableCellRichTextBlock,
    rawTextAsTableCell,
    matchTableCellRawText,
    DataTableCell,
    richTextBlockAsDataTableCell,
    matchDataTableCellRichTextBlock,
    rawNumberAsDataTableCell,
    matchDataTableCellRawNumber,
    rawTextAsDataTableCell,
    matchDataTableCellRawText,
    Element,
    buttonElementAsElement,
    matchElementButtonElement,
    channelMultiSelectElementAsElement,
    matchElementChannelMultiSelectElement,
    channelSelectElementAsElement,
    matchElementChannelSelectElement,
    checkboxesElementAsElement,
    matchElementCheckboxesElement,
    conversationMultiSelectElementAsElement,
    matchElementConversationMultiSelectElement,
    conversationSelectElementAsElement,
    matchElementConversationSelectElement,
    datePickerElementAsElement,
    matchElementDatePickerElement,
    dateTimePickerElementAsElement,
    matchElementDateTimePickerElement,
    emailInputElementAsElement,
    matchElementEmailInputElement,
    externalMultiSelectElementAsElement,
    matchElementExternalMultiSelectElement,
    externalSelectElementAsElement,
    matchElementExternalSelectElement,
    feedbackButtonsElementAsElement,
    matchElementFeedbackButtonsElement,
    fileInputElementAsElement,
    matchElementFileInputElement,
    iconButtonElementAsElement,
    matchElementIconButtonElement,
    imageElementAsElement,
    matchElementImageElement,
    numberInputElementAsElement,
    matchElementNumberInputElement,
    overflowElementAsElement,
    matchElementOverflowElement,
    plainTextInputElementAsElement,
    matchElementPlainTextInputElement,
    radioButtonsElementAsElement,
    matchElementRadioButtonsElement,
    richTextInputElementAsElement,
    matchElementRichTextInputElement,
    staticMultiSelectElementAsElement,
    matchElementStaticMultiSelectElement,
    staticSelectElementAsElement,
    matchElementStaticSelectElement,
    timePickerElementAsElement,
    matchElementTimePickerElement,
    urlInputElementAsElement,
    matchElementUrlInputElement,
    userMultiSelectElementAsElement,
    matchElementUserMultiSelectElement,
    userSelectElementAsElement,
    matchElementUserSelectElement,
    workflowButtonElementAsElement,
    matchElementWorkflowButtonElement,
    InputElement,
    channelMultiSelectElementAsInputElement,
    matchInputElementChannelMultiSelectElement,
    channelSelectElementAsInputElement,
    matchInputElementChannelSelectElement,
    checkboxesElementAsInputElement,
    matchInputElementCheckboxesElement,
    conversationMultiSelectElementAsInputElement,
    matchInputElementConversationMultiSelectElement,
    conversationSelectElementAsInputElement,
    matchInputElementConversationSelectElement,
    datePickerElementAsInputElement,
    matchInputElementDatePickerElement,
    dateTimePickerElementAsInputElement,
    matchInputElementDateTimePickerElement,
    emailInputElementAsInputElement,
    matchInputElementEmailInputElement,
    externalMultiSelectElementAsInputElement,
    matchInputElementExternalMultiSelectElement,
    externalSelectElementAsInputElement,
    matchInputElementExternalSelectElement,
    fileInputElementAsInputElement,
    matchInputElementFileInputElement,
    numberInputElementAsInputElement,
    matchInputElementNumberInputElement,
    plainTextInputElementAsInputElement,
    matchInputElementPlainTextInputElement,
    radioButtonsElementAsInputElement,
    matchInputElementRadioButtonsElement,
    richTextInputElementAsInputElement,
    matchInputElementRichTextInputElement,
    staticMultiSelectElementAsInputElement,
    matchInputElementStaticMultiSelectElement,
    staticSelectElementAsInputElement,
    matchInputElementStaticSelectElement,
    timePickerElementAsInputElement,
    matchInputElementTimePickerElement,
    urlInputElementAsInputElement,
    matchInputElementUrlInputElement,
    userMultiSelectElementAsInputElement,
    matchInputElementUserMultiSelectElement,
    userSelectElementAsInputElement,
    matchInputElementUserSelectElement,
    TextObject,
    markdownTextAsText,
    matchTextObjectMarkdownText,
    plainTextAsText,
    matchTextObjectPlainText,
    Chart,
    areaChartAsChart,
    matchChartAreaChart,
    barChartAsChart,
    matchChartBarChart,
    lineChartAsChart,
    matchChartLineChart,
    pieChartAsChart,
    matchChartPieChart,
    RichTextBlockElement,
    richTextCodeBlockAsRichTextBlockElement,
    matchRichTextBlockElementRichTextCodeBlock,
    richTextListAsRichTextBlockElement,
    matchRichTextBlockElementRichTextList,
    richTextQuoteAsRichTextBlockElement,
    matchRichTextBlockElementRichTextQuote,
    richTextSectionAsRichTextBlockElement,
    matchRichTextBlockElementRichTextSection,
    RichTextSectionElement,
    richTextChannelAsRichTextSectionElement,
    matchRichTextSectionElementRichTextChannel,
    richTextEmojiAsRichTextSectionElement,
    matchRichTextSectionElementRichTextEmoji,
    richTextLinkAsRichTextSectionElement,
    matchRichTextSectionElementRichTextLink,
    richTextTextAsRichTextSectionElement,
    matchRichTextSectionElementRichTextText,
    richTextUserAsRichTextSectionElement,
    matchRichTextSectionElementRichTextUser,
    richTextUserGroupAsRichTextSectionElement,
    matchRichTextSectionElementRichTextUserGroup,
  )
where

import Data.Aeson (FromJSON (..), ToJSON (..), Value (..), object, (.=))
import Data.Map.Strict (Map)
import Data.Map.Strict qualified as Map
import Data.Scientific (Scientific)
import Data.Text (Text)
import Slackblocks.Internal.Rules (checkIntegerBounds, standaloneTask, validateFields)
import Slackblocks.Internal.Wire
import Slackblocks.Json (FromSlackJSON (..))
import Slackblocks.Style
import Slackblocks.Validation

-- | Coordinated package version, distinct from the shared contract.
packageVersion :: Text

-- | Shared Block Kit contract version implemented by this package.
specVersion :: Text

packageVersion = "3.1.0"

specVersion = "1.4.0"

-- | Severity levels supported by alert blocks.
data AlertLevel
  = -- | Slack wire value: @default@.
    AlertLevelDefault
  | -- | Slack wire value: @info@.
    AlertLevelInfo
  | -- | Slack wire value: @warning@.
    AlertLevelWarning
  | -- | Slack wire value: @error@.
    AlertLevelError
  | -- | Slack wire value: @success@.
    AlertLevelSuccess
  deriving (Eq, Ord, Show, Enum, Bounded)

instance ToJSON AlertLevel where
  toJSON AlertLevelDefault = String "default"
  toJSON AlertLevelInfo = String "info"
  toJSON AlertLevelWarning = String "warning"
  toJSON AlertLevelError = String "error"
  toJSON AlertLevelSuccess = String "success"

instance FromSlackJSON AlertLevel where
  fromSlackJSON value = case value of
    String "default" -> Right AlertLevelDefault
    String "info" -> Right AlertLevelInfo
    String "warning" -> Right AlertLevelWarning
    String "error" -> Right AlertLevelError
    String "success" -> Right AlertLevelSuccess
    _ -> failure TypeMismatch [] "enum" "unknown enumeration value"

instance FromJSON AlertLevel where parseJSON = checkedParser

-- | Widths supported by Slack container blocks.
data ContainerWidth
  = -- | Slack wire value: @narrow@.
    ContainerWidthNarrow
  | -- | Slack wire value: @standard@.
    ContainerWidthStandard
  | -- | Slack wire value: @wide@.
    ContainerWidthWide
  | -- | Slack wire value: @full@.
    ContainerWidthFull
  deriving (Eq, Ord, Show, Enum, Bounded)

instance ToJSON ContainerWidth where
  toJSON ContainerWidthNarrow = String "narrow"
  toJSON ContainerWidthStandard = String "standard"
  toJSON ContainerWidthWide = String "wide"
  toJSON ContainerWidthFull = String "full"

instance FromSlackJSON ContainerWidth where
  fromSlackJSON value = case value of
    String "narrow" -> Right ContainerWidthNarrow
    String "standard" -> Right ContainerWidthStandard
    String "wide" -> Right ContainerWidthWide
    String "full" -> Right ContainerWidthFull
    _ -> failure TypeMismatch [] "enum" "unknown enumeration value"

instance FromJSON ContainerWidth where parseJSON = checkedParser

-- | States supported by task card blocks.
data TaskStatus
  = -- | Slack wire value: @pending@.
    TaskStatusPending
  | -- | Slack wire value: @in_progress@.
    TaskStatusInProgress
  | -- | Slack wire value: @complete@.
    TaskStatusComplete
  | -- | Slack wire value: @error@.
    TaskStatusError
  deriving (Eq, Ord, Show, Enum, Bounded)

instance ToJSON TaskStatus where
  toJSON TaskStatusPending = String "pending"
  toJSON TaskStatusInProgress = String "in_progress"
  toJSON TaskStatusComplete = String "complete"
  toJSON TaskStatusError = String "error"

instance FromSlackJSON TaskStatus where
  fromSlackJSON value = case value of
    String "pending" -> Right TaskStatusPending
    String "in_progress" -> Right TaskStatusInProgress
    String "complete" -> Right TaskStatusComplete
    String "error" -> Right TaskStatusError
    _ -> failure TypeMismatch [] "enum" "unknown enumeration value"

instance FromJSON TaskStatus where parseJSON = checkedParser

-- | Visual emphasis for buttons and confirmation dialogs.
data ButtonStyle
  = -- | Slack wire value: @primary@.
    ButtonStylePrimary
  | -- | Slack wire value: @danger@.
    ButtonStyleDanger
  deriving (Eq, Ord, Show, Enum, Bounded)

instance ToJSON ButtonStyle where
  toJSON ButtonStylePrimary = String "primary"
  toJSON ButtonStyleDanger = String "danger"

instance FromSlackJSON ButtonStyle where
  fromSlackJSON value = case value of
    String "primary" -> Right ButtonStylePrimary
    String "danger" -> Right ButtonStyleDanger
    _ -> failure TypeMismatch [] "enum" "unknown enumeration value"

instance FromJSON ButtonStyle where parseJSON = checkedParser

-- | Icons supported by icon buttons.
data IconButtonIcon
  = -- | Slack wire value: @trash@.
    IconButtonIconTrash
  deriving (Eq, Ord, Show, Enum, Bounded)

instance ToJSON IconButtonIcon where
  toJSON IconButtonIconTrash = String "trash"

instance FromSlackJSON IconButtonIcon where
  fromSlackJSON value = case value of
    String "trash" -> Right IconButtonIconTrash
    _ -> failure TypeMismatch [] "enum" "unknown enumeration value"

instance FromJSON IconButtonIcon where parseJSON = checkedParser

-- | Horizontal alignment for table columns.
data ColumnAlign
  = -- | Slack wire value: @left@.
    ColumnAlignLeft
  | -- | Slack wire value: @center@.
    ColumnAlignCenter
  | -- | Slack wire value: @right@.
    ColumnAlignRight
  deriving (Eq, Ord, Show, Enum, Bounded)

instance ToJSON ColumnAlign where
  toJSON ColumnAlignLeft = String "left"
  toJSON ColumnAlignCenter = String "center"
  toJSON ColumnAlignRight = String "right"

instance FromSlackJSON ColumnAlign where
  fromSlackJSON value = case value of
    String "left" -> Right ColumnAlignLeft
    String "center" -> Right ColumnAlignCenter
    String "right" -> Right ColumnAlignRight
    _ -> failure TypeMismatch [] "enum" "unknown enumeration value"

instance FromJSON ColumnAlign where parseJSON = checkedParser

-- | Marker styles for rich text lists.
data RichTextListStyle
  = -- | Slack wire value: @bullet@.
    RichTextListStyleBullet
  | -- | Slack wire value: @ordered@.
    RichTextListStyleOrdered
  deriving (Eq, Ord, Show, Enum, Bounded)

instance ToJSON RichTextListStyle where
  toJSON RichTextListStyleBullet = String "bullet"
  toJSON RichTextListStyleOrdered = String "ordered"

instance FromSlackJSON RichTextListStyle where
  fromSlackJSON value = case value of
    String "bullet" -> Right RichTextListStyleBullet
    String "ordered" -> Right RichTextListStyleOrdered
    _ -> failure TypeMismatch [] "enum" "unknown enumeration value"

instance FromJSON RichTextListStyle where parseJSON = checkedParser

-- | Visibility of a slash-command or interaction response.
data ResponseType
  = -- | Slack wire value: @in_channel@.
    ResponseTypeInChannel
  | -- | Slack wire value: @ephemeral@.
    ResponseTypeEphemeral
  deriving (Eq, Ord, Show, Enum, Bounded)

instance ToJSON ResponseType where
  toJSON ResponseTypeInChannel = String "in_channel"
  toJSON ResponseTypeEphemeral = String "ephemeral"

instance FromSlackJSON ResponseType where
  fromSlackJSON value = case value of
    String "in_channel" -> Right ResponseTypeInChannel
    String "ephemeral" -> Right ResponseTypeEphemeral
    _ -> failure TypeMismatch [] "enum" "unknown enumeration value"

instance FromJSON ResponseType where parseJSON = checkedParser

-- | A block that holds interactive elements such as buttons and menus.
--
-- <https://docs.slack.dev/reference/block-kit/blocks/actions-block>
newtype ActionsBlock = CheckedActionsBlock ActionsBlockFields deriving (Eq, Show)

-- | Editable construction input. Call 'buildActionsBlock' before encoding.
data ActionsBlockFields = ActionsBlockFields
  { -- | Adds interactive elements in display order. Required. Shared limit: @actions.elements@.
    actionsBlockElements :: [Element],
    -- | Sets a unique identifier for this block. Slack returns it in interaction payloads, so use a stable value when you need to find the block again. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @block_id@.
    actionsBlockBlockId :: Maybe (Text),
    -- | Unmodeled extension fields. Reserved and modeled keys are rejected.
    actionsBlockExtensions :: Map Text Value
  }
  deriving (Eq, Show)

-- | Start editable fields for ActionsBlock; required arguments follow the signature.
-- Optional fields start absent except the explicit shared defaults; no block ID is invented.
-- Finish with 'buildActionsBlock' to validate before JSON encoding.
actionsBlock :: [Element] -> ActionsBlockFields
actionsBlock arg0 = ActionsBlockFields (arg0) (Nothing) (Map.empty)

-- | Inspect immutable construction fields. Rebuild edits with 'buildActionsBlock' to revalidate.
inspectActionsBlock :: ActionsBlock -> ActionsBlockFields
inspectActionsBlock (CheckedActionsBlock fields) = fields

-- | Validate fields, extensions and receiving context. Return structured errors or a checked ActionsBlock.
buildActionsBlock :: ActionsBlockFields -> Result ActionsBlock
buildActionsBlock fields = do
  checkExtensions ["elements", "block_id"] (actionsBlockExtensions fields)
  validateFields "ActionsBlock" (wireActionsBlock fields)
  pure (CheckedActionsBlock fields)

wireActionsBlock :: ActionsBlockFields -> Value
wireActionsBlock fields =
  object $
    ["type" .= ("actions" :: Text)] <> ["elements" .= (actionsBlockElements fields)] <> optional "block_id" (actionsBlockBlockId fields) <> extensionPairs (actionsBlockExtensions fields)

instance ToJSON ActionsBlock where toJSON (CheckedActionsBlock fields) = wireActionsBlock fields

instance FromSlackJSON ActionsBlock where
  fromSlackJSON value = do
    fields <- wireObject "actions" value
    parsedElements <- required "elements" fields
    parsedBlockId <- optionalField "block_id" fields
    buildActionsBlock (ActionsBlockFields parsedElements parsedBlockId (remaining ["elements", "block_id"] fields))

instance FromJSON ActionsBlock where parseJSON = checkedParser

-- | A severity-labelled alert, available in modals.
--
-- <https://docs.slack.dev/reference/block-kit/blocks/alert-block>
newtype AlertBlock = CheckedAlertBlock AlertBlockFields deriving (Eq, Show)

-- | Editable construction input. Call 'buildAlertBlock' before encoding.
data AlertBlockFields = AlertBlockFields
  { -- | Sets the alert message. Required. Shared limit: @alert.text@.
    alertBlockText :: TextObject,
    -- | Sets the alert severity, which controls its color and icon. Optional; Nothing omits the field. Factory default: @Nothing@.
    alertBlockLevel :: Maybe (AlertLevel),
    -- | Sets a unique identifier for this block. Slack returns it in interaction payloads, so use a stable value when you need to find the block again. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @block_id@.
    alertBlockBlockId :: Maybe (Text),
    -- | Unmodeled extension fields. Reserved and modeled keys are rejected.
    alertBlockExtensions :: Map Text Value
  }
  deriving (Eq, Show)

-- | Start editable fields for AlertBlock; required arguments follow the signature.
-- Optional fields start absent except the explicit shared defaults; no block ID is invented.
-- Finish with 'buildAlertBlock' to validate before JSON encoding.
alertBlock :: TextObject -> AlertBlockFields
alertBlock arg0 = AlertBlockFields (arg0) (Nothing) (Nothing) (Map.empty)

-- | Inspect immutable construction fields. Rebuild edits with 'buildAlertBlock' to revalidate.
inspectAlertBlock :: AlertBlock -> AlertBlockFields
inspectAlertBlock (CheckedAlertBlock fields) = fields

-- | Validate fields, extensions and receiving context. Return structured errors or a checked AlertBlock.
buildAlertBlock :: AlertBlockFields -> Result AlertBlock
buildAlertBlock fields = do
  checkExtensions ["text", "level", "block_id"] (alertBlockExtensions fields)
  validateFields "AlertBlock" (wireAlertBlock fields)
  pure (CheckedAlertBlock fields)

wireAlertBlock :: AlertBlockFields -> Value
wireAlertBlock fields =
  object $
    ["type" .= ("alert" :: Text)] <> ["text" .= (alertBlockText fields)] <> optional "level" (alertBlockLevel fields) <> optional "block_id" (alertBlockBlockId fields) <> extensionPairs (alertBlockExtensions fields)

instance ToJSON AlertBlock where toJSON (CheckedAlertBlock fields) = wireAlertBlock fields

instance FromSlackJSON AlertBlock where
  fromSlackJSON value = do
    fields <- wireObject "alert" value
    parsedText <- required "text" (coerceField "text" "mrkdwn" fields)
    parsedLevel <- optionalField "level" fields
    parsedBlockId <- optionalField "block_id" fields
    buildAlertBlock (AlertBlockFields parsedText parsedLevel parsedBlockId (remaining ["text", "level", "block_id"] fields))

instance FromJSON AlertBlock where parseJSON = checkedParser

-- | A compact card with an image, text, and up to three buttons.
--
-- <https://docs.slack.dev/reference/block-kit/blocks/card-block>
-- Provide at least one of a hero image, title, actions, or body.
-- An image icon and a Slack icon cannot be combined.
newtype CardBlock = CheckedCardBlock CardBlockFields deriving (Eq, Show)

-- | Editable construction input. Call 'buildCardBlock' before encoding.
data CardBlockFields = CardBlockFields
  { -- | Sets the image displayed prominently at the top of the card. Optional; Nothing omits the field. Factory default: @Nothing@.
    cardBlockHeroImage :: Maybe (ImageElement),
    -- | Sets the image displayed beside the title. Optional; Nothing omits the field. Factory default: @Nothing@.
    cardBlockIcon :: Maybe (ImageElement),
    -- | Sets the card title. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @card.title@.
    cardBlockTitle :: Maybe (TextObject),
    -- | Sets the supporting text shown below the title. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @card.subtitle@.
    cardBlockSubtitle :: Maybe (TextObject),
    -- | Sets the main body text of the card. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @card.body@.
    cardBlockBody :: Maybe (TextObject),
    -- | Adds buttons displayed at the bottom of the card, in display order. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @card.actions@.
    cardBlockActions :: Maybe ([ButtonElement]),
    -- | Sets a Slack-provided icon displayed beside the title. Cannot be combined with an image icon. Optional; Nothing omits the field. Factory default: @Nothing@.
    cardBlockSlackIcon :: Maybe (SlackIcon),
    -- | Sets the small print shown at the bottom of the card. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @card.subtext@.
    cardBlockSubtext :: Maybe (TextObject),
    -- | Sets a unique identifier for this block. Slack returns it in interaction payloads, so use a stable value when you need to find the block again. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @block_id@.
    cardBlockBlockId :: Maybe (Text),
    -- | Unmodeled extension fields. Reserved and modeled keys are rejected.
    cardBlockExtensions :: Map Text Value
  }
  deriving (Eq, Show)

-- | Start editable fields for CardBlock; required arguments follow the signature.
-- Optional fields start absent except the explicit shared defaults; no block ID is invented.
-- Finish with 'buildCardBlock' to validate before JSON encoding.
cardBlock :: CardBlockFields
cardBlock = CardBlockFields (Nothing) (Nothing) (Nothing) (Nothing) (Nothing) (Nothing) (Nothing) (Nothing) (Nothing) (Map.empty)

-- | Inspect immutable construction fields. Rebuild edits with 'buildCardBlock' to revalidate.
inspectCardBlock :: CardBlock -> CardBlockFields
inspectCardBlock (CheckedCardBlock fields) = fields

-- | Validate fields, extensions and receiving context. Return structured errors or a checked CardBlock.
buildCardBlock :: CardBlockFields -> Result CardBlock
buildCardBlock fields = do
  checkExtensions ["hero_image", "icon", "title", "subtitle", "body", "actions", "slack_icon", "subtext", "block_id"] (cardBlockExtensions fields)
  validateFields "CardBlock" (wireCardBlock fields)
  pure (CheckedCardBlock fields)

wireCardBlock :: CardBlockFields -> Value
wireCardBlock fields =
  object $
    ["type" .= ("card" :: Text)] <> optional "hero_image" (cardBlockHeroImage fields) <> optional "icon" (cardBlockIcon fields) <> optional "title" (cardBlockTitle fields) <> optional "subtitle" (cardBlockSubtitle fields) <> optional "body" (cardBlockBody fields) <> optional "actions" (cardBlockActions fields) <> optional "slack_icon" (cardBlockSlackIcon fields) <> optional "subtext" (cardBlockSubtext fields) <> optional "block_id" (cardBlockBlockId fields) <> extensionPairs (cardBlockExtensions fields)

instance ToJSON CardBlock where toJSON (CheckedCardBlock fields) = wireCardBlock fields

instance FromSlackJSON CardBlock where
  fromSlackJSON value = do
    fields <- wireObject "card" value
    parsedHeroImage <- optionalField "hero_image" fields
    parsedIcon <- optionalField "icon" fields
    parsedTitle <- optionalField "title" (coerceField "title" "mrkdwn" fields)
    parsedSubtitle <- optionalField "subtitle" (coerceField "subtitle" "mrkdwn" fields)
    parsedBody <- optionalField "body" (coerceField "body" "mrkdwn" fields)
    parsedActions <- optionalField "actions" fields
    parsedSlackIcon <- optionalField "slack_icon" fields
    parsedSubtext <- optionalField "subtext" (coerceField "subtext" "mrkdwn" fields)
    parsedBlockId <- optionalField "block_id" fields
    buildCardBlock (CardBlockFields parsedHeroImage parsedIcon parsedTitle parsedSubtitle parsedBody parsedActions parsedSlackIcon parsedSubtext parsedBlockId (remaining ["hero_image", "icon", "title", "subtitle", "body", "actions", "slack_icon", "subtext", "block_id"] fields))

instance FromJSON CardBlock where parseJSON = checkedParser

-- | A horizontally scrolling set of cards, available in messages and App Home.
--
-- <https://docs.slack.dev/reference/block-kit/blocks/carousel-block>
newtype CarouselBlock = CheckedCarouselBlock CarouselBlockFields deriving (Eq, Show)

-- | Editable construction input. Call 'buildCarouselBlock' before encoding.
data CarouselBlockFields = CarouselBlockFields
  { -- | Adds the cards in display order. Required. Shared limit: @carousel.elements@.
    carouselBlockElements :: [CardBlock],
    -- | Sets a unique identifier for this block. Slack returns it in interaction payloads, so use a stable value when you need to find the block again. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @block_id@.
    carouselBlockBlockId :: Maybe (Text),
    -- | Unmodeled extension fields. Reserved and modeled keys are rejected.
    carouselBlockExtensions :: Map Text Value
  }
  deriving (Eq, Show)

-- | Start editable fields for CarouselBlock; required arguments follow the signature.
-- Optional fields start absent except the explicit shared defaults; no block ID is invented.
-- Finish with 'buildCarouselBlock' to validate before JSON encoding.
carouselBlock :: [CardBlock] -> CarouselBlockFields
carouselBlock arg0 = CarouselBlockFields (arg0) (Nothing) (Map.empty)

-- | Inspect immutable construction fields. Rebuild edits with 'buildCarouselBlock' to revalidate.
inspectCarouselBlock :: CarouselBlock -> CarouselBlockFields
inspectCarouselBlock (CheckedCarouselBlock fields) = fields

-- | Validate fields, extensions and receiving context. Return structured errors or a checked CarouselBlock.
buildCarouselBlock :: CarouselBlockFields -> Result CarouselBlock
buildCarouselBlock fields = do
  checkExtensions ["elements", "block_id"] (carouselBlockExtensions fields)
  validateFields "CarouselBlock" (wireCarouselBlock fields)
  pure (CheckedCarouselBlock fields)

wireCarouselBlock :: CarouselBlockFields -> Value
wireCarouselBlock fields =
  object $
    ["type" .= ("carousel" :: Text)] <> ["elements" .= (carouselBlockElements fields)] <> optional "block_id" (carouselBlockBlockId fields) <> extensionPairs (carouselBlockExtensions fields)

instance ToJSON CarouselBlock where toJSON (CheckedCarouselBlock fields) = wireCarouselBlock fields

instance FromSlackJSON CarouselBlock where
  fromSlackJSON value = do
    fields <- wireObject "carousel" value
    parsedElements <- required "elements" fields
    parsedBlockId <- optionalField "block_id" fields
    buildCarouselBlock (CarouselBlockFields parsedElements parsedBlockId (remaining ["elements", "block_id"] fields))

instance FromJSON CarouselBlock where parseJSON = checkedParser

-- | A titled group of blocks that can optionally collapse.
--
-- <https://docs.slack.dev/reference/block-kit/blocks/container-block>
-- Provide a title or a rich text title.
newtype ContainerBlock = CheckedContainerBlock ContainerBlockFields deriving (Eq, Show)

-- | Editable construction input. Call 'buildContainerBlock' before encoding.
data ContainerBlockFields = ContainerBlockFields
  { -- | Adds the blocks grouped inside the container, in display order. Required. Shared limit: @container.child_blocks@.
    containerBlockChildBlocks :: [Block],
    -- | Sets the container title. Provide either a title or a rich text title. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @container.title@.
    containerBlockTitle :: Maybe (PlainText),
    -- | Sets a rich text block used as the title in place of a plain-text title. Optional; Nothing omits the field. Factory default: @Nothing@.
    containerBlockRichTextTitle :: Maybe (RichTextBlock),
    -- | Sets the supporting text shown below the title. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @container.subtitle@.
    containerBlockSubtitle :: Maybe (TextObject),
    -- | Sets the horizontal width of the container. Optional; Nothing omits the field. Factory default: @Nothing@.
    containerBlockWidth :: Maybe (ContainerWidth),
    -- | Sets the image displayed beside the title. Optional; Nothing omits the field. Factory default: @Nothing@.
    containerBlockIcon :: Maybe (ImageElement),
    -- | Sets whether users can collapse and expand the container. Optional; Nothing omits the field. Factory default: @Nothing@.
    containerBlockIsCollapsible :: Maybe (Bool),
    -- | Sets whether a collapsible container starts collapsed. Requires the container to be collapsible. Optional; Nothing omits the field. Factory default: @Nothing@.
    containerBlockDefaultCollapsed :: Maybe (Bool),
    -- | Sets whether Slack draws a divider below the container header. Only valid for non-collapsible containers. Optional; Nothing omits the field. Factory default: @Nothing@.
    containerBlockHasHeaderDivider :: Maybe (Bool),
    -- | Sets a unique identifier for this block. Slack returns it in interaction payloads, so use a stable value when you need to find the block again. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @block_id@.
    containerBlockBlockId :: Maybe (Text),
    -- | Unmodeled extension fields. Reserved and modeled keys are rejected.
    containerBlockExtensions :: Map Text Value
  }
  deriving (Eq, Show)

-- | Start editable fields for ContainerBlock; required arguments follow the signature.
-- Optional fields start absent except the explicit shared defaults; no block ID is invented.
-- Finish with 'buildContainerBlock' to validate before JSON encoding.
containerBlock :: [Block] -> ContainerBlockFields
containerBlock arg0 = ContainerBlockFields (arg0) (Nothing) (Nothing) (Nothing) (Nothing) (Nothing) (Nothing) (Nothing) (Nothing) (Nothing) (Map.empty)

-- | Inspect immutable construction fields. Rebuild edits with 'buildContainerBlock' to revalidate.
inspectContainerBlock :: ContainerBlock -> ContainerBlockFields
inspectContainerBlock (CheckedContainerBlock fields) = fields

-- | Validate fields, extensions and receiving context. Return structured errors or a checked ContainerBlock.
buildContainerBlock :: ContainerBlockFields -> Result ContainerBlock
buildContainerBlock fields = do
  checkExtensions ["child_blocks", "title", "rich_text_title", "subtitle", "width", "icon", "is_collapsible", "default_collapsed", "has_header_divider", "block_id"] (containerBlockExtensions fields)
  validateFields "ContainerBlock" (wireContainerBlock fields)
  pure (CheckedContainerBlock fields)

wireContainerBlock :: ContainerBlockFields -> Value
wireContainerBlock fields =
  object $
    ["type" .= ("container" :: Text)] <> ["child_blocks" .= (containerBlockChildBlocks fields)] <> optional "title" (containerBlockTitle fields) <> optional "rich_text_title" (containerBlockRichTextTitle fields) <> optional "subtitle" (containerBlockSubtitle fields) <> optional "width" (containerBlockWidth fields) <> optional "icon" (containerBlockIcon fields) <> optional "is_collapsible" (containerBlockIsCollapsible fields) <> optional "default_collapsed" (containerBlockDefaultCollapsed fields) <> optional "has_header_divider" (containerBlockHasHeaderDivider fields) <> optional "block_id" (containerBlockBlockId fields) <> extensionPairs (containerBlockExtensions fields)

instance ToJSON ContainerBlock where toJSON (CheckedContainerBlock fields) = wireContainerBlock fields

instance FromSlackJSON ContainerBlock where
  fromSlackJSON value = do
    fields <- wireObject "container" value
    parsedChildBlocks <- required "child_blocks" fields
    parsedTitle <- optionalField "title" (coerceField "title" "plain_text" fields)
    parsedRichTextTitle <- optionalField "rich_text_title" fields
    parsedSubtitle <- optionalField "subtitle" (coerceField "subtitle" "mrkdwn" fields)
    parsedWidth <- optionalField "width" fields
    parsedIcon <- optionalField "icon" fields
    parsedIsCollapsible <- optionalField "is_collapsible" fields
    parsedDefaultCollapsed <- optionalField "default_collapsed" fields
    parsedHasHeaderDivider <- optionalField "has_header_divider" fields
    parsedBlockId <- optionalField "block_id" fields
    buildContainerBlock (ContainerBlockFields parsedChildBlocks parsedTitle parsedRichTextTitle parsedSubtitle parsedWidth parsedIcon parsedIsCollapsible parsedDefaultCollapsed parsedHasHeaderDivider parsedBlockId (remaining ["child_blocks", "title", "rich_text_title", "subtitle", "width", "icon", "is_collapsible", "default_collapsed", "has_header_divider", "block_id"] fields))

instance FromJSON ContainerBlock where parseJSON = checkedParser

-- | A row of feedback or icon buttons, usually shown below AI-generated content.
--
-- <https://docs.slack.dev/reference/block-kit/blocks/context-actions-block>
newtype ContextActionsBlock = CheckedContextActionsBlock ContextActionsBlockFields deriving (Eq, Show)

-- | Editable construction input. Call 'buildContextActionsBlock' before encoding.
data ContextActionsBlockFields = ContextActionsBlockFields
  { -- | Adds feedback buttons or icon buttons in display order. Required. Shared limit: @context_actions.elements@.
    contextActionsBlockElements :: [ContextActionsElement],
    -- | Sets a unique identifier for this block. Slack returns it in interaction payloads, so use a stable value when you need to find the block again. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @block_id@.
    contextActionsBlockBlockId :: Maybe (Text),
    -- | Unmodeled extension fields. Reserved and modeled keys are rejected.
    contextActionsBlockExtensions :: Map Text Value
  }
  deriving (Eq, Show)

-- | Start editable fields for ContextActionsBlock; required arguments follow the signature.
-- Optional fields start absent except the explicit shared defaults; no block ID is invented.
-- Finish with 'buildContextActionsBlock' to validate before JSON encoding.
contextActionsBlock :: [ContextActionsElement] -> ContextActionsBlockFields
contextActionsBlock arg0 = ContextActionsBlockFields (arg0) (Nothing) (Map.empty)

-- | Inspect immutable construction fields. Rebuild edits with 'buildContextActionsBlock' to revalidate.
inspectContextActionsBlock :: ContextActionsBlock -> ContextActionsBlockFields
inspectContextActionsBlock (CheckedContextActionsBlock fields) = fields

-- | Validate fields, extensions and receiving context. Return structured errors or a checked ContextActionsBlock.
buildContextActionsBlock :: ContextActionsBlockFields -> Result ContextActionsBlock
buildContextActionsBlock fields = do
  checkExtensions ["elements", "block_id"] (contextActionsBlockExtensions fields)
  validateFields "ContextActionsBlock" (wireContextActionsBlock fields)
  pure (CheckedContextActionsBlock fields)

wireContextActionsBlock :: ContextActionsBlockFields -> Value
wireContextActionsBlock fields =
  object $
    ["type" .= ("context_actions" :: Text)] <> ["elements" .= (contextActionsBlockElements fields)] <> optional "block_id" (contextActionsBlockBlockId fields) <> extensionPairs (contextActionsBlockExtensions fields)

instance ToJSON ContextActionsBlock where toJSON (CheckedContextActionsBlock fields) = wireContextActionsBlock fields

instance FromSlackJSON ContextActionsBlock where
  fromSlackJSON value = do
    fields <- wireObject "context_actions" value
    parsedElements <- required "elements" fields
    parsedBlockId <- optionalField "block_id" fields
    buildContextActionsBlock (ContextActionsBlockFields parsedElements parsedBlockId (remaining ["elements", "block_id"] fields))

instance FromJSON ContextActionsBlock where parseJSON = checkedParser

-- | A block of small, secondary images and text.
--
-- <https://docs.slack.dev/reference/block-kit/blocks/context-block>
newtype ContextBlock = CheckedContextBlock ContextBlockFields deriving (Eq, Show)

-- | Editable construction input. Call 'buildContextBlock' before encoding.
data ContextBlockFields = ContextBlockFields
  { -- | Adds images and text in display order. Required. Shared limit: @context.elements@.
    contextBlockElements :: [ContextElement],
    -- | Sets a unique identifier for this block. Slack returns it in interaction payloads, so use a stable value when you need to find the block again. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @block_id@.
    contextBlockBlockId :: Maybe (Text),
    -- | Unmodeled extension fields. Reserved and modeled keys are rejected.
    contextBlockExtensions :: Map Text Value
  }
  deriving (Eq, Show)

-- | Start editable fields for ContextBlock; required arguments follow the signature.
-- Optional fields start absent except the explicit shared defaults; no block ID is invented.
-- Finish with 'buildContextBlock' to validate before JSON encoding.
contextBlock :: [ContextElement] -> ContextBlockFields
contextBlock arg0 = ContextBlockFields (arg0) (Nothing) (Map.empty)

-- | Inspect immutable construction fields. Rebuild edits with 'buildContextBlock' to revalidate.
inspectContextBlock :: ContextBlock -> ContextBlockFields
inspectContextBlock (CheckedContextBlock fields) = fields

-- | Validate fields, extensions and receiving context. Return structured errors or a checked ContextBlock.
buildContextBlock :: ContextBlockFields -> Result ContextBlock
buildContextBlock fields = do
  checkExtensions ["elements", "block_id"] (contextBlockExtensions fields)
  validateFields "ContextBlock" (wireContextBlock fields)
  pure (CheckedContextBlock fields)

wireContextBlock :: ContextBlockFields -> Value
wireContextBlock fields =
  object $
    ["type" .= ("context" :: Text)] <> ["elements" .= (contextBlockElements fields)] <> optional "block_id" (contextBlockBlockId fields) <> extensionPairs (contextBlockExtensions fields)

instance ToJSON ContextBlock where toJSON (CheckedContextBlock fields) = wireContextBlock fields

instance FromSlackJSON ContextBlock where
  fromSlackJSON value = do
    fields <- wireObject "context" value
    parsedElements <- required "elements" fields
    parsedBlockId <- optionalField "block_id" fields
    buildContextBlock (ContextBlockFields parsedElements parsedBlockId (remaining ["elements", "block_id"] fields))

instance FromJSON ContextBlock where parseJSON = checkedParser

-- | A sortable, paginated table of raw text, numbers, and rich text.
--
-- <https://docs.slack.dev/reference/block-kit/blocks/data-table-block>
-- The first row is the header row and cannot contain rich text.
-- Every row must have the same number of cells, and all cell text together is limited to 20,000 characters.
newtype DataTableBlock = CheckedDataTableBlock DataTableBlockFields deriving (Eq, Show)

-- | Editable construction input. Call 'buildDataTableBlock' before encoding.
data DataTableBlockFields = DataTableBlockFields
  { -- | Adds complete table rows in display order. Every row must have the same number of cells. Required. Shared limit: @data_table.rows@.
    dataTableBlockRows :: [[DataTableCell]],
    -- | Sets the caption that describes the table's contents. Required.
    dataTableBlockCaption :: Text,
    -- | Sets how many rows Slack shows per page. Optional; Nothing omits the field. Factory default: @Just (5)@. Shared limit: @data_table.page_size@.
    dataTableBlockPageSize :: Maybe (Integer),
    -- | Sets the zero-based index of the column whose cells act as row headers. Optional; Nothing omits the field. Factory default: @Just (0)@. Shared limit: @data_table.row_header_column_index@.
    dataTableBlockRowHeaderColumnIndex :: Maybe (Integer),
    -- | Sets a unique identifier for this block. Slack returns it in interaction payloads, so use a stable value when you need to find the block again. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @block_id@.
    dataTableBlockBlockId :: Maybe (Text),
    -- | Unmodeled extension fields. Reserved and modeled keys are rejected.
    dataTableBlockExtensions :: Map Text Value
  }
  deriving (Eq, Show)

-- | Start editable fields for DataTableBlock; required arguments follow the signature.
-- Optional fields start absent except the explicit shared defaults; no block ID is invented.
-- Finish with 'buildDataTableBlock' to validate before JSON encoding.
dataTableBlock :: [[DataTableCell]] -> Text -> DataTableBlockFields
dataTableBlock arg0 arg1 = DataTableBlockFields (arg0) (arg1) (Just (5)) (Just (0)) (Nothing) (Map.empty)

-- | Inspect immutable construction fields. Rebuild edits with 'buildDataTableBlock' to revalidate.
inspectDataTableBlock :: DataTableBlock -> DataTableBlockFields
inspectDataTableBlock (CheckedDataTableBlock fields) = fields

-- | Validate fields, extensions and receiving context. Return structured errors or a checked DataTableBlock.
buildDataTableBlock :: DataTableBlockFields -> Result DataTableBlock
buildDataTableBlock fields = do
  checkExtensions ["rows", "caption", "page_size", "row_header_column_index", "block_id"] (dataTableBlockExtensions fields)
  validateFields "DataTableBlock" (wireDataTableBlock fields)
  pure (CheckedDataTableBlock fields)

wireDataTableBlock :: DataTableBlockFields -> Value
wireDataTableBlock fields =
  object $
    ["type" .= ("data_table" :: Text)] <> ["rows" .= (dataTableBlockRows fields)] <> ["caption" .= (dataTableBlockCaption fields)] <> optional "page_size" (dataTableBlockPageSize fields) <> optional "row_header_column_index" (dataTableBlockRowHeaderColumnIndex fields) <> optional "block_id" (dataTableBlockBlockId fields) <> extensionPairs (dataTableBlockExtensions fields)

instance ToJSON DataTableBlock where toJSON (CheckedDataTableBlock fields) = wireDataTableBlock fields

instance FromSlackJSON DataTableBlock where
  fromSlackJSON value = do
    fields <- wireObject "data_table" value
    checkIntegerBounds "DataTableBlock" (Object fields)
    parsedRows <- required "rows" fields
    parsedCaption <- required "caption" fields
    parsedPageSize <- optionalField "page_size" fields
    parsedRowHeaderColumnIndex <- optionalField "row_header_column_index" fields
    parsedBlockId <- optionalField "block_id" fields
    buildDataTableBlock (DataTableBlockFields parsedRows parsedCaption parsedPageSize parsedRowHeaderColumnIndex parsedBlockId (remaining ["rows", "caption", "page_size", "row_header_column_index", "block_id"] fields))

instance FromJSON DataTableBlock where parseJSON = checkedParser

-- | A titled pie, bar, area, or line chart.
--
-- <https://docs.slack.dev/reference/block-kit/blocks/data-visualization-block>
newtype DataVisualizationBlock = CheckedDataVisualizationBlock DataVisualizationBlockFields deriving (Eq, Show)

-- | Editable construction input. Call 'buildDataVisualizationBlock' before encoding.
data DataVisualizationBlockFields = DataVisualizationBlockFields
  { -- | Sets the chart title. Required. Shared limit: @data_visualization.title@.
    dataVisualizationBlockTitle :: Text,
    -- | Sets the chart to display. Required.
    dataVisualizationBlockChart :: Chart,
    -- | Sets a unique identifier for this block. Slack returns it in interaction payloads, so use a stable value when you need to find the block again. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @block_id@.
    dataVisualizationBlockBlockId :: Maybe (Text),
    -- | Unmodeled extension fields. Reserved and modeled keys are rejected.
    dataVisualizationBlockExtensions :: Map Text Value
  }
  deriving (Eq, Show)

-- | Start editable fields for DataVisualizationBlock; required arguments follow the signature.
-- Optional fields start absent except the explicit shared defaults; no block ID is invented.
-- Finish with 'buildDataVisualizationBlock' to validate before JSON encoding.
dataVisualizationBlock :: Text -> Chart -> DataVisualizationBlockFields
dataVisualizationBlock arg0 arg1 = DataVisualizationBlockFields (arg0) (arg1) (Nothing) (Map.empty)

-- | Inspect immutable construction fields. Rebuild edits with 'buildDataVisualizationBlock' to revalidate.
inspectDataVisualizationBlock :: DataVisualizationBlock -> DataVisualizationBlockFields
inspectDataVisualizationBlock (CheckedDataVisualizationBlock fields) = fields

-- | Validate fields, extensions and receiving context. Return structured errors or a checked DataVisualizationBlock.
buildDataVisualizationBlock :: DataVisualizationBlockFields -> Result DataVisualizationBlock
buildDataVisualizationBlock fields = do
  checkExtensions ["title", "chart", "block_id"] (dataVisualizationBlockExtensions fields)
  validateFields "DataVisualizationBlock" (wireDataVisualizationBlock fields)
  pure (CheckedDataVisualizationBlock fields)

wireDataVisualizationBlock :: DataVisualizationBlockFields -> Value
wireDataVisualizationBlock fields =
  object $
    ["type" .= ("data_visualization" :: Text)] <> ["title" .= (dataVisualizationBlockTitle fields)] <> ["chart" .= (dataVisualizationBlockChart fields)] <> optional "block_id" (dataVisualizationBlockBlockId fields) <> extensionPairs (dataVisualizationBlockExtensions fields)

instance ToJSON DataVisualizationBlock where toJSON (CheckedDataVisualizationBlock fields) = wireDataVisualizationBlock fields

instance FromSlackJSON DataVisualizationBlock where
  fromSlackJSON value = do
    fields <- wireObject "data_visualization" value
    parsedTitle <- required "title" fields
    parsedChart <- required "chart" fields
    parsedBlockId <- optionalField "block_id" fields
    buildDataVisualizationBlock (DataVisualizationBlockFields parsedTitle parsedChart parsedBlockId (remaining ["title", "chart", "block_id"] fields))

instance FromJSON DataVisualizationBlock where parseJSON = checkedParser

-- | A horizontal rule that separates blocks.
--
-- <https://docs.slack.dev/reference/block-kit/blocks/divider-block>
newtype DividerBlock = CheckedDividerBlock DividerBlockFields deriving (Eq, Show)

-- | Editable construction input. Call 'buildDividerBlock' before encoding.
data DividerBlockFields = DividerBlockFields
  { -- | Sets a unique identifier for this block. Slack returns it in interaction payloads, so use a stable value when you need to find the block again. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @block_id@.
    dividerBlockBlockId :: Maybe (Text),
    -- | Unmodeled extension fields. Reserved and modeled keys are rejected.
    dividerBlockExtensions :: Map Text Value
  }
  deriving (Eq, Show)

-- | Start editable fields for DividerBlock; required arguments follow the signature.
-- Optional fields start absent except the explicit shared defaults; no block ID is invented.
-- Finish with 'buildDividerBlock' to validate before JSON encoding.
dividerBlock :: DividerBlockFields
dividerBlock = DividerBlockFields (Nothing) (Map.empty)

-- | Inspect immutable construction fields. Rebuild edits with 'buildDividerBlock' to revalidate.
inspectDividerBlock :: DividerBlock -> DividerBlockFields
inspectDividerBlock (CheckedDividerBlock fields) = fields

-- | Validate fields, extensions and receiving context. Return structured errors or a checked DividerBlock.
buildDividerBlock :: DividerBlockFields -> Result DividerBlock
buildDividerBlock fields = do
  checkExtensions ["block_id"] (dividerBlockExtensions fields)
  validateFields "DividerBlock" (wireDividerBlock fields)
  pure (CheckedDividerBlock fields)

wireDividerBlock :: DividerBlockFields -> Value
wireDividerBlock fields =
  object $
    ["type" .= ("divider" :: Text)] <> optional "block_id" (dividerBlockBlockId fields) <> extensionPairs (dividerBlockExtensions fields)

instance ToJSON DividerBlock where toJSON (CheckedDividerBlock fields) = wireDividerBlock fields

instance FromSlackJSON DividerBlock where
  fromSlackJSON value = do
    fields <- wireObject "divider" value
    parsedBlockId <- optionalField "block_id" fields
    buildDividerBlock (DividerBlockFields parsedBlockId (remaining ["block_id"] fields))

instance FromJSON DividerBlock where parseJSON = checkedParser

-- | A remote file previously added with the files.remote API.
--
-- <https://docs.slack.dev/reference/block-kit/blocks/file-block>
newtype FileBlock = CheckedFileBlock FileBlockFields deriving (Eq, Show)

-- | Editable construction input. Call 'buildFileBlock' before encoding.
data FileBlockFields = FileBlockFields
  { -- | Sets the external identifier of a remote file previously added with the files.remote API. Required.
    fileBlockExternalId :: Text,
    -- | Sets the file source. Slack currently supports only remote files. Required.
    fileBlockSource :: Text,
    -- | Sets a unique identifier for this block. Slack returns it in interaction payloads, so use a stable value when you need to find the block again. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @block_id@.
    fileBlockBlockId :: Maybe (Text),
    -- | Unmodeled extension fields. Reserved and modeled keys are rejected.
    fileBlockExtensions :: Map Text Value
  }
  deriving (Eq, Show)

-- | Start editable fields for FileBlock; required arguments follow the signature.
-- Optional fields start absent except the explicit shared defaults; no block ID is invented.
-- Finish with 'buildFileBlock' to validate before JSON encoding.
fileBlock :: Text -> Text -> FileBlockFields
fileBlock arg0 arg1 = FileBlockFields (arg0) (arg1) (Nothing) (Map.empty)

-- | Inspect immutable construction fields. Rebuild edits with 'buildFileBlock' to revalidate.
inspectFileBlock :: FileBlock -> FileBlockFields
inspectFileBlock (CheckedFileBlock fields) = fields

-- | Validate fields, extensions and receiving context. Return structured errors or a checked FileBlock.
buildFileBlock :: FileBlockFields -> Result FileBlock
buildFileBlock fields = do
  checkExtensions ["external_id", "source", "block_id"] (fileBlockExtensions fields)
  validateFields "FileBlock" (wireFileBlock fields)
  pure (CheckedFileBlock fields)

wireFileBlock :: FileBlockFields -> Value
wireFileBlock fields =
  object $
    ["type" .= ("file" :: Text)] <> ["external_id" .= (fileBlockExternalId fields)] <> ["source" .= (fileBlockSource fields)] <> optional "block_id" (fileBlockBlockId fields) <> extensionPairs (fileBlockExtensions fields)

instance ToJSON FileBlock where toJSON (CheckedFileBlock fields) = wireFileBlock fields

instance FromSlackJSON FileBlock where
  fromSlackJSON value = do
    fields <- wireObject "file" value
    parsedExternalId <- required "external_id" fields
    parsedSource <- required "source" fields
    parsedBlockId <- optionalField "block_id" fields
    buildFileBlock (FileBlockFields parsedExternalId parsedSource parsedBlockId (remaining ["external_id", "source", "block_id"] fields))

instance FromJSON FileBlock where parseJSON = checkedParser

-- | Large, bold plain text that introduces a group of blocks.
--
-- <https://docs.slack.dev/reference/block-kit/blocks/header-block>
newtype HeaderBlock = CheckedHeaderBlock HeaderBlockFields deriving (Eq, Show)

-- | Editable construction input. Call 'buildHeaderBlock' before encoding.
data HeaderBlockFields = HeaderBlockFields
  { -- | Sets the header text, shown in a larger bold font. Required. Shared limit: @header.text@.
    headerBlockText :: PlainText,
    -- | Sets a unique identifier for this block. Slack returns it in interaction payloads, so use a stable value when you need to find the block again. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @block_id@.
    headerBlockBlockId :: Maybe (Text),
    -- | Unmodeled extension fields. Reserved and modeled keys are rejected.
    headerBlockExtensions :: Map Text Value
  }
  deriving (Eq, Show)

-- | Start editable fields for HeaderBlock; required arguments follow the signature.
-- Optional fields start absent except the explicit shared defaults; no block ID is invented.
-- Finish with 'buildHeaderBlock' to validate before JSON encoding.
headerBlock :: PlainText -> HeaderBlockFields
headerBlock arg0 = HeaderBlockFields (arg0) (Nothing) (Map.empty)

-- | Inspect immutable construction fields. Rebuild edits with 'buildHeaderBlock' to revalidate.
inspectHeaderBlock :: HeaderBlock -> HeaderBlockFields
inspectHeaderBlock (CheckedHeaderBlock fields) = fields

-- | Validate fields, extensions and receiving context. Return structured errors or a checked HeaderBlock.
buildHeaderBlock :: HeaderBlockFields -> Result HeaderBlock
buildHeaderBlock fields = do
  checkExtensions ["text", "block_id"] (headerBlockExtensions fields)
  validateFields "HeaderBlock" (wireHeaderBlock fields)
  pure (CheckedHeaderBlock fields)

wireHeaderBlock :: HeaderBlockFields -> Value
wireHeaderBlock fields =
  object $
    ["type" .= ("header" :: Text)] <> ["text" .= (headerBlockText fields)] <> optional "block_id" (headerBlockBlockId fields) <> extensionPairs (headerBlockExtensions fields)

instance ToJSON HeaderBlock where toJSON (CheckedHeaderBlock fields) = wireHeaderBlock fields

instance FromSlackJSON HeaderBlock where
  fromSlackJSON value = do
    fields <- wireObject "header" value
    parsedText <- required "text" (coerceField "text" "plain_text" fields)
    parsedBlockId <- optionalField "block_id" fields
    buildHeaderBlock (HeaderBlockFields parsedText parsedBlockId (remaining ["text", "block_id"] fields))

instance FromJSON HeaderBlock where parseJSON = checkedParser

-- | A standalone image with alternative text and an optional title.
--
-- <https://docs.slack.dev/reference/block-kit/blocks/image-block>
-- Provide exactly one of an image URL or a Slack file.
newtype ImageBlock = CheckedImageBlock ImageBlockFields deriving (Eq, Show)

-- | Editable construction input. Call 'buildImageBlock' before encoding.
data ImageBlockFields = ImageBlockFields
  { -- | Sets the publicly accessible URL of the image. Cannot be combined with a Slack file. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @image.image_url@.
    imageBlockImageUrl :: Maybe (Text),
    -- | Sets a file hosted in Slack as the image source. Cannot be combined with an image URL. Optional; Nothing omits the field. Factory default: @Nothing@.
    imageBlockSlackFile :: Maybe (SlackFile),
    -- | Sets a plain-text summary of the image or video for assistive technology. Required. Shared limit: @image.alt_text@.
    imageBlockAltText :: Text,
    -- | Sets the title shown above the image. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @image.title@.
    imageBlockTitle :: Maybe (PlainText),
    -- | Sets a unique identifier for this block. Slack returns it in interaction payloads, so use a stable value when you need to find the block again. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @block_id@.
    imageBlockBlockId :: Maybe (Text),
    -- | Unmodeled extension fields. Reserved and modeled keys are rejected.
    imageBlockExtensions :: Map Text Value
  }
  deriving (Eq, Show)

-- | Start editable fields for ImageBlock; required arguments follow the signature.
-- Optional fields start absent except the explicit shared defaults; no block ID is invented.
-- Finish with 'buildImageBlock' to validate before JSON encoding.
imageBlock :: Text -> ImageBlockFields
imageBlock arg0 = ImageBlockFields (Nothing) (Nothing) (arg0) (Nothing) (Nothing) (Map.empty)

-- | Inspect immutable construction fields. Rebuild edits with 'buildImageBlock' to revalidate.
inspectImageBlock :: ImageBlock -> ImageBlockFields
inspectImageBlock (CheckedImageBlock fields) = fields

-- | Validate fields, extensions and receiving context. Return structured errors or a checked ImageBlock.
buildImageBlock :: ImageBlockFields -> Result ImageBlock
buildImageBlock fields = do
  checkExtensions ["image_url", "slack_file", "alt_text", "title", "block_id"] (imageBlockExtensions fields)
  validateFields "ImageBlock" (wireImageBlock fields)
  pure (CheckedImageBlock fields)

wireImageBlock :: ImageBlockFields -> Value
wireImageBlock fields =
  object $
    ["type" .= ("image" :: Text)] <> optional "image_url" (imageBlockImageUrl fields) <> optional "slack_file" (imageBlockSlackFile fields) <> ["alt_text" .= (imageBlockAltText fields)] <> optional "title" (imageBlockTitle fields) <> optional "block_id" (imageBlockBlockId fields) <> extensionPairs (imageBlockExtensions fields)

instance ToJSON ImageBlock where toJSON (CheckedImageBlock fields) = wireImageBlock fields

instance FromSlackJSON ImageBlock where
  fromSlackJSON value = do
    fields <- wireObject "image" value
    parsedImageUrl <- optionalField "image_url" fields
    parsedSlackFile <- optionalField "slack_file" fields
    parsedAltText <- required "alt_text" fields
    parsedTitle <- optionalField "title" (coerceField "title" "plain_text" fields)
    parsedBlockId <- optionalField "block_id" fields
    buildImageBlock (ImageBlockFields parsedImageUrl parsedSlackFile parsedAltText parsedTitle parsedBlockId (remaining ["image_url", "slack_file", "alt_text", "title", "block_id"] fields))

instance FromJSON ImageBlock where parseJSON = checkedParser

-- | A labelled input that collects a value in a modal, App Home, or message.
--
-- <https://docs.slack.dev/reference/block-kit/blocks/input-block>
newtype InputBlock = CheckedInputBlock InputBlockFields deriving (Eq, Show)

-- | Editable construction input. Call 'buildInputBlock' before encoding.
data InputBlockFields = InputBlockFields
  { -- | Sets the label shown above the input. Required. Shared limit: @input.label@.
    inputBlockLabel :: PlainText,
    -- | Sets the input element that collects the user's value. Required.
    inputBlockElement :: InputElement,
    -- | Sets whether changing the element sends a block_actions payload immediately. Optional; Nothing omits the field. Factory default: @Nothing@.
    inputBlockDispatchAction :: Maybe (Bool),
    -- | Sets a unique identifier for this block. Slack returns it in interaction payloads, so use a stable value when you need to find the block again. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @block_id@.
    inputBlockBlockId :: Maybe (Text),
    -- | Sets helper text shown below the input. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @input.hint@.
    inputBlockHint :: Maybe (PlainText),
    -- | Sets whether the modal can be submitted when this input is empty. Optional; Nothing omits the field. Factory default: @Nothing@.
    inputBlockOptional :: Maybe (Bool),
    -- | Unmodeled extension fields. Reserved and modeled keys are rejected.
    inputBlockExtensions :: Map Text Value
  }
  deriving (Eq, Show)

-- | Start editable fields for InputBlock; required arguments follow the signature.
-- Optional fields start absent except the explicit shared defaults; no block ID is invented.
-- Finish with 'buildInputBlock' to validate before JSON encoding.
inputBlock :: PlainText -> InputElement -> InputBlockFields
inputBlock arg0 arg1 = InputBlockFields (arg0) (arg1) (Nothing) (Nothing) (Nothing) (Nothing) (Map.empty)

-- | Inspect immutable construction fields. Rebuild edits with 'buildInputBlock' to revalidate.
inspectInputBlock :: InputBlock -> InputBlockFields
inspectInputBlock (CheckedInputBlock fields) = fields

-- | Validate fields, extensions and receiving context. Return structured errors or a checked InputBlock.
buildInputBlock :: InputBlockFields -> Result InputBlock
buildInputBlock fields = do
  checkExtensions ["label", "element", "dispatch_action", "block_id", "hint", "optional"] (inputBlockExtensions fields)
  validateFields "InputBlock" (wireInputBlock fields)
  pure (CheckedInputBlock fields)

wireInputBlock :: InputBlockFields -> Value
wireInputBlock fields =
  object $
    ["type" .= ("input" :: Text)] <> ["label" .= (inputBlockLabel fields)] <> ["element" .= (inputBlockElement fields)] <> optional "dispatch_action" (inputBlockDispatchAction fields) <> optional "block_id" (inputBlockBlockId fields) <> optional "hint" (inputBlockHint fields) <> optional "optional" (inputBlockOptional fields) <> extensionPairs (inputBlockExtensions fields)

instance ToJSON InputBlock where toJSON (CheckedInputBlock fields) = wireInputBlock fields

instance FromSlackJSON InputBlock where
  fromSlackJSON value = do
    fields <- wireObject "input" value
    parsedLabel <- required "label" (coerceField "label" "plain_text" fields)
    parsedElement <- required "element" fields
    parsedDispatchAction <- optionalField "dispatch_action" fields
    parsedBlockId <- optionalField "block_id" fields
    parsedHint <- optionalField "hint" (coerceField "hint" "plain_text" fields)
    parsedOptional <- optionalField "optional" fields
    buildInputBlock (InputBlockFields parsedLabel parsedElement parsedDispatchAction parsedBlockId parsedHint parsedOptional (remaining ["label", "element", "dispatch_action", "block_id", "hint", "optional"] fields))

instance FromJSON InputBlock where parseJSON = checkedParser

-- | Standard markdown rendered by Slack, intended for AI-generated content.
--
-- <https://docs.slack.dev/reference/block-kit/blocks/markdown-block>
newtype MarkdownBlock = CheckedMarkdownBlock MarkdownBlockFields deriving (Eq, Show)

-- | Editable construction input. Call 'buildMarkdownBlock' before encoding.
data MarkdownBlockFields = MarkdownBlockFields
  { -- | Sets standard markdown content, which Slack renders directly. Required. Shared limit: @markdown.text@.
    markdownBlockText :: Text,
    -- | Sets a unique identifier for this block. Slack returns it in interaction payloads, so use a stable value when you need to find the block again. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @block_id@.
    markdownBlockBlockId :: Maybe (Text),
    -- | Unmodeled extension fields. Reserved and modeled keys are rejected.
    markdownBlockExtensions :: Map Text Value
  }
  deriving (Eq, Show)

-- | Start editable fields for MarkdownBlock; required arguments follow the signature.
-- Optional fields start absent except the explicit shared defaults; no block ID is invented.
-- Finish with 'buildMarkdownBlock' to validate before JSON encoding.
markdownBlock :: Text -> MarkdownBlockFields
markdownBlock arg0 = MarkdownBlockFields (arg0) (Nothing) (Map.empty)

-- | Inspect immutable construction fields. Rebuild edits with 'buildMarkdownBlock' to revalidate.
inspectMarkdownBlock :: MarkdownBlock -> MarkdownBlockFields
inspectMarkdownBlock (CheckedMarkdownBlock fields) = fields

-- | Validate fields, extensions and receiving context. Return structured errors or a checked MarkdownBlock.
buildMarkdownBlock :: MarkdownBlockFields -> Result MarkdownBlock
buildMarkdownBlock fields = do
  checkExtensions ["text", "block_id"] (markdownBlockExtensions fields)
  validateFields "MarkdownBlock" (wireMarkdownBlock fields)
  pure (CheckedMarkdownBlock fields)

wireMarkdownBlock :: MarkdownBlockFields -> Value
wireMarkdownBlock fields =
  object $
    ["type" .= ("markdown" :: Text)] <> ["text" .= (markdownBlockText fields)] <> optional "block_id" (markdownBlockBlockId fields) <> extensionPairs (markdownBlockExtensions fields)

instance ToJSON MarkdownBlock where toJSON (CheckedMarkdownBlock fields) = wireMarkdownBlock fields

instance FromSlackJSON MarkdownBlock where
  fromSlackJSON value = do
    fields <- wireObject "markdown" value
    parsedText <- required "text" fields
    parsedBlockId <- optionalField "block_id" fields
    buildMarkdownBlock (MarkdownBlockFields parsedText parsedBlockId (remaining ["text", "block_id"] fields))

instance FromJSON MarkdownBlock where parseJSON = checkedParser

-- | A titled sequence of task cards.
--
-- <https://docs.slack.dev/reference/block-kit/blocks/plan-block>
-- Task IDs must be unique within a plan.
newtype PlanBlock = CheckedPlanBlock PlanBlockFields deriving (Eq, Show)

-- | Editable construction input. Call 'buildPlanBlock' before encoding.
data PlanBlockFields = PlanBlockFields
  { -- | Sets the plan title. Required.
    planBlockTitle :: Text,
    -- | Adds task cards in display order. Required. Shared limit: @plan.tasks@.
    planBlockTasks :: [PlanTask],
    -- | Sets a unique identifier for this block. Slack returns it in interaction payloads, so use a stable value when you need to find the block again. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @block_id@.
    planBlockBlockId :: Maybe (Text),
    -- | Unmodeled extension fields. Reserved and modeled keys are rejected.
    planBlockExtensions :: Map Text Value
  }
  deriving (Eq, Show)

-- | Start editable fields for PlanBlock; required arguments follow the signature.
-- Optional fields start absent except the explicit shared defaults; no block ID is invented.
-- Finish with 'buildPlanBlock' to validate before JSON encoding.
planBlock :: Text -> [PlanTask] -> PlanBlockFields
planBlock arg0 arg1 = PlanBlockFields (arg0) (arg1) (Nothing) (Map.empty)

-- | Inspect immutable construction fields. Rebuild edits with 'buildPlanBlock' to revalidate.
inspectPlanBlock :: PlanBlock -> PlanBlockFields
inspectPlanBlock (CheckedPlanBlock fields) = fields

-- | Validate fields, extensions and receiving context. Return structured errors or a checked PlanBlock.
buildPlanBlock :: PlanBlockFields -> Result PlanBlock
buildPlanBlock fields = do
  checkExtensions ["title", "tasks", "block_id"] (planBlockExtensions fields)
  validateFields "PlanBlock" (wirePlanBlock fields)
  pure (CheckedPlanBlock fields)

wirePlanBlock :: PlanBlockFields -> Value
wirePlanBlock fields =
  object $
    ["type" .= ("plan" :: Text)] <> ["title" .= (planBlockTitle fields)] <> ["tasks" .= (map (stripTag . toJSON) (planBlockTasks fields))] <> optional "block_id" (planBlockBlockId fields) <> extensionPairs (planBlockExtensions fields)

instance ToJSON PlanBlock where toJSON (CheckedPlanBlock fields) = wirePlanBlock fields

instance FromSlackJSON PlanBlock where
  fromSlackJSON value = do
    fields <- wireObject "plan" value
    parsedTitle <- required "title" fields
    parsedTasks <- required "tasks" (restoreTasks fields)
    parsedBlockId <- optionalField "block_id" fields
    buildPlanBlock (PlanBlockFields parsedTitle parsedTasks parsedBlockId (remaining ["title", "tasks", "block_id"] fields))

instance FromJSON PlanBlock where parseJSON = checkedParser

-- | Formatted text built from sections, lists, preformatted blocks, and quotes.
--
-- <https://docs.slack.dev/reference/block-kit/blocks/rich-text-block>
newtype RichTextBlock = CheckedRichTextBlock RichTextBlockFields deriving (Eq, Show)

-- | Editable construction input. Call 'buildRichTextBlock' before encoding.
data RichTextBlockFields = RichTextBlockFields
  { -- | Adds sections, lists, preformatted blocks, and quotes in display order. Required.
    richTextBlockElements :: [RichTextBlockElement],
    -- | Sets a unique identifier for this block. Slack returns it in interaction payloads, so use a stable value when you need to find the block again. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @block_id@.
    richTextBlockBlockId :: Maybe (Text),
    -- | Unmodeled extension fields. Reserved and modeled keys are rejected.
    richTextBlockExtensions :: Map Text Value
  }
  deriving (Eq, Show)

-- | Start editable fields for RichTextBlock; required arguments follow the signature.
-- Optional fields start absent except the explicit shared defaults; no block ID is invented.
-- Finish with 'buildRichTextBlock' to validate before JSON encoding.
richTextBlock :: [RichTextBlockElement] -> RichTextBlockFields
richTextBlock arg0 = RichTextBlockFields (arg0) (Nothing) (Map.empty)

-- | Inspect immutable construction fields. Rebuild edits with 'buildRichTextBlock' to revalidate.
inspectRichTextBlock :: RichTextBlock -> RichTextBlockFields
inspectRichTextBlock (CheckedRichTextBlock fields) = fields

-- | Validate fields, extensions and receiving context. Return structured errors or a checked RichTextBlock.
buildRichTextBlock :: RichTextBlockFields -> Result RichTextBlock
buildRichTextBlock fields = do
  checkExtensions ["elements", "block_id"] (richTextBlockExtensions fields)
  validateFields "RichTextBlock" (wireRichTextBlock fields)
  pure (CheckedRichTextBlock fields)

wireRichTextBlock :: RichTextBlockFields -> Value
wireRichTextBlock fields =
  object $
    ["type" .= ("rich_text" :: Text)] <> ["elements" .= (richTextBlockElements fields)] <> optional "block_id" (richTextBlockBlockId fields) <> extensionPairs (richTextBlockExtensions fields)

instance ToJSON RichTextBlock where toJSON (CheckedRichTextBlock fields) = wireRichTextBlock fields

instance FromSlackJSON RichTextBlock where
  fromSlackJSON value = do
    fields <- wireObject "rich_text" value
    parsedElements <- required "elements" fields
    parsedBlockId <- optionalField "block_id" fields
    buildRichTextBlock (RichTextBlockFields parsedElements parsedBlockId (remaining ["elements", "block_id"] fields))

instance FromJSON RichTextBlock where parseJSON = checkedParser

-- | Text, a grid of fields, or both, with an optional accessory element.
--
-- <https://docs.slack.dev/reference/block-kit/blocks/section-block>
-- Provide text, fields, or both.
newtype SectionBlock = CheckedSectionBlock SectionBlockFields deriving (Eq, Show)

-- | Editable construction input. Call 'buildSectionBlock' before encoding.
data SectionBlockFields = SectionBlockFields
  { -- | Sets the main text of the section. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @section.text@.
    sectionBlockText :: Maybe (TextObject),
    -- | Adds section fields, shown in a two-column grid, in display order. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @section.fields@.
    sectionBlockFields :: Maybe ([TextObject]),
    -- | Sets the element displayed beside the section text. Optional; Nothing omits the field. Factory default: @Nothing@.
    sectionBlockAccessory :: Maybe (Element),
    -- | Sets a unique identifier for this block. Slack returns it in interaction payloads, so use a stable value when you need to find the block again. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @block_id@.
    sectionBlockBlockId :: Maybe (Text),
    -- | Unmodeled extension fields. Reserved and modeled keys are rejected.
    sectionBlockExtensions :: Map Text Value
  }
  deriving (Eq, Show)

-- | Start editable fields for SectionBlock; required arguments follow the signature.
-- Optional fields start absent except the explicit shared defaults; no block ID is invented.
-- Finish with 'buildSectionBlock' to validate before JSON encoding.
sectionBlock :: SectionBlockFields
sectionBlock = SectionBlockFields (Nothing) (Nothing) (Nothing) (Nothing) (Map.empty)

-- | Inspect immutable construction fields. Rebuild edits with 'buildSectionBlock' to revalidate.
inspectSectionBlock :: SectionBlock -> SectionBlockFields
inspectSectionBlock (CheckedSectionBlock fields) = fields

-- | Validate fields, extensions and receiving context. Return structured errors or a checked SectionBlock.
buildSectionBlock :: SectionBlockFields -> Result SectionBlock
buildSectionBlock fields = do
  checkExtensions ["text", "fields", "accessory", "block_id"] (sectionBlockExtensions fields)
  validateFields "SectionBlock" (wireSectionBlock fields)
  pure (CheckedSectionBlock fields)

wireSectionBlock :: SectionBlockFields -> Value
wireSectionBlock fields =
  object $
    ["type" .= ("section" :: Text)] <> optional "text" (sectionBlockText fields) <> optional "fields" (sectionBlockFields fields) <> optional "accessory" (sectionBlockAccessory fields) <> optional "block_id" (sectionBlockBlockId fields) <> extensionPairs (sectionBlockExtensions fields)

instance ToJSON SectionBlock where toJSON (CheckedSectionBlock fields) = wireSectionBlock fields

instance FromSlackJSON SectionBlock where
  fromSlackJSON value = do
    fields <- wireObject "section" value
    parsedText <- optionalField "text" (coerceField "text" "mrkdwn" fields)
    parsedFields <- optionalField "fields" (coerceField "fields" "mrkdwn" fields)
    parsedAccessory <- optionalField "accessory" fields
    parsedBlockId <- optionalField "block_id" fields
    buildSectionBlock (SectionBlockFields parsedText parsedFields parsedAccessory parsedBlockId (remaining ["text", "fields", "accessory", "block_id"] fields))

instance FromJSON SectionBlock where parseJSON = checkedParser

-- | A simple table of raw text and rich text cells.
--
-- <https://docs.slack.dev/reference/block-kit/blocks/table-block>
newtype TableBlock = CheckedTableBlock TableBlockFields deriving (Eq, Show)

-- | Editable construction input. Call 'buildTableBlock' before encoding.
data TableBlockFields = TableBlockFields
  { -- | Adds complete table rows in display order. Required. Shared limit: @table.rows@.
    tableBlockRows :: [[TableCell]],
    -- | Adds per-column settings in column order. Provide one entry for every column. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @table.column_settings@.
    tableBlockColumnSettings :: Maybe ([ColumnSettings]),
    -- | Sets a unique identifier for this block. Slack returns it in interaction payloads, so use a stable value when you need to find the block again. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @block_id@.
    tableBlockBlockId :: Maybe (Text),
    -- | Unmodeled extension fields. Reserved and modeled keys are rejected.
    tableBlockExtensions :: Map Text Value
  }
  deriving (Eq, Show)

-- | Start editable fields for TableBlock; required arguments follow the signature.
-- Optional fields start absent except the explicit shared defaults; no block ID is invented.
-- Finish with 'buildTableBlock' to validate before JSON encoding.
tableBlock :: [[TableCell]] -> TableBlockFields
tableBlock arg0 = TableBlockFields (arg0) (Nothing) (Nothing) (Map.empty)

-- | Inspect immutable construction fields. Rebuild edits with 'buildTableBlock' to revalidate.
inspectTableBlock :: TableBlock -> TableBlockFields
inspectTableBlock (CheckedTableBlock fields) = fields

-- | Validate fields, extensions and receiving context. Return structured errors or a checked TableBlock.
buildTableBlock :: TableBlockFields -> Result TableBlock
buildTableBlock fields = do
  checkExtensions ["rows", "column_settings", "block_id"] (tableBlockExtensions fields)
  validateFields "TableBlock" (wireTableBlock fields)
  pure (CheckedTableBlock fields)

wireTableBlock :: TableBlockFields -> Value
wireTableBlock fields =
  object $
    ["type" .= ("table" :: Text)] <> ["rows" .= (tableBlockRows fields)] <> optional "column_settings" (tableBlockColumnSettings fields) <> optional "block_id" (tableBlockBlockId fields) <> extensionPairs (tableBlockExtensions fields)

instance ToJSON TableBlock where toJSON (CheckedTableBlock fields) = wireTableBlock fields

instance FromSlackJSON TableBlock where
  fromSlackJSON value = do
    fields <- wireObject "table" value
    parsedRows <- required "rows" fields
    parsedColumnSettings <- optionalField "column_settings" fields
    parsedBlockId <- optionalField "block_id" fields
    buildTableBlock (TableBlockFields parsedRows parsedColumnSettings parsedBlockId (remaining ["rows", "column_settings", "block_id"] fields))

instance FromJSON TableBlock where parseJSON = checkedParser

-- | One task with its status, details, output, and sources.
--
-- <https://docs.slack.dev/reference/block-kit/blocks/task-card-block>
-- A standalone task card's status cannot be pending; pending is only valid for plan tasks.
newtype TaskCardBlock = CheckedTaskCardBlock TaskCardBlockFields deriving (Eq, Show)

-- | Editable construction input. Call 'buildTaskCardBlock' before encoding.
data TaskCardBlockFields = TaskCardBlockFields
  { -- | Sets the identifier of the task. Required.
    taskCardBlockTaskId :: Text,
    -- | Sets the task title. Required.
    taskCardBlockTitle :: Text,
    -- | Sets a rich text description of the task. Optional; Nothing omits the field. Factory default: @Nothing@.
    taskCardBlockDetails :: Maybe (RichTextBlock),
    -- | Sets rich text describing the task's output. Optional; Nothing omits the field. Factory default: @Nothing@.
    taskCardBlockOutput :: Maybe (RichTextBlock),
    -- | Adds links to the sources the task used, in display order. Optional; Nothing omits the field. Factory default: @Nothing@.
    taskCardBlockSources :: Maybe ([UrlSource]),
    -- | Sets the task's current state. Required.
    taskCardBlockStatus :: TaskStatus,
    -- | Sets a unique identifier for this block. Slack returns it in interaction payloads, so use a stable value when you need to find the block again. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @block_id@.
    taskCardBlockBlockId :: Maybe (Text),
    -- | Unmodeled extension fields. Reserved and modeled keys are rejected.
    taskCardBlockExtensions :: Map Text Value
  }
  deriving (Eq, Show)

-- | Start editable fields for TaskCardBlock; required arguments follow the signature.
-- Optional fields start absent except the explicit shared defaults; no block ID is invented.
-- Finish with 'buildTaskCardBlock' to validate before JSON encoding.
taskCardBlock :: Text -> Text -> TaskStatus -> TaskCardBlockFields
taskCardBlock arg0 arg1 arg2 = TaskCardBlockFields (arg0) (arg1) (Nothing) (Nothing) (Nothing) (arg2) (Nothing) (Map.empty)

-- | Inspect immutable construction fields. Rebuild edits with 'buildTaskCardBlock' to revalidate.
inspectTaskCardBlock :: TaskCardBlock -> TaskCardBlockFields
inspectTaskCardBlock (CheckedTaskCardBlock fields) = fields

-- | Validate fields, extensions and receiving context. Return structured errors or a checked TaskCardBlock.
buildTaskCardBlock :: TaskCardBlockFields -> Result TaskCardBlock
buildTaskCardBlock fields = do
  checkExtensions ["task_id", "title", "details", "output", "sources", "status", "block_id"] (taskCardBlockExtensions fields)
  validateFields "TaskCardBlock" (wireTaskCardBlock fields)
  standaloneTask (wireTaskCardBlock fields)
  pure (CheckedTaskCardBlock fields)

wireTaskCardBlock :: TaskCardBlockFields -> Value
wireTaskCardBlock fields =
  object $
    ["type" .= ("task_card" :: Text)] <> ["task_id" .= (taskCardBlockTaskId fields)] <> ["title" .= (taskCardBlockTitle fields)] <> optional "details" (taskCardBlockDetails fields) <> optional "output" (taskCardBlockOutput fields) <> optional "sources" (taskCardBlockSources fields) <> ["status" .= (taskCardBlockStatus fields)] <> optional "block_id" (taskCardBlockBlockId fields) <> extensionPairs (taskCardBlockExtensions fields)

instance ToJSON TaskCardBlock where toJSON (CheckedTaskCardBlock fields) = wireTaskCardBlock fields

instance FromSlackJSON TaskCardBlock where fromSlackJSON = decodeTaskCard buildTaskCardBlock

decodeTaskCard :: (TaskCardBlockFields -> Result a) -> Value -> Result a
decodeTaskCard constructor value = do
  fields <- wireObject "task_card" value
  parsedTaskId <- required "task_id" fields
  parsedTitle <- required "title" fields
  parsedDetails <- optionalField "details" fields
  parsedOutput <- optionalField "output" fields
  parsedSources <- optionalField "sources" fields
  parsedStatus <- required "status" fields
  parsedBlockId <- optionalField "block_id" fields
  constructor (TaskCardBlockFields parsedTaskId parsedTitle parsedDetails parsedOutput parsedSources parsedStatus parsedBlockId (remaining ["task_id", "title", "details", "output", "sources", "status", "block_id"] fields))

instance FromJSON TaskCardBlock where parseJSON = checkedParser

-- | An embedded video player.
--
-- <https://docs.slack.dev/reference/block-kit/blocks/video-block>
newtype VideoBlock = CheckedVideoBlock VideoBlockFields deriving (Eq, Show)

-- | Editable construction input. Call 'buildVideoBlock' before encoding.
data VideoBlockFields = VideoBlockFields
  { -- | Sets a plain-text summary of the image or video for assistive technology. Required. Shared limit: @video.alt_text@.
    videoBlockAltText :: Text,
    -- | Sets the URL of the image shown before the video plays. Required. Shared limit: @video.thumbnail_url@.
    videoBlockThumbnailUrl :: Text,
    -- | Sets the video title. Required. Shared limit: @video.title@.
    videoBlockTitle :: PlainText,
    -- | Sets the embeddable URL of the video. The domain must be listed in the app's unfurl domains. Required. Shared limit: @video.video_url@.
    videoBlockVideoUrl :: Text,
    -- | Sets a unique identifier for this block. Slack returns it in interaction payloads, so use a stable value when you need to find the block again. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @block_id@.
    videoBlockBlockId :: Maybe (Text),
    -- | Sets the name of the video's author. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @video.author_name@.
    videoBlockAuthorName :: Maybe (Text),
    -- | Sets the video description. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @video.description@.
    videoBlockDescription :: Maybe (PlainText),
    -- | Sets the URL of the video provider's icon. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @video.provider_icon_url@.
    videoBlockProviderIconUrl :: Maybe (Text),
    -- | Sets the name of the video provider, such as YouTube. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @video.provider_name@.
    videoBlockProviderName :: Maybe (Text),
    -- | Sets the HTTPS URL opened when the title is clicked. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @video.title_url@.
    videoBlockTitleUrl :: Maybe (Text),
    -- | Unmodeled extension fields. Reserved and modeled keys are rejected.
    videoBlockExtensions :: Map Text Value
  }
  deriving (Eq, Show)

-- | Start editable fields for VideoBlock; required arguments follow the signature.
-- Optional fields start absent except the explicit shared defaults; no block ID is invented.
-- Finish with 'buildVideoBlock' to validate before JSON encoding.
videoBlock :: Text -> Text -> PlainText -> Text -> VideoBlockFields
videoBlock arg0 arg1 arg2 arg3 = VideoBlockFields (arg0) (arg1) (arg2) (arg3) (Nothing) (Nothing) (Nothing) (Nothing) (Nothing) (Nothing) (Map.empty)

-- | Inspect immutable construction fields. Rebuild edits with 'buildVideoBlock' to revalidate.
inspectVideoBlock :: VideoBlock -> VideoBlockFields
inspectVideoBlock (CheckedVideoBlock fields) = fields

-- | Validate fields, extensions and receiving context. Return structured errors or a checked VideoBlock.
buildVideoBlock :: VideoBlockFields -> Result VideoBlock
buildVideoBlock fields = do
  checkExtensions ["alt_text", "thumbnail_url", "title", "video_url", "block_id", "author_name", "description", "provider_icon_url", "provider_name", "title_url"] (videoBlockExtensions fields)
  validateFields "VideoBlock" (wireVideoBlock fields)
  pure (CheckedVideoBlock fields)

wireVideoBlock :: VideoBlockFields -> Value
wireVideoBlock fields =
  object $
    ["type" .= ("video" :: Text)] <> ["alt_text" .= (videoBlockAltText fields)] <> ["thumbnail_url" .= (videoBlockThumbnailUrl fields)] <> ["title" .= (videoBlockTitle fields)] <> ["video_url" .= (videoBlockVideoUrl fields)] <> optional "block_id" (videoBlockBlockId fields) <> optional "author_name" (videoBlockAuthorName fields) <> optional "description" (videoBlockDescription fields) <> optional "provider_icon_url" (videoBlockProviderIconUrl fields) <> optional "provider_name" (videoBlockProviderName fields) <> optional "title_url" (videoBlockTitleUrl fields) <> extensionPairs (videoBlockExtensions fields)

instance ToJSON VideoBlock where toJSON (CheckedVideoBlock fields) = wireVideoBlock fields

instance FromSlackJSON VideoBlock where
  fromSlackJSON value = do
    fields <- wireObject "video" value
    parsedAltText <- required "alt_text" fields
    parsedThumbnailUrl <- required "thumbnail_url" fields
    parsedTitle <- required "title" (coerceField "title" "plain_text" fields)
    parsedVideoUrl <- required "video_url" fields
    parsedBlockId <- optionalField "block_id" fields
    parsedAuthorName <- optionalField "author_name" fields
    parsedDescription <- optionalField "description" (coerceField "description" "plain_text" fields)
    parsedProviderIconUrl <- optionalField "provider_icon_url" fields
    parsedProviderName <- optionalField "provider_name" fields
    parsedTitleUrl <- optionalField "title_url" fields
    buildVideoBlock (VideoBlockFields parsedAltText parsedThumbnailUrl parsedTitle parsedVideoUrl parsedBlockId parsedAuthorName parsedDescription parsedProviderIconUrl parsedProviderName parsedTitleUrl (remaining ["alt_text", "thumbnail_url", "title", "video_url", "block_id", "author_name", "description", "provider_icon_url", "provider_name", "title_url"] fields))

instance FromJSON VideoBlock where parseJSON = checkedParser

-- | An interactive button that sends a payload or opens a URL.
--
-- <https://docs.slack.dev/reference/block-kit/block-elements/button-element>
-- A prompt display requires an agent prompt.
newtype ButtonElement = CheckedButtonElement ButtonElementFields deriving (Eq, Show)

-- | Editable construction input. Call 'buildButtonElement' before encoding.
data ButtonElementFields = ButtonElementFields
  { -- | Sets the button label. Required. Shared limit: @button.text@.
    buttonElementText :: PlainText,
    -- | Sets the identifier Slack returns in interaction payloads when a user acts on this element. It must be unique among the elements of its block. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @action_id@.
    buttonElementActionId :: Maybe (Text),
    -- | Sets a URL opened in the user's browser when the button is clicked. Slack still sends an interaction payload. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @button.url@.
    buttonElementUrl :: Maybe (Text),
    -- | Sets the application-defined value sent in interaction payloads. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @button.value@.
    buttonElementValue :: Maybe (Text),
    -- | Sets the button's emphasis. Omit it for the default neutral style. Optional; Nothing omits the field. Factory default: @Nothing@.
    buttonElementStyle :: Maybe (ButtonStyle),
    -- | Sets a confirmation dialog shown before the action is sent. Optional; Nothing omits the field. Factory default: @Nothing@.
    buttonElementConfirm :: Maybe (ConfirmationDialogue),
    -- | Sets the label read by screen readers in place of the visible text. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @button.accessibility_label@.
    buttonElementAccessibilityLabel :: Maybe (Text),
    -- | Sets a prompt sent to Slackbot when AI is available to the clicking user. The app receives a block_actions payload in either case and must acknowledge it within three seconds. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @button.agent_prompt@.
    buttonElementAgentPrompt :: Maybe (Text),
    -- | Sets the collapsed Slackbot message text in place of the full prompt. Requires agent_prompt. Omit this field to let Slack use the button text; the full prompt remains expandable. Optional; Nothing omits the field. Factory default: @Nothing@.
    buttonElementAgentPromptDisplay :: Maybe (Text),
    -- | Unmodeled extension fields. Reserved and modeled keys are rejected.
    buttonElementExtensions :: Map Text Value
  }
  deriving (Eq, Show)

-- | Start editable fields for ButtonElement; required arguments follow the signature.
-- Optional fields start absent except the explicit shared defaults; no block ID is invented.
-- Finish with 'buildButtonElement' to validate before JSON encoding.
buttonElement :: PlainText -> ButtonElementFields
buttonElement arg0 = ButtonElementFields (arg0) (Nothing) (Nothing) (Nothing) (Nothing) (Nothing) (Nothing) (Nothing) (Nothing) (Map.empty)

-- | Inspect immutable construction fields. Rebuild edits with 'buildButtonElement' to revalidate.
inspectButtonElement :: ButtonElement -> ButtonElementFields
inspectButtonElement (CheckedButtonElement fields) = fields

-- | Validate fields, extensions and receiving context. Return structured errors or a checked ButtonElement.
buildButtonElement :: ButtonElementFields -> Result ButtonElement
buildButtonElement fields = do
  checkExtensions ["text", "action_id", "url", "value", "style", "confirm", "accessibility_label", "agent_prompt", "agent_prompt_display"] (buttonElementExtensions fields)
  validateFields "ButtonElement" (wireButtonElement fields)
  pure (CheckedButtonElement fields)

wireButtonElement :: ButtonElementFields -> Value
wireButtonElement fields =
  object $
    ["type" .= ("button" :: Text)] <> ["text" .= (buttonElementText fields)] <> optional "action_id" (buttonElementActionId fields) <> optional "url" (buttonElementUrl fields) <> optional "value" (buttonElementValue fields) <> optional "style" (buttonElementStyle fields) <> optional "confirm" (buttonElementConfirm fields) <> optional "accessibility_label" (buttonElementAccessibilityLabel fields) <> optional "agent_prompt" (buttonElementAgentPrompt fields) <> optional "agent_prompt_display" (buttonElementAgentPromptDisplay fields) <> extensionPairs (buttonElementExtensions fields)

instance ToJSON ButtonElement where toJSON (CheckedButtonElement fields) = wireButtonElement fields

instance FromSlackJSON ButtonElement where
  fromSlackJSON value = do
    fields <- wireObject "button" value
    parsedText <- required "text" (coerceField "text" "plain_text" fields)
    parsedActionId <- optionalField "action_id" fields
    parsedUrl <- optionalField "url" fields
    parsedValue <- optionalField "value" fields
    parsedStyle <- optionalField "style" fields
    parsedConfirm <- optionalField "confirm" fields
    parsedAccessibilityLabel <- optionalField "accessibility_label" fields
    parsedAgentPrompt <- optionalField "agent_prompt" fields
    parsedAgentPromptDisplay <- optionalField "agent_prompt_display" fields
    buildButtonElement (ButtonElementFields parsedText parsedActionId parsedUrl parsedValue parsedStyle parsedConfirm parsedAccessibilityLabel parsedAgentPrompt parsedAgentPromptDisplay (remaining ["text", "action_id", "url", "value", "style", "confirm", "accessibility_label", "agent_prompt", "agent_prompt_display"] fields))

instance FromJSON ButtonElement where parseJSON = checkedParser

-- | A menu for selecting multiple public channels.
--
-- <https://docs.slack.dev/reference/block-kit/block-elements/multi-select-menu-element>
newtype ChannelMultiSelectElement = CheckedChannelMultiSelectElement ChannelMultiSelectElementFields deriving (Eq, Show)

-- | Editable construction input. Call 'buildChannelMultiSelectElement' before encoding.
data ChannelMultiSelectElementFields = ChannelMultiSelectElementFields
  { -- | Sets the identifier Slack returns in interaction payloads when a user acts on this element. It must be unique among the elements of its block. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @action_id@.
    channelMultiSelectElementActionId :: Maybe (Text),
    -- | Adds channel IDs that are selected when the menu loads. Optional; Nothing omits the field. Factory default: @Nothing@.
    channelMultiSelectElementInitialChannels :: Maybe ([Text]),
    -- | Sets a confirmation dialog shown before the action is sent. Optional; Nothing omits the field. Factory default: @Nothing@.
    channelMultiSelectElementConfirm :: Maybe (ConfirmationDialogue),
    -- | Sets the maximum number of items a user can select. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @multi_select.max_selected_items@.
    channelMultiSelectElementMaxSelectedItems :: Maybe (Integer),
    -- | Sets whether the element receives focus when the view opens. Only one element per view may do so. Optional; Nothing omits the field. Factory default: @Nothing@.
    channelMultiSelectElementFocusOnLoad :: Maybe (Bool),
    -- | Sets the placeholder text shown before a value is chosen. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @select.placeholder@.
    channelMultiSelectElementPlaceholder :: Maybe (PlainText),
    -- | Unmodeled extension fields. Reserved and modeled keys are rejected.
    channelMultiSelectElementExtensions :: Map Text Value
  }
  deriving (Eq, Show)

-- | Start editable fields for ChannelMultiSelectElement; required arguments follow the signature.
-- Optional fields start absent except the explicit shared defaults; no block ID is invented.
-- Finish with 'buildChannelMultiSelectElement' to validate before JSON encoding.
channelMultiSelectElement :: ChannelMultiSelectElementFields
channelMultiSelectElement = ChannelMultiSelectElementFields (Nothing) (Nothing) (Nothing) (Nothing) (Nothing) (Nothing) (Map.empty)

-- | Inspect immutable construction fields. Rebuild edits with 'buildChannelMultiSelectElement' to revalidate.
inspectChannelMultiSelectElement :: ChannelMultiSelectElement -> ChannelMultiSelectElementFields
inspectChannelMultiSelectElement (CheckedChannelMultiSelectElement fields) = fields

-- | Validate fields, extensions and receiving context. Return structured errors or a checked ChannelMultiSelectElement.
buildChannelMultiSelectElement :: ChannelMultiSelectElementFields -> Result ChannelMultiSelectElement
buildChannelMultiSelectElement fields = do
  checkExtensions ["action_id", "initial_channels", "confirm", "max_selected_items", "focus_on_load", "placeholder"] (channelMultiSelectElementExtensions fields)
  validateFields "ChannelMultiSelectElement" (wireChannelMultiSelectElement fields)
  pure (CheckedChannelMultiSelectElement fields)

wireChannelMultiSelectElement :: ChannelMultiSelectElementFields -> Value
wireChannelMultiSelectElement fields =
  object $
    ["type" .= ("multi_channels_select" :: Text)] <> optional "action_id" (channelMultiSelectElementActionId fields) <> optional "initial_channels" (channelMultiSelectElementInitialChannels fields) <> optional "confirm" (channelMultiSelectElementConfirm fields) <> optional "max_selected_items" (channelMultiSelectElementMaxSelectedItems fields) <> optional "focus_on_load" (channelMultiSelectElementFocusOnLoad fields) <> optional "placeholder" (channelMultiSelectElementPlaceholder fields) <> extensionPairs (channelMultiSelectElementExtensions fields)

instance ToJSON ChannelMultiSelectElement where toJSON (CheckedChannelMultiSelectElement fields) = wireChannelMultiSelectElement fields

instance FromSlackJSON ChannelMultiSelectElement where
  fromSlackJSON value = do
    fields <- wireObject "multi_channels_select" value
    checkIntegerBounds "ChannelMultiSelectElement" (Object fields)
    parsedActionId <- optionalField "action_id" fields
    parsedInitialChannels <- optionalField "initial_channels" fields
    parsedConfirm <- optionalField "confirm" fields
    parsedMaxSelectedItems <- optionalField "max_selected_items" fields
    parsedFocusOnLoad <- optionalField "focus_on_load" fields
    parsedPlaceholder <- optionalField "placeholder" (coerceField "placeholder" "plain_text" fields)
    buildChannelMultiSelectElement (ChannelMultiSelectElementFields parsedActionId parsedInitialChannels parsedConfirm parsedMaxSelectedItems parsedFocusOnLoad parsedPlaceholder (remaining ["action_id", "initial_channels", "confirm", "max_selected_items", "focus_on_load", "placeholder"] fields))

instance FromJSON ChannelMultiSelectElement where parseJSON = checkedParser

-- | A menu for selecting one public channel.
--
-- <https://docs.slack.dev/reference/block-kit/block-elements/select-menu-element>
newtype ChannelSelectElement = CheckedChannelSelectElement ChannelSelectElementFields deriving (Eq, Show)

-- | Editable construction input. Call 'buildChannelSelectElement' before encoding.
data ChannelSelectElementFields = ChannelSelectElementFields
  { -- | Sets the identifier Slack returns in interaction payloads when a user acts on this element. It must be unique among the elements of its block. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @action_id@.
    channelSelectElementActionId :: Maybe (Text),
    -- | Sets the channel ID selected when the menu loads. Optional; Nothing omits the field. Factory default: @Nothing@.
    channelSelectElementInitialChannel :: Maybe (Text),
    -- | Sets whether the selected conversation receives a response URL in the view submission payload. Only valid in modals. Optional; Nothing omits the field. Factory default: @Nothing@.
    channelSelectElementResponseUrlEnabled :: Maybe (Bool),
    -- | Sets a confirmation dialog shown before the action is sent. Optional; Nothing omits the field. Factory default: @Nothing@.
    channelSelectElementConfirm :: Maybe (ConfirmationDialogue),
    -- | Sets whether the element receives focus when the view opens. Only one element per view may do so. Optional; Nothing omits the field. Factory default: @Nothing@.
    channelSelectElementFocusOnLoad :: Maybe (Bool),
    -- | Sets the placeholder text shown before a value is chosen. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @select.placeholder@.
    channelSelectElementPlaceholder :: Maybe (PlainText),
    -- | Unmodeled extension fields. Reserved and modeled keys are rejected.
    channelSelectElementExtensions :: Map Text Value
  }
  deriving (Eq, Show)

-- | Start editable fields for ChannelSelectElement; required arguments follow the signature.
-- Optional fields start absent except the explicit shared defaults; no block ID is invented.
-- Finish with 'buildChannelSelectElement' to validate before JSON encoding.
channelSelectElement :: ChannelSelectElementFields
channelSelectElement = ChannelSelectElementFields (Nothing) (Nothing) (Nothing) (Nothing) (Nothing) (Nothing) (Map.empty)

-- | Inspect immutable construction fields. Rebuild edits with 'buildChannelSelectElement' to revalidate.
inspectChannelSelectElement :: ChannelSelectElement -> ChannelSelectElementFields
inspectChannelSelectElement (CheckedChannelSelectElement fields) = fields

-- | Validate fields, extensions and receiving context. Return structured errors or a checked ChannelSelectElement.
buildChannelSelectElement :: ChannelSelectElementFields -> Result ChannelSelectElement
buildChannelSelectElement fields = do
  checkExtensions ["action_id", "initial_channel", "response_url_enabled", "confirm", "focus_on_load", "placeholder"] (channelSelectElementExtensions fields)
  validateFields "ChannelSelectElement" (wireChannelSelectElement fields)
  pure (CheckedChannelSelectElement fields)

wireChannelSelectElement :: ChannelSelectElementFields -> Value
wireChannelSelectElement fields =
  object $
    ["type" .= ("channels_select" :: Text)] <> optional "action_id" (channelSelectElementActionId fields) <> optional "initial_channel" (channelSelectElementInitialChannel fields) <> optional "response_url_enabled" (channelSelectElementResponseUrlEnabled fields) <> optional "confirm" (channelSelectElementConfirm fields) <> optional "focus_on_load" (channelSelectElementFocusOnLoad fields) <> optional "placeholder" (channelSelectElementPlaceholder fields) <> extensionPairs (channelSelectElementExtensions fields)

instance ToJSON ChannelSelectElement where toJSON (CheckedChannelSelectElement fields) = wireChannelSelectElement fields

instance FromSlackJSON ChannelSelectElement where
  fromSlackJSON value = do
    fields <- wireObject "channels_select" value
    parsedActionId <- optionalField "action_id" fields
    parsedInitialChannel <- optionalField "initial_channel" fields
    parsedResponseUrlEnabled <- optionalField "response_url_enabled" fields
    parsedConfirm <- optionalField "confirm" fields
    parsedFocusOnLoad <- optionalField "focus_on_load" fields
    parsedPlaceholder <- optionalField "placeholder" (coerceField "placeholder" "plain_text" fields)
    buildChannelSelectElement (ChannelSelectElementFields parsedActionId parsedInitialChannel parsedResponseUrlEnabled parsedConfirm parsedFocusOnLoad parsedPlaceholder (remaining ["action_id", "initial_channel", "response_url_enabled", "confirm", "focus_on_load", "placeholder"] fields))

instance FromJSON ChannelSelectElement where parseJSON = checkedParser

-- | A group of checkboxes.
--
-- <https://docs.slack.dev/reference/block-kit/block-elements/checkboxes-element>
newtype CheckboxesElement = CheckedCheckboxesElement CheckboxesElementFields deriving (Eq, Show)

-- | Editable construction input. Call 'buildCheckboxesElement' before encoding.
data CheckboxesElementFields = CheckboxesElementFields
  { -- | Sets the identifier Slack returns in interaction payloads when a user acts on this element. It must be unique among the elements of its block. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @action_id@.
    checkboxesElementActionId :: Maybe (Text),
    -- | Adds selectable options in display order. Required. Shared limit: @checkboxes.options@.
    checkboxesElementOptions :: [SelectOption],
    -- | Adds options that are selected when the element loads. Each must match an option in the element. Optional; Nothing omits the field. Factory default: @Nothing@.
    checkboxesElementInitialOptions :: Maybe ([SelectOption]),
    -- | Sets a confirmation dialog shown before the action is sent. Optional; Nothing omits the field. Factory default: @Nothing@.
    checkboxesElementConfirm :: Maybe (ConfirmationDialogue),
    -- | Sets whether the element receives focus when the view opens. Only one element per view may do so. Optional; Nothing omits the field. Factory default: @Nothing@.
    checkboxesElementFocusOnLoad :: Maybe (Bool),
    -- | Unmodeled extension fields. Reserved and modeled keys are rejected.
    checkboxesElementExtensions :: Map Text Value
  }
  deriving (Eq, Show)

-- | Start editable fields for CheckboxesElement; required arguments follow the signature.
-- Optional fields start absent except the explicit shared defaults; no block ID is invented.
-- Finish with 'buildCheckboxesElement' to validate before JSON encoding.
checkboxesElement :: [SelectOption] -> CheckboxesElementFields
checkboxesElement arg0 = CheckboxesElementFields (Nothing) (arg0) (Nothing) (Nothing) (Nothing) (Map.empty)

-- | Inspect immutable construction fields. Rebuild edits with 'buildCheckboxesElement' to revalidate.
inspectCheckboxesElement :: CheckboxesElement -> CheckboxesElementFields
inspectCheckboxesElement (CheckedCheckboxesElement fields) = fields

-- | Validate fields, extensions and receiving context. Return structured errors or a checked CheckboxesElement.
buildCheckboxesElement :: CheckboxesElementFields -> Result CheckboxesElement
buildCheckboxesElement fields = do
  checkExtensions ["action_id", "options", "initial_options", "confirm", "focus_on_load"] (checkboxesElementExtensions fields)
  validateFields "CheckboxesElement" (wireCheckboxesElement fields)
  pure (CheckedCheckboxesElement fields)

wireCheckboxesElement :: CheckboxesElementFields -> Value
wireCheckboxesElement fields =
  object $
    ["type" .= ("checkboxes" :: Text)] <> optional "action_id" (checkboxesElementActionId fields) <> ["options" .= (checkboxesElementOptions fields)] <> optional "initial_options" (checkboxesElementInitialOptions fields) <> optional "confirm" (checkboxesElementConfirm fields) <> optional "focus_on_load" (checkboxesElementFocusOnLoad fields) <> extensionPairs (checkboxesElementExtensions fields)

instance ToJSON CheckboxesElement where toJSON (CheckedCheckboxesElement fields) = wireCheckboxesElement fields

instance FromSlackJSON CheckboxesElement where
  fromSlackJSON value = do
    fields <- wireObject "checkboxes" value
    parsedActionId <- optionalField "action_id" fields
    parsedOptions <- required "options" fields
    parsedInitialOptions <- optionalField "initial_options" fields
    parsedConfirm <- optionalField "confirm" fields
    parsedFocusOnLoad <- optionalField "focus_on_load" fields
    buildCheckboxesElement (CheckboxesElementFields parsedActionId parsedOptions parsedInitialOptions parsedConfirm parsedFocusOnLoad (remaining ["action_id", "options", "initial_options", "confirm", "focus_on_load"] fields))

instance FromJSON CheckboxesElement where parseJSON = checkedParser

-- | A menu for selecting multiple conversations.
--
-- <https://docs.slack.dev/reference/block-kit/block-elements/multi-select-menu-element>
newtype ConversationMultiSelectElement = CheckedConversationMultiSelectElement ConversationMultiSelectElementFields deriving (Eq, Show)

-- | Editable construction input. Call 'buildConversationMultiSelectElement' before encoding.
data ConversationMultiSelectElementFields = ConversationMultiSelectElementFields
  { -- | Sets the identifier Slack returns in interaction payloads when a user acts on this element. It must be unique among the elements of its block. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @action_id@.
    conversationMultiSelectElementActionId :: Maybe (Text),
    -- | Adds conversation IDs that are selected when the menu loads. Optional; Nothing omits the field. Factory default: @Nothing@.
    conversationMultiSelectElementInitialConversations :: Maybe ([Text]),
    -- | Sets whether the menu pre-selects the conversation the user is viewing. Optional; Nothing omits the field. Factory default: @Nothing@.
    conversationMultiSelectElementDefaultToCurrentConversation :: Maybe (Bool),
    -- | Sets which conversation types the menu offers. Optional; Nothing omits the field. Factory default: @Nothing@.
    conversationMultiSelectElementFilter :: Maybe (ConversationFilter),
    -- | Sets a confirmation dialog shown before the action is sent. Optional; Nothing omits the field. Factory default: @Nothing@.
    conversationMultiSelectElementConfirm :: Maybe (ConfirmationDialogue),
    -- | Sets the maximum number of items a user can select. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @multi_select.max_selected_items@.
    conversationMultiSelectElementMaxSelectedItems :: Maybe (Integer),
    -- | Sets whether the element receives focus when the view opens. Only one element per view may do so. Optional; Nothing omits the field. Factory default: @Nothing@.
    conversationMultiSelectElementFocusOnLoad :: Maybe (Bool),
    -- | Sets the placeholder text shown before a value is chosen. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @select.placeholder@.
    conversationMultiSelectElementPlaceholder :: Maybe (PlainText),
    -- | Unmodeled extension fields. Reserved and modeled keys are rejected.
    conversationMultiSelectElementExtensions :: Map Text Value
  }
  deriving (Eq, Show)

-- | Start editable fields for ConversationMultiSelectElement; required arguments follow the signature.
-- Optional fields start absent except the explicit shared defaults; no block ID is invented.
-- Finish with 'buildConversationMultiSelectElement' to validate before JSON encoding.
conversationMultiSelectElement :: ConversationMultiSelectElementFields
conversationMultiSelectElement = ConversationMultiSelectElementFields (Nothing) (Nothing) (Nothing) (Nothing) (Nothing) (Nothing) (Nothing) (Nothing) (Map.empty)

-- | Inspect immutable construction fields. Rebuild edits with 'buildConversationMultiSelectElement' to revalidate.
inspectConversationMultiSelectElement :: ConversationMultiSelectElement -> ConversationMultiSelectElementFields
inspectConversationMultiSelectElement (CheckedConversationMultiSelectElement fields) = fields

-- | Validate fields, extensions and receiving context. Return structured errors or a checked ConversationMultiSelectElement.
buildConversationMultiSelectElement :: ConversationMultiSelectElementFields -> Result ConversationMultiSelectElement
buildConversationMultiSelectElement fields = do
  checkExtensions ["action_id", "initial_conversations", "default_to_current_conversation", "filter", "confirm", "max_selected_items", "focus_on_load", "placeholder"] (conversationMultiSelectElementExtensions fields)
  validateFields "ConversationMultiSelectElement" (wireConversationMultiSelectElement fields)
  pure (CheckedConversationMultiSelectElement fields)

wireConversationMultiSelectElement :: ConversationMultiSelectElementFields -> Value
wireConversationMultiSelectElement fields =
  object $
    ["type" .= ("multi_conversations_select" :: Text)] <> optional "action_id" (conversationMultiSelectElementActionId fields) <> optional "initial_conversations" (conversationMultiSelectElementInitialConversations fields) <> optional "default_to_current_conversation" (conversationMultiSelectElementDefaultToCurrentConversation fields) <> optional "filter" (conversationMultiSelectElementFilter fields) <> optional "confirm" (conversationMultiSelectElementConfirm fields) <> optional "max_selected_items" (conversationMultiSelectElementMaxSelectedItems fields) <> optional "focus_on_load" (conversationMultiSelectElementFocusOnLoad fields) <> optional "placeholder" (conversationMultiSelectElementPlaceholder fields) <> extensionPairs (conversationMultiSelectElementExtensions fields)

instance ToJSON ConversationMultiSelectElement where toJSON (CheckedConversationMultiSelectElement fields) = wireConversationMultiSelectElement fields

instance FromSlackJSON ConversationMultiSelectElement where
  fromSlackJSON value = do
    fields <- wireObject "multi_conversations_select" value
    checkIntegerBounds "ConversationMultiSelectElement" (Object fields)
    parsedActionId <- optionalField "action_id" fields
    parsedInitialConversations <- optionalField "initial_conversations" fields
    parsedDefaultToCurrentConversation <- optionalField "default_to_current_conversation" fields
    parsedFilter <- optionalField "filter" fields
    parsedConfirm <- optionalField "confirm" fields
    parsedMaxSelectedItems <- optionalField "max_selected_items" fields
    parsedFocusOnLoad <- optionalField "focus_on_load" fields
    parsedPlaceholder <- optionalField "placeholder" (coerceField "placeholder" "plain_text" fields)
    buildConversationMultiSelectElement (ConversationMultiSelectElementFields parsedActionId parsedInitialConversations parsedDefaultToCurrentConversation parsedFilter parsedConfirm parsedMaxSelectedItems parsedFocusOnLoad parsedPlaceholder (remaining ["action_id", "initial_conversations", "default_to_current_conversation", "filter", "confirm", "max_selected_items", "focus_on_load", "placeholder"] fields))

instance FromJSON ConversationMultiSelectElement where parseJSON = checkedParser

-- | A menu for selecting one conversation.
--
-- <https://docs.slack.dev/reference/block-kit/block-elements/select-menu-element>
newtype ConversationSelectElement = CheckedConversationSelectElement ConversationSelectElementFields deriving (Eq, Show)

-- | Editable construction input. Call 'buildConversationSelectElement' before encoding.
data ConversationSelectElementFields = ConversationSelectElementFields
  { -- | Sets the identifier Slack returns in interaction payloads when a user acts on this element. It must be unique among the elements of its block. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @action_id@.
    conversationSelectElementActionId :: Maybe (Text),
    -- | Sets the conversation ID selected when the menu loads. Optional; Nothing omits the field. Factory default: @Nothing@.
    conversationSelectElementInitialConversation :: Maybe (Text),
    -- | Sets whether the menu pre-selects the conversation the user is viewing. Optional; Nothing omits the field. Factory default: @Nothing@.
    conversationSelectElementDefaultToCurrentConversation :: Maybe (Bool),
    -- | Sets which conversation types the menu offers. Optional; Nothing omits the field. Factory default: @Nothing@.
    conversationSelectElementFilter :: Maybe (ConversationFilter),
    -- | Sets whether the selected conversation receives a response URL in the view submission payload. Only valid in modals. Optional; Nothing omits the field. Factory default: @Nothing@.
    conversationSelectElementResponseUrlEnabled :: Maybe (Bool),
    -- | Sets a confirmation dialog shown before the action is sent. Optional; Nothing omits the field. Factory default: @Nothing@.
    conversationSelectElementConfirm :: Maybe (ConfirmationDialogue),
    -- | Sets whether the element receives focus when the view opens. Only one element per view may do so. Optional; Nothing omits the field. Factory default: @Nothing@.
    conversationSelectElementFocusOnLoad :: Maybe (Bool),
    -- | Sets the placeholder text shown before a value is chosen. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @select.placeholder@.
    conversationSelectElementPlaceholder :: Maybe (PlainText),
    -- | Unmodeled extension fields. Reserved and modeled keys are rejected.
    conversationSelectElementExtensions :: Map Text Value
  }
  deriving (Eq, Show)

-- | Start editable fields for ConversationSelectElement; required arguments follow the signature.
-- Optional fields start absent except the explicit shared defaults; no block ID is invented.
-- Finish with 'buildConversationSelectElement' to validate before JSON encoding.
conversationSelectElement :: ConversationSelectElementFields
conversationSelectElement = ConversationSelectElementFields (Nothing) (Nothing) (Nothing) (Nothing) (Nothing) (Nothing) (Nothing) (Nothing) (Map.empty)

-- | Inspect immutable construction fields. Rebuild edits with 'buildConversationSelectElement' to revalidate.
inspectConversationSelectElement :: ConversationSelectElement -> ConversationSelectElementFields
inspectConversationSelectElement (CheckedConversationSelectElement fields) = fields

-- | Validate fields, extensions and receiving context. Return structured errors or a checked ConversationSelectElement.
buildConversationSelectElement :: ConversationSelectElementFields -> Result ConversationSelectElement
buildConversationSelectElement fields = do
  checkExtensions ["action_id", "initial_conversation", "default_to_current_conversation", "filter", "response_url_enabled", "confirm", "focus_on_load", "placeholder"] (conversationSelectElementExtensions fields)
  validateFields "ConversationSelectElement" (wireConversationSelectElement fields)
  pure (CheckedConversationSelectElement fields)

wireConversationSelectElement :: ConversationSelectElementFields -> Value
wireConversationSelectElement fields =
  object $
    ["type" .= ("conversations_select" :: Text)] <> optional "action_id" (conversationSelectElementActionId fields) <> optional "initial_conversation" (conversationSelectElementInitialConversation fields) <> optional "default_to_current_conversation" (conversationSelectElementDefaultToCurrentConversation fields) <> optional "filter" (conversationSelectElementFilter fields) <> optional "response_url_enabled" (conversationSelectElementResponseUrlEnabled fields) <> optional "confirm" (conversationSelectElementConfirm fields) <> optional "focus_on_load" (conversationSelectElementFocusOnLoad fields) <> optional "placeholder" (conversationSelectElementPlaceholder fields) <> extensionPairs (conversationSelectElementExtensions fields)

instance ToJSON ConversationSelectElement where toJSON (CheckedConversationSelectElement fields) = wireConversationSelectElement fields

instance FromSlackJSON ConversationSelectElement where
  fromSlackJSON value = do
    fields <- wireObject "conversations_select" value
    parsedActionId <- optionalField "action_id" fields
    parsedInitialConversation <- optionalField "initial_conversation" fields
    parsedDefaultToCurrentConversation <- optionalField "default_to_current_conversation" fields
    parsedFilter <- optionalField "filter" fields
    parsedResponseUrlEnabled <- optionalField "response_url_enabled" fields
    parsedConfirm <- optionalField "confirm" fields
    parsedFocusOnLoad <- optionalField "focus_on_load" fields
    parsedPlaceholder <- optionalField "placeholder" (coerceField "placeholder" "plain_text" fields)
    buildConversationSelectElement (ConversationSelectElementFields parsedActionId parsedInitialConversation parsedDefaultToCurrentConversation parsedFilter parsedResponseUrlEnabled parsedConfirm parsedFocusOnLoad parsedPlaceholder (remaining ["action_id", "initial_conversation", "default_to_current_conversation", "filter", "response_url_enabled", "confirm", "focus_on_load", "placeholder"] fields))

instance FromJSON ConversationSelectElement where parseJSON = checkedParser

-- | A calendar date picker.
--
-- <https://docs.slack.dev/reference/block-kit/block-elements/date-picker-element>
-- initial_date must have the YYYY-MM-DD shape. Calendar validity is application-owned; some language date parsers additionally reject impossible calendar dates.
newtype DatePickerElement = CheckedDatePickerElement DatePickerElementFields deriving (Eq, Show)

-- | Editable construction input. Call 'buildDatePickerElement' before encoding.
data DatePickerElementFields = DatePickerElementFields
  { -- | Sets the identifier Slack returns in interaction payloads when a user acts on this element. It must be unique among the elements of its block. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @action_id@.
    datePickerElementActionId :: Maybe (Text),
    -- | Sets the initially selected date, formatted as YYYY-MM-DD. Optional; Nothing omits the field. Factory default: @Nothing@.
    datePickerElementInitialDate :: Maybe (Text),
    -- | Sets a confirmation dialog shown before the action is sent. Optional; Nothing omits the field. Factory default: @Nothing@.
    datePickerElementConfirm :: Maybe (ConfirmationDialogue),
    -- | Sets whether the element receives focus when the view opens. Only one element per view may do so. Optional; Nothing omits the field. Factory default: @Nothing@.
    datePickerElementFocusOnLoad :: Maybe (Bool),
    -- | Sets the placeholder text shown before a value is chosen. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @date_picker.placeholder@.
    datePickerElementPlaceholder :: Maybe (PlainText),
    -- | Unmodeled extension fields. Reserved and modeled keys are rejected.
    datePickerElementExtensions :: Map Text Value
  }
  deriving (Eq, Show)

-- | Start editable fields for DatePickerElement; required arguments follow the signature.
-- Optional fields start absent except the explicit shared defaults; no block ID is invented.
-- Finish with 'buildDatePickerElement' to validate before JSON encoding.
datePickerElement :: DatePickerElementFields
datePickerElement = DatePickerElementFields (Nothing) (Nothing) (Nothing) (Nothing) (Nothing) (Map.empty)

-- | Inspect immutable construction fields. Rebuild edits with 'buildDatePickerElement' to revalidate.
inspectDatePickerElement :: DatePickerElement -> DatePickerElementFields
inspectDatePickerElement (CheckedDatePickerElement fields) = fields

-- | Validate fields, extensions and receiving context. Return structured errors or a checked DatePickerElement.
buildDatePickerElement :: DatePickerElementFields -> Result DatePickerElement
buildDatePickerElement fields = do
  checkExtensions ["action_id", "initial_date", "confirm", "focus_on_load", "placeholder"] (datePickerElementExtensions fields)
  validateFields "DatePickerElement" (wireDatePickerElement fields)
  pure (CheckedDatePickerElement fields)

wireDatePickerElement :: DatePickerElementFields -> Value
wireDatePickerElement fields =
  object $
    ["type" .= ("datepicker" :: Text)] <> optional "action_id" (datePickerElementActionId fields) <> optional "initial_date" (datePickerElementInitialDate fields) <> optional "confirm" (datePickerElementConfirm fields) <> optional "focus_on_load" (datePickerElementFocusOnLoad fields) <> optional "placeholder" (datePickerElementPlaceholder fields) <> extensionPairs (datePickerElementExtensions fields)

instance ToJSON DatePickerElement where toJSON (CheckedDatePickerElement fields) = wireDatePickerElement fields

instance FromSlackJSON DatePickerElement where
  fromSlackJSON value = do
    fields <- wireObject "datepicker" value
    parsedActionId <- optionalField "action_id" fields
    parsedInitialDate <- optionalField "initial_date" fields
    parsedConfirm <- optionalField "confirm" fields
    parsedFocusOnLoad <- optionalField "focus_on_load" fields
    parsedPlaceholder <- optionalField "placeholder" (coerceField "placeholder" "plain_text" fields)
    buildDatePickerElement (DatePickerElementFields parsedActionId parsedInitialDate parsedConfirm parsedFocusOnLoad parsedPlaceholder (remaining ["action_id", "initial_date", "confirm", "focus_on_load", "placeholder"] fields))

instance FromJSON DatePickerElement where parseJSON = checkedParser

-- | A combined date and time picker.
--
-- <https://docs.slack.dev/reference/block-kit/block-elements/datetime-picker-element>
newtype DateTimePickerElement = CheckedDateTimePickerElement DateTimePickerElementFields deriving (Eq, Show)

-- | Editable construction input. Call 'buildDateTimePickerElement' before encoding.
data DateTimePickerElementFields = DateTimePickerElementFields
  { -- | Sets the identifier Slack returns in interaction payloads when a user acts on this element. It must be unique among the elements of its block. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @action_id@.
    dateTimePickerElementActionId :: Maybe (Text),
    -- | Sets the initially selected moment as a UNIX timestamp in seconds. Optional; Nothing omits the field. Factory default: @Nothing@.
    dateTimePickerElementInitialDateTime :: Maybe (Integer),
    -- | Sets a confirmation dialog shown before the action is sent. Optional; Nothing omits the field. Factory default: @Nothing@.
    dateTimePickerElementConfirm :: Maybe (ConfirmationDialogue),
    -- | Sets whether the element receives focus when the view opens. Only one element per view may do so. Optional; Nothing omits the field. Factory default: @Nothing@.
    dateTimePickerElementFocusOnLoad :: Maybe (Bool),
    -- | Unmodeled extension fields. Reserved and modeled keys are rejected.
    dateTimePickerElementExtensions :: Map Text Value
  }
  deriving (Eq, Show)

-- | Start editable fields for DateTimePickerElement; required arguments follow the signature.
-- Optional fields start absent except the explicit shared defaults; no block ID is invented.
-- Finish with 'buildDateTimePickerElement' to validate before JSON encoding.
dateTimePickerElement :: DateTimePickerElementFields
dateTimePickerElement = DateTimePickerElementFields (Nothing) (Nothing) (Nothing) (Nothing) (Map.empty)

-- | Inspect immutable construction fields. Rebuild edits with 'buildDateTimePickerElement' to revalidate.
inspectDateTimePickerElement :: DateTimePickerElement -> DateTimePickerElementFields
inspectDateTimePickerElement (CheckedDateTimePickerElement fields) = fields

-- | Validate fields, extensions and receiving context. Return structured errors or a checked DateTimePickerElement.
buildDateTimePickerElement :: DateTimePickerElementFields -> Result DateTimePickerElement
buildDateTimePickerElement fields = do
  checkExtensions ["action_id", "initial_date_time", "confirm", "focus_on_load"] (dateTimePickerElementExtensions fields)
  validateFields "DateTimePickerElement" (wireDateTimePickerElement fields)
  pure (CheckedDateTimePickerElement fields)

wireDateTimePickerElement :: DateTimePickerElementFields -> Value
wireDateTimePickerElement fields =
  object $
    ["type" .= ("datetimepicker" :: Text)] <> optional "action_id" (dateTimePickerElementActionId fields) <> optional "initial_date_time" (dateTimePickerElementInitialDateTime fields) <> optional "confirm" (dateTimePickerElementConfirm fields) <> optional "focus_on_load" (dateTimePickerElementFocusOnLoad fields) <> extensionPairs (dateTimePickerElementExtensions fields)

instance ToJSON DateTimePickerElement where toJSON (CheckedDateTimePickerElement fields) = wireDateTimePickerElement fields

instance FromSlackJSON DateTimePickerElement where
  fromSlackJSON value = do
    fields <- wireObject "datetimepicker" value
    parsedActionId <- optionalField "action_id" fields
    parsedInitialDateTime <- optionalField "initial_date_time" fields
    parsedConfirm <- optionalField "confirm" fields
    parsedFocusOnLoad <- optionalField "focus_on_load" fields
    buildDateTimePickerElement (DateTimePickerElementFields parsedActionId parsedInitialDateTime parsedConfirm parsedFocusOnLoad (remaining ["action_id", "initial_date_time", "confirm", "focus_on_load"] fields))

instance FromJSON DateTimePickerElement where parseJSON = checkedParser

-- | A single-line input that accepts an email address.
--
-- <https://docs.slack.dev/reference/block-kit/block-elements/email-input-element>
newtype EmailInputElement = CheckedEmailInputElement EmailInputElementFields deriving (Eq, Show)

-- | Editable construction input. Call 'buildEmailInputElement' before encoding.
data EmailInputElementFields = EmailInputElementFields
  { -- | Sets the identifier Slack returns in interaction payloads when a user acts on this element. It must be unique among the elements of its block. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @action_id@.
    emailInputElementActionId :: Maybe (Text),
    -- | Sets the value present when the input loads. Optional; Nothing omits the field. Factory default: @Nothing@.
    emailInputElementInitialValue :: Maybe (Text),
    -- | Sets which user interactions send a block_actions payload. Optional; Nothing omits the field. Factory default: @Nothing@.
    emailInputElementDispatchActionConfig :: Maybe (DispatchActionConfiguration),
    -- | Sets whether the element receives focus when the view opens. Only one element per view may do so. Optional; Nothing omits the field. Factory default: @Nothing@.
    emailInputElementFocusOnLoad :: Maybe (Bool),
    -- | Sets the placeholder text shown before a value is chosen. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @email_input.placeholder@.
    emailInputElementPlaceholder :: Maybe (PlainText),
    -- | Unmodeled extension fields. Reserved and modeled keys are rejected.
    emailInputElementExtensions :: Map Text Value
  }
  deriving (Eq, Show)

-- | Start editable fields for EmailInputElement; required arguments follow the signature.
-- Optional fields start absent except the explicit shared defaults; no block ID is invented.
-- Finish with 'buildEmailInputElement' to validate before JSON encoding.
emailInputElement :: EmailInputElementFields
emailInputElement = EmailInputElementFields (Nothing) (Nothing) (Nothing) (Nothing) (Nothing) (Map.empty)

-- | Inspect immutable construction fields. Rebuild edits with 'buildEmailInputElement' to revalidate.
inspectEmailInputElement :: EmailInputElement -> EmailInputElementFields
inspectEmailInputElement (CheckedEmailInputElement fields) = fields

-- | Validate fields, extensions and receiving context. Return structured errors or a checked EmailInputElement.
buildEmailInputElement :: EmailInputElementFields -> Result EmailInputElement
buildEmailInputElement fields = do
  checkExtensions ["action_id", "initial_value", "dispatch_action_config", "focus_on_load", "placeholder"] (emailInputElementExtensions fields)
  validateFields "EmailInputElement" (wireEmailInputElement fields)
  pure (CheckedEmailInputElement fields)

wireEmailInputElement :: EmailInputElementFields -> Value
wireEmailInputElement fields =
  object $
    ["type" .= ("email_text_input" :: Text)] <> optional "action_id" (emailInputElementActionId fields) <> optional "initial_value" (emailInputElementInitialValue fields) <> optional "dispatch_action_config" (emailInputElementDispatchActionConfig fields) <> optional "focus_on_load" (emailInputElementFocusOnLoad fields) <> optional "placeholder" (emailInputElementPlaceholder fields) <> extensionPairs (emailInputElementExtensions fields)

instance ToJSON EmailInputElement where toJSON (CheckedEmailInputElement fields) = wireEmailInputElement fields

instance FromSlackJSON EmailInputElement where
  fromSlackJSON value = do
    fields <- wireObject "email_text_input" value
    parsedActionId <- optionalField "action_id" fields
    parsedInitialValue <- optionalField "initial_value" fields
    parsedDispatchActionConfig <- optionalField "dispatch_action_config" fields
    parsedFocusOnLoad <- optionalField "focus_on_load" fields
    parsedPlaceholder <- optionalField "placeholder" (coerceField "placeholder" "plain_text" fields)
    buildEmailInputElement (EmailInputElementFields parsedActionId parsedInitialValue parsedDispatchActionConfig parsedFocusOnLoad parsedPlaceholder (remaining ["action_id", "initial_value", "dispatch_action_config", "focus_on_load", "placeholder"] fields))

instance FromJSON EmailInputElement where parseJSON = checkedParser

-- | A menu for selecting multiple options loaded from your app.
--
-- <https://docs.slack.dev/reference/block-kit/block-elements/multi-select-menu-element>
-- focus_on_load is unsupported and must be omitted, including explicit false.
newtype ExternalMultiSelectElement = CheckedExternalMultiSelectElement ExternalMultiSelectElementFields deriving (Eq, Show)

-- | Editable construction input. Call 'buildExternalMultiSelectElement' before encoding.
data ExternalMultiSelectElementFields = ExternalMultiSelectElementFields
  { -- | Sets the identifier Slack returns in interaction payloads when a user acts on this element. It must be unique among the elements of its block. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @action_id@.
    externalMultiSelectElementActionId :: Maybe (Text),
    -- | Sets how many characters the user must type before Slack queries your options endpoint. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @select.min_query_length@.
    externalMultiSelectElementMinQueryLength :: Maybe (Integer),
    -- | Adds options that are selected when the element loads. Each must match an option in the element. Optional; Nothing omits the field. Factory default: @Nothing@.
    externalMultiSelectElementInitialOptions :: Maybe ([SelectOption]),
    -- | Sets a confirmation dialog shown before the action is sent. Optional; Nothing omits the field. Factory default: @Nothing@.
    externalMultiSelectElementConfirm :: Maybe (ConfirmationDialogue),
    -- | Sets the maximum number of items a user can select. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @multi_select.max_selected_items@.
    externalMultiSelectElementMaxSelectedItems :: Maybe (Integer),
    -- | Deprecated compatibility parameter. Slack external multi-select menus do not support focus_on_load; omit it. Explicit true or false is rejected. Optional; Nothing omits the field. Factory default: @Nothing@.
    externalMultiSelectElementFocusOnLoad :: Maybe (Bool),
    -- | Sets the placeholder text shown before a value is chosen. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @select.placeholder@.
    externalMultiSelectElementPlaceholder :: Maybe (PlainText),
    -- | Unmodeled extension fields. Reserved and modeled keys are rejected.
    externalMultiSelectElementExtensions :: Map Text Value
  }
  deriving (Eq, Show)

-- | Start editable fields for ExternalMultiSelectElement; required arguments follow the signature.
-- Optional fields start absent except the explicit shared defaults; no block ID is invented.
-- Finish with 'buildExternalMultiSelectElement' to validate before JSON encoding.
externalMultiSelectElement :: ExternalMultiSelectElementFields
externalMultiSelectElement = ExternalMultiSelectElementFields (Nothing) (Nothing) (Nothing) (Nothing) (Nothing) (Nothing) (Nothing) (Map.empty)

-- | Inspect immutable construction fields. Rebuild edits with 'buildExternalMultiSelectElement' to revalidate.
inspectExternalMultiSelectElement :: ExternalMultiSelectElement -> ExternalMultiSelectElementFields
inspectExternalMultiSelectElement (CheckedExternalMultiSelectElement fields) = fields

-- | Validate fields, extensions and receiving context. Return structured errors or a checked ExternalMultiSelectElement.
buildExternalMultiSelectElement :: ExternalMultiSelectElementFields -> Result ExternalMultiSelectElement
buildExternalMultiSelectElement fields = do
  checkExtensions ["action_id", "min_query_length", "initial_options", "confirm", "max_selected_items", "focus_on_load", "placeholder"] (externalMultiSelectElementExtensions fields)
  validateFields "ExternalMultiSelectElement" (wireExternalMultiSelectElement fields)
  pure (CheckedExternalMultiSelectElement fields)

wireExternalMultiSelectElement :: ExternalMultiSelectElementFields -> Value
wireExternalMultiSelectElement fields =
  object $
    ["type" .= ("multi_external_select" :: Text)] <> optional "action_id" (externalMultiSelectElementActionId fields) <> optional "min_query_length" (externalMultiSelectElementMinQueryLength fields) <> optional "initial_options" (externalMultiSelectElementInitialOptions fields) <> optional "confirm" (externalMultiSelectElementConfirm fields) <> optional "max_selected_items" (externalMultiSelectElementMaxSelectedItems fields) <> optional "focus_on_load" (externalMultiSelectElementFocusOnLoad fields) <> optional "placeholder" (externalMultiSelectElementPlaceholder fields) <> extensionPairs (externalMultiSelectElementExtensions fields)

instance ToJSON ExternalMultiSelectElement where toJSON (CheckedExternalMultiSelectElement fields) = wireExternalMultiSelectElement fields

instance FromSlackJSON ExternalMultiSelectElement where
  fromSlackJSON value = do
    fields <- wireObject "multi_external_select" value
    checkIntegerBounds "ExternalMultiSelectElement" (Object fields)
    parsedActionId <- optionalField "action_id" fields
    parsedMinQueryLength <- optionalField "min_query_length" fields
    parsedInitialOptions <- optionalField "initial_options" fields
    parsedConfirm <- optionalField "confirm" fields
    parsedMaxSelectedItems <- optionalField "max_selected_items" fields
    parsedFocusOnLoad <- optionalField "focus_on_load" fields
    parsedPlaceholder <- optionalField "placeholder" (coerceField "placeholder" "plain_text" fields)
    buildExternalMultiSelectElement (ExternalMultiSelectElementFields parsedActionId parsedMinQueryLength parsedInitialOptions parsedConfirm parsedMaxSelectedItems parsedFocusOnLoad parsedPlaceholder (remaining ["action_id", "min_query_length", "initial_options", "confirm", "max_selected_items", "focus_on_load", "placeholder"] fields))

instance FromJSON ExternalMultiSelectElement where parseJSON = checkedParser

-- | A menu for selecting one option loaded from your app.
--
-- <https://docs.slack.dev/reference/block-kit/block-elements/select-menu-element>
newtype ExternalSelectElement = CheckedExternalSelectElement ExternalSelectElementFields deriving (Eq, Show)

-- | Editable construction input. Call 'buildExternalSelectElement' before encoding.
data ExternalSelectElementFields = ExternalSelectElementFields
  { -- | Sets the identifier Slack returns in interaction payloads when a user acts on this element. It must be unique among the elements of its block. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @action_id@.
    externalSelectElementActionId :: Maybe (Text),
    -- | Sets how many characters the user must type before Slack queries your options endpoint. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @select.min_query_length@.
    externalSelectElementMinQueryLength :: Maybe (Integer),
    -- | Sets the option selected when the element loads. It must match an option in the element. Optional; Nothing omits the field. Factory default: @Nothing@.
    externalSelectElementInitialOption :: Maybe (SelectOption),
    -- | Sets a confirmation dialog shown before the action is sent. Optional; Nothing omits the field. Factory default: @Nothing@.
    externalSelectElementConfirm :: Maybe (ConfirmationDialogue),
    -- | Sets whether the element receives focus when the view opens. Only one element per view may do so. Optional; Nothing omits the field. Factory default: @Nothing@.
    externalSelectElementFocusOnLoad :: Maybe (Bool),
    -- | Sets the placeholder text shown before a value is chosen. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @select.placeholder@.
    externalSelectElementPlaceholder :: Maybe (PlainText),
    -- | Unmodeled extension fields. Reserved and modeled keys are rejected.
    externalSelectElementExtensions :: Map Text Value
  }
  deriving (Eq, Show)

-- | Start editable fields for ExternalSelectElement; required arguments follow the signature.
-- Optional fields start absent except the explicit shared defaults; no block ID is invented.
-- Finish with 'buildExternalSelectElement' to validate before JSON encoding.
externalSelectElement :: ExternalSelectElementFields
externalSelectElement = ExternalSelectElementFields (Nothing) (Nothing) (Nothing) (Nothing) (Nothing) (Nothing) (Map.empty)

-- | Inspect immutable construction fields. Rebuild edits with 'buildExternalSelectElement' to revalidate.
inspectExternalSelectElement :: ExternalSelectElement -> ExternalSelectElementFields
inspectExternalSelectElement (CheckedExternalSelectElement fields) = fields

-- | Validate fields, extensions and receiving context. Return structured errors or a checked ExternalSelectElement.
buildExternalSelectElement :: ExternalSelectElementFields -> Result ExternalSelectElement
buildExternalSelectElement fields = do
  checkExtensions ["action_id", "min_query_length", "initial_option", "confirm", "focus_on_load", "placeholder"] (externalSelectElementExtensions fields)
  validateFields "ExternalSelectElement" (wireExternalSelectElement fields)
  pure (CheckedExternalSelectElement fields)

wireExternalSelectElement :: ExternalSelectElementFields -> Value
wireExternalSelectElement fields =
  object $
    ["type" .= ("external_select" :: Text)] <> optional "action_id" (externalSelectElementActionId fields) <> optional "min_query_length" (externalSelectElementMinQueryLength fields) <> optional "initial_option" (externalSelectElementInitialOption fields) <> optional "confirm" (externalSelectElementConfirm fields) <> optional "focus_on_load" (externalSelectElementFocusOnLoad fields) <> optional "placeholder" (externalSelectElementPlaceholder fields) <> extensionPairs (externalSelectElementExtensions fields)

instance ToJSON ExternalSelectElement where toJSON (CheckedExternalSelectElement fields) = wireExternalSelectElement fields

instance FromSlackJSON ExternalSelectElement where
  fromSlackJSON value = do
    fields <- wireObject "external_select" value
    checkIntegerBounds "ExternalSelectElement" (Object fields)
    parsedActionId <- optionalField "action_id" fields
    parsedMinQueryLength <- optionalField "min_query_length" fields
    parsedInitialOption <- optionalField "initial_option" fields
    parsedConfirm <- optionalField "confirm" fields
    parsedFocusOnLoad <- optionalField "focus_on_load" fields
    parsedPlaceholder <- optionalField "placeholder" (coerceField "placeholder" "plain_text" fields)
    buildExternalSelectElement (ExternalSelectElementFields parsedActionId parsedMinQueryLength parsedInitialOption parsedConfirm parsedFocusOnLoad parsedPlaceholder (remaining ["action_id", "min_query_length", "initial_option", "confirm", "focus_on_load", "placeholder"] fields))

instance FromJSON ExternalSelectElement where parseJSON = checkedParser

-- | A pair of thumbs-up and thumbs-down feedback buttons.
--
-- <https://docs.slack.dev/reference/block-kit/block-elements/feedback-buttons-element>
newtype FeedbackButtonsElement = CheckedFeedbackButtonsElement FeedbackButtonsElementFields deriving (Eq, Show)

-- | Editable construction input. Call 'buildFeedbackButtonsElement' before encoding.
data FeedbackButtonsElementFields = FeedbackButtonsElementFields
  { -- | Sets the button for positive feedback. Required.
    feedbackButtonsElementPositiveButton :: FeedbackButton,
    -- | Sets the button for negative feedback. Required.
    feedbackButtonsElementNegativeButton :: FeedbackButton,
    -- | Sets the identifier Slack returns in interaction payloads when a user acts on this element. It must be unique among the elements of its block. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @action_id@.
    feedbackButtonsElementActionId :: Maybe (Text),
    -- | Unmodeled extension fields. Reserved and modeled keys are rejected.
    feedbackButtonsElementExtensions :: Map Text Value
  }
  deriving (Eq, Show)

-- | Start editable fields for FeedbackButtonsElement; required arguments follow the signature.
-- Optional fields start absent except the explicit shared defaults; no block ID is invented.
-- Finish with 'buildFeedbackButtonsElement' to validate before JSON encoding.
feedbackButtonsElement :: FeedbackButton -> FeedbackButton -> FeedbackButtonsElementFields
feedbackButtonsElement arg0 arg1 = FeedbackButtonsElementFields (arg0) (arg1) (Nothing) (Map.empty)

-- | Inspect immutable construction fields. Rebuild edits with 'buildFeedbackButtonsElement' to revalidate.
inspectFeedbackButtonsElement :: FeedbackButtonsElement -> FeedbackButtonsElementFields
inspectFeedbackButtonsElement (CheckedFeedbackButtonsElement fields) = fields

-- | Validate fields, extensions and receiving context. Return structured errors or a checked FeedbackButtonsElement.
buildFeedbackButtonsElement :: FeedbackButtonsElementFields -> Result FeedbackButtonsElement
buildFeedbackButtonsElement fields = do
  checkExtensions ["positive_button", "negative_button", "action_id"] (feedbackButtonsElementExtensions fields)
  validateFields "FeedbackButtonsElement" (wireFeedbackButtonsElement fields)
  pure (CheckedFeedbackButtonsElement fields)

wireFeedbackButtonsElement :: FeedbackButtonsElementFields -> Value
wireFeedbackButtonsElement fields =
  object $
    ["type" .= ("feedback_buttons" :: Text)] <> ["positive_button" .= (feedbackButtonsElementPositiveButton fields)] <> ["negative_button" .= (feedbackButtonsElementNegativeButton fields)] <> optional "action_id" (feedbackButtonsElementActionId fields) <> extensionPairs (feedbackButtonsElementExtensions fields)

instance ToJSON FeedbackButtonsElement where toJSON (CheckedFeedbackButtonsElement fields) = wireFeedbackButtonsElement fields

instance FromSlackJSON FeedbackButtonsElement where
  fromSlackJSON value = do
    fields <- wireObject "feedback_buttons" value
    parsedPositiveButton <- required "positive_button" fields
    parsedNegativeButton <- required "negative_button" fields
    parsedActionId <- optionalField "action_id" fields
    buildFeedbackButtonsElement (FeedbackButtonsElementFields parsedPositiveButton parsedNegativeButton parsedActionId (remaining ["positive_button", "negative_button", "action_id"] fields))

instance FromJSON FeedbackButtonsElement where parseJSON = checkedParser

-- | An input that lets users upload files.
--
-- <https://docs.slack.dev/reference/block-kit/block-elements/file-input-element>
newtype FileInputElement = CheckedFileInputElement FileInputElementFields deriving (Eq, Show)

-- | Editable construction input. Call 'buildFileInputElement' before encoding.
data FileInputElementFields = FileInputElementFields
  { -- | Sets the identifier Slack returns in interaction payloads when a user acts on this element. It must be unique among the elements of its block. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @action_id@.
    fileInputElementActionId :: Maybe (Text),
    -- | Adds accepted file extensions, such as pdf or png. Optional; Nothing omits the field. Factory default: @Nothing@.
    fileInputElementFiletypes :: Maybe ([Text]),
    -- | Sets the maximum number of files a user can upload. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @file_input.max_files@.
    fileInputElementMaxFiles :: Maybe (Integer),
    -- | Unmodeled extension fields. Reserved and modeled keys are rejected.
    fileInputElementExtensions :: Map Text Value
  }
  deriving (Eq, Show)

-- | Start editable fields for FileInputElement; required arguments follow the signature.
-- Optional fields start absent except the explicit shared defaults; no block ID is invented.
-- Finish with 'buildFileInputElement' to validate before JSON encoding.
fileInputElement :: FileInputElementFields
fileInputElement = FileInputElementFields (Nothing) (Nothing) (Nothing) (Map.empty)

-- | Inspect immutable construction fields. Rebuild edits with 'buildFileInputElement' to revalidate.
inspectFileInputElement :: FileInputElement -> FileInputElementFields
inspectFileInputElement (CheckedFileInputElement fields) = fields

-- | Validate fields, extensions and receiving context. Return structured errors or a checked FileInputElement.
buildFileInputElement :: FileInputElementFields -> Result FileInputElement
buildFileInputElement fields = do
  checkExtensions ["action_id", "filetypes", "max_files"] (fileInputElementExtensions fields)
  validateFields "FileInputElement" (wireFileInputElement fields)
  pure (CheckedFileInputElement fields)

wireFileInputElement :: FileInputElementFields -> Value
wireFileInputElement fields =
  object $
    ["type" .= ("file_input" :: Text)] <> optional "action_id" (fileInputElementActionId fields) <> optional "filetypes" (fileInputElementFiletypes fields) <> optional "max_files" (fileInputElementMaxFiles fields) <> extensionPairs (fileInputElementExtensions fields)

instance ToJSON FileInputElement where toJSON (CheckedFileInputElement fields) = wireFileInputElement fields

instance FromSlackJSON FileInputElement where
  fromSlackJSON value = do
    fields <- wireObject "file_input" value
    checkIntegerBounds "FileInputElement" (Object fields)
    parsedActionId <- optionalField "action_id" fields
    parsedFiletypes <- optionalField "filetypes" fields
    parsedMaxFiles <- optionalField "max_files" fields
    buildFileInputElement (FileInputElementFields parsedActionId parsedFiletypes parsedMaxFiles (remaining ["action_id", "filetypes", "max_files"] fields))

instance FromJSON FileInputElement where parseJSON = checkedParser

-- | A button that shows an icon instead of text.
--
-- <https://docs.slack.dev/reference/block-kit/block-elements/icon-button-element>
newtype IconButtonElement = CheckedIconButtonElement IconButtonElementFields deriving (Eq, Show)

-- | Editable construction input. Call 'buildIconButtonElement' before encoding.
data IconButtonElementFields = IconButtonElementFields
  { -- | Sets the text used as the button's accessible name. Required.
    iconButtonElementText :: PlainText,
    -- | Sets the icon shown on the button. Required.
    iconButtonElementIcon :: IconButtonIcon,
    -- | Sets the identifier Slack returns in interaction payloads when a user acts on this element. It must be unique among the elements of its block. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @action_id@.
    iconButtonElementActionId :: Maybe (Text),
    -- | Sets the application-defined value sent in interaction payloads. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @icon_button.value@.
    iconButtonElementValue :: Maybe (Text),
    -- | Sets a confirmation dialog shown before the action is sent. Optional; Nothing omits the field. Factory default: @Nothing@.
    iconButtonElementConfirm :: Maybe (ConfirmationDialogue),
    -- | Sets the label read by screen readers in place of the visible text. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @icon_button.accessibility_label@.
    iconButtonElementAccessibilityLabel :: Maybe (Text),
    -- | Adds the IDs of users who can see this button. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @icon_button.visible_to_user_ids@.
    iconButtonElementVisibleToUserIds :: Maybe ([Text]),
    -- | Unmodeled extension fields. Reserved and modeled keys are rejected.
    iconButtonElementExtensions :: Map Text Value
  }
  deriving (Eq, Show)

-- | Start editable fields for IconButtonElement; required arguments follow the signature.
-- Optional fields start absent except the explicit shared defaults; no block ID is invented.
-- Finish with 'buildIconButtonElement' to validate before JSON encoding.
iconButtonElement :: PlainText -> IconButtonIcon -> IconButtonElementFields
iconButtonElement arg0 arg1 = IconButtonElementFields (arg0) (arg1) (Nothing) (Nothing) (Nothing) (Nothing) (Nothing) (Map.empty)

-- | Inspect immutable construction fields. Rebuild edits with 'buildIconButtonElement' to revalidate.
inspectIconButtonElement :: IconButtonElement -> IconButtonElementFields
inspectIconButtonElement (CheckedIconButtonElement fields) = fields

-- | Validate fields, extensions and receiving context. Return structured errors or a checked IconButtonElement.
buildIconButtonElement :: IconButtonElementFields -> Result IconButtonElement
buildIconButtonElement fields = do
  checkExtensions ["text", "icon", "action_id", "value", "confirm", "accessibility_label", "visible_to_user_ids"] (iconButtonElementExtensions fields)
  validateFields "IconButtonElement" (wireIconButtonElement fields)
  pure (CheckedIconButtonElement fields)

wireIconButtonElement :: IconButtonElementFields -> Value
wireIconButtonElement fields =
  object $
    ["type" .= ("icon_button" :: Text)] <> ["text" .= (iconButtonElementText fields)] <> ["icon" .= (iconButtonElementIcon fields)] <> optional "action_id" (iconButtonElementActionId fields) <> optional "value" (iconButtonElementValue fields) <> optional "confirm" (iconButtonElementConfirm fields) <> optional "accessibility_label" (iconButtonElementAccessibilityLabel fields) <> optional "visible_to_user_ids" (iconButtonElementVisibleToUserIds fields) <> extensionPairs (iconButtonElementExtensions fields)

instance ToJSON IconButtonElement where toJSON (CheckedIconButtonElement fields) = wireIconButtonElement fields

instance FromSlackJSON IconButtonElement where
  fromSlackJSON value = do
    fields <- wireObject "icon_button" value
    parsedText <- required "text" (coerceField "text" "plain_text" fields)
    parsedIcon <- required "icon" fields
    parsedActionId <- optionalField "action_id" fields
    parsedValue <- optionalField "value" fields
    parsedConfirm <- optionalField "confirm" fields
    parsedAccessibilityLabel <- optionalField "accessibility_label" fields
    parsedVisibleToUserIds <- optionalField "visible_to_user_ids" fields
    buildIconButtonElement (IconButtonElementFields parsedText parsedIcon parsedActionId parsedValue parsedConfirm parsedAccessibilityLabel parsedVisibleToUserIds (remaining ["text", "icon", "action_id", "value", "confirm", "accessibility_label", "visible_to_user_ids"] fields))

instance FromJSON IconButtonElement where parseJSON = checkedParser

-- | An image displayed inside a section, context, or card.
--
-- <https://docs.slack.dev/reference/block-kit/block-elements/image-element>
-- Provide exactly one of an image URL or a Slack file.
newtype ImageElement = CheckedImageElement ImageElementFields deriving (Eq, Show)

-- | Editable construction input. Call 'buildImageElement' before encoding.
data ImageElementFields = ImageElementFields
  { -- | Sets a plain-text summary of the image or video for assistive technology. Required. Shared limit: @image_element.alt_text@.
    imageElementAltText :: Text,
    -- | Sets the publicly accessible URL of the image. Cannot be combined with a Slack file. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @image_element.image_url@.
    imageElementImageUrl :: Maybe (Text),
    -- | Sets a file hosted in Slack as the image source. Cannot be combined with an image URL. Optional; Nothing omits the field. Factory default: @Nothing@.
    imageElementSlackFile :: Maybe (SlackFile),
    -- | Unmodeled extension fields. Reserved and modeled keys are rejected.
    imageElementExtensions :: Map Text Value
  }
  deriving (Eq, Show)

-- | Start editable fields for ImageElement; required arguments follow the signature.
-- Optional fields start absent except the explicit shared defaults; no block ID is invented.
-- Finish with 'buildImageElement' to validate before JSON encoding.
imageElement :: Text -> ImageElementFields
imageElement arg0 = ImageElementFields (arg0) (Nothing) (Nothing) (Map.empty)

-- | Inspect immutable construction fields. Rebuild edits with 'buildImageElement' to revalidate.
inspectImageElement :: ImageElement -> ImageElementFields
inspectImageElement (CheckedImageElement fields) = fields

-- | Validate fields, extensions and receiving context. Return structured errors or a checked ImageElement.
buildImageElement :: ImageElementFields -> Result ImageElement
buildImageElement fields = do
  checkExtensions ["alt_text", "image_url", "slack_file"] (imageElementExtensions fields)
  validateFields "ImageElement" (wireImageElement fields)
  pure (CheckedImageElement fields)

wireImageElement :: ImageElementFields -> Value
wireImageElement fields =
  object $
    ["type" .= ("image" :: Text)] <> ["alt_text" .= (imageElementAltText fields)] <> optional "image_url" (imageElementImageUrl fields) <> optional "slack_file" (imageElementSlackFile fields) <> extensionPairs (imageElementExtensions fields)

instance ToJSON ImageElement where toJSON (CheckedImageElement fields) = wireImageElement fields

instance FromSlackJSON ImageElement where
  fromSlackJSON value = do
    fields <- wireObject "image" value
    parsedAltText <- required "alt_text" fields
    parsedImageUrl <- optionalField "image_url" fields
    parsedSlackFile <- optionalField "slack_file" fields
    buildImageElement (ImageElementFields parsedAltText parsedImageUrl parsedSlackFile (remaining ["alt_text", "image_url", "slack_file"] fields))

instance FromJSON ImageElement where parseJSON = checkedParser

-- | An input that accepts whole or decimal numbers.
--
-- <https://docs.slack.dev/reference/block-kit/block-elements/number-input-element>
-- The minimum value cannot exceed the maximum value.
newtype NumberInputElement = CheckedNumberInputElement NumberInputElementFields deriving (Eq, Show)

-- | Editable construction input. Call 'buildNumberInputElement' before encoding.
data NumberInputElementFields = NumberInputElementFields
  { -- | Sets the identifier Slack returns in interaction payloads when a user acts on this element. It must be unique among the elements of its block. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @action_id@.
    numberInputElementActionId :: Maybe (Text),
    -- | Sets whether the input accepts decimal numbers. Required.
    numberInputElementIsDecimalAllowed :: Bool,
    -- | Sets the number present when the input loads, as a string such as 42 or 3.5. Optional; Nothing omits the field. Factory default: @Nothing@.
    numberInputElementInitialValue :: Maybe (Text),
    -- | Sets the smallest accepted number. Sent as a finite numeric string; native numeric convenience arguments are converted to strings. Optional; Nothing omits the field. Factory default: @Nothing@.
    numberInputElementMinValue :: Maybe (Text),
    -- | Sets the largest accepted number. Sent as a finite numeric string; native numeric convenience arguments are converted to strings. Optional; Nothing omits the field. Factory default: @Nothing@.
    numberInputElementMaxValue :: Maybe (Text),
    -- | Sets which user interactions send a block_actions payload. Optional; Nothing omits the field. Factory default: @Nothing@.
    numberInputElementDispatchActionConfig :: Maybe (DispatchActionConfiguration),
    -- | Sets whether the element receives focus when the view opens. Only one element per view may do so. Optional; Nothing omits the field. Factory default: @Nothing@.
    numberInputElementFocusOnLoad :: Maybe (Bool),
    -- | Sets the placeholder text shown before a value is chosen. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @number_input.placeholder@.
    numberInputElementPlaceholder :: Maybe (PlainText),
    -- | Unmodeled extension fields. Reserved and modeled keys are rejected.
    numberInputElementExtensions :: Map Text Value
  }
  deriving (Eq, Show)

-- | Start editable fields for NumberInputElement; required arguments follow the signature.
-- Optional fields start absent except the explicit shared defaults; no block ID is invented.
-- Finish with 'buildNumberInputElement' to validate before JSON encoding.
numberInputElement :: Bool -> NumberInputElementFields
numberInputElement arg0 = NumberInputElementFields (Nothing) (arg0) (Nothing) (Nothing) (Nothing) (Nothing) (Nothing) (Nothing) (Map.empty)

-- | Inspect immutable construction fields. Rebuild edits with 'buildNumberInputElement' to revalidate.
inspectNumberInputElement :: NumberInputElement -> NumberInputElementFields
inspectNumberInputElement (CheckedNumberInputElement fields) = fields

-- | Validate fields, extensions and receiving context. Return structured errors or a checked NumberInputElement.
buildNumberInputElement :: NumberInputElementFields -> Result NumberInputElement
buildNumberInputElement fields = do
  checkExtensions ["action_id", "is_decimal_allowed", "initial_value", "min_value", "max_value", "dispatch_action_config", "focus_on_load", "placeholder"] (numberInputElementExtensions fields)
  validateFields "NumberInputElement" (wireNumberInputElement fields)
  pure (CheckedNumberInputElement fields)

wireNumberInputElement :: NumberInputElementFields -> Value
wireNumberInputElement fields =
  object $
    ["type" .= ("number_input" :: Text)] <> optional "action_id" (numberInputElementActionId fields) <> ["is_decimal_allowed" .= (numberInputElementIsDecimalAllowed fields)] <> optional "initial_value" (numberInputElementInitialValue fields) <> optional "min_value" (numberInputElementMinValue fields) <> optional "max_value" (numberInputElementMaxValue fields) <> optional "dispatch_action_config" (numberInputElementDispatchActionConfig fields) <> optional "focus_on_load" (numberInputElementFocusOnLoad fields) <> optional "placeholder" (numberInputElementPlaceholder fields) <> extensionPairs (numberInputElementExtensions fields)

instance ToJSON NumberInputElement where toJSON (CheckedNumberInputElement fields) = wireNumberInputElement fields

instance FromSlackJSON NumberInputElement where
  fromSlackJSON value = do
    fields <- wireObject "number_input" value
    parsedActionId <- optionalField "action_id" fields
    parsedIsDecimalAllowed <- required "is_decimal_allowed" fields
    parsedInitialValue <- optionalField "initial_value" fields
    parsedMinValue <- optionalField "min_value" (coerceField "min_value" "decimal_string" fields)
    parsedMaxValue <- optionalField "max_value" (coerceField "max_value" "decimal_string" fields)
    parsedDispatchActionConfig <- optionalField "dispatch_action_config" fields
    parsedFocusOnLoad <- optionalField "focus_on_load" fields
    parsedPlaceholder <- optionalField "placeholder" (coerceField "placeholder" "plain_text" fields)
    buildNumberInputElement (NumberInputElementFields parsedActionId parsedIsDecimalAllowed parsedInitialValue parsedMinValue parsedMaxValue parsedDispatchActionConfig parsedFocusOnLoad parsedPlaceholder (remaining ["action_id", "is_decimal_allowed", "initial_value", "min_value", "max_value", "dispatch_action_config", "focus_on_load", "placeholder"] fields))

instance FromJSON NumberInputElement where parseJSON = checkedParser

-- | A compact menu of up to five options.
--
-- <https://docs.slack.dev/reference/block-kit/block-elements/overflow-menu-element>
newtype OverflowElement = CheckedOverflowElement OverflowElementFields deriving (Eq, Show)

-- | Editable construction input. Call 'buildOverflowElement' before encoding.
data OverflowElementFields = OverflowElementFields
  { -- | Sets the identifier Slack returns in interaction payloads when a user acts on this element. It must be unique among the elements of its block. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @action_id@.
    overflowElementActionId :: Maybe (Text),
    -- | Adds selectable options in display order. Required. Shared limit: @overflow.options@.
    overflowElementOptions :: [SelectOption],
    -- | Sets a confirmation dialog shown before the action is sent. Optional; Nothing omits the field. Factory default: @Nothing@.
    overflowElementConfirm :: Maybe (ConfirmationDialogue),
    -- | Unmodeled extension fields. Reserved and modeled keys are rejected.
    overflowElementExtensions :: Map Text Value
  }
  deriving (Eq, Show)

-- | Start editable fields for OverflowElement; required arguments follow the signature.
-- Optional fields start absent except the explicit shared defaults; no block ID is invented.
-- Finish with 'buildOverflowElement' to validate before JSON encoding.
overflowElement :: [SelectOption] -> OverflowElementFields
overflowElement arg0 = OverflowElementFields (Nothing) (arg0) (Nothing) (Map.empty)

-- | Inspect immutable construction fields. Rebuild edits with 'buildOverflowElement' to revalidate.
inspectOverflowElement :: OverflowElement -> OverflowElementFields
inspectOverflowElement (CheckedOverflowElement fields) = fields

-- | Validate fields, extensions and receiving context. Return structured errors or a checked OverflowElement.
buildOverflowElement :: OverflowElementFields -> Result OverflowElement
buildOverflowElement fields = do
  checkExtensions ["action_id", "options", "confirm"] (overflowElementExtensions fields)
  validateFields "OverflowElement" (wireOverflowElement fields)
  pure (CheckedOverflowElement fields)

wireOverflowElement :: OverflowElementFields -> Value
wireOverflowElement fields =
  object $
    ["type" .= ("overflow" :: Text)] <> optional "action_id" (overflowElementActionId fields) <> ["options" .= (overflowElementOptions fields)] <> optional "confirm" (overflowElementConfirm fields) <> extensionPairs (overflowElementExtensions fields)

instance ToJSON OverflowElement where toJSON (CheckedOverflowElement fields) = wireOverflowElement fields

instance FromSlackJSON OverflowElement where
  fromSlackJSON value = do
    fields <- wireObject "overflow" value
    parsedActionId <- optionalField "action_id" fields
    parsedOptions <- required "options" fields
    parsedConfirm <- optionalField "confirm" fields
    buildOverflowElement (OverflowElementFields parsedActionId parsedOptions parsedConfirm (remaining ["action_id", "options", "confirm"] fields))

instance FromJSON OverflowElement where parseJSON = checkedParser

-- | A single-line or multi-line free-text input.
--
-- <https://docs.slack.dev/reference/block-kit/block-elements/plain-text-input-element>
-- When both min_length and max_length are supplied, min_length must not exceed max_length; otherwise the input cannot be satisfied.
newtype PlainTextInputElement = CheckedPlainTextInputElement PlainTextInputElementFields deriving (Eq, Show)

-- | Editable construction input. Call 'buildPlainTextInputElement' before encoding.
data PlainTextInputElementFields = PlainTextInputElementFields
  { -- | Sets the identifier Slack returns in interaction payloads when a user acts on this element. It must be unique among the elements of its block. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @action_id@.
    plainTextInputElementActionId :: Maybe (Text),
    -- | Sets the value present when the input loads. Optional; Nothing omits the field. Factory default: @Nothing@.
    plainTextInputElementInitialValue :: Maybe (Text),
    -- | Sets whether the input is a multi-line text area. Optional; Nothing omits the field. Factory default: @Nothing@.
    plainTextInputElementMultiline :: Maybe (Bool),
    -- | Sets the minimum number of characters the user must enter. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @plain_text_input.min_length@.
    plainTextInputElementMinLength :: Maybe (Integer),
    -- | Sets the maximum number of characters the user can enter. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @plain_text_input.max_length@.
    plainTextInputElementMaxLength :: Maybe (Integer),
    -- | Sets which user interactions send a block_actions payload. Optional; Nothing omits the field. Factory default: @Nothing@.
    plainTextInputElementDispatchActionConfig :: Maybe (DispatchActionConfiguration),
    -- | Sets whether the element receives focus when the view opens. Only one element per view may do so. Optional; Nothing omits the field. Factory default: @Nothing@.
    plainTextInputElementFocusOnLoad :: Maybe (Bool),
    -- | Sets the placeholder text shown before a value is chosen. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @plain_text_input.placeholder@.
    plainTextInputElementPlaceholder :: Maybe (PlainText),
    -- | Unmodeled extension fields. Reserved and modeled keys are rejected.
    plainTextInputElementExtensions :: Map Text Value
  }
  deriving (Eq, Show)

-- | Start editable fields for PlainTextInputElement; required arguments follow the signature.
-- Optional fields start absent except the explicit shared defaults; no block ID is invented.
-- Finish with 'buildPlainTextInputElement' to validate before JSON encoding.
plainTextInputElement :: PlainTextInputElementFields
plainTextInputElement = PlainTextInputElementFields (Nothing) (Nothing) (Nothing) (Nothing) (Nothing) (Nothing) (Nothing) (Nothing) (Map.empty)

-- | Inspect immutable construction fields. Rebuild edits with 'buildPlainTextInputElement' to revalidate.
inspectPlainTextInputElement :: PlainTextInputElement -> PlainTextInputElementFields
inspectPlainTextInputElement (CheckedPlainTextInputElement fields) = fields

-- | Validate fields, extensions and receiving context. Return structured errors or a checked PlainTextInputElement.
buildPlainTextInputElement :: PlainTextInputElementFields -> Result PlainTextInputElement
buildPlainTextInputElement fields = do
  checkExtensions ["action_id", "initial_value", "multiline", "min_length", "max_length", "dispatch_action_config", "focus_on_load", "placeholder"] (plainTextInputElementExtensions fields)
  validateFields "PlainTextInputElement" (wirePlainTextInputElement fields)
  pure (CheckedPlainTextInputElement fields)

wirePlainTextInputElement :: PlainTextInputElementFields -> Value
wirePlainTextInputElement fields =
  object $
    ["type" .= ("plain_text_input" :: Text)] <> optional "action_id" (plainTextInputElementActionId fields) <> optional "initial_value" (plainTextInputElementInitialValue fields) <> optional "multiline" (plainTextInputElementMultiline fields) <> optional "min_length" (plainTextInputElementMinLength fields) <> optional "max_length" (plainTextInputElementMaxLength fields) <> optional "dispatch_action_config" (plainTextInputElementDispatchActionConfig fields) <> optional "focus_on_load" (plainTextInputElementFocusOnLoad fields) <> optional "placeholder" (plainTextInputElementPlaceholder fields) <> extensionPairs (plainTextInputElementExtensions fields)

instance ToJSON PlainTextInputElement where toJSON (CheckedPlainTextInputElement fields) = wirePlainTextInputElement fields

instance FromSlackJSON PlainTextInputElement where
  fromSlackJSON value = do
    fields <- wireObject "plain_text_input" value
    checkIntegerBounds "PlainTextInputElement" (Object fields)
    parsedActionId <- optionalField "action_id" fields
    parsedInitialValue <- optionalField "initial_value" fields
    parsedMultiline <- optionalField "multiline" fields
    parsedMinLength <- optionalField "min_length" fields
    parsedMaxLength <- optionalField "max_length" fields
    parsedDispatchActionConfig <- optionalField "dispatch_action_config" fields
    parsedFocusOnLoad <- optionalField "focus_on_load" fields
    parsedPlaceholder <- optionalField "placeholder" (coerceField "placeholder" "plain_text" fields)
    buildPlainTextInputElement (PlainTextInputElementFields parsedActionId parsedInitialValue parsedMultiline parsedMinLength parsedMaxLength parsedDispatchActionConfig parsedFocusOnLoad parsedPlaceholder (remaining ["action_id", "initial_value", "multiline", "min_length", "max_length", "dispatch_action_config", "focus_on_load", "placeholder"] fields))

instance FromJSON PlainTextInputElement where parseJSON = checkedParser

-- | A group of radio buttons.
--
-- <https://docs.slack.dev/reference/block-kit/block-elements/radio-button-group-element>
newtype RadioButtonsElement = CheckedRadioButtonsElement RadioButtonsElementFields deriving (Eq, Show)

-- | Editable construction input. Call 'buildRadioButtonsElement' before encoding.
data RadioButtonsElementFields = RadioButtonsElementFields
  { -- | Sets the identifier Slack returns in interaction payloads when a user acts on this element. It must be unique among the elements of its block. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @action_id@.
    radioButtonsElementActionId :: Maybe (Text),
    -- | Adds selectable options in display order. Required. Shared limit: @radio_buttons.options@.
    radioButtonsElementOptions :: [SelectOption],
    -- | Sets the option selected when the element loads. It must match an option in the element. Optional; Nothing omits the field. Factory default: @Nothing@.
    radioButtonsElementInitialOption :: Maybe (SelectOption),
    -- | Sets a confirmation dialog shown before the action is sent. Optional; Nothing omits the field. Factory default: @Nothing@.
    radioButtonsElementConfirm :: Maybe (ConfirmationDialogue),
    -- | Sets whether the element receives focus when the view opens. Only one element per view may do so. Optional; Nothing omits the field. Factory default: @Nothing@.
    radioButtonsElementFocusOnLoad :: Maybe (Bool),
    -- | Unmodeled extension fields. Reserved and modeled keys are rejected.
    radioButtonsElementExtensions :: Map Text Value
  }
  deriving (Eq, Show)

-- | Start editable fields for RadioButtonsElement; required arguments follow the signature.
-- Optional fields start absent except the explicit shared defaults; no block ID is invented.
-- Finish with 'buildRadioButtonsElement' to validate before JSON encoding.
radioButtonsElement :: [SelectOption] -> RadioButtonsElementFields
radioButtonsElement arg0 = RadioButtonsElementFields (Nothing) (arg0) (Nothing) (Nothing) (Nothing) (Map.empty)

-- | Inspect immutable construction fields. Rebuild edits with 'buildRadioButtonsElement' to revalidate.
inspectRadioButtonsElement :: RadioButtonsElement -> RadioButtonsElementFields
inspectRadioButtonsElement (CheckedRadioButtonsElement fields) = fields

-- | Validate fields, extensions and receiving context. Return structured errors or a checked RadioButtonsElement.
buildRadioButtonsElement :: RadioButtonsElementFields -> Result RadioButtonsElement
buildRadioButtonsElement fields = do
  checkExtensions ["action_id", "options", "initial_option", "confirm", "focus_on_load"] (radioButtonsElementExtensions fields)
  validateFields "RadioButtonsElement" (wireRadioButtonsElement fields)
  pure (CheckedRadioButtonsElement fields)

wireRadioButtonsElement :: RadioButtonsElementFields -> Value
wireRadioButtonsElement fields =
  object $
    ["type" .= ("radio_buttons" :: Text)] <> optional "action_id" (radioButtonsElementActionId fields) <> ["options" .= (radioButtonsElementOptions fields)] <> optional "initial_option" (radioButtonsElementInitialOption fields) <> optional "confirm" (radioButtonsElementConfirm fields) <> optional "focus_on_load" (radioButtonsElementFocusOnLoad fields) <> extensionPairs (radioButtonsElementExtensions fields)

instance ToJSON RadioButtonsElement where toJSON (CheckedRadioButtonsElement fields) = wireRadioButtonsElement fields

instance FromSlackJSON RadioButtonsElement where
  fromSlackJSON value = do
    fields <- wireObject "radio_buttons" value
    parsedActionId <- optionalField "action_id" fields
    parsedOptions <- required "options" fields
    parsedInitialOption <- optionalField "initial_option" fields
    parsedConfirm <- optionalField "confirm" fields
    parsedFocusOnLoad <- optionalField "focus_on_load" fields
    buildRadioButtonsElement (RadioButtonsElementFields parsedActionId parsedOptions parsedInitialOption parsedConfirm parsedFocusOnLoad (remaining ["action_id", "options", "initial_option", "confirm", "focus_on_load"] fields))

instance FromJSON RadioButtonsElement where parseJSON = checkedParser

-- | An input that accepts formatted rich text.
--
-- <https://docs.slack.dev/reference/block-kit/block-elements/rich-text-input-element>
newtype RichTextInputElement = CheckedRichTextInputElement RichTextInputElementFields deriving (Eq, Show)

-- | Editable construction input. Call 'buildRichTextInputElement' before encoding.
data RichTextInputElementFields = RichTextInputElementFields
  { -- | Sets the identifier Slack returns in interaction payloads when a user acts on this element. It must be unique among the elements of its block. Required. Shared limit: @action_id@.
    richTextInputElementActionId :: Text,
    -- | Sets the rich text present when the input loads. Optional; Nothing omits the field. Factory default: @Nothing@.
    richTextInputElementInitialValue :: Maybe (RichTextBlock),
    -- | Sets which user interactions send a block_actions payload. Optional; Nothing omits the field. Factory default: @Nothing@.
    richTextInputElementDispatchActionConfig :: Maybe (DispatchActionConfiguration),
    -- | Sets whether the element receives focus when the view opens. Only one element per view may do so. Optional; Nothing omits the field. Factory default: @Nothing@.
    richTextInputElementFocusOnLoad :: Maybe (Bool),
    -- | Sets the placeholder text shown before a value is chosen. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @rich_text_input.placeholder@.
    richTextInputElementPlaceholder :: Maybe (PlainText),
    -- | Sets the minimum visible height of the input, in lines. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @rich_text_input.min_lines@.
    richTextInputElementMinLines :: Maybe (Integer),
    -- | Sets the maximum visible height of the input, in lines. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @rich_text_input.max_lines@.
    richTextInputElementMaxLines :: Maybe (Integer),
    -- | Unmodeled extension fields. Reserved and modeled keys are rejected.
    richTextInputElementExtensions :: Map Text Value
  }
  deriving (Eq, Show)

-- | Start editable fields for RichTextInputElement; required arguments follow the signature.
-- Optional fields start absent except the explicit shared defaults; no block ID is invented.
-- Finish with 'buildRichTextInputElement' to validate before JSON encoding.
richTextInputElement :: Text -> RichTextInputElementFields
richTextInputElement arg0 = RichTextInputElementFields (arg0) (Nothing) (Nothing) (Nothing) (Nothing) (Nothing) (Nothing) (Map.empty)

-- | Inspect immutable construction fields. Rebuild edits with 'buildRichTextInputElement' to revalidate.
inspectRichTextInputElement :: RichTextInputElement -> RichTextInputElementFields
inspectRichTextInputElement (CheckedRichTextInputElement fields) = fields

-- | Validate fields, extensions and receiving context. Return structured errors or a checked RichTextInputElement.
buildRichTextInputElement :: RichTextInputElementFields -> Result RichTextInputElement
buildRichTextInputElement fields = do
  checkExtensions ["action_id", "initial_value", "dispatch_action_config", "focus_on_load", "placeholder", "min_lines", "max_lines"] (richTextInputElementExtensions fields)
  validateFields "RichTextInputElement" (wireRichTextInputElement fields)
  pure (CheckedRichTextInputElement fields)

wireRichTextInputElement :: RichTextInputElementFields -> Value
wireRichTextInputElement fields =
  object $
    ["type" .= ("rich_text_input" :: Text)] <> ["action_id" .= (richTextInputElementActionId fields)] <> optional "initial_value" (richTextInputElementInitialValue fields) <> optional "dispatch_action_config" (richTextInputElementDispatchActionConfig fields) <> optional "focus_on_load" (richTextInputElementFocusOnLoad fields) <> optional "placeholder" (richTextInputElementPlaceholder fields) <> optional "min_lines" (richTextInputElementMinLines fields) <> optional "max_lines" (richTextInputElementMaxLines fields) <> extensionPairs (richTextInputElementExtensions fields)

instance ToJSON RichTextInputElement where toJSON (CheckedRichTextInputElement fields) = wireRichTextInputElement fields

instance FromSlackJSON RichTextInputElement where
  fromSlackJSON value = do
    fields <- wireObject "rich_text_input" value
    checkIntegerBounds "RichTextInputElement" (Object fields)
    parsedActionId <- required "action_id" fields
    parsedInitialValue <- optionalField "initial_value" fields
    parsedDispatchActionConfig <- optionalField "dispatch_action_config" fields
    parsedFocusOnLoad <- optionalField "focus_on_load" fields
    parsedPlaceholder <- optionalField "placeholder" (coerceField "placeholder" "plain_text" fields)
    parsedMinLines <- optionalField "min_lines" fields
    parsedMaxLines <- optionalField "max_lines" fields
    buildRichTextInputElement (RichTextInputElementFields parsedActionId parsedInitialValue parsedDispatchActionConfig parsedFocusOnLoad parsedPlaceholder parsedMinLines parsedMaxLines (remaining ["action_id", "initial_value", "dispatch_action_config", "focus_on_load", "placeholder", "min_lines", "max_lines"] fields))

instance FromJSON RichTextInputElement where parseJSON = checkedParser

-- | A menu for selecting multiple options defined in the payload.
--
-- <https://docs.slack.dev/reference/block-kit/block-elements/multi-select-menu-element>
-- Use options or option groups, not both.
newtype StaticMultiSelectElement = CheckedStaticMultiSelectElement StaticMultiSelectElementFields deriving (Eq, Show)

-- | Editable construction input. Call 'buildStaticMultiSelectElement' before encoding.
data StaticMultiSelectElementFields = StaticMultiSelectElementFields
  { -- | Sets the identifier Slack returns in interaction payloads when a user acts on this element. It must be unique among the elements of its block. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @action_id@.
    staticMultiSelectElementActionId :: Maybe (Text),
    -- | Adds selectable options in display order. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @select.options@.
    staticMultiSelectElementOptions :: Maybe ([SelectOption]),
    -- | Adds labelled groups of options in display order. Cannot be combined with ungrouped options. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @select.option_groups@.
    staticMultiSelectElementOptionGroups :: Maybe ([SelectOptionGroup]),
    -- | Adds options that are selected when the element loads. Each must match an option in the element. Optional; Nothing omits the field. Factory default: @Nothing@.
    staticMultiSelectElementInitialOptions :: Maybe ([SelectOption]),
    -- | Sets a confirmation dialog shown before the action is sent. Optional; Nothing omits the field. Factory default: @Nothing@.
    staticMultiSelectElementConfirm :: Maybe (ConfirmationDialogue),
    -- | Sets the maximum number of items a user can select. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @multi_select.max_selected_items@.
    staticMultiSelectElementMaxSelectedItems :: Maybe (Integer),
    -- | Sets whether the element receives focus when the view opens. Only one element per view may do so. Optional; Nothing omits the field. Factory default: @Nothing@.
    staticMultiSelectElementFocusOnLoad :: Maybe (Bool),
    -- | Sets the placeholder text shown before a value is chosen. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @select.placeholder@.
    staticMultiSelectElementPlaceholder :: Maybe (PlainText),
    -- | Unmodeled extension fields. Reserved and modeled keys are rejected.
    staticMultiSelectElementExtensions :: Map Text Value
  }
  deriving (Eq, Show)

-- | Start editable fields for StaticMultiSelectElement; required arguments follow the signature.
-- Optional fields start absent except the explicit shared defaults; no block ID is invented.
-- Finish with 'buildStaticMultiSelectElement' to validate before JSON encoding.
staticMultiSelectElement :: StaticMultiSelectElementFields
staticMultiSelectElement = StaticMultiSelectElementFields (Nothing) (Nothing) (Nothing) (Nothing) (Nothing) (Nothing) (Nothing) (Nothing) (Map.empty)

-- | Inspect immutable construction fields. Rebuild edits with 'buildStaticMultiSelectElement' to revalidate.
inspectStaticMultiSelectElement :: StaticMultiSelectElement -> StaticMultiSelectElementFields
inspectStaticMultiSelectElement (CheckedStaticMultiSelectElement fields) = fields

-- | Validate fields, extensions and receiving context. Return structured errors or a checked StaticMultiSelectElement.
buildStaticMultiSelectElement :: StaticMultiSelectElementFields -> Result StaticMultiSelectElement
buildStaticMultiSelectElement fields = do
  checkExtensions ["action_id", "options", "option_groups", "initial_options", "confirm", "max_selected_items", "focus_on_load", "placeholder"] (staticMultiSelectElementExtensions fields)
  validateFields "StaticMultiSelectElement" (wireStaticMultiSelectElement fields)
  pure (CheckedStaticMultiSelectElement fields)

wireStaticMultiSelectElement :: StaticMultiSelectElementFields -> Value
wireStaticMultiSelectElement fields =
  object $
    ["type" .= ("multi_static_select" :: Text)] <> optional "action_id" (staticMultiSelectElementActionId fields) <> optional "options" (staticMultiSelectElementOptions fields) <> optional "option_groups" (staticMultiSelectElementOptionGroups fields) <> optional "initial_options" (staticMultiSelectElementInitialOptions fields) <> optional "confirm" (staticMultiSelectElementConfirm fields) <> optional "max_selected_items" (staticMultiSelectElementMaxSelectedItems fields) <> optional "focus_on_load" (staticMultiSelectElementFocusOnLoad fields) <> optional "placeholder" (staticMultiSelectElementPlaceholder fields) <> extensionPairs (staticMultiSelectElementExtensions fields)

instance ToJSON StaticMultiSelectElement where toJSON (CheckedStaticMultiSelectElement fields) = wireStaticMultiSelectElement fields

instance FromSlackJSON StaticMultiSelectElement where
  fromSlackJSON value = do
    fields <- wireObject "multi_static_select" value
    checkIntegerBounds "StaticMultiSelectElement" (Object fields)
    parsedActionId <- optionalField "action_id" fields
    parsedOptions <- optionalField "options" fields
    parsedOptionGroups <- optionalField "option_groups" fields
    parsedInitialOptions <- optionalField "initial_options" fields
    parsedConfirm <- optionalField "confirm" fields
    parsedMaxSelectedItems <- optionalField "max_selected_items" fields
    parsedFocusOnLoad <- optionalField "focus_on_load" fields
    parsedPlaceholder <- optionalField "placeholder" (coerceField "placeholder" "plain_text" fields)
    buildStaticMultiSelectElement (StaticMultiSelectElementFields parsedActionId parsedOptions parsedOptionGroups parsedInitialOptions parsedConfirm parsedMaxSelectedItems parsedFocusOnLoad parsedPlaceholder (remaining ["action_id", "options", "option_groups", "initial_options", "confirm", "max_selected_items", "focus_on_load", "placeholder"] fields))

instance FromJSON StaticMultiSelectElement where parseJSON = checkedParser

-- | A menu for selecting one option defined in the payload.
--
-- <https://docs.slack.dev/reference/block-kit/block-elements/select-menu-element>
-- Use options or option groups, not both.
newtype StaticSelectElement = CheckedStaticSelectElement StaticSelectElementFields deriving (Eq, Show)

-- | Editable construction input. Call 'buildStaticSelectElement' before encoding.
data StaticSelectElementFields = StaticSelectElementFields
  { -- | Sets the identifier Slack returns in interaction payloads when a user acts on this element. It must be unique among the elements of its block. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @action_id@.
    staticSelectElementActionId :: Maybe (Text),
    -- | Adds selectable options in display order. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @select.options@.
    staticSelectElementOptions :: Maybe ([SelectOption]),
    -- | Adds labelled groups of options in display order. Cannot be combined with ungrouped options. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @select.option_groups@.
    staticSelectElementOptionGroups :: Maybe ([SelectOptionGroup]),
    -- | Sets the option selected when the element loads. It must match an option in the element. Optional; Nothing omits the field. Factory default: @Nothing@.
    staticSelectElementInitialOption :: Maybe (SelectOption),
    -- | Sets a confirmation dialog shown before the action is sent. Optional; Nothing omits the field. Factory default: @Nothing@.
    staticSelectElementConfirm :: Maybe (ConfirmationDialogue),
    -- | Sets whether the element receives focus when the view opens. Only one element per view may do so. Optional; Nothing omits the field. Factory default: @Nothing@.
    staticSelectElementFocusOnLoad :: Maybe (Bool),
    -- | Sets the placeholder text shown before a value is chosen. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @select.placeholder@.
    staticSelectElementPlaceholder :: Maybe (PlainText),
    -- | Unmodeled extension fields. Reserved and modeled keys are rejected.
    staticSelectElementExtensions :: Map Text Value
  }
  deriving (Eq, Show)

-- | Start editable fields for StaticSelectElement; required arguments follow the signature.
-- Optional fields start absent except the explicit shared defaults; no block ID is invented.
-- Finish with 'buildStaticSelectElement' to validate before JSON encoding.
staticSelectElement :: StaticSelectElementFields
staticSelectElement = StaticSelectElementFields (Nothing) (Nothing) (Nothing) (Nothing) (Nothing) (Nothing) (Nothing) (Map.empty)

-- | Inspect immutable construction fields. Rebuild edits with 'buildStaticSelectElement' to revalidate.
inspectStaticSelectElement :: StaticSelectElement -> StaticSelectElementFields
inspectStaticSelectElement (CheckedStaticSelectElement fields) = fields

-- | Validate fields, extensions and receiving context. Return structured errors or a checked StaticSelectElement.
buildStaticSelectElement :: StaticSelectElementFields -> Result StaticSelectElement
buildStaticSelectElement fields = do
  checkExtensions ["action_id", "options", "option_groups", "initial_option", "confirm", "focus_on_load", "placeholder"] (staticSelectElementExtensions fields)
  validateFields "StaticSelectElement" (wireStaticSelectElement fields)
  pure (CheckedStaticSelectElement fields)

wireStaticSelectElement :: StaticSelectElementFields -> Value
wireStaticSelectElement fields =
  object $
    ["type" .= ("static_select" :: Text)] <> optional "action_id" (staticSelectElementActionId fields) <> optional "options" (staticSelectElementOptions fields) <> optional "option_groups" (staticSelectElementOptionGroups fields) <> optional "initial_option" (staticSelectElementInitialOption fields) <> optional "confirm" (staticSelectElementConfirm fields) <> optional "focus_on_load" (staticSelectElementFocusOnLoad fields) <> optional "placeholder" (staticSelectElementPlaceholder fields) <> extensionPairs (staticSelectElementExtensions fields)

instance ToJSON StaticSelectElement where toJSON (CheckedStaticSelectElement fields) = wireStaticSelectElement fields

instance FromSlackJSON StaticSelectElement where
  fromSlackJSON value = do
    fields <- wireObject "static_select" value
    parsedActionId <- optionalField "action_id" fields
    parsedOptions <- optionalField "options" fields
    parsedOptionGroups <- optionalField "option_groups" fields
    parsedInitialOption <- optionalField "initial_option" fields
    parsedConfirm <- optionalField "confirm" fields
    parsedFocusOnLoad <- optionalField "focus_on_load" fields
    parsedPlaceholder <- optionalField "placeholder" (coerceField "placeholder" "plain_text" fields)
    buildStaticSelectElement (StaticSelectElementFields parsedActionId parsedOptions parsedOptionGroups parsedInitialOption parsedConfirm parsedFocusOnLoad parsedPlaceholder (remaining ["action_id", "options", "option_groups", "initial_option", "confirm", "focus_on_load", "placeholder"] fields))

instance FromJSON StaticSelectElement where parseJSON = checkedParser

-- | A time-of-day picker.
--
-- <https://docs.slack.dev/reference/block-kit/block-elements/time-picker-element>
-- initial_time must be HH:mm in 24-hour time, from 00:00 through 23:59.
newtype TimePickerElement = CheckedTimePickerElement TimePickerElementFields deriving (Eq, Show)

-- | Editable construction input. Call 'buildTimePickerElement' before encoding.
data TimePickerElementFields = TimePickerElementFields
  { -- | Sets the identifier Slack returns in interaction payloads when a user acts on this element. It must be unique among the elements of its block. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @action_id@.
    timePickerElementActionId :: Maybe (Text),
    -- | Sets the initially selected time, formatted as HH:mm in 24-hour time. Optional; Nothing omits the field. Factory default: @Nothing@.
    timePickerElementInitialTime :: Maybe (Text),
    -- | Sets the IANA time zone used to display the time, such as Australia/Brisbane. Optional; Nothing omits the field. Factory default: @Nothing@.
    timePickerElementTimezone :: Maybe (Text),
    -- | Sets a confirmation dialog shown before the action is sent. Optional; Nothing omits the field. Factory default: @Nothing@.
    timePickerElementConfirm :: Maybe (ConfirmationDialogue),
    -- | Sets whether the element receives focus when the view opens. Only one element per view may do so. Optional; Nothing omits the field. Factory default: @Nothing@.
    timePickerElementFocusOnLoad :: Maybe (Bool),
    -- | Sets the placeholder text shown before a value is chosen. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @time_picker.placeholder@.
    timePickerElementPlaceholder :: Maybe (PlainText),
    -- | Unmodeled extension fields. Reserved and modeled keys are rejected.
    timePickerElementExtensions :: Map Text Value
  }
  deriving (Eq, Show)

-- | Start editable fields for TimePickerElement; required arguments follow the signature.
-- Optional fields start absent except the explicit shared defaults; no block ID is invented.
-- Finish with 'buildTimePickerElement' to validate before JSON encoding.
timePickerElement :: TimePickerElementFields
timePickerElement = TimePickerElementFields (Nothing) (Nothing) (Nothing) (Nothing) (Nothing) (Nothing) (Map.empty)

-- | Inspect immutable construction fields. Rebuild edits with 'buildTimePickerElement' to revalidate.
inspectTimePickerElement :: TimePickerElement -> TimePickerElementFields
inspectTimePickerElement (CheckedTimePickerElement fields) = fields

-- | Validate fields, extensions and receiving context. Return structured errors or a checked TimePickerElement.
buildTimePickerElement :: TimePickerElementFields -> Result TimePickerElement
buildTimePickerElement fields = do
  checkExtensions ["action_id", "initial_time", "timezone", "confirm", "focus_on_load", "placeholder"] (timePickerElementExtensions fields)
  validateFields "TimePickerElement" (wireTimePickerElement fields)
  pure (CheckedTimePickerElement fields)

wireTimePickerElement :: TimePickerElementFields -> Value
wireTimePickerElement fields =
  object $
    ["type" .= ("timepicker" :: Text)] <> optional "action_id" (timePickerElementActionId fields) <> optional "initial_time" (timePickerElementInitialTime fields) <> optional "timezone" (timePickerElementTimezone fields) <> optional "confirm" (timePickerElementConfirm fields) <> optional "focus_on_load" (timePickerElementFocusOnLoad fields) <> optional "placeholder" (timePickerElementPlaceholder fields) <> extensionPairs (timePickerElementExtensions fields)

instance ToJSON TimePickerElement where toJSON (CheckedTimePickerElement fields) = wireTimePickerElement fields

instance FromSlackJSON TimePickerElement where
  fromSlackJSON value = do
    fields <- wireObject "timepicker" value
    parsedActionId <- optionalField "action_id" fields
    parsedInitialTime <- optionalField "initial_time" fields
    parsedTimezone <- optionalField "timezone" fields
    parsedConfirm <- optionalField "confirm" fields
    parsedFocusOnLoad <- optionalField "focus_on_load" fields
    parsedPlaceholder <- optionalField "placeholder" (coerceField "placeholder" "plain_text" fields)
    buildTimePickerElement (TimePickerElementFields parsedActionId parsedInitialTime parsedTimezone parsedConfirm parsedFocusOnLoad parsedPlaceholder (remaining ["action_id", "initial_time", "timezone", "confirm", "focus_on_load", "placeholder"] fields))

instance FromJSON TimePickerElement where parseJSON = checkedParser

-- | A single-line input that accepts a URL.
--
-- <https://docs.slack.dev/reference/block-kit/block-elements/url-input-element>
newtype UrlInputElement = CheckedUrlInputElement UrlInputElementFields deriving (Eq, Show)

-- | Editable construction input. Call 'buildUrlInputElement' before encoding.
data UrlInputElementFields = UrlInputElementFields
  { -- | Sets the identifier Slack returns in interaction payloads when a user acts on this element. It must be unique among the elements of its block. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @action_id@.
    urlInputElementActionId :: Maybe (Text),
    -- | Sets the value present when the input loads. Optional; Nothing omits the field. Factory default: @Nothing@.
    urlInputElementInitialValue :: Maybe (Text),
    -- | Sets which user interactions send a block_actions payload. Optional; Nothing omits the field. Factory default: @Nothing@.
    urlInputElementDispatchActionConfig :: Maybe (DispatchActionConfiguration),
    -- | Sets whether the element receives focus when the view opens. Only one element per view may do so. Optional; Nothing omits the field. Factory default: @Nothing@.
    urlInputElementFocusOnLoad :: Maybe (Bool),
    -- | Sets the placeholder text shown before a value is chosen. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @url_input.placeholder@.
    urlInputElementPlaceholder :: Maybe (PlainText),
    -- | Unmodeled extension fields. Reserved and modeled keys are rejected.
    urlInputElementExtensions :: Map Text Value
  }
  deriving (Eq, Show)

-- | Start editable fields for UrlInputElement; required arguments follow the signature.
-- Optional fields start absent except the explicit shared defaults; no block ID is invented.
-- Finish with 'buildUrlInputElement' to validate before JSON encoding.
urlInputElement :: UrlInputElementFields
urlInputElement = UrlInputElementFields (Nothing) (Nothing) (Nothing) (Nothing) (Nothing) (Map.empty)

-- | Inspect immutable construction fields. Rebuild edits with 'buildUrlInputElement' to revalidate.
inspectUrlInputElement :: UrlInputElement -> UrlInputElementFields
inspectUrlInputElement (CheckedUrlInputElement fields) = fields

-- | Validate fields, extensions and receiving context. Return structured errors or a checked UrlInputElement.
buildUrlInputElement :: UrlInputElementFields -> Result UrlInputElement
buildUrlInputElement fields = do
  checkExtensions ["action_id", "initial_value", "dispatch_action_config", "focus_on_load", "placeholder"] (urlInputElementExtensions fields)
  validateFields "UrlInputElement" (wireUrlInputElement fields)
  pure (CheckedUrlInputElement fields)

wireUrlInputElement :: UrlInputElementFields -> Value
wireUrlInputElement fields =
  object $
    ["type" .= ("url_text_input" :: Text)] <> optional "action_id" (urlInputElementActionId fields) <> optional "initial_value" (urlInputElementInitialValue fields) <> optional "dispatch_action_config" (urlInputElementDispatchActionConfig fields) <> optional "focus_on_load" (urlInputElementFocusOnLoad fields) <> optional "placeholder" (urlInputElementPlaceholder fields) <> extensionPairs (urlInputElementExtensions fields)

instance ToJSON UrlInputElement where toJSON (CheckedUrlInputElement fields) = wireUrlInputElement fields

instance FromSlackJSON UrlInputElement where
  fromSlackJSON value = do
    fields <- wireObject "url_text_input" value
    parsedActionId <- optionalField "action_id" fields
    parsedInitialValue <- optionalField "initial_value" fields
    parsedDispatchActionConfig <- optionalField "dispatch_action_config" fields
    parsedFocusOnLoad <- optionalField "focus_on_load" fields
    parsedPlaceholder <- optionalField "placeholder" (coerceField "placeholder" "plain_text" fields)
    buildUrlInputElement (UrlInputElementFields parsedActionId parsedInitialValue parsedDispatchActionConfig parsedFocusOnLoad parsedPlaceholder (remaining ["action_id", "initial_value", "dispatch_action_config", "focus_on_load", "placeholder"] fields))

instance FromJSON UrlInputElement where parseJSON = checkedParser

-- | A menu for selecting multiple workspace users.
--
-- <https://docs.slack.dev/reference/block-kit/block-elements/multi-select-menu-element>
newtype UserMultiSelectElement = CheckedUserMultiSelectElement UserMultiSelectElementFields deriving (Eq, Show)

-- | Editable construction input. Call 'buildUserMultiSelectElement' before encoding.
data UserMultiSelectElementFields = UserMultiSelectElementFields
  { -- | Sets the identifier Slack returns in interaction payloads when a user acts on this element. It must be unique among the elements of its block. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @action_id@.
    userMultiSelectElementActionId :: Maybe (Text),
    -- | Adds user IDs that are selected when the menu loads. Optional; Nothing omits the field. Factory default: @Nothing@.
    userMultiSelectElementInitialUsers :: Maybe ([Text]),
    -- | Sets a confirmation dialog shown before the action is sent. Optional; Nothing omits the field. Factory default: @Nothing@.
    userMultiSelectElementConfirm :: Maybe (ConfirmationDialogue),
    -- | Sets the maximum number of items a user can select. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @multi_select.max_selected_items@.
    userMultiSelectElementMaxSelectedItems :: Maybe (Integer),
    -- | Sets whether the element receives focus when the view opens. Only one element per view may do so. Optional; Nothing omits the field. Factory default: @Nothing@.
    userMultiSelectElementFocusOnLoad :: Maybe (Bool),
    -- | Sets the placeholder text shown before a value is chosen. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @select.placeholder@.
    userMultiSelectElementPlaceholder :: Maybe (PlainText),
    -- | Unmodeled extension fields. Reserved and modeled keys are rejected.
    userMultiSelectElementExtensions :: Map Text Value
  }
  deriving (Eq, Show)

-- | Start editable fields for UserMultiSelectElement; required arguments follow the signature.
-- Optional fields start absent except the explicit shared defaults; no block ID is invented.
-- Finish with 'buildUserMultiSelectElement' to validate before JSON encoding.
userMultiSelectElement :: UserMultiSelectElementFields
userMultiSelectElement = UserMultiSelectElementFields (Nothing) (Nothing) (Nothing) (Nothing) (Nothing) (Nothing) (Map.empty)

-- | Inspect immutable construction fields. Rebuild edits with 'buildUserMultiSelectElement' to revalidate.
inspectUserMultiSelectElement :: UserMultiSelectElement -> UserMultiSelectElementFields
inspectUserMultiSelectElement (CheckedUserMultiSelectElement fields) = fields

-- | Validate fields, extensions and receiving context. Return structured errors or a checked UserMultiSelectElement.
buildUserMultiSelectElement :: UserMultiSelectElementFields -> Result UserMultiSelectElement
buildUserMultiSelectElement fields = do
  checkExtensions ["action_id", "initial_users", "confirm", "max_selected_items", "focus_on_load", "placeholder"] (userMultiSelectElementExtensions fields)
  validateFields "UserMultiSelectElement" (wireUserMultiSelectElement fields)
  pure (CheckedUserMultiSelectElement fields)

wireUserMultiSelectElement :: UserMultiSelectElementFields -> Value
wireUserMultiSelectElement fields =
  object $
    ["type" .= ("multi_users_select" :: Text)] <> optional "action_id" (userMultiSelectElementActionId fields) <> optional "initial_users" (userMultiSelectElementInitialUsers fields) <> optional "confirm" (userMultiSelectElementConfirm fields) <> optional "max_selected_items" (userMultiSelectElementMaxSelectedItems fields) <> optional "focus_on_load" (userMultiSelectElementFocusOnLoad fields) <> optional "placeholder" (userMultiSelectElementPlaceholder fields) <> extensionPairs (userMultiSelectElementExtensions fields)

instance ToJSON UserMultiSelectElement where toJSON (CheckedUserMultiSelectElement fields) = wireUserMultiSelectElement fields

instance FromSlackJSON UserMultiSelectElement where
  fromSlackJSON value = do
    fields <- wireObject "multi_users_select" value
    checkIntegerBounds "UserMultiSelectElement" (Object fields)
    parsedActionId <- optionalField "action_id" fields
    parsedInitialUsers <- optionalField "initial_users" fields
    parsedConfirm <- optionalField "confirm" fields
    parsedMaxSelectedItems <- optionalField "max_selected_items" fields
    parsedFocusOnLoad <- optionalField "focus_on_load" fields
    parsedPlaceholder <- optionalField "placeholder" (coerceField "placeholder" "plain_text" fields)
    buildUserMultiSelectElement (UserMultiSelectElementFields parsedActionId parsedInitialUsers parsedConfirm parsedMaxSelectedItems parsedFocusOnLoad parsedPlaceholder (remaining ["action_id", "initial_users", "confirm", "max_selected_items", "focus_on_load", "placeholder"] fields))

instance FromJSON UserMultiSelectElement where parseJSON = checkedParser

-- | A menu for selecting one workspace user.
--
-- <https://docs.slack.dev/reference/block-kit/block-elements/select-menu-element>
newtype UserSelectElement = CheckedUserSelectElement UserSelectElementFields deriving (Eq, Show)

-- | Editable construction input. Call 'buildUserSelectElement' before encoding.
data UserSelectElementFields = UserSelectElementFields
  { -- | Sets the identifier Slack returns in interaction payloads when a user acts on this element. It must be unique among the elements of its block. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @action_id@.
    userSelectElementActionId :: Maybe (Text),
    -- | Sets the user ID selected when the menu loads. Optional; Nothing omits the field. Factory default: @Nothing@.
    userSelectElementInitialUser :: Maybe (Text),
    -- | Sets a confirmation dialog shown before the action is sent. Optional; Nothing omits the field. Factory default: @Nothing@.
    userSelectElementConfirm :: Maybe (ConfirmationDialogue),
    -- | Sets whether the element receives focus when the view opens. Only one element per view may do so. Optional; Nothing omits the field. Factory default: @Nothing@.
    userSelectElementFocusOnLoad :: Maybe (Bool),
    -- | Sets the placeholder text shown before a value is chosen. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @select.placeholder@.
    userSelectElementPlaceholder :: Maybe (PlainText),
    -- | Unmodeled extension fields. Reserved and modeled keys are rejected.
    userSelectElementExtensions :: Map Text Value
  }
  deriving (Eq, Show)

-- | Start editable fields for UserSelectElement; required arguments follow the signature.
-- Optional fields start absent except the explicit shared defaults; no block ID is invented.
-- Finish with 'buildUserSelectElement' to validate before JSON encoding.
userSelectElement :: UserSelectElementFields
userSelectElement = UserSelectElementFields (Nothing) (Nothing) (Nothing) (Nothing) (Nothing) (Map.empty)

-- | Inspect immutable construction fields. Rebuild edits with 'buildUserSelectElement' to revalidate.
inspectUserSelectElement :: UserSelectElement -> UserSelectElementFields
inspectUserSelectElement (CheckedUserSelectElement fields) = fields

-- | Validate fields, extensions and receiving context. Return structured errors or a checked UserSelectElement.
buildUserSelectElement :: UserSelectElementFields -> Result UserSelectElement
buildUserSelectElement fields = do
  checkExtensions ["action_id", "initial_user", "confirm", "focus_on_load", "placeholder"] (userSelectElementExtensions fields)
  validateFields "UserSelectElement" (wireUserSelectElement fields)
  pure (CheckedUserSelectElement fields)

wireUserSelectElement :: UserSelectElementFields -> Value
wireUserSelectElement fields =
  object $
    ["type" .= ("users_select" :: Text)] <> optional "action_id" (userSelectElementActionId fields) <> optional "initial_user" (userSelectElementInitialUser fields) <> optional "confirm" (userSelectElementConfirm fields) <> optional "focus_on_load" (userSelectElementFocusOnLoad fields) <> optional "placeholder" (userSelectElementPlaceholder fields) <> extensionPairs (userSelectElementExtensions fields)

instance ToJSON UserSelectElement where toJSON (CheckedUserSelectElement fields) = wireUserSelectElement fields

instance FromSlackJSON UserSelectElement where
  fromSlackJSON value = do
    fields <- wireObject "users_select" value
    parsedActionId <- optionalField "action_id" fields
    parsedInitialUser <- optionalField "initial_user" fields
    parsedConfirm <- optionalField "confirm" fields
    parsedFocusOnLoad <- optionalField "focus_on_load" fields
    parsedPlaceholder <- optionalField "placeholder" (coerceField "placeholder" "plain_text" fields)
    buildUserSelectElement (UserSelectElementFields parsedActionId parsedInitialUser parsedConfirm parsedFocusOnLoad parsedPlaceholder (remaining ["action_id", "initial_user", "confirm", "focus_on_load", "placeholder"] fields))

instance FromJSON UserSelectElement where parseJSON = checkedParser

-- | A button that starts a workflow through a link trigger.
--
-- <https://docs.slack.dev/reference/block-kit/block-elements/workflow-button-element>
newtype WorkflowButtonElement = CheckedWorkflowButtonElement WorkflowButtonElementFields deriving (Eq, Show)

-- | Editable construction input. Call 'buildWorkflowButtonElement' before encoding.
data WorkflowButtonElementFields = WorkflowButtonElementFields
  { -- | Sets the button label. Required. Shared limit: @workflow_button.text@.
    workflowButtonElementText :: PlainText,
    -- | Sets the workflow started when the button is clicked. Required.
    workflowButtonElementWorkflow :: Workflow,
    -- | Sets the identifier Slack returns in interaction payloads when a user acts on this element. It must be unique among the elements of its block. Required. Shared limit: @action_id@.
    workflowButtonElementActionId :: Text,
    -- | Sets a confirmation dialog shown before the action is sent. Optional; Nothing omits the field. Factory default: @Nothing@.
    workflowButtonElementConfirm :: Maybe (ConfirmationDialogue),
    -- | Sets the button's emphasis. Omit it for the default neutral style. Optional; Nothing omits the field. Factory default: @Nothing@.
    workflowButtonElementStyle :: Maybe (ButtonStyle),
    -- | Sets the label read by screen readers in place of the visible text. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @workflow_button.accessibility_label@.
    workflowButtonElementAccessibilityLabel :: Maybe (Text),
    -- | Unmodeled extension fields. Reserved and modeled keys are rejected.
    workflowButtonElementExtensions :: Map Text Value
  }
  deriving (Eq, Show)

-- | Start editable fields for WorkflowButtonElement; required arguments follow the signature.
-- Optional fields start absent except the explicit shared defaults; no block ID is invented.
-- Finish with 'buildWorkflowButtonElement' to validate before JSON encoding.
workflowButtonElement :: PlainText -> Workflow -> Text -> WorkflowButtonElementFields
workflowButtonElement arg0 arg1 arg2 = WorkflowButtonElementFields (arg0) (arg1) (arg2) (Nothing) (Nothing) (Nothing) (Map.empty)

-- | Inspect immutable construction fields. Rebuild edits with 'buildWorkflowButtonElement' to revalidate.
inspectWorkflowButtonElement :: WorkflowButtonElement -> WorkflowButtonElementFields
inspectWorkflowButtonElement (CheckedWorkflowButtonElement fields) = fields

-- | Validate fields, extensions and receiving context. Return structured errors or a checked WorkflowButtonElement.
buildWorkflowButtonElement :: WorkflowButtonElementFields -> Result WorkflowButtonElement
buildWorkflowButtonElement fields = do
  checkExtensions ["text", "workflow", "action_id", "confirm", "style", "accessibility_label"] (workflowButtonElementExtensions fields)
  validateFields "WorkflowButtonElement" (wireWorkflowButtonElement fields)
  pure (CheckedWorkflowButtonElement fields)

wireWorkflowButtonElement :: WorkflowButtonElementFields -> Value
wireWorkflowButtonElement fields =
  object $
    ["type" .= ("workflow_button" :: Text)] <> ["text" .= (workflowButtonElementText fields)] <> ["workflow" .= (workflowButtonElementWorkflow fields)] <> ["action_id" .= (workflowButtonElementActionId fields)] <> optional "confirm" (workflowButtonElementConfirm fields) <> optional "style" (workflowButtonElementStyle fields) <> optional "accessibility_label" (workflowButtonElementAccessibilityLabel fields) <> extensionPairs (workflowButtonElementExtensions fields)

instance ToJSON WorkflowButtonElement where toJSON (CheckedWorkflowButtonElement fields) = wireWorkflowButtonElement fields

instance FromSlackJSON WorkflowButtonElement where
  fromSlackJSON value = do
    fields <- wireObject "workflow_button" value
    parsedText <- required "text" (coerceField "text" "plain_text" fields)
    parsedWorkflow <- required "workflow" fields
    parsedActionId <- required "action_id" fields
    parsedConfirm <- optionalField "confirm" fields
    parsedStyle <- optionalField "style" fields
    parsedAccessibilityLabel <- optionalField "accessibility_label" fields
    buildWorkflowButtonElement (WorkflowButtonElementFields parsedText parsedWorkflow parsedActionId parsedConfirm parsedStyle parsedAccessibilityLabel (remaining ["text", "workflow", "action_id", "confirm", "style", "accessibility_label"] fields))

instance FromJSON WorkflowButtonElement where parseJSON = checkedParser

-- | An area chart for a data visualization block.
--
-- <https://docs.slack.dev/reference/block-kit/blocks/data-visualization-block>
-- Every series needs exactly one data point for each axis category.
newtype AreaChart = CheckedAreaChart AreaChartFields deriving (Eq, Show)

-- | Editable construction input. Call 'buildAreaChart' before encoding.
data AreaChartFields = AreaChartFields
  { -- | Adds data series in display order. Series names must be unique. Required. Shared limit: @data_visualization.series@.
    areaChartSeries :: [DataSeries],
    -- | Sets the axis categories and labels. Every series needs exactly one point per category. Required.
    areaChartAxisConfig :: AxisConfig,
    -- | Unmodeled extension fields. Reserved and modeled keys are rejected.
    areaChartExtensions :: Map Text Value
  }
  deriving (Eq, Show)

-- | Start editable fields for AreaChart; required arguments follow the signature.
-- Optional fields start absent except the explicit shared defaults; no block ID is invented.
-- Finish with 'buildAreaChart' to validate before JSON encoding.
areaChart :: [DataSeries] -> AxisConfig -> AreaChartFields
areaChart arg0 arg1 = AreaChartFields (arg0) (arg1) (Map.empty)

-- | Inspect immutable construction fields. Rebuild edits with 'buildAreaChart' to revalidate.
inspectAreaChart :: AreaChart -> AreaChartFields
inspectAreaChart (CheckedAreaChart fields) = fields

-- | Validate fields, extensions and receiving context. Return structured errors or a checked AreaChart.
buildAreaChart :: AreaChartFields -> Result AreaChart
buildAreaChart fields = do
  checkExtensions ["series", "axis_config"] (areaChartExtensions fields)
  validateFields "AreaChart" (wireAreaChart fields)
  pure (CheckedAreaChart fields)

wireAreaChart :: AreaChartFields -> Value
wireAreaChart fields =
  object $
    ["type" .= ("area" :: Text)] <> ["series" .= (areaChartSeries fields)] <> ["axis_config" .= (areaChartAxisConfig fields)] <> extensionPairs (areaChartExtensions fields)

instance ToJSON AreaChart where toJSON (CheckedAreaChart fields) = wireAreaChart fields

instance FromSlackJSON AreaChart where
  fromSlackJSON value = do
    fields <- wireObject "area" value
    parsedSeries <- required "series" fields
    parsedAxisConfig <- required "axis_config" fields
    buildAreaChart (AreaChartFields parsedSeries parsedAxisConfig (remaining ["series", "axis_config"] fields))

instance FromJSON AreaChart where parseJSON = checkedParser

-- | The categories and labels shared by bar, area, and line chart axes.
--
-- <https://docs.slack.dev/reference/block-kit/blocks/data-visualization-block>
newtype AxisConfig = CheckedAxisConfig AxisConfigFields deriving (Eq, Show)

-- | Editable construction input. Call 'buildAxisConfig' before encoding.
data AxisConfigFields = AxisConfigFields
  { -- | Adds axis categories in display order. Labels must be unique. Required. Shared limit: @data_visualization.categories@.
    axisConfigCategories :: [Text],
    -- | Sets the horizontal axis label. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @data_visualization.axis_label@.
    axisConfigXLabel :: Maybe (Text),
    -- | Sets the vertical axis label. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @data_visualization.axis_label@.
    axisConfigYLabel :: Maybe (Text),
    -- | Unmodeled extension fields. Reserved and modeled keys are rejected.
    axisConfigExtensions :: Map Text Value
  }
  deriving (Eq, Show)

-- | Start editable fields for AxisConfig; required arguments follow the signature.
-- Optional fields start absent except the explicit shared defaults; no block ID is invented.
-- Finish with 'buildAxisConfig' to validate before JSON encoding.
axisConfig :: [Text] -> AxisConfigFields
axisConfig arg0 = AxisConfigFields (arg0) (Nothing) (Nothing) (Map.empty)

-- | Inspect immutable construction fields. Rebuild edits with 'buildAxisConfig' to revalidate.
inspectAxisConfig :: AxisConfig -> AxisConfigFields
inspectAxisConfig (CheckedAxisConfig fields) = fields

-- | Validate fields, extensions and receiving context. Return structured errors or a checked AxisConfig.
buildAxisConfig :: AxisConfigFields -> Result AxisConfig
buildAxisConfig fields = do
  checkExtensions ["categories", "x_label", "y_label"] (axisConfigExtensions fields)
  validateFields "AxisConfig" (wireAxisConfig fields)
  pure (CheckedAxisConfig fields)

wireAxisConfig :: AxisConfigFields -> Value
wireAxisConfig fields =
  object $
    [] <> ["categories" .= (axisConfigCategories fields)] <> optional "x_label" (axisConfigXLabel fields) <> optional "y_label" (axisConfigYLabel fields) <> extensionPairs (axisConfigExtensions fields)

instance ToJSON AxisConfig where toJSON (CheckedAxisConfig fields) = wireAxisConfig fields

instance FromSlackJSON AxisConfig where
  fromSlackJSON value = do
    fields <- wireObject "" value
    parsedCategories <- required "categories" fields
    parsedXLabel <- optionalField "x_label" fields
    parsedYLabel <- optionalField "y_label" fields
    buildAxisConfig (AxisConfigFields parsedCategories parsedXLabel parsedYLabel (remaining ["categories", "x_label", "y_label"] fields))

instance FromJSON AxisConfig where parseJSON = checkedParser

-- | A bar chart for a data visualization block.
--
-- <https://docs.slack.dev/reference/block-kit/blocks/data-visualization-block>
-- Every series needs exactly one data point for each axis category.
newtype BarChart = CheckedBarChart BarChartFields deriving (Eq, Show)

-- | Editable construction input. Call 'buildBarChart' before encoding.
data BarChartFields = BarChartFields
  { -- | Adds data series in display order. Series names must be unique. Required. Shared limit: @data_visualization.series@.
    barChartSeries :: [DataSeries],
    -- | Sets the axis categories and labels. Every series needs exactly one point per category. Required.
    barChartAxisConfig :: AxisConfig,
    -- | Unmodeled extension fields. Reserved and modeled keys are rejected.
    barChartExtensions :: Map Text Value
  }
  deriving (Eq, Show)

-- | Start editable fields for BarChart; required arguments follow the signature.
-- Optional fields start absent except the explicit shared defaults; no block ID is invented.
-- Finish with 'buildBarChart' to validate before JSON encoding.
barChart :: [DataSeries] -> AxisConfig -> BarChartFields
barChart arg0 arg1 = BarChartFields (arg0) (arg1) (Map.empty)

-- | Inspect immutable construction fields. Rebuild edits with 'buildBarChart' to revalidate.
inspectBarChart :: BarChart -> BarChartFields
inspectBarChart (CheckedBarChart fields) = fields

-- | Validate fields, extensions and receiving context. Return structured errors or a checked BarChart.
buildBarChart :: BarChartFields -> Result BarChart
buildBarChart fields = do
  checkExtensions ["series", "axis_config"] (barChartExtensions fields)
  validateFields "BarChart" (wireBarChart fields)
  pure (CheckedBarChart fields)

wireBarChart :: BarChartFields -> Value
wireBarChart fields =
  object $
    ["type" .= ("bar" :: Text)] <> ["series" .= (barChartSeries fields)] <> ["axis_config" .= (barChartAxisConfig fields)] <> extensionPairs (barChartExtensions fields)

instance ToJSON BarChart where toJSON (CheckedBarChart fields) = wireBarChart fields

instance FromSlackJSON BarChart where
  fromSlackJSON value = do
    fields <- wireObject "bar" value
    parsedSeries <- required "series" fields
    parsedAxisConfig <- required "axis_config" fields
    buildBarChart (BarChartFields parsedSeries parsedAxisConfig (remaining ["series", "axis_config"] fields))

instance FromJSON BarChart where parseJSON = checkedParser

-- | One labelled segment of a pie chart.
--
-- <https://docs.slack.dev/reference/block-kit/blocks/data-visualization-block>
newtype ChartSegment = CheckedChartSegment ChartSegmentFields deriving (Eq, Show)

-- | Editable construction input. Call 'buildChartSegment' before encoding.
data ChartSegmentFields = ChartSegmentFields
  { -- | Sets the segment label. Required. Shared limit: @data_visualization.segment.label@.
    chartSegmentLabel :: Text,
    -- | Sets the segment's size. Must be greater than zero. Required.
    chartSegmentValue :: Scientific,
    -- | Unmodeled extension fields. Reserved and modeled keys are rejected.
    chartSegmentExtensions :: Map Text Value
  }
  deriving (Eq, Show)

-- | Start editable fields for ChartSegment; required arguments follow the signature.
-- Optional fields start absent except the explicit shared defaults; no block ID is invented.
-- Finish with 'buildChartSegment' to validate before JSON encoding.
chartSegment :: Text -> Scientific -> ChartSegmentFields
chartSegment arg0 arg1 = ChartSegmentFields (arg0) (arg1) (Map.empty)

-- | Inspect immutable construction fields. Rebuild edits with 'buildChartSegment' to revalidate.
inspectChartSegment :: ChartSegment -> ChartSegmentFields
inspectChartSegment (CheckedChartSegment fields) = fields

-- | Validate fields, extensions and receiving context. Return structured errors or a checked ChartSegment.
buildChartSegment :: ChartSegmentFields -> Result ChartSegment
buildChartSegment fields = do
  checkExtensions ["label", "value"] (chartSegmentExtensions fields)
  validateFields "ChartSegment" (wireChartSegment fields)
  pure (CheckedChartSegment fields)

wireChartSegment :: ChartSegmentFields -> Value
wireChartSegment fields =
  object $
    [] <> ["label" .= (chartSegmentLabel fields)] <> ["value" .= (chartSegmentValue fields)] <> extensionPairs (chartSegmentExtensions fields)

instance ToJSON ChartSegment where toJSON (CheckedChartSegment fields) = wireChartSegment fields

instance FromSlackJSON ChartSegment where
  fromSlackJSON value = do
    fields <- wireObject "" value
    parsedLabel <- required "label" fields
    parsedValue <- required "value" fields
    buildChartSegment (ChartSegmentFields parsedLabel parsedValue (remaining ["label", "value"] fields))

instance FromJSON ChartSegment where parseJSON = checkedParser

-- | Alignment and wrapping settings for one table column.
--
-- <https://docs.slack.dev/reference/block-kit/blocks/table-block>
newtype ColumnSettings = CheckedColumnSettings ColumnSettingsFields deriving (Eq, Show)

-- | Editable construction input. Call 'buildColumnSettings' before encoding.
data ColumnSettingsFields = ColumnSettingsFields
  { -- | Sets how cell content in the column is aligned. Optional; Nothing omits the field. Factory default: @Nothing@.
    columnSettingsAlign :: Maybe (ColumnAlign),
    -- | Sets whether long cell content wraps instead of being truncated. Optional; Nothing omits the field. Factory default: @Nothing@.
    columnSettingsIsWrapped :: Maybe (Bool),
    -- | Unmodeled extension fields. Reserved and modeled keys are rejected.
    columnSettingsExtensions :: Map Text Value
  }
  deriving (Eq, Show)

-- | Start editable fields for ColumnSettings; required arguments follow the signature.
-- Optional fields start absent except the explicit shared defaults; no block ID is invented.
-- Finish with 'buildColumnSettings' to validate before JSON encoding.
columnSettings :: ColumnSettingsFields
columnSettings = ColumnSettingsFields (Nothing) (Nothing) (Map.empty)

-- | Inspect immutable construction fields. Rebuild edits with 'buildColumnSettings' to revalidate.
inspectColumnSettings :: ColumnSettings -> ColumnSettingsFields
inspectColumnSettings (CheckedColumnSettings fields) = fields

-- | Validate fields, extensions and receiving context. Return structured errors or a checked ColumnSettings.
buildColumnSettings :: ColumnSettingsFields -> Result ColumnSettings
buildColumnSettings fields = do
  checkExtensions ["align", "is_wrapped"] (columnSettingsExtensions fields)
  validateFields "ColumnSettings" (wireColumnSettings fields)
  pure (CheckedColumnSettings fields)

wireColumnSettings :: ColumnSettingsFields -> Value
wireColumnSettings fields =
  object $
    [] <> optional "align" (columnSettingsAlign fields) <> optional "is_wrapped" (columnSettingsIsWrapped fields) <> extensionPairs (columnSettingsExtensions fields)

instance ToJSON ColumnSettings where toJSON (CheckedColumnSettings fields) = wireColumnSettings fields

instance FromSlackJSON ColumnSettings where
  fromSlackJSON value = do
    fields <- wireObject "" value
    parsedAlign <- optionalField "align" fields
    parsedIsWrapped <- optionalField "is_wrapped" fields
    buildColumnSettings (ColumnSettingsFields parsedAlign parsedIsWrapped (remaining ["align", "is_wrapped"] fields))

instance FromJSON ColumnSettings where parseJSON = checkedParser

-- | A dialog that asks users to confirm an action before it is sent.
--
-- <https://docs.slack.dev/reference/block-kit/composition-objects/confirmation-dialog-object>
newtype ConfirmationDialogue = CheckedConfirmationDialogue ConfirmationDialogueFields deriving (Eq, Show)

-- | Editable construction input. Call 'buildConfirmationDialogue' before encoding.
data ConfirmationDialogueFields = ConfirmationDialogueFields
  { -- | Sets the dialog title. Required. Shared limit: @confirmation.title@.
    confirmationDialogueTitle :: PlainText,
    -- | Sets the explanatory text in the dialog body. Required. Shared limit: @confirmation.text@.
    confirmationDialogueText :: TextObject,
    -- | Sets the label of the button that confirms the action. Required. Shared limit: @confirmation.confirm@.
    confirmationDialogueConfirm :: PlainText,
    -- | Sets the label of the button that cancels the action. Required. Shared limit: @confirmation.deny@.
    confirmationDialogueDeny :: PlainText,
    -- | Sets the emphasis of the confirm button. Optional; Nothing omits the field. Factory default: @Nothing@.
    confirmationDialogueStyle :: Maybe (ButtonStyle),
    -- | Unmodeled extension fields. Reserved and modeled keys are rejected.
    confirmationDialogueExtensions :: Map Text Value
  }
  deriving (Eq, Show)

-- | Start editable fields for ConfirmationDialogue; required arguments follow the signature.
-- Optional fields start absent except the explicit shared defaults; no block ID is invented.
-- Finish with 'buildConfirmationDialogue' to validate before JSON encoding.
confirmationDialogue :: PlainText -> TextObject -> PlainText -> PlainText -> ConfirmationDialogueFields
confirmationDialogue arg0 arg1 arg2 arg3 = ConfirmationDialogueFields (arg0) (arg1) (arg2) (arg3) (Nothing) (Map.empty)

-- | Inspect immutable construction fields. Rebuild edits with 'buildConfirmationDialogue' to revalidate.
inspectConfirmationDialogue :: ConfirmationDialogue -> ConfirmationDialogueFields
inspectConfirmationDialogue (CheckedConfirmationDialogue fields) = fields

-- | Validate fields, extensions and receiving context. Return structured errors or a checked ConfirmationDialogue.
buildConfirmationDialogue :: ConfirmationDialogueFields -> Result ConfirmationDialogue
buildConfirmationDialogue fields = do
  checkExtensions ["title", "text", "confirm", "deny", "style"] (confirmationDialogueExtensions fields)
  validateFields "Confirmation" (wireConfirmationDialogue fields)
  pure (CheckedConfirmationDialogue fields)

wireConfirmationDialogue :: ConfirmationDialogueFields -> Value
wireConfirmationDialogue fields =
  object $
    [] <> ["title" .= (confirmationDialogueTitle fields)] <> ["text" .= (confirmationDialogueText fields)] <> ["confirm" .= (confirmationDialogueConfirm fields)] <> ["deny" .= (confirmationDialogueDeny fields)] <> optional "style" (confirmationDialogueStyle fields) <> extensionPairs (confirmationDialogueExtensions fields)

instance ToJSON ConfirmationDialogue where toJSON (CheckedConfirmationDialogue fields) = wireConfirmationDialogue fields

instance FromSlackJSON ConfirmationDialogue where
  fromSlackJSON value = do
    fields <- wireObject "" value
    parsedTitle <- required "title" (coerceField "title" "plain_text" fields)
    parsedText <- required "text" (coerceField "text" "mrkdwn" fields)
    parsedConfirm <- required "confirm" (coerceField "confirm" "plain_text" fields)
    parsedDeny <- required "deny" (coerceField "deny" "plain_text" fields)
    parsedStyle <- optionalField "style" fields
    buildConfirmationDialogue (ConfirmationDialogueFields parsedTitle parsedText parsedConfirm parsedDeny parsedStyle (remaining ["title", "text", "confirm", "deny", "style"] fields))

instance FromJSON ConfirmationDialogue where parseJSON = checkedParser

-- | Limits which conversations a conversation menu offers.
--
-- <https://docs.slack.dev/reference/block-kit/composition-objects/conversation-filter-object>
-- Set at least one filter.
-- Include only im, mpim, private, and public.
newtype ConversationFilter = CheckedConversationFilter ConversationFilterFields deriving (Eq, Show)

-- | Editable construction input. Call 'buildConversationFilter' before encoding.
data ConversationFilterFields = ConversationFilterFields
  { -- | Adds conversation types to offer: im, mpim, private, or public. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @conversation_filter.include@.
    conversationFilterInclude :: Maybe ([Text]),
    -- | Sets whether externally shared channels are excluded. Optional; Nothing omits the field. Factory default: @Nothing@.
    conversationFilterExcludeExternalSharedChannels :: Maybe (Bool),
    -- | Sets whether bot users are excluded. Optional; Nothing omits the field. Factory default: @Nothing@.
    conversationFilterExcludeBotUsers :: Maybe (Bool),
    -- | Unmodeled extension fields. Reserved and modeled keys are rejected.
    conversationFilterExtensions :: Map Text Value
  }
  deriving (Eq, Show)

-- | Start editable fields for ConversationFilter; required arguments follow the signature.
-- Optional fields start absent except the explicit shared defaults; no block ID is invented.
-- Finish with 'buildConversationFilter' to validate before JSON encoding.
conversationFilter :: ConversationFilterFields
conversationFilter = ConversationFilterFields (Nothing) (Nothing) (Nothing) (Map.empty)

-- | Inspect immutable construction fields. Rebuild edits with 'buildConversationFilter' to revalidate.
inspectConversationFilter :: ConversationFilter -> ConversationFilterFields
inspectConversationFilter (CheckedConversationFilter fields) = fields

-- | Validate fields, extensions and receiving context. Return structured errors or a checked ConversationFilter.
buildConversationFilter :: ConversationFilterFields -> Result ConversationFilter
buildConversationFilter fields = do
  checkExtensions ["include", "exclude_external_shared_channels", "exclude_bot_users"] (conversationFilterExtensions fields)
  validateFields "ConversationFilter" (wireConversationFilter fields)
  pure (CheckedConversationFilter fields)

wireConversationFilter :: ConversationFilterFields -> Value
wireConversationFilter fields =
  object $
    [] <> optional "include" (conversationFilterInclude fields) <> optional "exclude_external_shared_channels" (conversationFilterExcludeExternalSharedChannels fields) <> optional "exclude_bot_users" (conversationFilterExcludeBotUsers fields) <> extensionPairs (conversationFilterExtensions fields)

instance ToJSON ConversationFilter where toJSON (CheckedConversationFilter fields) = wireConversationFilter fields

instance FromSlackJSON ConversationFilter where
  fromSlackJSON value = do
    fields <- wireObject "" value
    parsedInclude <- optionalField "include" fields
    parsedExcludeExternalSharedChannels <- optionalField "exclude_external_shared_channels" fields
    parsedExcludeBotUsers <- optionalField "exclude_bot_users" fields
    buildConversationFilter (ConversationFilterFields parsedInclude parsedExcludeExternalSharedChannels parsedExcludeBotUsers (remaining ["include", "exclude_external_shared_channels", "exclude_bot_users"] fields))

instance FromJSON ConversationFilter where parseJSON = checkedParser

-- | One value of a chart series, keyed by axis category.
--
-- <https://docs.slack.dev/reference/block-kit/blocks/data-visualization-block>
newtype DataPoint = CheckedDataPoint DataPointFields deriving (Eq, Show)

-- | Editable construction input. Call 'buildDataPoint' before encoding.
data DataPointFields = DataPointFields
  { -- | Sets the axis category this point belongs to. Required. Shared limit: @data_visualization.point_label@.
    dataPointLabel :: Text,
    -- | Sets the point's value. Required.
    dataPointValue :: Scientific,
    -- | Unmodeled extension fields. Reserved and modeled keys are rejected.
    dataPointExtensions :: Map Text Value
  }
  deriving (Eq, Show)

-- | Start editable fields for DataPoint; required arguments follow the signature.
-- Optional fields start absent except the explicit shared defaults; no block ID is invented.
-- Finish with 'buildDataPoint' to validate before JSON encoding.
dataPoint :: Text -> Scientific -> DataPointFields
dataPoint arg0 arg1 = DataPointFields (arg0) (arg1) (Map.empty)

-- | Inspect immutable construction fields. Rebuild edits with 'buildDataPoint' to revalidate.
inspectDataPoint :: DataPoint -> DataPointFields
inspectDataPoint (CheckedDataPoint fields) = fields

-- | Validate fields, extensions and receiving context. Return structured errors or a checked DataPoint.
buildDataPoint :: DataPointFields -> Result DataPoint
buildDataPoint fields = do
  checkExtensions ["label", "value"] (dataPointExtensions fields)
  validateFields "DataPoint" (wireDataPoint fields)
  pure (CheckedDataPoint fields)

wireDataPoint :: DataPointFields -> Value
wireDataPoint fields =
  object $
    [] <> ["label" .= (dataPointLabel fields)] <> ["value" .= (dataPointValue fields)] <> extensionPairs (dataPointExtensions fields)

instance ToJSON DataPoint where toJSON (CheckedDataPoint fields) = wireDataPoint fields

instance FromSlackJSON DataPoint where
  fromSlackJSON value = do
    fields <- wireObject "" value
    parsedLabel <- required "label" fields
    parsedValue <- required "value" fields
    buildDataPoint (DataPointFields parsedLabel parsedValue (remaining ["label", "value"] fields))

instance FromJSON DataPoint where parseJSON = checkedParser

-- | A named series of chart data points.
--
-- <https://docs.slack.dev/reference/block-kit/blocks/data-visualization-block>
newtype DataSeries = CheckedDataSeries DataSeriesFields deriving (Eq, Show)

-- | Editable construction input. Call 'buildDataSeries' before encoding.
data DataSeriesFields = DataSeriesFields
  { -- | Sets the series name shown in the legend. Required. Shared limit: @data_visualization.series_name@.
    dataSeriesName :: Text,
    -- | Adds data points in axis-category order. Required. Shared limit: @data_visualization.data@.
    dataSeriesData :: [DataPoint],
    -- | Unmodeled extension fields. Reserved and modeled keys are rejected.
    dataSeriesExtensions :: Map Text Value
  }
  deriving (Eq, Show)

-- | Start editable fields for DataSeries; required arguments follow the signature.
-- Optional fields start absent except the explicit shared defaults; no block ID is invented.
-- Finish with 'buildDataSeries' to validate before JSON encoding.
dataSeries :: Text -> [DataPoint] -> DataSeriesFields
dataSeries arg0 arg1 = DataSeriesFields (arg0) (arg1) (Map.empty)

-- | Inspect immutable construction fields. Rebuild edits with 'buildDataSeries' to revalidate.
inspectDataSeries :: DataSeries -> DataSeriesFields
inspectDataSeries (CheckedDataSeries fields) = fields

-- | Validate fields, extensions and receiving context. Return structured errors or a checked DataSeries.
buildDataSeries :: DataSeriesFields -> Result DataSeries
buildDataSeries fields = do
  checkExtensions ["name", "data"] (dataSeriesExtensions fields)
  validateFields "DataSeries" (wireDataSeries fields)
  pure (CheckedDataSeries fields)

wireDataSeries :: DataSeriesFields -> Value
wireDataSeries fields =
  object $
    [] <> ["name" .= (dataSeriesName fields)] <> ["data" .= (dataSeriesData fields)] <> extensionPairs (dataSeriesExtensions fields)

instance ToJSON DataSeries where toJSON (CheckedDataSeries fields) = wireDataSeries fields

instance FromSlackJSON DataSeries where
  fromSlackJSON value = do
    fields <- wireObject "" value
    parsedName <- required "name" fields
    parsedData <- required "data" fields
    buildDataSeries (DataSeriesFields parsedName parsedData (remaining ["name", "data"] fields))

instance FromJSON DataSeries where parseJSON = checkedParser

-- | Chooses which interactions with an input send a block_actions payload.
--
-- <https://docs.slack.dev/reference/block-kit/composition-objects/dispatch-action-configuration-object>
newtype DispatchActionConfiguration = CheckedDispatchActionConfiguration DispatchActionConfigurationFields deriving (Eq, Show)

-- | Editable construction input. Call 'buildDispatchActionConfiguration' before encoding.
data DispatchActionConfigurationFields = DispatchActionConfigurationFields
  { -- | Adds the interactions that send a payload: on_enter_pressed or on_character_entered. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @dispatch_action_configuration.trigger_actions_on@.
    dispatchActionConfigurationTriggerActionsOn :: Maybe ([Text]),
    -- | Unmodeled extension fields. Reserved and modeled keys are rejected.
    dispatchActionConfigurationExtensions :: Map Text Value
  }
  deriving (Eq, Show)

-- | Start editable fields for DispatchActionConfiguration; required arguments follow the signature.
-- Optional fields start absent except the explicit shared defaults; no block ID is invented.
-- Finish with 'buildDispatchActionConfiguration' to validate before JSON encoding.
dispatchActionConfiguration :: DispatchActionConfigurationFields
dispatchActionConfiguration = DispatchActionConfigurationFields (Nothing) (Map.empty)

-- | Inspect immutable construction fields. Rebuild edits with 'buildDispatchActionConfiguration' to revalidate.
inspectDispatchActionConfiguration :: DispatchActionConfiguration -> DispatchActionConfigurationFields
inspectDispatchActionConfiguration (CheckedDispatchActionConfiguration fields) = fields

-- | Validate fields, extensions and receiving context. Return structured errors or a checked DispatchActionConfiguration.
buildDispatchActionConfiguration :: DispatchActionConfigurationFields -> Result DispatchActionConfiguration
buildDispatchActionConfiguration fields = do
  checkExtensions ["trigger_actions_on"] (dispatchActionConfigurationExtensions fields)
  validateFields "DispatchActionConfiguration" (wireDispatchActionConfiguration fields)
  pure (CheckedDispatchActionConfiguration fields)

wireDispatchActionConfiguration :: DispatchActionConfigurationFields -> Value
wireDispatchActionConfiguration fields =
  object $
    [] <> optional "trigger_actions_on" (dispatchActionConfigurationTriggerActionsOn fields) <> extensionPairs (dispatchActionConfigurationExtensions fields)

instance ToJSON DispatchActionConfiguration where toJSON (CheckedDispatchActionConfiguration fields) = wireDispatchActionConfiguration fields

instance FromSlackJSON DispatchActionConfiguration where
  fromSlackJSON value = do
    fields <- wireObject "" value
    parsedTriggerActionsOn <- optionalField "trigger_actions_on" fields
    buildDispatchActionConfiguration (DispatchActionConfigurationFields parsedTriggerActionsOn (remaining ["trigger_actions_on"] fields))

instance FromJSON DispatchActionConfiguration where parseJSON = checkedParser

-- | One button of a feedback buttons element.
--
-- <https://docs.slack.dev/reference/block-kit/block-elements/feedback-buttons-element>
newtype FeedbackButton = CheckedFeedbackButton FeedbackButtonFields deriving (Eq, Show)

-- | Editable construction input. Call 'buildFeedbackButton' before encoding.
data FeedbackButtonFields = FeedbackButtonFields
  { -- | Sets the button label. Required. Shared limit: @feedback_button.text@.
    feedbackButtonText :: PlainText,
    -- | Sets the application-defined value sent in interaction payloads. Required. Shared limit: @feedback_button.value@.
    feedbackButtonValue :: Text,
    -- | Sets the label read by screen readers in place of the visible text. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @feedback_button.accessibility_label@.
    feedbackButtonAccessibilityLabel :: Maybe (Text),
    -- | Unmodeled extension fields. Reserved and modeled keys are rejected.
    feedbackButtonExtensions :: Map Text Value
  }
  deriving (Eq, Show)

-- | Start editable fields for FeedbackButton; required arguments follow the signature.
-- Optional fields start absent except the explicit shared defaults; no block ID is invented.
-- Finish with 'buildFeedbackButton' to validate before JSON encoding.
feedbackButton :: PlainText -> Text -> FeedbackButtonFields
feedbackButton arg0 arg1 = FeedbackButtonFields (arg0) (arg1) (Nothing) (Map.empty)

-- | Inspect immutable construction fields. Rebuild edits with 'buildFeedbackButton' to revalidate.
inspectFeedbackButton :: FeedbackButton -> FeedbackButtonFields
inspectFeedbackButton (CheckedFeedbackButton fields) = fields

-- | Validate fields, extensions and receiving context. Return structured errors or a checked FeedbackButton.
buildFeedbackButton :: FeedbackButtonFields -> Result FeedbackButton
buildFeedbackButton fields = do
  checkExtensions ["text", "value", "accessibility_label"] (feedbackButtonExtensions fields)
  validateFields "FeedbackButton" (wireFeedbackButton fields)
  pure (CheckedFeedbackButton fields)

wireFeedbackButton :: FeedbackButtonFields -> Value
wireFeedbackButton fields =
  object $
    [] <> ["text" .= (feedbackButtonText fields)] <> ["value" .= (feedbackButtonValue fields)] <> optional "accessibility_label" (feedbackButtonAccessibilityLabel fields) <> extensionPairs (feedbackButtonExtensions fields)

instance ToJSON FeedbackButton where toJSON (CheckedFeedbackButton fields) = wireFeedbackButton fields

instance FromSlackJSON FeedbackButton where
  fromSlackJSON value = do
    fields <- wireObject "" value
    parsedText <- required "text" (coerceField "text" "plain_text" fields)
    parsedValue <- required "value" fields
    parsedAccessibilityLabel <- optionalField "accessibility_label" fields
    buildFeedbackButton (FeedbackButtonFields parsedText parsedValue parsedAccessibilityLabel (remaining ["text", "value", "accessibility_label"] fields))

instance FromJSON FeedbackButton where parseJSON = checkedParser

-- | A named value passed to a workflow trigger.
--
-- <https://docs.slack.dev/reference/block-kit/composition-objects/trigger-object>
newtype InputParameter = CheckedInputParameter InputParameterFields deriving (Eq, Show)

-- | Editable construction input. Call 'buildInputParameter' before encoding.
data InputParameterFields = InputParameterFields
  { -- | Sets the workflow input parameter name. Required.
    inputParameterName :: Text,
    -- | Sets the value passed to the workflow input. Required.
    inputParameterValue :: Text,
    -- | Unmodeled extension fields. Reserved and modeled keys are rejected.
    inputParameterExtensions :: Map Text Value
  }
  deriving (Eq, Show)

-- | Start editable fields for InputParameter; required arguments follow the signature.
-- Optional fields start absent except the explicit shared defaults; no block ID is invented.
-- Finish with 'buildInputParameter' to validate before JSON encoding.
inputParameter :: Text -> Text -> InputParameterFields
inputParameter arg0 arg1 = InputParameterFields (arg0) (arg1) (Map.empty)

-- | Inspect immutable construction fields. Rebuild edits with 'buildInputParameter' to revalidate.
inspectInputParameter :: InputParameter -> InputParameterFields
inspectInputParameter (CheckedInputParameter fields) = fields

-- | Validate fields, extensions and receiving context. Return structured errors or a checked InputParameter.
buildInputParameter :: InputParameterFields -> Result InputParameter
buildInputParameter fields = do
  checkExtensions ["name", "value"] (inputParameterExtensions fields)
  validateFields "InputParameter" (wireInputParameter fields)
  pure (CheckedInputParameter fields)

wireInputParameter :: InputParameterFields -> Value
wireInputParameter fields =
  object $
    [] <> ["name" .= (inputParameterName fields)] <> ["value" .= (inputParameterValue fields)] <> extensionPairs (inputParameterExtensions fields)

instance ToJSON InputParameter where toJSON (CheckedInputParameter fields) = wireInputParameter fields

instance FromSlackJSON InputParameter where
  fromSlackJSON value = do
    fields <- wireObject "" value
    parsedName <- required "name" fields
    parsedValue <- required "value" fields
    buildInputParameter (InputParameterFields parsedName parsedValue (remaining ["name", "value"] fields))

instance FromJSON InputParameter where parseJSON = checkedParser

-- | A line chart for a data visualization block.
--
-- <https://docs.slack.dev/reference/block-kit/blocks/data-visualization-block>
-- Every series needs exactly one data point for each axis category.
newtype LineChart = CheckedLineChart LineChartFields deriving (Eq, Show)

-- | Editable construction input. Call 'buildLineChart' before encoding.
data LineChartFields = LineChartFields
  { -- | Adds data series in display order. Series names must be unique. Required. Shared limit: @data_visualization.series@.
    lineChartSeries :: [DataSeries],
    -- | Sets the axis categories and labels. Every series needs exactly one point per category. Required.
    lineChartAxisConfig :: AxisConfig,
    -- | Unmodeled extension fields. Reserved and modeled keys are rejected.
    lineChartExtensions :: Map Text Value
  }
  deriving (Eq, Show)

-- | Start editable fields for LineChart; required arguments follow the signature.
-- Optional fields start absent except the explicit shared defaults; no block ID is invented.
-- Finish with 'buildLineChart' to validate before JSON encoding.
lineChart :: [DataSeries] -> AxisConfig -> LineChartFields
lineChart arg0 arg1 = LineChartFields (arg0) (arg1) (Map.empty)

-- | Inspect immutable construction fields. Rebuild edits with 'buildLineChart' to revalidate.
inspectLineChart :: LineChart -> LineChartFields
inspectLineChart (CheckedLineChart fields) = fields

-- | Validate fields, extensions and receiving context. Return structured errors or a checked LineChart.
buildLineChart :: LineChartFields -> Result LineChart
buildLineChart fields = do
  checkExtensions ["series", "axis_config"] (lineChartExtensions fields)
  validateFields "LineChart" (wireLineChart fields)
  pure (CheckedLineChart fields)

wireLineChart :: LineChartFields -> Value
wireLineChart fields =
  object $
    ["type" .= ("line" :: Text)] <> ["series" .= (lineChartSeries fields)] <> ["axis_config" .= (lineChartAxisConfig fields)] <> extensionPairs (lineChartExtensions fields)

instance ToJSON LineChart where toJSON (CheckedLineChart fields) = wireLineChart fields

instance FromSlackJSON LineChart where
  fromSlackJSON value = do
    fields <- wireObject "line" value
    parsedSeries <- required "series" fields
    parsedAxisConfig <- required "axis_config" fields
    buildLineChart (LineChartFields parsedSeries parsedAxisConfig (remaining ["series", "axis_config"] fields))

instance FromJSON LineChart where parseJSON = checkedParser

-- | A mrkdwn text composition object.
--
-- <https://docs.slack.dev/reference/block-kit/composition-objects/text-object>
newtype MarkdownText = CheckedMarkdownText MarkdownTextFields deriving (Eq, Show)

-- | Editable construction input. Call 'buildMarkdownText' before encoding.
data MarkdownTextFields = MarkdownTextFields
  { -- | Sets the mrkdwn-formatted text content. Required.
    markdownTextText :: Text,
    -- | Sets whether Slack leaves URLs, mentions, and channel names unlinked. Optional; Nothing omits the field. Factory default: @Nothing@.
    markdownTextVerbatim :: Maybe (Bool),
    -- | Unmodeled extension fields. Reserved and modeled keys are rejected.
    markdownTextExtensions :: Map Text Value
  }
  deriving (Eq, Show)

-- | Start editable fields for MarkdownText; required arguments follow the signature.
-- Optional fields start absent except the explicit shared defaults; no block ID is invented.
-- Finish with 'buildMarkdownText' to validate before JSON encoding.
markdownText :: Text -> MarkdownTextFields
markdownText arg0 = MarkdownTextFields (arg0) (Nothing) (Map.empty)

-- | Inspect immutable construction fields. Rebuild edits with 'buildMarkdownText' to revalidate.
inspectMarkdownText :: MarkdownText -> MarkdownTextFields
inspectMarkdownText (CheckedMarkdownText fields) = fields

-- | Validate fields, extensions and receiving context. Return structured errors or a checked MarkdownText.
buildMarkdownText :: MarkdownTextFields -> Result MarkdownText
buildMarkdownText fields = do
  checkExtensions ["text", "verbatim"] (markdownTextExtensions fields)
  validateFields "MarkdownText" (wireMarkdownText fields)
  pure (CheckedMarkdownText fields)

wireMarkdownText :: MarkdownTextFields -> Value
wireMarkdownText fields =
  object $
    ["type" .= ("mrkdwn" :: Text)] <> ["text" .= (markdownTextText fields)] <> optional "verbatim" (markdownTextVerbatim fields) <> extensionPairs (markdownTextExtensions fields)

instance ToJSON MarkdownText where toJSON (CheckedMarkdownText fields) = wireMarkdownText fields

instance FromSlackJSON MarkdownText where
  fromSlackJSON value = do
    fields <- wireObject "mrkdwn" value
    parsedText <- required "text" fields
    parsedVerbatim <- optionalField "verbatim" fields
    buildMarkdownText (MarkdownTextFields parsedText parsedVerbatim (remaining ["text", "verbatim"] fields))

instance FromJSON MarkdownText where parseJSON = checkedParser

-- | A selectable option for menus, checkboxes, radio buttons, and overflow menus.
--
-- <https://docs.slack.dev/reference/block-kit/composition-objects/option-object>
newtype SelectOption = CheckedSelectOption SelectOptionFields deriving (Eq, Show)

-- | Editable construction input. Call 'buildSelectOption' before encoding.
data SelectOptionFields = SelectOptionFields
  { -- | Sets the option label shown to users. Required. Shared limit: @option.text@.
    selectOptionText :: TextObject,
    -- | Sets the value sent in interaction payloads when this option is chosen. Required. Shared limit: @option.value@.
    selectOptionValue :: Text,
    -- | Sets supporting text shown below the label. Only rendered by checkboxes and radio buttons. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @option.description@.
    selectOptionDescription :: Maybe (TextObject),
    -- | Sets a URL loaded in the user's browser when an overflow menu option is chosen. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @option.url@.
    selectOptionUrl :: Maybe (Text),
    -- | Unmodeled extension fields. Reserved and modeled keys are rejected.
    selectOptionExtensions :: Map Text Value
  }
  deriving (Eq, Show)

-- | Start editable fields for SelectOption; required arguments follow the signature.
-- Optional fields start absent except the explicit shared defaults; no block ID is invented.
-- Finish with 'buildSelectOption' to validate before JSON encoding.
selectOption :: TextObject -> Text -> SelectOptionFields
selectOption arg0 arg1 = SelectOptionFields (arg0) (arg1) (Nothing) (Nothing) (Map.empty)

-- | Inspect immutable construction fields. Rebuild edits with 'buildSelectOption' to revalidate.
inspectSelectOption :: SelectOption -> SelectOptionFields
inspectSelectOption (CheckedSelectOption fields) = fields

-- | Validate fields, extensions and receiving context. Return structured errors or a checked SelectOption.
buildSelectOption :: SelectOptionFields -> Result SelectOption
buildSelectOption fields = do
  checkExtensions ["text", "value", "description", "url"] (selectOptionExtensions fields)
  validateFields "Option" (wireSelectOption fields)
  pure (CheckedSelectOption fields)

wireSelectOption :: SelectOptionFields -> Value
wireSelectOption fields =
  object $
    [] <> ["text" .= (selectOptionText fields)] <> ["value" .= (selectOptionValue fields)] <> optional "description" (selectOptionDescription fields) <> optional "url" (selectOptionUrl fields) <> extensionPairs (selectOptionExtensions fields)

instance ToJSON SelectOption where toJSON (CheckedSelectOption fields) = wireSelectOption fields

instance FromSlackJSON SelectOption where
  fromSlackJSON value = do
    fields <- wireObject "" value
    parsedText <- required "text" (coerceField "text" "plain_text" fields)
    parsedValue <- required "value" fields
    parsedDescription <- optionalField "description" (coerceField "description" "plain_text" fields)
    parsedUrl <- optionalField "url" fields
    buildSelectOption (SelectOptionFields parsedText parsedValue parsedDescription parsedUrl (remaining ["text", "value", "description", "url"] fields))

instance FromJSON SelectOption where parseJSON = checkedParser

-- | A labelled group of options in a static select menu.
--
-- <https://docs.slack.dev/reference/block-kit/composition-objects/option-group-object>
newtype SelectOptionGroup = CheckedSelectOptionGroup SelectOptionGroupFields deriving (Eq, Show)

-- | Editable construction input. Call 'buildSelectOptionGroup' before encoding.
data SelectOptionGroupFields = SelectOptionGroupFields
  { -- | Sets the group heading. Required. Shared limit: @option_group.label@.
    selectOptionGroupLabel :: PlainText,
    -- | Adds selectable options in display order. Required. Shared limit: @option_group.options@.
    selectOptionGroupOptions :: [SelectOption],
    -- | Unmodeled extension fields. Reserved and modeled keys are rejected.
    selectOptionGroupExtensions :: Map Text Value
  }
  deriving (Eq, Show)

-- | Start editable fields for SelectOptionGroup; required arguments follow the signature.
-- Optional fields start absent except the explicit shared defaults; no block ID is invented.
-- Finish with 'buildSelectOptionGroup' to validate before JSON encoding.
selectOptionGroup :: PlainText -> [SelectOption] -> SelectOptionGroupFields
selectOptionGroup arg0 arg1 = SelectOptionGroupFields (arg0) (arg1) (Map.empty)

-- | Inspect immutable construction fields. Rebuild edits with 'buildSelectOptionGroup' to revalidate.
inspectSelectOptionGroup :: SelectOptionGroup -> SelectOptionGroupFields
inspectSelectOptionGroup (CheckedSelectOptionGroup fields) = fields

-- | Validate fields, extensions and receiving context. Return structured errors or a checked SelectOptionGroup.
buildSelectOptionGroup :: SelectOptionGroupFields -> Result SelectOptionGroup
buildSelectOptionGroup fields = do
  checkExtensions ["label", "options"] (selectOptionGroupExtensions fields)
  validateFields "OptionGroup" (wireSelectOptionGroup fields)
  pure (CheckedSelectOptionGroup fields)

wireSelectOptionGroup :: SelectOptionGroupFields -> Value
wireSelectOptionGroup fields =
  object $
    [] <> ["label" .= (selectOptionGroupLabel fields)] <> ["options" .= (selectOptionGroupOptions fields)] <> extensionPairs (selectOptionGroupExtensions fields)

instance ToJSON SelectOptionGroup where toJSON (CheckedSelectOptionGroup fields) = wireSelectOptionGroup fields

instance FromSlackJSON SelectOptionGroup where
  fromSlackJSON value = do
    fields <- wireObject "" value
    parsedLabel <- required "label" (coerceField "label" "plain_text" fields)
    parsedOptions <- required "options" fields
    buildSelectOptionGroup (SelectOptionGroupFields parsedLabel parsedOptions (remaining ["label", "options"] fields))

instance FromJSON SelectOptionGroup where parseJSON = checkedParser

-- | A pie chart for a data visualization block.
--
-- <https://docs.slack.dev/reference/block-kit/blocks/data-visualization-block>
newtype PieChart = CheckedPieChart PieChartFields deriving (Eq, Show)

-- | Editable construction input. Call 'buildPieChart' before encoding.
data PieChartFields = PieChartFields
  { -- | Adds pie segments in display order. Required. Shared limit: @data_visualization.segments@.
    pieChartSegments :: [ChartSegment],
    -- | Unmodeled extension fields. Reserved and modeled keys are rejected.
    pieChartExtensions :: Map Text Value
  }
  deriving (Eq, Show)

-- | Start editable fields for PieChart; required arguments follow the signature.
-- Optional fields start absent except the explicit shared defaults; no block ID is invented.
-- Finish with 'buildPieChart' to validate before JSON encoding.
pieChart :: [ChartSegment] -> PieChartFields
pieChart arg0 = PieChartFields (arg0) (Map.empty)

-- | Inspect immutable construction fields. Rebuild edits with 'buildPieChart' to revalidate.
inspectPieChart :: PieChart -> PieChartFields
inspectPieChart (CheckedPieChart fields) = fields

-- | Validate fields, extensions and receiving context. Return structured errors or a checked PieChart.
buildPieChart :: PieChartFields -> Result PieChart
buildPieChart fields = do
  checkExtensions ["segments"] (pieChartExtensions fields)
  validateFields "PieChart" (wirePieChart fields)
  pure (CheckedPieChart fields)

wirePieChart :: PieChartFields -> Value
wirePieChart fields =
  object $
    ["type" .= ("pie" :: Text)] <> ["segments" .= (pieChartSegments fields)] <> extensionPairs (pieChartExtensions fields)

instance ToJSON PieChart where toJSON (CheckedPieChart fields) = wirePieChart fields

instance FromSlackJSON PieChart where
  fromSlackJSON value = do
    fields <- wireObject "pie" value
    parsedSegments <- required "segments" fields
    buildPieChart (PieChartFields parsedSegments (remaining ["segments"] fields))

instance FromJSON PieChart where parseJSON = checkedParser

-- | A plain-text composition object.
--
-- <https://docs.slack.dev/reference/block-kit/composition-objects/text-object>
newtype PlainText = CheckedPlainText PlainTextFields deriving (Eq, Show)

-- | Editable construction input. Call 'buildPlainText' before encoding.
data PlainTextFields = PlainTextFields
  { -- | Sets the text content. Required.
    plainTextText :: Text,
    -- | Sets whether emoji shortcodes such as :tada: are rendered as emoji. Optional; Nothing omits the field. Factory default: @Nothing@.
    plainTextEmoji :: Maybe (Bool),
    -- | Unmodeled extension fields. Reserved and modeled keys are rejected.
    plainTextExtensions :: Map Text Value
  }
  deriving (Eq, Show)

-- | Start editable fields for PlainText; required arguments follow the signature.
-- Optional fields start absent except the explicit shared defaults; no block ID is invented.
-- Finish with 'buildPlainText' to validate before JSON encoding.
plainText :: Text -> PlainTextFields
plainText arg0 = PlainTextFields (arg0) (Nothing) (Map.empty)

-- | Inspect immutable construction fields. Rebuild edits with 'buildPlainText' to revalidate.
inspectPlainText :: PlainText -> PlainTextFields
inspectPlainText (CheckedPlainText fields) = fields

-- | Validate fields, extensions and receiving context. Return structured errors or a checked PlainText.
buildPlainText :: PlainTextFields -> Result PlainText
buildPlainText fields = do
  checkExtensions ["text", "emoji"] (plainTextExtensions fields)
  validateFields "PlainText" (wirePlainText fields)
  pure (CheckedPlainText fields)

wirePlainText :: PlainTextFields -> Value
wirePlainText fields =
  object $
    ["type" .= ("plain_text" :: Text)] <> ["text" .= (plainTextText fields)] <> optional "emoji" (plainTextEmoji fields) <> extensionPairs (plainTextExtensions fields)

instance ToJSON PlainText where toJSON (CheckedPlainText fields) = wirePlainText fields

instance FromSlackJSON PlainText where
  fromSlackJSON value = do
    fields <- wireObject "plain_text" value
    parsedText <- required "text" fields
    parsedEmoji <- optionalField "emoji" fields
    buildPlainText (PlainTextFields parsedText parsedEmoji (remaining ["text", "emoji"] fields))

instance FromJSON PlainText where parseJSON = checkedParser

-- | A numeric data table cell with display text.
--
-- <https://docs.slack.dev/reference/block-kit/blocks/data-table-block>
newtype RawNumber = CheckedRawNumber RawNumberFields deriving (Eq, Show)

-- | Editable construction input. Call 'buildRawNumber' before encoding.
data RawNumberFields = RawNumberFields
  { -- | Sets the numeric value used for sorting. Required.
    rawNumberValue :: Scientific,
    -- | Sets the formatted text displayed for the number, such as 1,234.5. Required.
    rawNumberText :: Text,
    -- | Unmodeled extension fields. Reserved and modeled keys are rejected.
    rawNumberExtensions :: Map Text Value
  }
  deriving (Eq, Show)

-- | Start editable fields for RawNumber; required arguments follow the signature.
-- Optional fields start absent except the explicit shared defaults; no block ID is invented.
-- Finish with 'buildRawNumber' to validate before JSON encoding.
rawNumber :: Scientific -> Text -> RawNumberFields
rawNumber arg0 arg1 = RawNumberFields (arg0) (arg1) (Map.empty)

-- | Inspect immutable construction fields. Rebuild edits with 'buildRawNumber' to revalidate.
inspectRawNumber :: RawNumber -> RawNumberFields
inspectRawNumber (CheckedRawNumber fields) = fields

-- | Validate fields, extensions and receiving context. Return structured errors or a checked RawNumber.
buildRawNumber :: RawNumberFields -> Result RawNumber
buildRawNumber fields = do
  checkExtensions ["value", "text"] (rawNumberExtensions fields)
  validateFields "RawNumber" (wireRawNumber fields)
  pure (CheckedRawNumber fields)

wireRawNumber :: RawNumberFields -> Value
wireRawNumber fields =
  object $
    ["type" .= ("raw_number" :: Text)] <> ["value" .= (rawNumberValue fields)] <> ["text" .= (rawNumberText fields)] <> extensionPairs (rawNumberExtensions fields)

instance ToJSON RawNumber where toJSON (CheckedRawNumber fields) = wireRawNumber fields

instance FromSlackJSON RawNumber where
  fromSlackJSON value = do
    fields <- wireObject "raw_number" value
    parsedValue <- required "value" fields
    parsedText <- required "text" fields
    buildRawNumber (RawNumberFields parsedValue parsedText (remaining ["value", "text"] fields))

instance FromJSON RawNumber where parseJSON = checkedParser

-- | An unformatted table cell.
--
-- <https://docs.slack.dev/reference/block-kit/blocks/table-block>
newtype RawText = CheckedRawText RawTextFields deriving (Eq, Show)

-- | Editable construction input. Call 'buildRawText' before encoding.
data RawTextFields = RawTextFields
  { -- | Sets the cell text. Required.
    rawTextText :: Text,
    -- | Unmodeled extension fields. Reserved and modeled keys are rejected.
    rawTextExtensions :: Map Text Value
  }
  deriving (Eq, Show)

-- | Start editable fields for RawText; required arguments follow the signature.
-- Optional fields start absent except the explicit shared defaults; no block ID is invented.
-- Finish with 'buildRawText' to validate before JSON encoding.
rawText :: Text -> RawTextFields
rawText arg0 = RawTextFields (arg0) (Map.empty)

-- | Inspect immutable construction fields. Rebuild edits with 'buildRawText' to revalidate.
inspectRawText :: RawText -> RawTextFields
inspectRawText (CheckedRawText fields) = fields

-- | Validate fields, extensions and receiving context. Return structured errors or a checked RawText.
buildRawText :: RawTextFields -> Result RawText
buildRawText fields = do
  checkExtensions ["text"] (rawTextExtensions fields)
  validateFields "RawText" (wireRawText fields)
  pure (CheckedRawText fields)

wireRawText :: RawTextFields -> Value
wireRawText fields =
  object $
    ["type" .= ("raw_text" :: Text)] <> ["text" .= (rawTextText fields)] <> extensionPairs (rawTextExtensions fields)

instance ToJSON RawText where toJSON (CheckedRawText fields) = wireRawText fields

instance FromSlackJSON RawText where
  fromSlackJSON value = do
    fields <- wireObject "raw_text" value
    parsedText <- required "text" fields
    buildRawText (RawTextFields parsedText (remaining ["text"] fields))

instance FromJSON RawText where parseJSON = checkedParser

-- | A channel mention inside rich text.
--
-- <https://docs.slack.dev/reference/block-kit/blocks/rich-text-block>
newtype RichTextChannel = CheckedRichTextChannel RichTextChannelFields deriving (Eq, Show)

-- | Editable construction input. Call 'buildRichTextChannel' before encoding.
data RichTextChannelFields = RichTextChannelFields
  { -- | Sets the ID of the mentioned channel. Required.
    richTextChannelChannelId :: Text,
    -- | Sets the mention style. Optional; Nothing omits the field. Factory default: @Nothing@.
    richTextChannelStyle :: Maybe (RichTextStyle),
    -- | Unmodeled extension fields. Reserved and modeled keys are rejected.
    richTextChannelExtensions :: Map Text Value
  }
  deriving (Eq, Show)

-- | Start editable fields for RichTextChannel; required arguments follow the signature.
-- Optional fields start absent except the explicit shared defaults; no block ID is invented.
-- Finish with 'buildRichTextChannel' to validate before JSON encoding.
richTextChannel :: Text -> RichTextChannelFields
richTextChannel arg0 = RichTextChannelFields (arg0) (Nothing) (Map.empty)

-- | Inspect immutable construction fields. Rebuild edits with 'buildRichTextChannel' to revalidate.
inspectRichTextChannel :: RichTextChannel -> RichTextChannelFields
inspectRichTextChannel (CheckedRichTextChannel fields) = fields

-- | Validate fields, extensions and receiving context. Return structured errors or a checked RichTextChannel.
buildRichTextChannel :: RichTextChannelFields -> Result RichTextChannel
buildRichTextChannel fields = do
  checkExtensions ["channel_id", "style"] (richTextChannelExtensions fields)
  validateFields "RichTextChannel" (wireRichTextChannel fields)
  pure (CheckedRichTextChannel fields)

wireRichTextChannel :: RichTextChannelFields -> Value
wireRichTextChannel fields =
  object $
    ["type" .= ("channel" :: Text)] <> ["channel_id" .= (richTextChannelChannelId fields)] <> optional "style" (richTextChannelStyle fields) <> extensionPairs (richTextChannelExtensions fields)

instance ToJSON RichTextChannel where toJSON (CheckedRichTextChannel fields) = wireRichTextChannel fields

instance FromSlackJSON RichTextChannel where
  fromSlackJSON value = do
    fields <- wireObject "channel" value
    parsedChannelId <- required "channel_id" fields
    parsedStyle <- optionalField "style" fields
    buildRichTextChannel (RichTextChannelFields parsedChannelId parsedStyle (remaining ["channel_id", "style"] fields))

instance FromJSON RichTextChannel where parseJSON = checkedParser

-- | A preformatted code block inside rich text.
--
-- <https://docs.slack.dev/reference/block-kit/blocks/rich-text-block>
newtype RichTextCodeBlock = CheckedRichTextCodeBlock RichTextCodeBlockFields deriving (Eq, Show)

-- | Editable construction input. Call 'buildRichTextCodeBlock' before encoding.
data RichTextCodeBlockFields = RichTextCodeBlockFields
  { -- | Adds inline rich text elements in display order. Required.
    richTextCodeBlockElements :: [RichTextSectionElement],
    -- | Sets the width of the left border, in pixels. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @rich_text_preformatted.border@.
    richTextCodeBlockBorder :: Maybe (Integer),
    -- | Unmodeled extension fields. Reserved and modeled keys are rejected.
    richTextCodeBlockExtensions :: Map Text Value
  }
  deriving (Eq, Show)

-- | Start editable fields for RichTextCodeBlock; required arguments follow the signature.
-- Optional fields start absent except the explicit shared defaults; no block ID is invented.
-- Finish with 'buildRichTextCodeBlock' to validate before JSON encoding.
richTextCodeBlock :: [RichTextSectionElement] -> RichTextCodeBlockFields
richTextCodeBlock arg0 = RichTextCodeBlockFields (arg0) (Nothing) (Map.empty)

-- | Inspect immutable construction fields. Rebuild edits with 'buildRichTextCodeBlock' to revalidate.
inspectRichTextCodeBlock :: RichTextCodeBlock -> RichTextCodeBlockFields
inspectRichTextCodeBlock (CheckedRichTextCodeBlock fields) = fields

-- | Validate fields, extensions and receiving context. Return structured errors or a checked RichTextCodeBlock.
buildRichTextCodeBlock :: RichTextCodeBlockFields -> Result RichTextCodeBlock
buildRichTextCodeBlock fields = do
  checkExtensions ["elements", "border"] (richTextCodeBlockExtensions fields)
  validateFields "RichTextCodeBlock" (wireRichTextCodeBlock fields)
  pure (CheckedRichTextCodeBlock fields)

wireRichTextCodeBlock :: RichTextCodeBlockFields -> Value
wireRichTextCodeBlock fields =
  object $
    ["type" .= ("rich_text_preformatted" :: Text)] <> ["elements" .= (richTextCodeBlockElements fields)] <> optional "border" (richTextCodeBlockBorder fields) <> extensionPairs (richTextCodeBlockExtensions fields)

instance ToJSON RichTextCodeBlock where toJSON (CheckedRichTextCodeBlock fields) = wireRichTextCodeBlock fields

instance FromSlackJSON RichTextCodeBlock where
  fromSlackJSON value = do
    fields <- wireObject "rich_text_preformatted" value
    checkIntegerBounds "RichTextCodeBlock" (Object fields)
    parsedElements <- required "elements" fields
    parsedBorder <- optionalField "border" fields
    buildRichTextCodeBlock (RichTextCodeBlockFields parsedElements parsedBorder (remaining ["elements", "border"] fields))

instance FromJSON RichTextCodeBlock where parseJSON = checkedParser

-- | An emoji inside rich text.
--
-- <https://docs.slack.dev/reference/block-kit/blocks/rich-text-block>
newtype RichTextEmoji = CheckedRichTextEmoji RichTextEmojiFields deriving (Eq, Show)

-- | Editable construction input. Call 'buildRichTextEmoji' before encoding.
data RichTextEmojiFields = RichTextEmojiFields
  { -- | Sets the emoji shortcode name, without colons. Required.
    richTextEmojiName :: Text,
    -- | Sets the emoji skin tone, from 1 to 6. Optional; Nothing omits the field. Factory default: @Nothing@.
    richTextEmojiSkinTone :: Maybe (Integer),
    -- | Unmodeled extension fields. Reserved and modeled keys are rejected.
    richTextEmojiExtensions :: Map Text Value
  }
  deriving (Eq, Show)

-- | Start editable fields for RichTextEmoji; required arguments follow the signature.
-- Optional fields start absent except the explicit shared defaults; no block ID is invented.
-- Finish with 'buildRichTextEmoji' to validate before JSON encoding.
richTextEmoji :: Text -> RichTextEmojiFields
richTextEmoji arg0 = RichTextEmojiFields (arg0) (Nothing) (Map.empty)

-- | Inspect immutable construction fields. Rebuild edits with 'buildRichTextEmoji' to revalidate.
inspectRichTextEmoji :: RichTextEmoji -> RichTextEmojiFields
inspectRichTextEmoji (CheckedRichTextEmoji fields) = fields

-- | Validate fields, extensions and receiving context. Return structured errors or a checked RichTextEmoji.
buildRichTextEmoji :: RichTextEmojiFields -> Result RichTextEmoji
buildRichTextEmoji fields = do
  checkExtensions ["name", "skin_tone"] (richTextEmojiExtensions fields)
  validateFields "RichTextEmoji" (wireRichTextEmoji fields)
  pure (CheckedRichTextEmoji fields)

wireRichTextEmoji :: RichTextEmojiFields -> Value
wireRichTextEmoji fields =
  object $
    ["type" .= ("emoji" :: Text)] <> ["name" .= (richTextEmojiName fields)] <> optional "skin_tone" (richTextEmojiSkinTone fields) <> extensionPairs (richTextEmojiExtensions fields)

instance ToJSON RichTextEmoji where toJSON (CheckedRichTextEmoji fields) = wireRichTextEmoji fields

instance FromSlackJSON RichTextEmoji where
  fromSlackJSON value = do
    fields <- wireObject "emoji" value
    parsedName <- required "name" fields
    parsedSkinTone <- optionalField "skin_tone" fields
    buildRichTextEmoji (RichTextEmojiFields parsedName parsedSkinTone (remaining ["name", "skin_tone"] fields))

instance FromJSON RichTextEmoji where parseJSON = checkedParser

-- | A hyperlink inside rich text.
--
-- <https://docs.slack.dev/reference/block-kit/blocks/rich-text-block>
newtype RichTextLink = CheckedRichTextLink RichTextLinkFields deriving (Eq, Show)

-- | Editable construction input. Call 'buildRichTextLink' before encoding.
data RichTextLinkFields = RichTextLinkFields
  { -- | Sets the link target. Required.
    richTextLinkUrl :: Text,
    -- | Sets the visible link text. Slack shows the URL when omitted. Optional; Nothing omits the field. Factory default: @Nothing@.
    richTextLinkText :: Maybe (Text),
    -- | Sets the visual style. Optional; Nothing omits the field. Factory default: @Nothing@.
    richTextLinkStyle :: Maybe (RichTextStyle),
    -- | Sets whether Slack treats the link as unsafe. Optional; Nothing omits the field. Factory default: @Nothing@.
    richTextLinkUnsafe :: Maybe (Bool),
    -- | Unmodeled extension fields. Reserved and modeled keys are rejected.
    richTextLinkExtensions :: Map Text Value
  }
  deriving (Eq, Show)

-- | Start editable fields for RichTextLink; required arguments follow the signature.
-- Optional fields start absent except the explicit shared defaults; no block ID is invented.
-- Finish with 'buildRichTextLink' to validate before JSON encoding.
richTextLink :: Text -> RichTextLinkFields
richTextLink arg0 = RichTextLinkFields (arg0) (Nothing) (Nothing) (Nothing) (Map.empty)

-- | Inspect immutable construction fields. Rebuild edits with 'buildRichTextLink' to revalidate.
inspectRichTextLink :: RichTextLink -> RichTextLinkFields
inspectRichTextLink (CheckedRichTextLink fields) = fields

-- | Validate fields, extensions and receiving context. Return structured errors or a checked RichTextLink.
buildRichTextLink :: RichTextLinkFields -> Result RichTextLink
buildRichTextLink fields = do
  checkExtensions ["url", "text", "style", "unsafe"] (richTextLinkExtensions fields)
  validateFields "RichTextLink" (wireRichTextLink fields)
  pure (CheckedRichTextLink fields)

wireRichTextLink :: RichTextLinkFields -> Value
wireRichTextLink fields =
  object $
    ["type" .= ("link" :: Text)] <> ["url" .= (richTextLinkUrl fields)] <> optional "text" (richTextLinkText fields) <> optional "style" (richTextLinkStyle fields) <> optional "unsafe" (richTextLinkUnsafe fields) <> extensionPairs (richTextLinkExtensions fields)

instance ToJSON RichTextLink where toJSON (CheckedRichTextLink fields) = wireRichTextLink fields

instance FromSlackJSON RichTextLink where
  fromSlackJSON value = do
    fields <- wireObject "link" value
    parsedUrl <- required "url" fields
    parsedText <- optionalField "text" fields
    parsedStyle <- optionalField "style" fields
    parsedUnsafe <- optionalField "unsafe" fields
    buildRichTextLink (RichTextLinkFields parsedUrl parsedText parsedStyle parsedUnsafe (remaining ["url", "text", "style", "unsafe"] fields))

instance FromJSON RichTextLink where parseJSON = checkedParser

-- | A bulleted or numbered list inside rich text.
--
-- <https://docs.slack.dev/reference/block-kit/blocks/rich-text-block>
newtype RichTextList = CheckedRichTextList RichTextListFields deriving (Eq, Show)

-- | Editable construction input. Call 'buildRichTextList' before encoding.
data RichTextListFields = RichTextListFields
  { -- | Sets whether the list is bulleted or numbered. Required.
    richTextListStyle :: RichTextListStyle,
    -- | Adds list items, one rich text section per item. Required.
    richTextListElements :: [RichTextSection],
    -- | Sets the list's indentation level. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @rich_text_list.indent@.
    richTextListIndent :: Maybe (Integer),
    -- | Sets the number of items to skip when numbering an ordered list. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @rich_text_list.offset@.
    richTextListOffset :: Maybe (Integer),
    -- | Sets the width of the left border, in pixels. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @rich_text_list.border@.
    richTextListBorder :: Maybe (Integer),
    -- | Unmodeled extension fields. Reserved and modeled keys are rejected.
    richTextListExtensions :: Map Text Value
  }
  deriving (Eq, Show)

-- | Start editable fields for RichTextList; required arguments follow the signature.
-- Optional fields start absent except the explicit shared defaults; no block ID is invented.
-- Finish with 'buildRichTextList' to validate before JSON encoding.
richTextList :: RichTextListStyle -> [RichTextSection] -> RichTextListFields
richTextList arg0 arg1 = RichTextListFields (arg0) (arg1) (Nothing) (Nothing) (Nothing) (Map.empty)

-- | Inspect immutable construction fields. Rebuild edits with 'buildRichTextList' to revalidate.
inspectRichTextList :: RichTextList -> RichTextListFields
inspectRichTextList (CheckedRichTextList fields) = fields

-- | Validate fields, extensions and receiving context. Return structured errors or a checked RichTextList.
buildRichTextList :: RichTextListFields -> Result RichTextList
buildRichTextList fields = do
  checkExtensions ["style", "elements", "indent", "offset", "border"] (richTextListExtensions fields)
  validateFields "RichTextList" (wireRichTextList fields)
  pure (CheckedRichTextList fields)

wireRichTextList :: RichTextListFields -> Value
wireRichTextList fields =
  object $
    ["type" .= ("rich_text_list" :: Text)] <> ["style" .= (richTextListStyle fields)] <> ["elements" .= (richTextListElements fields)] <> optional "indent" (richTextListIndent fields) <> optional "offset" (richTextListOffset fields) <> optional "border" (richTextListBorder fields) <> extensionPairs (richTextListExtensions fields)

instance ToJSON RichTextList where toJSON (CheckedRichTextList fields) = wireRichTextList fields

instance FromSlackJSON RichTextList where
  fromSlackJSON value = do
    fields <- wireObject "rich_text_list" value
    checkIntegerBounds "RichTextList" (Object fields)
    parsedStyle <- required "style" fields
    parsedElements <- required "elements" fields
    parsedIndent <- optionalField "indent" fields
    parsedOffset <- optionalField "offset" fields
    parsedBorder <- optionalField "border" fields
    buildRichTextList (RichTextListFields parsedStyle parsedElements parsedIndent parsedOffset parsedBorder (remaining ["style", "elements", "indent", "offset", "border"] fields))

instance FromJSON RichTextList where parseJSON = checkedParser

-- | A quotation inside rich text.
--
-- <https://docs.slack.dev/reference/block-kit/blocks/rich-text-block>
newtype RichTextQuote = CheckedRichTextQuote RichTextQuoteFields deriving (Eq, Show)

-- | Editable construction input. Call 'buildRichTextQuote' before encoding.
data RichTextQuoteFields = RichTextQuoteFields
  { -- | Adds inline rich text elements in display order. Required.
    richTextQuoteElements :: [RichTextSectionElement],
    -- | Sets the width of the left border, in pixels. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @rich_text_quote.border@.
    richTextQuoteBorder :: Maybe (Integer),
    -- | Unmodeled extension fields. Reserved and modeled keys are rejected.
    richTextQuoteExtensions :: Map Text Value
  }
  deriving (Eq, Show)

-- | Start editable fields for RichTextQuote; required arguments follow the signature.
-- Optional fields start absent except the explicit shared defaults; no block ID is invented.
-- Finish with 'buildRichTextQuote' to validate before JSON encoding.
richTextQuote :: [RichTextSectionElement] -> RichTextQuoteFields
richTextQuote arg0 = RichTextQuoteFields (arg0) (Nothing) (Map.empty)

-- | Inspect immutable construction fields. Rebuild edits with 'buildRichTextQuote' to revalidate.
inspectRichTextQuote :: RichTextQuote -> RichTextQuoteFields
inspectRichTextQuote (CheckedRichTextQuote fields) = fields

-- | Validate fields, extensions and receiving context. Return structured errors or a checked RichTextQuote.
buildRichTextQuote :: RichTextQuoteFields -> Result RichTextQuote
buildRichTextQuote fields = do
  checkExtensions ["elements", "border"] (richTextQuoteExtensions fields)
  validateFields "RichTextQuote" (wireRichTextQuote fields)
  pure (CheckedRichTextQuote fields)

wireRichTextQuote :: RichTextQuoteFields -> Value
wireRichTextQuote fields =
  object $
    ["type" .= ("rich_text_quote" :: Text)] <> ["elements" .= (richTextQuoteElements fields)] <> optional "border" (richTextQuoteBorder fields) <> extensionPairs (richTextQuoteExtensions fields)

instance ToJSON RichTextQuote where toJSON (CheckedRichTextQuote fields) = wireRichTextQuote fields

instance FromSlackJSON RichTextQuote where
  fromSlackJSON value = do
    fields <- wireObject "rich_text_quote" value
    checkIntegerBounds "RichTextQuote" (Object fields)
    parsedElements <- required "elements" fields
    parsedBorder <- optionalField "border" fields
    buildRichTextQuote (RichTextQuoteFields parsedElements parsedBorder (remaining ["elements", "border"] fields))

instance FromJSON RichTextQuote where parseJSON = checkedParser

-- | A paragraph of inline rich text elements.
--
-- <https://docs.slack.dev/reference/block-kit/blocks/rich-text-block>
newtype RichTextSection = CheckedRichTextSection RichTextSectionFields deriving (Eq, Show)

-- | Editable construction input. Call 'buildRichTextSection' before encoding.
data RichTextSectionFields = RichTextSectionFields
  { -- | Adds inline rich text elements in display order. Required.
    richTextSectionElements :: [RichTextSectionElement],
    -- | Unmodeled extension fields. Reserved and modeled keys are rejected.
    richTextSectionExtensions :: Map Text Value
  }
  deriving (Eq, Show)

-- | Start editable fields for RichTextSection; required arguments follow the signature.
-- Optional fields start absent except the explicit shared defaults; no block ID is invented.
-- Finish with 'buildRichTextSection' to validate before JSON encoding.
richTextSection :: [RichTextSectionElement] -> RichTextSectionFields
richTextSection arg0 = RichTextSectionFields (arg0) (Map.empty)

-- | Inspect immutable construction fields. Rebuild edits with 'buildRichTextSection' to revalidate.
inspectRichTextSection :: RichTextSection -> RichTextSectionFields
inspectRichTextSection (CheckedRichTextSection fields) = fields

-- | Validate fields, extensions and receiving context. Return structured errors or a checked RichTextSection.
buildRichTextSection :: RichTextSectionFields -> Result RichTextSection
buildRichTextSection fields = do
  checkExtensions ["elements"] (richTextSectionExtensions fields)
  validateFields "RichTextSection" (wireRichTextSection fields)
  pure (CheckedRichTextSection fields)

wireRichTextSection :: RichTextSectionFields -> Value
wireRichTextSection fields =
  object $
    ["type" .= ("rich_text_section" :: Text)] <> ["elements" .= (richTextSectionElements fields)] <> extensionPairs (richTextSectionExtensions fields)

instance ToJSON RichTextSection where toJSON (CheckedRichTextSection fields) = wireRichTextSection fields

instance FromSlackJSON RichTextSection where
  fromSlackJSON value = do
    fields <- wireObject "rich_text_section" value
    parsedElements <- required "elements" fields
    buildRichTextSection (RichTextSectionFields parsedElements (remaining ["elements"] fields))

instance FromJSON RichTextSection where parseJSON = checkedParser

-- | A run of optionally styled text inside rich text.
--
-- <https://docs.slack.dev/reference/block-kit/blocks/rich-text-block>
newtype RichTextText = CheckedRichTextText RichTextTextFields deriving (Eq, Show)

-- | Editable construction input. Call 'buildRichTextText' before encoding.
data RichTextTextFields = RichTextTextFields
  { -- | Sets the text content. Required.
    richTextTextText :: Text,
    -- | Sets the visual style. Optional; Nothing omits the field. Factory default: @Nothing@.
    richTextTextStyle :: Maybe (RichTextStyle),
    -- | Unmodeled extension fields. Reserved and modeled keys are rejected.
    richTextTextExtensions :: Map Text Value
  }
  deriving (Eq, Show)

-- | Start editable fields for RichTextText; required arguments follow the signature.
-- Optional fields start absent except the explicit shared defaults; no block ID is invented.
-- Finish with 'buildRichTextText' to validate before JSON encoding.
richTextText :: Text -> RichTextTextFields
richTextText arg0 = RichTextTextFields (arg0) (Nothing) (Map.empty)

-- | Inspect immutable construction fields. Rebuild edits with 'buildRichTextText' to revalidate.
inspectRichTextText :: RichTextText -> RichTextTextFields
inspectRichTextText (CheckedRichTextText fields) = fields

-- | Validate fields, extensions and receiving context. Return structured errors or a checked RichTextText.
buildRichTextText :: RichTextTextFields -> Result RichTextText
buildRichTextText fields = do
  checkExtensions ["text", "style"] (richTextTextExtensions fields)
  validateFields "RichTextText" (wireRichTextText fields)
  pure (CheckedRichTextText fields)

wireRichTextText :: RichTextTextFields -> Value
wireRichTextText fields =
  object $
    ["type" .= ("text" :: Text)] <> ["text" .= (richTextTextText fields)] <> optional "style" (richTextTextStyle fields) <> extensionPairs (richTextTextExtensions fields)

instance ToJSON RichTextText where toJSON (CheckedRichTextText fields) = wireRichTextText fields

instance FromSlackJSON RichTextText where
  fromSlackJSON value = do
    fields <- wireObject "text" value
    parsedText <- required "text" fields
    parsedStyle <- optionalField "style" fields
    buildRichTextText (RichTextTextFields parsedText parsedStyle (remaining ["text", "style"] fields))

instance FromJSON RichTextText where parseJSON = checkedParser

-- | A user mention inside rich text.
--
-- <https://docs.slack.dev/reference/block-kit/blocks/rich-text-block>
newtype RichTextUser = CheckedRichTextUser RichTextUserFields deriving (Eq, Show)

-- | Editable construction input. Call 'buildRichTextUser' before encoding.
data RichTextUserFields = RichTextUserFields
  { -- | Sets the ID of the mentioned user. Required.
    richTextUserUserId :: Text,
    -- | Sets the visual style. Optional; Nothing omits the field. Factory default: @Nothing@.
    richTextUserStyle :: Maybe (RichTextStyle),
    -- | Unmodeled extension fields. Reserved and modeled keys are rejected.
    richTextUserExtensions :: Map Text Value
  }
  deriving (Eq, Show)

-- | Start editable fields for RichTextUser; required arguments follow the signature.
-- Optional fields start absent except the explicit shared defaults; no block ID is invented.
-- Finish with 'buildRichTextUser' to validate before JSON encoding.
richTextUser :: Text -> RichTextUserFields
richTextUser arg0 = RichTextUserFields (arg0) (Nothing) (Map.empty)

-- | Inspect immutable construction fields. Rebuild edits with 'buildRichTextUser' to revalidate.
inspectRichTextUser :: RichTextUser -> RichTextUserFields
inspectRichTextUser (CheckedRichTextUser fields) = fields

-- | Validate fields, extensions and receiving context. Return structured errors or a checked RichTextUser.
buildRichTextUser :: RichTextUserFields -> Result RichTextUser
buildRichTextUser fields = do
  checkExtensions ["user_id", "style"] (richTextUserExtensions fields)
  validateFields "RichTextUser" (wireRichTextUser fields)
  pure (CheckedRichTextUser fields)

wireRichTextUser :: RichTextUserFields -> Value
wireRichTextUser fields =
  object $
    ["type" .= ("user" :: Text)] <> ["user_id" .= (richTextUserUserId fields)] <> optional "style" (richTextUserStyle fields) <> extensionPairs (richTextUserExtensions fields)

instance ToJSON RichTextUser where toJSON (CheckedRichTextUser fields) = wireRichTextUser fields

instance FromSlackJSON RichTextUser where
  fromSlackJSON value = do
    fields <- wireObject "user" value
    parsedUserId <- required "user_id" fields
    parsedStyle <- optionalField "style" fields
    buildRichTextUser (RichTextUserFields parsedUserId parsedStyle (remaining ["user_id", "style"] fields))

instance FromJSON RichTextUser where parseJSON = checkedParser

-- | A user group mention inside rich text.
--
-- <https://docs.slack.dev/reference/block-kit/blocks/rich-text-block>
newtype RichTextUserGroup = CheckedRichTextUserGroup RichTextUserGroupFields deriving (Eq, Show)

-- | Editable construction input. Call 'buildRichTextUserGroup' before encoding.
data RichTextUserGroupFields = RichTextUserGroupFields
  { -- | Sets the ID of the mentioned user group. Required.
    richTextUserGroupUserGroupId :: Text,
    -- | Sets the visual style. Optional; Nothing omits the field. Factory default: @Nothing@.
    richTextUserGroupStyle :: Maybe (RichTextStyle),
    -- | Unmodeled extension fields. Reserved and modeled keys are rejected.
    richTextUserGroupExtensions :: Map Text Value
  }
  deriving (Eq, Show)

-- | Start editable fields for RichTextUserGroup; required arguments follow the signature.
-- Optional fields start absent except the explicit shared defaults; no block ID is invented.
-- Finish with 'buildRichTextUserGroup' to validate before JSON encoding.
richTextUserGroup :: Text -> RichTextUserGroupFields
richTextUserGroup arg0 = RichTextUserGroupFields (arg0) (Nothing) (Map.empty)

-- | Inspect immutable construction fields. Rebuild edits with 'buildRichTextUserGroup' to revalidate.
inspectRichTextUserGroup :: RichTextUserGroup -> RichTextUserGroupFields
inspectRichTextUserGroup (CheckedRichTextUserGroup fields) = fields

-- | Validate fields, extensions and receiving context. Return structured errors or a checked RichTextUserGroup.
buildRichTextUserGroup :: RichTextUserGroupFields -> Result RichTextUserGroup
buildRichTextUserGroup fields = do
  checkExtensions ["usergroup_id", "style"] (richTextUserGroupExtensions fields)
  validateFields "RichTextUserGroup" (wireRichTextUserGroup fields)
  pure (CheckedRichTextUserGroup fields)

wireRichTextUserGroup :: RichTextUserGroupFields -> Value
wireRichTextUserGroup fields =
  object $
    ["type" .= ("usergroup" :: Text)] <> ["usergroup_id" .= (richTextUserGroupUserGroupId fields)] <> optional "style" (richTextUserGroupStyle fields) <> extensionPairs (richTextUserGroupExtensions fields)

instance ToJSON RichTextUserGroup where toJSON (CheckedRichTextUserGroup fields) = wireRichTextUserGroup fields

instance FromSlackJSON RichTextUserGroup where
  fromSlackJSON value = do
    fields <- wireObject "usergroup" value
    parsedUserGroupId <- required "usergroup_id" fields
    parsedStyle <- optionalField "style" fields
    buildRichTextUserGroup (RichTextUserGroupFields parsedUserGroupId parsedStyle (remaining ["usergroup_id", "style"] fields))

instance FromJSON RichTextUserGroup where parseJSON = checkedParser

-- | A reference to an image file hosted in Slack.
--
-- <https://docs.slack.dev/reference/block-kit/composition-objects/slack-file-object>
-- Provide exactly one of an ID or a URL.
-- An ID must match ^F[A-Z0-9]{8,}$.
newtype SlackFile = CheckedSlackFile SlackFileFields deriving (Eq, Show)

-- | Editable construction input. Call 'buildSlackFile' before encoding.
data SlackFileFields = SlackFileFields
  { -- | Sets the ID of a file previously uploaded to Slack. Cannot be combined with a URL. Optional; Nothing omits the field. Factory default: @Nothing@.
    slackFileId :: Maybe (Text),
    -- | Sets the URL of a file hosted in Slack. Cannot be combined with an ID. Optional; Nothing omits the field. Factory default: @Nothing@.
    slackFileUrl :: Maybe (Text),
    -- | Unmodeled extension fields. Reserved and modeled keys are rejected.
    slackFileExtensions :: Map Text Value
  }
  deriving (Eq, Show)

-- | Start editable fields for SlackFile; required arguments follow the signature.
-- Optional fields start absent except the explicit shared defaults; no block ID is invented.
-- Finish with 'buildSlackFile' to validate before JSON encoding.
slackFile :: SlackFileFields
slackFile = SlackFileFields (Nothing) (Nothing) (Map.empty)

-- | Inspect immutable construction fields. Rebuild edits with 'buildSlackFile' to revalidate.
inspectSlackFile :: SlackFile -> SlackFileFields
inspectSlackFile (CheckedSlackFile fields) = fields

-- | Validate fields, extensions and receiving context. Return structured errors or a checked SlackFile.
buildSlackFile :: SlackFileFields -> Result SlackFile
buildSlackFile fields = do
  checkExtensions ["id", "url"] (slackFileExtensions fields)
  validateFields "SlackFile" (wireSlackFile fields)
  pure (CheckedSlackFile fields)

wireSlackFile :: SlackFileFields -> Value
wireSlackFile fields =
  object $
    [] <> optional "id" (slackFileId fields) <> optional "url" (slackFileUrl fields) <> extensionPairs (slackFileExtensions fields)

instance ToJSON SlackFile where toJSON (CheckedSlackFile fields) = wireSlackFile fields

instance FromSlackJSON SlackFile where
  fromSlackJSON value = do
    fields <- wireObject "" value
    parsedId <- optionalField "id" fields
    parsedUrl <- optionalField "url" fields
    buildSlackFile (SlackFileFields parsedId parsedUrl (remaining ["id", "url"] fields))

instance FromJSON SlackFile where parseJSON = checkedParser

-- | A Slack-provided icon, referenced by name.
--
-- <https://docs.slack.dev/reference/block-kit/blocks/card-block>
newtype SlackIcon = CheckedSlackIcon SlackIconFields deriving (Eq, Show)

-- | Editable construction input. Call 'buildSlackIcon' before encoding.
data SlackIconFields = SlackIconFields
  { -- | Sets the name of the Slack-provided icon, such as rocket. Required.
    slackIconName :: Text,
    -- | Unmodeled extension fields. Reserved and modeled keys are rejected.
    slackIconExtensions :: Map Text Value
  }
  deriving (Eq, Show)

-- | Start editable fields for SlackIcon; required arguments follow the signature.
-- Optional fields start absent except the explicit shared defaults; no block ID is invented.
-- Finish with 'buildSlackIcon' to validate before JSON encoding.
slackIcon :: Text -> SlackIconFields
slackIcon arg0 = SlackIconFields (arg0) (Map.empty)

-- | Inspect immutable construction fields. Rebuild edits with 'buildSlackIcon' to revalidate.
inspectSlackIcon :: SlackIcon -> SlackIconFields
inspectSlackIcon (CheckedSlackIcon fields) = fields

-- | Validate fields, extensions and receiving context. Return structured errors or a checked SlackIcon.
buildSlackIcon :: SlackIconFields -> Result SlackIcon
buildSlackIcon fields = do
  checkExtensions ["name"] (slackIconExtensions fields)
  validateFields "SlackIcon" (wireSlackIcon fields)
  pure (CheckedSlackIcon fields)

wireSlackIcon :: SlackIconFields -> Value
wireSlackIcon fields =
  object $
    ["type" .= ("icon" :: Text)] <> ["name" .= (slackIconName fields)] <> extensionPairs (slackIconExtensions fields)

instance ToJSON SlackIcon where toJSON (CheckedSlackIcon fields) = wireSlackIcon fields

instance FromSlackJSON SlackIcon where
  fromSlackJSON value = do
    fields <- wireObject "icon" value
    parsedName <- required "name" fields
    buildSlackIcon (SlackIconFields parsedName (remaining ["name"] fields))

instance FromJSON SlackIcon where parseJSON = checkedParser

-- | A link trigger that starts a workflow.
--
-- <https://docs.slack.dev/reference/block-kit/composition-objects/trigger-object>
newtype Trigger = CheckedTrigger TriggerFields deriving (Eq, Show)

-- | Editable construction input. Call 'buildTrigger' before encoding.
data TriggerFields = TriggerFields
  { -- | Sets the link trigger URL. Required.
    triggerUrl :: Text,
    -- | Adds the input values passed to the workflow's trigger. Optional; Nothing omits the field. Factory default: @Nothing@.
    triggerCustomizableInputParameters :: Maybe ([InputParameter]),
    -- | Unmodeled extension fields. Reserved and modeled keys are rejected.
    triggerExtensions :: Map Text Value
  }
  deriving (Eq, Show)

-- | Start editable fields for Trigger; required arguments follow the signature.
-- Optional fields start absent except the explicit shared defaults; no block ID is invented.
-- Finish with 'buildTrigger' to validate before JSON encoding.
trigger :: Text -> TriggerFields
trigger arg0 = TriggerFields (arg0) (Nothing) (Map.empty)

-- | Inspect immutable construction fields. Rebuild edits with 'buildTrigger' to revalidate.
inspectTrigger :: Trigger -> TriggerFields
inspectTrigger (CheckedTrigger fields) = fields

-- | Validate fields, extensions and receiving context. Return structured errors or a checked Trigger.
buildTrigger :: TriggerFields -> Result Trigger
buildTrigger fields = do
  checkExtensions ["url", "customizable_input_parameters"] (triggerExtensions fields)
  validateFields "Trigger" (wireTrigger fields)
  pure (CheckedTrigger fields)

wireTrigger :: TriggerFields -> Value
wireTrigger fields =
  object $
    [] <> ["url" .= (triggerUrl fields)] <> optional "customizable_input_parameters" (triggerCustomizableInputParameters fields) <> extensionPairs (triggerExtensions fields)

instance ToJSON Trigger where toJSON (CheckedTrigger fields) = wireTrigger fields

instance FromSlackJSON Trigger where
  fromSlackJSON value = do
    fields <- wireObject "" value
    parsedUrl <- required "url" fields
    parsedCustomizableInputParameters <- optionalField "customizable_input_parameters" fields
    buildTrigger (TriggerFields parsedUrl parsedCustomizableInputParameters (remaining ["url", "customizable_input_parameters"] fields))

instance FromJSON Trigger where parseJSON = checkedParser

-- | A linked source cited by a task card.
--
-- <https://docs.slack.dev/reference/block-kit/blocks/task-card-block>
newtype UrlSource = CheckedUrlSource UrlSourceFields deriving (Eq, Show)

-- | Editable construction input. Call 'buildUrlSource' before encoding.
data UrlSourceFields = UrlSourceFields
  { -- | Sets the source URL. Required.
    urlSourceUrl :: Text,
    -- | Sets the source link text. Required.
    urlSourceText :: Text,
    -- | Unmodeled extension fields. Reserved and modeled keys are rejected.
    urlSourceExtensions :: Map Text Value
  }
  deriving (Eq, Show)

-- | Start editable fields for UrlSource; required arguments follow the signature.
-- Optional fields start absent except the explicit shared defaults; no block ID is invented.
-- Finish with 'buildUrlSource' to validate before JSON encoding.
urlSource :: Text -> Text -> UrlSourceFields
urlSource arg0 arg1 = UrlSourceFields (arg0) (arg1) (Map.empty)

-- | Inspect immutable construction fields. Rebuild edits with 'buildUrlSource' to revalidate.
inspectUrlSource :: UrlSource -> UrlSourceFields
inspectUrlSource (CheckedUrlSource fields) = fields

-- | Validate fields, extensions and receiving context. Return structured errors or a checked UrlSource.
buildUrlSource :: UrlSourceFields -> Result UrlSource
buildUrlSource fields = do
  checkExtensions ["url", "text"] (urlSourceExtensions fields)
  validateFields "UrlSource" (wireUrlSource fields)
  pure (CheckedUrlSource fields)

wireUrlSource :: UrlSourceFields -> Value
wireUrlSource fields =
  object $
    ["type" .= ("url" :: Text)] <> ["url" .= (urlSourceUrl fields)] <> ["text" .= (urlSourceText fields)] <> extensionPairs (urlSourceExtensions fields)

instance ToJSON UrlSource where toJSON (CheckedUrlSource fields) = wireUrlSource fields

instance FromSlackJSON UrlSource where
  fromSlackJSON value = do
    fields <- wireObject "url" value
    parsedUrl <- required "url" fields
    parsedText <- required "text" fields
    buildUrlSource (UrlSourceFields parsedUrl parsedText (remaining ["url", "text"] fields))

instance FromJSON UrlSource where parseJSON = checkedParser

-- | The workflow started by a workflow button.
--
-- <https://docs.slack.dev/reference/block-kit/composition-objects/workflow-object>
newtype Workflow = CheckedWorkflow WorkflowFields deriving (Eq, Show)

-- | Editable construction input. Call 'buildWorkflow' before encoding.
data WorkflowFields = WorkflowFields
  { -- | Sets the link trigger that starts the workflow. Required.
    workflowTrigger :: Trigger,
    -- | Unmodeled extension fields. Reserved and modeled keys are rejected.
    workflowExtensions :: Map Text Value
  }
  deriving (Eq, Show)

-- | Start editable fields for Workflow; required arguments follow the signature.
-- Optional fields start absent except the explicit shared defaults; no block ID is invented.
-- Finish with 'buildWorkflow' to validate before JSON encoding.
workflow :: Trigger -> WorkflowFields
workflow arg0 = WorkflowFields (arg0) (Map.empty)

-- | Inspect immutable construction fields. Rebuild edits with 'buildWorkflow' to revalidate.
inspectWorkflow :: Workflow -> WorkflowFields
inspectWorkflow (CheckedWorkflow fields) = fields

-- | Validate fields, extensions and receiving context. Return structured errors or a checked Workflow.
buildWorkflow :: WorkflowFields -> Result Workflow
buildWorkflow fields = do
  checkExtensions ["trigger"] (workflowExtensions fields)
  validateFields "Workflow" (wireWorkflow fields)
  pure (CheckedWorkflow fields)

wireWorkflow :: WorkflowFields -> Value
wireWorkflow fields =
  object $
    [] <> ["trigger" .= (workflowTrigger fields)] <> extensionPairs (workflowExtensions fields)

instance ToJSON Workflow where toJSON (CheckedWorkflow fields) = wireWorkflow fields

instance FromSlackJSON Workflow where
  fromSlackJSON value = do
    fields <- wireObject "" value
    parsedTrigger <- required "trigger" fields
    buildWorkflow (WorkflowFields parsedTrigger (remaining ["trigger"] fields))

instance FromJSON Workflow where parseJSON = checkedParser

-- | A legacy message attachment containing blocks and an optional color bar.
--
-- <https://docs.slack.dev/messaging/formatting-message-text#when-to-use-attachments>
-- Only blocks supported in messages are accepted.
newtype Attachment = CheckedAttachment AttachmentFields deriving (Eq, Show)

-- | Editable construction input. Call 'buildAttachment' before encoding.
data AttachmentFields = AttachmentFields
  { -- | Adds the attachment's blocks in display order. Required.
    attachmentBlocks :: [Block],
    -- | Sets the attachment's left border color: a six-digit hex color or good, warning, or danger. Optional; Nothing omits the field. Factory default: @Nothing@.
    attachmentColor :: Maybe (Text),
    -- | Sets plain-text summary shown in clients that cannot display attachments. Optional; Nothing omits the field. Factory default: @Nothing@.
    attachmentFallback :: Maybe (Text),
    -- | Unmodeled extension fields. Reserved and modeled keys are rejected.
    attachmentExtensions :: Map Text Value
  }
  deriving (Eq, Show)

-- | Start editable fields for Attachment; required arguments follow the signature.
-- Optional fields start absent except the explicit shared defaults; no block ID is invented.
-- Finish with 'buildAttachment' to validate before JSON encoding.
attachment :: [Block] -> AttachmentFields
attachment arg0 = AttachmentFields (arg0) (Nothing) (Nothing) (Map.empty)

-- | Inspect immutable construction fields. Rebuild edits with 'buildAttachment' to revalidate.
inspectAttachment :: Attachment -> AttachmentFields
inspectAttachment (CheckedAttachment fields) = fields

-- | Validate fields, extensions and receiving context. Return structured errors or a checked Attachment.
buildAttachment :: AttachmentFields -> Result Attachment
buildAttachment fields = do
  checkExtensions ["blocks", "color", "fallback"] (attachmentExtensions fields)
  validateFields "Attachment" (wireAttachment fields)
  pure (CheckedAttachment fields)

wireAttachment :: AttachmentFields -> Value
wireAttachment fields =
  object $
    [] <> ["blocks" .= (attachmentBlocks fields)] <> optional "color" (attachmentColor fields) <> optional "fallback" (attachmentFallback fields) <> extensionPairs (attachmentExtensions fields)

instance ToJSON Attachment where toJSON (CheckedAttachment fields) = wireAttachment fields

instance FromSlackJSON Attachment where
  fromSlackJSON value = do
    fields <- wireObject "" value
    parsedBlocks <- required "blocks" fields
    parsedColor <- optionalField "color" fields
    parsedFallback <- optionalField "fallback" fields
    buildAttachment (AttachmentFields parsedBlocks parsedColor parsedFallback (remaining ["blocks", "color", "fallback"] fields))

instance FromJSON Attachment where parseJSON = checkedParser

-- | The payload for publishing an App Home tab with views.publish.
--
-- <https://docs.slack.dev/surfaces/app-home>
-- Only blocks supported on the App Home tab are accepted.
newtype HomeTabView = CheckedHomeTabView HomeTabViewFields deriving (Eq, Show)

-- | Editable construction input. Call 'buildHomeTabView' before encoding.
data HomeTabViewFields = HomeTabViewFields
  { -- | Adds the blocks shown on the App Home tab, in display order. Required. Shared limit: @view.blocks@.
    homeTabViewBlocks :: [Block],
    -- | Sets application-defined data returned in view payloads. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @view.private_metadata@.
    homeTabViewPrivateMetadata :: Maybe (Text),
    -- | Sets an identifier returned in view payloads so your app can recognize the view. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @view.callback_id@.
    homeTabViewCallbackId :: Maybe (Text),
    -- | Sets a workspace-unique identifier you can use to update the view later. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @view.external_id@.
    homeTabViewExternalId :: Maybe (Text),
    -- | Unmodeled extension fields. Reserved and modeled keys are rejected.
    homeTabViewExtensions :: Map Text Value
  }
  deriving (Eq, Show)

-- | Start editable fields for HomeTabView; required arguments follow the signature.
-- Optional fields start absent except the explicit shared defaults; no block ID is invented.
-- Finish with 'buildHomeTabView' to validate before JSON encoding.
homeTabView :: [Block] -> HomeTabViewFields
homeTabView arg0 = HomeTabViewFields (arg0) (Nothing) (Nothing) (Nothing) (Map.empty)

-- | Inspect immutable construction fields. Rebuild edits with 'buildHomeTabView' to revalidate.
inspectHomeTabView :: HomeTabView -> HomeTabViewFields
inspectHomeTabView (CheckedHomeTabView fields) = fields

-- | Validate fields, extensions and receiving context. Return structured errors or a checked HomeTabView.
buildHomeTabView :: HomeTabViewFields -> Result HomeTabView
buildHomeTabView fields = do
  checkExtensions ["blocks", "private_metadata", "callback_id", "external_id"] (homeTabViewExtensions fields)
  validateFields "HomeTabView" (wireHomeTabView fields)
  pure (CheckedHomeTabView fields)

wireHomeTabView :: HomeTabViewFields -> Value
wireHomeTabView fields =
  object $
    ["type" .= ("home" :: Text)] <> ["blocks" .= (homeTabViewBlocks fields)] <> optional "private_metadata" (homeTabViewPrivateMetadata fields) <> optional "callback_id" (homeTabViewCallbackId fields) <> optional "external_id" (homeTabViewExternalId fields) <> extensionPairs (homeTabViewExtensions fields)

instance ToJSON HomeTabView where toJSON (CheckedHomeTabView fields) = wireHomeTabView fields

instance FromSlackJSON HomeTabView where
  fromSlackJSON value = do
    fields <- wireObject "home" value
    parsedBlocks <- required "blocks" fields
    parsedPrivateMetadata <- optionalField "private_metadata" fields
    parsedCallbackId <- optionalField "callback_id" fields
    parsedExternalId <- optionalField "external_id" fields
    buildHomeTabView (HomeTabViewFields parsedBlocks parsedPrivateMetadata parsedCallbackId parsedExternalId (remaining ["blocks", "private_metadata", "callback_id", "external_id"] fields))

instance FromJSON HomeTabView where parseJSON = checkedParser

-- | A complete payload for chat.postMessage and related Web API methods.
--
-- <https://docs.slack.dev/reference/methods/chat.postMessage>
-- Only blocks supported in messages are accepted.
-- Markdown block text is limited to 12,000 characters, and data table cell text to 20,000 characters, across the whole message.
-- At most two data visualization blocks may be sent per message, across blocks and attachments after helper expansion (message.data_visualizations.max_items).
newtype MessagePayload = CheckedMessagePayload MessagePayloadFields deriving (Eq, Show)

-- | Editable construction input. Call 'buildMessagePayload' before encoding.
data MessagePayloadFields = MessagePayloadFields
  { -- | Sets the ID of the channel, private group, or conversation that receives the message. Required. Shared limit: @message.channel@.
    messagePayloadChannel :: Text,
    -- | Adds the message blocks in display order. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @message.blocks@.
    messagePayloadBlocks :: Maybe ([Block]),
    -- | Adds legacy attachments in display order. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @message.attachments@.
    messagePayloadAttachments :: Maybe ([Attachment]),
    -- | Sets the fallback text used in notifications and by clients that cannot display blocks. Optional; Nothing omits the field. Factory default: @Just ("")@.
    messagePayloadText :: Maybe (Text),
    -- | Sets whether Slack formats the top-level text as mrkdwn. Optional; Nothing omits the field. Factory default: @Just (True)@.
    messagePayloadMrkdwn :: Maybe (Bool),
    -- | Sets whether Slack unfurls text-based links. Optional; Nothing omits the field. Factory default: @Nothing@.
    messagePayloadUnfurlLinks :: Maybe (Bool),
    -- | Sets whether Slack unfurls media links. Optional; Nothing omits the field. Factory default: @Nothing@.
    messagePayloadUnfurlMedia :: Maybe (Bool),
    -- | Sets message metadata as a JSON-compatible map, such as event_type and event_payload. Optional; Nothing omits the field. Factory default: @Nothing@.
    messagePayloadMetadata :: Maybe (Map Text Value),
    -- | Unmodeled extension fields. Reserved and modeled keys are rejected.
    messagePayloadExtensions :: Map Text Value
  }
  deriving (Eq, Show)

-- | Start editable fields for MessagePayload; required arguments follow the signature.
-- Optional fields start absent except the explicit shared defaults; no block ID is invented.
-- Finish with 'buildMessagePayload' to validate before JSON encoding.
messagePayload :: Text -> MessagePayloadFields
messagePayload arg0 = MessagePayloadFields (arg0) (Nothing) (Nothing) (Just ("")) (Just (True)) (Nothing) (Nothing) (Nothing) (Map.empty)

-- | Inspect immutable construction fields. Rebuild edits with 'buildMessagePayload' to revalidate.
inspectMessagePayload :: MessagePayload -> MessagePayloadFields
inspectMessagePayload (CheckedMessagePayload fields) = fields

-- | Validate fields, extensions and receiving context. Return structured errors or a checked MessagePayload.
buildMessagePayload :: MessagePayloadFields -> Result MessagePayload
buildMessagePayload fields = do
  checkExtensions ["channel", "blocks", "attachments", "text", "mrkdwn", "unfurl_links", "unfurl_media", "metadata"] (messagePayloadExtensions fields)
  validateFields "MessagePayload" (wireMessagePayload fields)
  pure (CheckedMessagePayload fields)

wireMessagePayload :: MessagePayloadFields -> Value
wireMessagePayload fields =
  object $
    [] <> ["channel" .= (messagePayloadChannel fields)] <> optional "blocks" (messagePayloadBlocks fields) <> optional "attachments" (messagePayloadAttachments fields) <> optional "text" (messagePayloadText fields) <> optional "mrkdwn" (messagePayloadMrkdwn fields) <> optional "unfurl_links" (messagePayloadUnfurlLinks fields) <> optional "unfurl_media" (messagePayloadUnfurlMedia fields) <> optional "metadata" (messagePayloadMetadata fields) <> extensionPairs (messagePayloadExtensions fields)

instance ToJSON MessagePayload where toJSON (CheckedMessagePayload fields) = wireMessagePayload fields

instance FromSlackJSON MessagePayload where
  fromSlackJSON value = do
    fields <- wireObject "" value
    parsedChannel <- required "channel" fields
    parsedBlocks <- optionalField "blocks" fields
    parsedAttachments <- optionalField "attachments" fields
    parsedText <- optionalField "text" fields
    parsedMrkdwn <- optionalField "mrkdwn" fields
    parsedUnfurlLinks <- optionalField "unfurl_links" fields
    parsedUnfurlMedia <- optionalField "unfurl_media" fields
    parsedMetadata <- optionalField "metadata" fields
    buildMessagePayload (MessagePayloadFields parsedChannel parsedBlocks parsedAttachments parsedText parsedMrkdwn parsedUnfurlLinks parsedUnfurlMedia parsedMetadata (remaining ["channel", "blocks", "attachments", "text", "mrkdwn", "unfurl_links", "unfurl_media", "metadata"] fields))

instance FromJSON MessagePayload where parseJSON = checkedParser

-- | A response body for slash commands and interaction response URLs.
--
-- <https://docs.slack.dev/interactivity/handling-user-interaction#message_responses>
-- Only blocks supported in messages are accepted.
-- Markdown block text is limited to 12,000 characters, and data table cell text to 20,000 characters, across the whole message.
-- At most two data visualization blocks may be sent per message, across blocks and attachments after helper expansion (message.data_visualizations.max_items).
newtype MessageResponse = CheckedMessageResponse MessageResponseFields deriving (Eq, Show)

-- | Editable construction input. Call 'buildMessageResponse' before encoding.
data MessageResponseFields = MessageResponseFields
  { -- | Adds the response blocks in display order. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @message.blocks@.
    messageResponseBlocks :: Maybe ([Block]),
    -- | Adds legacy attachments in display order. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @message.attachments@.
    messageResponseAttachments :: Maybe ([Attachment]),
    -- | Sets the fallback text used in notifications and by clients that cannot display blocks. Optional; Nothing omits the field. Factory default: @Just ("")@.
    messageResponseText :: Maybe (Text),
    -- | Sets whether Slack formats the top-level text as mrkdwn. Optional; Nothing omits the field. Factory default: @Just (True)@.
    messageResponseMrkdwn :: Maybe (Bool),
    -- | Sets whether the response replaces the message that triggered it. Optional; Nothing omits the field. Factory default: @Just (False)@.
    messageResponseReplaceOriginal :: Maybe (Bool),
    -- | Sets who can see the response. Optional; Nothing omits the field. Factory default: @Just (ResponseTypeInChannel)@.
    messageResponseResponseType :: Maybe (ResponseType),
    -- | Unmodeled extension fields. Reserved and modeled keys are rejected.
    messageResponseExtensions :: Map Text Value
  }
  deriving (Eq, Show)

-- | Start editable fields for MessageResponse; required arguments follow the signature.
-- Optional fields start absent except the explicit shared defaults; no block ID is invented.
-- Finish with 'buildMessageResponse' to validate before JSON encoding.
messageResponse :: MessageResponseFields
messageResponse = MessageResponseFields (Nothing) (Nothing) (Just ("")) (Just (True)) (Just (False)) (Just (ResponseTypeInChannel)) (Map.empty)

-- | Inspect immutable construction fields. Rebuild edits with 'buildMessageResponse' to revalidate.
inspectMessageResponse :: MessageResponse -> MessageResponseFields
inspectMessageResponse (CheckedMessageResponse fields) = fields

-- | Validate fields, extensions and receiving context. Return structured errors or a checked MessageResponse.
buildMessageResponse :: MessageResponseFields -> Result MessageResponse
buildMessageResponse fields = do
  checkExtensions ["blocks", "attachments", "text", "mrkdwn", "replace_original", "response_type"] (messageResponseExtensions fields)
  validateFields "MessageResponse" (wireMessageResponse fields)
  pure (CheckedMessageResponse fields)

wireMessageResponse :: MessageResponseFields -> Value
wireMessageResponse fields =
  object $
    [] <> optional "blocks" (messageResponseBlocks fields) <> optional "attachments" (messageResponseAttachments fields) <> optional "text" (messageResponseText fields) <> optional "mrkdwn" (messageResponseMrkdwn fields) <> optional "replace_original" (messageResponseReplaceOriginal fields) <> optional "response_type" (messageResponseResponseType fields) <> extensionPairs (messageResponseExtensions fields)

instance ToJSON MessageResponse where toJSON (CheckedMessageResponse fields) = wireMessageResponse fields

instance FromSlackJSON MessageResponse where
  fromSlackJSON value = do
    fields <- wireObject "" value
    parsedBlocks <- optionalField "blocks" fields
    parsedAttachments <- optionalField "attachments" fields
    parsedText <- optionalField "text" fields
    parsedMrkdwn <- optionalField "mrkdwn" fields
    parsedReplaceOriginal <- optionalField "replace_original" fields
    parsedResponseType <- optionalField "response_type" fields
    buildMessageResponse (MessageResponseFields parsedBlocks parsedAttachments parsedText parsedMrkdwn parsedReplaceOriginal parsedResponseType (remaining ["blocks", "attachments", "text", "mrkdwn", "replace_original", "response_type"] fields))

instance FromJSON MessageResponse where parseJSON = checkedParser

-- | The view payload for views.open, views.push, and views.update.
--
-- <https://docs.slack.dev/surfaces/modals>
-- Only blocks supported in modals are accepted.
-- A modal that contains an input block must have a submit label.
newtype ModalView = CheckedModalView ModalViewFields deriving (Eq, Show)

-- | Editable construction input. Call 'buildModalView' before encoding.
data ModalViewFields = ModalViewFields
  { -- | Sets the title in the modal's top bar. Required. Shared limit: @view.title@.
    modalViewTitle :: PlainText,
    -- | Adds the blocks shown in the modal, in display order. Required. Shared limit: @view.blocks@.
    modalViewBlocks :: [Block],
    -- | Sets the label of the button that closes the modal. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @view.close@.
    modalViewClose :: Maybe (PlainText),
    -- | Sets the label of the button that submits the modal. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @view.submit@.
    modalViewSubmit :: Maybe (PlainText),
    -- | Sets application-defined data returned in view payloads. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @view.private_metadata@.
    modalViewPrivateMetadata :: Maybe (Text),
    -- | Sets an identifier returned in view payloads so your app can recognize the view. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @view.callback_id@.
    modalViewCallbackId :: Maybe (Text),
    -- | Sets whether closing this modal closes every view in its stack. Optional; Nothing omits the field. Factory default: @Nothing@.
    modalViewClearOnClose :: Maybe (Bool),
    -- | Sets whether Slack sends a view_closed event when the user closes the modal. Optional; Nothing omits the field. Factory default: @Nothing@.
    modalViewNotifyOnClose :: Maybe (Bool),
    -- | Sets a workspace-unique identifier you can use to update the view later. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @view.external_id@.
    modalViewExternalId :: Maybe (Text),
    -- | Sets whether the submit button starts disabled in workflow configuration modals only. Omit this field for ordinary views.open/views.push modals, including when false. The general ModalView value cannot infer its receiving workflow context. Optional; Nothing omits the field. Factory default: @Nothing@.
    modalViewSubmitDisabled :: Maybe (Bool),
    -- | Unmodeled extension fields. Reserved and modeled keys are rejected.
    modalViewExtensions :: Map Text Value
  }
  deriving (Eq, Show)

-- | Start editable fields for ModalView; required arguments follow the signature.
-- Optional fields start absent except the explicit shared defaults; no block ID is invented.
-- Finish with 'buildModalView' to validate before JSON encoding.
modalView :: PlainText -> [Block] -> ModalViewFields
modalView arg0 arg1 = ModalViewFields (arg0) (arg1) (Nothing) (Nothing) (Nothing) (Nothing) (Nothing) (Nothing) (Nothing) (Nothing) (Map.empty)

-- | Inspect immutable construction fields. Rebuild edits with 'buildModalView' to revalidate.
inspectModalView :: ModalView -> ModalViewFields
inspectModalView (CheckedModalView fields) = fields

-- | Validate fields, extensions and receiving context. Return structured errors or a checked ModalView.
buildModalView :: ModalViewFields -> Result ModalView
buildModalView fields = do
  checkExtensions ["title", "blocks", "close", "submit", "private_metadata", "callback_id", "clear_on_close", "notify_on_close", "external_id", "submit_disabled"] (modalViewExtensions fields)
  validateFields "ModalView" (wireModalView fields)
  pure (CheckedModalView fields)

wireModalView :: ModalViewFields -> Value
wireModalView fields =
  object $
    ["type" .= ("modal" :: Text)] <> ["title" .= (modalViewTitle fields)] <> ["blocks" .= (modalViewBlocks fields)] <> optional "close" (modalViewClose fields) <> optional "submit" (modalViewSubmit fields) <> optional "private_metadata" (modalViewPrivateMetadata fields) <> optional "callback_id" (modalViewCallbackId fields) <> optional "clear_on_close" (modalViewClearOnClose fields) <> optional "notify_on_close" (modalViewNotifyOnClose fields) <> optional "external_id" (modalViewExternalId fields) <> optional "submit_disabled" (modalViewSubmitDisabled fields) <> extensionPairs (modalViewExtensions fields)

instance ToJSON ModalView where toJSON (CheckedModalView fields) = wireModalView fields

instance FromSlackJSON ModalView where
  fromSlackJSON value = do
    fields <- wireObject "modal" value
    parsedTitle <- required "title" (coerceField "title" "plain_text" fields)
    parsedBlocks <- required "blocks" fields
    parsedClose <- optionalField "close" (coerceField "close" "plain_text" fields)
    parsedSubmit <- optionalField "submit" (coerceField "submit" "plain_text" fields)
    parsedPrivateMetadata <- optionalField "private_metadata" fields
    parsedCallbackId <- optionalField "callback_id" fields
    parsedClearOnClose <- optionalField "clear_on_close" fields
    parsedNotifyOnClose <- optionalField "notify_on_close" fields
    parsedExternalId <- optionalField "external_id" fields
    parsedSubmitDisabled <- optionalField "submit_disabled" fields
    buildModalView (ModalViewFields parsedTitle parsedBlocks parsedClose parsedSubmit parsedPrivateMetadata parsedCallbackId parsedClearOnClose parsedNotifyOnClose parsedExternalId parsedSubmitDisabled (remaining ["title", "blocks", "close", "submit", "private_metadata", "callback_id", "clear_on_close", "notify_on_close", "external_id", "submit_disabled"] fields))

instance FromJSON ModalView where parseJSON = checkedParser

-- | A payload for incoming webhooks.
--
-- <https://docs.slack.dev/messaging/sending-messages-using-incoming-webhooks>
-- Only blocks supported in messages are accepted.
-- Markdown block text is limited to 12,000 characters, and data table cell text to 20,000 characters, across the whole message.
-- At most two data visualization blocks may be sent per message, across blocks and attachments after helper expansion (message.data_visualizations.max_items).
newtype WebhookMessage = CheckedWebhookMessage WebhookMessageFields deriving (Eq, Show)

-- | Editable construction input. Call 'buildWebhookMessage' before encoding.
data WebhookMessageFields = WebhookMessageFields
  { -- | Adds the message blocks in display order. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @message.blocks@.
    webhookMessageBlocks :: Maybe ([Block]),
    -- | Adds legacy attachments in display order. Optional; Nothing omits the field. Factory default: @Nothing@. Shared limit: @message.attachments@.
    webhookMessageAttachments :: Maybe ([Attachment]),
    -- | Sets the fallback text used in notifications and by clients that cannot display blocks. Optional; Nothing omits the field. Factory default: @Nothing@.
    webhookMessageText :: Maybe (Text),
    -- | Sets who can see the response. Optional; Nothing omits the field. Factory default: @Nothing@.
    webhookMessageResponseType :: Maybe (ResponseType),
    -- | Sets whether the response replaces the message that triggered it. Optional; Nothing omits the field. Factory default: @Nothing@.
    webhookMessageReplaceOriginal :: Maybe (Bool),
    -- | Sets whether the response deletes the message that triggered it. Optional; Nothing omits the field. Factory default: @Nothing@.
    webhookMessageDeleteOriginal :: Maybe (Bool),
    -- | Sets whether Slack unfurls text-based links. Optional; Nothing omits the field. Factory default: @Nothing@.
    webhookMessageUnfurlLinks :: Maybe (Bool),
    -- | Sets whether Slack unfurls media links. Optional; Nothing omits the field. Factory default: @Nothing@.
    webhookMessageUnfurlMedia :: Maybe (Bool),
    -- | Sets message metadata as a JSON-compatible map, such as event_type and event_payload. Optional; Nothing omits the field. Factory default: @Nothing@.
    webhookMessageMetadata :: Maybe (Map Text Value),
    -- | Unmodeled extension fields. Reserved and modeled keys are rejected.
    webhookMessageExtensions :: Map Text Value
  }
  deriving (Eq, Show)

-- | Start editable fields for WebhookMessage; required arguments follow the signature.
-- Optional fields start absent except the explicit shared defaults; no block ID is invented.
-- Finish with 'buildWebhookMessage' to validate before JSON encoding.
webhookMessage :: WebhookMessageFields
webhookMessage = WebhookMessageFields (Nothing) (Nothing) (Nothing) (Nothing) (Nothing) (Nothing) (Nothing) (Nothing) (Nothing) (Map.empty)

-- | Inspect immutable construction fields. Rebuild edits with 'buildWebhookMessage' to revalidate.
inspectWebhookMessage :: WebhookMessage -> WebhookMessageFields
inspectWebhookMessage (CheckedWebhookMessage fields) = fields

-- | Validate fields, extensions and receiving context. Return structured errors or a checked WebhookMessage.
buildWebhookMessage :: WebhookMessageFields -> Result WebhookMessage
buildWebhookMessage fields = do
  checkExtensions ["blocks", "attachments", "text", "response_type", "replace_original", "delete_original", "unfurl_links", "unfurl_media", "metadata"] (webhookMessageExtensions fields)
  validateFields "WebhookMessage" (wireWebhookMessage fields)
  pure (CheckedWebhookMessage fields)

wireWebhookMessage :: WebhookMessageFields -> Value
wireWebhookMessage fields =
  object $
    [] <> optional "blocks" (webhookMessageBlocks fields) <> optional "attachments" (webhookMessageAttachments fields) <> optional "text" (webhookMessageText fields) <> optional "response_type" (webhookMessageResponseType fields) <> optional "replace_original" (webhookMessageReplaceOriginal fields) <> optional "delete_original" (webhookMessageDeleteOriginal fields) <> optional "unfurl_links" (webhookMessageUnfurlLinks fields) <> optional "unfurl_media" (webhookMessageUnfurlMedia fields) <> optional "metadata" (webhookMessageMetadata fields) <> extensionPairs (webhookMessageExtensions fields)

instance ToJSON WebhookMessage where toJSON (CheckedWebhookMessage fields) = wireWebhookMessage fields

instance FromSlackJSON WebhookMessage where
  fromSlackJSON value = do
    fields <- wireObject "" value
    parsedBlocks <- optionalField "blocks" fields
    parsedAttachments <- optionalField "attachments" fields
    parsedText <- optionalField "text" fields
    parsedResponseType <- optionalField "response_type" fields
    parsedReplaceOriginal <- optionalField "replace_original" fields
    parsedDeleteOriginal <- optionalField "delete_original" fields
    parsedUnfurlLinks <- optionalField "unfurl_links" fields
    parsedUnfurlMedia <- optionalField "unfurl_media" fields
    parsedMetadata <- optionalField "metadata" fields
    buildWebhookMessage (WebhookMessageFields parsedBlocks parsedAttachments parsedText parsedResponseType parsedReplaceOriginal parsedDeleteOriginal parsedUnfurlLinks parsedUnfurlMedia parsedMetadata (remaining ["blocks", "attachments", "text", "response_type", "replace_original", "delete_original", "unfurl_links", "unfurl_media", "metadata"] fields))

instance FromJSON WebhookMessage where parseJSON = checkedParser

-- | A task in a plan. Unlike a standalone task card, it may be pending.
newtype PlanTask = CheckedPlanTask TaskCardBlock deriving (Eq, Show)

-- | Check a task for a plan, where pending is allowed. This value cannot enter the Block role.
buildPlanTask :: TaskCardBlockFields -> Result PlanTask
buildPlanTask fields = do
  checkExtensions ["task_id", "title", "details", "output", "sources", "status", "block_id"] (taskCardBlockExtensions fields)
  validateFields "TaskCardBlock" (wireTaskCardBlock fields)
  pure (CheckedPlanTask (CheckedTaskCardBlock fields))

-- | Inspect a plan task; call buildPlanTask after editing its fields.
inspectPlanTask :: PlanTask -> TaskCardBlockFields
inspectPlanTask (CheckedPlanTask task) = inspectTaskCardBlock task

instance ToJSON PlanTask where toJSON (CheckedPlanTask task) = stripTag (toJSON task)

instance FromSlackJSON PlanTask where fromSlackJSON = decodeTaskCard buildPlanTask . restoreTask

instance FromJSON PlanTask where parseJSON = checkedParser

-- | Closed role: only checked members may enter this position.
data Block = BlockActionsBlock ActionsBlock | BlockAlertBlock AlertBlock | BlockCardBlock CardBlock | BlockCarouselBlock CarouselBlock | BlockContainerBlock ContainerBlock | BlockContextActionsBlock ContextActionsBlock | BlockContextBlock ContextBlock | BlockDataTableBlock DataTableBlock | BlockDataVisualizationBlock DataVisualizationBlock | BlockDividerBlock DividerBlock | BlockFileBlock FileBlock | BlockHeaderBlock HeaderBlock | BlockImageBlock ImageBlock | BlockInputBlock InputBlock | BlockMarkdownBlock MarkdownBlock | BlockPlanBlock PlanBlock | BlockRichTextBlock RichTextBlock | BlockSectionBlock SectionBlock | BlockTableBlock TableBlock | BlockTaskCardBlock TaskCardBlock | BlockVideoBlock VideoBlock deriving (Eq, Show)

instance ToJSON Block where
  toJSON (BlockActionsBlock value) = toJSON value
  toJSON (BlockAlertBlock value) = toJSON value
  toJSON (BlockCardBlock value) = toJSON value
  toJSON (BlockCarouselBlock value) = toJSON value
  toJSON (BlockContainerBlock value) = toJSON value
  toJSON (BlockContextActionsBlock value) = toJSON value
  toJSON (BlockContextBlock value) = toJSON value
  toJSON (BlockDataTableBlock value) = toJSON value
  toJSON (BlockDataVisualizationBlock value) = toJSON value
  toJSON (BlockDividerBlock value) = toJSON value
  toJSON (BlockFileBlock value) = toJSON value
  toJSON (BlockHeaderBlock value) = toJSON value
  toJSON (BlockImageBlock value) = toJSON value
  toJSON (BlockInputBlock value) = toJSON value
  toJSON (BlockMarkdownBlock value) = toJSON value
  toJSON (BlockPlanBlock value) = toJSON value
  toJSON (BlockRichTextBlock value) = toJSON value
  toJSON (BlockSectionBlock value) = toJSON value
  toJSON (BlockTableBlock value) = toJSON value
  toJSON (BlockTaskCardBlock value) = toJSON value
  toJSON (BlockVideoBlock value) = toJSON value

instance FromSlackJSON Block where
  fromSlackJSON value = do
    tag <- wireTag value
    case tag of
      "actions" -> BlockActionsBlock <$> fromSlackJSON value
      "alert" -> BlockAlertBlock <$> fromSlackJSON value
      "card" -> BlockCardBlock <$> fromSlackJSON value
      "carousel" -> BlockCarouselBlock <$> fromSlackJSON value
      "container" -> BlockContainerBlock <$> fromSlackJSON value
      "context_actions" -> BlockContextActionsBlock <$> fromSlackJSON value
      "context" -> BlockContextBlock <$> fromSlackJSON value
      "data_table" -> BlockDataTableBlock <$> fromSlackJSON value
      "data_visualization" -> BlockDataVisualizationBlock <$> fromSlackJSON value
      "divider" -> BlockDividerBlock <$> fromSlackJSON value
      "file" -> BlockFileBlock <$> fromSlackJSON value
      "header" -> BlockHeaderBlock <$> fromSlackJSON value
      "image" -> BlockImageBlock <$> fromSlackJSON value
      "input" -> BlockInputBlock <$> fromSlackJSON value
      "markdown" -> BlockMarkdownBlock <$> fromSlackJSON value
      "plan" -> BlockPlanBlock <$> fromSlackJSON value
      "rich_text" -> BlockRichTextBlock <$> fromSlackJSON value
      "section" -> BlockSectionBlock <$> fromSlackJSON value
      "table" -> BlockTableBlock <$> fromSlackJSON value
      "task_card" -> fromSlackJSON value >>= taskCardBlockAsBlock
      "video" -> BlockVideoBlock <$> fromSlackJSON value
      _ -> failure TypeMismatch [Field "type"] "role" "unsupported child type"

instance FromJSON Block where parseJSON = checkedParser

-- | Place a checked ActionsBlock in the Block role. The receiving parent retains its contextual validation.
actionsBlockAsBlock :: ActionsBlock -> Block
actionsBlockAsBlock = BlockActionsBlock

-- | Return the ActionsBlock member when present, otherwise Nothing; no unchecked cast.
matchBlockActionsBlock :: Block -> Maybe ActionsBlock
matchBlockActionsBlock (BlockActionsBlock value) = Just value
matchBlockActionsBlock _ = Nothing

-- | Place a checked AlertBlock in the Block role. The receiving parent retains its contextual validation.
alertBlockAsBlock :: AlertBlock -> Block
alertBlockAsBlock = BlockAlertBlock

-- | Return the AlertBlock member when present, otherwise Nothing; no unchecked cast.
matchBlockAlertBlock :: Block -> Maybe AlertBlock
matchBlockAlertBlock (BlockAlertBlock value) = Just value
matchBlockAlertBlock _ = Nothing

-- | Place a checked CardBlock in the Block role. The receiving parent retains its contextual validation.
cardBlockAsBlock :: CardBlock -> Block
cardBlockAsBlock = BlockCardBlock

-- | Return the CardBlock member when present, otherwise Nothing; no unchecked cast.
matchBlockCardBlock :: Block -> Maybe CardBlock
matchBlockCardBlock (BlockCardBlock value) = Just value
matchBlockCardBlock _ = Nothing

-- | Place a checked CarouselBlock in the Block role. The receiving parent retains its contextual validation.
carouselBlockAsBlock :: CarouselBlock -> Block
carouselBlockAsBlock = BlockCarouselBlock

-- | Return the CarouselBlock member when present, otherwise Nothing; no unchecked cast.
matchBlockCarouselBlock :: Block -> Maybe CarouselBlock
matchBlockCarouselBlock (BlockCarouselBlock value) = Just value
matchBlockCarouselBlock _ = Nothing

-- | Place a checked ContainerBlock in the Block role. The receiving parent retains its contextual validation.
containerBlockAsBlock :: ContainerBlock -> Block
containerBlockAsBlock = BlockContainerBlock

-- | Return the ContainerBlock member when present, otherwise Nothing; no unchecked cast.
matchBlockContainerBlock :: Block -> Maybe ContainerBlock
matchBlockContainerBlock (BlockContainerBlock value) = Just value
matchBlockContainerBlock _ = Nothing

-- | Place a checked ContextActionsBlock in the Block role. The receiving parent retains its contextual validation.
contextActionsBlockAsBlock :: ContextActionsBlock -> Block
contextActionsBlockAsBlock = BlockContextActionsBlock

-- | Return the ContextActionsBlock member when present, otherwise Nothing; no unchecked cast.
matchBlockContextActionsBlock :: Block -> Maybe ContextActionsBlock
matchBlockContextActionsBlock (BlockContextActionsBlock value) = Just value
matchBlockContextActionsBlock _ = Nothing

-- | Place a checked ContextBlock in the Block role. The receiving parent retains its contextual validation.
contextBlockAsBlock :: ContextBlock -> Block
contextBlockAsBlock = BlockContextBlock

-- | Return the ContextBlock member when present, otherwise Nothing; no unchecked cast.
matchBlockContextBlock :: Block -> Maybe ContextBlock
matchBlockContextBlock (BlockContextBlock value) = Just value
matchBlockContextBlock _ = Nothing

-- | Place a checked DataTableBlock in the Block role. The receiving parent retains its contextual validation.
dataTableBlockAsBlock :: DataTableBlock -> Block
dataTableBlockAsBlock = BlockDataTableBlock

-- | Return the DataTableBlock member when present, otherwise Nothing; no unchecked cast.
matchBlockDataTableBlock :: Block -> Maybe DataTableBlock
matchBlockDataTableBlock (BlockDataTableBlock value) = Just value
matchBlockDataTableBlock _ = Nothing

-- | Place a checked DataVisualizationBlock in the Block role. The receiving parent retains its contextual validation.
dataVisualizationBlockAsBlock :: DataVisualizationBlock -> Block
dataVisualizationBlockAsBlock = BlockDataVisualizationBlock

-- | Return the DataVisualizationBlock member when present, otherwise Nothing; no unchecked cast.
matchBlockDataVisualizationBlock :: Block -> Maybe DataVisualizationBlock
matchBlockDataVisualizationBlock (BlockDataVisualizationBlock value) = Just value
matchBlockDataVisualizationBlock _ = Nothing

-- | Place a checked DividerBlock in the Block role. The receiving parent retains its contextual validation.
dividerBlockAsBlock :: DividerBlock -> Block
dividerBlockAsBlock = BlockDividerBlock

-- | Return the DividerBlock member when present, otherwise Nothing; no unchecked cast.
matchBlockDividerBlock :: Block -> Maybe DividerBlock
matchBlockDividerBlock (BlockDividerBlock value) = Just value
matchBlockDividerBlock _ = Nothing

-- | Place a checked FileBlock in the Block role. The receiving parent retains its contextual validation.
fileBlockAsBlock :: FileBlock -> Block
fileBlockAsBlock = BlockFileBlock

-- | Return the FileBlock member when present, otherwise Nothing; no unchecked cast.
matchBlockFileBlock :: Block -> Maybe FileBlock
matchBlockFileBlock (BlockFileBlock value) = Just value
matchBlockFileBlock _ = Nothing

-- | Place a checked HeaderBlock in the Block role. The receiving parent retains its contextual validation.
headerBlockAsBlock :: HeaderBlock -> Block
headerBlockAsBlock = BlockHeaderBlock

-- | Return the HeaderBlock member when present, otherwise Nothing; no unchecked cast.
matchBlockHeaderBlock :: Block -> Maybe HeaderBlock
matchBlockHeaderBlock (BlockHeaderBlock value) = Just value
matchBlockHeaderBlock _ = Nothing

-- | Place a checked ImageBlock in the Block role. The receiving parent retains its contextual validation.
imageBlockAsBlock :: ImageBlock -> Block
imageBlockAsBlock = BlockImageBlock

-- | Return the ImageBlock member when present, otherwise Nothing; no unchecked cast.
matchBlockImageBlock :: Block -> Maybe ImageBlock
matchBlockImageBlock (BlockImageBlock value) = Just value
matchBlockImageBlock _ = Nothing

-- | Place a checked InputBlock in the Block role. The receiving parent retains its contextual validation.
inputBlockAsBlock :: InputBlock -> Block
inputBlockAsBlock = BlockInputBlock

-- | Return the InputBlock member when present, otherwise Nothing; no unchecked cast.
matchBlockInputBlock :: Block -> Maybe InputBlock
matchBlockInputBlock (BlockInputBlock value) = Just value
matchBlockInputBlock _ = Nothing

-- | Place a checked MarkdownBlock in the Block role. The receiving parent retains its contextual validation.
markdownBlockAsBlock :: MarkdownBlock -> Block
markdownBlockAsBlock = BlockMarkdownBlock

-- | Return the MarkdownBlock member when present, otherwise Nothing; no unchecked cast.
matchBlockMarkdownBlock :: Block -> Maybe MarkdownBlock
matchBlockMarkdownBlock (BlockMarkdownBlock value) = Just value
matchBlockMarkdownBlock _ = Nothing

-- | Place a checked PlanBlock in the Block role. The receiving parent retains its contextual validation.
planBlockAsBlock :: PlanBlock -> Block
planBlockAsBlock = BlockPlanBlock

-- | Return the PlanBlock member when present, otherwise Nothing; no unchecked cast.
matchBlockPlanBlock :: Block -> Maybe PlanBlock
matchBlockPlanBlock (BlockPlanBlock value) = Just value
matchBlockPlanBlock _ = Nothing

-- | Place a checked RichTextBlock in the Block role. The receiving parent retains its contextual validation.
richTextBlockAsBlock :: RichTextBlock -> Block
richTextBlockAsBlock = BlockRichTextBlock

-- | Return the RichTextBlock member when present, otherwise Nothing; no unchecked cast.
matchBlockRichTextBlock :: Block -> Maybe RichTextBlock
matchBlockRichTextBlock (BlockRichTextBlock value) = Just value
matchBlockRichTextBlock _ = Nothing

-- | Place a checked SectionBlock in the Block role. The receiving parent retains its contextual validation.
sectionBlockAsBlock :: SectionBlock -> Block
sectionBlockAsBlock = BlockSectionBlock

-- | Return the SectionBlock member when present, otherwise Nothing; no unchecked cast.
matchBlockSectionBlock :: Block -> Maybe SectionBlock
matchBlockSectionBlock (BlockSectionBlock value) = Just value
matchBlockSectionBlock _ = Nothing

-- | Place a checked TableBlock in the Block role. The receiving parent retains its contextual validation.
tableBlockAsBlock :: TableBlock -> Block
tableBlockAsBlock = BlockTableBlock

-- | Return the TableBlock member when present, otherwise Nothing; no unchecked cast.
matchBlockTableBlock :: Block -> Maybe TableBlock
matchBlockTableBlock (BlockTableBlock value) = Just value
matchBlockTableBlock _ = Nothing

-- | Place a checked TaskCardBlock in the Block role. The receiving parent retains its contextual validation.
taskCardBlockAsBlock :: TaskCardBlock -> Result Block
taskCardBlockAsBlock value = do
  standaloneTask (toJSON value)
  pure (BlockTaskCardBlock value)

-- | Return the TaskCardBlock member when present, otherwise Nothing; no unchecked cast.
matchBlockTaskCardBlock :: Block -> Maybe TaskCardBlock
matchBlockTaskCardBlock (BlockTaskCardBlock value) = Just value
matchBlockTaskCardBlock _ = Nothing

-- | Place a checked VideoBlock in the Block role. The receiving parent retains its contextual validation.
videoBlockAsBlock :: VideoBlock -> Block
videoBlockAsBlock = BlockVideoBlock

-- | Return the VideoBlock member when present, otherwise Nothing; no unchecked cast.
matchBlockVideoBlock :: Block -> Maybe VideoBlock
matchBlockVideoBlock (BlockVideoBlock value) = Just value
matchBlockVideoBlock _ = Nothing

-- | Closed role: only checked members may enter this position.
data ContextElement = ContextElementImageElement ImageElement | ContextElementMarkdownText MarkdownText | ContextElementPlainText PlainText deriving (Eq, Show)

instance ToJSON ContextElement where
  toJSON (ContextElementImageElement value) = toJSON value
  toJSON (ContextElementMarkdownText value) = toJSON value
  toJSON (ContextElementPlainText value) = toJSON value

instance FromSlackJSON ContextElement where
  fromSlackJSON value = do
    tag <- wireTag value
    case tag of
      "image" -> ContextElementImageElement <$> fromSlackJSON value
      "mrkdwn" -> ContextElementMarkdownText <$> fromSlackJSON value
      "plain_text" -> ContextElementPlainText <$> fromSlackJSON value
      _ -> failure TypeMismatch [Field "type"] "role" "unsupported child type"

instance FromJSON ContextElement where parseJSON = checkedParser

-- | Place a checked ImageElement in the ContextElement role. The receiving parent retains its contextual validation.
imageElementAsContextElement :: ImageElement -> ContextElement
imageElementAsContextElement = ContextElementImageElement

-- | Return the ImageElement member when present, otherwise Nothing; no unchecked cast.
matchContextElementImageElement :: ContextElement -> Maybe ImageElement
matchContextElementImageElement (ContextElementImageElement value) = Just value
matchContextElementImageElement _ = Nothing

-- | Place a checked MarkdownText in the ContextElement role. The receiving parent retains its contextual validation.
markdownTextAsContextElement :: MarkdownText -> ContextElement
markdownTextAsContextElement = ContextElementMarkdownText

-- | Return the MarkdownText member when present, otherwise Nothing; no unchecked cast.
matchContextElementMarkdownText :: ContextElement -> Maybe MarkdownText
matchContextElementMarkdownText (ContextElementMarkdownText value) = Just value
matchContextElementMarkdownText _ = Nothing

-- | Place a checked PlainText in the ContextElement role. The receiving parent retains its contextual validation.
plainTextAsContextElement :: PlainText -> ContextElement
plainTextAsContextElement = ContextElementPlainText

-- | Return the PlainText member when present, otherwise Nothing; no unchecked cast.
matchContextElementPlainText :: ContextElement -> Maybe PlainText
matchContextElementPlainText (ContextElementPlainText value) = Just value
matchContextElementPlainText _ = Nothing

-- | Closed role: only checked members may enter this position.
data ContextActionsElement = ContextActionsElementFeedbackButtonsElement FeedbackButtonsElement | ContextActionsElementIconButtonElement IconButtonElement deriving (Eq, Show)

instance ToJSON ContextActionsElement where
  toJSON (ContextActionsElementFeedbackButtonsElement value) = toJSON value
  toJSON (ContextActionsElementIconButtonElement value) = toJSON value

instance FromSlackJSON ContextActionsElement where
  fromSlackJSON value = do
    tag <- wireTag value
    case tag of
      "feedback_buttons" -> ContextActionsElementFeedbackButtonsElement <$> fromSlackJSON value
      "icon_button" -> ContextActionsElementIconButtonElement <$> fromSlackJSON value
      _ -> failure TypeMismatch [Field "type"] "role" "unsupported child type"

instance FromJSON ContextActionsElement where parseJSON = checkedParser

-- | Place a checked FeedbackButtonsElement in the ContextActionsElement role. The receiving parent retains its contextual validation.
feedbackButtonsElementAsContextActionsElement :: FeedbackButtonsElement -> ContextActionsElement
feedbackButtonsElementAsContextActionsElement = ContextActionsElementFeedbackButtonsElement

-- | Return the FeedbackButtonsElement member when present, otherwise Nothing; no unchecked cast.
matchContextActionsElementFeedbackButtonsElement :: ContextActionsElement -> Maybe FeedbackButtonsElement
matchContextActionsElementFeedbackButtonsElement (ContextActionsElementFeedbackButtonsElement value) = Just value
matchContextActionsElementFeedbackButtonsElement _ = Nothing

-- | Place a checked IconButtonElement in the ContextActionsElement role. The receiving parent retains its contextual validation.
iconButtonElementAsContextActionsElement :: IconButtonElement -> ContextActionsElement
iconButtonElementAsContextActionsElement = ContextActionsElementIconButtonElement

-- | Return the IconButtonElement member when present, otherwise Nothing; no unchecked cast.
matchContextActionsElementIconButtonElement :: ContextActionsElement -> Maybe IconButtonElement
matchContextActionsElementIconButtonElement (ContextActionsElementIconButtonElement value) = Just value
matchContextActionsElementIconButtonElement _ = Nothing

-- | Closed role: only checked members may enter this position.
data TableCell = TableCellRichTextBlock RichTextBlock | TableCellRawText RawText deriving (Eq, Show)

instance ToJSON TableCell where
  toJSON (TableCellRichTextBlock value) = toJSON value
  toJSON (TableCellRawText value) = toJSON value

instance FromSlackJSON TableCell where
  fromSlackJSON value = do
    tag <- wireTag value
    case tag of
      "rich_text" -> TableCellRichTextBlock <$> fromSlackJSON value
      "raw_text" -> TableCellRawText <$> fromSlackJSON value
      _ -> failure TypeMismatch [Field "type"] "role" "unsupported child type"

instance FromJSON TableCell where parseJSON = checkedParser

-- | Place a checked RichTextBlock in the TableCell role. The receiving parent retains its contextual validation.
richTextBlockAsTableCell :: RichTextBlock -> TableCell
richTextBlockAsTableCell = TableCellRichTextBlock

-- | Return the RichTextBlock member when present, otherwise Nothing; no unchecked cast.
matchTableCellRichTextBlock :: TableCell -> Maybe RichTextBlock
matchTableCellRichTextBlock (TableCellRichTextBlock value) = Just value
matchTableCellRichTextBlock _ = Nothing

-- | Place a checked RawText in the TableCell role. The receiving parent retains its contextual validation.
rawTextAsTableCell :: RawText -> TableCell
rawTextAsTableCell = TableCellRawText

-- | Return the RawText member when present, otherwise Nothing; no unchecked cast.
matchTableCellRawText :: TableCell -> Maybe RawText
matchTableCellRawText (TableCellRawText value) = Just value
matchTableCellRawText _ = Nothing

-- | Closed role: only checked members may enter this position.
data DataTableCell = DataTableCellRichTextBlock RichTextBlock | DataTableCellRawNumber RawNumber | DataTableCellRawText RawText deriving (Eq, Show)

instance ToJSON DataTableCell where
  toJSON (DataTableCellRichTextBlock value) = toJSON value
  toJSON (DataTableCellRawNumber value) = toJSON value
  toJSON (DataTableCellRawText value) = toJSON value

instance FromSlackJSON DataTableCell where
  fromSlackJSON value = do
    tag <- wireTag value
    case tag of
      "rich_text" -> DataTableCellRichTextBlock <$> fromSlackJSON value
      "raw_number" -> DataTableCellRawNumber <$> fromSlackJSON value
      "raw_text" -> DataTableCellRawText <$> fromSlackJSON value
      _ -> failure TypeMismatch [Field "type"] "role" "unsupported child type"

instance FromJSON DataTableCell where parseJSON = checkedParser

-- | Place a checked RichTextBlock in the DataTableCell role. The receiving parent retains its contextual validation.
richTextBlockAsDataTableCell :: RichTextBlock -> DataTableCell
richTextBlockAsDataTableCell = DataTableCellRichTextBlock

-- | Return the RichTextBlock member when present, otherwise Nothing; no unchecked cast.
matchDataTableCellRichTextBlock :: DataTableCell -> Maybe RichTextBlock
matchDataTableCellRichTextBlock (DataTableCellRichTextBlock value) = Just value
matchDataTableCellRichTextBlock _ = Nothing

-- | Place a checked RawNumber in the DataTableCell role. The receiving parent retains its contextual validation.
rawNumberAsDataTableCell :: RawNumber -> DataTableCell
rawNumberAsDataTableCell = DataTableCellRawNumber

-- | Return the RawNumber member when present, otherwise Nothing; no unchecked cast.
matchDataTableCellRawNumber :: DataTableCell -> Maybe RawNumber
matchDataTableCellRawNumber (DataTableCellRawNumber value) = Just value
matchDataTableCellRawNumber _ = Nothing

-- | Place a checked RawText in the DataTableCell role. The receiving parent retains its contextual validation.
rawTextAsDataTableCell :: RawText -> DataTableCell
rawTextAsDataTableCell = DataTableCellRawText

-- | Return the RawText member when present, otherwise Nothing; no unchecked cast.
matchDataTableCellRawText :: DataTableCell -> Maybe RawText
matchDataTableCellRawText (DataTableCellRawText value) = Just value
matchDataTableCellRawText _ = Nothing

-- | Closed role: only checked members may enter this position.
data Element = ElementButtonElement ButtonElement | ElementChannelMultiSelectElement ChannelMultiSelectElement | ElementChannelSelectElement ChannelSelectElement | ElementCheckboxesElement CheckboxesElement | ElementConversationMultiSelectElement ConversationMultiSelectElement | ElementConversationSelectElement ConversationSelectElement | ElementDatePickerElement DatePickerElement | ElementDateTimePickerElement DateTimePickerElement | ElementEmailInputElement EmailInputElement | ElementExternalMultiSelectElement ExternalMultiSelectElement | ElementExternalSelectElement ExternalSelectElement | ElementFeedbackButtonsElement FeedbackButtonsElement | ElementFileInputElement FileInputElement | ElementIconButtonElement IconButtonElement | ElementImageElement ImageElement | ElementNumberInputElement NumberInputElement | ElementOverflowElement OverflowElement | ElementPlainTextInputElement PlainTextInputElement | ElementRadioButtonsElement RadioButtonsElement | ElementRichTextInputElement RichTextInputElement | ElementStaticMultiSelectElement StaticMultiSelectElement | ElementStaticSelectElement StaticSelectElement | ElementTimePickerElement TimePickerElement | ElementUrlInputElement UrlInputElement | ElementUserMultiSelectElement UserMultiSelectElement | ElementUserSelectElement UserSelectElement | ElementWorkflowButtonElement WorkflowButtonElement deriving (Eq, Show)

instance ToJSON Element where
  toJSON (ElementButtonElement value) = toJSON value
  toJSON (ElementChannelMultiSelectElement value) = toJSON value
  toJSON (ElementChannelSelectElement value) = toJSON value
  toJSON (ElementCheckboxesElement value) = toJSON value
  toJSON (ElementConversationMultiSelectElement value) = toJSON value
  toJSON (ElementConversationSelectElement value) = toJSON value
  toJSON (ElementDatePickerElement value) = toJSON value
  toJSON (ElementDateTimePickerElement value) = toJSON value
  toJSON (ElementEmailInputElement value) = toJSON value
  toJSON (ElementExternalMultiSelectElement value) = toJSON value
  toJSON (ElementExternalSelectElement value) = toJSON value
  toJSON (ElementFeedbackButtonsElement value) = toJSON value
  toJSON (ElementFileInputElement value) = toJSON value
  toJSON (ElementIconButtonElement value) = toJSON value
  toJSON (ElementImageElement value) = toJSON value
  toJSON (ElementNumberInputElement value) = toJSON value
  toJSON (ElementOverflowElement value) = toJSON value
  toJSON (ElementPlainTextInputElement value) = toJSON value
  toJSON (ElementRadioButtonsElement value) = toJSON value
  toJSON (ElementRichTextInputElement value) = toJSON value
  toJSON (ElementStaticMultiSelectElement value) = toJSON value
  toJSON (ElementStaticSelectElement value) = toJSON value
  toJSON (ElementTimePickerElement value) = toJSON value
  toJSON (ElementUrlInputElement value) = toJSON value
  toJSON (ElementUserMultiSelectElement value) = toJSON value
  toJSON (ElementUserSelectElement value) = toJSON value
  toJSON (ElementWorkflowButtonElement value) = toJSON value

instance FromSlackJSON Element where
  fromSlackJSON value = do
    tag <- wireTag value
    case tag of
      "button" -> ElementButtonElement <$> fromSlackJSON value
      "multi_channels_select" -> ElementChannelMultiSelectElement <$> fromSlackJSON value
      "channels_select" -> ElementChannelSelectElement <$> fromSlackJSON value
      "checkboxes" -> ElementCheckboxesElement <$> fromSlackJSON value
      "multi_conversations_select" -> ElementConversationMultiSelectElement <$> fromSlackJSON value
      "conversations_select" -> ElementConversationSelectElement <$> fromSlackJSON value
      "datepicker" -> ElementDatePickerElement <$> fromSlackJSON value
      "datetimepicker" -> ElementDateTimePickerElement <$> fromSlackJSON value
      "email_text_input" -> ElementEmailInputElement <$> fromSlackJSON value
      "multi_external_select" -> ElementExternalMultiSelectElement <$> fromSlackJSON value
      "external_select" -> ElementExternalSelectElement <$> fromSlackJSON value
      "feedback_buttons" -> ElementFeedbackButtonsElement <$> fromSlackJSON value
      "file_input" -> ElementFileInputElement <$> fromSlackJSON value
      "icon_button" -> ElementIconButtonElement <$> fromSlackJSON value
      "image" -> ElementImageElement <$> fromSlackJSON value
      "number_input" -> ElementNumberInputElement <$> fromSlackJSON value
      "overflow" -> ElementOverflowElement <$> fromSlackJSON value
      "plain_text_input" -> ElementPlainTextInputElement <$> fromSlackJSON value
      "radio_buttons" -> ElementRadioButtonsElement <$> fromSlackJSON value
      "rich_text_input" -> ElementRichTextInputElement <$> fromSlackJSON value
      "multi_static_select" -> ElementStaticMultiSelectElement <$> fromSlackJSON value
      "static_select" -> ElementStaticSelectElement <$> fromSlackJSON value
      "timepicker" -> ElementTimePickerElement <$> fromSlackJSON value
      "url_text_input" -> ElementUrlInputElement <$> fromSlackJSON value
      "multi_users_select" -> ElementUserMultiSelectElement <$> fromSlackJSON value
      "users_select" -> ElementUserSelectElement <$> fromSlackJSON value
      "workflow_button" -> ElementWorkflowButtonElement <$> fromSlackJSON value
      _ -> failure TypeMismatch [Field "type"] "role" "unsupported child type"

instance FromJSON Element where parseJSON = checkedParser

-- | Place a checked ButtonElement in the Element role. The receiving parent retains its contextual validation.
buttonElementAsElement :: ButtonElement -> Element
buttonElementAsElement = ElementButtonElement

-- | Return the ButtonElement member when present, otherwise Nothing; no unchecked cast.
matchElementButtonElement :: Element -> Maybe ButtonElement
matchElementButtonElement (ElementButtonElement value) = Just value
matchElementButtonElement _ = Nothing

-- | Place a checked ChannelMultiSelectElement in the Element role. The receiving parent retains its contextual validation.
channelMultiSelectElementAsElement :: ChannelMultiSelectElement -> Element
channelMultiSelectElementAsElement = ElementChannelMultiSelectElement

-- | Return the ChannelMultiSelectElement member when present, otherwise Nothing; no unchecked cast.
matchElementChannelMultiSelectElement :: Element -> Maybe ChannelMultiSelectElement
matchElementChannelMultiSelectElement (ElementChannelMultiSelectElement value) = Just value
matchElementChannelMultiSelectElement _ = Nothing

-- | Place a checked ChannelSelectElement in the Element role. The receiving parent retains its contextual validation.
channelSelectElementAsElement :: ChannelSelectElement -> Element
channelSelectElementAsElement = ElementChannelSelectElement

-- | Return the ChannelSelectElement member when present, otherwise Nothing; no unchecked cast.
matchElementChannelSelectElement :: Element -> Maybe ChannelSelectElement
matchElementChannelSelectElement (ElementChannelSelectElement value) = Just value
matchElementChannelSelectElement _ = Nothing

-- | Place a checked CheckboxesElement in the Element role. The receiving parent retains its contextual validation.
checkboxesElementAsElement :: CheckboxesElement -> Element
checkboxesElementAsElement = ElementCheckboxesElement

-- | Return the CheckboxesElement member when present, otherwise Nothing; no unchecked cast.
matchElementCheckboxesElement :: Element -> Maybe CheckboxesElement
matchElementCheckboxesElement (ElementCheckboxesElement value) = Just value
matchElementCheckboxesElement _ = Nothing

-- | Place a checked ConversationMultiSelectElement in the Element role. The receiving parent retains its contextual validation.
conversationMultiSelectElementAsElement :: ConversationMultiSelectElement -> Element
conversationMultiSelectElementAsElement = ElementConversationMultiSelectElement

-- | Return the ConversationMultiSelectElement member when present, otherwise Nothing; no unchecked cast.
matchElementConversationMultiSelectElement :: Element -> Maybe ConversationMultiSelectElement
matchElementConversationMultiSelectElement (ElementConversationMultiSelectElement value) = Just value
matchElementConversationMultiSelectElement _ = Nothing

-- | Place a checked ConversationSelectElement in the Element role. The receiving parent retains its contextual validation.
conversationSelectElementAsElement :: ConversationSelectElement -> Element
conversationSelectElementAsElement = ElementConversationSelectElement

-- | Return the ConversationSelectElement member when present, otherwise Nothing; no unchecked cast.
matchElementConversationSelectElement :: Element -> Maybe ConversationSelectElement
matchElementConversationSelectElement (ElementConversationSelectElement value) = Just value
matchElementConversationSelectElement _ = Nothing

-- | Place a checked DatePickerElement in the Element role. The receiving parent retains its contextual validation.
datePickerElementAsElement :: DatePickerElement -> Element
datePickerElementAsElement = ElementDatePickerElement

-- | Return the DatePickerElement member when present, otherwise Nothing; no unchecked cast.
matchElementDatePickerElement :: Element -> Maybe DatePickerElement
matchElementDatePickerElement (ElementDatePickerElement value) = Just value
matchElementDatePickerElement _ = Nothing

-- | Place a checked DateTimePickerElement in the Element role. The receiving parent retains its contextual validation.
dateTimePickerElementAsElement :: DateTimePickerElement -> Element
dateTimePickerElementAsElement = ElementDateTimePickerElement

-- | Return the DateTimePickerElement member when present, otherwise Nothing; no unchecked cast.
matchElementDateTimePickerElement :: Element -> Maybe DateTimePickerElement
matchElementDateTimePickerElement (ElementDateTimePickerElement value) = Just value
matchElementDateTimePickerElement _ = Nothing

-- | Place a checked EmailInputElement in the Element role. The receiving parent retains its contextual validation.
emailInputElementAsElement :: EmailInputElement -> Element
emailInputElementAsElement = ElementEmailInputElement

-- | Return the EmailInputElement member when present, otherwise Nothing; no unchecked cast.
matchElementEmailInputElement :: Element -> Maybe EmailInputElement
matchElementEmailInputElement (ElementEmailInputElement value) = Just value
matchElementEmailInputElement _ = Nothing

-- | Place a checked ExternalMultiSelectElement in the Element role. The receiving parent retains its contextual validation.
externalMultiSelectElementAsElement :: ExternalMultiSelectElement -> Element
externalMultiSelectElementAsElement = ElementExternalMultiSelectElement

-- | Return the ExternalMultiSelectElement member when present, otherwise Nothing; no unchecked cast.
matchElementExternalMultiSelectElement :: Element -> Maybe ExternalMultiSelectElement
matchElementExternalMultiSelectElement (ElementExternalMultiSelectElement value) = Just value
matchElementExternalMultiSelectElement _ = Nothing

-- | Place a checked ExternalSelectElement in the Element role. The receiving parent retains its contextual validation.
externalSelectElementAsElement :: ExternalSelectElement -> Element
externalSelectElementAsElement = ElementExternalSelectElement

-- | Return the ExternalSelectElement member when present, otherwise Nothing; no unchecked cast.
matchElementExternalSelectElement :: Element -> Maybe ExternalSelectElement
matchElementExternalSelectElement (ElementExternalSelectElement value) = Just value
matchElementExternalSelectElement _ = Nothing

-- | Place a checked FeedbackButtonsElement in the Element role. The receiving parent retains its contextual validation.
feedbackButtonsElementAsElement :: FeedbackButtonsElement -> Element
feedbackButtonsElementAsElement = ElementFeedbackButtonsElement

-- | Return the FeedbackButtonsElement member when present, otherwise Nothing; no unchecked cast.
matchElementFeedbackButtonsElement :: Element -> Maybe FeedbackButtonsElement
matchElementFeedbackButtonsElement (ElementFeedbackButtonsElement value) = Just value
matchElementFeedbackButtonsElement _ = Nothing

-- | Place a checked FileInputElement in the Element role. The receiving parent retains its contextual validation.
fileInputElementAsElement :: FileInputElement -> Element
fileInputElementAsElement = ElementFileInputElement

-- | Return the FileInputElement member when present, otherwise Nothing; no unchecked cast.
matchElementFileInputElement :: Element -> Maybe FileInputElement
matchElementFileInputElement (ElementFileInputElement value) = Just value
matchElementFileInputElement _ = Nothing

-- | Place a checked IconButtonElement in the Element role. The receiving parent retains its contextual validation.
iconButtonElementAsElement :: IconButtonElement -> Element
iconButtonElementAsElement = ElementIconButtonElement

-- | Return the IconButtonElement member when present, otherwise Nothing; no unchecked cast.
matchElementIconButtonElement :: Element -> Maybe IconButtonElement
matchElementIconButtonElement (ElementIconButtonElement value) = Just value
matchElementIconButtonElement _ = Nothing

-- | Place a checked ImageElement in the Element role. The receiving parent retains its contextual validation.
imageElementAsElement :: ImageElement -> Element
imageElementAsElement = ElementImageElement

-- | Return the ImageElement member when present, otherwise Nothing; no unchecked cast.
matchElementImageElement :: Element -> Maybe ImageElement
matchElementImageElement (ElementImageElement value) = Just value
matchElementImageElement _ = Nothing

-- | Place a checked NumberInputElement in the Element role. The receiving parent retains its contextual validation.
numberInputElementAsElement :: NumberInputElement -> Element
numberInputElementAsElement = ElementNumberInputElement

-- | Return the NumberInputElement member when present, otherwise Nothing; no unchecked cast.
matchElementNumberInputElement :: Element -> Maybe NumberInputElement
matchElementNumberInputElement (ElementNumberInputElement value) = Just value
matchElementNumberInputElement _ = Nothing

-- | Place a checked OverflowElement in the Element role. The receiving parent retains its contextual validation.
overflowElementAsElement :: OverflowElement -> Element
overflowElementAsElement = ElementOverflowElement

-- | Return the OverflowElement member when present, otherwise Nothing; no unchecked cast.
matchElementOverflowElement :: Element -> Maybe OverflowElement
matchElementOverflowElement (ElementOverflowElement value) = Just value
matchElementOverflowElement _ = Nothing

-- | Place a checked PlainTextInputElement in the Element role. The receiving parent retains its contextual validation.
plainTextInputElementAsElement :: PlainTextInputElement -> Element
plainTextInputElementAsElement = ElementPlainTextInputElement

-- | Return the PlainTextInputElement member when present, otherwise Nothing; no unchecked cast.
matchElementPlainTextInputElement :: Element -> Maybe PlainTextInputElement
matchElementPlainTextInputElement (ElementPlainTextInputElement value) = Just value
matchElementPlainTextInputElement _ = Nothing

-- | Place a checked RadioButtonsElement in the Element role. The receiving parent retains its contextual validation.
radioButtonsElementAsElement :: RadioButtonsElement -> Element
radioButtonsElementAsElement = ElementRadioButtonsElement

-- | Return the RadioButtonsElement member when present, otherwise Nothing; no unchecked cast.
matchElementRadioButtonsElement :: Element -> Maybe RadioButtonsElement
matchElementRadioButtonsElement (ElementRadioButtonsElement value) = Just value
matchElementRadioButtonsElement _ = Nothing

-- | Place a checked RichTextInputElement in the Element role. The receiving parent retains its contextual validation.
richTextInputElementAsElement :: RichTextInputElement -> Element
richTextInputElementAsElement = ElementRichTextInputElement

-- | Return the RichTextInputElement member when present, otherwise Nothing; no unchecked cast.
matchElementRichTextInputElement :: Element -> Maybe RichTextInputElement
matchElementRichTextInputElement (ElementRichTextInputElement value) = Just value
matchElementRichTextInputElement _ = Nothing

-- | Place a checked StaticMultiSelectElement in the Element role. The receiving parent retains its contextual validation.
staticMultiSelectElementAsElement :: StaticMultiSelectElement -> Element
staticMultiSelectElementAsElement = ElementStaticMultiSelectElement

-- | Return the StaticMultiSelectElement member when present, otherwise Nothing; no unchecked cast.
matchElementStaticMultiSelectElement :: Element -> Maybe StaticMultiSelectElement
matchElementStaticMultiSelectElement (ElementStaticMultiSelectElement value) = Just value
matchElementStaticMultiSelectElement _ = Nothing

-- | Place a checked StaticSelectElement in the Element role. The receiving parent retains its contextual validation.
staticSelectElementAsElement :: StaticSelectElement -> Element
staticSelectElementAsElement = ElementStaticSelectElement

-- | Return the StaticSelectElement member when present, otherwise Nothing; no unchecked cast.
matchElementStaticSelectElement :: Element -> Maybe StaticSelectElement
matchElementStaticSelectElement (ElementStaticSelectElement value) = Just value
matchElementStaticSelectElement _ = Nothing

-- | Place a checked TimePickerElement in the Element role. The receiving parent retains its contextual validation.
timePickerElementAsElement :: TimePickerElement -> Element
timePickerElementAsElement = ElementTimePickerElement

-- | Return the TimePickerElement member when present, otherwise Nothing; no unchecked cast.
matchElementTimePickerElement :: Element -> Maybe TimePickerElement
matchElementTimePickerElement (ElementTimePickerElement value) = Just value
matchElementTimePickerElement _ = Nothing

-- | Place a checked UrlInputElement in the Element role. The receiving parent retains its contextual validation.
urlInputElementAsElement :: UrlInputElement -> Element
urlInputElementAsElement = ElementUrlInputElement

-- | Return the UrlInputElement member when present, otherwise Nothing; no unchecked cast.
matchElementUrlInputElement :: Element -> Maybe UrlInputElement
matchElementUrlInputElement (ElementUrlInputElement value) = Just value
matchElementUrlInputElement _ = Nothing

-- | Place a checked UserMultiSelectElement in the Element role. The receiving parent retains its contextual validation.
userMultiSelectElementAsElement :: UserMultiSelectElement -> Element
userMultiSelectElementAsElement = ElementUserMultiSelectElement

-- | Return the UserMultiSelectElement member when present, otherwise Nothing; no unchecked cast.
matchElementUserMultiSelectElement :: Element -> Maybe UserMultiSelectElement
matchElementUserMultiSelectElement (ElementUserMultiSelectElement value) = Just value
matchElementUserMultiSelectElement _ = Nothing

-- | Place a checked UserSelectElement in the Element role. The receiving parent retains its contextual validation.
userSelectElementAsElement :: UserSelectElement -> Element
userSelectElementAsElement = ElementUserSelectElement

-- | Return the UserSelectElement member when present, otherwise Nothing; no unchecked cast.
matchElementUserSelectElement :: Element -> Maybe UserSelectElement
matchElementUserSelectElement (ElementUserSelectElement value) = Just value
matchElementUserSelectElement _ = Nothing

-- | Place a checked WorkflowButtonElement in the Element role. The receiving parent retains its contextual validation.
workflowButtonElementAsElement :: WorkflowButtonElement -> Element
workflowButtonElementAsElement = ElementWorkflowButtonElement

-- | Return the WorkflowButtonElement member when present, otherwise Nothing; no unchecked cast.
matchElementWorkflowButtonElement :: Element -> Maybe WorkflowButtonElement
matchElementWorkflowButtonElement (ElementWorkflowButtonElement value) = Just value
matchElementWorkflowButtonElement _ = Nothing

-- | Closed role: only checked members may enter this position.
data InputElement = InputElementChannelMultiSelectElement ChannelMultiSelectElement | InputElementChannelSelectElement ChannelSelectElement | InputElementCheckboxesElement CheckboxesElement | InputElementConversationMultiSelectElement ConversationMultiSelectElement | InputElementConversationSelectElement ConversationSelectElement | InputElementDatePickerElement DatePickerElement | InputElementDateTimePickerElement DateTimePickerElement | InputElementEmailInputElement EmailInputElement | InputElementExternalMultiSelectElement ExternalMultiSelectElement | InputElementExternalSelectElement ExternalSelectElement | InputElementFileInputElement FileInputElement | InputElementNumberInputElement NumberInputElement | InputElementPlainTextInputElement PlainTextInputElement | InputElementRadioButtonsElement RadioButtonsElement | InputElementRichTextInputElement RichTextInputElement | InputElementStaticMultiSelectElement StaticMultiSelectElement | InputElementStaticSelectElement StaticSelectElement | InputElementTimePickerElement TimePickerElement | InputElementUrlInputElement UrlInputElement | InputElementUserMultiSelectElement UserMultiSelectElement | InputElementUserSelectElement UserSelectElement deriving (Eq, Show)

instance ToJSON InputElement where
  toJSON (InputElementChannelMultiSelectElement value) = toJSON value
  toJSON (InputElementChannelSelectElement value) = toJSON value
  toJSON (InputElementCheckboxesElement value) = toJSON value
  toJSON (InputElementConversationMultiSelectElement value) = toJSON value
  toJSON (InputElementConversationSelectElement value) = toJSON value
  toJSON (InputElementDatePickerElement value) = toJSON value
  toJSON (InputElementDateTimePickerElement value) = toJSON value
  toJSON (InputElementEmailInputElement value) = toJSON value
  toJSON (InputElementExternalMultiSelectElement value) = toJSON value
  toJSON (InputElementExternalSelectElement value) = toJSON value
  toJSON (InputElementFileInputElement value) = toJSON value
  toJSON (InputElementNumberInputElement value) = toJSON value
  toJSON (InputElementPlainTextInputElement value) = toJSON value
  toJSON (InputElementRadioButtonsElement value) = toJSON value
  toJSON (InputElementRichTextInputElement value) = toJSON value
  toJSON (InputElementStaticMultiSelectElement value) = toJSON value
  toJSON (InputElementStaticSelectElement value) = toJSON value
  toJSON (InputElementTimePickerElement value) = toJSON value
  toJSON (InputElementUrlInputElement value) = toJSON value
  toJSON (InputElementUserMultiSelectElement value) = toJSON value
  toJSON (InputElementUserSelectElement value) = toJSON value

instance FromSlackJSON InputElement where
  fromSlackJSON value = do
    tag <- wireTag value
    case tag of
      "multi_channels_select" -> InputElementChannelMultiSelectElement <$> fromSlackJSON value
      "channels_select" -> InputElementChannelSelectElement <$> fromSlackJSON value
      "checkboxes" -> InputElementCheckboxesElement <$> fromSlackJSON value
      "multi_conversations_select" -> InputElementConversationMultiSelectElement <$> fromSlackJSON value
      "conversations_select" -> InputElementConversationSelectElement <$> fromSlackJSON value
      "datepicker" -> InputElementDatePickerElement <$> fromSlackJSON value
      "datetimepicker" -> InputElementDateTimePickerElement <$> fromSlackJSON value
      "email_text_input" -> InputElementEmailInputElement <$> fromSlackJSON value
      "multi_external_select" -> InputElementExternalMultiSelectElement <$> fromSlackJSON value
      "external_select" -> InputElementExternalSelectElement <$> fromSlackJSON value
      "file_input" -> InputElementFileInputElement <$> fromSlackJSON value
      "number_input" -> InputElementNumberInputElement <$> fromSlackJSON value
      "plain_text_input" -> InputElementPlainTextInputElement <$> fromSlackJSON value
      "radio_buttons" -> InputElementRadioButtonsElement <$> fromSlackJSON value
      "rich_text_input" -> InputElementRichTextInputElement <$> fromSlackJSON value
      "multi_static_select" -> InputElementStaticMultiSelectElement <$> fromSlackJSON value
      "static_select" -> InputElementStaticSelectElement <$> fromSlackJSON value
      "timepicker" -> InputElementTimePickerElement <$> fromSlackJSON value
      "url_text_input" -> InputElementUrlInputElement <$> fromSlackJSON value
      "multi_users_select" -> InputElementUserMultiSelectElement <$> fromSlackJSON value
      "users_select" -> InputElementUserSelectElement <$> fromSlackJSON value
      _ -> failure TypeMismatch [Field "type"] "role" "unsupported child type"

instance FromJSON InputElement where parseJSON = checkedParser

-- | Place a checked ChannelMultiSelectElement in the InputElement role. The receiving parent retains its contextual validation.
channelMultiSelectElementAsInputElement :: ChannelMultiSelectElement -> InputElement
channelMultiSelectElementAsInputElement = InputElementChannelMultiSelectElement

-- | Return the ChannelMultiSelectElement member when present, otherwise Nothing; no unchecked cast.
matchInputElementChannelMultiSelectElement :: InputElement -> Maybe ChannelMultiSelectElement
matchInputElementChannelMultiSelectElement (InputElementChannelMultiSelectElement value) = Just value
matchInputElementChannelMultiSelectElement _ = Nothing

-- | Place a checked ChannelSelectElement in the InputElement role. The receiving parent retains its contextual validation.
channelSelectElementAsInputElement :: ChannelSelectElement -> InputElement
channelSelectElementAsInputElement = InputElementChannelSelectElement

-- | Return the ChannelSelectElement member when present, otherwise Nothing; no unchecked cast.
matchInputElementChannelSelectElement :: InputElement -> Maybe ChannelSelectElement
matchInputElementChannelSelectElement (InputElementChannelSelectElement value) = Just value
matchInputElementChannelSelectElement _ = Nothing

-- | Place a checked CheckboxesElement in the InputElement role. The receiving parent retains its contextual validation.
checkboxesElementAsInputElement :: CheckboxesElement -> InputElement
checkboxesElementAsInputElement = InputElementCheckboxesElement

-- | Return the CheckboxesElement member when present, otherwise Nothing; no unchecked cast.
matchInputElementCheckboxesElement :: InputElement -> Maybe CheckboxesElement
matchInputElementCheckboxesElement (InputElementCheckboxesElement value) = Just value
matchInputElementCheckboxesElement _ = Nothing

-- | Place a checked ConversationMultiSelectElement in the InputElement role. The receiving parent retains its contextual validation.
conversationMultiSelectElementAsInputElement :: ConversationMultiSelectElement -> InputElement
conversationMultiSelectElementAsInputElement = InputElementConversationMultiSelectElement

-- | Return the ConversationMultiSelectElement member when present, otherwise Nothing; no unchecked cast.
matchInputElementConversationMultiSelectElement :: InputElement -> Maybe ConversationMultiSelectElement
matchInputElementConversationMultiSelectElement (InputElementConversationMultiSelectElement value) = Just value
matchInputElementConversationMultiSelectElement _ = Nothing

-- | Place a checked ConversationSelectElement in the InputElement role. The receiving parent retains its contextual validation.
conversationSelectElementAsInputElement :: ConversationSelectElement -> InputElement
conversationSelectElementAsInputElement = InputElementConversationSelectElement

-- | Return the ConversationSelectElement member when present, otherwise Nothing; no unchecked cast.
matchInputElementConversationSelectElement :: InputElement -> Maybe ConversationSelectElement
matchInputElementConversationSelectElement (InputElementConversationSelectElement value) = Just value
matchInputElementConversationSelectElement _ = Nothing

-- | Place a checked DatePickerElement in the InputElement role. The receiving parent retains its contextual validation.
datePickerElementAsInputElement :: DatePickerElement -> InputElement
datePickerElementAsInputElement = InputElementDatePickerElement

-- | Return the DatePickerElement member when present, otherwise Nothing; no unchecked cast.
matchInputElementDatePickerElement :: InputElement -> Maybe DatePickerElement
matchInputElementDatePickerElement (InputElementDatePickerElement value) = Just value
matchInputElementDatePickerElement _ = Nothing

-- | Place a checked DateTimePickerElement in the InputElement role. The receiving parent retains its contextual validation.
dateTimePickerElementAsInputElement :: DateTimePickerElement -> InputElement
dateTimePickerElementAsInputElement = InputElementDateTimePickerElement

-- | Return the DateTimePickerElement member when present, otherwise Nothing; no unchecked cast.
matchInputElementDateTimePickerElement :: InputElement -> Maybe DateTimePickerElement
matchInputElementDateTimePickerElement (InputElementDateTimePickerElement value) = Just value
matchInputElementDateTimePickerElement _ = Nothing

-- | Place a checked EmailInputElement in the InputElement role. The receiving parent retains its contextual validation.
emailInputElementAsInputElement :: EmailInputElement -> InputElement
emailInputElementAsInputElement = InputElementEmailInputElement

-- | Return the EmailInputElement member when present, otherwise Nothing; no unchecked cast.
matchInputElementEmailInputElement :: InputElement -> Maybe EmailInputElement
matchInputElementEmailInputElement (InputElementEmailInputElement value) = Just value
matchInputElementEmailInputElement _ = Nothing

-- | Place a checked ExternalMultiSelectElement in the InputElement role. The receiving parent retains its contextual validation.
externalMultiSelectElementAsInputElement :: ExternalMultiSelectElement -> InputElement
externalMultiSelectElementAsInputElement = InputElementExternalMultiSelectElement

-- | Return the ExternalMultiSelectElement member when present, otherwise Nothing; no unchecked cast.
matchInputElementExternalMultiSelectElement :: InputElement -> Maybe ExternalMultiSelectElement
matchInputElementExternalMultiSelectElement (InputElementExternalMultiSelectElement value) = Just value
matchInputElementExternalMultiSelectElement _ = Nothing

-- | Place a checked ExternalSelectElement in the InputElement role. The receiving parent retains its contextual validation.
externalSelectElementAsInputElement :: ExternalSelectElement -> InputElement
externalSelectElementAsInputElement = InputElementExternalSelectElement

-- | Return the ExternalSelectElement member when present, otherwise Nothing; no unchecked cast.
matchInputElementExternalSelectElement :: InputElement -> Maybe ExternalSelectElement
matchInputElementExternalSelectElement (InputElementExternalSelectElement value) = Just value
matchInputElementExternalSelectElement _ = Nothing

-- | Place a checked FileInputElement in the InputElement role. The receiving parent retains its contextual validation.
fileInputElementAsInputElement :: FileInputElement -> InputElement
fileInputElementAsInputElement = InputElementFileInputElement

-- | Return the FileInputElement member when present, otherwise Nothing; no unchecked cast.
matchInputElementFileInputElement :: InputElement -> Maybe FileInputElement
matchInputElementFileInputElement (InputElementFileInputElement value) = Just value
matchInputElementFileInputElement _ = Nothing

-- | Place a checked NumberInputElement in the InputElement role. The receiving parent retains its contextual validation.
numberInputElementAsInputElement :: NumberInputElement -> InputElement
numberInputElementAsInputElement = InputElementNumberInputElement

-- | Return the NumberInputElement member when present, otherwise Nothing; no unchecked cast.
matchInputElementNumberInputElement :: InputElement -> Maybe NumberInputElement
matchInputElementNumberInputElement (InputElementNumberInputElement value) = Just value
matchInputElementNumberInputElement _ = Nothing

-- | Place a checked PlainTextInputElement in the InputElement role. The receiving parent retains its contextual validation.
plainTextInputElementAsInputElement :: PlainTextInputElement -> InputElement
plainTextInputElementAsInputElement = InputElementPlainTextInputElement

-- | Return the PlainTextInputElement member when present, otherwise Nothing; no unchecked cast.
matchInputElementPlainTextInputElement :: InputElement -> Maybe PlainTextInputElement
matchInputElementPlainTextInputElement (InputElementPlainTextInputElement value) = Just value
matchInputElementPlainTextInputElement _ = Nothing

-- | Place a checked RadioButtonsElement in the InputElement role. The receiving parent retains its contextual validation.
radioButtonsElementAsInputElement :: RadioButtonsElement -> InputElement
radioButtonsElementAsInputElement = InputElementRadioButtonsElement

-- | Return the RadioButtonsElement member when present, otherwise Nothing; no unchecked cast.
matchInputElementRadioButtonsElement :: InputElement -> Maybe RadioButtonsElement
matchInputElementRadioButtonsElement (InputElementRadioButtonsElement value) = Just value
matchInputElementRadioButtonsElement _ = Nothing

-- | Place a checked RichTextInputElement in the InputElement role. The receiving parent retains its contextual validation.
richTextInputElementAsInputElement :: RichTextInputElement -> InputElement
richTextInputElementAsInputElement = InputElementRichTextInputElement

-- | Return the RichTextInputElement member when present, otherwise Nothing; no unchecked cast.
matchInputElementRichTextInputElement :: InputElement -> Maybe RichTextInputElement
matchInputElementRichTextInputElement (InputElementRichTextInputElement value) = Just value
matchInputElementRichTextInputElement _ = Nothing

-- | Place a checked StaticMultiSelectElement in the InputElement role. The receiving parent retains its contextual validation.
staticMultiSelectElementAsInputElement :: StaticMultiSelectElement -> InputElement
staticMultiSelectElementAsInputElement = InputElementStaticMultiSelectElement

-- | Return the StaticMultiSelectElement member when present, otherwise Nothing; no unchecked cast.
matchInputElementStaticMultiSelectElement :: InputElement -> Maybe StaticMultiSelectElement
matchInputElementStaticMultiSelectElement (InputElementStaticMultiSelectElement value) = Just value
matchInputElementStaticMultiSelectElement _ = Nothing

-- | Place a checked StaticSelectElement in the InputElement role. The receiving parent retains its contextual validation.
staticSelectElementAsInputElement :: StaticSelectElement -> InputElement
staticSelectElementAsInputElement = InputElementStaticSelectElement

-- | Return the StaticSelectElement member when present, otherwise Nothing; no unchecked cast.
matchInputElementStaticSelectElement :: InputElement -> Maybe StaticSelectElement
matchInputElementStaticSelectElement (InputElementStaticSelectElement value) = Just value
matchInputElementStaticSelectElement _ = Nothing

-- | Place a checked TimePickerElement in the InputElement role. The receiving parent retains its contextual validation.
timePickerElementAsInputElement :: TimePickerElement -> InputElement
timePickerElementAsInputElement = InputElementTimePickerElement

-- | Return the TimePickerElement member when present, otherwise Nothing; no unchecked cast.
matchInputElementTimePickerElement :: InputElement -> Maybe TimePickerElement
matchInputElementTimePickerElement (InputElementTimePickerElement value) = Just value
matchInputElementTimePickerElement _ = Nothing

-- | Place a checked UrlInputElement in the InputElement role. The receiving parent retains its contextual validation.
urlInputElementAsInputElement :: UrlInputElement -> InputElement
urlInputElementAsInputElement = InputElementUrlInputElement

-- | Return the UrlInputElement member when present, otherwise Nothing; no unchecked cast.
matchInputElementUrlInputElement :: InputElement -> Maybe UrlInputElement
matchInputElementUrlInputElement (InputElementUrlInputElement value) = Just value
matchInputElementUrlInputElement _ = Nothing

-- | Place a checked UserMultiSelectElement in the InputElement role. The receiving parent retains its contextual validation.
userMultiSelectElementAsInputElement :: UserMultiSelectElement -> InputElement
userMultiSelectElementAsInputElement = InputElementUserMultiSelectElement

-- | Return the UserMultiSelectElement member when present, otherwise Nothing; no unchecked cast.
matchInputElementUserMultiSelectElement :: InputElement -> Maybe UserMultiSelectElement
matchInputElementUserMultiSelectElement (InputElementUserMultiSelectElement value) = Just value
matchInputElementUserMultiSelectElement _ = Nothing

-- | Place a checked UserSelectElement in the InputElement role. The receiving parent retains its contextual validation.
userSelectElementAsInputElement :: UserSelectElement -> InputElement
userSelectElementAsInputElement = InputElementUserSelectElement

-- | Return the UserSelectElement member when present, otherwise Nothing; no unchecked cast.
matchInputElementUserSelectElement :: InputElement -> Maybe UserSelectElement
matchInputElementUserSelectElement (InputElementUserSelectElement value) = Just value
matchInputElementUserSelectElement _ = Nothing

-- | Closed role: only checked members may enter this position.
data TextObject = TextObjectMarkdownText MarkdownText | TextObjectPlainText PlainText deriving (Eq, Show)

instance ToJSON TextObject where
  toJSON (TextObjectMarkdownText value) = toJSON value
  toJSON (TextObjectPlainText value) = toJSON value

instance FromSlackJSON TextObject where
  fromSlackJSON value = do
    tag <- wireTag value
    case tag of
      "mrkdwn" -> TextObjectMarkdownText <$> fromSlackJSON value
      "plain_text" -> TextObjectPlainText <$> fromSlackJSON value
      _ -> failure TypeMismatch [Field "type"] "role" "unsupported child type"

instance FromJSON TextObject where parseJSON = checkedParser

-- | Place a checked MarkdownText in the TextObject role. The receiving parent retains its contextual validation.
markdownTextAsText :: MarkdownText -> TextObject
markdownTextAsText = TextObjectMarkdownText

-- | Return the MarkdownText member when present, otherwise Nothing; no unchecked cast.
matchTextObjectMarkdownText :: TextObject -> Maybe MarkdownText
matchTextObjectMarkdownText (TextObjectMarkdownText value) = Just value
matchTextObjectMarkdownText _ = Nothing

-- | Place a checked PlainText in the TextObject role. The receiving parent retains its contextual validation.
plainTextAsText :: PlainText -> TextObject
plainTextAsText = TextObjectPlainText

-- | Return the PlainText member when present, otherwise Nothing; no unchecked cast.
matchTextObjectPlainText :: TextObject -> Maybe PlainText
matchTextObjectPlainText (TextObjectPlainText value) = Just value
matchTextObjectPlainText _ = Nothing

-- | Closed role: only checked members may enter this position.
data Chart = ChartAreaChart AreaChart | ChartBarChart BarChart | ChartLineChart LineChart | ChartPieChart PieChart deriving (Eq, Show)

instance ToJSON Chart where
  toJSON (ChartAreaChart value) = toJSON value
  toJSON (ChartBarChart value) = toJSON value
  toJSON (ChartLineChart value) = toJSON value
  toJSON (ChartPieChart value) = toJSON value

instance FromSlackJSON Chart where
  fromSlackJSON value = do
    tag <- wireTag value
    case tag of
      "area" -> ChartAreaChart <$> fromSlackJSON value
      "bar" -> ChartBarChart <$> fromSlackJSON value
      "line" -> ChartLineChart <$> fromSlackJSON value
      "pie" -> ChartPieChart <$> fromSlackJSON value
      _ -> failure TypeMismatch [Field "type"] "role" "unsupported child type"

instance FromJSON Chart where parseJSON = checkedParser

-- | Place a checked AreaChart in the Chart role. The receiving parent retains its contextual validation.
areaChartAsChart :: AreaChart -> Chart
areaChartAsChart = ChartAreaChart

-- | Return the AreaChart member when present, otherwise Nothing; no unchecked cast.
matchChartAreaChart :: Chart -> Maybe AreaChart
matchChartAreaChart (ChartAreaChart value) = Just value
matchChartAreaChart _ = Nothing

-- | Place a checked BarChart in the Chart role. The receiving parent retains its contextual validation.
barChartAsChart :: BarChart -> Chart
barChartAsChart = ChartBarChart

-- | Return the BarChart member when present, otherwise Nothing; no unchecked cast.
matchChartBarChart :: Chart -> Maybe BarChart
matchChartBarChart (ChartBarChart value) = Just value
matchChartBarChart _ = Nothing

-- | Place a checked LineChart in the Chart role. The receiving parent retains its contextual validation.
lineChartAsChart :: LineChart -> Chart
lineChartAsChart = ChartLineChart

-- | Return the LineChart member when present, otherwise Nothing; no unchecked cast.
matchChartLineChart :: Chart -> Maybe LineChart
matchChartLineChart (ChartLineChart value) = Just value
matchChartLineChart _ = Nothing

-- | Place a checked PieChart in the Chart role. The receiving parent retains its contextual validation.
pieChartAsChart :: PieChart -> Chart
pieChartAsChart = ChartPieChart

-- | Return the PieChart member when present, otherwise Nothing; no unchecked cast.
matchChartPieChart :: Chart -> Maybe PieChart
matchChartPieChart (ChartPieChart value) = Just value
matchChartPieChart _ = Nothing

-- | Closed role: only checked members may enter this position.
data RichTextBlockElement = RichTextBlockElementRichTextCodeBlock RichTextCodeBlock | RichTextBlockElementRichTextList RichTextList | RichTextBlockElementRichTextQuote RichTextQuote | RichTextBlockElementRichTextSection RichTextSection deriving (Eq, Show)

instance ToJSON RichTextBlockElement where
  toJSON (RichTextBlockElementRichTextCodeBlock value) = toJSON value
  toJSON (RichTextBlockElementRichTextList value) = toJSON value
  toJSON (RichTextBlockElementRichTextQuote value) = toJSON value
  toJSON (RichTextBlockElementRichTextSection value) = toJSON value

instance FromSlackJSON RichTextBlockElement where
  fromSlackJSON value = do
    tag <- wireTag value
    case tag of
      "rich_text_preformatted" -> RichTextBlockElementRichTextCodeBlock <$> fromSlackJSON value
      "rich_text_list" -> RichTextBlockElementRichTextList <$> fromSlackJSON value
      "rich_text_quote" -> RichTextBlockElementRichTextQuote <$> fromSlackJSON value
      "rich_text_section" -> RichTextBlockElementRichTextSection <$> fromSlackJSON value
      _ -> failure TypeMismatch [Field "type"] "role" "unsupported child type"

instance FromJSON RichTextBlockElement where parseJSON = checkedParser

-- | Place a checked RichTextCodeBlock in the RichTextBlockElement role. The receiving parent retains its contextual validation.
richTextCodeBlockAsRichTextBlockElement :: RichTextCodeBlock -> RichTextBlockElement
richTextCodeBlockAsRichTextBlockElement = RichTextBlockElementRichTextCodeBlock

-- | Return the RichTextCodeBlock member when present, otherwise Nothing; no unchecked cast.
matchRichTextBlockElementRichTextCodeBlock :: RichTextBlockElement -> Maybe RichTextCodeBlock
matchRichTextBlockElementRichTextCodeBlock (RichTextBlockElementRichTextCodeBlock value) = Just value
matchRichTextBlockElementRichTextCodeBlock _ = Nothing

-- | Place a checked RichTextList in the RichTextBlockElement role. The receiving parent retains its contextual validation.
richTextListAsRichTextBlockElement :: RichTextList -> RichTextBlockElement
richTextListAsRichTextBlockElement = RichTextBlockElementRichTextList

-- | Return the RichTextList member when present, otherwise Nothing; no unchecked cast.
matchRichTextBlockElementRichTextList :: RichTextBlockElement -> Maybe RichTextList
matchRichTextBlockElementRichTextList (RichTextBlockElementRichTextList value) = Just value
matchRichTextBlockElementRichTextList _ = Nothing

-- | Place a checked RichTextQuote in the RichTextBlockElement role. The receiving parent retains its contextual validation.
richTextQuoteAsRichTextBlockElement :: RichTextQuote -> RichTextBlockElement
richTextQuoteAsRichTextBlockElement = RichTextBlockElementRichTextQuote

-- | Return the RichTextQuote member when present, otherwise Nothing; no unchecked cast.
matchRichTextBlockElementRichTextQuote :: RichTextBlockElement -> Maybe RichTextQuote
matchRichTextBlockElementRichTextQuote (RichTextBlockElementRichTextQuote value) = Just value
matchRichTextBlockElementRichTextQuote _ = Nothing

-- | Place a checked RichTextSection in the RichTextBlockElement role. The receiving parent retains its contextual validation.
richTextSectionAsRichTextBlockElement :: RichTextSection -> RichTextBlockElement
richTextSectionAsRichTextBlockElement = RichTextBlockElementRichTextSection

-- | Return the RichTextSection member when present, otherwise Nothing; no unchecked cast.
matchRichTextBlockElementRichTextSection :: RichTextBlockElement -> Maybe RichTextSection
matchRichTextBlockElementRichTextSection (RichTextBlockElementRichTextSection value) = Just value
matchRichTextBlockElementRichTextSection _ = Nothing

-- | Closed role: only checked members may enter this position.
data RichTextSectionElement = RichTextSectionElementRichTextChannel RichTextChannel | RichTextSectionElementRichTextEmoji RichTextEmoji | RichTextSectionElementRichTextLink RichTextLink | RichTextSectionElementRichTextText RichTextText | RichTextSectionElementRichTextUser RichTextUser | RichTextSectionElementRichTextUserGroup RichTextUserGroup deriving (Eq, Show)

instance ToJSON RichTextSectionElement where
  toJSON (RichTextSectionElementRichTextChannel value) = toJSON value
  toJSON (RichTextSectionElementRichTextEmoji value) = toJSON value
  toJSON (RichTextSectionElementRichTextLink value) = toJSON value
  toJSON (RichTextSectionElementRichTextText value) = toJSON value
  toJSON (RichTextSectionElementRichTextUser value) = toJSON value
  toJSON (RichTextSectionElementRichTextUserGroup value) = toJSON value

instance FromSlackJSON RichTextSectionElement where
  fromSlackJSON value = do
    tag <- wireTag value
    case tag of
      "channel" -> RichTextSectionElementRichTextChannel <$> fromSlackJSON value
      "emoji" -> RichTextSectionElementRichTextEmoji <$> fromSlackJSON value
      "link" -> RichTextSectionElementRichTextLink <$> fromSlackJSON value
      "text" -> RichTextSectionElementRichTextText <$> fromSlackJSON value
      "user" -> RichTextSectionElementRichTextUser <$> fromSlackJSON value
      "usergroup" -> RichTextSectionElementRichTextUserGroup <$> fromSlackJSON value
      _ -> failure TypeMismatch [Field "type"] "role" "unsupported child type"

instance FromJSON RichTextSectionElement where parseJSON = checkedParser

-- | Place a checked RichTextChannel in the RichTextSectionElement role. The receiving parent retains its contextual validation.
richTextChannelAsRichTextSectionElement :: RichTextChannel -> RichTextSectionElement
richTextChannelAsRichTextSectionElement = RichTextSectionElementRichTextChannel

-- | Return the RichTextChannel member when present, otherwise Nothing; no unchecked cast.
matchRichTextSectionElementRichTextChannel :: RichTextSectionElement -> Maybe RichTextChannel
matchRichTextSectionElementRichTextChannel (RichTextSectionElementRichTextChannel value) = Just value
matchRichTextSectionElementRichTextChannel _ = Nothing

-- | Place a checked RichTextEmoji in the RichTextSectionElement role. The receiving parent retains its contextual validation.
richTextEmojiAsRichTextSectionElement :: RichTextEmoji -> RichTextSectionElement
richTextEmojiAsRichTextSectionElement = RichTextSectionElementRichTextEmoji

-- | Return the RichTextEmoji member when present, otherwise Nothing; no unchecked cast.
matchRichTextSectionElementRichTextEmoji :: RichTextSectionElement -> Maybe RichTextEmoji
matchRichTextSectionElementRichTextEmoji (RichTextSectionElementRichTextEmoji value) = Just value
matchRichTextSectionElementRichTextEmoji _ = Nothing

-- | Place a checked RichTextLink in the RichTextSectionElement role. The receiving parent retains its contextual validation.
richTextLinkAsRichTextSectionElement :: RichTextLink -> RichTextSectionElement
richTextLinkAsRichTextSectionElement = RichTextSectionElementRichTextLink

-- | Return the RichTextLink member when present, otherwise Nothing; no unchecked cast.
matchRichTextSectionElementRichTextLink :: RichTextSectionElement -> Maybe RichTextLink
matchRichTextSectionElementRichTextLink (RichTextSectionElementRichTextLink value) = Just value
matchRichTextSectionElementRichTextLink _ = Nothing

-- | Place a checked RichTextText in the RichTextSectionElement role. The receiving parent retains its contextual validation.
richTextTextAsRichTextSectionElement :: RichTextText -> RichTextSectionElement
richTextTextAsRichTextSectionElement = RichTextSectionElementRichTextText

-- | Return the RichTextText member when present, otherwise Nothing; no unchecked cast.
matchRichTextSectionElementRichTextText :: RichTextSectionElement -> Maybe RichTextText
matchRichTextSectionElementRichTextText (RichTextSectionElementRichTextText value) = Just value
matchRichTextSectionElementRichTextText _ = Nothing

-- | Place a checked RichTextUser in the RichTextSectionElement role. The receiving parent retains its contextual validation.
richTextUserAsRichTextSectionElement :: RichTextUser -> RichTextSectionElement
richTextUserAsRichTextSectionElement = RichTextSectionElementRichTextUser

-- | Return the RichTextUser member when present, otherwise Nothing; no unchecked cast.
matchRichTextSectionElementRichTextUser :: RichTextSectionElement -> Maybe RichTextUser
matchRichTextSectionElementRichTextUser (RichTextSectionElementRichTextUser value) = Just value
matchRichTextSectionElementRichTextUser _ = Nothing

-- | Place a checked RichTextUserGroup in the RichTextSectionElement role. The receiving parent retains its contextual validation.
richTextUserGroupAsRichTextSectionElement :: RichTextUserGroup -> RichTextSectionElement
richTextUserGroupAsRichTextSectionElement = RichTextSectionElementRichTextUserGroup

-- | Return the RichTextUserGroup member when present, otherwise Nothing; no unchecked cast.
matchRichTextSectionElementRichTextUserGroup :: RichTextSectionElement -> Maybe RichTextUserGroup
matchRichTextSectionElementRichTextUserGroup (RichTextSectionElementRichTextUserGroup value) = Just value
matchRichTextSectionElementRichTextUserGroup _ = Nothing