@elastic/isomer-studio 0.0.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 (406) hide show
  1. package/LICENSE.txt +93 -0
  2. package/NOTICE.txt +17329 -0
  3. package/README.md +64 -0
  4. package/THIRD_PARTY_LICENSES.md +404 -0
  5. package/bin/isomer-studio.js +10 -0
  6. package/dist/app/assets/codicon-5T574S7B.ttf +0 -0
  7. package/dist/app/assets/editor.worker.js +11 -0
  8. package/dist/app/assets/esbuild.wasm +0 -0
  9. package/dist/app/assets/json.worker.js +47 -0
  10. package/dist/app/assets/slack.css +1 -0
  11. package/dist/app/assets/studio.css +11 -0
  12. package/dist/app/assets/ts.worker.js +37029 -0
  13. package/dist/app/index.html +16 -0
  14. package/dist/apps/app_host.d.ts +8 -0
  15. package/dist/apps/app_host.d.ts.map +1 -0
  16. package/dist/apps/app_host.js +73 -0
  17. package/dist/apps/app_host.js.map +1 -0
  18. package/dist/browser/dev_host.d.ts +5 -0
  19. package/dist/browser/dev_host.d.ts.map +1 -0
  20. package/dist/browser/dev_host.js +46 -0
  21. package/dist/browser/dev_host.js.map +1 -0
  22. package/dist/browser/mount.d.ts +16 -0
  23. package/dist/browser/mount.d.ts.map +1 -0
  24. package/dist/browser/mount.js +37 -0
  25. package/dist/browser/mount.js.map +1 -0
  26. package/dist/browser/static_host.d.ts +5 -0
  27. package/dist/browser/static_host.d.ts.map +1 -0
  28. package/dist/browser/static_host.js +55 -0
  29. package/dist/browser/static_host.js.map +1 -0
  30. package/dist/chrome/accent.d.ts +14 -0
  31. package/dist/chrome/accent.d.ts.map +1 -0
  32. package/dist/chrome/accent.js +31 -0
  33. package/dist/chrome/accent.js.map +1 -0
  34. package/dist/chrome/app_pages.d.ts +13 -0
  35. package/dist/chrome/app_pages.d.ts.map +1 -0
  36. package/dist/chrome/app_pages.js +33 -0
  37. package/dist/chrome/app_pages.js.map +1 -0
  38. package/dist/chrome/color_mode.d.ts +10 -0
  39. package/dist/chrome/color_mode.d.ts.map +1 -0
  40. package/dist/chrome/color_mode.js +45 -0
  41. package/dist/chrome/color_mode.js.map +1 -0
  42. package/dist/chrome/dev_tint.d.ts +7 -0
  43. package/dist/chrome/dev_tint.d.ts.map +1 -0
  44. package/dist/chrome/dev_tint.js +31 -0
  45. package/dist/chrome/dev_tint.js.map +1 -0
  46. package/dist/chrome/header.d.ts +20 -0
  47. package/dist/chrome/header.d.ts.map +1 -0
  48. package/dist/chrome/header.js +124 -0
  49. package/dist/chrome/header.js.map +1 -0
  50. package/dist/chrome/icon_data_uri.d.ts +12 -0
  51. package/dist/chrome/icon_data_uri.d.ts.map +1 -0
  52. package/dist/chrome/icon_data_uri.js +21 -0
  53. package/dist/chrome/icon_data_uri.js.map +1 -0
  54. package/dist/chrome/isomer_mark.d.ts +17 -0
  55. package/dist/chrome/isomer_mark.d.ts.map +1 -0
  56. package/dist/chrome/isomer_mark.js +46 -0
  57. package/dist/chrome/isomer_mark.js.map +1 -0
  58. package/dist/chrome/nav.d.ts +22 -0
  59. package/dist/chrome/nav.d.ts.map +1 -0
  60. package/dist/chrome/nav.js +306 -0
  61. package/dist/chrome/nav.js.map +1 -0
  62. package/dist/chrome/nav_groups.d.ts +6 -0
  63. package/dist/chrome/nav_groups.d.ts.map +1 -0
  64. package/dist/chrome/nav_groups.js +48 -0
  65. package/dist/chrome/nav_groups.js.map +1 -0
  66. package/dist/chrome/nav_sections.d.ts +29 -0
  67. package/dist/chrome/nav_sections.d.ts.map +1 -0
  68. package/dist/chrome/nav_sections.js +55 -0
  69. package/dist/chrome/nav_sections.js.map +1 -0
  70. package/dist/chrome/oklch.d.ts +10 -0
  71. package/dist/chrome/oklch.d.ts.map +1 -0
  72. package/dist/chrome/oklch.js +61 -0
  73. package/dist/chrome/oklch.js.map +1 -0
  74. package/dist/chrome/primitive_glyph.d.ts +14 -0
  75. package/dist/chrome/primitive_glyph.d.ts.map +1 -0
  76. package/dist/chrome/primitive_glyph.js +48 -0
  77. package/dist/chrome/primitive_glyph.js.map +1 -0
  78. package/dist/chrome/primitive_heading.d.ts +14 -0
  79. package/dist/chrome/primitive_heading.d.ts.map +1 -0
  80. package/dist/chrome/primitive_heading.js +32 -0
  81. package/dist/chrome/primitive_heading.js.map +1 -0
  82. package/dist/chrome/primitive_peek.d.ts +8 -0
  83. package/dist/chrome/primitive_peek.d.ts.map +1 -0
  84. package/dist/chrome/primitive_peek.js +51 -0
  85. package/dist/chrome/primitive_peek.js.map +1 -0
  86. package/dist/chrome/primitive_search.d.ts +9 -0
  87. package/dist/chrome/primitive_search.d.ts.map +1 -0
  88. package/dist/chrome/primitive_search.js +93 -0
  89. package/dist/chrome/primitive_search.js.map +1 -0
  90. package/dist/chrome/route.d.ts +48 -0
  91. package/dist/chrome/route.d.ts.map +1 -0
  92. package/dist/chrome/route.js +136 -0
  93. package/dist/chrome/route.js.map +1 -0
  94. package/dist/cli/args.d.ts +39 -0
  95. package/dist/cli/args.d.ts.map +1 -0
  96. package/dist/cli/args.js +171 -0
  97. package/dist/cli/args.js.map +1 -0
  98. package/dist/cli/run.d.ts +15 -0
  99. package/dist/cli/run.d.ts.map +1 -0
  100. package/dist/cli/run.js +113 -0
  101. package/dist/cli/run.js.map +1 -0
  102. package/dist/cli.d.ts +2 -0
  103. package/dist/cli.d.ts.map +1 -0
  104. package/dist/cli.js +22 -0
  105. package/dist/cli.js.map +1 -0
  106. package/dist/config.d.ts +118 -0
  107. package/dist/config.d.ts.map +1 -0
  108. package/dist/config.js +11 -0
  109. package/dist/config.js.map +1 -0
  110. package/dist/dev/code_editor.d.ts +10 -0
  111. package/dist/dev/code_editor.d.ts.map +1 -0
  112. package/dist/dev/code_editor.js +22 -0
  113. package/dist/dev/code_editor.js.map +1 -0
  114. package/dist/dev/dev_view.d.ts +9 -0
  115. package/dist/dev/dev_view.d.ts.map +1 -0
  116. package/dist/dev/dev_view.js +65 -0
  117. package/dist/dev/dev_view.js.map +1 -0
  118. package/dist/dev/editor_panel.d.ts +17 -0
  119. package/dist/dev/editor_panel.d.ts.map +1 -0
  120. package/dist/dev/editor_panel.js +51 -0
  121. package/dist/dev/editor_panel.js.map +1 -0
  122. package/dist/dev/monaco_editor.d.ts +15 -0
  123. package/dist/dev/monaco_editor.d.ts.map +1 -0
  124. package/dist/dev/monaco_editor.js +159 -0
  125. package/dist/dev/monaco_editor.js.map +1 -0
  126. package/dist/dev/preview_panel.d.ts +10 -0
  127. package/dist/dev/preview_panel.d.ts.map +1 -0
  128. package/dist/dev/preview_panel.js +45 -0
  129. package/dist/dev/preview_panel.js.map +1 -0
  130. package/dist/dev/prop_reference.d.ts +9 -0
  131. package/dist/dev/prop_reference.d.ts.map +1 -0
  132. package/dist/dev/prop_reference.js +134 -0
  133. package/dist/dev/prop_reference.js.map +1 -0
  134. package/dist/dev/tsx_language.d.ts +10 -0
  135. package/dist/dev/tsx_language.d.ts.map +1 -0
  136. package/dist/dev/tsx_language.js +283 -0
  137. package/dist/dev/tsx_language.js.map +1 -0
  138. package/dist/dev/use_editor.d.ts +23 -0
  139. package/dist/dev/use_editor.d.ts.map +1 -0
  140. package/dist/dev/use_editor.js +124 -0
  141. package/dist/dev/use_editor.js.map +1 -0
  142. package/dist/docs/docs_view.d.ts +10 -0
  143. package/dist/docs/docs_view.d.ts.map +1 -0
  144. package/dist/docs/docs_view.js +80 -0
  145. package/dist/docs/docs_view.js.map +1 -0
  146. package/dist/docs/example_source.d.ts +7 -0
  147. package/dist/docs/example_source.d.ts.map +1 -0
  148. package/dist/docs/example_source.js +56 -0
  149. package/dist/docs/example_source.js.map +1 -0
  150. package/dist/docs/examples_panel.d.ts +10 -0
  151. package/dist/docs/examples_panel.d.ts.map +1 -0
  152. package/dist/docs/examples_panel.js +51 -0
  153. package/dist/docs/examples_panel.js.map +1 -0
  154. package/dist/docs/gallery_view.d.ts +9 -0
  155. package/dist/docs/gallery_view.d.ts.map +1 -0
  156. package/dist/docs/gallery_view.js +98 -0
  157. package/dist/docs/gallery_view.js.map +1 -0
  158. package/dist/docs/inline_code.d.ts +11 -0
  159. package/dist/docs/inline_code.d.ts.map +1 -0
  160. package/dist/docs/inline_code.js +24 -0
  161. package/dist/docs/inline_code.js.map +1 -0
  162. package/dist/docs/on_this_page.d.ts +17 -0
  163. package/dist/docs/on_this_page.d.ts.map +1 -0
  164. package/dist/docs/on_this_page.js +77 -0
  165. package/dist/docs/on_this_page.js.map +1 -0
  166. package/dist/docs/props_table.d.ts +14 -0
  167. package/dist/docs/props_table.d.ts.map +1 -0
  168. package/dist/docs/props_table.js +34 -0
  169. package/dist/docs/props_table.js.map +1 -0
  170. package/dist/home/apps_section.d.ts +6 -0
  171. package/dist/home/apps_section.d.ts.map +1 -0
  172. package/dist/home/apps_section.js +44 -0
  173. package/dist/home/apps_section.js.map +1 -0
  174. package/dist/home/featured_strip.d.ts +12 -0
  175. package/dist/home/featured_strip.d.ts.map +1 -0
  176. package/dist/home/featured_strip.js +176 -0
  177. package/dist/home/featured_strip.js.map +1 -0
  178. package/dist/home/home_view.d.ts +11 -0
  179. package/dist/home/home_view.d.ts.map +1 -0
  180. package/dist/home/home_view.js +261 -0
  181. package/dist/home/home_view.js.map +1 -0
  182. package/dist/home/links.d.ts +8 -0
  183. package/dist/home/links.d.ts.map +1 -0
  184. package/dist/home/links.js +14 -0
  185. package/dist/home/links.js.map +1 -0
  186. package/dist/home/loaded_panel.d.ts +6 -0
  187. package/dist/home/loaded_panel.d.ts.map +1 -0
  188. package/dist/home/loaded_panel.js +116 -0
  189. package/dist/home/loaded_panel.js.map +1 -0
  190. package/dist/home/surface_chart.d.ts +6 -0
  191. package/dist/home/surface_chart.d.ts.map +1 -0
  192. package/dist/home/surface_chart.js +263 -0
  193. package/dist/home/surface_chart.js.map +1 -0
  194. package/dist/home/tokens.d.ts +49 -0
  195. package/dist/home/tokens.d.ts.map +1 -0
  196. package/dist/home/tokens.js +171 -0
  197. package/dist/home/tokens.js.map +1 -0
  198. package/dist/index.d.ts +6 -0
  199. package/dist/index.d.ts.map +1 -0
  200. package/dist/index.js +9 -0
  201. package/dist/index.js.map +1 -0
  202. package/dist/model/app_problems.d.ts +4 -0
  203. package/dist/model/app_problems.d.ts.map +1 -0
  204. package/dist/model/app_problems.js +90 -0
  205. package/dist/model/app_problems.js.map +1 -0
  206. package/dist/model/authoring_types.d.ts +23 -0
  207. package/dist/model/authoring_types.d.ts.map +1 -0
  208. package/dist/model/authoring_types.js +35 -0
  209. package/dist/model/authoring_types.js.map +1 -0
  210. package/dist/model/compile_jsx.d.ts +19 -0
  211. package/dist/model/compile_jsx.d.ts.map +1 -0
  212. package/dist/model/compile_jsx.js +55 -0
  213. package/dist/model/compile_jsx.js.map +1 -0
  214. package/dist/model/compose_example.d.ts +9 -0
  215. package/dist/model/compose_example.d.ts.map +1 -0
  216. package/dist/model/compose_example.js +24 -0
  217. package/dist/model/compose_example.js.map +1 -0
  218. package/dist/model/composition_key.d.ts +6 -0
  219. package/dist/model/composition_key.d.ts.map +1 -0
  220. package/dist/model/composition_key.js +26 -0
  221. package/dist/model/composition_key.js.map +1 -0
  222. package/dist/model/describe_runtime.d.ts +33 -0
  223. package/dist/model/describe_runtime.d.ts.map +1 -0
  224. package/dist/model/describe_runtime.js +77 -0
  225. package/dist/model/describe_runtime.js.map +1 -0
  226. package/dist/model/featured.d.ts +11 -0
  227. package/dist/model/featured.d.ts.map +1 -0
  228. package/dist/model/featured.js +70 -0
  229. package/dist/model/featured.js.map +1 -0
  230. package/dist/model/jsx_transform.d.ts +10 -0
  231. package/dist/model/jsx_transform.d.ts.map +1 -0
  232. package/dist/model/jsx_transform.js +31 -0
  233. package/dist/model/jsx_transform.js.map +1 -0
  234. package/dist/model/png_manifest.d.ts +23 -0
  235. package/dist/model/png_manifest.d.ts.map +1 -0
  236. package/dist/model/png_manifest.js +26 -0
  237. package/dist/model/png_manifest.js.map +1 -0
  238. package/dist/model/read_examples.d.ts +12 -0
  239. package/dist/model/read_examples.d.ts.map +1 -0
  240. package/dist/model/read_examples.js +43 -0
  241. package/dist/model/read_examples.js.map +1 -0
  242. package/dist/model/search.d.ts +4 -0
  243. package/dist/model/search.d.ts.map +1 -0
  244. package/dist/model/search.js +29 -0
  245. package/dist/model/search.js.map +1 -0
  246. package/dist/model/sha256.d.ts +3 -0
  247. package/dist/model/sha256.d.ts.map +1 -0
  248. package/dist/model/sha256.js +72 -0
  249. package/dist/model/sha256.js.map +1 -0
  250. package/dist/model/slack_limits.d.ts +9 -0
  251. package/dist/model/slack_limits.d.ts.map +1 -0
  252. package/dist/model/slack_limits.js +213 -0
  253. package/dist/model/slack_limits.js.map +1 -0
  254. package/dist/node/app_bundle.d.ts +45 -0
  255. package/dist/node/app_bundle.d.ts.map +1 -0
  256. package/dist/node/app_bundle.js +212 -0
  257. package/dist/node/app_bundle.js.map +1 -0
  258. package/dist/node/build_site.d.ts +28 -0
  259. package/dist/node/build_site.d.ts.map +1 -0
  260. package/dist/node/build_site.js +90 -0
  261. package/dist/node/build_site.js.map +1 -0
  262. package/dist/node/check.d.ts +40 -0
  263. package/dist/node/check.d.ts.map +1 -0
  264. package/dist/node/check.js +162 -0
  265. package/dist/node/check.js.map +1 -0
  266. package/dist/node/dev_bundle.d.ts +21 -0
  267. package/dist/node/dev_bundle.d.ts.map +1 -0
  268. package/dist/node/dev_bundle.js +121 -0
  269. package/dist/node/dev_bundle.js.map +1 -0
  270. package/dist/node/dev_server.d.ts +16 -0
  271. package/dist/node/dev_server.d.ts.map +1 -0
  272. package/dist/node/dev_server.js +291 -0
  273. package/dist/node/dev_server.js.map +1 -0
  274. package/dist/node/init_config.d.ts +30 -0
  275. package/dist/node/init_config.d.ts.map +1 -0
  276. package/dist/node/init_config.js +158 -0
  277. package/dist/node/init_config.js.map +1 -0
  278. package/dist/node/load_config.d.ts +34 -0
  279. package/dist/node/load_config.d.ts.map +1 -0
  280. package/dist/node/load_config.js +246 -0
  281. package/dist/node/load_config.js.map +1 -0
  282. package/dist/node/project_resolution.d.ts +17 -0
  283. package/dist/node/project_resolution.d.ts.map +1 -0
  284. package/dist/node/project_resolution.js +66 -0
  285. package/dist/node/project_resolution.js.map +1 -0
  286. package/dist/node/rasterize.d.ts +23 -0
  287. package/dist/node/rasterize.d.ts.map +1 -0
  288. package/dist/node/rasterize.js +79 -0
  289. package/dist/node/rasterize.js.map +1 -0
  290. package/dist/node/report.d.ts +8 -0
  291. package/dist/node/report.d.ts.map +1 -0
  292. package/dist/node/report.js +57 -0
  293. package/dist/node/report.js.map +1 -0
  294. package/dist/node/resolve_hooks.d.ts +16 -0
  295. package/dist/node/resolve_hooks.d.ts.map +1 -0
  296. package/dist/node/resolve_hooks.js +104 -0
  297. package/dist/node/resolve_hooks.js.map +1 -0
  298. package/dist/studio.d.ts +4 -0
  299. package/dist/studio.d.ts.map +1 -0
  300. package/dist/studio.js +188 -0
  301. package/dist/studio.js.map +1 -0
  302. package/dist/studio_context.d.ts +27 -0
  303. package/dist/studio_context.d.ts.map +1 -0
  304. package/dist/studio_context.js +17 -0
  305. package/dist/studio_context.js.map +1 -0
  306. package/dist/surfaces/adopt_stylesheet.d.ts +7 -0
  307. package/dist/surfaces/adopt_stylesheet.d.ts.map +1 -0
  308. package/dist/surfaces/adopt_stylesheet.js +64 -0
  309. package/dist/surfaces/adopt_stylesheet.js.map +1 -0
  310. package/dist/surfaces/app_preview.d.ts +4 -0
  311. package/dist/surfaces/app_preview.d.ts.map +1 -0
  312. package/dist/surfaces/app_preview.js +28 -0
  313. package/dist/surfaces/app_preview.js.map +1 -0
  314. package/dist/surfaces/app_surface.d.ts +9 -0
  315. package/dist/surfaces/app_surface.d.ts.map +1 -0
  316. package/dist/surfaces/app_surface.js +27 -0
  317. package/dist/surfaces/app_surface.js.map +1 -0
  318. package/dist/surfaces/applicable_enhancements.d.ts +4 -0
  319. package/dist/surfaces/applicable_enhancements.d.ts.map +1 -0
  320. package/dist/surfaces/applicable_enhancements.js +16 -0
  321. package/dist/surfaces/applicable_enhancements.js.map +1 -0
  322. package/dist/surfaces/enhancement_select.d.ts +10 -0
  323. package/dist/surfaces/enhancement_select.d.ts.map +1 -0
  324. package/dist/surfaces/enhancement_select.js +28 -0
  325. package/dist/surfaces/enhancement_select.js.map +1 -0
  326. package/dist/surfaces/example_picker.d.ts +11 -0
  327. package/dist/surfaces/example_picker.d.ts.map +1 -0
  328. package/dist/surfaces/example_picker.js +44 -0
  329. package/dist/surfaces/example_picker.js.map +1 -0
  330. package/dist/surfaces/format_source.d.ts +4 -0
  331. package/dist/surfaces/format_source.d.ts.map +1 -0
  332. package/dist/surfaces/format_source.js +30 -0
  333. package/dist/surfaces/format_source.js.map +1 -0
  334. package/dist/surfaces/html_surface.d.ts +14 -0
  335. package/dist/surfaces/html_surface.d.ts.map +1 -0
  336. package/dist/surfaces/html_surface.js +122 -0
  337. package/dist/surfaces/html_surface.js.map +1 -0
  338. package/dist/surfaces/png_surface.d.ts +13 -0
  339. package/dist/surfaces/png_surface.d.ts.map +1 -0
  340. package/dist/surfaces/png_surface.js +68 -0
  341. package/dist/surfaces/png_surface.js.map +1 -0
  342. package/dist/surfaces/react_surface.d.ts +11 -0
  343. package/dist/surfaces/react_surface.d.ts.map +1 -0
  344. package/dist/surfaces/react_surface.js +55 -0
  345. package/dist/surfaces/react_surface.js.map +1 -0
  346. package/dist/surfaces/render_output.d.ts +31 -0
  347. package/dist/surfaces/render_output.d.ts.map +1 -0
  348. package/dist/surfaces/render_output.js +119 -0
  349. package/dist/surfaces/render_output.js.map +1 -0
  350. package/dist/surfaces/scaled_preview.d.ts +17 -0
  351. package/dist/surfaces/scaled_preview.d.ts.map +1 -0
  352. package/dist/surfaces/scaled_preview.js +74 -0
  353. package/dist/surfaces/scaled_preview.js.map +1 -0
  354. package/dist/surfaces/shadow_root.d.ts +8 -0
  355. package/dist/surfaces/shadow_root.d.ts.map +1 -0
  356. package/dist/surfaces/shadow_root.js +41 -0
  357. package/dist/surfaces/shadow_root.js.map +1 -0
  358. package/dist/surfaces/slack_surface.d.ts +12 -0
  359. package/dist/surfaces/slack_surface.d.ts.map +1 -0
  360. package/dist/surfaces/slack_surface.js +27 -0
  361. package/dist/surfaces/slack_surface.js.map +1 -0
  362. package/dist/surfaces/snapshot_surface.d.ts +6 -0
  363. package/dist/surfaces/snapshot_surface.d.ts.map +1 -0
  364. package/dist/surfaces/snapshot_surface.js +5 -0
  365. package/dist/surfaces/snapshot_surface.js.map +1 -0
  366. package/dist/surfaces/surface_board.d.ts +19 -0
  367. package/dist/surfaces/surface_board.d.ts.map +1 -0
  368. package/dist/surfaces/surface_board.js +128 -0
  369. package/dist/surfaces/surface_board.js.map +1 -0
  370. package/dist/surfaces/surface_frame.d.ts +8 -0
  371. package/dist/surfaces/surface_frame.d.ts.map +1 -0
  372. package/dist/surfaces/surface_frame.js +4 -0
  373. package/dist/surfaces/surface_frame.js.map +1 -0
  374. package/dist/surfaces/surface_logos.d.ts +9 -0
  375. package/dist/surfaces/surface_logos.d.ts.map +1 -0
  376. package/dist/surfaces/surface_logos.js +21 -0
  377. package/dist/surfaces/surface_logos.js.map +1 -0
  378. package/dist/surfaces/surface_preview.d.ts +32 -0
  379. package/dist/surfaces/surface_preview.d.ts.map +1 -0
  380. package/dist/surfaces/surface_preview.js +66 -0
  381. package/dist/surfaces/surface_preview.js.map +1 -0
  382. package/dist/surfaces/surface_select.d.ts +34 -0
  383. package/dist/surfaces/surface_select.d.ts.map +1 -0
  384. package/dist/surfaces/surface_select.js +119 -0
  385. package/dist/surfaces/surface_select.js.map +1 -0
  386. package/dist/surfaces/text_surfaces.d.ts +14 -0
  387. package/dist/surfaces/text_surfaces.d.ts.map +1 -0
  388. package/dist/surfaces/text_surfaces.js +31 -0
  389. package/dist/surfaces/text_surfaces.js.map +1 -0
  390. package/dist/surfaces/zoom_select.d.ts +9 -0
  391. package/dist/surfaces/zoom_select.d.ts.map +1 -0
  392. package/dist/surfaces/zoom_select.js +32 -0
  393. package/dist/surfaces/zoom_select.js.map +1 -0
  394. package/dist/types.d.ts +32 -0
  395. package/dist/types.d.ts.map +1 -0
  396. package/dist/types.js +9 -0
  397. package/dist/types.js.map +1 -0
  398. package/docs/ci.md +55 -0
  399. package/docs/commands.md +167 -0
  400. package/docs/config.md +192 -0
  401. package/docs/images/home.png +0 -0
  402. package/docs/images/reference.png +0 -0
  403. package/docs/images/workbench.png +0 -0
  404. package/docs/index.md +96 -0
  405. package/docs/toc.yml +10 -0
  406. package/package.json +89 -5
@@ -0,0 +1,213 @@
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 { isModeledSlackBlockType, isUnmodeledSlackBlock, SLACK_LIMITS, } from '@elastic/isomer-sdk/slack';
8
+ const list = (value) => value ?? [];
9
+ const overLength = (where, text, limit) => typeof text === 'string' && text.length > limit
10
+ ? [`${where} has ${text.length} characters; Slack allows ${limit}.`]
11
+ : [];
12
+ const overCount = (where, count, limit) => count > limit ? [`${where} has ${count}; Slack allows ${limit}.`] : [];
13
+ const empty = (where, count) => count === 0 ? [`${where} is empty; Slack requires at least 1.`] : [];
14
+ const inlineText = (inline) => inline.type === 'link' ? (inline.text ?? inline.url) : inline.text;
15
+ const richTextText = (element) => element.type === 'rich_text_list'
16
+ ? list(element.elements).map(richTextText).join('')
17
+ : list(element.elements).map(inlineText).join('');
18
+ const cellText = (cell) => cell.type === 'raw_text'
19
+ ? cell.text
20
+ : list(cell.elements).map(richTextText).join('');
21
+ const imageProblems = (where, { image_url, alt_text }) => [
22
+ ...overLength(`${where} image_url`, image_url, SLACK_LIMITS.imageUrlChars),
23
+ ...overLength(`${where} alt_text`, alt_text, SLACK_LIMITS.imageAltTextChars),
24
+ ];
25
+ const optionProblems = (where, { text, value, description, url }) => [
26
+ ...overLength(`${where} text`, text?.text, SLACK_LIMITS.optionTextChars),
27
+ ...overLength(`${where} value`, value, SLACK_LIMITS.optionValueChars),
28
+ ...overLength(`${where} description`, description?.text, SLACK_LIMITS.optionTextChars),
29
+ ...overLength(`${where} url`, url, SLACK_LIMITS.urlChars),
30
+ ];
31
+ const optionsProblems = (where, options, limit) => [
32
+ ...overCount(`${where} options`, list(options).length, limit),
33
+ ...list(options).flatMap((option, index) => optionProblems(`${where} options[${index}]`, option)),
34
+ ];
35
+ const controlProblems = (where, element) => {
36
+ const actionId = overLength(`${where} action_id`, element.action_id, SLACK_LIMITS.actionIdChars);
37
+ switch (element.type) {
38
+ case 'button':
39
+ return [
40
+ ...actionId,
41
+ ...overLength(`${where} text`, element.text?.text, SLACK_LIMITS.buttonTextChars),
42
+ ...overLength(`${where} value`, element.value, SLACK_LIMITS.buttonValueChars),
43
+ ...overLength(`${where} url`, element.url, SLACK_LIMITS.urlChars),
44
+ ];
45
+ case 'overflow':
46
+ return [
47
+ ...actionId,
48
+ ...optionsProblems(where, element.options, SLACK_LIMITS.optionsPerOverflow),
49
+ ];
50
+ case 'radio_buttons':
51
+ case 'checkboxes':
52
+ return [
53
+ ...actionId,
54
+ ...optionsProblems(where, element.options, SLACK_LIMITS.optionsPerChoice),
55
+ ];
56
+ case 'static_select':
57
+ case 'multi_static_select': {
58
+ const groups = element.type === 'static_select' ? list(element.option_groups) : [];
59
+ return [
60
+ ...actionId,
61
+ ...overLength(`${where} placeholder`, element.placeholder?.text, SLACK_LIMITS.placeholderChars),
62
+ ...optionsProblems(where, element.options, SLACK_LIMITS.optionsPerSelect),
63
+ ...overCount(`${where} option_groups`, groups.length, SLACK_LIMITS.optionGroupsPerSelect),
64
+ ...groups.flatMap(({ label, options }, index) => [
65
+ ...overLength(`${where} option_groups[${index}] label`, label?.text, SLACK_LIMITS.optionGroupLabelChars),
66
+ ...optionsProblems(`${where} option_groups[${index}]`, options, SLACK_LIMITS.optionsPerSelect),
67
+ ]),
68
+ ];
69
+ }
70
+ default:
71
+ return actionId;
72
+ }
73
+ };
74
+ const accessoryProblems = (where, accessory) => accessory.type === 'image'
75
+ ? imageProblems(where, accessory)
76
+ : controlProblems(where, accessory);
77
+ const richTextProblems = (where, element, textLimit) => {
78
+ if (element.type === 'rich_text_list') {
79
+ return overCount(`${where} indent`, element.indent ?? 0, SLACK_LIMITS.richTextListMaxIndent);
80
+ }
81
+ return textLimit === undefined
82
+ ? []
83
+ : overLength(`${where} text`, richTextText(element), textLimit);
84
+ };
85
+ /** Only a top-level element has a `textLimit`; list items and table cells count toward the message's budgets alone. */
86
+ const richTextBlockProblems = (where, { elements }, textLimit) => list(elements).flatMap((element, elementIndex) => richTextProblems(`${where} elements[${elementIndex}]`, element, textLimit));
87
+ /** Every block in the message, a container's children after it, each with the path a problem names. */
88
+ const located = (blocks) => blocks.flatMap((block, index) => {
89
+ const where = `blocks[${index}] (${block.type})`;
90
+ return [
91
+ { where, block },
92
+ ...(block.type === 'container'
93
+ ? list(block.child_blocks).map((child, childIndex) => ({
94
+ where: `${where} child_blocks[${childIndex}] (${child.type})`,
95
+ block: child,
96
+ }))
97
+ : []),
98
+ ];
99
+ });
100
+ const blockProblems = ({ where, block }) => {
101
+ switch (block.type) {
102
+ case 'container': {
103
+ const children = list(block.child_blocks);
104
+ return [
105
+ ...overLength(`${where} title`, block.title?.text, SLACK_LIMITS.containerTitleChars),
106
+ ...overLength(`${where} subtitle`, block.subtitle?.text, SLACK_LIMITS.containerSubtitleChars),
107
+ ...(block.icon ? imageProblems(`${where} icon`, block.icon) : []),
108
+ ...(block.rich_text_title
109
+ ? richTextBlockProblems(`${where} rich_text_title`, block.rich_text_title, SLACK_LIMITS.sectionTextChars)
110
+ : []),
111
+ ...overCount(`${where} child_blocks`, children.length, SLACK_LIMITS.containerChildBlocks),
112
+ ...empty(`${where} child_blocks`, children.length),
113
+ ...children.flatMap(({ type }, childIndex) => type === 'container'
114
+ ? [
115
+ `${where} child_blocks[${childIndex}] is a container; Slack does not accept one inside another.`,
116
+ ]
117
+ : []),
118
+ ];
119
+ }
120
+ case 'header':
121
+ return overLength(`${where} text`, block.text?.text, SLACK_LIMITS.headerTextChars);
122
+ case 'section': {
123
+ const fields = list(block.fields);
124
+ return [
125
+ ...overLength(`${where} text`, block.text?.text, SLACK_LIMITS.sectionTextChars),
126
+ ...overCount(`${where} fields`, fields.length, SLACK_LIMITS.fieldsPerSection),
127
+ ...fields.flatMap((field, fieldIndex) => overLength(`${where} fields[${fieldIndex}]`, field?.text, SLACK_LIMITS.sectionFieldChars)),
128
+ ...(block.accessory
129
+ ? accessoryProblems(`${where} accessory`, block.accessory)
130
+ : []),
131
+ ];
132
+ }
133
+ case 'context': {
134
+ const elements = list(block.elements);
135
+ return [
136
+ ...overCount(`${where} elements`, elements.length, SLACK_LIMITS.contextElements),
137
+ ...elements.flatMap((element, elementIndex) => element.type === 'image'
138
+ ? imageProblems(`${where} elements[${elementIndex}]`, element)
139
+ : overLength(`${where} elements[${elementIndex}]`, element.text, SLACK_LIMITS.contextElementChars)),
140
+ ];
141
+ }
142
+ case 'actions': {
143
+ const elements = list(block.elements);
144
+ return [
145
+ ...overCount(`${where} elements`, elements.length, SLACK_LIMITS.buttonsPerActions),
146
+ ...elements.flatMap((element, elementIndex) => controlProblems(`${where} elements[${elementIndex}]`, element)),
147
+ ];
148
+ }
149
+ case 'image':
150
+ return [
151
+ ...imageProblems(where, block),
152
+ ...overLength(`${where} title`, block.title?.text, SLACK_LIMITS.imageTitleChars),
153
+ ];
154
+ case 'video':
155
+ return [
156
+ ...overLength(`${where} title`, block.title?.text, SLACK_LIMITS.videoTitleChars),
157
+ ...overLength(`${where} description`, block.description?.text, SLACK_LIMITS.videoDescriptionChars),
158
+ ...overLength(`${where} author_name`, block.author_name, SLACK_LIMITS.videoAuthorNameChars),
159
+ ];
160
+ case 'rich_text':
161
+ return richTextBlockProblems(where, block, SLACK_LIMITS.sectionTextChars);
162
+ case 'table': {
163
+ const rows = list(block.rows);
164
+ return [
165
+ ...overCount(`${where} rows`, rows.length, SLACK_LIMITS.tableRows),
166
+ ...empty(`${where} rows`, rows.length),
167
+ ...rows.flatMap((row, rowIndex) => [
168
+ ...overCount(`${where} rows[${rowIndex}] cells`, list(row).length, SLACK_LIMITS.tableColumns),
169
+ ...empty(`${where} rows[${rowIndex}] cells`, list(row).length),
170
+ ...list(row).flatMap((cell, cellIndex) => cell.type === 'rich_text'
171
+ ? richTextBlockProblems(`${where} rows[${rowIndex}][${cellIndex}]`, cell)
172
+ : []),
173
+ ]),
174
+ ];
175
+ }
176
+ default:
177
+ return [];
178
+ }
179
+ };
180
+ const overTableText = (length) => length > SLACK_LIMITS.tableCellCharsPerMessage
181
+ ? [
182
+ `The message's table cells have ${length} characters; Slack allows ${SLACK_LIMITS.tableCellCharsPerMessage}.`,
183
+ ]
184
+ : [];
185
+ const tableTextLength = (blocks) => blocks.reduce((total, block) => block.type === 'table'
186
+ ? list(block.rows).reduce((sum, row) => list(row).reduce((cells, cell) => cells + cellText(cell).length, sum), total)
187
+ : total, 0);
188
+ const staleWrapperProblems = ({ where, block }) => {
189
+ const { type } = block;
190
+ return isUnmodeledSlackBlock(block) && isModeledSlackBlockType(type)
191
+ ? [
192
+ `${where} is wrapped in \`unmodeledSlackBlock\`, but Isomer models \`${type}\` blocks: return it unwrapped so its limits are fitted.`,
193
+ ]
194
+ : [];
195
+ };
196
+ /** One note per block type Isomer does not model: the envelope passed those blocks through unfitted, and {@link slackLimitProblems} cannot check them. */
197
+ export const unmodeledSlackNotes = (blocks) => [
198
+ ...new Set(located(blocks)
199
+ .map(({ block: { type } }) => type)
200
+ .filter((type) => !isModeledSlackBlockType(type))),
201
+ ].map((type) => `Isomer doesn't model \`${type}\` blocks, so their Slack limits aren't checked and this preview may not draw them. Check the message in Block Kit Builder.`);
202
+ /** Where a rendered Slack message breaks `SLACK_LIMITS`; empty when Slack would accept it. */
203
+ export const slackLimitProblems = ({ text, blocks, }) => {
204
+ const all = located(blocks);
205
+ return [
206
+ ...overCount('The message blocks', blocks.length, SLACK_LIMITS.blocksPerMessage),
207
+ ...overLength('The fallback text', text, SLACK_LIMITS.fallbackTextChars),
208
+ ...overTableText(tableTextLength(all.map(({ block }) => block))),
209
+ ...all.flatMap(blockProblems),
210
+ ...all.flatMap(staleWrapperProblems),
211
+ ];
212
+ };
213
+ //# sourceMappingURL=slack_limits.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slack_limits.js","sourceRoot":"","sources":["../../src/model/slack_limits.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\nimport type {\n SlackActionElement,\n SlackBlock,\n SlackOptionObject,\n SlackRichTextBlock,\n SlackRichTextBlockElement,\n SlackRichTextInline,\n SlackSectionAccessory,\n SlackTableCell,\n} from '@elastic/isomer-sdk/slack';\nimport {\n isModeledSlackBlockType,\n isUnmodeledSlackBlock,\n SLACK_LIMITS,\n} from '@elastic/isomer-sdk/slack';\n\nconst list = <T>(value: readonly T[] | undefined): readonly T[] => value ?? [];\n\nconst overLength = (\n where: string,\n text: string | undefined,\n limit: number\n): string[] =>\n typeof text === 'string' && text.length > limit\n ? [`${where} has ${text.length} characters; Slack allows ${limit}.`]\n : [];\n\nconst overCount = (where: string, count: number, limit: number): string[] =>\n count > limit ? [`${where} has ${count}; Slack allows ${limit}.`] : [];\n\nconst empty = (where: string, count: number): string[] =>\n count === 0 ? [`${where} is empty; Slack requires at least 1.`] : [];\n\nconst inlineText = (inline: SlackRichTextInline): string =>\n inline.type === 'link' ? (inline.text ?? inline.url) : inline.text;\n\nconst richTextText = (element: SlackRichTextBlockElement): string =>\n element.type === 'rich_text_list'\n ? list(element.elements).map(richTextText).join('')\n : list(element.elements).map(inlineText).join('');\n\nconst cellText = (cell: SlackTableCell): string =>\n cell.type === 'raw_text'\n ? cell.text\n : list(cell.elements).map(richTextText).join('');\n\nconst imageProblems = (\n where: string,\n { image_url, alt_text }: { image_url?: string; alt_text?: string }\n): string[] => [\n ...overLength(`${where} image_url`, image_url, SLACK_LIMITS.imageUrlChars),\n ...overLength(`${where} alt_text`, alt_text, SLACK_LIMITS.imageAltTextChars),\n];\n\nconst optionProblems = (\n where: string,\n { text, value, description, url }: SlackOptionObject\n): string[] => [\n ...overLength(`${where} text`, text?.text, SLACK_LIMITS.optionTextChars),\n ...overLength(`${where} value`, value, SLACK_LIMITS.optionValueChars),\n ...overLength(\n `${where} description`,\n description?.text,\n SLACK_LIMITS.optionTextChars\n ),\n ...overLength(`${where} url`, url, SLACK_LIMITS.urlChars),\n];\n\nconst optionsProblems = (\n where: string,\n options: readonly SlackOptionObject[] | undefined,\n limit: number\n): string[] => [\n ...overCount(`${where} options`, list(options).length, limit),\n ...list(options).flatMap((option, index) =>\n optionProblems(`${where} options[${index}]`, option)\n ),\n];\n\nconst controlProblems = (\n where: string,\n element: SlackActionElement\n): string[] => {\n const actionId = overLength(\n `${where} action_id`,\n element.action_id,\n SLACK_LIMITS.actionIdChars\n );\n switch (element.type) {\n case 'button':\n return [\n ...actionId,\n ...overLength(\n `${where} text`,\n element.text?.text,\n SLACK_LIMITS.buttonTextChars\n ),\n ...overLength(\n `${where} value`,\n element.value,\n SLACK_LIMITS.buttonValueChars\n ),\n ...overLength(`${where} url`, element.url, SLACK_LIMITS.urlChars),\n ];\n case 'overflow':\n return [\n ...actionId,\n ...optionsProblems(\n where,\n element.options,\n SLACK_LIMITS.optionsPerOverflow\n ),\n ];\n case 'radio_buttons':\n case 'checkboxes':\n return [\n ...actionId,\n ...optionsProblems(\n where,\n element.options,\n SLACK_LIMITS.optionsPerChoice\n ),\n ];\n case 'static_select':\n case 'multi_static_select': {\n const groups =\n element.type === 'static_select' ? list(element.option_groups) : [];\n return [\n ...actionId,\n ...overLength(\n `${where} placeholder`,\n element.placeholder?.text,\n SLACK_LIMITS.placeholderChars\n ),\n ...optionsProblems(\n where,\n element.options,\n SLACK_LIMITS.optionsPerSelect\n ),\n ...overCount(\n `${where} option_groups`,\n groups.length,\n SLACK_LIMITS.optionGroupsPerSelect\n ),\n ...groups.flatMap(({ label, options }, index) => [\n ...overLength(\n `${where} option_groups[${index}] label`,\n label?.text,\n SLACK_LIMITS.optionGroupLabelChars\n ),\n ...optionsProblems(\n `${where} option_groups[${index}]`,\n options,\n SLACK_LIMITS.optionsPerSelect\n ),\n ]),\n ];\n }\n default:\n return actionId;\n }\n};\n\nconst accessoryProblems = (\n where: string,\n accessory: SlackSectionAccessory\n): string[] =>\n accessory.type === 'image'\n ? imageProblems(where, accessory)\n : controlProblems(where, accessory);\n\nconst richTextProblems = (\n where: string,\n element: SlackRichTextBlockElement,\n textLimit: number | undefined\n): string[] => {\n if (element.type === 'rich_text_list') {\n return overCount(\n `${where} indent`,\n element.indent ?? 0,\n SLACK_LIMITS.richTextListMaxIndent\n );\n }\n return textLimit === undefined\n ? []\n : overLength(`${where} text`, richTextText(element), textLimit);\n};\n\n/** Only a top-level element has a `textLimit`; list items and table cells count toward the message's budgets alone. */\nconst richTextBlockProblems = (\n where: string,\n { elements }: SlackRichTextBlock,\n textLimit?: number\n): string[] =>\n list(elements).flatMap((element, elementIndex) =>\n richTextProblems(`${where} elements[${elementIndex}]`, element, textLimit)\n );\n\ninterface LocatedBlock {\n where: string;\n block: SlackBlock;\n}\n\n/** Every block in the message, a container's children after it, each with the path a problem names. */\nconst located = (blocks: readonly SlackBlock[]): LocatedBlock[] =>\n blocks.flatMap((block, index) => {\n const where = `blocks[${index}] (${block.type})`;\n return [\n { where, block },\n ...(block.type === 'container'\n ? list(block.child_blocks).map((child, childIndex) => ({\n where: `${where} child_blocks[${childIndex}] (${child.type})`,\n block: child,\n }))\n : []),\n ];\n });\n\nconst blockProblems = ({ where, block }: LocatedBlock): string[] => {\n switch (block.type) {\n case 'container': {\n const children = list(block.child_blocks);\n return [\n ...overLength(\n `${where} title`,\n block.title?.text,\n SLACK_LIMITS.containerTitleChars\n ),\n ...overLength(\n `${where} subtitle`,\n block.subtitle?.text,\n SLACK_LIMITS.containerSubtitleChars\n ),\n ...(block.icon ? imageProblems(`${where} icon`, block.icon) : []),\n ...(block.rich_text_title\n ? richTextBlockProblems(\n `${where} rich_text_title`,\n block.rich_text_title,\n SLACK_LIMITS.sectionTextChars\n )\n : []),\n ...overCount(\n `${where} child_blocks`,\n children.length,\n SLACK_LIMITS.containerChildBlocks\n ),\n ...empty(`${where} child_blocks`, children.length),\n ...children.flatMap(({ type }, childIndex) =>\n (type as string) === 'container'\n ? [\n `${where} child_blocks[${childIndex}] is a container; Slack does not accept one inside another.`,\n ]\n : []\n ),\n ];\n }\n case 'header':\n return overLength(\n `${where} text`,\n block.text?.text,\n SLACK_LIMITS.headerTextChars\n );\n case 'section': {\n const fields = list(block.fields);\n return [\n ...overLength(\n `${where} text`,\n block.text?.text,\n SLACK_LIMITS.sectionTextChars\n ),\n ...overCount(\n `${where} fields`,\n fields.length,\n SLACK_LIMITS.fieldsPerSection\n ),\n ...fields.flatMap((field, fieldIndex) =>\n overLength(\n `${where} fields[${fieldIndex}]`,\n field?.text,\n SLACK_LIMITS.sectionFieldChars\n )\n ),\n ...(block.accessory\n ? accessoryProblems(`${where} accessory`, block.accessory)\n : []),\n ];\n }\n case 'context': {\n const elements = list(block.elements);\n return [\n ...overCount(\n `${where} elements`,\n elements.length,\n SLACK_LIMITS.contextElements\n ),\n ...elements.flatMap((element, elementIndex) =>\n element.type === 'image'\n ? imageProblems(`${where} elements[${elementIndex}]`, element)\n : overLength(\n `${where} elements[${elementIndex}]`,\n element.text,\n SLACK_LIMITS.contextElementChars\n )\n ),\n ];\n }\n case 'actions': {\n const elements = list(block.elements);\n return [\n ...overCount(\n `${where} elements`,\n elements.length,\n SLACK_LIMITS.buttonsPerActions\n ),\n ...elements.flatMap((element, elementIndex) =>\n controlProblems(`${where} elements[${elementIndex}]`, element)\n ),\n ];\n }\n case 'image':\n return [\n ...imageProblems(where, block),\n ...overLength(\n `${where} title`,\n block.title?.text,\n SLACK_LIMITS.imageTitleChars\n ),\n ];\n case 'video':\n return [\n ...overLength(\n `${where} title`,\n block.title?.text,\n SLACK_LIMITS.videoTitleChars\n ),\n ...overLength(\n `${where} description`,\n block.description?.text,\n SLACK_LIMITS.videoDescriptionChars\n ),\n ...overLength(\n `${where} author_name`,\n block.author_name,\n SLACK_LIMITS.videoAuthorNameChars\n ),\n ];\n case 'rich_text':\n return richTextBlockProblems(where, block, SLACK_LIMITS.sectionTextChars);\n case 'table': {\n const rows = list(block.rows);\n return [\n ...overCount(`${where} rows`, rows.length, SLACK_LIMITS.tableRows),\n ...empty(`${where} rows`, rows.length),\n ...rows.flatMap((row, rowIndex) => [\n ...overCount(\n `${where} rows[${rowIndex}] cells`,\n list(row).length,\n SLACK_LIMITS.tableColumns\n ),\n ...empty(`${where} rows[${rowIndex}] cells`, list(row).length),\n ...list(row).flatMap((cell, cellIndex) =>\n cell.type === 'rich_text'\n ? richTextBlockProblems(\n `${where} rows[${rowIndex}][${cellIndex}]`,\n cell\n )\n : []\n ),\n ]),\n ];\n }\n default:\n return [];\n }\n};\n\nconst overTableText = (length: number): string[] =>\n length > SLACK_LIMITS.tableCellCharsPerMessage\n ? [\n `The message's table cells have ${length} characters; Slack allows ${SLACK_LIMITS.tableCellCharsPerMessage}.`,\n ]\n : [];\n\nconst tableTextLength = (blocks: readonly SlackBlock[]): number =>\n blocks.reduce(\n (total, block) =>\n block.type === 'table'\n ? list(block.rows).reduce(\n (sum, row) =>\n list(row).reduce(\n (cells, cell) => cells + cellText(cell).length,\n sum\n ),\n total\n )\n : total,\n 0\n );\n\nconst staleWrapperProblems = ({ where, block }: LocatedBlock): string[] => {\n const { type } = block;\n return isUnmodeledSlackBlock(block) && isModeledSlackBlockType(type)\n ? [\n `${where} is wrapped in \\`unmodeledSlackBlock\\`, but Isomer models \\`${type}\\` blocks: return it unwrapped so its limits are fitted.`,\n ]\n : [];\n};\n\n/** One note per block type Isomer does not model: the envelope passed those blocks through unfitted, and {@link slackLimitProblems} cannot check them. */\nexport const unmodeledSlackNotes = (blocks: readonly SlackBlock[]): string[] =>\n [\n ...new Set(\n located(blocks)\n .map(({ block: { type } }): string => type)\n .filter((type) => !isModeledSlackBlockType(type))\n ),\n ].map(\n (type) =>\n `Isomer doesn't model \\`${type}\\` blocks, so their Slack limits aren't checked and this preview may not draw them. Check the message in Block Kit Builder.`\n );\n\n/** Where a rendered Slack message breaks `SLACK_LIMITS`; empty when Slack would accept it. */\nexport const slackLimitProblems = ({\n text,\n blocks,\n}: {\n text: string;\n blocks: readonly SlackBlock[];\n}): string[] => {\n const all = located(blocks);\n return [\n ...overCount(\n 'The message blocks',\n blocks.length,\n SLACK_LIMITS.blocksPerMessage\n ),\n ...overLength('The fallback text', text, SLACK_LIMITS.fallbackTextChars),\n ...overTableText(tableTextLength(all.map(({ block }) => block))),\n ...all.flatMap(blockProblems),\n ...all.flatMap(staleWrapperProblems),\n ];\n};\n"]}
@@ -0,0 +1,45 @@
1
+ import type { BuildOptions, Metafile, Plugin } from 'esbuild';
2
+ export type AppMode = 'build' | 'dev';
3
+ /** The package root, whether this module runs from `dist/node` or `src/node`. */
4
+ export declare const PACKAGE_DIR: string;
5
+ /** Whether the CLI runs from its TypeScript source, as `pnpm studio:dev` does, rather than from `dist`. */
6
+ export declare const RUNS_FROM_SOURCE: boolean;
7
+ /** The package's prebuilt, pack-independent assets: `dist/app/`. */
8
+ export declare const APP_DIR: string;
9
+ /** Without an extension, so the bundle takes `dist/browser/*.js`, or the `.ts(x)` beside it when the CLI runs from source. */
10
+ export declare const browserModule: (name: string) => string;
11
+ /** The bundle's entry: the config's default export mounted with the mode's host functions. In `dev`, a changed config re-renders the mounted Studio in place. */
12
+ export declare const appEntry: (configPath: string, mode: AppMode) => string;
13
+ /** The package directories of the config's `react` and `react-dom`, which every React import in the bundle resolves into. */
14
+ export declare const reactDirectories: (configPath: string) => string[];
15
+ /**
16
+ * Resolves `react`, `react-dom` and their subpaths as if imported from the config, so the app, the pack and
17
+ * Emotion share the config's React. Re-resolving the specifier, rather than aliasing a directory, keeps
18
+ * each package's `browser` and `exports` mappings, which pick `react-dom/server`'s browser build.
19
+ */
20
+ export declare const reactFromConfig: (configPath: string) => Plugin;
21
+ /** Resolves `SHARED_PACKAGES` from the project when imported from outside it, and `STUDIO_PACKAGES` from the Studio when the project lacks them. */
22
+ export declare const projectResolution: (configPath: string) => Plugin;
23
+ /** esbuild options for a static build's `assets/app.js` and its chunks, written to `assetsDir`. */
24
+ export declare const appBuildOptions: ({ configPath, assetsDir, plugins, }: {
25
+ configPath: string;
26
+ assetsDir: string;
27
+ plugins?: Plugin[] | undefined;
28
+ }) => BuildOptions;
29
+ /**
30
+ * The entry's CSS bundle, relative to the working directory: every CSS file the config reaches, lazy chunks
31
+ * included, with `url()`s relative to `assets/`. The per-chunk CSS esbuild also writes is never linked.
32
+ */
33
+ export declare const appStylesheets: (metafile: Metafile, entryPoint?: string) => {
34
+ bundle: string | undefined;
35
+ chunks: string[];
36
+ };
37
+ /** `dist/app/index.html` with the deployment's `<base href>`, the config's title, and the entry script. */
38
+ export declare const renderIndexHtml: ({ base, title, entry, stylesheets, }: {
39
+ base: string;
40
+ title?: string | undefined;
41
+ entry?: string | undefined;
42
+ /** Linked after the Studio's own stylesheets, relative to `base`. */
43
+ stylesheets?: readonly string[] | undefined;
44
+ }) => string;
45
+ //# sourceMappingURL=app_bundle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app_bundle.d.ts","sourceRoot":"","sources":["../../src/node/app_bundle.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAQ9D,MAAM,MAAM,OAAO,GAAG,OAAO,GAAG,KAAK,CAAC;AAItC,iFAAiF;AACjF,eAAO,MAAM,WAAW,QAAyB,CAAC;AAElD,2GAA2G;AAC3G,eAAO,MAAM,gBAAgB,SAAkC,CAAC;AAEhE,oEAAoE;AACpE,eAAO,MAAM,OAAO,QAAgC,CAAC;AAErD,8HAA8H;AAC9H,eAAO,MAAM,aAAa,GAAI,MAAM,MAAM,KAAG,MACV,CAAC;AAOpC,iKAAiK;AACjK,eAAO,MAAM,QAAQ,GAAI,YAAY,MAAM,EAAE,MAAM,OAAO,KAAG,MAmB5D,CAAC;AAEF,6HAA6H;AAC7H,eAAO,MAAM,gBAAgB,GAAI,YAAY,MAAM,KAAG,MAAM,EAK3D,CAAC;AAIF;;;;GAIG;AACH,eAAO,MAAM,eAAe,GAAI,YAAY,MAAM,KAAG,MAoBnD,CAAC;AAIH,oJAAoJ;AACpJ,eAAO,MAAM,iBAAiB,GAAI,YAAY,MAAM,KAAG,MAkCtD,CAAC;AAiDF,mGAAmG;AACnG,eAAO,MAAM,eAAe,GAAI,qCAI7B;IACD,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;CAChC,KAAG,YA4BF,CAAC;AAKH;;;GAGG;AACH,eAAO,MAAM,cAAc,GACzB,UAAU,QAAQ,EAClB,aAAY,MAAwB,KACnC;IAAE,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAUhD,CAAC;AAcF,2GAA2G;AAC3G,eAAO,MAAM,eAAe,GAAI,sCAK7B;IACD,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,qEAAqE;IACrE,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,CAAC;CAC7C,KAAG,MAqBH,CAAC"}
@@ -0,0 +1,212 @@
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 { readFileSync } from 'node:fs';
8
+ import { createRequire } from 'node:module';
9
+ import { dirname, join, resolve } from 'node:path';
10
+ import { fileURLToPath } from 'node:url';
11
+ import { isStudioSpecifier, projectDirectory, sharedResolveDir, } from './project_resolution.js';
12
+ const here = dirname(fileURLToPath(import.meta.url));
13
+ /** The package root, whether this module runs from `dist/node` or `src/node`. */
14
+ export const PACKAGE_DIR = resolve(here, '../..');
15
+ /** Whether the CLI runs from its TypeScript source, as `pnpm studio:dev` does, rather than from `dist`. */
16
+ export const RUNS_FROM_SOURCE = import.meta.url.endsWith('.ts');
17
+ /** The package's prebuilt, pack-independent assets: `dist/app/`. */
18
+ export const APP_DIR = join(PACKAGE_DIR, 'dist/app');
19
+ /** Without an extension, so the bundle takes `dist/browser/*.js`, or the `.ts(x)` beside it when the CLI runs from source. */
20
+ export const browserModule = (name) => resolve(here, '../browser', name);
21
+ const HOSTS = {
22
+ dev: { module: 'dev_host', name: 'devHost' },
23
+ build: { module: 'static_host', name: 'staticHost' },
24
+ };
25
+ /** The bundle's entry: the config's default export mounted with the mode's host functions. In `dev`, a changed config re-renders the mounted Studio in place. */
26
+ export const appEntry = (configPath, mode) => {
27
+ const { module, name } = HOSTS[mode];
28
+ const config = JSON.stringify(configPath);
29
+ return [
30
+ `import config from ${config};`,
31
+ `import { mountStudio } from ${JSON.stringify(browserModule('mount'))};`,
32
+ `import { ${name} } from ${JSON.stringify(browserModule(module))};`,
33
+ `const studio = mountStudio(config, ${name}(config));`,
34
+ ...(mode === 'dev'
35
+ ? [
36
+ 'if (import.meta.hot) {',
37
+ ` import.meta.hot.accept(${config}, (next) => {`,
38
+ ` if (next) studio.update(next.default, ${name}(next.default));`,
39
+ ' });',
40
+ '}',
41
+ ]
42
+ : []),
43
+ '',
44
+ ].join('\n');
45
+ };
46
+ /** The package directories of the config's `react` and `react-dom`, which every React import in the bundle resolves into. */
47
+ export const reactDirectories = (configPath) => {
48
+ const require = createRequire(configPath);
49
+ return ['react', 'react-dom'].map((name) => dirname(require.resolve(`${name}/package.json`)));
50
+ };
51
+ const REACT_SPECIFIER = /^react(-dom)?(\/.*)?$/;
52
+ /**
53
+ * Resolves `react`, `react-dom` and their subpaths as if imported from the config, so the app, the pack and
54
+ * Emotion share the config's React. Re-resolving the specifier, rather than aliasing a directory, keeps
55
+ * each package's `browser` and `exports` mappings, which pick `react-dom/server`'s browser build.
56
+ */
57
+ export const reactFromConfig = (configPath) => ({
58
+ name: 'isomer-studio-react',
59
+ setup: (build) => {
60
+ build.onResolve({ filter: REACT_SPECIFIER }, async ({ path, kind, pluginData }) => {
61
+ if (pluginData === REACT_SPECIFIER) {
62
+ return undefined;
63
+ }
64
+ const result = await build.resolve(path, {
65
+ kind,
66
+ resolveDir: dirname(configPath),
67
+ pluginData: REACT_SPECIFIER,
68
+ });
69
+ return result.errors.length
70
+ ? { errors: result.errors }
71
+ : { path: result.path };
72
+ });
73
+ },
74
+ });
75
+ const SKIP = Symbol.for('elastic.isomer.studio.project_resolution');
76
+ /** Resolves `SHARED_PACKAGES` from the project when imported from outside it, and `STUDIO_PACKAGES` from the Studio when the project lacks them. */
77
+ export const projectResolution = (configPath) => {
78
+ const projectDir = projectDirectory(configPath);
79
+ return {
80
+ name: 'isomer-studio-project-resolution',
81
+ setup: (build) => {
82
+ build.onResolve({ filter: /^[^./]/ }, async ({ path, importer, kind, resolveDir, pluginData }) => {
83
+ if (pluginData === SKIP || REACT_SPECIFIER.test(path)) {
84
+ return undefined;
85
+ }
86
+ const resolveFrom = async (dir) => build.resolve(path, { kind, resolveDir: dir, pluginData: SKIP });
87
+ const shared = sharedResolveDir(path, importer, projectDir);
88
+ if (shared !== undefined) {
89
+ const result = await resolveFrom(shared);
90
+ if (!result.errors.length) {
91
+ return { path: result.path };
92
+ }
93
+ }
94
+ if (!isStudioSpecifier(path)) {
95
+ return undefined;
96
+ }
97
+ const own = await resolveFrom(resolveDir);
98
+ const result = own.errors.length
99
+ ? await resolveFrom(PACKAGE_DIR)
100
+ : own;
101
+ return result.errors.length
102
+ ? { errors: own.errors }
103
+ : { path: result.path };
104
+ });
105
+ },
106
+ };
107
+ };
108
+ const ENTRY = 'isomer-studio:app';
109
+ const entryPlugin = (configPath) => ({
110
+ name: 'isomer-studio-entry',
111
+ setup: (build) => {
112
+ build.onResolve({ filter: /^isomer-studio:app$/ }, ({ path }) => ({
113
+ path,
114
+ namespace: 'isomer-studio',
115
+ }));
116
+ build.onLoad({ filter: /.*/, namespace: 'isomer-studio' }, () => ({
117
+ contents: appEntry(configPath, 'build'),
118
+ resolveDir: dirname(configPath),
119
+ loader: 'js',
120
+ }));
121
+ },
122
+ });
123
+ /** Fonts and images a stylesheet or module may reference, emitted to `assets/media/`. */
124
+ const ASSET_LOADERS = Object.fromEntries([
125
+ '.avif',
126
+ '.eot',
127
+ '.gif',
128
+ '.ico',
129
+ '.jpeg',
130
+ '.jpg',
131
+ '.otf',
132
+ '.png',
133
+ '.svg',
134
+ '.ttf',
135
+ '.webp',
136
+ '.woff',
137
+ '.woff2',
138
+ ].map((extension) => [extension, 'file']));
139
+ /** `assets/studio.css` already carries Monaco's stylesheet, which Monaco's modules also import piecemeal. */
140
+ const monacoCssEmpty = {
141
+ name: 'isomer-studio-monaco-css',
142
+ setup: (build) => {
143
+ build.onLoad({ filter: /[\\/]monaco-editor[\\/].*\.css$/ }, () => ({
144
+ contents: '',
145
+ loader: 'empty',
146
+ }));
147
+ },
148
+ };
149
+ /** esbuild options for a static build's `assets/app.js` and its chunks, written to `assetsDir`. */
150
+ export const appBuildOptions = ({ configPath, assetsDir, plugins = [], }) => ({
151
+ entryPoints: { app: ENTRY },
152
+ outdir: assetsDir,
153
+ chunkNames: 'chunks/[name]-[hash]',
154
+ assetNames: 'media/[name]-[hash]',
155
+ bundle: true,
156
+ splitting: true,
157
+ format: 'esm',
158
+ platform: 'browser',
159
+ target: 'es2022',
160
+ loader: {
161
+ '.css': 'css',
162
+ '.module.css': 'local-css',
163
+ ...ASSET_LOADERS,
164
+ },
165
+ define: {
166
+ 'process.env.NODE_ENV': JSON.stringify('production'),
167
+ global: 'globalThis',
168
+ },
169
+ minify: true,
170
+ logLevel: 'warning',
171
+ plugins: [
172
+ entryPlugin(configPath),
173
+ reactFromConfig(configPath),
174
+ projectResolution(configPath),
175
+ monacoCssEmpty,
176
+ ...plugins,
177
+ ],
178
+ });
179
+ /** The bundle entry's id in an esbuild metafile. */
180
+ const APP_ENTRY_POINT = `isomer-studio:${ENTRY}`;
181
+ /**
182
+ * The entry's CSS bundle, relative to the working directory: every CSS file the config reaches, lazy chunks
183
+ * included, with `url()`s relative to `assets/`. The per-chunk CSS esbuild also writes is never linked.
184
+ */
185
+ export const appStylesheets = (metafile, entryPoint = APP_ENTRY_POINT) => {
186
+ const bundle = Object.values(metafile.outputs).find((output) => output.entryPoint === entryPoint)?.cssBundle;
187
+ return {
188
+ bundle,
189
+ chunks: Object.keys(metafile.outputs).filter((output) => output.endsWith('.css') && output !== bundle),
190
+ };
191
+ };
192
+ const SLACK_STYLESHEET = '<link rel="stylesheet" href="assets/slack.css" />';
193
+ const HTML_ESCAPES = {
194
+ '&': '&amp;',
195
+ '<': '&lt;',
196
+ '>': '&gt;',
197
+ '"': '&quot;',
198
+ };
199
+ const escapeHtml = (value) => value.replace(/[&<>"]/g, (char) => HTML_ESCAPES[char] ?? char);
200
+ /** `dist/app/index.html` with the deployment's `<base href>`, the config's title, and the entry script. */
201
+ export const renderIndexHtml = ({ base, title = 'Isomer Studio', entry = 'assets/app.js', stylesheets = [], }) => {
202
+ const template = readFileSync(join(APP_DIR, 'index.html'), 'utf8');
203
+ return template
204
+ .replace('<base href="./" />', `<base href="${escapeHtml(base)}" />`)
205
+ .replace('<title>Isomer Studio</title>', `<title>${escapeHtml(title)}</title>`)
206
+ .replace(SLACK_STYLESHEET, [
207
+ SLACK_STYLESHEET,
208
+ ...stylesheets.map((href) => `<link rel="stylesheet" href="${escapeHtml(href)}" />`),
209
+ ].join('\n '))
210
+ .replace('<script type="module" src="assets/app.js"></script>', `<script type="module" src="${escapeHtml(entry)}"></script>`);
211
+ };
212
+ //# sourceMappingURL=app_bundle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app_bundle.js","sourceRoot":"","sources":["../../src/node/app_bundle.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\nimport { readFileSync } from 'node:fs';\nimport { createRequire } from 'node:module';\nimport { dirname, join, resolve } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nimport type { BuildOptions, Metafile, Plugin } from 'esbuild';\n\nimport {\n isStudioSpecifier,\n projectDirectory,\n sharedResolveDir,\n} from './project_resolution';\n\nexport type AppMode = 'build' | 'dev';\n\nconst here = dirname(fileURLToPath(import.meta.url));\n\n/** The package root, whether this module runs from `dist/node` or `src/node`. */\nexport const PACKAGE_DIR = resolve(here, '../..');\n\n/** Whether the CLI runs from its TypeScript source, as `pnpm studio:dev` does, rather than from `dist`. */\nexport const RUNS_FROM_SOURCE = import.meta.url.endsWith('.ts');\n\n/** The package's prebuilt, pack-independent assets: `dist/app/`. */\nexport const APP_DIR = join(PACKAGE_DIR, 'dist/app');\n\n/** Without an extension, so the bundle takes `dist/browser/*.js`, or the `.ts(x)` beside it when the CLI runs from source. */\nexport const browserModule = (name: string): string =>\n resolve(here, '../browser', name);\n\nconst HOSTS: Readonly<Record<AppMode, { module: string; name: string }>> = {\n dev: { module: 'dev_host', name: 'devHost' },\n build: { module: 'static_host', name: 'staticHost' },\n};\n\n/** The bundle's entry: the config's default export mounted with the mode's host functions. In `dev`, a changed config re-renders the mounted Studio in place. */\nexport const appEntry = (configPath: string, mode: AppMode): string => {\n const { module, name } = HOSTS[mode];\n const config = JSON.stringify(configPath);\n return [\n `import config from ${config};`,\n `import { mountStudio } from ${JSON.stringify(browserModule('mount'))};`,\n `import { ${name} } from ${JSON.stringify(browserModule(module))};`,\n `const studio = mountStudio(config, ${name}(config));`,\n ...(mode === 'dev'\n ? [\n 'if (import.meta.hot) {',\n ` import.meta.hot.accept(${config}, (next) => {`,\n ` if (next) studio.update(next.default, ${name}(next.default));`,\n ' });',\n '}',\n ]\n : []),\n '',\n ].join('\\n');\n};\n\n/** The package directories of the config's `react` and `react-dom`, which every React import in the bundle resolves into. */\nexport const reactDirectories = (configPath: string): string[] => {\n const require = createRequire(configPath);\n return ['react', 'react-dom'].map((name) =>\n dirname(require.resolve(`${name}/package.json`))\n );\n};\n\nconst REACT_SPECIFIER = /^react(-dom)?(\\/.*)?$/;\n\n/**\n * Resolves `react`, `react-dom` and their subpaths as if imported from the config, so the app, the pack and\n * Emotion share the config's React. Re-resolving the specifier, rather than aliasing a directory, keeps\n * each package's `browser` and `exports` mappings, which pick `react-dom/server`'s browser build.\n */\nexport const reactFromConfig = (configPath: string): Plugin => ({\n name: 'isomer-studio-react',\n setup: (build) => {\n build.onResolve(\n { filter: REACT_SPECIFIER },\n async ({ path, kind, pluginData }) => {\n if (pluginData === REACT_SPECIFIER) {\n return undefined;\n }\n const result = await build.resolve(path, {\n kind,\n resolveDir: dirname(configPath),\n pluginData: REACT_SPECIFIER,\n });\n return result.errors.length\n ? { errors: result.errors }\n : { path: result.path };\n }\n );\n },\n});\n\nconst SKIP = Symbol.for('elastic.isomer.studio.project_resolution');\n\n/** Resolves `SHARED_PACKAGES` from the project when imported from outside it, and `STUDIO_PACKAGES` from the Studio when the project lacks them. */\nexport const projectResolution = (configPath: string): Plugin => {\n const projectDir = projectDirectory(configPath);\n return {\n name: 'isomer-studio-project-resolution',\n setup: (build) => {\n build.onResolve(\n { filter: /^[^./]/ },\n async ({ path, importer, kind, resolveDir, pluginData }) => {\n if (pluginData === SKIP || REACT_SPECIFIER.test(path)) {\n return undefined;\n }\n const resolveFrom = async (dir: string) =>\n build.resolve(path, { kind, resolveDir: dir, pluginData: SKIP });\n const shared = sharedResolveDir(path, importer, projectDir);\n if (shared !== undefined) {\n const result = await resolveFrom(shared);\n if (!result.errors.length) {\n return { path: result.path };\n }\n }\n if (!isStudioSpecifier(path)) {\n return undefined;\n }\n const own = await resolveFrom(resolveDir);\n const result = own.errors.length\n ? await resolveFrom(PACKAGE_DIR)\n : own;\n return result.errors.length\n ? { errors: own.errors }\n : { path: result.path };\n }\n );\n },\n };\n};\n\nconst ENTRY = 'isomer-studio:app';\n\nconst entryPlugin = (configPath: string): Plugin => ({\n name: 'isomer-studio-entry',\n setup: (build) => {\n build.onResolve({ filter: /^isomer-studio:app$/ }, ({ path }) => ({\n path,\n namespace: 'isomer-studio',\n }));\n build.onLoad({ filter: /.*/, namespace: 'isomer-studio' }, () => ({\n contents: appEntry(configPath, 'build'),\n resolveDir: dirname(configPath),\n loader: 'js',\n }));\n },\n});\n\n/** Fonts and images a stylesheet or module may reference, emitted to `assets/media/`. */\nconst ASSET_LOADERS = Object.fromEntries(\n [\n '.avif',\n '.eot',\n '.gif',\n '.ico',\n '.jpeg',\n '.jpg',\n '.otf',\n '.png',\n '.svg',\n '.ttf',\n '.webp',\n '.woff',\n '.woff2',\n ].map((extension) => [extension, 'file' as const])\n);\n\n/** `assets/studio.css` already carries Monaco's stylesheet, which Monaco's modules also import piecemeal. */\nconst monacoCssEmpty: Plugin = {\n name: 'isomer-studio-monaco-css',\n setup: (build) => {\n build.onLoad({ filter: /[\\\\/]monaco-editor[\\\\/].*\\.css$/ }, () => ({\n contents: '',\n loader: 'empty',\n }));\n },\n};\n\n/** esbuild options for a static build's `assets/app.js` and its chunks, written to `assetsDir`. */\nexport const appBuildOptions = ({\n configPath,\n assetsDir,\n plugins = [],\n}: {\n configPath: string;\n assetsDir: string;\n plugins?: Plugin[] | undefined;\n}): BuildOptions => ({\n entryPoints: { app: ENTRY },\n outdir: assetsDir,\n chunkNames: 'chunks/[name]-[hash]',\n assetNames: 'media/[name]-[hash]',\n bundle: true,\n splitting: true,\n format: 'esm',\n platform: 'browser',\n target: 'es2022',\n loader: {\n '.css': 'css',\n '.module.css': 'local-css',\n ...ASSET_LOADERS,\n },\n define: {\n 'process.env.NODE_ENV': JSON.stringify('production'),\n global: 'globalThis',\n },\n minify: true,\n logLevel: 'warning',\n plugins: [\n entryPlugin(configPath),\n reactFromConfig(configPath),\n projectResolution(configPath),\n monacoCssEmpty,\n ...plugins,\n ],\n});\n\n/** The bundle entry's id in an esbuild metafile. */\nconst APP_ENTRY_POINT = `isomer-studio:${ENTRY}`;\n\n/**\n * The entry's CSS bundle, relative to the working directory: every CSS file the config reaches, lazy chunks\n * included, with `url()`s relative to `assets/`. The per-chunk CSS esbuild also writes is never linked.\n */\nexport const appStylesheets = (\n metafile: Metafile,\n entryPoint: string = APP_ENTRY_POINT\n): { bundle: string | undefined; chunks: string[] } => {\n const bundle = Object.values(metafile.outputs).find(\n (output) => output.entryPoint === entryPoint\n )?.cssBundle;\n return {\n bundle,\n chunks: Object.keys(metafile.outputs).filter(\n (output) => output.endsWith('.css') && output !== bundle\n ),\n };\n};\n\nconst SLACK_STYLESHEET = '<link rel=\"stylesheet\" href=\"assets/slack.css\" />';\n\nconst HTML_ESCAPES: Readonly<Record<string, string>> = {\n '&': '&amp;',\n '<': '&lt;',\n '>': '&gt;',\n '\"': '&quot;',\n};\n\nconst escapeHtml = (value: string): string =>\n value.replace(/[&<>\"]/g, (char) => HTML_ESCAPES[char] ?? char);\n\n/** `dist/app/index.html` with the deployment's `<base href>`, the config's title, and the entry script. */\nexport const renderIndexHtml = ({\n base,\n title = 'Isomer Studio',\n entry = 'assets/app.js',\n stylesheets = [],\n}: {\n base: string;\n title?: string | undefined;\n entry?: string | undefined;\n /** Linked after the Studio's own stylesheets, relative to `base`. */\n stylesheets?: readonly string[] | undefined;\n}): string => {\n const template = readFileSync(join(APP_DIR, 'index.html'), 'utf8');\n return template\n .replace('<base href=\"./\" />', `<base href=\"${escapeHtml(base)}\" />`)\n .replace(\n '<title>Isomer Studio</title>',\n `<title>${escapeHtml(title)}</title>`\n )\n .replace(\n SLACK_STYLESHEET,\n [\n SLACK_STYLESHEET,\n ...stylesheets.map(\n (href) => `<link rel=\"stylesheet\" href=\"${escapeHtml(href)}\" />`\n ),\n ].join('\\n ')\n )\n .replace(\n '<script type=\"module\" src=\"assets/app.js\"></script>',\n `<script type=\"module\" src=\"${escapeHtml(entry)}\"></script>`\n );\n};\n"]}
@@ -0,0 +1,28 @@
1
+ import type { StudioConfig } from '../config.js';
2
+ import type { PngManifest } from '../model/png_manifest.js';
3
+ import type { ConfigLoader } from './load_config.js';
4
+ import type { NodeRasterizer } from './rasterize.js';
5
+ export interface PrerenderResult {
6
+ manifest: PngManifest;
7
+ /** Examples that could not be rasterized, as `primitive › example (theme): message`. */
8
+ failures: string[];
9
+ }
10
+ /** Rasterizes every example in both themes into `dir`, keyed by `compositionKey`, plus `manifest.json`. */
11
+ export declare const prerenderPngs: (config: StudioConfig, rasterize: NodeRasterizer, dir: string) => Promise<PrerenderResult>;
12
+ /** Written into every build, so a later build only clears a directory a Studio build made. */
13
+ export declare const BUILD_MARKER = ".isomer-studio-build";
14
+ /** Clears `out` for a new build, refusing a non-empty directory that is not a previous build. */
15
+ export declare const prepareOut: (out: string) => void;
16
+ export interface BuildSiteOptions {
17
+ configPath: string;
18
+ out: string;
19
+ base: string;
20
+ loader?: ConfigLoader | undefined;
21
+ }
22
+ export interface BuildSiteResult {
23
+ pngs: number;
24
+ failures: string[];
25
+ }
26
+ /** Writes the static Studio for `configPath` to `out`: the prebuilt assets, `app.js`, and the PNG manifest. */
27
+ export declare const buildSite: ({ configPath, out, base, loader, }: BuildSiteOptions) => Promise<BuildSiteResult>;
28
+ //# sourceMappingURL=build_site.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build_site.d.ts","sourceRoot":"","sources":["../../src/node/build_site.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAE,YAAY,EAAe,MAAM,WAAW,CAAC;AAG3D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AASzD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAElD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAKlD,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,WAAW,CAAC;IACtB,wFAAwF;IACxF,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,2GAA2G;AAC3G,eAAO,MAAM,aAAa,GACxB,QAAQ,YAAY,EACpB,WAAW,cAAc,EACzB,KAAK,MAAM,KACV,OAAO,CAAC,eAAe,CAsCzB,CAAC;AAEF,8FAA8F;AAC9F,eAAO,MAAM,YAAY,yBAAyB,CAAC;AAEnD,iGAAiG;AACjG,eAAO,MAAM,UAAU,GAAI,KAAK,MAAM,KAAG,IAaxC,CAAC;AAEF,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,YAAY,GAAG,SAAS,CAAC;CACnC;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,+GAA+G;AAC/G,eAAO,MAAM,SAAS,GAAU,oCAK7B,gBAAgB,KAAG,OAAO,CAAC,eAAe,CAoC5C,CAAC"}