slackblocks 3.1.0 → 3.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/lib/slackblocks/generated/limits.rb +1 -1
- data/lib/slackblocks/generated/models.rb +77 -0
- data/lib/slackblocks/generated/vocabulary.rb +1 -1
- data/lib/slackblocks/validator.rb +47 -3
- data/lib/slackblocks/version.rb +2 -2
- data/sig/slackblocks/generated.rbs +84 -0
- data/sig/slackblocks.rbs +4 -0
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 827536ece4c547f433c37b5ea250d8df94e5cc1455675c5c6535bfc43a662f0f
|
|
4
|
+
data.tar.gz: 5a070516e5d8948924d79dd08d779678f3ae7d4af2dbbda540d9e0332df5e44c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: fcb284a50cc685907415660a3308f4b7107f086d45dc523fd56c93ea996ae1605f9e8dd853b63cbcbfbdefa257e9af5019e0bd59a4f2c2a5bb8143c9f8a34283
|
|
7
|
+
data.tar.gz: 6fbaaae9df8455182841fa8102310f44e9d377fa48dd2c6218a963764033f1a57026af29142ca05544ae1fbfda802a6631a05153b31b23cd2e3b61c738d5fbce
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [3.2.0] — 2026-10-31
|
|
4
|
+
|
|
5
|
+
- Add native layout blocks, rows and items with typed widths/alignment, closed child and fallback roles, checked nesting and receiving-surface validation (spec 1.5.0).
|
|
6
|
+
- Preserve confirmed top-level message/view block counting, supported runtime minimums, legacy container-only behavior, and existing chart/text limits. No unconfirmed recursive block budget is imposed.
|
|
7
|
+
- Add a runnable ten-language layout recipe and rendered preview; preserve outgoing 3.1.0 documentation.
|
|
8
|
+
|
|
3
9
|
## [3.1.0] — 2026-10-28
|
|
4
10
|
|
|
5
11
|
- Coordinate this release with the new Haskell implementation and ten-language documentation. Existing runtime support remains unchanged.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Generated from spec/limits.json. Do not edit by hand.
|
|
2
2
|
module Slackblocks
|
|
3
3
|
module Limits
|
|
4
|
-
VALUES = {"action_id.max_length" => 255, "actions.elements.max_items" => 25, "alert.text.max_length" => 200, "block_id.max_length" => 255, "button.accessibility_label.max_length" => 75, "button.agent_prompt.max_length" => 4000, "button.text.max_length" => 75, "button.url.max_length" => 3000, "button.value.max_length" => 2000, "card.actions.max_items" => 3, "card.body.max_length" => 200, "card.subtext.max_length" => 200, "card.subtitle.max_length" => 150, "card.title.max_length" => 150, "carousel.elements.max_items" => 10, "carousel.elements.min_items" => 1, "checkboxes.options.max_items" => 10, "checkboxes.options.min_items" => 1, "confirmation.confirm.max_length" => 30, "confirmation.deny.max_length" => 30, "confirmation.text.max_length" => 300, "confirmation.title.max_length" => 100, "container.child_blocks.max_items" => 10, "container.child_blocks.min_items" => 1, "container.subtitle.max_length" => 150, "container.title.max_length" => 150, "context.elements.max_items" => 10, "context_actions.elements.max_items" => 5, "conversation_filter.include.min_items" => 1, "data_table.cell_text.min_length" => 1, "data_table.columns.max_items" => 20, "data_table.columns.min_items" => 1, "data_table.content.max_length" => 20000, "data_table.page_size.max" => 100, "data_table.page_size.min" => 1, "data_table.row_header_column_index.min" => 0, "data_table.rows.max_items" => 201, "data_table.rows.min_items" => 2, "data_table.total_content.max_length" => 20000, "data_visualization.axis_label.max_length" => 50, "data_visualization.categories.max_items" => 20, "data_visualization.categories.min_items" => 1, "data_visualization.category_label.max_length" => 20, "data_visualization.data.max_items" => 20, "data_visualization.data.min_items" => 1, "data_visualization.point_label.max_length" => 20, "data_visualization.segment.label.max_length" => 20, "data_visualization.segment.value.exclusive_min" => 0, "data_visualization.segments.max_items" => 12, "data_visualization.segments.min_items" => 1, "data_visualization.series.max_items" => 12, "data_visualization.series.min_items" => 1, "data_visualization.series_name.max_length" => 20, "data_visualization.title.max_length" => 50, "date_picker.placeholder.max_length" => 150, "dispatch_action_configuration.trigger_actions_on.max_items" => 2, "dispatch_action_configuration.trigger_actions_on.min_items" => 1, "email_input.placeholder.max_length" => 150, "feedback_button.accessibility_label.max_length" => 75, "feedback_button.text.max_length" => 75, "feedback_button.value.max_length" => 2000, "file_input.max_files.max" => 10, "file_input.max_files.min" => 1, "header.text.max_length" => 150, "icon_button.accessibility_label.max_length" => 75, "icon_button.value.max_length" => 2000, "icon_button.visible_to_user_ids.max_items" => 10, "image.alt_text.max_length" => 2000, "image.image_url.max_length" => 3000, "image.title.max_length" => 2000, "image_element.alt_text.max_length" => 2000, "image_element.image_url.max_length" => 3000, "input.hint.max_length" => 2000, "input.label.max_length" => 2000, "markdown.text.max_length" => 12000, "markdown.total_text.max_length" => 12000, "message.attachments.max_items" => 100, "message.blocks.max_items" => 50, "message.channel.min_length" => 1, "message.data_visualizations.max_items" => 2, "multi_select.max_selected_items.min" => 1, "number_input.placeholder.max_length" => 150, "option.description.max_length" => 75, "option.text.max_length" => 75, "option.url.max_length" => 3000, "option.value.max_length" => 150, "option_group.label.max_length" => 75, "option_group.options.max_items" => 100, "option_group.options.min_items" => 1, "overflow.options.max_items" => 5, "overflow.options.min_items" => 1, "plain_text_input.max_length.max" => 3000, "plain_text_input.max_length.min" => 1, "plain_text_input.min_length.max" => 3000, "plain_text_input.min_length.min" => 0, "plain_text_input.placeholder.max_length" => 150, "plan.tasks.max_items" => 50, "radio_buttons.options.max_items" => 10, "radio_buttons.options.min_items" => 1, "rich_text_input.max_lines.max" => 100, "rich_text_input.max_lines.min" => 1, "rich_text_input.min_lines.max" => 100, "rich_text_input.min_lines.min" => 1, "rich_text_input.placeholder.max_length" => 150, "rich_text_list.border.max" => 1, "rich_text_list.border.min" => 0, "rich_text_list.indent.max" => 8, "rich_text_list.indent.min" => 0, "rich_text_list.offset.min" => 0, "rich_text_preformatted.border.max" => 1, "rich_text_preformatted.border.min" => 0, "rich_text_quote.border.max" => 1, "rich_text_quote.border.min" => 0, "section.fields.item_max_length" => 2000, "section.fields.max_items" => 10, "section.text.max_length" => 3000, "select.min_query_length.min" => 0, "select.option_groups.max_items" => 100, "select.option_groups.min_items" => 1, "select.options.max_items" => 100, "select.options.min_items" => 1, "select.placeholder.max_length" => 150, "table.column_settings.max_items" => 20, "table.columns.max_items" => 20, "table.rows.max_items" => 100, "text.max_length" => 3000, "text.min_length" => 1, "time_picker.placeholder.max_length" => 150, "url_input.placeholder.max_length" => 150, "video.alt_text.max_length" => 2000, "video.author_name.max_length" => 50, "video.description.max_length" => 200, "video.provider_icon_url.max_length" => 2000, "video.provider_name.max_length" => 50, "video.thumbnail_url.max_length" => 3000, "video.title.max_length" => 200, "video.title_url.max_length" => 2000, "video.video_url.max_length" => 3000, "view.blocks.max_items" => 100, "view.callback_id.max_length" => 255, "view.close.max_length" => 24, "view.external_id.max_length" => 255, "view.private_metadata.max_length" => 3000, "view.submit.max_length" => 24, "view.title.max_length" => 24, "workflow_button.accessibility_label.max_length" => 75, "workflow_button.text.max_length" => 75}.freeze
|
|
4
|
+
VALUES = {"action_id.max_length" => 255, "actions.elements.max_items" => 25, "alert.text.max_length" => 200, "block_id.max_length" => 255, "button.accessibility_label.max_length" => 75, "button.agent_prompt.max_length" => 4000, "button.text.max_length" => 75, "button.url.max_length" => 3000, "button.value.max_length" => 2000, "card.actions.max_items" => 3, "card.body.max_length" => 200, "card.subtext.max_length" => 200, "card.subtitle.max_length" => 150, "card.title.max_length" => 150, "carousel.elements.max_items" => 10, "carousel.elements.min_items" => 1, "checkboxes.options.max_items" => 10, "checkboxes.options.min_items" => 1, "confirmation.confirm.max_length" => 30, "confirmation.deny.max_length" => 30, "confirmation.text.max_length" => 300, "confirmation.title.max_length" => 100, "container.child_blocks.max_items" => 10, "container.child_blocks.min_items" => 1, "container.subtitle.max_length" => 150, "container.title.max_length" => 150, "context.elements.max_items" => 10, "context_actions.elements.max_items" => 5, "conversation_filter.include.min_items" => 1, "data_table.cell_text.min_length" => 1, "data_table.columns.max_items" => 20, "data_table.columns.min_items" => 1, "data_table.content.max_length" => 20000, "data_table.page_size.max" => 100, "data_table.page_size.min" => 1, "data_table.row_header_column_index.min" => 0, "data_table.rows.max_items" => 201, "data_table.rows.min_items" => 2, "data_table.total_content.max_length" => 20000, "data_visualization.axis_label.max_length" => 50, "data_visualization.categories.max_items" => 20, "data_visualization.categories.min_items" => 1, "data_visualization.category_label.max_length" => 20, "data_visualization.data.max_items" => 20, "data_visualization.data.min_items" => 1, "data_visualization.point_label.max_length" => 20, "data_visualization.segment.label.max_length" => 20, "data_visualization.segment.value.exclusive_min" => 0, "data_visualization.segments.max_items" => 12, "data_visualization.segments.min_items" => 1, "data_visualization.series.max_items" => 12, "data_visualization.series.min_items" => 1, "data_visualization.series_name.max_length" => 20, "data_visualization.title.max_length" => 50, "date_picker.placeholder.max_length" => 150, "dispatch_action_configuration.trigger_actions_on.max_items" => 2, "dispatch_action_configuration.trigger_actions_on.min_items" => 1, "email_input.placeholder.max_length" => 150, "feedback_button.accessibility_label.max_length" => 75, "feedback_button.text.max_length" => 75, "feedback_button.value.max_length" => 2000, "file_input.max_files.max" => 10, "file_input.max_files.min" => 1, "header.text.max_length" => 150, "icon_button.accessibility_label.max_length" => 75, "icon_button.value.max_length" => 2000, "icon_button.visible_to_user_ids.max_items" => 10, "image.alt_text.max_length" => 2000, "image.image_url.max_length" => 3000, "image.title.max_length" => 2000, "image_element.alt_text.max_length" => 2000, "image_element.image_url.max_length" => 3000, "input.hint.max_length" => 2000, "input.label.max_length" => 2000, "layout.items.max_items" => 3, "layout.items.min_items" => 1, "layout.label.max_length" => 150, "layout.label.min_length" => 1, "layout.rows.max_items" => 5, "layout.rows.min_items" => 1, "markdown.text.max_length" => 12000, "markdown.total_text.max_length" => 12000, "message.attachments.max_items" => 100, "message.blocks.max_items" => 50, "message.channel.min_length" => 1, "message.data_visualizations.max_items" => 2, "multi_select.max_selected_items.min" => 1, "number_input.placeholder.max_length" => 150, "option.description.max_length" => 75, "option.text.max_length" => 75, "option.url.max_length" => 3000, "option.value.max_length" => 150, "option_group.label.max_length" => 75, "option_group.options.max_items" => 100, "option_group.options.min_items" => 1, "overflow.options.max_items" => 5, "overflow.options.min_items" => 1, "plain_text_input.max_length.max" => 3000, "plain_text_input.max_length.min" => 1, "plain_text_input.min_length.max" => 3000, "plain_text_input.min_length.min" => 0, "plain_text_input.placeholder.max_length" => 150, "plan.tasks.max_items" => 50, "radio_buttons.options.max_items" => 10, "radio_buttons.options.min_items" => 1, "rich_text_input.max_lines.max" => 100, "rich_text_input.max_lines.min" => 1, "rich_text_input.min_lines.max" => 100, "rich_text_input.min_lines.min" => 1, "rich_text_input.placeholder.max_length" => 150, "rich_text_list.border.max" => 1, "rich_text_list.border.min" => 0, "rich_text_list.indent.max" => 8, "rich_text_list.indent.min" => 0, "rich_text_list.offset.min" => 0, "rich_text_preformatted.border.max" => 1, "rich_text_preformatted.border.min" => 0, "rich_text_quote.border.max" => 1, "rich_text_quote.border.min" => 0, "section.fields.item_max_length" => 2000, "section.fields.max_items" => 10, "section.text.max_length" => 3000, "select.min_query_length.min" => 0, "select.option_groups.max_items" => 100, "select.option_groups.min_items" => 1, "select.options.max_items" => 100, "select.options.min_items" => 1, "select.placeholder.max_length" => 150, "table.column_settings.max_items" => 20, "table.columns.max_items" => 20, "table.rows.max_items" => 100, "text.max_length" => 3000, "text.min_length" => 1, "time_picker.placeholder.max_length" => 150, "url_input.placeholder.max_length" => 150, "video.alt_text.max_length" => 2000, "video.author_name.max_length" => 50, "video.description.max_length" => 200, "video.provider_icon_url.max_length" => 2000, "video.provider_name.max_length" => 50, "video.thumbnail_url.max_length" => 3000, "video.title.max_length" => 200, "video.title_url.max_length" => 2000, "video.video_url.max_length" => 3000, "view.blocks.max_items" => 100, "view.callback_id.max_length" => 255, "view.close.max_length" => 24, "view.external_id.max_length" => 255, "view.private_metadata.max_length" => 3000, "view.submit.max_length" => 24, "view.title.max_length" => 24, "workflow_button.accessibility_label.max_length" => 75, "workflow_button.text.max_length" => 75}.freeze
|
|
5
5
|
def self.[](path)
|
|
6
6
|
VALUES.fetch(path)
|
|
7
7
|
end
|
|
@@ -33,6 +33,12 @@ module Slackblocks
|
|
|
33
33
|
module RichTextSectionElement
|
|
34
34
|
end
|
|
35
35
|
|
|
36
|
+
module LayoutChild
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
module LayoutFallback
|
|
40
|
+
end
|
|
41
|
+
|
|
36
42
|
module AlertLevel
|
|
37
43
|
DEFAULT = :default
|
|
38
44
|
INFO = :info
|
|
@@ -80,9 +86,28 @@ module Slackblocks
|
|
|
80
86
|
EPHEMERAL = :ephemeral
|
|
81
87
|
end
|
|
82
88
|
|
|
89
|
+
module LayoutWidth
|
|
90
|
+
NARROW = :narrow
|
|
91
|
+
STANDARD = :standard
|
|
92
|
+
WIDE = :wide
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
module LayoutAlignment
|
|
96
|
+
START = :start
|
|
97
|
+
CENTER = :center
|
|
98
|
+
END_ = :end
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
module LayoutGridLines
|
|
102
|
+
NONE = :none
|
|
103
|
+
ROWS = :rows
|
|
104
|
+
OUTER = :outer
|
|
105
|
+
end
|
|
106
|
+
|
|
83
107
|
class ActionsBlock
|
|
84
108
|
include Value
|
|
85
109
|
include Block
|
|
110
|
+
include LayoutChild
|
|
86
111
|
attr_reader :elements, :block_id, :additional_fields
|
|
87
112
|
end
|
|
88
113
|
ActionsBlock.const_set(:WIRE_TYPE, "actions")
|
|
@@ -93,6 +118,7 @@ module Slackblocks
|
|
|
93
118
|
class AlertBlock
|
|
94
119
|
include Value
|
|
95
120
|
include Block
|
|
121
|
+
include LayoutChild
|
|
96
122
|
attr_reader :text, :level, :block_id, :additional_fields
|
|
97
123
|
end
|
|
98
124
|
AlertBlock.const_set(:WIRE_TYPE, "alert")
|
|
@@ -103,6 +129,7 @@ module Slackblocks
|
|
|
103
129
|
class CardBlock
|
|
104
130
|
include Value
|
|
105
131
|
include Block
|
|
132
|
+
include LayoutChild
|
|
106
133
|
attr_reader :hero_image, :icon, :title, :subtitle, :body, :actions, :slack_icon, :subtext, :block_id, :additional_fields
|
|
107
134
|
end
|
|
108
135
|
CardBlock.const_set(:WIRE_TYPE, "card")
|
|
@@ -113,6 +140,7 @@ module Slackblocks
|
|
|
113
140
|
class CarouselBlock
|
|
114
141
|
include Value
|
|
115
142
|
include Block
|
|
143
|
+
include LayoutChild
|
|
116
144
|
attr_reader :elements, :block_id, :additional_fields
|
|
117
145
|
end
|
|
118
146
|
CarouselBlock.const_set(:WIRE_TYPE, "carousel")
|
|
@@ -123,6 +151,7 @@ module Slackblocks
|
|
|
123
151
|
class ContainerBlock
|
|
124
152
|
include Value
|
|
125
153
|
include Block
|
|
154
|
+
include LayoutChild
|
|
126
155
|
attr_reader :child_blocks, :title, :rich_text_title, :subtitle, :width, :icon, :is_collapsible, :default_collapsed, :has_header_divider, :block_id, :additional_fields
|
|
127
156
|
end
|
|
128
157
|
ContainerBlock.const_set(:WIRE_TYPE, "container")
|
|
@@ -143,6 +172,8 @@ module Slackblocks
|
|
|
143
172
|
class ContextBlock
|
|
144
173
|
include Value
|
|
145
174
|
include Block
|
|
175
|
+
include LayoutChild
|
|
176
|
+
include LayoutFallback
|
|
146
177
|
attr_reader :elements, :block_id, :additional_fields
|
|
147
178
|
end
|
|
148
179
|
ContextBlock.const_set(:WIRE_TYPE, "context")
|
|
@@ -153,6 +184,7 @@ module Slackblocks
|
|
|
153
184
|
class DataTableBlock
|
|
154
185
|
include Value
|
|
155
186
|
include Block
|
|
187
|
+
include LayoutChild
|
|
156
188
|
attr_reader :rows, :caption, :page_size, :row_header_column_index, :block_id, :additional_fields
|
|
157
189
|
end
|
|
158
190
|
DataTableBlock.const_set(:WIRE_TYPE, "data_table")
|
|
@@ -163,6 +195,7 @@ module Slackblocks
|
|
|
163
195
|
class DataVisualizationBlock
|
|
164
196
|
include Value
|
|
165
197
|
include Block
|
|
198
|
+
include LayoutChild
|
|
166
199
|
attr_reader :title, :chart, :block_id, :additional_fields
|
|
167
200
|
end
|
|
168
201
|
DataVisualizationBlock.const_set(:WIRE_TYPE, "data_visualization")
|
|
@@ -173,6 +206,8 @@ module Slackblocks
|
|
|
173
206
|
class DividerBlock
|
|
174
207
|
include Value
|
|
175
208
|
include Block
|
|
209
|
+
include LayoutChild
|
|
210
|
+
include LayoutFallback
|
|
176
211
|
attr_reader :block_id, :additional_fields
|
|
177
212
|
end
|
|
178
213
|
DividerBlock.const_set(:WIRE_TYPE, "divider")
|
|
@@ -183,6 +218,7 @@ module Slackblocks
|
|
|
183
218
|
class FileBlock
|
|
184
219
|
include Value
|
|
185
220
|
include Block
|
|
221
|
+
include LayoutChild
|
|
186
222
|
attr_reader :external_id, :source, :block_id, :additional_fields
|
|
187
223
|
end
|
|
188
224
|
FileBlock.const_set(:WIRE_TYPE, "file")
|
|
@@ -193,6 +229,8 @@ module Slackblocks
|
|
|
193
229
|
class HeaderBlock
|
|
194
230
|
include Value
|
|
195
231
|
include Block
|
|
232
|
+
include LayoutChild
|
|
233
|
+
include LayoutFallback
|
|
196
234
|
attr_reader :text, :block_id, :additional_fields
|
|
197
235
|
end
|
|
198
236
|
HeaderBlock.const_set(:WIRE_TYPE, "header")
|
|
@@ -203,6 +241,8 @@ module Slackblocks
|
|
|
203
241
|
class ImageBlock
|
|
204
242
|
include Value
|
|
205
243
|
include Block
|
|
244
|
+
include LayoutChild
|
|
245
|
+
include LayoutFallback
|
|
206
246
|
attr_reader :image_url, :slack_file, :alt_text, :title, :block_id, :additional_fields
|
|
207
247
|
end
|
|
208
248
|
ImageBlock.const_set(:WIRE_TYPE, "image")
|
|
@@ -213,6 +253,7 @@ module Slackblocks
|
|
|
213
253
|
class InputBlock
|
|
214
254
|
include Value
|
|
215
255
|
include Block
|
|
256
|
+
include LayoutChild
|
|
216
257
|
attr_reader :label, :element, :dispatch_action, :block_id, :hint, :optional, :additional_fields
|
|
217
258
|
end
|
|
218
259
|
InputBlock.const_set(:WIRE_TYPE, "input")
|
|
@@ -244,6 +285,8 @@ module Slackblocks
|
|
|
244
285
|
include Value
|
|
245
286
|
include Block
|
|
246
287
|
include DataTableCell
|
|
288
|
+
include LayoutChild
|
|
289
|
+
include LayoutFallback
|
|
247
290
|
include TableCell
|
|
248
291
|
attr_reader :elements, :block_id, :additional_fields
|
|
249
292
|
end
|
|
@@ -255,6 +298,8 @@ module Slackblocks
|
|
|
255
298
|
class SectionBlock
|
|
256
299
|
include Value
|
|
257
300
|
include Block
|
|
301
|
+
include LayoutChild
|
|
302
|
+
include LayoutFallback
|
|
258
303
|
attr_reader :text, :fields, :accessory, :block_id, :additional_fields
|
|
259
304
|
end
|
|
260
305
|
SectionBlock.const_set(:WIRE_TYPE, "section")
|
|
@@ -265,6 +310,8 @@ module Slackblocks
|
|
|
265
310
|
class TableBlock
|
|
266
311
|
include Value
|
|
267
312
|
include Block
|
|
313
|
+
include LayoutChild
|
|
314
|
+
include LayoutFallback
|
|
268
315
|
attr_reader :rows, :column_settings, :block_id, :additional_fields
|
|
269
316
|
end
|
|
270
317
|
TableBlock.const_set(:WIRE_TYPE, "table")
|
|
@@ -285,6 +332,8 @@ module Slackblocks
|
|
|
285
332
|
class VideoBlock
|
|
286
333
|
include Value
|
|
287
334
|
include Block
|
|
335
|
+
include LayoutChild
|
|
336
|
+
include LayoutFallback
|
|
288
337
|
attr_reader :alt_text, :thumbnail_url, :title, :video_url, :block_id, :author_name, :description, :provider_icon_url, :provider_name, :title_url, :additional_fields
|
|
289
338
|
end
|
|
290
339
|
VideoBlock.const_set(:WIRE_TYPE, "video")
|
|
@@ -976,4 +1025,32 @@ module Slackblocks
|
|
|
976
1025
|
WebhookMessage.const_set(:DEFAULTS, Value.deep_freeze({}))
|
|
977
1026
|
WebhookMessage.singleton_class.prepend(KeywordOnly)
|
|
978
1027
|
|
|
1028
|
+
class LayoutBlock
|
|
1029
|
+
include Value
|
|
1030
|
+
include Block
|
|
1031
|
+
attr_reader :label, :rows, :is_label_visible, :grid_lines, :fallback, :block_id, :additional_fields
|
|
1032
|
+
end
|
|
1033
|
+
LayoutBlock.const_set(:WIRE_TYPE, "layout")
|
|
1034
|
+
LayoutBlock.const_set(:FIELD_SPECS, Value.deep_freeze([{"name" => "label", "wire" => "label", "kind" => "string", "target" => nil, "coerce" => nil, "flags" => nil, "limits" => "layout.label", "required" => true}, {"name" => "rows", "wire" => "rows", "kind" => "list", "target" => "LayoutRow", "coerce" => nil, "flags" => nil, "limits" => "layout.rows", "required" => true}, {"name" => "is_label_visible", "wire" => "is_label_visible", "kind" => "boolean", "target" => nil, "coerce" => nil, "flags" => nil, "limits" => nil, "required" => false}, {"name" => "grid_lines", "wire" => "grid_lines", "kind" => "enum", "target" => "LayoutGridLines", "coerce" => nil, "flags" => nil, "limits" => nil, "required" => false}, {"name" => "fallback", "wire" => "fallback", "kind" => "list", "target" => "LayoutFallback", "coerce" => nil, "flags" => nil, "limits" => nil, "required" => false}, {"name" => "block_id", "wire" => "block_id", "kind" => "string", "target" => nil, "coerce" => nil, "flags" => nil, "limits" => "block_id", "required" => false}]))
|
|
1035
|
+
LayoutBlock.const_set(:DEFAULTS, Value.deep_freeze({}))
|
|
1036
|
+
LayoutBlock.singleton_class.prepend(KeywordOnly)
|
|
1037
|
+
|
|
1038
|
+
class LayoutRow
|
|
1039
|
+
include Value
|
|
1040
|
+
attr_reader :items, :additional_fields
|
|
1041
|
+
end
|
|
1042
|
+
LayoutRow.const_set(:WIRE_TYPE, "")
|
|
1043
|
+
LayoutRow.const_set(:FIELD_SPECS, Value.deep_freeze([{"name" => "items", "wire" => "items", "kind" => "list", "target" => "LayoutItem", "coerce" => nil, "flags" => nil, "limits" => "layout.items", "required" => true}]))
|
|
1044
|
+
LayoutRow.const_set(:DEFAULTS, Value.deep_freeze({}))
|
|
1045
|
+
LayoutRow.singleton_class.prepend(KeywordOnly)
|
|
1046
|
+
|
|
1047
|
+
class LayoutItem
|
|
1048
|
+
include Value
|
|
1049
|
+
attr_reader :block, :width, :horizontal_alignment, :additional_fields
|
|
1050
|
+
end
|
|
1051
|
+
LayoutItem.const_set(:WIRE_TYPE, "")
|
|
1052
|
+
LayoutItem.const_set(:FIELD_SPECS, Value.deep_freeze([{"name" => "block", "wire" => "block", "kind" => "object", "target" => "LayoutChild", "coerce" => nil, "flags" => nil, "limits" => nil, "required" => true}, {"name" => "width", "wire" => "width", "kind" => "enum", "target" => "LayoutWidth", "coerce" => nil, "flags" => nil, "limits" => nil, "required" => false}, {"name" => "horizontal_alignment", "wire" => "horizontal_alignment", "kind" => "enum", "target" => "LayoutAlignment", "coerce" => nil, "flags" => nil, "limits" => nil, "required" => false}]))
|
|
1053
|
+
LayoutItem.const_set(:DEFAULTS, Value.deep_freeze({}))
|
|
1054
|
+
LayoutItem.singleton_class.prepend(KeywordOnly)
|
|
1055
|
+
|
|
979
1056
|
end
|
|
@@ -2,6 +2,6 @@
|
|
|
2
2
|
module Slackblocks
|
|
3
3
|
module Vocabulary
|
|
4
4
|
ICON_NAMES = Value.deep_freeze(["archive", "book", "bookmark", "bot", "bug", "calendar", "call", "caret-left", "caret-right", "check", "clipboard", "code", "comment", "compass", "copy", "cube", "download", "edit", "email", "eye-closed", "eye-open", "file", "flag", "folder", "gear", "globe", "heart", "help", "image", "info", "key", "lightbulb", "link", "map", "mobile", "new-window", "pin", "plus", "refine", "refresh", "rocket", "save", "screen", "share", "sparkle", "star", "star-filled", "tag", "thumbs-down", "thumbs-up", "trash", "upload", "user", "warning"])
|
|
5
|
-
SURFACE_BLOCK_TYPES = Value.deep_freeze({"home" => ["actions", "card", "carousel", "container", "context", "data_table", "data_visualization", "divider", "header", "image", "input", "rich_text", "section", "table", "video"], "message" => ["actions", "card", "carousel", "container", "context", "context_actions", "data_table", "data_visualization", "divider", "file", "header", "image", "input", "markdown", "plan", "rich_text", "section", "table", "task_card", "video"], "modal" => ["actions", "alert", "card", "context", "divider", "header", "image", "input", "rich_text", "section", "video"]})
|
|
5
|
+
SURFACE_BLOCK_TYPES = Value.deep_freeze({"home" => ["actions", "card", "carousel", "container", "context", "data_table", "data_visualization", "divider", "header", "image", "input", "layout", "rich_text", "section", "table", "video"], "message" => ["actions", "card", "carousel", "container", "context", "context_actions", "data_table", "data_visualization", "divider", "file", "header", "image", "input", "layout", "markdown", "plan", "rich_text", "section", "table", "task_card", "video"], "modal" => ["actions", "alert", "card", "context", "divider", "header", "image", "input", "layout", "rich_text", "section", "video"]})
|
|
6
6
|
end
|
|
7
7
|
end
|
|
@@ -73,7 +73,23 @@ module Slackblocks
|
|
|
73
73
|
if wire.key?("icon") && wire.key?("slack_icon")
|
|
74
74
|
fail!("mutually-exclusive", path, "icon and slack_icon cannot both be present")
|
|
75
75
|
end
|
|
76
|
+
when "LayoutBlock"
|
|
77
|
+
composite_depth(wire, path)
|
|
78
|
+
when "LayoutRow"
|
|
79
|
+
fail!("type-mismatch", path, "a row only supports items") unless (wire.keys - ["items"]).empty?
|
|
80
|
+
items = wire.fetch("items")
|
|
81
|
+
wide = items.count { |item| %w[carousel data_table data_visualization].include?(item.fetch("block")["type"]) }
|
|
82
|
+
fail!("invalid-usage", path, "at most one wide-content block per row") if wide > 1
|
|
83
|
+
total = items.sum { |item| layout_weight(item) }
|
|
84
|
+
items.each do |item|
|
|
85
|
+
if item.fetch("block")["type"] == "data_visualization" && layout_weight(item) * 2 <= total
|
|
86
|
+
fail!("invalid-usage", path, "a data visualization requires more than half the row weight")
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
when "LayoutItem"
|
|
90
|
+
fail!("type-mismatch", path, "unsupported layout item property") unless (wire.keys - %w[block width horizontal_alignment]).empty?
|
|
76
91
|
when "ContainerBlock"
|
|
92
|
+
composite_depth(wire, path)
|
|
77
93
|
unless wire.key?("title") || wire.key?("rich_text_title")
|
|
78
94
|
fail!("missing-required", path, "expected title")
|
|
79
95
|
end
|
|
@@ -147,7 +163,7 @@ module Slackblocks
|
|
|
147
163
|
message(wire, path)
|
|
148
164
|
when "ModalView", "HomeTabView"
|
|
149
165
|
surface(wire.fetch("blocks"), (klass == ModalView) ? "modal" : "home", "#{path}.blocks")
|
|
150
|
-
if klass == ModalView && !wire.key?("submit") && wire.fetch("blocks").any? { |block| block["type"] == "input" }
|
|
166
|
+
if klass == ModalView && !wire.key?("submit") && descendants(wire.fetch("blocks")).any? { |block| block["type"] == "input" }
|
|
151
167
|
fail!("missing-required", "#{path}.submit", "required when modal contains an input")
|
|
152
168
|
end
|
|
153
169
|
end
|
|
@@ -179,12 +195,40 @@ module Slackblocks
|
|
|
179
195
|
left[0] * (rank.zero? ? left[2].ljust(width, "0") <=> right[2].ljust(width, "0") : rank)
|
|
180
196
|
end
|
|
181
197
|
|
|
198
|
+
def self.layout_weight(item)
|
|
199
|
+
{"narrow" => 1, "wide" => 3}.fetch(item["width"], 2)
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
def self.composite_children(block, fallback: true)
|
|
203
|
+
empty = [] # : Array[Hash[String, untyped]]
|
|
204
|
+
case block["type"]
|
|
205
|
+
when "container" then block.fetch("child_blocks")
|
|
206
|
+
when "layout"
|
|
207
|
+
block.fetch("rows").flat_map { |row| row.fetch("items").map { |item| item.fetch("block") } } + (fallback ? block.fetch("fallback", empty) : empty)
|
|
208
|
+
else []
|
|
209
|
+
end
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
def self.composite_depth(block, path, depth = 0, has_layout = false)
|
|
213
|
+
has_layout ||= block["type"] == "layout"
|
|
214
|
+
depth += 1 if %w[layout container].include?(block["type"])
|
|
215
|
+
fail!("invalid-usage", path, "layout/container nesting exceeds two composite levels") if has_layout && depth > 2
|
|
216
|
+
composite_children(block, fallback: false).each { |child| composite_depth(child, path, depth, has_layout) }
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
def self.descendants(blocks)
|
|
220
|
+
blocks.flat_map { |block| [block] + descendants(composite_children(block)) }
|
|
221
|
+
end
|
|
222
|
+
|
|
182
223
|
def self.surface(blocks, name, path)
|
|
224
|
+
empty = [] # : Array[Hash[String, untyped]]
|
|
183
225
|
allowed = Vocabulary::SURFACE_BLOCK_TYPES.fetch(name)
|
|
184
226
|
blocks.each_with_index do |block, index|
|
|
185
227
|
type = block["type"]
|
|
186
228
|
fail!("type-mismatch", "#{path}[#{index}].type", "unsupported #{name} block") unless allowed.include?(type)
|
|
187
229
|
standalone_task(block, "#{path}[#{index}]")
|
|
230
|
+
surface(composite_children(block, fallback: false), name, "#{path}[#{index}].children")
|
|
231
|
+
surface(block.fetch("fallback", empty), name, "#{path}[#{index}].fallback") if type == "layout"
|
|
188
232
|
end
|
|
189
233
|
end
|
|
190
234
|
|
|
@@ -227,8 +271,8 @@ module Slackblocks
|
|
|
227
271
|
totals["data_visualization"] += 1
|
|
228
272
|
elsif node["type"] == "data_table"
|
|
229
273
|
totals["data_table"] += characters(node.fetch("rows"))
|
|
230
|
-
elsif node["type"]
|
|
231
|
-
tally(node
|
|
274
|
+
elsif %w[container layout].include?(node["type"])
|
|
275
|
+
tally(composite_children(node), totals)
|
|
232
276
|
end
|
|
233
277
|
when Array
|
|
234
278
|
node.each { |child| tally(child, totals) }
|
data/lib/slackblocks/version.rb
CHANGED
|
@@ -33,6 +33,12 @@ module Slackblocks
|
|
|
33
33
|
module RichTextSectionElement
|
|
34
34
|
end
|
|
35
35
|
|
|
36
|
+
module LayoutChild
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
module LayoutFallback
|
|
40
|
+
end
|
|
41
|
+
|
|
36
42
|
module AlertLevel
|
|
37
43
|
DEFAULT: :default
|
|
38
44
|
INFO: :info
|
|
@@ -80,9 +86,28 @@ module Slackblocks
|
|
|
80
86
|
EPHEMERAL: :ephemeral
|
|
81
87
|
end
|
|
82
88
|
|
|
89
|
+
module LayoutWidth
|
|
90
|
+
NARROW: :narrow
|
|
91
|
+
STANDARD: :standard
|
|
92
|
+
WIDE: :wide
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
module LayoutAlignment
|
|
96
|
+
START: :start
|
|
97
|
+
CENTER: :center
|
|
98
|
+
END_: :end
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
module LayoutGridLines
|
|
102
|
+
NONE: :none
|
|
103
|
+
ROWS: :rows
|
|
104
|
+
OUTER: :outer
|
|
105
|
+
end
|
|
106
|
+
|
|
83
107
|
class ActionsBlock
|
|
84
108
|
include Value
|
|
85
109
|
include Block
|
|
110
|
+
include LayoutChild
|
|
86
111
|
attr_reader elements: Array[Element]
|
|
87
112
|
attr_reader block_id: (String)?
|
|
88
113
|
attr_reader additional_fields: Hash[String, untyped]
|
|
@@ -94,6 +119,7 @@ module Slackblocks
|
|
|
94
119
|
class AlertBlock
|
|
95
120
|
include Value
|
|
96
121
|
include Block
|
|
122
|
+
include LayoutChild
|
|
97
123
|
attr_reader text: Text
|
|
98
124
|
attr_reader level: (:default | :info | :warning | :error | :success)?
|
|
99
125
|
attr_reader block_id: (String)?
|
|
@@ -106,6 +132,7 @@ module Slackblocks
|
|
|
106
132
|
class CardBlock
|
|
107
133
|
include Value
|
|
108
134
|
include Block
|
|
135
|
+
include LayoutChild
|
|
109
136
|
attr_reader hero_image: (ImageElement)?
|
|
110
137
|
attr_reader icon: (ImageElement)?
|
|
111
138
|
attr_reader title: (Text)?
|
|
@@ -124,6 +151,7 @@ module Slackblocks
|
|
|
124
151
|
class CarouselBlock
|
|
125
152
|
include Value
|
|
126
153
|
include Block
|
|
154
|
+
include LayoutChild
|
|
127
155
|
attr_reader elements: Array[CardBlock]
|
|
128
156
|
attr_reader block_id: (String)?
|
|
129
157
|
attr_reader additional_fields: Hash[String, untyped]
|
|
@@ -135,6 +163,7 @@ module Slackblocks
|
|
|
135
163
|
class ContainerBlock
|
|
136
164
|
include Value
|
|
137
165
|
include Block
|
|
166
|
+
include LayoutChild
|
|
138
167
|
attr_reader child_blocks: Array[Block]
|
|
139
168
|
attr_reader title: (PlainText)?
|
|
140
169
|
attr_reader rich_text_title: (RichTextBlock)?
|
|
@@ -165,6 +194,8 @@ module Slackblocks
|
|
|
165
194
|
class ContextBlock
|
|
166
195
|
include Value
|
|
167
196
|
include Block
|
|
197
|
+
include LayoutChild
|
|
198
|
+
include LayoutFallback
|
|
168
199
|
attr_reader elements: Array[ContextElement]
|
|
169
200
|
attr_reader block_id: (String)?
|
|
170
201
|
attr_reader additional_fields: Hash[String, untyped]
|
|
@@ -176,6 +207,7 @@ module Slackblocks
|
|
|
176
207
|
class DataTableBlock
|
|
177
208
|
include Value
|
|
178
209
|
include Block
|
|
210
|
+
include LayoutChild
|
|
179
211
|
attr_reader rows: Array[Array[DataTableCell]]
|
|
180
212
|
attr_reader caption: String
|
|
181
213
|
attr_reader page_size: (Integer)?
|
|
@@ -190,6 +222,7 @@ module Slackblocks
|
|
|
190
222
|
class DataVisualizationBlock
|
|
191
223
|
include Value
|
|
192
224
|
include Block
|
|
225
|
+
include LayoutChild
|
|
193
226
|
attr_reader title: String
|
|
194
227
|
attr_reader chart: Chart
|
|
195
228
|
attr_reader block_id: (String)?
|
|
@@ -202,6 +235,8 @@ module Slackblocks
|
|
|
202
235
|
class DividerBlock
|
|
203
236
|
include Value
|
|
204
237
|
include Block
|
|
238
|
+
include LayoutChild
|
|
239
|
+
include LayoutFallback
|
|
205
240
|
attr_reader block_id: (String)?
|
|
206
241
|
attr_reader additional_fields: Hash[String, untyped]
|
|
207
242
|
def initialize: (?block_id: (String)?, ?additional_fields: Hash[String | Symbol, untyped]?) -> void
|
|
@@ -212,6 +247,7 @@ module Slackblocks
|
|
|
212
247
|
class FileBlock
|
|
213
248
|
include Value
|
|
214
249
|
include Block
|
|
250
|
+
include LayoutChild
|
|
215
251
|
attr_reader external_id: String
|
|
216
252
|
attr_reader source: (String)?
|
|
217
253
|
attr_reader block_id: (String)?
|
|
@@ -224,6 +260,8 @@ module Slackblocks
|
|
|
224
260
|
class HeaderBlock
|
|
225
261
|
include Value
|
|
226
262
|
include Block
|
|
263
|
+
include LayoutChild
|
|
264
|
+
include LayoutFallback
|
|
227
265
|
attr_reader text: PlainText
|
|
228
266
|
attr_reader block_id: (String)?
|
|
229
267
|
attr_reader additional_fields: Hash[String, untyped]
|
|
@@ -235,6 +273,8 @@ module Slackblocks
|
|
|
235
273
|
class ImageBlock
|
|
236
274
|
include Value
|
|
237
275
|
include Block
|
|
276
|
+
include LayoutChild
|
|
277
|
+
include LayoutFallback
|
|
238
278
|
attr_reader image_url: (String)?
|
|
239
279
|
attr_reader slack_file: (SlackFile)?
|
|
240
280
|
attr_reader alt_text: String
|
|
@@ -249,6 +289,7 @@ module Slackblocks
|
|
|
249
289
|
class InputBlock
|
|
250
290
|
include Value
|
|
251
291
|
include Block
|
|
292
|
+
include LayoutChild
|
|
252
293
|
attr_reader label: PlainText
|
|
253
294
|
attr_reader element: InputElement
|
|
254
295
|
attr_reader dispatch_action: (bool)?
|
|
@@ -288,6 +329,8 @@ module Slackblocks
|
|
|
288
329
|
include Value
|
|
289
330
|
include Block
|
|
290
331
|
include DataTableCell
|
|
332
|
+
include LayoutChild
|
|
333
|
+
include LayoutFallback
|
|
291
334
|
include TableCell
|
|
292
335
|
attr_reader elements: Array[RichTextBlockElement]
|
|
293
336
|
attr_reader block_id: (String)?
|
|
@@ -300,6 +343,8 @@ module Slackblocks
|
|
|
300
343
|
class SectionBlock
|
|
301
344
|
include Value
|
|
302
345
|
include Block
|
|
346
|
+
include LayoutChild
|
|
347
|
+
include LayoutFallback
|
|
303
348
|
attr_reader text: (Text)?
|
|
304
349
|
attr_reader fields: (Array[Text])?
|
|
305
350
|
attr_reader accessory: (Element)?
|
|
@@ -313,6 +358,8 @@ module Slackblocks
|
|
|
313
358
|
class TableBlock
|
|
314
359
|
include Value
|
|
315
360
|
include Block
|
|
361
|
+
include LayoutChild
|
|
362
|
+
include LayoutFallback
|
|
316
363
|
attr_reader rows: Array[Array[TableCell]]
|
|
317
364
|
attr_reader column_settings: (Array[ColumnSettings])?
|
|
318
365
|
attr_reader block_id: (String)?
|
|
@@ -341,6 +388,8 @@ module Slackblocks
|
|
|
341
388
|
class VideoBlock
|
|
342
389
|
include Value
|
|
343
390
|
include Block
|
|
391
|
+
include LayoutChild
|
|
392
|
+
include LayoutFallback
|
|
344
393
|
attr_reader alt_text: String
|
|
345
394
|
attr_reader thumbnail_url: String
|
|
346
395
|
attr_reader title: PlainText
|
|
@@ -1249,6 +1298,41 @@ module Slackblocks
|
|
|
1249
1298
|
def self.[]: (?blocks: (Array[Block])?, ?attachments: (Array[Attachment])?, ?text: (String)?, ?response_type: (:in_channel | :ephemeral)?, ?replace_original: (bool)?, ?delete_original: (bool)?, ?unfurl_links: (bool)?, ?unfurl_media: (bool)?, ?metadata: (Hash[String | Symbol, untyped])?, ?additional_fields: Hash[String | Symbol, untyped]?) -> WebhookMessage
|
|
1250
1299
|
end
|
|
1251
1300
|
|
|
1301
|
+
class LayoutBlock
|
|
1302
|
+
include Value
|
|
1303
|
+
include Block
|
|
1304
|
+
attr_reader label: String
|
|
1305
|
+
attr_reader rows: Array[LayoutRow]
|
|
1306
|
+
attr_reader is_label_visible: (bool)?
|
|
1307
|
+
attr_reader grid_lines: (:none | :rows | :outer)?
|
|
1308
|
+
attr_reader fallback: (Array[LayoutFallback])?
|
|
1309
|
+
attr_reader block_id: (String)?
|
|
1310
|
+
attr_reader additional_fields: Hash[String, untyped]
|
|
1311
|
+
def initialize: (label: String, rows: Array[LayoutRow], ?is_label_visible: (bool)?, ?grid_lines: (:none | :rows | :outer)?, ?fallback: (Array[LayoutFallback])?, ?block_id: (String)?, ?additional_fields: Hash[String | Symbol, untyped]?) -> void
|
|
1312
|
+
def self.new: (label: String, rows: Array[LayoutRow], ?is_label_visible: (bool)?, ?grid_lines: (:none | :rows | :outer)?, ?fallback: (Array[LayoutFallback])?, ?block_id: (String)?, ?additional_fields: Hash[String | Symbol, untyped]?) -> LayoutBlock
|
|
1313
|
+
def self.[]: (label: String, rows: Array[LayoutRow], ?is_label_visible: (bool)?, ?grid_lines: (:none | :rows | :outer)?, ?fallback: (Array[LayoutFallback])?, ?block_id: (String)?, ?additional_fields: Hash[String | Symbol, untyped]?) -> LayoutBlock
|
|
1314
|
+
end
|
|
1315
|
+
|
|
1316
|
+
class LayoutRow
|
|
1317
|
+
include Value
|
|
1318
|
+
attr_reader items: Array[LayoutItem]
|
|
1319
|
+
attr_reader additional_fields: Hash[String, untyped]
|
|
1320
|
+
def initialize: (items: Array[LayoutItem], ?additional_fields: Hash[String | Symbol, untyped]?) -> void
|
|
1321
|
+
def self.new: (items: Array[LayoutItem], ?additional_fields: Hash[String | Symbol, untyped]?) -> LayoutRow
|
|
1322
|
+
def self.[]: (items: Array[LayoutItem], ?additional_fields: Hash[String | Symbol, untyped]?) -> LayoutRow
|
|
1323
|
+
end
|
|
1324
|
+
|
|
1325
|
+
class LayoutItem
|
|
1326
|
+
include Value
|
|
1327
|
+
attr_reader block: LayoutChild
|
|
1328
|
+
attr_reader width: (:narrow | :standard | :wide)?
|
|
1329
|
+
attr_reader horizontal_alignment: (:start | :center | :end)?
|
|
1330
|
+
attr_reader additional_fields: Hash[String, untyped]
|
|
1331
|
+
def initialize: (block: LayoutChild, ?width: (:narrow | :standard | :wide)?, ?horizontal_alignment: (:start | :center | :end)?, ?additional_fields: Hash[String | Symbol, untyped]?) -> void
|
|
1332
|
+
def self.new: (block: LayoutChild, ?width: (:narrow | :standard | :wide)?, ?horizontal_alignment: (:start | :center | :end)?, ?additional_fields: Hash[String | Symbol, untyped]?) -> LayoutItem
|
|
1333
|
+
def self.[]: (block: LayoutChild, ?width: (:narrow | :standard | :wide)?, ?horizontal_alignment: (:start | :center | :end)?, ?additional_fields: Hash[String | Symbol, untyped]?) -> LayoutItem
|
|
1334
|
+
end
|
|
1335
|
+
|
|
1252
1336
|
module StyleFlags
|
|
1253
1337
|
NAMES: Array[String]
|
|
1254
1338
|
end
|
data/sig/slackblocks.rbs
CHANGED
|
@@ -38,6 +38,10 @@ module Slackblocks
|
|
|
38
38
|
end
|
|
39
39
|
|
|
40
40
|
module Validator
|
|
41
|
+
def self.layout_weight: (Hash[String, untyped] item) -> Integer
|
|
42
|
+
def self.composite_children: (Hash[String, untyped] block, ?fallback: bool) -> Array[Hash[String, untyped]]
|
|
43
|
+
def self.composite_depth: (Hash[String, untyped] block, String path, ?Integer depth, ?bool has_layout) -> untyped
|
|
44
|
+
def self.descendants: (Array[Hash[String, untyped]] blocks) -> Array[Hash[String, untyped]]
|
|
41
45
|
def self.validate: (untyped klass, Hash[Symbol, untyped] values) -> untyped
|
|
42
46
|
def self.limit: (String key) -> Integer
|
|
43
47
|
def self.fail!: (String category, String path, String message) -> bot
|