@tightknitai/slack-block-kit-validator 0.1.8 → 0.1.10
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.
- package/README.md +1 -1
- package/dist/helpers/check-surface-compatibility.d.ts.map +1 -1
- package/dist/helpers/check-surface-compatibility.js +17 -11
- package/dist/helpers/check-surface-compatibility.js.map +1 -1
- package/dist/slack-block-kit.schema.json +117 -0
- package/dist/standalone-validator.js +8014 -6713
- package/dist/types.generated.d.ts +1252 -531
- package/dist/types.generated.d.ts.map +1 -1
- package/dist/validate-block-kit.d.ts.map +1 -1
- package/dist/validate-block-kit.js +2 -0
- package/dist/validate-block-kit.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -141,7 +141,7 @@ Each returns an array of human-readable error strings — empty when valid.
|
|
|
141
141
|
|
|
142
142
|
## Coverage
|
|
143
143
|
|
|
144
|
-
- **
|
|
144
|
+
- **21 blocks**: actions, alert, card, carousel, container, context, context_actions, data_table, data_visualization, divider, file, header, image, input, markdown, plan, rich_text, section, table, task_card, video.
|
|
145
145
|
- **All block elements**: button, icon_button, workflow_button, feedback_buttons, plain_text / email / url / number inputs, datepicker, datetimepicker, timepicker, file_input, rich_text_input, checkboxes, radio_buttons, image, overflow, url source, and all 5 single + 5 multi-select menu variants.
|
|
146
146
|
- **All 9 composition objects**: text (plain_text + mrkdwn), confirm, option (3 contextual variants), option_group, slack_file, dispatch_action_config, conversation_filter, trigger, workflow.
|
|
147
147
|
- **Rich text**: 4 container kinds (section, list, preformatted, quote) + 10 leaf kinds (text, link, user, usergroup, team, channel, emoji, broadcast, color, date) with style flags.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"check-surface-compatibility.d.ts","sourceRoot":"","sources":["../../src/helpers/check-surface-compatibility.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,MAAM,OAAO,GAAG,SAAS,GAAG,OAAO,GAAG,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"check-surface-compatibility.d.ts","sourceRoot":"","sources":["../../src/helpers/check-surface-compatibility.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,MAAM,OAAO,GAAG,SAAS,GAAG,OAAO,GAAG,MAAM,CAAC;AAqEnD;;;;;;;;;GASG;AACH,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,SAAS;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,EAAE,EACjE,OAAO,EAAE,OAAO,GACf,MAAM,EAAE,CAsBV"}
|
|
@@ -3,22 +3,26 @@
|
|
|
3
3
|
// block entry there has an `available-in-surfaces` array valued with some
|
|
4
4
|
// subset of ["Modals", "Messages", "Home tabs"]. Whatever's missing from
|
|
5
5
|
// that array is what we forbid here.
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
//
|
|
6
|
+
//
|
|
7
|
+
// Four entries below intentionally deviate from blocks.json — Slack's canonical
|
|
8
|
+
// data lists a surface where the block doesn't actually render. Each is
|
|
9
|
+
// empirically grounded:
|
|
10
|
+
// • card / modals — blocks.json lists Modals; fails to render there.
|
|
11
|
+
// • file / messages — inbound-only; apps can't send it outbound at all
|
|
12
|
+
// (https://docs.slack.dev/reference/block-kit/blocks/file-block:
|
|
13
|
+
// "You can't add this block to app surfaces directly...").
|
|
14
|
+
// • table / home tabs — blocks.json lists Home tabs; Tightknit testing shows
|
|
15
|
+
// the table block renders on messages only (modals and home drop it).
|
|
16
|
+
// • data_table / home tabs — same: blocks.json lists Home tabs, but as a
|
|
17
|
+
// table-family block it inherits table's messages-only behavior (mirrored
|
|
18
|
+
// for consistency, pending independent confirmation).
|
|
10
19
|
const BLOCKS_NOT_ALLOWED_IN_MESSAGE = new Set(["alert", "file"]);
|
|
11
|
-
// carousel/card are listed as modal-available in Slack's blocks.json but
|
|
12
|
-
// empirically fail to render inside modal views — confirmed by the PR author
|
|
13
|
-
// against the live API. They work in messages and home tabs.
|
|
14
|
-
// `data_visualization` is a messages-only block — its reference page lists
|
|
15
|
-
// "Available in Surfaces: Messages" only
|
|
16
|
-
// (https://docs.slack.dev/reference/block-kit/blocks/data-visualization-block).
|
|
17
|
-
// Forbidden in both modals and home tabs.
|
|
18
20
|
const BLOCKS_NOT_ALLOWED_IN_MODAL = new Set([
|
|
19
21
|
"card",
|
|
20
22
|
"carousel",
|
|
23
|
+
"container",
|
|
21
24
|
"context_actions",
|
|
25
|
+
"data_table",
|
|
22
26
|
"data_visualization",
|
|
23
27
|
"file",
|
|
24
28
|
"markdown",
|
|
@@ -28,7 +32,9 @@ const BLOCKS_NOT_ALLOWED_IN_MODAL = new Set([
|
|
|
28
32
|
]);
|
|
29
33
|
const BLOCKS_NOT_ALLOWED_IN_HOME = new Set([
|
|
30
34
|
"alert",
|
|
35
|
+
"container",
|
|
31
36
|
"context_actions",
|
|
37
|
+
"data_table",
|
|
32
38
|
"data_visualization",
|
|
33
39
|
"file",
|
|
34
40
|
"markdown",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"check-surface-compatibility.js","sourceRoot":"","sources":["../../src/helpers/check-surface-compatibility.ts"],"names":[],"mappings":"AAMA,2EAA2E;AAC3E,0EAA0E;AAC1E,0EAA0E;AAC1E,yEAAyE;AACzE,qCAAqC;AACrC,yEAAyE;AACzE,
|
|
1
|
+
{"version":3,"file":"check-surface-compatibility.js","sourceRoot":"","sources":["../../src/helpers/check-surface-compatibility.ts"],"names":[],"mappings":"AAMA,2EAA2E;AAC3E,0EAA0E;AAC1E,0EAA0E;AAC1E,yEAAyE;AACzE,qCAAqC;AACrC,EAAE;AACF,gFAAgF;AAChF,wEAAwE;AACxE,wBAAwB;AACxB,yEAAyE;AACzE,yEAAyE;AACzE,qEAAqE;AACrE,+DAA+D;AAC/D,+EAA+E;AAC/E,0EAA0E;AAC1E,2EAA2E;AAC3E,8EAA8E;AAC9E,0DAA0D;AAC1D,MAAM,6BAA6B,GAAG,IAAI,GAAG,CAAC,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC;AAEjE,MAAM,2BAA2B,GAAG,IAAI,GAAG,CAAC;IAC1C,MAAM;IACN,UAAU;IACV,WAAW;IACX,iBAAiB;IACjB,YAAY;IACZ,oBAAoB;IACpB,MAAM;IACN,UAAU;IACV,MAAM;IACN,OAAO;IACP,WAAW;CACZ,CAAC,CAAC;AAEH,MAAM,0BAA0B,GAAG,IAAI,GAAG,CAAC;IACzC,OAAO;IACP,WAAW;IACX,iBAAiB;IACjB,YAAY;IACZ,oBAAoB;IACpB,MAAM;IACN,UAAU;IACV,MAAM;IACN,OAAO;IACP,WAAW;CACZ,CAAC,CAAC;AAEH,MAAM,oBAAoB,GAAiC;IACzD,OAAO,EAAE,6BAA6B;IACtC,KAAK,EAAE,2BAA2B;IAClC,IAAI,EAAE,0BAA0B;CACjC,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,qBAAqB,GAA4B;IACrD,OAAO,EAAE,EAAE;IACX,KAAK,EAAE,GAAG;IACV,IAAI,EAAE,GAAG;CACV,CAAC;AAEF;;;;;;;;;GASG;AACH,MAAM,UAAU,yBAAyB,CACvC,MAAiE,EACjE,OAAgB;IAEhB,MAAM,SAAS,GAAG,oBAAoB,CAAC,OAAO,CAAC,CAAC;IAChD,MAAM,MAAM,GAAa,EAAE,CAAC;IAE5B,MAAM,SAAS,GAAG,qBAAqB,CAAC,OAAO,CAAC,CAAC;IACjD,IAAI,MAAM,CAAC,MAAM,GAAG,SAAS,EAAE,CAAC;QAC9B,MAAM,CAAC,IAAI,CAAC,YAAY,OAAO,oBAAoB,SAAS,gBAAgB,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC;IAChG,CAAC;IAED,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE;QAC1B,IAAI,KAAK,EAAE,IAAI,IAAI,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YAC7C,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,WAAW,KAAK,CAAC,IAAI,gCAAgC,OAAO,GAAG,CAAC,CAAC;YACxF,mEAAmE;YACnE,uCAAuC;YACvC,OAAO;QACT,CAAC;QACD,IAAI,KAAK,EAAE,IAAI,KAAK,OAAO,IAAI,KAAK,CAAC,OAAO,EAAE,IAAI,KAAK,YAAY,IAAI,OAAO,KAAK,OAAO,EAAE,CAAC;YAC3F,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,uEAAuE,OAAO,IAAI,CAAC,CAAC;QAC7G,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -1178,6 +1178,58 @@
|
|
|
1178
1178
|
}
|
|
1179
1179
|
},
|
|
1180
1180
|
|
|
1181
|
+
"container_child_block": {
|
|
1182
|
+
"description": "A block allowed inside a container block's child_blocks array. Slack documents this set as: actions, context, divider, file, header, image, input, rich_text, section, table, video (https://docs.slack.dev/reference/block-kit/blocks/container-block). Notably excludes container itself (no nesting) and message-only chrome like card/carousel/markdown.",
|
|
1183
|
+
"oneOf": [
|
|
1184
|
+
{ "$ref": "#/$defs/actions_block" },
|
|
1185
|
+
{ "$ref": "#/$defs/context_block" },
|
|
1186
|
+
{ "$ref": "#/$defs/divider_block" },
|
|
1187
|
+
{ "$ref": "#/$defs/file_block" },
|
|
1188
|
+
{ "$ref": "#/$defs/header_block" },
|
|
1189
|
+
{ "$ref": "#/$defs/image_block" },
|
|
1190
|
+
{ "$ref": "#/$defs/input_block" },
|
|
1191
|
+
{ "$ref": "#/$defs/rich_text_block" },
|
|
1192
|
+
{ "$ref": "#/$defs/section_block" },
|
|
1193
|
+
{ "$ref": "#/$defs/table_block" },
|
|
1194
|
+
{ "$ref": "#/$defs/video_block" }
|
|
1195
|
+
]
|
|
1196
|
+
},
|
|
1197
|
+
|
|
1198
|
+
"container_block": {
|
|
1199
|
+
"description": "A general-purpose wrapper that groups child blocks into a single, optionally collapsible unit with a configurable width. Messages only (https://docs.slack.dev/reference/block-kit/blocks/container-block). default_collapsed only takes effect when is_collapsible is true; the schema rejects default_collapsed: true without is_collapsible: true.",
|
|
1200
|
+
"type": "object",
|
|
1201
|
+
"additionalProperties": false,
|
|
1202
|
+
"required": ["type", "title", "child_blocks"],
|
|
1203
|
+
"properties": {
|
|
1204
|
+
"type": { "const": "container" },
|
|
1205
|
+
"block_id": { "$ref": "#/$defs/block_id" },
|
|
1206
|
+
"title": {
|
|
1207
|
+
"allOf": [{ "$ref": "#/$defs/plain_text_object" }, { "properties": { "text": { "maxLength": 150 } } }]
|
|
1208
|
+
},
|
|
1209
|
+
"subtitle": {
|
|
1210
|
+
"allOf": [{ "$ref": "#/$defs/plain_text_object" }, { "properties": { "text": { "maxLength": 150 } } }]
|
|
1211
|
+
},
|
|
1212
|
+
"icon": { "$ref": "#/$defs/image_element" },
|
|
1213
|
+
"width": { "enum": ["narrow", "standard", "wide", "full"] },
|
|
1214
|
+
"is_collapsible": { "type": "boolean" },
|
|
1215
|
+
"default_collapsed": { "type": "boolean" },
|
|
1216
|
+
"child_blocks": {
|
|
1217
|
+
"type": "array",
|
|
1218
|
+
"minItems": 1,
|
|
1219
|
+
"maxItems": 10,
|
|
1220
|
+
"items": { "$ref": "#/$defs/container_child_block" }
|
|
1221
|
+
}
|
|
1222
|
+
},
|
|
1223
|
+
"if": {
|
|
1224
|
+
"properties": { "default_collapsed": { "const": true } },
|
|
1225
|
+
"required": ["default_collapsed"]
|
|
1226
|
+
},
|
|
1227
|
+
"then": {
|
|
1228
|
+
"properties": { "is_collapsible": { "const": true } },
|
|
1229
|
+
"required": ["is_collapsible"]
|
|
1230
|
+
}
|
|
1231
|
+
},
|
|
1232
|
+
|
|
1181
1233
|
"context_actions_block": {
|
|
1182
1234
|
"type": "object",
|
|
1183
1235
|
"additionalProperties": false,
|
|
@@ -1300,6 +1352,69 @@
|
|
|
1300
1352
|
]
|
|
1301
1353
|
},
|
|
1302
1354
|
|
|
1355
|
+
"data_table_cell": {
|
|
1356
|
+
"description": "A cell inside a data_table_block row. `raw_text` / `raw_number` for simple values, `rich_text` for formatted content. Per https://docs.slack.dev/reference/block-kit/blocks/data-table-block. The docs' per-cell schemas list `properties` without a `required` array; we mirror `table_cell` and require the value-bearing field(s). The rule 'the first (header) row cannot contain rich_text cells' is a row-position constraint JSON Schema can't express and is not enforced here.",
|
|
1357
|
+
"oneOf": [
|
|
1358
|
+
{
|
|
1359
|
+
"type": "object",
|
|
1360
|
+
"additionalProperties": false,
|
|
1361
|
+
"required": ["type", "text"],
|
|
1362
|
+
"properties": {
|
|
1363
|
+
"type": { "const": "raw_text" },
|
|
1364
|
+
"text": { "type": "string", "minLength": 1 }
|
|
1365
|
+
}
|
|
1366
|
+
},
|
|
1367
|
+
{
|
|
1368
|
+
"type": "object",
|
|
1369
|
+
"additionalProperties": false,
|
|
1370
|
+
"required": ["type", "value"],
|
|
1371
|
+
"properties": {
|
|
1372
|
+
"type": { "const": "raw_number" },
|
|
1373
|
+
"value": { "type": "number" },
|
|
1374
|
+
"text": { "type": "string", "minLength": 1 }
|
|
1375
|
+
}
|
|
1376
|
+
},
|
|
1377
|
+
{
|
|
1378
|
+
"type": "object",
|
|
1379
|
+
"additionalProperties": false,
|
|
1380
|
+
"required": ["type", "elements"],
|
|
1381
|
+
"properties": {
|
|
1382
|
+
"type": { "const": "rich_text" },
|
|
1383
|
+
"elements": {
|
|
1384
|
+
"type": "array",
|
|
1385
|
+
"items": { "$ref": "#/$defs/rich_text_container_element" }
|
|
1386
|
+
}
|
|
1387
|
+
}
|
|
1388
|
+
}
|
|
1389
|
+
]
|
|
1390
|
+
},
|
|
1391
|
+
|
|
1392
|
+
"data_table_block": {
|
|
1393
|
+
"description": "Rich, interactive table with pagination, sorting, and filtering (https://docs.slack.dev/reference/block-kit/blocks/data-table-block). Distinct from `table_block`, which is a simpler static table. The single-table and aggregate 10,000-character limits are payload-level rules not enforced here. `row_header_column_index` must point at an existing column, a cross-field rule JSON Schema can't check (bounded to 0–19 since a row has at most 20 cells).",
|
|
1394
|
+
"type": "object",
|
|
1395
|
+
"additionalProperties": false,
|
|
1396
|
+
"required": ["type", "caption", "rows"],
|
|
1397
|
+
"properties": {
|
|
1398
|
+
"type": { "const": "data_table" },
|
|
1399
|
+
"block_id": { "$ref": "#/$defs/block_id" },
|
|
1400
|
+
"caption": { "type": "string", "minLength": 1 },
|
|
1401
|
+
"page_size": { "type": "integer", "minimum": 1, "maximum": 100 },
|
|
1402
|
+
"row_header_column_index": { "type": "integer", "minimum": 0, "maximum": 19 },
|
|
1403
|
+
"rows": {
|
|
1404
|
+
"description": "First row is the header; 2–101 rows total (1 header + 1–100 data rows), 1–20 cells per row.",
|
|
1405
|
+
"type": "array",
|
|
1406
|
+
"minItems": 2,
|
|
1407
|
+
"maxItems": 101,
|
|
1408
|
+
"items": {
|
|
1409
|
+
"type": "array",
|
|
1410
|
+
"minItems": 1,
|
|
1411
|
+
"maxItems": 20,
|
|
1412
|
+
"items": { "$ref": "#/$defs/data_table_cell" }
|
|
1413
|
+
}
|
|
1414
|
+
}
|
|
1415
|
+
}
|
|
1416
|
+
},
|
|
1417
|
+
|
|
1303
1418
|
"data_visualization_block": {
|
|
1304
1419
|
"description": "Renders data as a line, bar, area, or pie chart. Messages only (https://docs.slack.dev/reference/block-kit/blocks/data-visualization-block). Slack renders at most two data_visualization blocks per message (enforced via the checkDataVisualizationMax helper, since JSON Schema can't count sibling blocks). Two further runtime rules are enforced via checkDataVisualizationConsistency, since they depend on sibling-field values JSON Schema can't compare: series names must be unique within a chart, and each series must contain exactly one data point per axis_config.categories label.",
|
|
1305
1420
|
"type": "object",
|
|
@@ -1623,8 +1738,10 @@
|
|
|
1623
1738
|
{ "$ref": "#/$defs/alert_block" },
|
|
1624
1739
|
{ "$ref": "#/$defs/card_block" },
|
|
1625
1740
|
{ "$ref": "#/$defs/carousel_block" },
|
|
1741
|
+
{ "$ref": "#/$defs/container_block" },
|
|
1626
1742
|
{ "$ref": "#/$defs/context_actions_block" },
|
|
1627
1743
|
{ "$ref": "#/$defs/context_block" },
|
|
1744
|
+
{ "$ref": "#/$defs/data_table_block" },
|
|
1628
1745
|
{ "$ref": "#/$defs/data_visualization_block" },
|
|
1629
1746
|
{ "$ref": "#/$defs/divider_block" },
|
|
1630
1747
|
{ "$ref": "#/$defs/file_block" },
|