@elastic/isomer-sdk 0.2.0 → 0.4.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.
Files changed (251) hide show
  1. package/NOTICE.txt +0 -286
  2. package/THIRD_PARTY_LICENSES.md +1 -885
  3. package/dist/author/authored_fields.d.ts +37 -12
  4. package/dist/author/authored_fields.d.ts.map +1 -1
  5. package/dist/author/authored_fields.js +45 -69
  6. package/dist/author/authored_fields.js.map +1 -1
  7. package/dist/author/authoring_input.d.ts.map +1 -1
  8. package/dist/author/authoring_input.js +12 -6
  9. package/dist/author/authoring_input.js.map +1 -1
  10. package/dist/author/authoring_model.d.ts +8 -2
  11. package/dist/author/authoring_model.d.ts.map +1 -1
  12. package/dist/author/authoring_model.js +67 -23
  13. package/dist/author/authoring_model.js.map +1 -1
  14. package/dist/author/declarations.d.ts.map +1 -1
  15. package/dist/author/declarations.js +45 -34
  16. package/dist/author/declarations.js.map +1 -1
  17. package/dist/author/index.d.ts +2 -1
  18. package/dist/author/index.d.ts.map +1 -1
  19. package/dist/author/index.js +2 -1
  20. package/dist/author/index.js.map +1 -1
  21. package/dist/author/jsx_shim.d.ts +49 -30
  22. package/dist/author/jsx_shim.d.ts.map +1 -1
  23. package/dist/author/jsx_shim.js +131 -40
  24. package/dist/author/jsx_shim.js.map +1 -1
  25. package/dist/author/print_jsx.d.ts +19 -0
  26. package/dist/author/print_jsx.d.ts.map +1 -0
  27. package/dist/author/print_jsx.js +372 -0
  28. package/dist/author/print_jsx.js.map +1 -0
  29. package/dist/author/prompt.d.ts +2 -2
  30. package/dist/author/prompt.d.ts.map +1 -1
  31. package/dist/author/prompt.js +7 -2
  32. package/dist/author/prompt.js.map +1 -1
  33. package/dist/author/schema_to_typescript.d.ts.map +1 -1
  34. package/dist/author/schema_to_typescript.js +6 -3
  35. package/dist/author/schema_to_typescript.js.map +1 -1
  36. package/dist/cjs/author/authored_fields.js +47 -70
  37. package/dist/cjs/author/authored_fields.js.map +1 -1
  38. package/dist/cjs/author/authoring_input.js +12 -6
  39. package/dist/cjs/author/authoring_input.js.map +1 -1
  40. package/dist/cjs/author/authoring_model.js +69 -24
  41. package/dist/cjs/author/authoring_model.js.map +1 -1
  42. package/dist/cjs/author/declarations.js +44 -33
  43. package/dist/cjs/author/declarations.js.map +1 -1
  44. package/dist/cjs/author/index.js +5 -1
  45. package/dist/cjs/author/index.js.map +1 -1
  46. package/dist/cjs/author/jsx_shim.js +130 -39
  47. package/dist/cjs/author/jsx_shim.js.map +1 -1
  48. package/dist/cjs/author/print_jsx.js +378 -0
  49. package/dist/cjs/author/print_jsx.js.map +1 -0
  50. package/dist/cjs/author/prompt.js +7 -2
  51. package/dist/cjs/author/prompt.js.map +1 -1
  52. package/dist/cjs/author/schema_to_typescript.js +6 -3
  53. package/dist/cjs/author/schema_to_typescript.js.map +1 -1
  54. package/dist/cjs/composition/error.js +2 -0
  55. package/dist/cjs/composition/error.js.map +1 -1
  56. package/dist/cjs/composition/structured_value.js.map +1 -1
  57. package/dist/cjs/define/index.js.map +1 -1
  58. package/dist/cjs/define/primitive_module.js +10 -4
  59. package/dist/cjs/define/primitive_module.js.map +1 -1
  60. package/dist/cjs/define/slack_blocks.js.map +1 -1
  61. package/dist/cjs/entries/index.js +5 -2
  62. package/dist/cjs/entries/index.js.map +1 -1
  63. package/dist/cjs/entries/markdown.js +3 -1
  64. package/dist/cjs/entries/markdown.js.map +1 -1
  65. package/dist/cjs/entries/react.js +2 -1
  66. package/dist/cjs/entries/react.js.map +1 -1
  67. package/dist/cjs/entries/slack.js +5 -1
  68. package/dist/cjs/entries/slack.js.map +1 -1
  69. package/dist/cjs/pack/enhancements.js.map +1 -1
  70. package/dist/cjs/pack/index.js +2 -1
  71. package/dist/cjs/pack/index.js.map +1 -1
  72. package/dist/cjs/pack/primitive_pack.js +14 -4
  73. package/dist/cjs/pack/primitive_pack.js.map +1 -1
  74. package/dist/cjs/render/format_number.js +2 -1
  75. package/dist/cjs/render/format_number.js.map +1 -1
  76. package/dist/cjs/render/html/envelope.js +12 -6
  77. package/dist/cjs/render/html/envelope.js.map +1 -1
  78. package/dist/cjs/render/markdown/blocks.js +82 -0
  79. package/dist/cjs/render/markdown/blocks.js.map +1 -0
  80. package/dist/cjs/render/markdown/builder.js +6 -2
  81. package/dist/cjs/render/markdown/builder.js.map +1 -1
  82. package/dist/cjs/render/markdown/format.js +46 -24
  83. package/dist/cjs/render/markdown/format.js.map +1 -1
  84. package/dist/cjs/render/markdown/host_tags.js +67 -0
  85. package/dist/cjs/render/markdown/host_tags.js.map +1 -0
  86. package/dist/cjs/render/markdown/index.js +5 -1
  87. package/dist/cjs/render/markdown/index.js.map +1 -1
  88. package/dist/cjs/render/markdown/split.js +325 -0
  89. package/dist/cjs/render/markdown/split.js.map +1 -0
  90. package/dist/cjs/render/primitive_dispatch.js +36 -6
  91. package/dist/cjs/render/primitive_dispatch.js.map +1 -1
  92. package/dist/cjs/render/react/content.js +3 -1
  93. package/dist/cjs/render/react/content.js.map +1 -1
  94. package/dist/cjs/render/react/index.js +3 -1
  95. package/dist/cjs/render/react/index.js.map +1 -1
  96. package/dist/cjs/render/react/markdown_content.js +143 -0
  97. package/dist/cjs/render/react/markdown_content.js.map +1 -0
  98. package/dist/cjs/render/slack/blocks.js +7 -0
  99. package/dist/cjs/render/slack/blocks.js.map +1 -1
  100. package/dist/cjs/render/slack/container.js +62 -0
  101. package/dist/cjs/render/slack/container.js.map +1 -0
  102. package/dist/cjs/render/slack/envelope.js +70 -14
  103. package/dist/cjs/render/slack/envelope.js.map +1 -1
  104. package/dist/cjs/render/slack/format.js +56 -6
  105. package/dist/cjs/render/slack/format.js.map +1 -1
  106. package/dist/cjs/render/slack/index.js +7 -1
  107. package/dist/cjs/render/slack/index.js.map +1 -1
  108. package/dist/cjs/render/slack/markdown_content.js +36 -77
  109. package/dist/cjs/render/slack/markdown_content.js.map +1 -1
  110. package/dist/cjs/render/slack/unmodeled.js +38 -0
  111. package/dist/cjs/render/slack/unmodeled.js.map +1 -0
  112. package/dist/cjs/testing/conformance.js +15 -1
  113. package/dist/cjs/testing/conformance.js.map +1 -1
  114. package/dist/cjs/testing/index.js +2 -1
  115. package/dist/cjs/testing/index.js.map +1 -1
  116. package/dist/cjs/validate/json_schema.js +10 -3
  117. package/dist/cjs/validate/json_schema.js.map +1 -1
  118. package/dist/cjs/validate/url.js +2 -1
  119. package/dist/cjs/validate/url.js.map +1 -1
  120. package/dist/composition/error.d.ts +2 -0
  121. package/dist/composition/error.d.ts.map +1 -1
  122. package/dist/composition/error.js +2 -0
  123. package/dist/composition/error.js.map +1 -1
  124. package/dist/composition/structured_value.d.ts +3 -3
  125. package/dist/composition/structured_value.d.ts.map +1 -1
  126. package/dist/composition/structured_value.js.map +1 -1
  127. package/dist/define/index.d.ts +1 -1
  128. package/dist/define/index.d.ts.map +1 -1
  129. package/dist/define/index.js.map +1 -1
  130. package/dist/define/primitive_module.d.ts +14 -5
  131. package/dist/define/primitive_module.d.ts.map +1 -1
  132. package/dist/define/primitive_module.js +10 -4
  133. package/dist/define/primitive_module.js.map +1 -1
  134. package/dist/define/slack_blocks.d.ts +31 -1
  135. package/dist/define/slack_blocks.d.ts.map +1 -1
  136. package/dist/define/slack_blocks.js.map +1 -1
  137. package/dist/entries/index.d.ts +2 -2
  138. package/dist/entries/index.d.ts.map +1 -1
  139. package/dist/entries/index.js +2 -2
  140. package/dist/entries/index.js.map +1 -1
  141. package/dist/entries/markdown.d.ts +1 -1
  142. package/dist/entries/markdown.d.ts.map +1 -1
  143. package/dist/entries/markdown.js +1 -1
  144. package/dist/entries/markdown.js.map +1 -1
  145. package/dist/entries/react.d.ts +1 -1
  146. package/dist/entries/react.d.ts.map +1 -1
  147. package/dist/entries/react.js +1 -1
  148. package/dist/entries/react.js.map +1 -1
  149. package/dist/entries/slack.d.ts +1 -1
  150. package/dist/entries/slack.d.ts.map +1 -1
  151. package/dist/entries/slack.js +1 -1
  152. package/dist/entries/slack.js.map +1 -1
  153. package/dist/pack/enhancements.d.ts +4 -0
  154. package/dist/pack/enhancements.d.ts.map +1 -1
  155. package/dist/pack/enhancements.js.map +1 -1
  156. package/dist/pack/index.d.ts +1 -1
  157. package/dist/pack/index.d.ts.map +1 -1
  158. package/dist/pack/index.js +1 -1
  159. package/dist/pack/index.js.map +1 -1
  160. package/dist/pack/primitive_pack.d.ts +3 -1
  161. package/dist/pack/primitive_pack.d.ts.map +1 -1
  162. package/dist/pack/primitive_pack.js +13 -3
  163. package/dist/pack/primitive_pack.js.map +1 -1
  164. package/dist/render/format_number.d.ts.map +1 -1
  165. package/dist/render/format_number.js +2 -1
  166. package/dist/render/format_number.js.map +1 -1
  167. package/dist/render/html/envelope.js +12 -6
  168. package/dist/render/html/envelope.js.map +1 -1
  169. package/dist/render/markdown/blocks.d.ts +6 -0
  170. package/dist/render/markdown/blocks.d.ts.map +1 -0
  171. package/dist/render/markdown/blocks.js +77 -0
  172. package/dist/render/markdown/blocks.js.map +1 -0
  173. package/dist/render/markdown/builder.d.ts +3 -0
  174. package/dist/render/markdown/builder.d.ts.map +1 -1
  175. package/dist/render/markdown/builder.js +3 -1
  176. package/dist/render/markdown/builder.js.map +1 -1
  177. package/dist/render/markdown/format.d.ts +2 -0
  178. package/dist/render/markdown/format.d.ts.map +1 -1
  179. package/dist/render/markdown/format.js +42 -22
  180. package/dist/render/markdown/format.js.map +1 -1
  181. package/dist/render/markdown/host_tags.d.ts +14 -0
  182. package/dist/render/markdown/host_tags.d.ts.map +1 -0
  183. package/dist/render/markdown/host_tags.js +63 -0
  184. package/dist/render/markdown/host_tags.js.map +1 -0
  185. package/dist/render/markdown/index.d.ts +2 -0
  186. package/dist/render/markdown/index.d.ts.map +1 -1
  187. package/dist/render/markdown/index.js +2 -0
  188. package/dist/render/markdown/index.js.map +1 -1
  189. package/dist/render/markdown/split.d.ts +32 -0
  190. package/dist/render/markdown/split.d.ts.map +1 -0
  191. package/dist/render/markdown/split.js +321 -0
  192. package/dist/render/markdown/split.js.map +1 -0
  193. package/dist/render/primitive_dispatch.d.ts +4 -2
  194. package/dist/render/primitive_dispatch.d.ts.map +1 -1
  195. package/dist/render/primitive_dispatch.js +36 -6
  196. package/dist/render/primitive_dispatch.js.map +1 -1
  197. package/dist/render/react/content.d.ts +1 -1
  198. package/dist/render/react/content.d.ts.map +1 -1
  199. package/dist/render/react/content.js +3 -1
  200. package/dist/render/react/content.js.map +1 -1
  201. package/dist/render/react/index.d.ts +1 -0
  202. package/dist/render/react/index.d.ts.map +1 -1
  203. package/dist/render/react/index.js +1 -0
  204. package/dist/render/react/index.js.map +1 -1
  205. package/dist/render/react/markdown_content.d.ts +9 -0
  206. package/dist/render/react/markdown_content.d.ts.map +1 -0
  207. package/dist/render/react/markdown_content.js +139 -0
  208. package/dist/render/react/markdown_content.js.map +1 -0
  209. package/dist/render/slack/blocks.d.ts +8 -1
  210. package/dist/render/slack/blocks.d.ts.map +1 -1
  211. package/dist/render/slack/blocks.js +7 -0
  212. package/dist/render/slack/blocks.js.map +1 -1
  213. package/dist/render/slack/container.d.ts +25 -0
  214. package/dist/render/slack/container.d.ts.map +1 -0
  215. package/dist/render/slack/container.js +55 -0
  216. package/dist/render/slack/container.js.map +1 -0
  217. package/dist/render/slack/envelope.d.ts +6 -4
  218. package/dist/render/slack/envelope.d.ts.map +1 -1
  219. package/dist/render/slack/envelope.js +71 -15
  220. package/dist/render/slack/envelope.js.map +1 -1
  221. package/dist/render/slack/format.d.ts +15 -3
  222. package/dist/render/slack/format.d.ts.map +1 -1
  223. package/dist/render/slack/format.js +54 -5
  224. package/dist/render/slack/format.js.map +1 -1
  225. package/dist/render/slack/index.d.ts +4 -2
  226. package/dist/render/slack/index.d.ts.map +1 -1
  227. package/dist/render/slack/index.js +2 -0
  228. package/dist/render/slack/index.js.map +1 -1
  229. package/dist/render/slack/markdown_content.d.ts +3 -2
  230. package/dist/render/slack/markdown_content.d.ts.map +1 -1
  231. package/dist/render/slack/markdown_content.js +27 -68
  232. package/dist/render/slack/markdown_content.js.map +1 -1
  233. package/dist/render/slack/unmodeled.d.ts +16 -0
  234. package/dist/render/slack/unmodeled.d.ts.map +1 -0
  235. package/dist/render/slack/unmodeled.js +32 -0
  236. package/dist/render/slack/unmodeled.js.map +1 -0
  237. package/dist/testing/conformance.d.ts +3 -1
  238. package/dist/testing/conformance.d.ts.map +1 -1
  239. package/dist/testing/conformance.js +14 -0
  240. package/dist/testing/conformance.js.map +1 -1
  241. package/dist/testing/index.d.ts +1 -1
  242. package/dist/testing/index.d.ts.map +1 -1
  243. package/dist/testing/index.js +1 -1
  244. package/dist/testing/index.js.map +1 -1
  245. package/dist/validate/json_schema.d.ts.map +1 -1
  246. package/dist/validate/json_schema.js +10 -3
  247. package/dist/validate/json_schema.js.map +1 -1
  248. package/dist/validate/url.d.ts.map +1 -1
  249. package/dist/validate/url.js +2 -1
  250. package/dist/validate/url.js.map +1 -1
  251. package/package.json +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"content.js","sourceRoot":"","sources":["../../../src/render/react/content.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EACL,aAAa,EACb,QAAQ,GAGT,MAAM,OAAO,CAAC;AAyBf;;;GAGG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAItC,WAA+B,EAC/B,UAAmD,EACnD,OAAiB,EACjB,EAAE,OAAO,GAAG,IAAI,KAA0B,EAAE,EACjC,EAAE,CACb,aAAa,CACX,QAAQ,EACR,IAAI,EACJ,GAAG;IACD,OAAO,IAAI,WAAW,CAAC,KAAK;QAC1B,CAAC,CAAC,aAAa,CAAC,IAAI,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE,WAAW,CAAC,KAAK,CAAC;QAC1D,CAAC,CAAC,IAAI;IACR,OAAO,IAAI,WAAW,CAAC,QAAQ;QAC7B,CAAC,CAAC,aAAa,CACX,GAAG,EACH,EAAE,GAAG,EAAE,UAAU,EAAE,SAAS,EAAE,KAAK,EAAE,EACrC,WAAW,CAAC,QAAQ,CACrB;QACH,CAAC,CAAC,IAAI;IACR,GAAG,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CACtC,aAAa,CAAC,CAAA,uBAAwC,CAAA,EAAE;QACtD,GAAG,EAAE,QAAQ,KAAK,EAAE;QACpB,IAAI;QACJ,OAAO;QACP,UAAU;KACX,CAAC,CACH;CACF,CAAC,MAAM,CAAC,OAAO,CAAC,CAClB,CAAC;AAWJ,MAAM,uBAAuB,GAAG,CAAwC,EACtE,IAAI,EACJ,OAAO,EACP,UAAU,GACoC,EAAa,EAAE,CAC7D,UAAU,CAAC,WAAW,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;AAcxC;;;GAGG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,CACpC,OAAkB,EAClB,WAA+B,EAC/B,EACE,MAAM,GAAG,IAAI,EACb,KAAK,GAAG,KAAK,EACb,KAAK,GAAG,WAAW,CAAC,KAAK,IAAI,MAAM,EACnC,gBAAgB,GAAG,MAAM,MACI,EAAE,EACnB,EAAE,CAChB,aAAa,CACX,SAAS,EACT;IACE,SAAS,EAAE,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;SAChE,MAAM,CAAC,OAAO,CAAC;SACf,IAAI,CAAC,GAAG,CAAC;IACZ,IAAI,EAAE,OAAO;IACb,YAAY,EACV,WAAW,CAAC,IAAI,EAAE,SAAS,IAAI,WAAW,CAAC,KAAK,IAAI,gBAAgB;IACtE,GAAG,CAAC,KAAK,KAAK,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,KAAK,EAAE,CAAC;CACrD,EACD,OAAO,CACR,CAAC","sourcesContent":["/*\n * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one\n * or more contributor license agreements. Licensed under the Elastic License\n * 2.0; you may not use this file except in compliance with the Elastic License\n * 2.0.\n */\n\nimport {\n createElement,\n Fragment,\n type ReactElement,\n type ReactNode,\n} from 'react';\n\nimport type { Composition } from '../../composition';\nimport type { RenderTheme } from '../../composition/named_color';\nimport type { PrimitiveNode, PrimitiveRenderContext } from '../../define';\n\n/** A pack's React renderer for one node of its own type. */\nexport interface ReactContentDispatcher<\n TNode extends PrimitiveNode,\n TContext = PrimitiveRenderContext,\n> {\n /** Must be side-effect free: the HTML surface calls it twice, once to collect styles and once to render. */\n renderReact(node: TNode, context?: TContext): ReactNode;\n}\n\n/** Options for {@link renderCompositionContent}. */\nexport interface ReactContentOptions {\n /**\n * Renders the composition's title and subtitle as the leading `h2` / `p.sub`.\n * Defaults to `true`. Pass `false` when the host already shows the title\n * itself; the title still backs the wrapper's `aria-label`.\n */\n heading?: boolean;\n}\n\n/**\n * A composition's heading and body as React nodes, without the surrounding\n * document or wrapper element.\n */\nexport const renderCompositionContent = <\n TNode extends PrimitiveNode,\n TContext = PrimitiveRenderContext,\n>(\n composition: Composition<TNode>,\n dispatcher: ReactContentDispatcher<TNode, TContext>,\n context: TContext,\n { heading = true }: ReactContentOptions = {}\n): ReactNode =>\n createElement(\n Fragment,\n null,\n ...[\n heading && composition.title\n ? createElement('h2', { key: 'title' }, composition.title)\n : null,\n heading && composition.subtitle\n ? createElement(\n 'p',\n { key: 'subtitle', className: 'sub' },\n composition.subtitle\n )\n : null,\n ...composition.body.map((node, index) =>\n createElement(RenderedCompositionNode<TNode, TContext>, {\n key: `body-${index}`,\n node,\n context,\n dispatcher,\n })\n ),\n ].filter(Boolean)\n );\n\ninterface RenderedCompositionNodeProps<\n TNode extends PrimitiveNode,\n TContext = PrimitiveRenderContext,\n> {\n node: TNode;\n context: TContext;\n dispatcher: ReactContentDispatcher<TNode, TContext>;\n}\n\nconst RenderedCompositionNode = <TNode extends PrimitiveNode, TContext>({\n node,\n context,\n dispatcher,\n}: RenderedCompositionNodeProps<TNode, TContext>): ReactNode =>\n dispatcher.renderReact(node, context);\n\n/** Options for {@link wrapCompositionContent}. */\nexport interface CompositionWrapperOptions {\n /** Adds the `framed` class. Defaults to `true`. */\n framed?: boolean;\n /** Adds the `fluid` class. */\n fluid?: boolean;\n /** Sets `data-theme`; defaults to the composition's `theme`, and `auto` sets nothing so the page's scheme applies. */\n theme?: RenderTheme;\n /** Used only when the composition has neither `meta.ariaLabel` nor a `title`. Defaults to `'View'`. */\n defaultAriaLabel?: string;\n}\n\n/**\n * The one `.isomer[.framed][.fluid]` `section` every surface wraps rendered\n * content in: the `html` surface's document wrapper and a React host's.\n */\nexport const wrapCompositionContent = <TNode extends PrimitiveNode>(\n content: ReactNode,\n composition: Composition<TNode>,\n {\n framed = true,\n fluid = false,\n theme = composition.theme ?? 'auto',\n defaultAriaLabel = 'View',\n }: CompositionWrapperOptions = {}\n): ReactElement =>\n createElement(\n 'section',\n {\n className: ['isomer', framed ? 'framed' : '', fluid ? 'fluid' : '']\n .filter(Boolean)\n .join(' '),\n role: 'group',\n 'aria-label':\n composition.meta?.ariaLabel ?? composition.title ?? defaultAriaLabel,\n ...(theme === 'auto' ? {} : { 'data-theme': theme }),\n },\n content\n );\n"]}
1
+ {"version":3,"file":"content.js","sourceRoot":"","sources":["../../../src/render/react/content.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EACL,aAAa,EACb,QAAQ,GAGT,MAAM,OAAO,CAAC;AAyBf;;;GAGG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAItC,WAA+B,EAC/B,UAAmD,EACnD,OAAiB,EACjB,EAAE,OAAO,GAAG,IAAI,KAA0B,EAAE,EACjC,EAAE,CACb,aAAa,CACX,QAAQ,EACR,IAAI,EACJ,GAAG;IACD,OAAO,IAAI,WAAW,CAAC,KAAK;QAC1B,CAAC,CAAC,aAAa,CAAC,IAAI,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE,WAAW,CAAC,KAAK,CAAC;QAC1D,CAAC,CAAC,IAAI;IACR,OAAO,IAAI,WAAW,CAAC,QAAQ;QAC7B,CAAC,CAAC,aAAa,CACX,GAAG,EACH,EAAE,GAAG,EAAE,UAAU,EAAE,SAAS,EAAE,KAAK,EAAE,EACrC,WAAW,CAAC,QAAQ,CACrB;QACH,CAAC,CAAC,IAAI;IACR,GAAG,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CACtC,aAAa,CAAC,CAAA,uBAAwC,CAAA,EAAE;QACtD,GAAG,EAAE,QAAQ,KAAK,EAAE;QACpB,IAAI;QACJ,OAAO;QACP,UAAU;KACX,CAAC,CACH;CACF,CAAC,MAAM,CAAC,OAAO,CAAC,CAClB,CAAC;AAWJ,MAAM,uBAAuB,GAAG,CAAwC,EACtE,IAAI,EACJ,OAAO,EACP,UAAU,GACoC,EAAa,EAAE,CAC7D,UAAU,CAAC,WAAW,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;AAcxC;;;GAGG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,CACpC,OAAkB,EAClB,WAA+B,EAC/B,EACE,MAAM,GAAG,IAAI,EACb,KAAK,GAAG,KAAK,EACb,KAAK,GAAG,WAAW,CAAC,KAAK,IAAI,MAAM,EACnC,gBAAgB,GAAG,MAAM,MACI,EAAE,EACnB,EAAE,CAChB,aAAa,CACX,SAAS,EACT;IACE,SAAS,EAAE,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;SAChE,MAAM,CAAC,OAAO,CAAC;SACf,IAAI,CAAC,GAAG,CAAC;IACZ,IAAI,EAAE,OAAO;IACb,YAAY,EACV,WAAW,CAAC,IAAI,EAAE,SAAS,IAAI,WAAW,CAAC,KAAK,IAAI,gBAAgB;IACtE,GAAG,CAAC,KAAK,KAAK,MAAM;QAClB,CAAC,CAAC,EAAE;QACJ,CAAC,CAAC,EAAE,YAAY,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE,EAAE,CAAC;CAC5D,EACD,OAAO,CACR,CAAC","sourcesContent":["/*\n * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one\n * or more contributor license agreements. Licensed under the Elastic License\n * 2.0; you may not use this file except in compliance with the Elastic License\n * 2.0.\n */\n\nimport {\n createElement,\n Fragment,\n type ReactElement,\n type ReactNode,\n} from 'react';\n\nimport type { Composition } from '../../composition';\nimport type { RenderTheme } from '../../composition/named_color';\nimport type { PrimitiveNode, PrimitiveRenderContext } from '../../define';\n\n/** A pack's React renderer for one node of its own type. */\nexport interface ReactContentDispatcher<\n TNode extends PrimitiveNode,\n TContext = PrimitiveRenderContext,\n> {\n /** Must be side-effect free: the HTML surface calls it twice, once to collect styles and once to render. */\n renderReact(node: TNode, context?: TContext): ReactNode;\n}\n\n/** Options for {@link renderCompositionContent}. */\nexport interface ReactContentOptions {\n /**\n * Renders the composition's title and subtitle as the leading `h2` / `p.sub`.\n * Defaults to `true`. Pass `false` when the host already shows the title\n * itself; the title still backs the wrapper's `aria-label`.\n */\n heading?: boolean;\n}\n\n/**\n * A composition's heading and body as React nodes, without the surrounding\n * document or wrapper element.\n */\nexport const renderCompositionContent = <\n TNode extends PrimitiveNode,\n TContext = PrimitiveRenderContext,\n>(\n composition: Composition<TNode>,\n dispatcher: ReactContentDispatcher<TNode, TContext>,\n context: TContext,\n { heading = true }: ReactContentOptions = {}\n): ReactNode =>\n createElement(\n Fragment,\n null,\n ...[\n heading && composition.title\n ? createElement('h2', { key: 'title' }, composition.title)\n : null,\n heading && composition.subtitle\n ? createElement(\n 'p',\n { key: 'subtitle', className: 'sub' },\n composition.subtitle\n )\n : null,\n ...composition.body.map((node, index) =>\n createElement(RenderedCompositionNode<TNode, TContext>, {\n key: `body-${index}`,\n node,\n context,\n dispatcher,\n })\n ),\n ].filter(Boolean)\n );\n\ninterface RenderedCompositionNodeProps<\n TNode extends PrimitiveNode,\n TContext = PrimitiveRenderContext,\n> {\n node: TNode;\n context: TContext;\n dispatcher: ReactContentDispatcher<TNode, TContext>;\n}\n\nconst RenderedCompositionNode = <TNode extends PrimitiveNode, TContext>({\n node,\n context,\n dispatcher,\n}: RenderedCompositionNodeProps<TNode, TContext>): ReactNode =>\n dispatcher.renderReact(node, context);\n\n/** Options for {@link wrapCompositionContent}. */\nexport interface CompositionWrapperOptions {\n /** Adds the `framed` class. Defaults to `true`. */\n framed?: boolean;\n /** Adds the `fluid` class. */\n fluid?: boolean;\n /** Sets `data-theme` and `color-scheme`, which `light-dark()` resolves against; defaults to the composition's `theme`, and `auto` sets nothing so the page's scheme applies. */\n theme?: RenderTheme;\n /** Used only when the composition has neither `meta.ariaLabel` nor a `title`. Defaults to `'View'`. */\n defaultAriaLabel?: string;\n}\n\n/**\n * The one `.isomer[.framed][.fluid]` `section` every surface wraps rendered\n * content in: the `html` surface's document wrapper and a React host's.\n */\nexport const wrapCompositionContent = <TNode extends PrimitiveNode>(\n content: ReactNode,\n composition: Composition<TNode>,\n {\n framed = true,\n fluid = false,\n theme = composition.theme ?? 'auto',\n defaultAriaLabel = 'View',\n }: CompositionWrapperOptions = {}\n): ReactElement =>\n createElement(\n 'section',\n {\n className: ['isomer', framed ? 'framed' : '', fluid ? 'fluid' : '']\n .filter(Boolean)\n .join(' '),\n role: 'group',\n 'aria-label':\n composition.meta?.ariaLabel ?? composition.title ?? defaultAriaLabel,\n ...(theme === 'auto'\n ? {}\n : { 'data-theme': theme, style: { colorScheme: theme } }),\n },\n content\n );\n"]}
@@ -1,3 +1,4 @@
1
1
  export { type CompositionWrapperOptions, type ReactContentDispatcher, type ReactContentOptions, renderCompositionContent, wrapCompositionContent, } from './content.js';
2
2
  export { applyEnhancements } from './enhancements.js';
3
+ export { renderMarkdownContent } from './markdown_content.js';
3
4
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/render/react/index.ts"],"names":[],"mappings":"AAOA,OAAO,EACL,KAAK,yBAAyB,EAC9B,KAAK,sBAAsB,EAC3B,KAAK,mBAAmB,EACxB,wBAAwB,EACxB,sBAAsB,GACvB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/render/react/index.ts"],"names":[],"mappings":"AAOA,OAAO,EACL,KAAK,yBAAyB,EAC9B,KAAK,sBAAsB,EAC3B,KAAK,mBAAmB,EACxB,wBAAwB,EACxB,sBAAsB,GACvB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC"}
@@ -6,4 +6,5 @@
6
6
  */
7
7
  export { renderCompositionContent, wrapCompositionContent, } from './content.js';
8
8
  export { applyEnhancements } from './enhancements.js';
9
+ export { renderMarkdownContent } from './markdown_content.js';
9
10
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/render/react/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAIL,wBAAwB,EACxB,sBAAsB,GACvB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC","sourcesContent":["/*\n * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one\n * or more contributor license agreements. Licensed under the Elastic License\n * 2.0; you may not use this file except in compliance with the Elastic License\n * 2.0.\n */\n\nexport {\n type CompositionWrapperOptions,\n type ReactContentDispatcher,\n type ReactContentOptions,\n renderCompositionContent,\n wrapCompositionContent,\n} from './content';\nexport { applyEnhancements } from './enhancements';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/render/react/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAIL,wBAAwB,EACxB,sBAAsB,GACvB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC","sourcesContent":["/*\n * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one\n * or more contributor license agreements. Licensed under the Elastic License\n * 2.0; you may not use this file except in compliance with the Elastic License\n * 2.0.\n */\n\nexport {\n type CompositionWrapperOptions,\n type ReactContentDispatcher,\n type ReactContentOptions,\n renderCompositionContent,\n wrapCompositionContent,\n} from './content';\nexport { applyEnhancements } from './enhancements';\nexport { renderMarkdownContent } from './markdown_content';\n"]}
@@ -0,0 +1,9 @@
1
+ import { type ReactNode } from 'react';
2
+ import type { MarkdownContent } from '../../define/markdown_content.js';
3
+ /**
4
+ * Builder content as React elements: paragraphs, headings, lists, quotes, code, tables, and thematic breaks, with inline marks, links, and images. Source from `md.authored` is parsed as GFM, once, as the Markdown and Slack surfaces read it.
5
+ *
6
+ * Links and images follow `md`'s URL policy: a blocked link keeps its label on {@link BLOCKED_HREF}, and a blocked image degrades to its alt text.
7
+ */
8
+ export declare const renderMarkdownContent: (content: MarkdownContent) => ReactNode;
9
+ //# sourceMappingURL=markdown_content.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdown_content.d.ts","sourceRoot":"","sources":["../../../src/render/react/markdown_content.ts"],"names":[],"mappings":"AAUA,OAAO,EAA2B,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAWhE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AA+MrE;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,GAAI,SAAS,eAAe,KAAG,SAK9D,CAAC"}
@@ -0,0 +1,139 @@
1
+ /*
2
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3
+ * or more contributor license agreements. Licensed under the Elastic License
4
+ * 2.0; you may not use this file except in compliance with the Elastic License
5
+ * 2.0.
6
+ */
7
+ // Builder content as React elements, read from the blocks the Markdown and
8
+ // Slack surfaces read. Unstyled: a pack's stylesheet owns the look.
9
+ import { createElement, Fragment } from 'react';
10
+ import { BLOCKED_HREF, sanitizeParsedAssetUrl, sanitizeParsedNavigationHref, } from '../../validate/url.js';
11
+ import { resolvedMarkdownBlocks } from '../markdown/blocks.js';
12
+ const HEADINGS = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'];
13
+ const footnoteLabel = ({ identifier, label, }) => `[^${label ?? identifier}]`;
14
+ const plainText = (node) => {
15
+ if ('value' in node) {
16
+ return node.value;
17
+ }
18
+ if (node.type === 'image') {
19
+ return node.alt ?? '';
20
+ }
21
+ if (node.type === 'footnoteReference') {
22
+ return footnoteLabel(node);
23
+ }
24
+ return 'children' in node ? node.children.map(plainText).join('') : '';
25
+ };
26
+ const keyed = (nodes) => nodes.map((node, index) => createElement(Fragment, { key: index }, node));
27
+ const inlines = (nodes) => keyed(nodes.map(inline));
28
+ const inline = (node) => {
29
+ switch (node.type) {
30
+ case 'strong':
31
+ return createElement('strong', null, ...inlines(node.children));
32
+ case 'emphasis':
33
+ return createElement('em', null, ...inlines(node.children));
34
+ case 'delete':
35
+ return createElement('del', null, ...inlines(node.children));
36
+ case 'inlineCode':
37
+ return createElement('code', null, node.value);
38
+ case 'break':
39
+ return createElement('br');
40
+ case 'link':
41
+ return createElement('a', {
42
+ href: sanitizeParsedNavigationHref(node.url) ?? BLOCKED_HREF,
43
+ ...(node.title ? { title: node.title } : {}),
44
+ }, ...inlines(node.children));
45
+ case 'image': {
46
+ const src = sanitizeParsedAssetUrl(node.url);
47
+ return src === null
48
+ ? (node.alt ?? '')
49
+ : createElement('img', {
50
+ src,
51
+ alt: node.alt ?? '',
52
+ ...(node.title ? { title: node.title } : {}),
53
+ });
54
+ }
55
+ default:
56
+ return plainText(node);
57
+ }
58
+ };
59
+ const paragraphCount = (item) => item.children.filter(({ type }) => type === 'paragraph').length;
60
+ // A spread list, a spread item, or an item with two paragraphs makes the whole list loose.
61
+ const items = (list) => {
62
+ const tight = list.spread !== true &&
63
+ !list.children.some((item) => item.spread === true || paragraphCount(item) > 1);
64
+ return list.children.map((item, index) => listItem(item, index, tight));
65
+ };
66
+ // A task item's checkbox leads its first paragraph, so a loose item keeps it on the task's line.
67
+ const listItem = (item, key, tight) => {
68
+ const checkbox = typeof item.checked === 'boolean'
69
+ ? [
70
+ createElement('input', {
71
+ type: 'checkbox',
72
+ checked: item.checked,
73
+ disabled: true,
74
+ }),
75
+ ' ',
76
+ ]
77
+ : [];
78
+ const [first, ...rest] = item.children;
79
+ const leadsWithParagraph = first?.type === 'paragraph';
80
+ const lead = leadsWithParagraph
81
+ ? [...checkbox, ...inlines(first.children)]
82
+ : checkbox;
83
+ const head = leadsWithParagraph && !tight ? [createElement('p', null, ...lead)] : lead;
84
+ const body = (leadsWithParagraph ? rest : item.children).flatMap((child) => child.type === 'paragraph' && tight
85
+ ? inlines(child.children)
86
+ : [block(child)]);
87
+ return createElement('li', { key }, ...keyed([...head, ...body]));
88
+ };
89
+ const tableRows = (table) => {
90
+ const [header, ...body] = table.children;
91
+ const cells = (row, tag) => createElement('tr', null, ...row.children.map((cell, index) => {
92
+ const align = table.align?.[index];
93
+ return createElement(tag, {
94
+ key: index,
95
+ ...(align ? { style: { textAlign: align } } : {}),
96
+ }, ...inlines(cell.children));
97
+ }));
98
+ return createElement(Fragment, null, header
99
+ ? createElement('thead', { key: 'head' }, cells(header, 'th'))
100
+ : null, body.length > 0
101
+ ? createElement('tbody', { key: 'body' }, ...body.map((row, index) => createElement(Fragment, { key: index }, cells(row, 'td'))))
102
+ : null);
103
+ };
104
+ const blocks = (nodes) => keyed(nodes.map(block));
105
+ const block = (node) => {
106
+ switch (node.type) {
107
+ case 'paragraph':
108
+ return createElement('p', null, ...inlines(node.children));
109
+ case 'heading':
110
+ return createElement(HEADINGS[node.depth - 1], null, ...inlines(node.children));
111
+ case 'blockquote':
112
+ return createElement('blockquote', null, ...blocks(node.children));
113
+ case 'list':
114
+ return createElement(node.ordered ? 'ol' : 'ul', node.ordered && node.start != null && node.start !== 1
115
+ ? { start: node.start }
116
+ : null, ...items(node));
117
+ case 'code':
118
+ return createElement('pre', null, createElement('code', node.lang ? { className: `language-${node.lang}` } : null, node.value));
119
+ case 'table':
120
+ return createElement('table', null, tableRows(node));
121
+ case 'thematicBreak':
122
+ return createElement('hr');
123
+ case 'html':
124
+ return createElement('p', null, node.value);
125
+ case 'footnoteDefinition': {
126
+ const [first, ...rest] = node.children;
127
+ return createElement(Fragment, null, createElement('p', null, `${footnoteLabel(node)}: `, ...(first?.type === 'paragraph' ? inlines(first.children) : [])), ...blocks(first?.type === 'paragraph' ? rest : node.children));
128
+ }
129
+ default:
130
+ return null;
131
+ }
132
+ };
133
+ /**
134
+ * Builder content as React elements: paragraphs, headings, lists, quotes, code, tables, and thematic breaks, with inline marks, links, and images. Source from `md.authored` is parsed as GFM, once, as the Markdown and Slack surfaces read it.
135
+ *
136
+ * Links and images follow `md`'s URL policy: a blocked link keeps its label on {@link BLOCKED_HREF}, and a blocked image degrades to its alt text.
137
+ */
138
+ export const renderMarkdownContent = (content) => createElement(Fragment, null, ...blocks(resolvedMarkdownBlocks(content)));
139
+ //# sourceMappingURL=markdown_content.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdown_content.js","sourceRoot":"","sources":["../../../src/render/react/markdown_content.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one\n * or more contributor license agreements. Licensed under the Elastic License\n * 2.0; you may not use this file except in compliance with the Elastic License\n * 2.0.\n */\n\n// Builder content as React elements, read from the blocks the Markdown and\n// Slack surfaces read. Unstyled: a pack's stylesheet owns the look.\n\nimport { createElement, Fragment, type ReactNode } from 'react';\nimport type {\n FootnoteDefinition,\n List,\n ListItem,\n Nodes,\n PhrasingContent,\n RootContent,\n Table,\n} from 'mdast';\n\nimport type { MarkdownContent } from '../../define/markdown_content';\nimport {\n BLOCKED_HREF,\n sanitizeParsedAssetUrl,\n sanitizeParsedNavigationHref,\n} from '../../validate/url';\nimport { resolvedMarkdownBlocks } from '../markdown/blocks';\n\nconst HEADINGS = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'] as const;\n\nconst footnoteLabel = ({\n identifier,\n label,\n}: Pick<FootnoteDefinition, 'identifier' | 'label'>): string =>\n `[^${label ?? identifier}]`;\n\nconst plainText = (node: Nodes): string => {\n if ('value' in node) {\n return node.value;\n }\n if (node.type === 'image') {\n return node.alt ?? '';\n }\n if (node.type === 'footnoteReference') {\n return footnoteLabel(node);\n }\n return 'children' in node ? node.children.map(plainText).join('') : '';\n};\n\nconst keyed = (nodes: readonly ReactNode[]): ReactNode[] =>\n nodes.map((node, index) => createElement(Fragment, { key: index }, node));\n\nconst inlines = (nodes: readonly PhrasingContent[]): ReactNode[] =>\n keyed(nodes.map(inline));\n\nconst inline = (node: PhrasingContent): ReactNode => {\n switch (node.type) {\n case 'strong':\n return createElement('strong', null, ...inlines(node.children));\n case 'emphasis':\n return createElement('em', null, ...inlines(node.children));\n case 'delete':\n return createElement('del', null, ...inlines(node.children));\n case 'inlineCode':\n return createElement('code', null, node.value);\n case 'break':\n return createElement('br');\n case 'link':\n return createElement(\n 'a',\n {\n href: sanitizeParsedNavigationHref(node.url) ?? BLOCKED_HREF,\n ...(node.title ? { title: node.title } : {}),\n },\n ...inlines(node.children)\n );\n case 'image': {\n const src = sanitizeParsedAssetUrl(node.url);\n return src === null\n ? (node.alt ?? '')\n : createElement('img', {\n src,\n alt: node.alt ?? '',\n ...(node.title ? { title: node.title } : {}),\n });\n }\n default:\n return plainText(node);\n }\n};\n\nconst paragraphCount = (item: ListItem): number =>\n item.children.filter(({ type }) => type === 'paragraph').length;\n\n// A spread list, a spread item, or an item with two paragraphs makes the whole list loose.\nconst items = (list: List): ReactNode[] => {\n const tight =\n list.spread !== true &&\n !list.children.some(\n (item) => item.spread === true || paragraphCount(item) > 1\n );\n return list.children.map((item, index) => listItem(item, index, tight));\n};\n\n// A task item's checkbox leads its first paragraph, so a loose item keeps it on the task's line.\nconst listItem = (item: ListItem, key: number, tight: boolean): ReactNode => {\n const checkbox =\n typeof item.checked === 'boolean'\n ? [\n createElement('input', {\n type: 'checkbox',\n checked: item.checked,\n disabled: true,\n }),\n ' ',\n ]\n : [];\n const [first, ...rest] = item.children;\n const leadsWithParagraph = first?.type === 'paragraph';\n const lead = leadsWithParagraph\n ? [...checkbox, ...inlines(first.children)]\n : checkbox;\n const head =\n leadsWithParagraph && !tight ? [createElement('p', null, ...lead)] : lead;\n const body = (leadsWithParagraph ? rest : item.children).flatMap(\n (child): ReactNode[] =>\n child.type === 'paragraph' && tight\n ? inlines(child.children)\n : [block(child)]\n );\n return createElement('li', { key }, ...keyed([...head, ...body]));\n};\n\nconst tableRows = (table: Table): ReactNode => {\n const [header, ...body] = table.children;\n const cells = (row: Table['children'][number], tag: 'th' | 'td'): ReactNode =>\n createElement(\n 'tr',\n null,\n ...row.children.map((cell, index) => {\n const align = table.align?.[index];\n return createElement(\n tag,\n {\n key: index,\n ...(align ? { style: { textAlign: align } } : {}),\n },\n ...inlines(cell.children)\n );\n })\n );\n return createElement(\n Fragment,\n null,\n header\n ? createElement('thead', { key: 'head' }, cells(header, 'th'))\n : null,\n body.length > 0\n ? createElement(\n 'tbody',\n { key: 'body' },\n ...body.map((row, index) =>\n createElement(Fragment, { key: index }, cells(row, 'td'))\n )\n )\n : null\n );\n};\n\nconst blocks = (nodes: readonly RootContent[]): ReactNode[] =>\n keyed(nodes.map(block));\n\nconst block = (node: RootContent): ReactNode => {\n switch (node.type) {\n case 'paragraph':\n return createElement('p', null, ...inlines(node.children));\n case 'heading':\n return createElement(\n HEADINGS[node.depth - 1]!,\n null,\n ...inlines(node.children)\n );\n case 'blockquote':\n return createElement('blockquote', null, ...blocks(node.children));\n case 'list':\n return createElement(\n node.ordered ? 'ol' : 'ul',\n node.ordered && node.start != null && node.start !== 1\n ? { start: node.start }\n : null,\n ...items(node)\n );\n case 'code':\n return createElement(\n 'pre',\n null,\n createElement(\n 'code',\n node.lang ? { className: `language-${node.lang}` } : null,\n node.value\n )\n );\n case 'table':\n return createElement('table', null, tableRows(node));\n case 'thematicBreak':\n return createElement('hr');\n case 'html':\n return createElement('p', null, node.value);\n case 'footnoteDefinition': {\n const [first, ...rest] = node.children;\n return createElement(\n Fragment,\n null,\n createElement(\n 'p',\n null,\n `${footnoteLabel(node)}: `,\n ...(first?.type === 'paragraph' ? inlines(first.children) : [])\n ),\n ...blocks(first?.type === 'paragraph' ? rest : node.children)\n );\n }\n default:\n return null;\n }\n};\n\n/**\n * Builder content as React elements: paragraphs, headings, lists, quotes, code, tables, and thematic breaks, with inline marks, links, and images. Source from `md.authored` is parsed as GFM, once, as the Markdown and Slack surfaces read it.\n *\n * Links and images follow `md`'s URL policy: a blocked link keeps its label on {@link BLOCKED_HREF}, and a blocked image degrades to its alt text.\n */\nexport const renderMarkdownContent = (content: MarkdownContent): ReactNode =>\n createElement(\n Fragment,\n null,\n ...blocks(resolvedMarkdownBlocks(content) as RootContent[])\n );\n"]}
@@ -1,10 +1,17 @@
1
- export type { SlackActionElement, SlackActionsBlock, SlackBlock, SlackButtonElement, SlackCheckboxesElement, SlackContextBlock, SlackDividerBlock, SlackFileReference, SlackHeaderBlock, SlackHeaderLevel, SlackImageBlock, SlackImageElement, SlackMrkdwnTextObject, SlackMultiStaticSelectElement, SlackOptionGroup, SlackOptionObject, SlackOverflowElement, SlackPlainTextObject, SlackRadioButtonsElement, SlackRawTextElement, SlackRichTextBlock, SlackRichTextBlockElement, SlackRichTextInline, SlackRichTextLink, SlackRichTextList, SlackRichTextPreformatted, SlackRichTextQuote, SlackRichTextSection, SlackRichTextStyle, SlackRichTextTag, SlackRichTextText, SlackSectionAccessory, SlackSectionBlock, SlackStaticSelectElement, SlackTableBlock, SlackTableCell, SlackTableColumnSetting, SlackTagColor, SlackTextObject, SlackVideoBlock, } from '../../define/slack_blocks.js';
1
+ export type { SlackActionElement, SlackActionsBlock, SlackBlock, SlackButtonElement, SlackCheckboxesElement, SlackContainerBlock, SlackContainerChildBlock, SlackContextBlock, SlackDividerBlock, SlackFileReference, SlackHeaderBlock, SlackHeaderLevel, SlackImageBlock, SlackImageElement, SlackMrkdwnTextObject, SlackMultiStaticSelectElement, SlackOptionGroup, SlackOptionObject, SlackOverflowElement, SlackPlainTextObject, SlackRadioButtonsElement, SlackRawTextElement, SlackRichTextBlock, SlackRichTextBlockElement, SlackRichTextInline, SlackRichTextLink, SlackRichTextList, SlackRichTextPreformatted, SlackRichTextQuote, SlackRichTextSection, SlackRichTextStyle, SlackRichTextTag, SlackRichTextText, SlackSectionAccessory, SlackSectionBlock, SlackStaticSelectElement, SlackTableBlock, SlackTableCell, SlackTableColumnSetting, SlackTagColor, SlackTextObject, SlackVideoBlock, } from '../../define/slack_blocks.js';
2
2
  /**
3
3
  * Slack's published surface limits, enforced by the renderer so a composition
4
4
  * cannot silently trip Slack's validation.
5
5
  */
6
6
  export declare const SLACK_LIMITS: {
7
+ /** Top-level blocks; a `container`'s `child_blocks` do not count. */
7
8
  readonly blocksPerMessage: 50;
9
+ /** `container.title`, which is `plain_text`. */
10
+ readonly containerTitleChars: 150;
11
+ /** `container.subtitle`. */
12
+ readonly containerSubtitleChars: 150;
13
+ /** `container.child_blocks`; Slack also requires at least one. */
14
+ readonly containerChildBlocks: 10;
8
15
  /** `section.text`. */
9
16
  readonly sectionTextChars: 3000;
10
17
  /** One entry of `section.fields`. */
@@ -1 +1 @@
1
- {"version":3,"file":"blocks.d.ts","sourceRoot":"","sources":["../../../src/render/slack/blocks.ts"],"names":[],"mappings":"AAOA,YAAY,EACV,kBAAkB,EAClB,iBAAiB,EACjB,UAAU,EACV,kBAAkB,EAClB,sBAAsB,EACtB,iBAAiB,EACjB,iBAAiB,EACjB,kBAAkB,EAClB,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,iBAAiB,EACjB,qBAAqB,EACrB,6BAA6B,EAC7B,gBAAgB,EAChB,iBAAiB,EACjB,oBAAoB,EACpB,oBAAoB,EACpB,wBAAwB,EACxB,mBAAmB,EACnB,kBAAkB,EAClB,yBAAyB,EACzB,mBAAmB,EACnB,iBAAiB,EACjB,iBAAiB,EACjB,yBAAyB,EACzB,kBAAkB,EAClB,oBAAoB,EACpB,kBAAkB,EAClB,gBAAgB,EAChB,iBAAiB,EACjB,qBAAqB,EACrB,iBAAiB,EACjB,wBAAwB,EACxB,eAAe,EACf,cAAc,EACd,uBAAuB,EACvB,aAAa,EACb,eAAe,EACf,eAAe,GAChB,MAAM,2BAA2B,CAAC;AAEnC;;;GAGG;AACH,eAAO,MAAM,YAAY;;IAEvB,sBAAsB;;IAEtB,qCAAqC;;IAErC,uCAAuC;;IAEvC,4CAA4C;;;IAG5C,oCAAoC;;;IAGpC,kFAAkF;;IAElF,yEAAyE;;IAEzE,sDAAsD;;IAEtD,4DAA4D;;IAE5D,4DAA4D;;IAE5D,+EAA+E;;IAE/E,yDAAyD;;IAEzD,0BAA0B;;IAE1B,6CAA6C;;IAE7C,4CAA4C;;IAE5C,6CAA6C;;IAE7C;;;;;OAKG;;IAEH,wDAAwD;;IAExD,iDAAiD;;IAEjD,oDAAoD;;IAEpD,mDAAmD;;IAEnD,6BAA6B;;IAE7B,4DAA4D;;IAE5D,kEAAkE;;IAElE,iEAAiE;;IAEjE,+BAA+B;;IAE/B,4BAA4B;;IAE5B,+BAA+B;;CAEvB,CAAC"}
1
+ {"version":3,"file":"blocks.d.ts","sourceRoot":"","sources":["../../../src/render/slack/blocks.ts"],"names":[],"mappings":"AAOA,YAAY,EACV,kBAAkB,EAClB,iBAAiB,EACjB,UAAU,EACV,kBAAkB,EAClB,sBAAsB,EACtB,mBAAmB,EACnB,wBAAwB,EACxB,iBAAiB,EACjB,iBAAiB,EACjB,kBAAkB,EAClB,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,iBAAiB,EACjB,qBAAqB,EACrB,6BAA6B,EAC7B,gBAAgB,EAChB,iBAAiB,EACjB,oBAAoB,EACpB,oBAAoB,EACpB,wBAAwB,EACxB,mBAAmB,EACnB,kBAAkB,EAClB,yBAAyB,EACzB,mBAAmB,EACnB,iBAAiB,EACjB,iBAAiB,EACjB,yBAAyB,EACzB,kBAAkB,EAClB,oBAAoB,EACpB,kBAAkB,EAClB,gBAAgB,EAChB,iBAAiB,EACjB,qBAAqB,EACrB,iBAAiB,EACjB,wBAAwB,EACxB,eAAe,EACf,cAAc,EACd,uBAAuB,EACvB,aAAa,EACb,eAAe,EACf,eAAe,GAChB,MAAM,2BAA2B,CAAC;AAEnC;;;GAGG;AACH,eAAO,MAAM,YAAY;IACvB,qEAAqE;;IAErE,gDAAgD;;IAEhD,4BAA4B;;IAE5B,kEAAkE;;IAElE,sBAAsB;;IAEtB,qCAAqC;;IAErC,uCAAuC;;IAEvC,4CAA4C;;;IAG5C,oCAAoC;;;IAGpC,kFAAkF;;IAElF,yEAAyE;;IAEzE,sDAAsD;;IAEtD,4DAA4D;;IAE5D,4DAA4D;;IAE5D,+EAA+E;;IAE/E,yDAAyD;;IAEzD,0BAA0B;;IAE1B,6CAA6C;;IAE7C,4CAA4C;;IAE5C,6CAA6C;;IAE7C;;;;;OAKG;;IAEH,wDAAwD;;IAExD,iDAAiD;;IAEjD,oDAAoD;;IAEpD,mDAAmD;;IAEnD,6BAA6B;;IAE7B,4DAA4D;;IAE5D,kEAAkE;;IAElE,iEAAiE;;IAEjE,+BAA+B;;IAE/B,4BAA4B;;IAE5B,+BAA+B;;CAEvB,CAAC"}
@@ -9,7 +9,14 @@
9
9
  * cannot silently trip Slack's validation.
10
10
  */
11
11
  export const SLACK_LIMITS = {
12
+ /** Top-level blocks; a `container`'s `child_blocks` do not count. */
12
13
  blocksPerMessage: 50,
14
+ /** `container.title`, which is `plain_text`. */
15
+ containerTitleChars: 150,
16
+ /** `container.subtitle`. */
17
+ containerSubtitleChars: 150,
18
+ /** `container.child_blocks`; Slack also requires at least one. */
19
+ containerChildBlocks: 10,
13
20
  /** `section.text`. */
14
21
  sectionTextChars: 3000,
15
22
  /** One entry of `section.fields`. */
@@ -1 +1 @@
1
- {"version":3,"file":"blocks.js","sourceRoot":"","sources":["../../../src/render/slack/blocks.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AA6CH;;;GAGG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,gBAAgB,EAAE,EAAE;IACpB,sBAAsB;IACtB,gBAAgB,EAAE,IAAI;IACtB,qCAAqC;IACrC,iBAAiB,EAAE,IAAI;IACvB,uCAAuC;IACvC,mBAAmB,EAAE,IAAI;IACzB,4CAA4C;IAC5C,eAAe,EAAE,GAAG;IACpB,gBAAgB,EAAE,EAAE;IACpB,oCAAoC;IACpC,eAAe,EAAE,EAAE;IACnB,iBAAiB,EAAE,EAAE;IACrB,kFAAkF;IAClF,iBAAiB,EAAE,IAAI;IACvB,yEAAyE;IACzE,eAAe,EAAE,EAAE;IACnB,sDAAsD;IACtD,gBAAgB,EAAE,GAAG;IACrB,4DAA4D;IAC5D,kBAAkB,EAAE,CAAC;IACrB,4DAA4D;IAC5D,gBAAgB,EAAE,EAAE;IACpB,+EAA+E;IAC/E,qBAAqB,EAAE,GAAG;IAC1B,yDAAyD;IACzD,gBAAgB,EAAE,GAAG;IACrB,0BAA0B;IAC1B,gBAAgB,EAAE,IAAI;IACtB,6CAA6C;IAC7C,QAAQ,EAAE,IAAI;IACd,4CAA4C;IAC5C,aAAa,EAAE,GAAG;IAClB,6CAA6C;IAC7C,qBAAqB,EAAE,CAAC;IACxB;;;;;OAKG;IACH,wBAAwB,EAAE,MAAM;IAChC,wDAAwD;IACxD,SAAS,EAAE,GAAG;IACd,iDAAiD;IACjD,YAAY,EAAE,EAAE;IAChB,oDAAoD;IACpD,aAAa,EAAE,IAAI;IACnB,mDAAmD;IACnD,iBAAiB,EAAE,IAAI;IACvB,6BAA6B;IAC7B,eAAe,EAAE,IAAI;IACrB,4DAA4D;IAC5D,eAAe,EAAE,GAAG;IACpB,kEAAkE;IAClE,qBAAqB,EAAE,GAAG;IAC1B,iEAAiE;IACjE,oBAAoB,EAAE,EAAE;IACxB,+BAA+B;IAC/B,eAAe,EAAE,EAAE;IACnB,4BAA4B;IAC5B,gBAAgB,EAAE,GAAG;IACrB,+BAA+B;IAC/B,qBAAqB,EAAE,EAAE;CACjB,CAAC","sourcesContent":["/*\n * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one\n * or more contributor license agreements. Licensed under the Elastic License\n * 2.0; you may not use this file except in compliance with the Elastic License\n * 2.0.\n */\n\nexport type {\n SlackActionElement,\n SlackActionsBlock,\n SlackBlock,\n SlackButtonElement,\n SlackCheckboxesElement,\n SlackContextBlock,\n SlackDividerBlock,\n SlackFileReference,\n SlackHeaderBlock,\n SlackHeaderLevel,\n SlackImageBlock,\n SlackImageElement,\n SlackMrkdwnTextObject,\n SlackMultiStaticSelectElement,\n SlackOptionGroup,\n SlackOptionObject,\n SlackOverflowElement,\n SlackPlainTextObject,\n SlackRadioButtonsElement,\n SlackRawTextElement,\n SlackRichTextBlock,\n SlackRichTextBlockElement,\n SlackRichTextInline,\n SlackRichTextLink,\n SlackRichTextList,\n SlackRichTextPreformatted,\n SlackRichTextQuote,\n SlackRichTextSection,\n SlackRichTextStyle,\n SlackRichTextTag,\n SlackRichTextText,\n SlackSectionAccessory,\n SlackSectionBlock,\n SlackStaticSelectElement,\n SlackTableBlock,\n SlackTableCell,\n SlackTableColumnSetting,\n SlackTagColor,\n SlackTextObject,\n SlackVideoBlock,\n} from '../../define/slack_blocks';\n\n/**\n * Slack's published surface limits, enforced by the renderer so a composition\n * cannot silently trip Slack's validation.\n */\nexport const SLACK_LIMITS = {\n blocksPerMessage: 50,\n /** `section.text`. */\n sectionTextChars: 3000,\n /** One entry of `section.fields`. */\n sectionFieldChars: 2000,\n /** One entry of `context.elements`. */\n contextElementChars: 2000,\n /** `header.text`, which is `plain_text`. */\n headerTextChars: 150,\n fieldsPerSection: 10,\n /** Elements per `context` block. */\n contextElements: 10,\n buttonsPerActions: 25,\n /** Slack truncates the top-level `text` fallback in notifications around here. */\n fallbackTextChars: 4000,\n /** `plain_text` option labels (selects, radio, checkboxes, overflow). */\n optionTextChars: 75,\n /** Options per select, or per option group of one. */\n optionsPerSelect: 100,\n /** Options per overflow menu (Slack caps overflow at 5). */\n optionsPerOverflow: 5,\n /** Options per radio button group or checkboxes element. */\n optionsPerChoice: 10,\n /** Option groups per select, each holding up to `optionsPerSelect` options. */\n optionGroupsPerSelect: 100,\n /** An option's `value`, which interactions send back. */\n optionValueChars: 150,\n /** A button's `value`. */\n buttonValueChars: 2000,\n /** A button's or overflow option's `url`. */\n urlChars: 3000,\n /** An interactive element's `action_id`. */\n actionIdChars: 255,\n /** Max indent level for `rich_text_list`. */\n richTextListMaxIndent: 8,\n /**\n * Characters across every table cell in one message. Slack publishes the\n * same 10,000 figure per table and per message, so the message-wide\n * aggregate is the binding one.\n * https://docs.slack.dev/reference/block-kit/blocks/table-block/\n */\n tableCellCharsPerMessage: 10_000,\n /** Rows per `table` block (includes the header row). */\n tableRows: 100,\n /** Cells per `table` row / columns per table. */\n tableColumns: 20,\n /** `image`/image-element `image_url` max length. */\n imageUrlChars: 3000,\n /** `image`/image-element `alt_text` max length. */\n imageAltTextChars: 2000,\n /** `image` block `title`. */\n imageTitleChars: 2000,\n /** `video` block `title`; Slack requires fewer than 200. */\n videoTitleChars: 199,\n /** `video` block `description`; Slack requires fewer than 200. */\n videoDescriptionChars: 199,\n /** `video` block `author_name`; Slack requires fewer than 50. */\n videoAuthorNameChars: 49,\n /** `button` element `text`. */\n buttonTextChars: 75,\n /** Select `placeholder`. */\n placeholderChars: 150,\n /** `option_groups[].label`. */\n optionGroupLabelChars: 75,\n} as const;\n"]}
1
+ {"version":3,"file":"blocks.js","sourceRoot":"","sources":["../../../src/render/slack/blocks.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AA+CH;;;GAGG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,qEAAqE;IACrE,gBAAgB,EAAE,EAAE;IACpB,gDAAgD;IAChD,mBAAmB,EAAE,GAAG;IACxB,4BAA4B;IAC5B,sBAAsB,EAAE,GAAG;IAC3B,kEAAkE;IAClE,oBAAoB,EAAE,EAAE;IACxB,sBAAsB;IACtB,gBAAgB,EAAE,IAAI;IACtB,qCAAqC;IACrC,iBAAiB,EAAE,IAAI;IACvB,uCAAuC;IACvC,mBAAmB,EAAE,IAAI;IACzB,4CAA4C;IAC5C,eAAe,EAAE,GAAG;IACpB,gBAAgB,EAAE,EAAE;IACpB,oCAAoC;IACpC,eAAe,EAAE,EAAE;IACnB,iBAAiB,EAAE,EAAE;IACrB,kFAAkF;IAClF,iBAAiB,EAAE,IAAI;IACvB,yEAAyE;IACzE,eAAe,EAAE,EAAE;IACnB,sDAAsD;IACtD,gBAAgB,EAAE,GAAG;IACrB,4DAA4D;IAC5D,kBAAkB,EAAE,CAAC;IACrB,4DAA4D;IAC5D,gBAAgB,EAAE,EAAE;IACpB,+EAA+E;IAC/E,qBAAqB,EAAE,GAAG;IAC1B,yDAAyD;IACzD,gBAAgB,EAAE,GAAG;IACrB,0BAA0B;IAC1B,gBAAgB,EAAE,IAAI;IACtB,6CAA6C;IAC7C,QAAQ,EAAE,IAAI;IACd,4CAA4C;IAC5C,aAAa,EAAE,GAAG;IAClB,6CAA6C;IAC7C,qBAAqB,EAAE,CAAC;IACxB;;;;;OAKG;IACH,wBAAwB,EAAE,MAAM;IAChC,wDAAwD;IACxD,SAAS,EAAE,GAAG;IACd,iDAAiD;IACjD,YAAY,EAAE,EAAE;IAChB,oDAAoD;IACpD,aAAa,EAAE,IAAI;IACnB,mDAAmD;IACnD,iBAAiB,EAAE,IAAI;IACvB,6BAA6B;IAC7B,eAAe,EAAE,IAAI;IACrB,4DAA4D;IAC5D,eAAe,EAAE,GAAG;IACpB,kEAAkE;IAClE,qBAAqB,EAAE,GAAG;IAC1B,iEAAiE;IACjE,oBAAoB,EAAE,EAAE;IACxB,+BAA+B;IAC/B,eAAe,EAAE,EAAE;IACnB,4BAA4B;IAC5B,gBAAgB,EAAE,GAAG;IACrB,+BAA+B;IAC/B,qBAAqB,EAAE,EAAE;CACjB,CAAC","sourcesContent":["/*\n * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one\n * or more contributor license agreements. Licensed under the Elastic License\n * 2.0; you may not use this file except in compliance with the Elastic License\n * 2.0.\n */\n\nexport type {\n SlackActionElement,\n SlackActionsBlock,\n SlackBlock,\n SlackButtonElement,\n SlackCheckboxesElement,\n SlackContainerBlock,\n SlackContainerChildBlock,\n SlackContextBlock,\n SlackDividerBlock,\n SlackFileReference,\n SlackHeaderBlock,\n SlackHeaderLevel,\n SlackImageBlock,\n SlackImageElement,\n SlackMrkdwnTextObject,\n SlackMultiStaticSelectElement,\n SlackOptionGroup,\n SlackOptionObject,\n SlackOverflowElement,\n SlackPlainTextObject,\n SlackRadioButtonsElement,\n SlackRawTextElement,\n SlackRichTextBlock,\n SlackRichTextBlockElement,\n SlackRichTextInline,\n SlackRichTextLink,\n SlackRichTextList,\n SlackRichTextPreformatted,\n SlackRichTextQuote,\n SlackRichTextSection,\n SlackRichTextStyle,\n SlackRichTextTag,\n SlackRichTextText,\n SlackSectionAccessory,\n SlackSectionBlock,\n SlackStaticSelectElement,\n SlackTableBlock,\n SlackTableCell,\n SlackTableColumnSetting,\n SlackTagColor,\n SlackTextObject,\n SlackVideoBlock,\n} from '../../define/slack_blocks';\n\n/**\n * Slack's published surface limits, enforced by the renderer so a composition\n * cannot silently trip Slack's validation.\n */\nexport const SLACK_LIMITS = {\n /** Top-level blocks; a `container`'s `child_blocks` do not count. */\n blocksPerMessage: 50,\n /** `container.title`, which is `plain_text`. */\n containerTitleChars: 150,\n /** `container.subtitle`. */\n containerSubtitleChars: 150,\n /** `container.child_blocks`; Slack also requires at least one. */\n containerChildBlocks: 10,\n /** `section.text`. */\n sectionTextChars: 3000,\n /** One entry of `section.fields`. */\n sectionFieldChars: 2000,\n /** One entry of `context.elements`. */\n contextElementChars: 2000,\n /** `header.text`, which is `plain_text`. */\n headerTextChars: 150,\n fieldsPerSection: 10,\n /** Elements per `context` block. */\n contextElements: 10,\n buttonsPerActions: 25,\n /** Slack truncates the top-level `text` fallback in notifications around here. */\n fallbackTextChars: 4000,\n /** `plain_text` option labels (selects, radio, checkboxes, overflow). */\n optionTextChars: 75,\n /** Options per select, or per option group of one. */\n optionsPerSelect: 100,\n /** Options per overflow menu (Slack caps overflow at 5). */\n optionsPerOverflow: 5,\n /** Options per radio button group or checkboxes element. */\n optionsPerChoice: 10,\n /** Option groups per select, each holding up to `optionsPerSelect` options. */\n optionGroupsPerSelect: 100,\n /** An option's `value`, which interactions send back. */\n optionValueChars: 150,\n /** A button's `value`. */\n buttonValueChars: 2000,\n /** A button's or overflow option's `url`. */\n urlChars: 3000,\n /** An interactive element's `action_id`. */\n actionIdChars: 255,\n /** Max indent level for `rich_text_list`. */\n richTextListMaxIndent: 8,\n /**\n * Characters across every table cell in one message. Slack publishes the\n * same 10,000 figure per table and per message, so the message-wide\n * aggregate is the binding one.\n * https://docs.slack.dev/reference/block-kit/blocks/table-block/\n */\n tableCellCharsPerMessage: 10_000,\n /** Rows per `table` block (includes the header row). */\n tableRows: 100,\n /** Cells per `table` row / columns per table. */\n tableColumns: 20,\n /** `image`/image-element `image_url` max length. */\n imageUrlChars: 3000,\n /** `image`/image-element `alt_text` max length. */\n imageAltTextChars: 2000,\n /** `image` block `title`. */\n imageTitleChars: 2000,\n /** `video` block `title`; Slack requires fewer than 200. */\n videoTitleChars: 199,\n /** `video` block `description`; Slack requires fewer than 200. */\n videoDescriptionChars: 199,\n /** `video` block `author_name`; Slack requires fewer than 50. */\n videoAuthorNameChars: 49,\n /** `button` element `text`. */\n buttonTextChars: 75,\n /** Select `placeholder`. */\n placeholderChars: 150,\n /** `option_groups[].label`. */\n optionGroupLabelChars: 75,\n} as const;\n"]}
@@ -0,0 +1,25 @@
1
+ import { type SlackBlock, type SlackContainerBlock, type SlackContainerChildBlock, type SlackHeaderLevel } from './blocks.js';
2
+ /** Options for {@link slackContainer}: the container's optional fields, and the level of the `header` it falls back to. */
3
+ export type SlackContainerOptions = Partial<Pick<SlackContainerBlock, 'block_id' | 'subtitle' | 'icon' | 'width' | 'is_collapsible' | 'default_collapsed' | 'has_header_divider'>> & {
4
+ fallbackLevel?: SlackHeaderLevel;
5
+ };
6
+ /** A container Isomer fits, as opposed to one passed through `unmodeledSlackBlock`. */
7
+ export declare const isContainer: (block: SlackBlock) => block is SlackContainerBlock;
8
+ /** A container as the blocks it holds, led by its title and subtitle. */
9
+ export declare const unwrapContainer: ({ title, rich_text_title, subtitle, child_blocks }: SlackContainerBlock, level?: SlackHeaderLevel) => SlackContainerChildBlock[];
10
+ /**
11
+ * `container` holding `children`, with any nested container unwrapped, since
12
+ * Slack rejects one. A container left with no children, or more than
13
+ * `containerChildBlocks`, is unwrapped itself.
14
+ */
15
+ export declare const containerWithChildren: (container: SlackContainerBlock, children: readonly SlackBlock[], level?: SlackHeaderLevel) => SlackBlock[];
16
+ /**
17
+ * A titled section as one Block Kit `container`, from its title and the
18
+ * blocks its body rendered to, typically through `scope.renderSlack`.
19
+ *
20
+ * A nested container among `children` is unwrapped to its title and blocks.
21
+ * With no children, or more than `SLACK_LIMITS.containerChildBlocks`, the
22
+ * section falls back to a `header` at `fallbackLevel` followed by the blocks.
23
+ */
24
+ export declare const slackContainer: (title: string, children: readonly SlackBlock[], { fallbackLevel, ...fields }?: SlackContainerOptions) => SlackBlock[];
25
+ //# sourceMappingURL=container.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"container.d.ts","sourceRoot":"","sources":["../../../src/render/slack/container.ts"],"names":[],"mappings":"AAOA,OAAO,EAEL,KAAK,UAAU,EACf,KAAK,mBAAmB,EACxB,KAAK,wBAAwB,EAC7B,KAAK,gBAAgB,EACtB,MAAM,UAAU,CAAC;AAIlB,2HAA2H;AAC3H,MAAM,MAAM,qBAAqB,GAAG,OAAO,CACzC,IAAI,CACF,mBAAmB,EACjB,UAAU,GACV,UAAU,GACV,MAAM,GACN,OAAO,GACP,gBAAgB,GAChB,mBAAmB,GACnB,oBAAoB,CACvB,CACF,GAAG;IAAE,aAAa,CAAC,EAAE,gBAAgB,CAAA;CAAE,CAAC;AAEzC,uFAAuF;AACvF,eAAO,MAAM,WAAW,GAAI,OAAO,UAAU,KAAG,KAAK,IAAI,mBACI,CAAC;AAE9D,yEAAyE;AACzE,eAAO,MAAM,eAAe,GAC1B,oDAAoD,mBAAmB,EACvE,QAAQ,gBAAgB,KACvB,wBAAwB,EAc1B,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,GAChC,WAAW,mBAAmB,EAC9B,UAAU,SAAS,UAAU,EAAE,EAC/B,QAAQ,gBAAgB,KACvB,UAAU,EASZ,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,cAAc,GACzB,OAAO,MAAM,EACb,UAAU,SAAS,UAAU,EAAE,EAC/B,+BAA8B,qBAA0B,KACvD,UAAU,EAUV,CAAC"}
@@ -0,0 +1,55 @@
1
+ /*
2
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3
+ * or more contributor license agreements. Licensed under the Elastic License
4
+ * 2.0; you may not use this file except in compliance with the Elastic License
5
+ * 2.0.
6
+ */
7
+ import { SLACK_LIMITS, } from './blocks.js';
8
+ import { formatHeaderText } from './format.js';
9
+ import { isUnmodeledSlackBlock } from './unmodeled.js';
10
+ /** A container Isomer fits, as opposed to one passed through `unmodeledSlackBlock`. */
11
+ export const isContainer = (block) => block.type === 'container' && !isUnmodeledSlackBlock(block);
12
+ /** A container as the blocks it holds, led by its title and subtitle. */
13
+ export const unwrapContainer = ({ title, rich_text_title, subtitle, child_blocks }, level) => [
14
+ ...(rich_text_title
15
+ ? [rich_text_title]
16
+ : title
17
+ ? [
18
+ {
19
+ type: 'header',
20
+ text: title,
21
+ ...(level === undefined ? {} : { level }),
22
+ },
23
+ ]
24
+ : []),
25
+ ...(subtitle ? [{ type: 'context', elements: [subtitle] }] : []),
26
+ ...child_blocks,
27
+ ];
28
+ /**
29
+ * `container` holding `children`, with any nested container unwrapped, since
30
+ * Slack rejects one. A container left with no children, or more than
31
+ * `containerChildBlocks`, is unwrapped itself.
32
+ */
33
+ export const containerWithChildren = (container, children, level) => {
34
+ const child_blocks = children.flatMap((child) => isContainer(child) ? unwrapContainer(child) : [child]);
35
+ const refitted = { ...container, child_blocks };
36
+ return child_blocks.length === 0 ||
37
+ child_blocks.length > SLACK_LIMITS.containerChildBlocks
38
+ ? unwrapContainer(refitted, level)
39
+ : [refitted];
40
+ };
41
+ /**
42
+ * A titled section as one Block Kit `container`, from its title and the
43
+ * blocks its body rendered to, typically through `scope.renderSlack`.
44
+ *
45
+ * A nested container among `children` is unwrapped to its title and blocks.
46
+ * With no children, or more than `SLACK_LIMITS.containerChildBlocks`, the
47
+ * section falls back to a `header` at `fallbackLevel` followed by the blocks.
48
+ */
49
+ export const slackContainer = (title, children, { fallbackLevel, ...fields } = {}) => containerWithChildren({
50
+ type: 'container',
51
+ title: { type: 'plain_text', text: formatHeaderText(title), emoji: true },
52
+ ...fields,
53
+ child_blocks: [],
54
+ }, children, fallbackLevel);
55
+ //# sourceMappingURL=container.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"container.js","sourceRoot":"","sources":["../../../src/render/slack/container.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EACL,YAAY,GAKb,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAgBpD,uFAAuF;AACvF,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,KAAiB,EAAgC,EAAE,CAC7E,KAAK,CAAC,IAAI,KAAK,WAAW,IAAI,CAAC,qBAAqB,CAAC,KAAK,CAAC,CAAC;AAE9D,yEAAyE;AACzE,MAAM,CAAC,MAAM,eAAe,GAAG,CAC7B,EAAE,KAAK,EAAE,eAAe,EAAE,QAAQ,EAAE,YAAY,EAAuB,EACvE,KAAwB,EACI,EAAE,CAAC;IAC/B,GAAG,CAAC,eAAe;QACjB,CAAC,CAAC,CAAC,eAAe,CAAC;QACnB,CAAC,CAAC,KAAK;YACL,CAAC,CAAC;gBACE;oBACE,IAAI,EAAE,QAAiB;oBACvB,IAAI,EAAE,KAAK;oBACX,GAAG,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC;iBAC1C;aACF;YACH,CAAC,CAAC,EAAE,CAAC;IACT,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,SAAkB,EAAE,QAAQ,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACzE,GAAG,YAAY;CAChB,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,CACnC,SAA8B,EAC9B,QAA+B,EAC/B,KAAwB,EACV,EAAE;IAChB,MAAM,YAAY,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,CAC9C,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CACtD,CAAC;IACF,MAAM,QAAQ,GAAG,EAAE,GAAG,SAAS,EAAE,YAAY,EAAE,CAAC;IAChD,OAAO,YAAY,CAAC,MAAM,KAAK,CAAC;QAC9B,YAAY,CAAC,MAAM,GAAG,YAAY,CAAC,oBAAoB;QACvD,CAAC,CAAC,eAAe,CAAC,QAAQ,EAAE,KAAK,CAAC;QAClC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;AACjB,CAAC,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,CAC5B,KAAa,EACb,QAA+B,EAC/B,EAAE,aAAa,EAAE,GAAG,MAAM,KAA4B,EAAE,EAC1C,EAAE,CAChB,qBAAqB,CACnB;IACE,IAAI,EAAE,WAAW;IACjB,KAAK,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,gBAAgB,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE;IACzE,GAAG,MAAM;IACT,YAAY,EAAE,EAAE;CACjB,EACD,QAAQ,EACR,aAAa,CACd,CAAC","sourcesContent":["/*\n * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one\n * or more contributor license agreements. Licensed under the Elastic License\n * 2.0; you may not use this file except in compliance with the Elastic License\n * 2.0.\n */\n\nimport {\n SLACK_LIMITS,\n type SlackBlock,\n type SlackContainerBlock,\n type SlackContainerChildBlock,\n type SlackHeaderLevel,\n} from './blocks';\nimport { formatHeaderText } from './format';\nimport { isUnmodeledSlackBlock } from './unmodeled';\n\n/** Options for {@link slackContainer}: the container's optional fields, and the level of the `header` it falls back to. */\nexport type SlackContainerOptions = Partial<\n Pick<\n SlackContainerBlock,\n | 'block_id'\n | 'subtitle'\n | 'icon'\n | 'width'\n | 'is_collapsible'\n | 'default_collapsed'\n | 'has_header_divider'\n >\n> & { fallbackLevel?: SlackHeaderLevel };\n\n/** A container Isomer fits, as opposed to one passed through `unmodeledSlackBlock`. */\nexport const isContainer = (block: SlackBlock): block is SlackContainerBlock =>\n block.type === 'container' && !isUnmodeledSlackBlock(block);\n\n/** A container as the blocks it holds, led by its title and subtitle. */\nexport const unwrapContainer = (\n { title, rich_text_title, subtitle, child_blocks }: SlackContainerBlock,\n level?: SlackHeaderLevel\n): SlackContainerChildBlock[] => [\n ...(rich_text_title\n ? [rich_text_title]\n : title\n ? [\n {\n type: 'header' as const,\n text: title,\n ...(level === undefined ? {} : { level }),\n },\n ]\n : []),\n ...(subtitle ? [{ type: 'context' as const, elements: [subtitle] }] : []),\n ...child_blocks,\n];\n\n/**\n * `container` holding `children`, with any nested container unwrapped, since\n * Slack rejects one. A container left with no children, or more than\n * `containerChildBlocks`, is unwrapped itself.\n */\nexport const containerWithChildren = (\n container: SlackContainerBlock,\n children: readonly SlackBlock[],\n level?: SlackHeaderLevel\n): SlackBlock[] => {\n const child_blocks = children.flatMap((child) =>\n isContainer(child) ? unwrapContainer(child) : [child]\n );\n const refitted = { ...container, child_blocks };\n return child_blocks.length === 0 ||\n child_blocks.length > SLACK_LIMITS.containerChildBlocks\n ? unwrapContainer(refitted, level)\n : [refitted];\n};\n\n/**\n * A titled section as one Block Kit `container`, from its title and the\n * blocks its body rendered to, typically through `scope.renderSlack`.\n *\n * A nested container among `children` is unwrapped to its title and blocks.\n * With no children, or more than `SLACK_LIMITS.containerChildBlocks`, the\n * section falls back to a `header` at `fallbackLevel` followed by the blocks.\n */\nexport const slackContainer = (\n title: string,\n children: readonly SlackBlock[],\n { fallbackLevel, ...fields }: SlackContainerOptions = {}\n): SlackBlock[] =>\n containerWithChildren(\n {\n type: 'container',\n title: { type: 'plain_text', text: formatHeaderText(title), emoji: true },\n ...fields,\n child_blocks: [],\n },\n children,\n fallbackLevel\n );\n"]}
@@ -3,6 +3,7 @@ import type { PrimitiveNode } from '../../define/primitive_module.js';
3
3
  import type { MarkdownEnvelopeDispatcher } from '../markdown/envelope.js';
4
4
  import { type SlackAssetCollector, type SlackAssetRequest } from './assets.js';
5
5
  import { type SlackBlock } from './blocks.js';
6
+ import { type SlackLinkOptions } from './format.js';
6
7
  /**
7
8
  * Adds Block Kit to {@link MarkdownEnvelopeDispatcher}.
8
9
  *
@@ -14,10 +15,10 @@ import { type SlackBlock } from './blocks.js';
14
15
  */
15
16
  export interface SlackEnvelopeDispatcher<TNode extends PrimitiveNode> extends MarkdownEnvelopeDispatcher<TNode> {
16
17
  /** `collector` is absent unless the caller opted into asset collection, so a renderer must still degrade an image it cannot upload. */
17
- renderSlack(node: TNode, collector?: SlackAssetCollector): readonly SlackBlock[];
18
+ renderSlack(node: TNode, collector?: SlackAssetCollector, options?: SlackLinkOptions): readonly SlackBlock[];
18
19
  }
19
20
  /** Options for {@link renderSlackEnvelope}. */
20
- export interface SlackEnvelopeOptions {
21
+ export interface SlackEnvelopeOptions extends SlackLinkOptions {
21
22
  /** Renders the composition's title and subtitle, in the blocks and the fallback `text`. Defaults to `true`. Pass `false` when the host already shows the title, or the body opens with its own. */
22
23
  heading?: boolean;
23
24
  /** Fallback `text` summary shown in notifications and previews, as `mrkdwn`; defaults to the text render, escaped. */
@@ -45,8 +46,9 @@ export interface SlackEnvelopeResult {
45
46
  * fitted to Slack's limits — text is clamped, blocks past a count limit and
46
47
  * `rich_text` elements past a section's limit split, tables past a table limit
47
48
  * or the message's cell budget become rich text, spacers and then whole blocks
48
- * are dropped — so the output is always postable. `assets` stays empty
49
- * unless `collectAssets` is set.
49
+ * are dropped — so the output is always postable, except for a block from
50
+ * `unmodeledSlackBlock` or of a type Isomer does not model, which passes
51
+ * through unfitted. `assets` stays empty unless `collectAssets` is set.
50
52
  */
51
53
  export declare const renderSlackEnvelope: <TNode extends PrimitiveNode>(composition: Composition<TNode>, dispatcher: SlackEnvelopeDispatcher<TNode>, options?: SlackEnvelopeOptions) => SlackEnvelopeResult;
52
54
  //# sourceMappingURL=envelope.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"envelope.d.ts","sourceRoot":"","sources":["../../../src/render/slack/envelope.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AACjE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,sBAAsB,CAAC;AAGvE,OAAO,EAEL,KAAK,mBAAmB,EACxB,KAAK,iBAAiB,EACvB,MAAM,UAAU,CAAC;AAClB,OAAO,EAGL,KAAK,UAAU,EAahB,MAAM,UAAU,CAAC;AAUlB;;;;;;;;GAQG;AACH,MAAM,WAAW,uBAAuB,CACtC,KAAK,SAAS,aAAa,CAC3B,SAAQ,0BAA0B,CAAC,KAAK,CAAC;IACzC,uIAAuI;IACvI,WAAW,CACT,IAAI,EAAE,KAAK,EACX,SAAS,CAAC,EAAE,mBAAmB,GAC9B,SAAS,UAAU,EAAE,CAAC;CAC1B;AAED,+CAA+C;AAC/C,MAAM,WAAW,oBAAoB;IACnC,mMAAmM;IACnM,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,sHAAsH;IACtH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,qEAAqE;IACrE,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,8GAA8G;IAC9G,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,gFAAgF;AAChF,MAAM,WAAW,mBAAmB;IAClC,qCAAqC;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,kDAAkD;IAClD,MAAM,EAAE,UAAU,EAAE,CAAC;IACrB,qEAAqE;IACrE,MAAM,EAAE,iBAAiB,EAAE,CAAC;CAC7B;AAED;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,mBAAmB,GAAI,KAAK,SAAS,aAAa,EAC7D,aAAa,WAAW,CAAC,KAAK,CAAC,EAC/B,YAAY,uBAAuB,CAAC,KAAK,CAAC,EAC1C,UAAS,oBAAyB,KACjC,mBA2CF,CAAC"}
1
+ {"version":3,"file":"envelope.d.ts","sourceRoot":"","sources":["../../../src/render/slack/envelope.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AACjE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,sBAAsB,CAAC;AAGvE,OAAO,EAEL,KAAK,mBAAmB,EACxB,KAAK,iBAAiB,EACvB,MAAM,UAAU,CAAC;AAClB,OAAO,EAGL,KAAK,UAAU,EAchB,MAAM,UAAU,CAAC;AAElB,OAAO,EAQL,KAAK,gBAAgB,EACtB,MAAM,UAAU,CAAC;AAGlB;;;;;;;;GAQG;AACH,MAAM,WAAW,uBAAuB,CACtC,KAAK,SAAS,aAAa,CAC3B,SAAQ,0BAA0B,CAAC,KAAK,CAAC;IACzC,uIAAuI;IACvI,WAAW,CACT,IAAI,EAAE,KAAK,EACX,SAAS,CAAC,EAAE,mBAAmB,EAC/B,OAAO,CAAC,EAAE,gBAAgB,GACzB,SAAS,UAAU,EAAE,CAAC;CAC1B;AAED,+CAA+C;AAC/C,MAAM,WAAW,oBAAqB,SAAQ,gBAAgB;IAC5D,mMAAmM;IACnM,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,sHAAsH;IACtH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,qEAAqE;IACrE,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,8GAA8G;IAC9G,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,gFAAgF;AAChF,MAAM,WAAW,mBAAmB;IAClC,qCAAqC;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,kDAAkD;IAClD,MAAM,EAAE,UAAU,EAAE,CAAC;IACrB,qEAAqE;IACrE,MAAM,EAAE,iBAAiB,EAAE,CAAC;CAC7B;AAED;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,mBAAmB,GAAI,KAAK,SAAS,aAAa,EAC7D,aAAa,WAAW,CAAC,KAAK,CAAC,EAC/B,YAAY,uBAAuB,CAAC,KAAK,CAAC,EAC1C,UAAS,oBAAyB,KACjC,mBA+CF,CAAC"}