@assistant-ui/react-generative-ui 0.0.24 → 0.1.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.
- package/README.md +2 -0
- package/dist/a2ui.d.ts +1 -4
- package/dist/a2ui.d.ts.map +1 -1
- package/dist/a2ui.js +1 -4
- package/dist/index.d.ts +1 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -10
- package/dist/index.server.d.ts +1 -2
- package/dist/index.server.d.ts.map +1 -1
- package/dist/index.server.js +1 -10
- package/dist/ir.d.ts +1 -111
- package/dist/ir.d.ts.map +1 -1
- package/dist/ir.js +1 -175
- package/dist/slack.d.ts +1 -4
- package/dist/slack.d.ts.map +1 -1
- package/dist/slack.js +1 -4
- package/dist/teams.d.ts +1 -4
- package/dist/teams.d.ts.map +1 -1
- package/dist/teams.js +1 -4
- package/package.json +4 -5
- package/src/a2ui.ts +1 -22
- package/src/index.server.ts +1 -2
- package/src/index.test.ts +75 -0
- package/src/index.ts +1 -2
- package/src/ir.ts +1 -279
- package/src/slack.ts +1 -39
- package/src/teams.ts +1 -35
- package/dist/JSONGenerativeUI.client.d.ts +0 -28
- package/dist/JSONGenerativeUI.client.d.ts.map +0 -1
- package/dist/JSONGenerativeUI.client.js +0 -101
- package/dist/JSONGenerativeUI.client.js.map +0 -1
- package/dist/JSONGenerativeUI.server.d.ts +0 -21
- package/dist/JSONGenerativeUI.server.d.ts.map +0 -1
- package/dist/JSONGenerativeUI.server.js +0 -32
- package/dist/JSONGenerativeUI.server.js.map +0 -1
- package/dist/JSONGenerativeUI.shared.d.ts +0 -63
- package/dist/JSONGenerativeUI.shared.d.ts.map +0 -1
- package/dist/JSONGenerativeUI.shared.js +0 -31
- package/dist/JSONGenerativeUI.shared.js.map +0 -1
- package/dist/RadioGroupScope.d.ts +0 -6
- package/dist/RadioGroupScope.d.ts.map +0 -1
- package/dist/RadioGroupScope.js +0 -25
- package/dist/RadioGroupScope.js.map +0 -1
- package/dist/a2ui/BindingContext.d.ts +0 -11
- package/dist/a2ui/BindingContext.d.ts.map +0 -1
- package/dist/a2ui/BindingContext.js +0 -12
- package/dist/a2ui/BindingContext.js.map +0 -1
- package/dist/a2ui/PresentRenderer.d.ts +0 -11
- package/dist/a2ui/PresentRenderer.d.ts.map +0 -1
- package/dist/a2ui/PresentRenderer.js +0 -39
- package/dist/a2ui/PresentRenderer.js.map +0 -1
- package/dist/a2ui/convert.d.ts +0 -15
- package/dist/a2ui/convert.d.ts.map +0 -1
- package/dist/a2ui/convert.js +0 -728
- package/dist/a2ui/convert.js.map +0 -1
- package/dist/a2ui/dataModel.d.ts +0 -9
- package/dist/a2ui/dataModel.d.ts.map +0 -1
- package/dist/a2ui/dataModel.js +0 -44
- package/dist/a2ui/dataModel.js.map +0 -1
- package/dist/a2ui/reducer.d.ts +0 -8
- package/dist/a2ui/reducer.d.ts.map +0 -1
- package/dist/a2ui/reducer.js +0 -242
- package/dist/a2ui/reducer.js.map +0 -1
- package/dist/a2ui/snapshot.d.ts +0 -3
- package/dist/a2ui/snapshot.d.ts.map +0 -1
- package/dist/a2ui/snapshot.js +0 -33
- package/dist/a2ui/snapshot.js.map +0 -1
- package/dist/a2ui/types.d.ts +0 -88
- package/dist/a2ui/types.d.ts.map +0 -1
- package/dist/a2ui/types.js +0 -6
- package/dist/a2ui/types.js.map +0 -1
- package/dist/a2ui/valueFunctions.d.ts +0 -16
- package/dist/a2ui/valueFunctions.d.ts.map +0 -1
- package/dist/a2ui/valueFunctions.js +0 -332
- package/dist/a2ui/valueFunctions.js.map +0 -1
- package/dist/actionRegistry.d.ts +0 -29
- package/dist/actionRegistry.d.ts.map +0 -1
- package/dist/actionRegistry.js +0 -41
- package/dist/actionRegistry.js.map +0 -1
- package/dist/answeredValues.d.ts +0 -16
- package/dist/answeredValues.d.ts.map +0 -1
- package/dist/answeredValues.js +0 -37
- package/dist/answeredValues.js.map +0 -1
- package/dist/buildPresentParameters.d.ts +0 -21
- package/dist/buildPresentParameters.d.ts.map +0 -1
- package/dist/buildPresentParameters.js +0 -95
- package/dist/buildPresentParameters.js.map +0 -1
- package/dist/constants.d.ts +0 -15
- package/dist/constants.d.ts.map +0 -1
- package/dist/constants.js +0 -19
- package/dist/constants.js.map +0 -1
- package/dist/convert/boundSpec.d.ts +0 -48
- package/dist/convert/boundSpec.d.ts.map +0 -1
- package/dist/convert/boundSpec.js +0 -108
- package/dist/convert/boundSpec.js.map +0 -1
- package/dist/convert/copyBounded.d.ts +0 -25
- package/dist/convert/copyBounded.d.ts.map +0 -1
- package/dist/convert/copyBounded.js +0 -38
- package/dist/convert/copyBounded.js.map +0 -1
- package/dist/convert/isElement.d.ts +0 -3
- package/dist/convert/isElement.d.ts.map +0 -1
- package/dist/convert/isElement.js +0 -6
- package/dist/convert/isElement.js.map +0 -1
- package/dist/convert/takeRun.d.ts +0 -6
- package/dist/convert/takeRun.d.ts.map +0 -1
- package/dist/convert/takeRun.js +0 -20
- package/dist/convert/takeRun.js.map +0 -1
- package/dist/defineGenerativeComponents.d.ts +0 -29
- package/dist/defineGenerativeComponents.d.ts.map +0 -1
- package/dist/defineGenerativeComponents.js +0 -34
- package/dist/defineGenerativeComponents.js.map +0 -1
- package/dist/fieldReferences.d.ts +0 -9
- package/dist/fieldReferences.d.ts.map +0 -1
- package/dist/fieldReferences.js +0 -53
- package/dist/fieldReferences.js.map +0 -1
- package/dist/generativeUIToJSX.d.ts +0 -18
- package/dist/generativeUIToJSX.d.ts.map +0 -1
- package/dist/generativeUIToJSX.js +0 -76
- package/dist/generativeUIToJSX.js.map +0 -1
- package/dist/index.shared.d.ts +0 -15
- package/dist/index.shared.d.ts.map +0 -1
- package/dist/index.shared.js +0 -9
- package/dist/ir.js.map +0 -1
- package/dist/renderGenerativeUI.d.ts +0 -14
- package/dist/renderGenerativeUI.d.ts.map +0 -1
- package/dist/renderGenerativeUI.js +0 -83
- package/dist/renderGenerativeUI.js.map +0 -1
- package/dist/scopeSchema.d.ts +0 -6
- package/dist/scopeSchema.d.ts.map +0 -1
- package/dist/scopeSchema.js +0 -56
- package/dist/scopeSchema.js.map +0 -1
- package/dist/slack/constants.d.ts +0 -93
- package/dist/slack/constants.d.ts.map +0 -1
- package/dist/slack/constants.js +0 -146
- package/dist/slack/constants.js.map +0 -1
- package/dist/slack/decodeBlockAction.d.ts +0 -10
- package/dist/slack/decodeBlockAction.d.ts.map +0 -1
- package/dist/slack/decodeBlockAction.js +0 -129
- package/dist/slack/decodeBlockAction.js.map +0 -1
- package/dist/slack/fromSlackBlocks.d.ts +0 -27
- package/dist/slack/fromSlackBlocks.d.ts.map +0 -1
- package/dist/slack/fromSlackBlocks.js +0 -483
- package/dist/slack/fromSlackBlocks.js.map +0 -1
- package/dist/slack/toSlackBlocks.d.ts +0 -4
- package/dist/slack/toSlackBlocks.d.ts.map +0 -1
- package/dist/slack/toSlackBlocks.js +0 -901
- package/dist/slack/toSlackBlocks.js.map +0 -1
- package/dist/slack/types.d.ts +0 -204
- package/dist/slack/types.d.ts.map +0 -1
- package/dist/slack/types.js +0 -0
- package/dist/teams/constants.d.ts +0 -34
- package/dist/teams/constants.d.ts.map +0 -1
- package/dist/teams/constants.js +0 -68
- package/dist/teams/constants.js.map +0 -1
- package/dist/teams/decodeSubmitData.d.ts +0 -26
- package/dist/teams/decodeSubmitData.d.ts.map +0 -1
- package/dist/teams/decodeSubmitData.js +0 -70
- package/dist/teams/decodeSubmitData.js.map +0 -1
- package/dist/teams/temporalId.d.ts +0 -5
- package/dist/teams/temporalId.d.ts.map +0 -1
- package/dist/teams/temporalId.js +0 -28
- package/dist/teams/temporalId.js.map +0 -1
- package/dist/teams/toAdaptiveCard.d.ts +0 -45
- package/dist/teams/toAdaptiveCard.d.ts.map +0 -1
- package/dist/teams/toAdaptiveCard.js +0 -642
- package/dist/teams/toAdaptiveCard.js.map +0 -1
- package/dist/teams/toTeamsAttachments.d.ts +0 -10
- package/dist/teams/toTeamsAttachments.d.ts.map +0 -1
- package/dist/teams/toTeamsAttachments.js +0 -99
- package/dist/teams/toTeamsAttachments.js.map +0 -1
- package/dist/teams/types.d.ts +0 -224
- package/dist/teams/types.d.ts.map +0 -1
- package/dist/teams/types.js +0 -0
- package/dist/temporal.d.ts +0 -33
- package/dist/temporal.d.ts.map +0 -1
- package/dist/temporal.js +0 -153
- package/dist/temporal.js.map +0 -1
- package/dist/types.d.ts +0 -99
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js +0 -0
- package/dist/vocabulary/alert.d.ts +0 -32
- package/dist/vocabulary/alert.d.ts.map +0 -1
- package/dist/vocabulary/alert.js +0 -160
- package/dist/vocabulary/alert.js.map +0 -1
- package/dist/vocabulary/collectFormValues.d.ts +0 -23
- package/dist/vocabulary/collectFormValues.d.ts.map +0 -1
- package/dist/vocabulary/collectFormValues.js +0 -44
- package/dist/vocabulary/collectFormValues.js.map +0 -1
- package/dist/vocabulary/data.d.ts +0 -66
- package/dist/vocabulary/data.d.ts.map +0 -1
- package/dist/vocabulary/data.js +0 -503
- package/dist/vocabulary/data.js.map +0 -1
- package/dist/vocabulary/dispatch.d.ts +0 -9
- package/dist/vocabulary/dispatch.d.ts.map +0 -1
- package/dist/vocabulary/dispatch.js +0 -50
- package/dist/vocabulary/dispatch.js.map +0 -1
- package/dist/vocabulary/fact.d.ts +0 -19
- package/dist/vocabulary/fact.d.ts.map +0 -1
- package/dist/vocabulary/fact.js +0 -51
- package/dist/vocabulary/fact.js.map +0 -1
- package/dist/vocabulary/form.d.ts +0 -11
- package/dist/vocabulary/form.d.ts.map +0 -1
- package/dist/vocabulary/form.js +0 -23
- package/dist/vocabulary/form.js.map +0 -1
- package/dist/vocabulary/formatValue.d.ts +0 -7
- package/dist/vocabulary/formatValue.d.ts.map +0 -1
- package/dist/vocabulary/formatValue.js +0 -76
- package/dist/vocabulary/formatValue.js.map +0 -1
- package/dist/vocabulary/icon.d.ts +0 -41
- package/dist/vocabulary/icon.d.ts.map +0 -1
- package/dist/vocabulary/icon.js +0 -272
- package/dist/vocabulary/icon.js.map +0 -1
- package/dist/vocabulary/index.d.ts +0 -12
- package/dist/vocabulary/index.d.ts.map +0 -1
- package/dist/vocabulary/index.js +0 -36
- package/dist/vocabulary/index.js.map +0 -1
- package/dist/vocabulary/interactive.d.ts +0 -230
- package/dist/vocabulary/interactive.d.ts.map +0 -1
- package/dist/vocabulary/interactive.js +0 -584
- package/dist/vocabulary/interactive.js.map +0 -1
- package/dist/vocabulary/layout.d.ts +0 -79
- package/dist/vocabulary/layout.d.ts.map +0 -1
- package/dist/vocabulary/layout.js +0 -139
- package/dist/vocabulary/layout.js.map +0 -1
- package/dist/vocabulary/list.d.ts +0 -14
- package/dist/vocabulary/list.d.ts.map +0 -1
- package/dist/vocabulary/list.js +0 -50
- package/dist/vocabulary/list.js.map +0 -1
- package/dist/vocabulary/media.d.ts +0 -25
- package/dist/vocabulary/media.d.ts.map +0 -1
- package/dist/vocabulary/media.js +0 -42
- package/dist/vocabulary/media.js.map +0 -1
- package/dist/vocabulary/text.d.ts +0 -57
- package/dist/vocabulary/text.d.ts.map +0 -1
- package/dist/vocabulary/text.js +0 -49
- package/dist/vocabulary/text.js.map +0 -1
- package/dist/vocabulary/toTextContent.d.ts +0 -2
- package/dist/vocabulary/toTextContent.d.ts.map +0 -1
- package/dist/vocabulary/toTextContent.js +0 -6
- package/dist/vocabulary/toTextContent.js.map +0 -1
- package/src/JSONGenerativeUI.client.tsx +0 -168
- package/src/JSONGenerativeUI.server.tsx +0 -39
- package/src/JSONGenerativeUI.shared.ts +0 -90
- package/src/JSONGenerativeUI.test.tsx +0 -1298
- package/src/RadioGroupScope.server.test.tsx +0 -24
- package/src/RadioGroupScope.tsx +0 -34
- package/src/a2ui/BindingContext.ts +0 -26
- package/src/a2ui/PresentRenderer.tsx +0 -83
- package/src/a2ui/convert.test.ts +0 -2923
- package/src/a2ui/convert.ts +0 -1207
- package/src/a2ui/dataModel.ts +0 -69
- package/src/a2ui/reducer.test.ts +0 -422
- package/src/a2ui/reducer.ts +0 -363
- package/src/a2ui/snapshot.test.ts +0 -52
- package/src/a2ui/snapshot.ts +0 -52
- package/src/a2ui/types.ts +0 -114
- package/src/a2ui/valueFunctions.test.ts +0 -271
- package/src/a2ui/valueFunctions.ts +0 -523
- package/src/actionRegistry.test.ts +0 -90
- package/src/actionRegistry.ts +0 -88
- package/src/answeredValues.test.ts +0 -33
- package/src/answeredValues.tsx +0 -70
- package/src/buildPresentParameters.test.ts +0 -246
- package/src/buildPresentParameters.ts +0 -130
- package/src/constants.ts +0 -17
- package/src/convert/boundSpec.test.ts +0 -192
- package/src/convert/boundSpec.ts +0 -134
- package/src/convert/copyBounded.test.ts +0 -131
- package/src/convert/copyBounded.ts +0 -38
- package/src/convert/isElement.ts +0 -6
- package/src/convert/takeRun.test.ts +0 -64
- package/src/convert/takeRun.ts +0 -19
- package/src/defineGenerativeComponents.ts +0 -38
- package/src/fieldReferences.test.ts +0 -66
- package/src/fieldReferences.ts +0 -83
- package/src/generativeUIToJSX.test.ts +0 -268
- package/src/generativeUIToJSX.ts +0 -152
- package/src/index.server.test.ts +0 -106
- package/src/index.shared.ts +0 -61
- package/src/ir.test.ts +0 -203
- package/src/renderGenerativeUI.test.tsx +0 -373
- package/src/renderGenerativeUI.tsx +0 -165
- package/src/scopeSchema.test.ts +0 -72
- package/src/scopeSchema.ts +0 -71
- package/src/slack/a2uiSlack.test.ts +0 -198
- package/src/slack/constants.ts +0 -194
- package/src/slack/datePicker.test.ts +0 -612
- package/src/slack/decodeBlockAction.test.ts +0 -233
- package/src/slack/decodeBlockAction.ts +0 -232
- package/src/slack/fromSlackBlocks.test.ts +0 -1465
- package/src/slack/fromSlackBlocks.ts +0 -789
- package/src/slack/toSlackBlocks.test.ts +0 -3065
- package/src/slack/toSlackBlocks.ts +0 -1818
- package/src/slack/types.ts +0 -264
- package/src/teams/constants.ts +0 -93
- package/src/teams/decodeSubmitData.test.ts +0 -397
- package/src/teams/decodeSubmitData.ts +0 -110
- package/src/teams/temporal.test.ts +0 -766
- package/src/teams/temporalId.ts +0 -56
- package/src/teams/toAdaptiveCard.test.ts +0 -1897
- package/src/teams/toAdaptiveCard.ts +0 -1057
- package/src/teams/toTeamsAttachments.test.ts +0 -74
- package/src/teams/toTeamsAttachments.ts +0 -133
- package/src/teams/types.ts +0 -266
- package/src/temporal.test.ts +0 -337
- package/src/temporal.ts +0 -263
- package/src/types.ts +0 -119
- package/src/vocabulary/alert.test.tsx +0 -427
- package/src/vocabulary/alert.tsx +0 -217
- package/src/vocabulary/collectFormValues.test.ts +0 -389
- package/src/vocabulary/collectFormValues.ts +0 -116
- package/src/vocabulary/data.test.tsx +0 -858
- package/src/vocabulary/data.tsx +0 -819
- package/src/vocabulary/datepicker.dom.test.tsx +0 -1457
- package/src/vocabulary/dispatch.ts +0 -83
- package/src/vocabulary/fact.test.tsx +0 -94
- package/src/vocabulary/fact.tsx +0 -54
- package/src/vocabulary/form.test.tsx +0 -113
- package/src/vocabulary/form.tsx +0 -39
- package/src/vocabulary/formatValue.test.ts +0 -72
- package/src/vocabulary/formatValue.ts +0 -127
- package/src/vocabulary/icon.test.tsx +0 -64
- package/src/vocabulary/icon.tsx +0 -174
- package/src/vocabulary/index.test.ts +0 -65
- package/src/vocabulary/index.ts +0 -33
- package/src/vocabulary/interactive.dispatch.test.tsx +0 -454
- package/src/vocabulary/interactive.dom.test.tsx +0 -1747
- package/src/vocabulary/interactive.test.tsx +0 -377
- package/src/vocabulary/interactive.tsx +0 -1109
- package/src/vocabulary/layout.test.tsx +0 -323
- package/src/vocabulary/layout.tsx +0 -247
- package/src/vocabulary/list.test.tsx +0 -222
- package/src/vocabulary/list.tsx +0 -50
- package/src/vocabulary/media.test.tsx +0 -85
- package/src/vocabulary/media.tsx +0 -56
- package/src/vocabulary/text.test.tsx +0 -102
- package/src/vocabulary/text.tsx +0 -60
- package/src/vocabulary/toTextContent.ts +0 -2
package/dist/slack/constants.js
DELETED
|
@@ -1,146 +0,0 @@
|
|
|
1
|
-
//#region src/slack/constants.ts
|
|
2
|
-
/** The block limit for a Slack message. */
|
|
3
|
-
const MESSAGE_BLOCK_CAP = 50;
|
|
4
|
-
/** The block limit for a Slack modal. */
|
|
5
|
-
const MODAL_BLOCK_CAP = 100;
|
|
6
|
-
/**
|
|
7
|
-
* The maximum number of top-level blocks accepted when parsing Slack Block
|
|
8
|
-
* Kit JSON back into generative UI, guarding against a hostile or malformed
|
|
9
|
-
* payload.
|
|
10
|
-
*/
|
|
11
|
-
const INBOUND_BLOCK_CAP = 200;
|
|
12
|
-
/** The character limit for header text. */
|
|
13
|
-
const HEADER_TEXT_CAP = 150;
|
|
14
|
-
/** The character limit for section text. */
|
|
15
|
-
const SECTION_TEXT_CAP = 3e3;
|
|
16
|
-
/** The maximum number of fields in one section. */
|
|
17
|
-
const FACT_FIELD_CAP = 10;
|
|
18
|
-
/** The character limit for one section field. */
|
|
19
|
-
const FACT_FIELD_TEXT_CAP = 2e3;
|
|
20
|
-
/** The character limit for button labels and option labels. */
|
|
21
|
-
const INTERACTIVE_TEXT_CAP = 75;
|
|
22
|
-
/** The character limit for an action_id. */
|
|
23
|
-
const ACTION_ID_CAP = 255;
|
|
24
|
-
/** The character limit for a button's serialized value payload. */
|
|
25
|
-
const BUTTON_VALUE_CAP = 2e3;
|
|
26
|
-
/** The maximum number of elements in one actions block. */
|
|
27
|
-
const ACTIONS_ELEMENT_CAP = 25;
|
|
28
|
-
/** The maximum number of options in a static select. */
|
|
29
|
-
const SELECT_OPTION_CAP = 100;
|
|
30
|
-
/** The maximum number of options in a radio-button group. */
|
|
31
|
-
const RADIO_OPTION_CAP = 10;
|
|
32
|
-
/** The maximum number of options in a checkbox group. */
|
|
33
|
-
const CHECKBOX_OPTION_CAP = 10;
|
|
34
|
-
/** The character limit for a select or input placeholder. */
|
|
35
|
-
const PLACEHOLDER_TEXT_CAP = 150;
|
|
36
|
-
/** The character limit for an input's label. */
|
|
37
|
-
const INPUT_LABEL_CAP = 2e3;
|
|
38
|
-
/** The maximum number of elements in one context block. */
|
|
39
|
-
const CONTEXT_ELEMENT_CAP = 10;
|
|
40
|
-
/** The character limit for one context element's text. */
|
|
41
|
-
const CONTEXT_TEXT_CAP = 3e3;
|
|
42
|
-
/** The character limit for card titles and subtitles. */
|
|
43
|
-
const CARD_TITLE_CAP = 150;
|
|
44
|
-
/** The character limit for a card's body text. */
|
|
45
|
-
const CARD_BODY_CAP = 200;
|
|
46
|
-
/** The character limit for a card's subtext. */
|
|
47
|
-
const CARD_SUBTEXT_CAP = 200;
|
|
48
|
-
/** The maximum number of buttons in a card's actions. */
|
|
49
|
-
const CARD_ACTIONS_CAP = 3;
|
|
50
|
-
/** The minimum number of elements in a renderable carousel. */
|
|
51
|
-
const CAROUSEL_CARD_MIN = 1;
|
|
52
|
-
/** The maximum number of elements in a carousel. */
|
|
53
|
-
const CAROUSEL_CARD_CAP = 10;
|
|
54
|
-
/** The character limit for an alert's text. */
|
|
55
|
-
const ALERT_TEXT_CAP = 200;
|
|
56
|
-
/**
|
|
57
|
-
* The maximum number of data rows in a data-table block; the emitted `rows`
|
|
58
|
-
* array additionally carries one header row.
|
|
59
|
-
*/
|
|
60
|
-
const DATA_TABLE_ROW_CAP = 200;
|
|
61
|
-
/** The maximum number of columns in a data-table block. */
|
|
62
|
-
const DATA_TABLE_COLUMN_CAP = 20;
|
|
63
|
-
/**
|
|
64
|
-
* The cumulative character limit (summed across every cell's text) shared by
|
|
65
|
-
* every data-table block in one payload.
|
|
66
|
-
*/
|
|
67
|
-
const DATA_TABLE_CHAR_BUDGET = 2e4;
|
|
68
|
-
/** The caption emitted on every native data-table block. */
|
|
69
|
-
const TABLE_CAPTION = "Table";
|
|
70
|
-
/** The cumulative character limit for native markdown blocks. */
|
|
71
|
-
const MARKDOWN_TEXT_BUDGET = 12e3;
|
|
72
|
-
/** Builds the message-surface fallback for an alert. */
|
|
73
|
-
function buildAlertFallback(title, description, tone) {
|
|
74
|
-
const emoji = {
|
|
75
|
-
info: "ℹ️",
|
|
76
|
-
success: "✅",
|
|
77
|
-
warning: "⚠️",
|
|
78
|
-
danger: "🛑"
|
|
79
|
-
}[tone];
|
|
80
|
-
return [{
|
|
81
|
-
type: "context",
|
|
82
|
-
elements: [{
|
|
83
|
-
type: "mrkdwn",
|
|
84
|
-
text: title ? `${emoji} *${title}*` : emoji
|
|
85
|
-
}]
|
|
86
|
-
}, {
|
|
87
|
-
type: "section",
|
|
88
|
-
text: {
|
|
89
|
-
type: "mrkdwn",
|
|
90
|
-
text: description
|
|
91
|
-
}
|
|
92
|
-
}];
|
|
93
|
-
}
|
|
94
|
-
/** Builds a 2026 Slack modal-only alert block, mapping `tone` to its `level`. */
|
|
95
|
-
function buildAlertBlock(text, tone) {
|
|
96
|
-
return {
|
|
97
|
-
type: "alert",
|
|
98
|
-
text: {
|
|
99
|
-
type: "mrkdwn",
|
|
100
|
-
text
|
|
101
|
-
},
|
|
102
|
-
level: tone === "danger" ? "error" : tone
|
|
103
|
-
};
|
|
104
|
-
}
|
|
105
|
-
/** Builds a 2026 Slack card block from its already-clamped fields. */
|
|
106
|
-
function buildCardBlock(fields) {
|
|
107
|
-
const { heroImage, title, subtitle, body, subtext, actions } = fields;
|
|
108
|
-
return {
|
|
109
|
-
type: "card",
|
|
110
|
-
...heroImage !== void 0 ? { hero_image: heroImage } : {},
|
|
111
|
-
...title !== void 0 ? { title } : {},
|
|
112
|
-
...subtitle !== void 0 ? { subtitle } : {},
|
|
113
|
-
...body !== void 0 ? { body } : {},
|
|
114
|
-
...subtext !== void 0 ? { subtext } : {},
|
|
115
|
-
...actions !== void 0 ? { actions } : {}
|
|
116
|
-
};
|
|
117
|
-
}
|
|
118
|
-
/** Builds a 2026 Slack carousel block. */
|
|
119
|
-
function buildCarouselBlock(elements) {
|
|
120
|
-
return {
|
|
121
|
-
type: "carousel",
|
|
122
|
-
elements
|
|
123
|
-
};
|
|
124
|
-
}
|
|
125
|
-
/** Builds a 2026 Slack data-table block; `rows[0]` must be the header row. */
|
|
126
|
-
function buildDataTableBlock(rows) {
|
|
127
|
-
return {
|
|
128
|
-
type: "data_table",
|
|
129
|
-
caption: TABLE_CAPTION,
|
|
130
|
-
rows
|
|
131
|
-
};
|
|
132
|
-
}
|
|
133
|
-
/** Builds the final note used when a surface block budget is exceeded. */
|
|
134
|
-
function buildBlockBudgetNote(omitted) {
|
|
135
|
-
return {
|
|
136
|
-
type: "context",
|
|
137
|
-
elements: [{
|
|
138
|
-
type: "mrkdwn",
|
|
139
|
-
text: `${omitted} ${omitted === 1 ? "block was" : "blocks were"} omitted.`
|
|
140
|
-
}]
|
|
141
|
-
};
|
|
142
|
-
}
|
|
143
|
-
//#endregion
|
|
144
|
-
export { ACTIONS_ELEMENT_CAP, ACTION_ID_CAP, ALERT_TEXT_CAP, BUTTON_VALUE_CAP, CARD_ACTIONS_CAP, CARD_BODY_CAP, CARD_SUBTEXT_CAP, CARD_TITLE_CAP, CAROUSEL_CARD_CAP, CAROUSEL_CARD_MIN, CHECKBOX_OPTION_CAP, CONTEXT_ELEMENT_CAP, CONTEXT_TEXT_CAP, DATA_TABLE_CHAR_BUDGET, DATA_TABLE_COLUMN_CAP, DATA_TABLE_ROW_CAP, FACT_FIELD_CAP, FACT_FIELD_TEXT_CAP, HEADER_TEXT_CAP, INBOUND_BLOCK_CAP, INPUT_LABEL_CAP, INTERACTIVE_TEXT_CAP, MARKDOWN_TEXT_BUDGET, MESSAGE_BLOCK_CAP, MODAL_BLOCK_CAP, PLACEHOLDER_TEXT_CAP, RADIO_OPTION_CAP, SECTION_TEXT_CAP, SELECT_OPTION_CAP, TABLE_CAPTION, buildAlertBlock, buildAlertFallback, buildBlockBudgetNote, buildCardBlock, buildCarouselBlock, buildDataTableBlock };
|
|
145
|
-
|
|
146
|
-
//# sourceMappingURL=constants.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"constants.js","names":[],"sources":["../../src/slack/constants.ts"],"sourcesContent":["import type {\n SlackAlertBlock,\n SlackButtonElement,\n SlackCardBlock,\n SlackCarouselBlock,\n SlackContextBlock,\n SlackDataTableBlock,\n SlackDataTableCell,\n SlackImageBlock,\n SlackSectionBlock,\n SlackTextObject,\n} from \"./types\";\n\n/** The block limit for a Slack message. */\nexport const MESSAGE_BLOCK_CAP = 50;\n\n/** The block limit for a Slack modal. */\nexport const MODAL_BLOCK_CAP = 100;\n\n/**\n * The maximum number of top-level blocks accepted when parsing Slack Block\n * Kit JSON back into generative UI, guarding against a hostile or malformed\n * payload.\n */\nexport const INBOUND_BLOCK_CAP = 200;\n\n/** The character limit for header text. */\nexport const HEADER_TEXT_CAP = 150;\n\n/** The character limit for section text. */\nexport const SECTION_TEXT_CAP = 3000;\n\n/** The maximum number of fields in one section. */\nexport const FACT_FIELD_CAP = 10;\n\n/** The character limit for one section field. */\nexport const FACT_FIELD_TEXT_CAP = 2000;\n\n/** The character limit for button labels and option labels. */\nexport const INTERACTIVE_TEXT_CAP = 75;\n\n/** The character limit for an action_id. */\nexport const ACTION_ID_CAP = 255;\n\n/** The character limit for a button's serialized value payload. */\nexport const BUTTON_VALUE_CAP = 2000;\n\n/** The maximum number of elements in one actions block. */\nexport const ACTIONS_ELEMENT_CAP = 25;\n\n/** The maximum number of options in a static select. */\nexport const SELECT_OPTION_CAP = 100;\n\n/** The maximum number of options in a radio-button group. */\nexport const RADIO_OPTION_CAP = 10;\n\n/** The maximum number of options in a checkbox group. */\nexport const CHECKBOX_OPTION_CAP = 10;\n\n/** The character limit for a select or input placeholder. */\nexport const PLACEHOLDER_TEXT_CAP = 150;\n\n/** The character limit for an input's label. */\nexport const INPUT_LABEL_CAP = 2000;\n\n/** The maximum number of elements in one context block. */\nexport const CONTEXT_ELEMENT_CAP = 10;\n\n/** The character limit for one context element's text. */\nexport const CONTEXT_TEXT_CAP = 3000;\n\n/** The character limit for card titles and subtitles. */\nexport const CARD_TITLE_CAP = 150;\n\n/** The character limit for a card's body text. */\nexport const CARD_BODY_CAP = 200;\n\n/** The character limit for a card's subtext. */\nexport const CARD_SUBTEXT_CAP = 200;\n\n/** The maximum number of buttons in a card's actions. */\nexport const CARD_ACTIONS_CAP = 3;\n\n/** The minimum number of elements in a renderable carousel. */\nexport const CAROUSEL_CARD_MIN = 1;\n\n/** The maximum number of elements in a carousel. */\nexport const CAROUSEL_CARD_CAP = 10;\n\n/** The character limit for an alert's text. */\nexport const ALERT_TEXT_CAP = 200;\n\n/**\n * The maximum number of data rows in a data-table block; the emitted `rows`\n * array additionally carries one header row.\n */\nexport const DATA_TABLE_ROW_CAP = 200;\n\n/** The maximum number of columns in a data-table block. */\nexport const DATA_TABLE_COLUMN_CAP = 20;\n\n/**\n * The cumulative character limit (summed across every cell's text) shared by\n * every data-table block in one payload.\n */\nexport const DATA_TABLE_CHAR_BUDGET = 20000;\n\n/** The caption emitted on every native data-table block. */\nexport const TABLE_CAPTION = \"Table\";\n\n/** The cumulative character limit for native markdown blocks. */\nexport const MARKDOWN_TEXT_BUDGET = 12000;\n\n/** Builds the message-surface fallback for an alert. */\nexport function buildAlertFallback(\n title: string,\n description: string,\n tone: \"info\" | \"success\" | \"warning\" | \"danger\",\n): readonly [SlackContextBlock, SlackSectionBlock] {\n const emoji = {\n info: \"ℹ️\",\n success: \"✅\",\n warning: \"⚠️\",\n danger: \"🛑\",\n }[tone];\n return [\n {\n type: \"context\",\n elements: [\n { type: \"mrkdwn\", text: title ? `${emoji} *${title}*` : emoji },\n ],\n },\n { type: \"section\", text: { type: \"mrkdwn\", text: description } },\n ];\n}\n\n/** Builds a 2026 Slack modal-only alert block, mapping `tone` to its `level`. */\nexport function buildAlertBlock(\n text: string,\n tone: \"info\" | \"success\" | \"warning\" | \"danger\",\n): SlackAlertBlock {\n const level = tone === \"danger\" ? \"error\" : tone;\n return { type: \"alert\", text: { type: \"mrkdwn\", text }, level };\n}\n\ntype CardBlockFields = {\n readonly heroImage?: SlackImageBlock;\n readonly title?: SlackTextObject;\n readonly subtitle?: SlackTextObject;\n readonly body?: SlackTextObject;\n readonly subtext?: SlackTextObject;\n readonly actions?: readonly SlackButtonElement[];\n};\n\n/** Builds a 2026 Slack card block from its already-clamped fields. */\nexport function buildCardBlock(fields: CardBlockFields): SlackCardBlock {\n const { heroImage, title, subtitle, body, subtext, actions } = fields;\n return {\n type: \"card\",\n ...(heroImage !== undefined ? { hero_image: heroImage } : {}),\n ...(title !== undefined ? { title } : {}),\n ...(subtitle !== undefined ? { subtitle } : {}),\n ...(body !== undefined ? { body } : {}),\n ...(subtext !== undefined ? { subtext } : {}),\n ...(actions !== undefined ? { actions } : {}),\n };\n}\n\n/** Builds a 2026 Slack carousel block. */\nexport function buildCarouselBlock(\n elements: readonly SlackCardBlock[],\n): SlackCarouselBlock {\n return { type: \"carousel\", elements };\n}\n\n/** Builds a 2026 Slack data-table block; `rows[0]` must be the header row. */\nexport function buildDataTableBlock(\n rows: readonly (readonly SlackDataTableCell[])[],\n): SlackDataTableBlock {\n return { type: \"data_table\", caption: TABLE_CAPTION, rows };\n}\n\n/** Builds the final note used when a surface block budget is exceeded. */\nexport function buildBlockBudgetNote(omitted: number): SlackContextBlock {\n return {\n type: \"context\",\n elements: [\n {\n type: \"mrkdwn\",\n text: `${omitted} ${omitted === 1 ? \"block was\" : \"blocks were\"} omitted.`,\n },\n ],\n };\n}\n"],"mappings":";;AAcA,MAAa,oBAAoB;;AAGjC,MAAa,kBAAkB;;;;;;AAO/B,MAAa,oBAAoB;;AAGjC,MAAa,kBAAkB;;AAG/B,MAAa,mBAAmB;;AAGhC,MAAa,iBAAiB;;AAG9B,MAAa,sBAAsB;;AAGnC,MAAa,uBAAuB;;AAGpC,MAAa,gBAAgB;;AAG7B,MAAa,mBAAmB;;AAGhC,MAAa,sBAAsB;;AAGnC,MAAa,oBAAoB;;AAGjC,MAAa,mBAAmB;;AAGhC,MAAa,sBAAsB;;AAGnC,MAAa,uBAAuB;;AAGpC,MAAa,kBAAkB;;AAG/B,MAAa,sBAAsB;;AAGnC,MAAa,mBAAmB;;AAGhC,MAAa,iBAAiB;;AAG9B,MAAa,gBAAgB;;AAG7B,MAAa,mBAAmB;;AAGhC,MAAa,mBAAmB;;AAGhC,MAAa,oBAAoB;;AAGjC,MAAa,oBAAoB;;AAGjC,MAAa,iBAAiB;;;;;AAM9B,MAAa,qBAAqB;;AAGlC,MAAa,wBAAwB;;;;;AAMrC,MAAa,yBAAyB;;AAGtC,MAAa,gBAAgB;;AAG7B,MAAa,uBAAuB;;AAGpC,SAAgB,mBACd,OACA,aACA,MACiD;CACjD,MAAM,QAAQ;EACZ,MAAM;EACN,SAAS;EACT,SAAS;EACT,QAAQ;CACV,EAAE;CACF,OAAO,CACL;EACE,MAAM;EACN,UAAU,CACR;GAAE,MAAM;GAAU,MAAM,QAAQ,GAAG,MAAM,IAAI,MAAM,KAAK;EAAM,CAChE;CACF,GACA;EAAE,MAAM;EAAW,MAAM;GAAE,MAAM;GAAU,MAAM;EAAY;CAAE,CACjE;AACF;;AAGA,SAAgB,gBACd,MACA,MACiB;CAEjB,OAAO;EAAE,MAAM;EAAS,MAAM;GAAE,MAAM;GAAU;EAAK;EAAG,OAD1C,SAAS,WAAW,UAAU;CACkB;AAChE;;AAYA,SAAgB,eAAe,QAAyC;CACtE,MAAM,EAAE,WAAW,OAAO,UAAU,MAAM,SAAS,YAAY;CAC/D,OAAO;EACL,MAAM;EACN,GAAI,cAAc,KAAA,IAAY,EAAE,YAAY,UAAU,IAAI,CAAC;EAC3D,GAAI,UAAU,KAAA,IAAY,EAAE,MAAM,IAAI,CAAC;EACvC,GAAI,aAAa,KAAA,IAAY,EAAE,SAAS,IAAI,CAAC;EAC7C,GAAI,SAAS,KAAA,IAAY,EAAE,KAAK,IAAI,CAAC;EACrC,GAAI,YAAY,KAAA,IAAY,EAAE,QAAQ,IAAI,CAAC;EAC3C,GAAI,YAAY,KAAA,IAAY,EAAE,QAAQ,IAAI,CAAC;CAC7C;AACF;;AAGA,SAAgB,mBACd,UACoB;CACpB,OAAO;EAAE,MAAM;EAAY;CAAS;AACtC;;AAGA,SAAgB,oBACd,MACqB;CACrB,OAAO;EAAE,MAAM;EAAc,SAAS;EAAe;CAAK;AAC5D;;AAGA,SAAgB,qBAAqB,SAAoC;CACvE,OAAO;EACL,MAAM;EACN,UAAU,CACR;GACE,MAAM;GACN,MAAM,GAAG,QAAQ,GAAG,YAAY,IAAI,cAAc,cAAc;EAClE,CACF;CACF;AACF"}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import type { Action } from "../ir.js";
|
|
2
|
-
/**
|
|
3
|
-
* Decodes one structural entry from a Slack `block_actions` payload.
|
|
4
|
-
* `$input` is reserved for the runtime selection: a `$input` key inside the
|
|
5
|
-
* button's JSON `value` payload is dropped rather than spread into the result.
|
|
6
|
-
* `stateValues` is the companion `state.values` object used to resolve named
|
|
7
|
-
* control values referenced by `{ "$field": name }` in the action payload.
|
|
8
|
-
*/
|
|
9
|
-
export declare function decodeBlockAction(action: unknown, stateValues?: unknown): Action | undefined;
|
|
10
|
-
//# sourceMappingURL=decodeBlockAction.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"decodeBlockAction.d.ts","sourceRoot":"","sources":["../../src/slack/decodeBlockAction.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,iBAAc;AA8JpC;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,OAAO,EACf,WAAW,CAAC,EAAE,OAAO,GACpB,MAAM,GAAG,SAAS,CA+DpB"}
|
|
@@ -1,129 +0,0 @@
|
|
|
1
|
-
import { resolveFieldReferences } from "../fieldReferences.js";
|
|
2
|
-
import { formatTemporalUnixSeconds, mergeTemporalMinutes, splitTemporalMinutes } from "../temporal.js";
|
|
3
|
-
//#region src/slack/decodeBlockAction.ts
|
|
4
|
-
const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
5
|
-
const optionValue = (value) => isRecord(value) && typeof value["value"] === "string" ? value["value"] : void 0;
|
|
6
|
-
const selectedValue = (action, field) => {
|
|
7
|
-
if (action["type"] === "datetimepicker" || "selected_date_time" in action) {
|
|
8
|
-
const seconds = action["selected_date_time"];
|
|
9
|
-
return seconds === null ? "" : typeof seconds === "number" ? formatTemporalUnixSeconds(seconds, field?.offset) : void 0;
|
|
10
|
-
}
|
|
11
|
-
if (action["type"] === "timepicker" || "selected_time" in action) {
|
|
12
|
-
const time = action["selected_time"];
|
|
13
|
-
if (time === null) return "";
|
|
14
|
-
const parts = typeof time === "string" ? splitTemporalMinutes(time) : void 0;
|
|
15
|
-
return parts?.date === void 0 ? parts?.time : void 0;
|
|
16
|
-
}
|
|
17
|
-
if (field?.part === "date" && action["selected_date"] === null) return "";
|
|
18
|
-
const selectedOption = optionValue(action["selected_option"]);
|
|
19
|
-
const selectedDate = typeof action["selected_date"] === "string" ? action["selected_date"] : void 0;
|
|
20
|
-
const selectedOptions = Array.isArray(action["selected_options"]) ? action["selected_options"].map(optionValue).filter((value) => value !== void 0) : void 0;
|
|
21
|
-
const numberInput = action["type"] === "number_input" && typeof action["value"] === "string" ? Number(action["value"]) : void 0;
|
|
22
|
-
return selectedOption ?? selectedDate ?? (selectedOptions !== void 0 ? selectedOptions : Number.isFinite(numberInput) ? numberInput : void 0);
|
|
23
|
-
};
|
|
24
|
-
const fieldMappingsFromBlockId = (blockId) => {
|
|
25
|
-
if (!/^aui:\d+:/.test(blockId)) return [];
|
|
26
|
-
const mappingStart = blockId.indexOf(":", 4);
|
|
27
|
-
if (mappingStart === -1) return [];
|
|
28
|
-
try {
|
|
29
|
-
const parsed = JSON.parse(blockId.slice(mappingStart + 1));
|
|
30
|
-
if (!Array.isArray(parsed)) return [];
|
|
31
|
-
return parsed.flatMap((entry) => {
|
|
32
|
-
if (!Array.isArray(entry) || typeof entry[0] !== "string" || typeof entry[1] !== "string") return [];
|
|
33
|
-
return [{
|
|
34
|
-
actionId: entry[0],
|
|
35
|
-
name: entry[1],
|
|
36
|
-
component: typeof entry[2] === "string" ? entry[2] : "",
|
|
37
|
-
...entry[2] === "DatePicker" && (entry[3] === "time" || entry[3] === "datetime") ? {
|
|
38
|
-
inputType: entry[3],
|
|
39
|
-
...typeof entry[4] === "string" ? { offset: entry[4] } : {},
|
|
40
|
-
...(entry[5] === "date" || entry[5] === "time") && Number.isSafeInteger(entry[6]) && entry[6] >= 0 ? {
|
|
41
|
-
part: entry[5],
|
|
42
|
-
pairId: entry[6]
|
|
43
|
-
} : {}
|
|
44
|
-
} : {}
|
|
45
|
-
}];
|
|
46
|
-
});
|
|
47
|
-
} catch {
|
|
48
|
-
return [];
|
|
49
|
-
}
|
|
50
|
-
};
|
|
51
|
-
const checkboxValue = (value, name) => Array.isArray(value["selected_options"]) ? value["selected_options"].some((option) => optionValue(option) === name) : void 0;
|
|
52
|
-
const stateFieldValue = (value, field) => {
|
|
53
|
-
if (!isRecord(value)) return void 0;
|
|
54
|
-
if (field.component === "Checkbox" && value["type"] === "checkboxes") return checkboxValue(value, field.name);
|
|
55
|
-
if (value["type"] === "plain_text_input") return typeof value["value"] === "string" ? value["value"] : void 0;
|
|
56
|
-
return selectedValue(value, field);
|
|
57
|
-
};
|
|
58
|
-
const fieldValuesFromState = (stateValues, action, actionField) => {
|
|
59
|
-
const fields = Object.create(null);
|
|
60
|
-
const pairs = /* @__PURE__ */ new Map();
|
|
61
|
-
const collect = (raw, field) => {
|
|
62
|
-
const value = stateFieldValue(raw, field);
|
|
63
|
-
if (field.part !== void 0 && field.pairId !== void 0) {
|
|
64
|
-
const pair = pairs.get(field.pairId) ?? {
|
|
65
|
-
name: field.name,
|
|
66
|
-
date: "",
|
|
67
|
-
time: ""
|
|
68
|
-
};
|
|
69
|
-
pair[field.part] = typeof value === "string" ? value : "";
|
|
70
|
-
pairs.set(field.pairId, pair);
|
|
71
|
-
} else if (field.name && value !== void 0) fields[field.name] = value;
|
|
72
|
-
};
|
|
73
|
-
if (isRecord(stateValues)) for (const [blockId, rawBlockValues] of Object.entries(stateValues)) {
|
|
74
|
-
if (!isRecord(rawBlockValues)) continue;
|
|
75
|
-
for (const field of fieldMappingsFromBlockId(blockId)) if (Object.hasOwn(rawBlockValues, field.actionId)) collect(rawBlockValues[field.actionId], field);
|
|
76
|
-
}
|
|
77
|
-
if (actionField?.inputType !== void 0) collect(action, actionField);
|
|
78
|
-
for (const pair of pairs.values()) if (pair.name) fields[pair.name] = mergeTemporalMinutes(pair.date, pair.time);
|
|
79
|
-
return {
|
|
80
|
-
fields,
|
|
81
|
-
pairs
|
|
82
|
-
};
|
|
83
|
-
};
|
|
84
|
-
/**
|
|
85
|
-
* Decodes one structural entry from a Slack `block_actions` payload.
|
|
86
|
-
* `$input` is reserved for the runtime selection: a `$input` key inside the
|
|
87
|
-
* button's JSON `value` payload is dropped rather than spread into the result.
|
|
88
|
-
* `stateValues` is the companion `state.values` object used to resolve named
|
|
89
|
-
* control values referenced by `{ "$field": name }` in the action payload.
|
|
90
|
-
*/
|
|
91
|
-
function decodeBlockAction(action, stateValues) {
|
|
92
|
-
try {
|
|
93
|
-
if (!isRecord(action) || typeof action["action_id"] !== "string") return;
|
|
94
|
-
const actionId = action["action_id"];
|
|
95
|
-
if (!actionId) return void 0;
|
|
96
|
-
const rawValue = action["value"];
|
|
97
|
-
let payload = {};
|
|
98
|
-
let plainValue;
|
|
99
|
-
if (action["type"] === "plain_text_input" && typeof rawValue === "string") plainValue = rawValue;
|
|
100
|
-
else if (typeof rawValue === "string") try {
|
|
101
|
-
const parsed = JSON.parse(rawValue);
|
|
102
|
-
if (isRecord(parsed)) payload = parsed;
|
|
103
|
-
else plainValue = rawValue;
|
|
104
|
-
} catch {
|
|
105
|
-
plainValue = rawValue;
|
|
106
|
-
}
|
|
107
|
-
const actionField = typeof action["block_id"] === "string" ? fieldMappingsFromBlockId(action["block_id"]).find((field) => field.actionId === actionId) : void 0;
|
|
108
|
-
const { fields, pairs } = fieldValuesFromState(stateValues, action, actionField);
|
|
109
|
-
let input = selectedValue(action, actionField) ?? plainValue;
|
|
110
|
-
if (actionField?.pairId !== void 0) {
|
|
111
|
-
const pair = pairs.get(actionField.pairId);
|
|
112
|
-
input = pair === void 0 ? "" : mergeTemporalMinutes(pair.date, pair.time);
|
|
113
|
-
if (!input) return void 0;
|
|
114
|
-
}
|
|
115
|
-
if ((action["type"] === "timepicker" || action["type"] === "datetimepicker") && input === void 0) return void 0;
|
|
116
|
-
const decoded = {
|
|
117
|
-
...Object.fromEntries(Object.entries(payload).filter(([key]) => key !== "$input")),
|
|
118
|
-
type: actionId,
|
|
119
|
-
...input !== void 0 ? { $input: input } : {}
|
|
120
|
-
};
|
|
121
|
-
return resolveFieldReferences(decoded, fields);
|
|
122
|
-
} catch {
|
|
123
|
-
return;
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
//#endregion
|
|
127
|
-
export { decodeBlockAction };
|
|
128
|
-
|
|
129
|
-
//# sourceMappingURL=decodeBlockAction.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"decodeBlockAction.js","names":[],"sources":["../../src/slack/decodeBlockAction.ts"],"sourcesContent":["import type { Action } from \"../ir\";\nimport { resolveFieldReferences } from \"../fieldReferences\";\nimport {\n formatTemporalUnixSeconds,\n mergeTemporalMinutes,\n splitTemporalMinutes,\n} from \"../temporal\";\nimport type { FieldMapping } from \"./types\";\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\n\nconst optionValue = (value: unknown): string | undefined =>\n isRecord(value) && typeof value[\"value\"] === \"string\"\n ? value[\"value\"]\n : undefined;\n\nconst selectedValue = (\n action: Record<string, unknown>,\n field?: FieldMapping,\n): unknown => {\n if (action[\"type\"] === \"datetimepicker\" || \"selected_date_time\" in action) {\n const seconds = action[\"selected_date_time\"];\n return seconds === null\n ? \"\"\n : typeof seconds === \"number\"\n ? formatTemporalUnixSeconds(seconds, field?.offset)\n : undefined;\n }\n if (action[\"type\"] === \"timepicker\" || \"selected_time\" in action) {\n const time = action[\"selected_time\"];\n if (time === null) return \"\";\n const parts =\n typeof time === \"string\" ? splitTemporalMinutes(time) : undefined;\n return parts?.date === undefined ? parts?.time : undefined;\n }\n if (field?.part === \"date\" && action[\"selected_date\"] === null) return \"\";\n const selectedOption = optionValue(action[\"selected_option\"]);\n const selectedDate =\n typeof action[\"selected_date\"] === \"string\"\n ? action[\"selected_date\"]\n : undefined;\n const selectedOptions = Array.isArray(action[\"selected_options\"])\n ? action[\"selected_options\"]\n .map(optionValue)\n .filter((value): value is string => value !== undefined)\n : undefined;\n const numberInput =\n action[\"type\"] === \"number_input\" && typeof action[\"value\"] === \"string\"\n ? Number(action[\"value\"])\n : undefined;\n return (\n selectedOption ??\n selectedDate ??\n (selectedOptions !== undefined\n ? selectedOptions\n : Number.isFinite(numberInput)\n ? numberInput\n : undefined)\n );\n};\n\nconst fieldMappingsFromBlockId = (blockId: string): readonly FieldMapping[] => {\n if (!/^aui:\\d+:/.test(blockId)) return [];\n const mappingStart = blockId.indexOf(\":\", 4);\n if (mappingStart === -1) return [];\n try {\n const parsed: unknown = JSON.parse(blockId.slice(mappingStart + 1));\n if (!Array.isArray(parsed)) return [];\n return parsed.flatMap((entry): FieldMapping[] => {\n if (\n !Array.isArray(entry) ||\n typeof entry[0] !== \"string\" ||\n typeof entry[1] !== \"string\"\n )\n return [];\n return [\n {\n actionId: entry[0],\n name: entry[1],\n component: typeof entry[2] === \"string\" ? entry[2] : \"\",\n ...(entry[2] === \"DatePicker\" &&\n (entry[3] === \"time\" || entry[3] === \"datetime\")\n ? {\n inputType: entry[3],\n ...(typeof entry[4] === \"string\" ? { offset: entry[4] } : {}),\n ...((entry[5] === \"date\" || entry[5] === \"time\") &&\n Number.isSafeInteger(entry[6]) &&\n entry[6] >= 0\n ? { part: entry[5], pairId: entry[6] }\n : {}),\n }\n : {}),\n },\n ];\n });\n } catch {\n return [];\n }\n};\n\nconst checkboxValue = (\n value: Record<string, unknown>,\n name: string,\n): boolean | undefined =>\n Array.isArray(value[\"selected_options\"])\n ? value[\"selected_options\"].some((option) => optionValue(option) === name)\n : undefined;\n\nconst stateFieldValue = (value: unknown, field: FieldMapping): unknown => {\n if (!isRecord(value)) return undefined;\n if (field.component === \"Checkbox\" && value[\"type\"] === \"checkboxes\") {\n return checkboxValue(value, field.name);\n }\n if (value[\"type\"] === \"plain_text_input\") {\n return typeof value[\"value\"] === \"string\" ? value[\"value\"] : undefined;\n }\n return selectedValue(value, field);\n};\n\nconst fieldValuesFromState = (\n stateValues: unknown,\n action: Record<string, unknown>,\n actionField: FieldMapping | undefined,\n) => {\n const fields: Record<string, unknown> = Object.create(null);\n const pairs = new Map<number, { name: string; date: string; time: string }>();\n const collect = (raw: unknown, field: FieldMapping) => {\n const value = stateFieldValue(raw, field);\n if (field.part !== undefined && field.pairId !== undefined) {\n const pair = pairs.get(field.pairId) ?? {\n name: field.name,\n date: \"\",\n time: \"\",\n };\n pair[field.part] = typeof value === \"string\" ? value : \"\";\n pairs.set(field.pairId, pair);\n } else if (field.name && value !== undefined) {\n fields[field.name] = value;\n }\n };\n if (isRecord(stateValues)) {\n for (const [blockId, rawBlockValues] of Object.entries(stateValues)) {\n if (!isRecord(rawBlockValues)) continue;\n for (const field of fieldMappingsFromBlockId(blockId)) {\n if (Object.hasOwn(rawBlockValues, field.actionId))\n collect(rawBlockValues[field.actionId], field);\n }\n }\n }\n if (actionField?.inputType !== undefined) collect(action, actionField);\n for (const pair of pairs.values()) {\n if (pair.name)\n fields[pair.name] = mergeTemporalMinutes(pair.date, pair.time);\n }\n return { fields, pairs };\n};\n\n/**\n * Decodes one structural entry from a Slack `block_actions` payload.\n * `$input` is reserved for the runtime selection: a `$input` key inside the\n * button's JSON `value` payload is dropped rather than spread into the result.\n * `stateValues` is the companion `state.values` object used to resolve named\n * control values referenced by `{ \"$field\": name }` in the action payload.\n */\nexport function decodeBlockAction(\n action: unknown,\n stateValues?: unknown,\n): Action | undefined {\n try {\n if (!isRecord(action) || typeof action[\"action_id\"] !== \"string\") {\n return undefined;\n }\n\n const actionId = action[\"action_id\"];\n if (!actionId) return undefined;\n\n const rawValue = action[\"value\"];\n let payload: Record<string, unknown> = {};\n let plainValue: string | undefined;\n if (action[\"type\"] === \"plain_text_input\" && typeof rawValue === \"string\") {\n plainValue = rawValue;\n } else if (typeof rawValue === \"string\") {\n try {\n const parsed: unknown = JSON.parse(rawValue);\n if (isRecord(parsed)) {\n payload = parsed;\n } else {\n plainValue = rawValue;\n }\n } catch {\n plainValue = rawValue;\n }\n }\n\n const actionField =\n typeof action[\"block_id\"] === \"string\"\n ? fieldMappingsFromBlockId(action[\"block_id\"]).find(\n (field) => field.actionId === actionId,\n )\n : undefined;\n const { fields, pairs } = fieldValuesFromState(\n stateValues,\n action,\n actionField,\n );\n let input = selectedValue(action, actionField) ?? plainValue;\n if (actionField?.pairId !== undefined) {\n const pair = pairs.get(actionField.pairId);\n input =\n pair === undefined ? \"\" : mergeTemporalMinutes(pair.date, pair.time);\n if (!input) return undefined;\n }\n if (\n (action[\"type\"] === \"timepicker\" ||\n action[\"type\"] === \"datetimepicker\") &&\n input === undefined\n )\n return undefined;\n\n const decoded = {\n ...Object.fromEntries(\n Object.entries(payload).filter(([key]) => key !== \"$input\"),\n ),\n type: actionId,\n ...(input !== undefined ? { $input: input } : {}),\n };\n return resolveFieldReferences(decoded, fields) as Action;\n } catch {\n return undefined;\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import type { FromSlackBlocksResult } from "./types.js";
|
|
2
|
-
/**
|
|
3
|
-
* Converts Slack Block Kit JSON back into a generative-ui IR tree, inverting
|
|
4
|
-
* {@link toSlackBlocks}. Accepts a blocks array or a `{ blocks }` wrapper;
|
|
5
|
-
* malformed input resolves to an empty node list plus a warning, and an
|
|
6
|
-
* unrecognized block or action element is skipped with a "dropped" warning.
|
|
7
|
-
* Every array read along the way (blocks, fields, options, elements, cards,
|
|
8
|
-
* rows, cells) is bounded to its site's cap before it is mapped over, so a
|
|
9
|
-
* hostile array (sparse or proxied with a fabricated `length`) is clamped
|
|
10
|
-
* with a "clamped" warning instead of stalling the event loop. Never throws.
|
|
11
|
-
*
|
|
12
|
-
* The Slack shape is lossier than the IR, so some information cannot be
|
|
13
|
-
* recovered: a context block's elements always decode as `Caption` (the
|
|
14
|
-
* original `Badge` vs `Caption` distinction does not survive the round trip),
|
|
15
|
-
* a button's `buttonStyle` is only recovered for the `primary`/`danger` Slack
|
|
16
|
-
* styles, a native alert block's `title` and `description` merge into a
|
|
17
|
-
* single `description` string, and a card's layout collapses to its `title`,
|
|
18
|
-
* a flat `children` list (image, then text, then caption, in that order),
|
|
19
|
-
* and `confirm`/`cancel` footer buttons. A section field's label and value
|
|
20
|
-
* are split on the first `*`+newline delimiter, so a label or value that
|
|
21
|
-
* itself contains that exact delimiter cannot be split back unambiguously.
|
|
22
|
-
* A data-table cell that Slack carries as `raw_text` always decodes as a
|
|
23
|
-
* string, even when its text is the stringified form of a boolean, since the
|
|
24
|
-
* Slack shape does not distinguish a boolean from ordinary text.
|
|
25
|
-
*/
|
|
26
|
-
export declare function fromSlackBlocks(blocks: unknown): FromSlackBlocksResult;
|
|
27
|
-
//# sourceMappingURL=fromSlackBlocks.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"fromSlackBlocks.d.ts","sourceRoot":"","sources":["../../src/slack/fromSlackBlocks.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,qBAAqB,EAA0B,mBAAgB;AAusB7E;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,OAAO,GAAG,qBAAqB,CAqCtE"}
|