@health-samurai/react-components 0.0.0-alpha.2 → 0.0.0-alpha.21

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 (571) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +102 -1
  3. package/dist/bundle.css +2349 -754
  4. package/dist/src/components/button-dropdown.d.ts +10 -0
  5. package/dist/src/components/button-dropdown.d.ts.map +1 -0
  6. package/dist/src/components/button-dropdown.js +70 -0
  7. package/dist/src/components/button-dropdown.js.map +1 -0
  8. package/dist/src/components/button-dropdown.stories.js +48 -0
  9. package/dist/src/components/button-dropdown.stories.js.map +1 -0
  10. package/dist/src/components/code-editor/fhir-autocomplete.d.ts +70 -0
  11. package/dist/src/components/code-editor/fhir-autocomplete.d.ts.map +1 -0
  12. package/dist/src/components/code-editor/fhir-autocomplete.js +1850 -0
  13. package/dist/src/components/code-editor/fhir-autocomplete.js.map +1 -0
  14. package/dist/src/components/code-editor/fhir-autocomplete.test.js +1099 -0
  15. package/dist/src/components/code-editor/fhir-autocomplete.test.js.map +1 -0
  16. package/dist/src/components/code-editor/http/grammar/http.d.ts +3 -0
  17. package/dist/src/components/code-editor/http/grammar/http.d.ts.map +1 -0
  18. package/dist/src/components/code-editor/http/grammar/http.grammar +74 -0
  19. package/dist/src/components/code-editor/http/grammar/http.js +38 -0
  20. package/dist/src/components/code-editor/http/grammar/http.js.map +1 -0
  21. package/dist/src/components/code-editor/http/grammar/http.terms.d.ts +2 -0
  22. package/dist/src/components/code-editor/http/grammar/http.terms.d.ts.map +1 -0
  23. package/dist/src/components/code-editor/http/grammar/http.terms.js +4 -0
  24. package/dist/src/components/code-editor/http/grammar/http.terms.js.map +1 -0
  25. package/dist/src/components/code-editor/http/grammar/http.test.js +80 -0
  26. package/dist/src/components/code-editor/http/grammar/http.test.js.map +1 -0
  27. package/dist/src/components/code-editor/http/index.d.ts +12 -0
  28. package/dist/src/components/code-editor/http/index.d.ts.map +1 -0
  29. package/dist/src/components/code-editor/http/index.js +486 -0
  30. package/dist/src/components/code-editor/http/index.js.map +1 -0
  31. package/dist/src/components/code-editor/index.d.ts +39 -1
  32. package/dist/src/components/code-editor/index.d.ts.map +1 -1
  33. package/dist/src/components/code-editor/index.js +1792 -45
  34. package/dist/src/components/code-editor/index.js.map +1 -1
  35. package/dist/src/components/code-editor/json-ast.d.ts +46 -0
  36. package/dist/src/components/code-editor/json-ast.d.ts.map +1 -0
  37. package/dist/src/components/code-editor/json-ast.js +465 -0
  38. package/dist/src/components/code-editor/json-ast.js.map +1 -0
  39. package/dist/src/components/code-editor/json-ast.test.js +206 -0
  40. package/dist/src/components/code-editor/json-ast.test.js.map +1 -0
  41. package/dist/src/components/code-editor/sql-completion.d.ts +22 -0
  42. package/dist/src/components/code-editor/sql-completion.d.ts.map +1 -0
  43. package/dist/src/components/code-editor/sql-completion.js +897 -0
  44. package/dist/src/components/code-editor/sql-completion.js.map +1 -0
  45. package/dist/src/components/code-editor.stories.js +280 -3
  46. package/dist/src/components/code-editor.stories.js.map +1 -1
  47. package/dist/src/components/copy-icon.d.ts +5 -1
  48. package/dist/src/components/copy-icon.d.ts.map +1 -1
  49. package/dist/src/components/copy-icon.js +41 -3
  50. package/dist/src/components/copy-icon.js.map +1 -1
  51. package/dist/src/components/data-table.d.ts +9 -0
  52. package/dist/src/components/data-table.d.ts.map +1 -0
  53. package/dist/src/components/data-table.js +66 -0
  54. package/dist/src/components/data-table.js.map +1 -0
  55. package/dist/src/components/data-table.stories.js +240 -0
  56. package/dist/src/components/data-table.stories.js.map +1 -0
  57. package/dist/src/components/date-picker-input.d.ts +10 -0
  58. package/dist/src/components/date-picker-input.d.ts.map +1 -0
  59. package/dist/src/components/date-picker-input.js +90 -0
  60. package/dist/src/components/date-picker-input.js.map +1 -0
  61. package/dist/src/components/date-picker-input.stories.js +76 -0
  62. package/dist/src/components/date-picker-input.stories.js.map +1 -0
  63. package/dist/src/components/fhir-structure-view.d.ts +34 -0
  64. package/dist/src/components/fhir-structure-view.d.ts.map +1 -0
  65. package/dist/src/components/fhir-structure-view.js +230 -0
  66. package/dist/src/components/fhir-structure-view.js.map +1 -0
  67. package/dist/src/components/fhir-structure-view.stories.js +447 -0
  68. package/dist/src/components/fhir-structure-view.stories.js.map +1 -0
  69. package/dist/src/components/icon-button.d.ts +12 -0
  70. package/dist/src/components/icon-button.d.ts.map +1 -0
  71. package/dist/src/components/icon-button.js +41 -0
  72. package/dist/src/components/icon-button.js.map +1 -0
  73. package/dist/src/components/icon-button.stories.js +157 -0
  74. package/dist/src/components/icon-button.stories.js.map +1 -0
  75. package/dist/src/components/operation-outcome-view.d.ts +27 -0
  76. package/dist/src/components/operation-outcome-view.d.ts.map +1 -0
  77. package/dist/src/components/operation-outcome-view.js +198 -0
  78. package/dist/src/components/operation-outcome-view.js.map +1 -0
  79. package/dist/src/components/operation-outcome-view.stories.js +207 -0
  80. package/dist/src/components/operation-outcome-view.stories.js.map +1 -0
  81. package/dist/src/components/request-line-editor.d.ts +13 -35
  82. package/dist/src/components/request-line-editor.d.ts.map +1 -1
  83. package/dist/src/components/request-line-editor.js +73 -49
  84. package/dist/src/components/request-line-editor.js.map +1 -1
  85. package/dist/src/components/request-line-editor.stories.js +17 -53
  86. package/dist/src/components/request-line-editor.stories.js.map +1 -1
  87. package/dist/src/components/sandbox.d.ts +13 -0
  88. package/dist/src/components/sandbox.d.ts.map +1 -0
  89. package/dist/src/components/sandbox.js +107 -0
  90. package/dist/src/components/sandbox.js.map +1 -0
  91. package/dist/src/components/sandbox.stories.js +126 -0
  92. package/dist/src/components/sandbox.stories.js.map +1 -0
  93. package/dist/src/components/segment-control.d.ts +13 -0
  94. package/dist/src/components/segment-control.d.ts.map +1 -0
  95. package/dist/src/components/segment-control.js +33 -0
  96. package/dist/src/components/segment-control.js.map +1 -0
  97. package/dist/src/components/segment-control.stories.js +68 -0
  98. package/dist/src/components/segment-control.stories.js.map +1 -0
  99. package/dist/src/components/split-button.d.ts +12 -0
  100. package/dist/src/components/split-button.d.ts.map +1 -0
  101. package/dist/src/components/split-button.js +33 -0
  102. package/dist/src/components/split-button.js.map +1 -0
  103. package/dist/src/components/split-button.stories.js +84 -0
  104. package/dist/src/components/split-button.stories.js.map +1 -0
  105. package/dist/src/components/tag.d.ts +16 -0
  106. package/dist/src/components/tag.d.ts.map +1 -0
  107. package/dist/src/components/tag.js +198 -0
  108. package/dist/src/components/tag.js.map +1 -0
  109. package/dist/src/components/tag.stories.js +459 -0
  110. package/dist/src/components/tag.stories.js.map +1 -0
  111. package/dist/src/components/tile.d.ts +15 -0
  112. package/dist/src/components/tile.d.ts.map +1 -0
  113. package/dist/src/components/tile.js +76 -0
  114. package/dist/src/components/tile.js.map +1 -0
  115. package/dist/src/components/tile.stories.js +167 -0
  116. package/dist/src/components/tile.stories.js.map +1 -0
  117. package/dist/src/components/toolbar.d.ts +18 -0
  118. package/dist/src/components/toolbar.d.ts.map +1 -0
  119. package/dist/src/components/toolbar.js +61 -0
  120. package/dist/src/components/toolbar.js.map +1 -0
  121. package/dist/src/components/toolbar.stories.js +69 -0
  122. package/dist/src/components/toolbar.stories.js.map +1 -0
  123. package/dist/src/components/tree-view.d.ts +47 -0
  124. package/dist/src/components/tree-view.d.ts.map +1 -0
  125. package/dist/src/components/tree-view.js +122 -0
  126. package/dist/src/components/tree-view.js.map +1 -0
  127. package/dist/src/components/tree-view.stories.js +283 -0
  128. package/dist/src/components/tree-view.stories.js.map +1 -0
  129. package/dist/src/icons.d.ts +11 -0
  130. package/dist/src/icons.d.ts.map +1 -0
  131. package/dist/src/icons.js +328 -0
  132. package/dist/src/icons.js.map +1 -0
  133. package/dist/src/index.css +358 -74
  134. package/dist/src/index.d.ts +17 -1
  135. package/dist/src/index.d.ts.map +1 -1
  136. package/dist/src/index.js +17 -1
  137. package/dist/src/index.js.map +1 -1
  138. package/dist/src/shadcn/components/ui/accordion.d.ts +2 -2
  139. package/dist/src/shadcn/components/ui/accordion.d.ts.map +1 -1
  140. package/dist/src/shadcn/components/ui/accordion.js +35 -9
  141. package/dist/src/shadcn/components/ui/accordion.js.map +1 -1
  142. package/dist/src/shadcn/components/ui/alert-dialog.d.ts +12 -4
  143. package/dist/src/shadcn/components/ui/alert-dialog.d.ts.map +1 -1
  144. package/dist/src/shadcn/components/ui/alert-dialog.js +128 -18
  145. package/dist/src/shadcn/components/ui/alert-dialog.js.map +1 -1
  146. package/dist/src/shadcn/components/ui/alert-dialog.stories.js +269 -19
  147. package/dist/src/shadcn/components/ui/alert-dialog.stories.js.map +1 -1
  148. package/dist/src/shadcn/components/ui/alert.d.ts +29 -6
  149. package/dist/src/shadcn/components/ui/alert.d.ts.map +1 -1
  150. package/dist/src/shadcn/components/ui/alert.js +50 -19
  151. package/dist/src/shadcn/components/ui/alert.js.map +1 -1
  152. package/dist/src/shadcn/components/ui/alert.stories.js +140 -36
  153. package/dist/src/shadcn/components/ui/alert.stories.js.map +1 -1
  154. package/dist/src/shadcn/components/ui/aspect-ratio.d.ts.map +1 -1
  155. package/dist/src/shadcn/components/ui/aspect-ratio.js +1 -0
  156. package/dist/src/shadcn/components/ui/aspect-ratio.js.map +1 -1
  157. package/dist/src/shadcn/components/ui/avatar.d.ts.map +1 -1
  158. package/dist/src/shadcn/components/ui/avatar.js +4 -3
  159. package/dist/src/shadcn/components/ui/avatar.js.map +1 -1
  160. package/dist/src/shadcn/components/ui/avatar.stories.js +68 -2
  161. package/dist/src/shadcn/components/ui/avatar.stories.js.map +1 -1
  162. package/dist/src/shadcn/components/ui/badge.d.ts +1 -1
  163. package/dist/src/shadcn/components/ui/badge.d.ts.map +1 -1
  164. package/dist/src/shadcn/components/ui/badge.js +16 -5
  165. package/dist/src/shadcn/components/ui/badge.js.map +1 -1
  166. package/dist/src/shadcn/components/ui/breadcrumb.d.ts +5 -2
  167. package/dist/src/shadcn/components/ui/breadcrumb.d.ts.map +1 -1
  168. package/dist/src/shadcn/components/ui/breadcrumb.js +98 -13
  169. package/dist/src/shadcn/components/ui/breadcrumb.js.map +1 -1
  170. package/dist/src/shadcn/components/ui/breadcrumb.stories.js +205 -45
  171. package/dist/src/shadcn/components/ui/breadcrumb.stories.js.map +1 -1
  172. package/dist/src/shadcn/components/ui/button.d.ts.map +1 -1
  173. package/dist/src/shadcn/components/ui/button.js +65 -11
  174. package/dist/src/shadcn/components/ui/button.js.map +1 -1
  175. package/dist/src/shadcn/components/ui/button.stories.js +99 -17
  176. package/dist/src/shadcn/components/ui/button.stories.js.map +1 -1
  177. package/dist/src/shadcn/components/ui/calendar.d.ts +1 -1
  178. package/dist/src/shadcn/components/ui/calendar.d.ts.map +1 -1
  179. package/dist/src/shadcn/components/ui/calendar.js +1 -0
  180. package/dist/src/shadcn/components/ui/calendar.js.map +1 -1
  181. package/dist/src/shadcn/components/ui/card.d.ts +5 -1
  182. package/dist/src/shadcn/components/ui/card.d.ts.map +1 -1
  183. package/dist/src/shadcn/components/ui/card.js +28 -7
  184. package/dist/src/shadcn/components/ui/card.js.map +1 -1
  185. package/dist/src/shadcn/components/ui/card.stories.js +23 -2
  186. package/dist/src/shadcn/components/ui/card.stories.js.map +1 -1
  187. package/dist/src/shadcn/components/ui/carousel.d.ts +1 -1
  188. package/dist/src/shadcn/components/ui/carousel.d.ts.map +1 -1
  189. package/dist/src/shadcn/components/ui/carousel.js +1 -0
  190. package/dist/src/shadcn/components/ui/carousel.js.map +1 -1
  191. package/dist/src/shadcn/components/ui/chart.d.ts +5 -5
  192. package/dist/src/shadcn/components/ui/chart.d.ts.map +1 -1
  193. package/dist/src/shadcn/components/ui/chart.js +4 -3
  194. package/dist/src/shadcn/components/ui/chart.js.map +1 -1
  195. package/dist/src/shadcn/components/ui/checkbox.d.ts +5 -1
  196. package/dist/src/shadcn/components/ui/checkbox.d.ts.map +1 -1
  197. package/dist/src/shadcn/components/ui/checkbox.js +46 -6
  198. package/dist/src/shadcn/components/ui/checkbox.js.map +1 -1
  199. package/dist/src/shadcn/components/ui/checkbox.stories.js +156 -46
  200. package/dist/src/shadcn/components/ui/checkbox.stories.js.map +1 -1
  201. package/dist/src/shadcn/components/ui/combobox.d.ts +29 -0
  202. package/dist/src/shadcn/components/ui/combobox.d.ts.map +1 -0
  203. package/dist/src/shadcn/components/ui/combobox.js +226 -0
  204. package/dist/src/shadcn/components/ui/combobox.js.map +1 -0
  205. package/dist/src/shadcn/components/ui/combobox.stories.js +167 -0
  206. package/dist/src/shadcn/components/ui/combobox.stories.js.map +1 -0
  207. package/dist/src/shadcn/components/ui/command.d.ts +4 -2
  208. package/dist/src/shadcn/components/ui/command.d.ts.map +1 -1
  209. package/dist/src/shadcn/components/ui/command.js +75 -13
  210. package/dist/src/shadcn/components/ui/command.js.map +1 -1
  211. package/dist/src/shadcn/components/ui/command.stories.js +277 -57
  212. package/dist/src/shadcn/components/ui/command.stories.js.map +1 -1
  213. package/dist/src/shadcn/components/ui/context-menu.d.ts +7 -3
  214. package/dist/src/shadcn/components/ui/context-menu.d.ts.map +1 -1
  215. package/dist/src/shadcn/components/ui/context-menu.js +120 -13
  216. package/dist/src/shadcn/components/ui/context-menu.js.map +1 -1
  217. package/dist/src/shadcn/components/ui/dialog.d.ts.map +1 -1
  218. package/dist/src/shadcn/components/ui/dialog.js +35 -7
  219. package/dist/src/shadcn/components/ui/dialog.js.map +1 -1
  220. package/dist/src/shadcn/components/ui/drawer.d.ts.map +1 -1
  221. package/dist/src/shadcn/components/ui/drawer.js +27 -5
  222. package/dist/src/shadcn/components/ui/drawer.js.map +1 -1
  223. package/dist/src/shadcn/components/ui/dropdown-menu.d.ts +7 -3
  224. package/dist/src/shadcn/components/ui/dropdown-menu.d.ts.map +1 -1
  225. package/dist/src/shadcn/components/ui/dropdown-menu.js +122 -14
  226. package/dist/src/shadcn/components/ui/dropdown-menu.js.map +1 -1
  227. package/dist/src/shadcn/components/ui/dropdown-menu.stories.js +22 -5
  228. package/dist/src/shadcn/components/ui/dropdown-menu.stories.js.map +1 -1
  229. package/dist/src/shadcn/components/ui/form.d.ts +2 -2
  230. package/dist/src/shadcn/components/ui/form.d.ts.map +1 -1
  231. package/dist/src/shadcn/components/ui/form.js +17 -8
  232. package/dist/src/shadcn/components/ui/form.js.map +1 -1
  233. package/dist/src/shadcn/components/ui/hover-card.d.ts.map +1 -1
  234. package/dist/src/shadcn/components/ui/hover-card.js +2 -1
  235. package/dist/src/shadcn/components/ui/hover-card.js.map +1 -1
  236. package/dist/src/shadcn/components/ui/input-otp.d.ts.map +1 -1
  237. package/dist/src/shadcn/components/ui/input-otp.js +1 -0
  238. package/dist/src/shadcn/components/ui/input-otp.js.map +1 -1
  239. package/dist/src/shadcn/components/ui/input.d.ts +3 -1
  240. package/dist/src/shadcn/components/ui/input.d.ts.map +1 -1
  241. package/dist/src/shadcn/components/ui/input.js +126 -17
  242. package/dist/src/shadcn/components/ui/input.js.map +1 -1
  243. package/dist/src/shadcn/components/ui/input.stories.js +218 -29
  244. package/dist/src/shadcn/components/ui/input.stories.js.map +1 -1
  245. package/dist/src/shadcn/components/ui/label.d.ts.map +1 -1
  246. package/dist/src/shadcn/components/ui/label.js +9 -1
  247. package/dist/src/shadcn/components/ui/label.js.map +1 -1
  248. package/dist/src/shadcn/components/ui/menubar.d.ts.map +1 -1
  249. package/dist/src/shadcn/components/ui/menubar.js +35 -13
  250. package/dist/src/shadcn/components/ui/menubar.js.map +1 -1
  251. package/dist/src/shadcn/components/ui/pagination.d.ts +9 -2
  252. package/dist/src/shadcn/components/ui/pagination.d.ts.map +1 -1
  253. package/dist/src/shadcn/components/ui/pagination.js +41 -24
  254. package/dist/src/shadcn/components/ui/pagination.js.map +1 -1
  255. package/dist/src/shadcn/components/ui/pagination.stories.js +44 -37
  256. package/dist/src/shadcn/components/ui/pagination.stories.js.map +1 -1
  257. package/dist/src/shadcn/components/ui/popover.d.ts.map +1 -1
  258. package/dist/src/shadcn/components/ui/popover.js +13 -1
  259. package/dist/src/shadcn/components/ui/popover.js.map +1 -1
  260. package/dist/src/shadcn/components/ui/progress.d.ts.map +1 -1
  261. package/dist/src/shadcn/components/ui/progress.js +6 -2
  262. package/dist/src/shadcn/components/ui/progress.js.map +1 -1
  263. package/dist/src/shadcn/components/ui/radio-button-group.d.ts +21 -0
  264. package/dist/src/shadcn/components/ui/radio-button-group.d.ts.map +1 -0
  265. package/dist/src/shadcn/components/ui/radio-button-group.js +148 -0
  266. package/dist/src/shadcn/components/ui/radio-button-group.js.map +1 -0
  267. package/dist/src/shadcn/components/ui/radio-button-group.stories.js +283 -0
  268. package/dist/src/shadcn/components/ui/radio-button-group.stories.js.map +1 -0
  269. package/dist/src/shadcn/components/ui/radio-group.d.ts +5 -1
  270. package/dist/src/shadcn/components/ui/radio-group.d.ts.map +1 -1
  271. package/dist/src/shadcn/components/ui/radio-group.js +40 -7
  272. package/dist/src/shadcn/components/ui/radio-group.js.map +1 -1
  273. package/dist/src/shadcn/components/ui/radio-group.stories.js +107 -32
  274. package/dist/src/shadcn/components/ui/radio-group.stories.js.map +1 -1
  275. package/dist/src/shadcn/components/ui/resizable.d.ts.map +1 -1
  276. package/dist/src/shadcn/components/ui/resizable.js +2 -1
  277. package/dist/src/shadcn/components/ui/resizable.js.map +1 -1
  278. package/dist/src/shadcn/components/ui/resizable.stories.js +2 -2
  279. package/dist/src/shadcn/components/ui/resizable.stories.js.map +1 -1
  280. package/dist/src/shadcn/components/ui/scroll-area.d.ts.map +1 -1
  281. package/dist/src/shadcn/components/ui/scroll-area.js +10 -3
  282. package/dist/src/shadcn/components/ui/scroll-area.js.map +1 -1
  283. package/dist/src/shadcn/components/ui/select.d.ts +1 -2
  284. package/dist/src/shadcn/components/ui/select.d.ts.map +1 -1
  285. package/dist/src/shadcn/components/ui/select.js +49 -19
  286. package/dist/src/shadcn/components/ui/select.js.map +1 -1
  287. package/dist/src/shadcn/components/ui/select.stories.js +193 -70
  288. package/dist/src/shadcn/components/ui/select.stories.js.map +1 -1
  289. package/dist/src/shadcn/components/ui/separator.d.ts.map +1 -1
  290. package/dist/src/shadcn/components/ui/separator.js +8 -1
  291. package/dist/src/shadcn/components/ui/separator.js.map +1 -1
  292. package/dist/src/shadcn/components/ui/sheet.js +1 -1
  293. package/dist/src/shadcn/components/ui/sheet.js.map +1 -1
  294. package/dist/src/shadcn/components/ui/sidebar.d.ts +4 -4
  295. package/dist/src/shadcn/components/ui/sidebar.d.ts.map +1 -1
  296. package/dist/src/shadcn/components/ui/sidebar.js +21 -6
  297. package/dist/src/shadcn/components/ui/sidebar.js.map +1 -1
  298. package/dist/src/shadcn/components/ui/skeleton.d.ts.map +1 -1
  299. package/dist/src/shadcn/components/ui/skeleton.js +3 -1
  300. package/dist/src/shadcn/components/ui/skeleton.js.map +1 -1
  301. package/dist/src/shadcn/components/ui/slider.d.ts.map +1 -1
  302. package/dist/src/shadcn/components/ui/slider.js +35 -4
  303. package/dist/src/shadcn/components/ui/slider.js.map +1 -1
  304. package/dist/src/shadcn/components/ui/sonner.d.ts +24 -2
  305. package/dist/src/shadcn/components/ui/sonner.d.ts.map +1 -1
  306. package/dist/src/shadcn/components/ui/sonner.js +127 -9
  307. package/dist/src/shadcn/components/ui/sonner.js.map +1 -1
  308. package/dist/src/shadcn/components/ui/sonner.stories.js +251 -12
  309. package/dist/src/shadcn/components/ui/sonner.stories.js.map +1 -1
  310. package/dist/src/shadcn/components/ui/switch.d.ts +7 -1
  311. package/dist/src/shadcn/components/ui/switch.d.ts.map +1 -1
  312. package/dist/src/shadcn/components/ui/switch.js +55 -3
  313. package/dist/src/shadcn/components/ui/switch.js.map +1 -1
  314. package/dist/src/shadcn/components/ui/switch.stories.js +84 -9
  315. package/dist/src/shadcn/components/ui/switch.stories.js.map +1 -1
  316. package/dist/src/shadcn/components/ui/table.d.ts +23 -6
  317. package/dist/src/shadcn/components/ui/table.d.ts.map +1 -1
  318. package/dist/src/shadcn/components/ui/table.js +65 -20
  319. package/dist/src/shadcn/components/ui/table.js.map +1 -1
  320. package/dist/src/shadcn/components/ui/table.stories.js +217 -97
  321. package/dist/src/shadcn/components/ui/table.stories.js.map +1 -1
  322. package/dist/src/shadcn/components/ui/tabs.d.ts +30 -5
  323. package/dist/src/shadcn/components/ui/tabs.d.ts.map +1 -1
  324. package/dist/src/shadcn/components/ui/tabs.js +470 -23
  325. package/dist/src/shadcn/components/ui/tabs.js.map +1 -1
  326. package/dist/src/shadcn/components/ui/tabs.stories.js +405 -181
  327. package/dist/src/shadcn/components/ui/tabs.stories.js.map +1 -1
  328. package/dist/src/shadcn/components/ui/textarea.d.ts +8 -1
  329. package/dist/src/shadcn/components/ui/textarea.d.ts.map +1 -1
  330. package/dist/src/shadcn/components/ui/textarea.js +30 -2
  331. package/dist/src/shadcn/components/ui/textarea.js.map +1 -1
  332. package/dist/src/shadcn/components/ui/textarea.stories.js +85 -4
  333. package/dist/src/shadcn/components/ui/textarea.stories.js.map +1 -1
  334. package/dist/src/shadcn/components/ui/toggle-group.d.ts +3 -3
  335. package/dist/src/shadcn/components/ui/toggle-group.d.ts.map +1 -1
  336. package/dist/src/shadcn/components/ui/toggle-group.js +14 -12
  337. package/dist/src/shadcn/components/ui/toggle-group.js.map +1 -1
  338. package/dist/src/shadcn/components/ui/toggle.d.ts +3 -4
  339. package/dist/src/shadcn/components/ui/toggle.d.ts.map +1 -1
  340. package/dist/src/shadcn/components/ui/toggle.js +44 -16
  341. package/dist/src/shadcn/components/ui/toggle.js.map +1 -1
  342. package/dist/src/shadcn/components/ui/toggle.stories.js +130 -7
  343. package/dist/src/shadcn/components/ui/toggle.stories.js.map +1 -1
  344. package/dist/src/shadcn/components/ui/tooltip.d.ts.map +1 -1
  345. package/dist/src/shadcn/components/ui/tooltip.js +12 -1
  346. package/dist/src/shadcn/components/ui/tooltip.js.map +1 -1
  347. package/dist/src/shadcn/components/ui/tree.d.ts +29 -0
  348. package/dist/src/shadcn/components/ui/tree.d.ts.map +1 -0
  349. package/dist/src/shadcn/components/ui/tree.js +135 -0
  350. package/dist/src/shadcn/components/ui/tree.js.map +1 -0
  351. package/dist/src/shadcn/shadcn.css +4 -4
  352. package/dist/src/tokens.css +50 -20
  353. package/dist/src/typography.css +78 -15
  354. package/package.json +84 -64
  355. package/src/components/button-dropdown.stories.tsx +41 -0
  356. package/src/components/button-dropdown.tsx +97 -0
  357. package/src/components/code-editor/fhir-autocomplete.test.ts +993 -0
  358. package/src/components/code-editor/fhir-autocomplete.ts +2322 -0
  359. package/src/components/code-editor/http/grammar/http.grammar +74 -0
  360. package/src/components/code-editor/http/grammar/http.terms.ts +9 -0
  361. package/src/components/code-editor/http/grammar/http.test.ts +110 -0
  362. package/src/components/code-editor/http/grammar/http.ts +21 -0
  363. package/src/components/code-editor/http/index.ts +424 -0
  364. package/src/components/code-editor/index.tsx +1944 -42
  365. package/src/components/code-editor/json-ast.test.ts +230 -0
  366. package/src/components/code-editor/json-ast.ts +590 -0
  367. package/src/components/code-editor/sql-completion.ts +1112 -0
  368. package/src/components/code-editor.stories.tsx +325 -2
  369. package/src/components/copy-icon.tsx +57 -3
  370. package/src/components/data-table.stories.tsx +91 -0
  371. package/src/components/data-table.tsx +126 -0
  372. package/src/components/date-picker-input.stories.tsx +79 -0
  373. package/src/components/date-picker-input.tsx +104 -0
  374. package/src/components/fhir-structure-view.stories.tsx +439 -0
  375. package/src/components/fhir-structure-view.tsx +233 -0
  376. package/src/components/icon-button.stories.tsx +86 -0
  377. package/src/components/icon-button.tsx +57 -0
  378. package/src/components/operation-outcome-view.stories.tsx +163 -0
  379. package/src/components/operation-outcome-view.tsx +254 -0
  380. package/src/components/request-line-editor.stories.tsx +17 -27
  381. package/src/components/request-line-editor.tsx +103 -61
  382. package/src/components/sandbox.stories.tsx +131 -0
  383. package/src/components/sandbox.tsx +191 -0
  384. package/src/components/segment-control.stories.tsx +61 -0
  385. package/src/components/segment-control.tsx +83 -0
  386. package/src/components/split-button.stories.tsx +68 -0
  387. package/src/components/split-button.tsx +74 -0
  388. package/src/components/tag.stories.tsx +371 -0
  389. package/src/components/tag.tsx +236 -0
  390. package/src/components/tile.stories.tsx +149 -0
  391. package/src/components/tile.tsx +105 -0
  392. package/src/components/toolbar.stories.tsx +64 -0
  393. package/src/components/toolbar.tsx +98 -0
  394. package/src/components/tree-view.stories.tsx +265 -0
  395. package/src/components/tree-view.tsx +246 -0
  396. package/src/icons.tsx +331 -0
  397. package/src/index.css +358 -74
  398. package/src/index.tsx +17 -3
  399. package/src/shadcn/components/ui/accordion.tsx +91 -10
  400. package/src/shadcn/components/ui/alert-dialog.stories.tsx +209 -15
  401. package/src/shadcn/components/ui/alert-dialog.tsx +236 -26
  402. package/src/shadcn/components/ui/alert.stories.tsx +120 -21
  403. package/src/shadcn/components/ui/alert.tsx +125 -28
  404. package/src/shadcn/components/ui/aspect-ratio.tsx +1 -0
  405. package/src/shadcn/components/ui/avatar.stories.tsx +74 -1
  406. package/src/shadcn/components/ui/avatar.tsx +22 -6
  407. package/src/shadcn/components/ui/badge.tsx +67 -18
  408. package/src/shadcn/components/ui/breadcrumb.stories.tsx +161 -41
  409. package/src/shadcn/components/ui/breadcrumb.tsx +172 -23
  410. package/src/shadcn/components/ui/button.stories.tsx +106 -18
  411. package/src/shadcn/components/ui/button.tsx +151 -55
  412. package/src/shadcn/components/ui/calendar.tsx +1 -0
  413. package/src/shadcn/components/ui/card.stories.tsx +17 -3
  414. package/src/shadcn/components/ui/card.tsx +89 -14
  415. package/src/shadcn/components/ui/carousel.tsx +1 -0
  416. package/src/shadcn/components/ui/chart.tsx +9 -5
  417. package/src/shadcn/components/ui/checkbox.stories.tsx +78 -30
  418. package/src/shadcn/components/ui/checkbox.tsx +91 -8
  419. package/src/shadcn/components/ui/combobox.stories.tsx +148 -0
  420. package/src/shadcn/components/ui/combobox.tsx +324 -0
  421. package/src/shadcn/components/ui/command.stories.tsx +184 -39
  422. package/src/shadcn/components/ui/command.tsx +218 -37
  423. package/src/shadcn/components/ui/context-menu.tsx +333 -40
  424. package/src/shadcn/components/ui/dialog.tsx +101 -13
  425. package/src/shadcn/components/ui/drawer.tsx +94 -18
  426. package/src/shadcn/components/ui/dropdown-menu.stories.tsx +18 -2
  427. package/src/shadcn/components/ui/dropdown-menu.tsx +334 -68
  428. package/src/shadcn/components/ui/form.tsx +22 -11
  429. package/src/shadcn/components/ui/hover-card.tsx +2 -1
  430. package/src/shadcn/components/ui/input-otp.tsx +1 -0
  431. package/src/shadcn/components/ui/input.stories.tsx +235 -27
  432. package/src/shadcn/components/ui/input.tsx +400 -29
  433. package/src/shadcn/components/ui/label.tsx +22 -4
  434. package/src/shadcn/components/ui/menubar.tsx +188 -43
  435. package/src/shadcn/components/ui/pagination.stories.tsx +8 -2
  436. package/src/shadcn/components/ui/pagination.tsx +65 -8
  437. package/src/shadcn/components/ui/popover.tsx +36 -4
  438. package/src/shadcn/components/ui/progress.tsx +21 -5
  439. package/src/shadcn/components/ui/radio-button-group.stories.tsx +247 -0
  440. package/src/shadcn/components/ui/radio-button-group.tsx +188 -0
  441. package/src/shadcn/components/ui/radio-group.stories.tsx +70 -14
  442. package/src/shadcn/components/ui/radio-group.tsx +85 -9
  443. package/src/shadcn/components/ui/resizable.stories.tsx +2 -2
  444. package/src/shadcn/components/ui/resizable.tsx +2 -1
  445. package/src/shadcn/components/ui/scroll-area.tsx +34 -5
  446. package/src/shadcn/components/ui/select.stories.tsx +108 -32
  447. package/src/shadcn/components/ui/select.tsx +182 -36
  448. package/src/shadcn/components/ui/separator.tsx +16 -5
  449. package/src/shadcn/components/ui/sheet.tsx +1 -1
  450. package/src/shadcn/components/ui/sidebar.tsx +69 -26
  451. package/src/shadcn/components/ui/skeleton.tsx +4 -1
  452. package/src/shadcn/components/ui/slider.tsx +83 -11
  453. package/src/shadcn/components/ui/sonner.stories.tsx +238 -17
  454. package/src/shadcn/components/ui/sonner.tsx +254 -11
  455. package/src/shadcn/components/ui/switch.stories.tsx +52 -5
  456. package/src/shadcn/components/ui/switch.tsx +92 -7
  457. package/src/shadcn/components/ui/table.stories.tsx +252 -72
  458. package/src/shadcn/components/ui/table.tsx +204 -26
  459. package/src/shadcn/components/ui/tabs.stories.tsx +235 -123
  460. package/src/shadcn/components/ui/tabs.tsx +694 -36
  461. package/src/shadcn/components/ui/textarea.stories.tsx +94 -2
  462. package/src/shadcn/components/ui/textarea.tsx +70 -5
  463. package/src/shadcn/components/ui/toggle-group.tsx +35 -13
  464. package/src/shadcn/components/ui/toggle.stories.tsx +92 -5
  465. package/src/shadcn/components/ui/toggle.tsx +96 -23
  466. package/src/shadcn/components/ui/tooltip.tsx +34 -8
  467. package/src/shadcn/components/ui/tree.tsx +257 -0
  468. package/src/shadcn/shadcn.css +4 -4
  469. package/src/tokens.css +50 -20
  470. package/src/typography.css +78 -15
  471. package/dist/src/components/code-editor.stories.d.ts +0 -7
  472. package/dist/src/components/code-editor.stories.d.ts.map +0 -1
  473. package/dist/src/components/request-line-editor.stories.d.ts +0 -11
  474. package/dist/src/components/request-line-editor.stories.d.ts.map +0 -1
  475. package/dist/src/index.stories.d.ts +0 -14
  476. package/dist/src/index.stories.d.ts.map +0 -1
  477. package/dist/src/index.stories.js +0 -19
  478. package/dist/src/index.stories.js.map +0 -1
  479. package/dist/src/shadcn/components/ui/accordion.stories.d.ts +0 -8
  480. package/dist/src/shadcn/components/ui/accordion.stories.d.ts.map +0 -1
  481. package/dist/src/shadcn/components/ui/alert-dialog.stories.d.ts +0 -8
  482. package/dist/src/shadcn/components/ui/alert-dialog.stories.d.ts.map +0 -1
  483. package/dist/src/shadcn/components/ui/alert.stories.d.ts +0 -8
  484. package/dist/src/shadcn/components/ui/alert.stories.d.ts.map +0 -1
  485. package/dist/src/shadcn/components/ui/aspect-ratio.stories.d.ts +0 -8
  486. package/dist/src/shadcn/components/ui/aspect-ratio.stories.d.ts.map +0 -1
  487. package/dist/src/shadcn/components/ui/avatar.stories.d.ts +0 -8
  488. package/dist/src/shadcn/components/ui/avatar.stories.d.ts.map +0 -1
  489. package/dist/src/shadcn/components/ui/badge.stories.d.ts +0 -8
  490. package/dist/src/shadcn/components/ui/badge.stories.d.ts.map +0 -1
  491. package/dist/src/shadcn/components/ui/breadcrumb.stories.d.ts +0 -8
  492. package/dist/src/shadcn/components/ui/breadcrumb.stories.d.ts.map +0 -1
  493. package/dist/src/shadcn/components/ui/button.stories.d.ts +0 -23
  494. package/dist/src/shadcn/components/ui/button.stories.d.ts.map +0 -1
  495. package/dist/src/shadcn/components/ui/calendar.stories.d.ts +0 -8
  496. package/dist/src/shadcn/components/ui/calendar.stories.d.ts.map +0 -1
  497. package/dist/src/shadcn/components/ui/card.stories.d.ts +0 -8
  498. package/dist/src/shadcn/components/ui/card.stories.d.ts.map +0 -1
  499. package/dist/src/shadcn/components/ui/carousel.stories.d.ts +0 -8
  500. package/dist/src/shadcn/components/ui/carousel.stories.d.ts.map +0 -1
  501. package/dist/src/shadcn/components/ui/chart.stories.d.ts +0 -8
  502. package/dist/src/shadcn/components/ui/chart.stories.d.ts.map +0 -1
  503. package/dist/src/shadcn/components/ui/checkbox.stories.d.ts +0 -8
  504. package/dist/src/shadcn/components/ui/checkbox.stories.d.ts.map +0 -1
  505. package/dist/src/shadcn/components/ui/collapsible.stories.d.ts +0 -8
  506. package/dist/src/shadcn/components/ui/collapsible.stories.d.ts.map +0 -1
  507. package/dist/src/shadcn/components/ui/command.stories.d.ts +0 -8
  508. package/dist/src/shadcn/components/ui/command.stories.d.ts.map +0 -1
  509. package/dist/src/shadcn/components/ui/context-menu.stories.d.ts +0 -8
  510. package/dist/src/shadcn/components/ui/context-menu.stories.d.ts.map +0 -1
  511. package/dist/src/shadcn/components/ui/dialog.stories.d.ts +0 -8
  512. package/dist/src/shadcn/components/ui/dialog.stories.d.ts.map +0 -1
  513. package/dist/src/shadcn/components/ui/drawer.stories.d.ts +0 -8
  514. package/dist/src/shadcn/components/ui/drawer.stories.d.ts.map +0 -1
  515. package/dist/src/shadcn/components/ui/dropdown-menu.stories.d.ts +0 -8
  516. package/dist/src/shadcn/components/ui/dropdown-menu.stories.d.ts.map +0 -1
  517. package/dist/src/shadcn/components/ui/form.stories.d.ts +0 -8
  518. package/dist/src/shadcn/components/ui/form.stories.d.ts.map +0 -1
  519. package/dist/src/shadcn/components/ui/hover-card.stories.d.ts +0 -8
  520. package/dist/src/shadcn/components/ui/hover-card.stories.d.ts.map +0 -1
  521. package/dist/src/shadcn/components/ui/input-otp.stories.d.ts +0 -8
  522. package/dist/src/shadcn/components/ui/input-otp.stories.d.ts.map +0 -1
  523. package/dist/src/shadcn/components/ui/input.stories.d.ts +0 -18
  524. package/dist/src/shadcn/components/ui/input.stories.d.ts.map +0 -1
  525. package/dist/src/shadcn/components/ui/label.stories.d.ts +0 -8
  526. package/dist/src/shadcn/components/ui/label.stories.d.ts.map +0 -1
  527. package/dist/src/shadcn/components/ui/menubar.stories.d.ts +0 -8
  528. package/dist/src/shadcn/components/ui/menubar.stories.d.ts.map +0 -1
  529. package/dist/src/shadcn/components/ui/navigation-menu.stories.d.ts +0 -8
  530. package/dist/src/shadcn/components/ui/navigation-menu.stories.d.ts.map +0 -1
  531. package/dist/src/shadcn/components/ui/pagination.stories.d.ts +0 -8
  532. package/dist/src/shadcn/components/ui/pagination.stories.d.ts.map +0 -1
  533. package/dist/src/shadcn/components/ui/popover.stories.d.ts +0 -8
  534. package/dist/src/shadcn/components/ui/popover.stories.d.ts.map +0 -1
  535. package/dist/src/shadcn/components/ui/progress.stories.d.ts +0 -8
  536. package/dist/src/shadcn/components/ui/progress.stories.d.ts.map +0 -1
  537. package/dist/src/shadcn/components/ui/radio-group.stories.d.ts +0 -8
  538. package/dist/src/shadcn/components/ui/radio-group.stories.d.ts.map +0 -1
  539. package/dist/src/shadcn/components/ui/resizable.stories.d.ts +0 -8
  540. package/dist/src/shadcn/components/ui/resizable.stories.d.ts.map +0 -1
  541. package/dist/src/shadcn/components/ui/scroll-area.stories.d.ts +0 -8
  542. package/dist/src/shadcn/components/ui/scroll-area.stories.d.ts.map +0 -1
  543. package/dist/src/shadcn/components/ui/select.stories.d.ts +0 -11
  544. package/dist/src/shadcn/components/ui/select.stories.d.ts.map +0 -1
  545. package/dist/src/shadcn/components/ui/separator.stories.d.ts +0 -8
  546. package/dist/src/shadcn/components/ui/separator.stories.d.ts.map +0 -1
  547. package/dist/src/shadcn/components/ui/sheet.stories.d.ts +0 -8
  548. package/dist/src/shadcn/components/ui/sheet.stories.d.ts.map +0 -1
  549. package/dist/src/shadcn/components/ui/sidebar.stories.d.ts +0 -11
  550. package/dist/src/shadcn/components/ui/sidebar.stories.d.ts.map +0 -1
  551. package/dist/src/shadcn/components/ui/skeleton.stories.d.ts +0 -8
  552. package/dist/src/shadcn/components/ui/skeleton.stories.d.ts.map +0 -1
  553. package/dist/src/shadcn/components/ui/slider.stories.d.ts +0 -8
  554. package/dist/src/shadcn/components/ui/slider.stories.d.ts.map +0 -1
  555. package/dist/src/shadcn/components/ui/sonner.stories.d.ts +0 -8
  556. package/dist/src/shadcn/components/ui/sonner.stories.d.ts.map +0 -1
  557. package/dist/src/shadcn/components/ui/switch.stories.d.ts +0 -8
  558. package/dist/src/shadcn/components/ui/switch.stories.d.ts.map +0 -1
  559. package/dist/src/shadcn/components/ui/table.stories.d.ts +0 -8
  560. package/dist/src/shadcn/components/ui/table.stories.d.ts.map +0 -1
  561. package/dist/src/shadcn/components/ui/tabs.stories.d.ts +0 -32
  562. package/dist/src/shadcn/components/ui/tabs.stories.d.ts.map +0 -1
  563. package/dist/src/shadcn/components/ui/textarea.stories.d.ts +0 -8
  564. package/dist/src/shadcn/components/ui/textarea.stories.d.ts.map +0 -1
  565. package/dist/src/shadcn/components/ui/toggle-group.stories.d.ts +0 -8
  566. package/dist/src/shadcn/components/ui/toggle-group.stories.d.ts.map +0 -1
  567. package/dist/src/shadcn/components/ui/toggle.stories.d.ts +0 -8
  568. package/dist/src/shadcn/components/ui/toggle.stories.d.ts.map +0 -1
  569. package/dist/src/shadcn/components/ui/tooltip.stories.d.ts +0 -8
  570. package/dist/src/shadcn/components/ui/tooltip.stories.d.ts.map +0 -1
  571. package/src/index.stories.tsx +0 -21
@@ -0,0 +1,993 @@
1
+ import { CompletionContext } from "@codemirror/autocomplete";
2
+ import { json } from "@codemirror/lang-json";
3
+ import { EditorState } from "@codemirror/state";
4
+ import { describe, expect, it } from "vitest";
5
+ import {
6
+ buildParameterSnippet,
7
+ type ExpandValueSet,
8
+ type GetStructureDefinitions,
9
+ jsonCompletionSource,
10
+ } from "./fhir-autocomplete";
11
+
12
+ // ── Minimal mock SDs ───────────────────────────────────────────────────
13
+
14
+ const PATIENT_SD = {
15
+ type: "Patient",
16
+ url: "http://hl7.org/fhir/StructureDefinition/Patient",
17
+ baseDefinition: "http://hl7.org/fhir/StructureDefinition/DomainResource",
18
+ differential: {
19
+ element: [
20
+ { path: "Patient", min: 0, max: "*" },
21
+ { path: "Patient.name", min: 0, max: "*", type: [{ code: "HumanName" }] },
22
+ {
23
+ path: "Patient.gender",
24
+ min: 0,
25
+ max: "1",
26
+ type: [{ code: "code" }],
27
+ binding: {
28
+ valueSet: "http://hl7.org/fhir/ValueSet/administrative-gender",
29
+ strength: "required",
30
+ },
31
+ },
32
+ { path: "Patient.birthDate", min: 0, max: "1", type: [{ code: "date" }] },
33
+ { path: "Patient.active", min: 0, max: "1", type: [{ code: "boolean" }] },
34
+ {
35
+ path: "Patient.managingOrganization",
36
+ min: 0,
37
+ max: "1",
38
+ type: [
39
+ {
40
+ code: "Reference",
41
+ targetProfile: [
42
+ "http://hl7.org/fhir/StructureDefinition/Organization",
43
+ ],
44
+ },
45
+ ],
46
+ },
47
+ {
48
+ path: "Patient.contained",
49
+ min: 0,
50
+ max: "*",
51
+ type: [{ code: "Resource" }],
52
+ },
53
+ {
54
+ path: "Patient.meta",
55
+ min: 0,
56
+ max: "1",
57
+ type: [{ code: "Meta" }],
58
+ },
59
+ ],
60
+ },
61
+ };
62
+
63
+ const OBSERVATION_SD = {
64
+ type: "Observation",
65
+ url: "http://hl7.org/fhir/StructureDefinition/Observation",
66
+ baseDefinition: "http://hl7.org/fhir/StructureDefinition/DomainResource",
67
+ differential: {
68
+ element: [
69
+ { path: "Observation", min: 0, max: "*" },
70
+ {
71
+ path: "Observation.status",
72
+ min: 1,
73
+ max: "1",
74
+ type: [{ code: "code" }],
75
+ },
76
+ {
77
+ path: "Observation.code",
78
+ min: 1,
79
+ max: "1",
80
+ type: [{ code: "CodeableConcept" }],
81
+ },
82
+ {
83
+ path: "Observation.subject",
84
+ min: 0,
85
+ max: "1",
86
+ type: [
87
+ {
88
+ code: "Reference",
89
+ targetProfile: [
90
+ "http://hl7.org/fhir/StructureDefinition/Patient",
91
+ "http://hl7.org/fhir/StructureDefinition/Group",
92
+ ],
93
+ },
94
+ ],
95
+ },
96
+ ],
97
+ },
98
+ };
99
+
100
+ const DOMAIN_RESOURCE_SD = {
101
+ type: "DomainResource",
102
+ url: "http://hl7.org/fhir/StructureDefinition/DomainResource",
103
+ baseDefinition: "http://hl7.org/fhir/StructureDefinition/Resource",
104
+ differential: {
105
+ element: [
106
+ { path: "DomainResource", min: 0, max: "*" },
107
+ {
108
+ path: "DomainResource.text",
109
+ min: 0,
110
+ max: "1",
111
+ type: [{ code: "Narrative" }],
112
+ },
113
+ {
114
+ path: "DomainResource.contained",
115
+ min: 0,
116
+ max: "*",
117
+ type: [{ code: "Resource" }],
118
+ },
119
+ {
120
+ path: "DomainResource.extension",
121
+ min: 0,
122
+ max: "*",
123
+ type: [{ code: "Extension" }],
124
+ },
125
+ {
126
+ path: "DomainResource.modifierExtension",
127
+ min: 0,
128
+ max: "*",
129
+ type: [{ code: "Extension" }],
130
+ },
131
+ ],
132
+ },
133
+ };
134
+
135
+ const RESOURCE_SD = {
136
+ type: "Resource",
137
+ url: "http://hl7.org/fhir/StructureDefinition/Resource",
138
+ differential: {
139
+ element: [
140
+ { path: "Resource", min: 0, max: "*" },
141
+ { path: "Resource.id", min: 0, max: "1", type: [{ code: "id" }] },
142
+ { path: "Resource.meta", min: 0, max: "1", type: [{ code: "Meta" }] },
143
+ ],
144
+ },
145
+ };
146
+
147
+ const HUMAN_NAME_SD = {
148
+ type: "HumanName",
149
+ url: "http://hl7.org/fhir/StructureDefinition/HumanName",
150
+ differential: {
151
+ element: [
152
+ { path: "HumanName", min: 0, max: "*" },
153
+ {
154
+ path: "HumanName.family",
155
+ min: 0,
156
+ max: "1",
157
+ type: [{ code: "string" }],
158
+ },
159
+ { path: "HumanName.given", min: 0, max: "*", type: [{ code: "string" }] },
160
+ ],
161
+ },
162
+ };
163
+
164
+ const REFERENCE_SD = {
165
+ type: "Reference",
166
+ url: "http://hl7.org/fhir/StructureDefinition/Reference",
167
+ differential: {
168
+ element: [
169
+ { path: "Reference", min: 0, max: "*" },
170
+ {
171
+ path: "Reference.reference",
172
+ min: 0,
173
+ max: "1",
174
+ type: [{ code: "string" }],
175
+ },
176
+ {
177
+ path: "Reference.display",
178
+ min: 0,
179
+ max: "1",
180
+ type: [{ code: "string" }],
181
+ },
182
+ ],
183
+ },
184
+ };
185
+
186
+ const META_SD = {
187
+ type: "Meta",
188
+ url: "http://hl7.org/fhir/StructureDefinition/Meta",
189
+ differential: {
190
+ element: [
191
+ { path: "Meta", min: 0, max: "*" },
192
+ {
193
+ path: "Meta.profile",
194
+ min: 0,
195
+ max: "*",
196
+ type: [
197
+ {
198
+ code: "canonical",
199
+ targetProfile: [
200
+ "http://hl7.org/fhir/StructureDefinition/StructureDefinition",
201
+ ],
202
+ },
203
+ ],
204
+ },
205
+ ],
206
+ },
207
+ };
208
+
209
+ const BUNDLE_SD = {
210
+ type: "Bundle",
211
+ url: "http://hl7.org/fhir/StructureDefinition/Bundle",
212
+ baseDefinition: "http://hl7.org/fhir/StructureDefinition/Resource",
213
+ differential: {
214
+ element: [
215
+ { path: "Bundle", min: 0, max: "*" },
216
+ { path: "Bundle.type", min: 1, max: "1", type: [{ code: "code" }] },
217
+ {
218
+ path: "Bundle.entry",
219
+ min: 0,
220
+ max: "*",
221
+ type: [{ code: "BackboneElement" }],
222
+ },
223
+ {
224
+ path: "Bundle.entry.resource",
225
+ min: 0,
226
+ max: "1",
227
+ type: [{ code: "Resource" }],
228
+ },
229
+ ],
230
+ },
231
+ };
232
+
233
+ const PARAMETERS_SD = {
234
+ type: "Parameters",
235
+ url: "http://hl7.org/fhir/StructureDefinition/Parameters",
236
+ baseDefinition: "http://hl7.org/fhir/StructureDefinition/Resource",
237
+ differential: {
238
+ element: [
239
+ { path: "Parameters", min: 0, max: "*" },
240
+ {
241
+ path: "Parameters.parameter",
242
+ min: 0,
243
+ max: "*",
244
+ type: [{ code: "BackboneElement" }],
245
+ },
246
+ {
247
+ path: "Parameters.parameter.name",
248
+ min: 1,
249
+ max: "1",
250
+ type: [{ code: "string" }],
251
+ },
252
+ {
253
+ path: "Parameters.parameter.value[x]",
254
+ min: 0,
255
+ max: "1",
256
+ type: [
257
+ { code: "string" },
258
+ { code: "boolean" },
259
+ { code: "integer" },
260
+ { code: "code" },
261
+ { code: "Reference" },
262
+ { code: "CodeableConcept" },
263
+ ],
264
+ },
265
+ {
266
+ path: "Parameters.parameter.resource",
267
+ min: 0,
268
+ max: "1",
269
+ type: [{ code: "Resource" }],
270
+ },
271
+ {
272
+ path: "Parameters.parameter.part",
273
+ min: 0,
274
+ max: "*",
275
+ contentReference: "#Parameters.parameter",
276
+ },
277
+ ],
278
+ },
279
+ };
280
+
281
+ const INSTALL_PARAMS_PROFILE = {
282
+ type: "Parameters",
283
+ url: "http://health-samurai.io/fhir/core/StructureDefinition/fhir-package-install-parameters",
284
+ baseDefinition: "http://hl7.org/fhir/StructureDefinition/Parameters",
285
+ differential: {
286
+ element: [
287
+ { path: "Parameters.parameter", min: 1 },
288
+ {
289
+ path: "Parameters.parameter",
290
+ sliceName: "package",
291
+ min: 1,
292
+ max: "*",
293
+ },
294
+ {
295
+ path: "Parameters.parameter.name",
296
+ fixedString: "package",
297
+ },
298
+ {
299
+ path: "Parameters.parameter",
300
+ sliceName: "registry",
301
+ min: 0,
302
+ max: "1",
303
+ },
304
+ {
305
+ path: "Parameters.parameter.name",
306
+ fixedString: "registry",
307
+ },
308
+ ],
309
+ },
310
+ };
311
+
312
+ const TYPED_PARAMS_PROFILE = {
313
+ type: "Parameters",
314
+ url: "http://example.com/StructureDefinition/typed-params",
315
+ baseDefinition: "http://hl7.org/fhir/StructureDefinition/Parameters",
316
+ differential: {
317
+ element: [
318
+ {
319
+ path: "Parameters.parameter",
320
+ sliceName: "count",
321
+ min: 1,
322
+ max: "1",
323
+ },
324
+ {
325
+ path: "Parameters.parameter.name",
326
+ fixedString: "count",
327
+ },
328
+ {
329
+ path: "Parameters.parameter.value[x]",
330
+ type: [{ code: "integer" }],
331
+ },
332
+ {
333
+ path: "Parameters.parameter",
334
+ sliceName: "label",
335
+ min: 0,
336
+ max: "1",
337
+ },
338
+ {
339
+ path: "Parameters.parameter.name",
340
+ fixedString: "label",
341
+ },
342
+ {
343
+ path: "Parameters.parameter.value[x]",
344
+ type: [{ code: "string" }],
345
+ },
346
+ ],
347
+ },
348
+ };
349
+
350
+ const TOPIC_DEST_SD = {
351
+ type: "AidboxTopicDestination",
352
+ url: "http://aidbox.app/StructureDefinition/AidboxTopicDestination",
353
+ baseDefinition: "http://hl7.org/fhir/StructureDefinition/Parameters",
354
+ differential: {
355
+ element: [
356
+ { path: "AidboxTopicDestination", min: 0, max: "*" },
357
+ {
358
+ path: "AidboxTopicDestination.kind",
359
+ min: 0,
360
+ max: "1",
361
+ type: [{ code: "string" }],
362
+ },
363
+ ],
364
+ },
365
+ };
366
+
367
+ const TOPIC_DEST_KAFKA_PROFILE = {
368
+ type: "AidboxTopicDestination",
369
+ url: "http://aidbox.app/StructureDefinition/aidboxtopicdestination-kafka-best-effort",
370
+ baseDefinition:
371
+ "http://aidbox.app/StructureDefinition/AidboxTopicDestination",
372
+ differential: {
373
+ element: [
374
+ {
375
+ path: "AidboxTopicDestination.kind",
376
+ fixedString: "kafka-best-effort",
377
+ },
378
+ {
379
+ path: "AidboxTopicDestination.parameter",
380
+ sliceName: "kafkaTopic",
381
+ min: 1,
382
+ max: "1",
383
+ },
384
+ {
385
+ path: "AidboxTopicDestination.parameter.name",
386
+ fixedString: "kafkaTopic",
387
+ },
388
+ {
389
+ path: "AidboxTopicDestination.parameter.value[x]",
390
+ type: [{ code: "string" }],
391
+ },
392
+ {
393
+ path: "AidboxTopicDestination.parameter",
394
+ sliceName: "bootstrapServers",
395
+ min: 1,
396
+ max: "1",
397
+ },
398
+ {
399
+ path: "AidboxTopicDestination.parameter.name",
400
+ fixedString: "bootstrapServers",
401
+ },
402
+ {
403
+ path: "AidboxTopicDestination.parameter.value[x]",
404
+ type: [{ code: "string" }],
405
+ },
406
+ {
407
+ path: "AidboxTopicDestination.parameter",
408
+ sliceName: "batchSize",
409
+ min: 0,
410
+ max: "1",
411
+ },
412
+ {
413
+ path: "AidboxTopicDestination.parameter.name",
414
+ fixedString: "batchSize",
415
+ },
416
+ {
417
+ path: "AidboxTopicDestination.parameter.value[x]",
418
+ type: [{ code: "integer" }],
419
+ },
420
+ ],
421
+ },
422
+ };
423
+
424
+ const RESOURCE_TYPE_LIST = [
425
+ { type: "Patient" },
426
+ { type: "Observation" },
427
+ { type: "Organization" },
428
+ { type: "Bundle" },
429
+ { type: "Parameters" },
430
+ { type: "AidboxTopicDestination" },
431
+ ];
432
+
433
+ const ALL_SDS: Record<string, typeof PATIENT_SD> = {
434
+ Patient: PATIENT_SD,
435
+ Observation: OBSERVATION_SD,
436
+ DomainResource: DOMAIN_RESOURCE_SD,
437
+ Resource: RESOURCE_SD,
438
+ HumanName: HUMAN_NAME_SD,
439
+ Reference: REFERENCE_SD,
440
+ Meta: META_SD,
441
+ Bundle: BUNDLE_SD,
442
+ Parameters: PARAMETERS_SD,
443
+ "http://hl7.org/fhir/StructureDefinition/Patient": PATIENT_SD,
444
+ "http://hl7.org/fhir/StructureDefinition/Observation": OBSERVATION_SD,
445
+ "http://hl7.org/fhir/StructureDefinition/DomainResource": DOMAIN_RESOURCE_SD,
446
+ "http://hl7.org/fhir/StructureDefinition/Resource": RESOURCE_SD,
447
+ "http://hl7.org/fhir/StructureDefinition/HumanName": HUMAN_NAME_SD,
448
+ "http://hl7.org/fhir/StructureDefinition/Reference": REFERENCE_SD,
449
+ "http://hl7.org/fhir/StructureDefinition/Meta": META_SD,
450
+ "http://hl7.org/fhir/StructureDefinition/Bundle": BUNDLE_SD,
451
+ "http://hl7.org/fhir/StructureDefinition/Parameters": PARAMETERS_SD,
452
+ "http://health-samurai.io/fhir/core/StructureDefinition/fhir-package-install-parameters":
453
+ INSTALL_PARAMS_PROFILE,
454
+ "http://example.com/StructureDefinition/typed-params": TYPED_PARAMS_PROFILE,
455
+ AidboxTopicDestination: TOPIC_DEST_SD,
456
+ "http://aidbox.app/StructureDefinition/AidboxTopicDestination": TOPIC_DEST_SD,
457
+ "http://aidbox.app/StructureDefinition/aidboxtopicdestination-kafka-best-effort":
458
+ TOPIC_DEST_KAFKA_PROFILE,
459
+ };
460
+
461
+ // ── Mock getSDs ────────────────────────────────────────────────────────
462
+
463
+ const mockGetSDs: GetStructureDefinitions = async (params) => {
464
+ if (params.kind === "resource" && params.derivation === "specialization") {
465
+ return RESOURCE_TYPE_LIST as (typeof PATIENT_SD)[];
466
+ }
467
+ if (params.url) {
468
+ const sd = ALL_SDS[params.url];
469
+ return sd ? [sd] : [];
470
+ }
471
+ if (params.type && params.derivation === "specialization") {
472
+ const sd = ALL_SDS[params.type];
473
+ return sd ? [sd] : [];
474
+ }
475
+ if (params.type && params["derivation:missing"] === "true") {
476
+ const sd = ALL_SDS[params.type];
477
+ return sd ? [sd] : [];
478
+ }
479
+ if (params.type === "Extension") {
480
+ return [];
481
+ }
482
+ return [];
483
+ };
484
+
485
+ const mockExpandValueSet: ExpandValueSet = async (url, _filter) => {
486
+ if (url === "http://hl7.org/fhir/ValueSet/administrative-gender") {
487
+ return [
488
+ { code: "male", display: "Male" },
489
+ { code: "female", display: "Female" },
490
+ { code: "other", display: "Other" },
491
+ { code: "unknown", display: "Unknown" },
492
+ ];
493
+ }
494
+ return [];
495
+ };
496
+
497
+ // ── Test helpers ───────────────────────────────────────────────────────
498
+
499
+ function completionAt(doc: string, marker = "|") {
500
+ const pos = doc.indexOf(marker);
501
+ const text = doc.slice(0, pos) + doc.slice(pos + 1);
502
+ const state = EditorState.create({ doc: text, extensions: [json()] });
503
+ const cc = new CompletionContext(state, pos, true);
504
+ return { state, cc, pos };
505
+ }
506
+
507
+ function labels(result: { options: { label: string }[] } | null): string[] {
508
+ return result?.options.map((o) => o.label) ?? [];
509
+ }
510
+
511
+ // ── Caches persist across tests — clear between describes ──────────────
512
+
513
+ // The SD cache is module-level in fhir-autocomplete.ts.
514
+ // Since we use consistent mock data, the cache doesn't cause issues.
515
+
516
+ // ── Tests ──────────────────────────────────────────────────────────────
517
+
518
+ describe("fhir-autocomplete: jsonCompletionSource", () => {
519
+ const source = jsonCompletionSource(
520
+ mockGetSDs,
521
+ undefined,
522
+ mockExpandValueSet,
523
+ );
524
+
525
+ describe("resourceType value completions", () => {
526
+ it("offers resource types in empty resourceType value", async () => {
527
+ const { cc } = completionAt('{\n "resourceType": "|\n}');
528
+ const result = await source(cc);
529
+ const l = labels(result);
530
+ expect(l).toContain("Patient");
531
+ expect(l).toContain("Observation");
532
+ expect(l).toContain("Organization");
533
+ });
534
+ });
535
+
536
+ describe("property completions", () => {
537
+ it("offers Patient fields when resourceType is set", async () => {
538
+ const { cc } = completionAt('{\n "resourceType": "Patient",\n |\n}');
539
+ const result = await source(cc);
540
+ const l = labels(result);
541
+ expect(l).toContain("name");
542
+ expect(l).toContain("gender");
543
+ expect(l).toContain("birthDate");
544
+ expect(l).toContain("managingOrganization");
545
+ });
546
+
547
+ it("offers resourceType when no resourceType is set", async () => {
548
+ const { cc } = completionAt("{\n |\n}");
549
+ const result = await source(cc);
550
+ const l = labels(result);
551
+ expect(l).toContain("resourceType");
552
+ });
553
+
554
+ it("offers primitive extensions (_birthDate)", async () => {
555
+ const { cc } = completionAt('{\n "resourceType": "Patient",\n |\n}');
556
+ const result = await source(cc);
557
+ const l = labels(result);
558
+ expect(l).toContain("_birthDate");
559
+ expect(l).toContain("_gender");
560
+ });
561
+
562
+ it("excludes properties already present in object", async () => {
563
+ const { cc } = completionAt(
564
+ '{\n "resourceType": "Patient",\n "gender": "male",\n |\n}',
565
+ );
566
+ const result = await source(cc);
567
+ const l = labels(result);
568
+ expect(l).toContain("name");
569
+ expect(l).toContain("birthDate");
570
+ expect(l).not.toContain("gender");
571
+ expect(l).not.toContain("resourceType");
572
+ });
573
+
574
+ it("does not offer property completions inside arrays", async () => {
575
+ const { cc } = completionAt(
576
+ '{\n "resourceType": "Patient",\n "name": [\n |\n ]\n}',
577
+ );
578
+ const result = await source(cc);
579
+ expect(result).toBe(null);
580
+ });
581
+ });
582
+
583
+ describe("property completions with resourceTypeHint", () => {
584
+ const hintSource = jsonCompletionSource(
585
+ mockGetSDs,
586
+ "Patient",
587
+ mockExpandValueSet,
588
+ );
589
+
590
+ it("uses hint when resourceType is not in document", async () => {
591
+ const { cc } = completionAt("{\n |\n}");
592
+ const result = await hintSource(cc);
593
+ const l = labels(result);
594
+ expect(l).toContain("name");
595
+ expect(l).toContain("gender");
596
+ });
597
+ });
598
+
599
+ describe("terminology binding completions", () => {
600
+ it("offers gender codes for Patient.gender", async () => {
601
+ const { cc } = completionAt(
602
+ '{\n "resourceType": "Patient",\n "gender": "|\n}',
603
+ );
604
+ const result = await source(cc);
605
+ const l = labels(result);
606
+ expect(l).toContain("male");
607
+ expect(l).toContain("female");
608
+ expect(l).toContain("other");
609
+ expect(l).toContain("unknown");
610
+ });
611
+ });
612
+
613
+ describe("boolean value completions", () => {
614
+ it("offers true and false for boolean fields", async () => {
615
+ const { cc } = completionAt(
616
+ '{\n "resourceType": "Patient",\n "active": |\n}',
617
+ );
618
+ const result = await source(cc);
619
+ const l = labels(result);
620
+ expect(l).toContain("true");
621
+ expect(l).toContain("false");
622
+ expect(l).toHaveLength(2);
623
+ });
624
+
625
+ it("offers property completions (not booleans) on new line after boolean value", async () => {
626
+ const { cc } = completionAt(
627
+ '{\n "resourceType": "Patient",\n "active": true,\n |\n}',
628
+ );
629
+ const result = await source(cc);
630
+ const l = labels(result);
631
+ expect(l).not.toContain("true");
632
+ expect(l).not.toContain("false");
633
+ expect(l).toContain("name");
634
+ expect(l).toContain("gender");
635
+ });
636
+ });
637
+
638
+ describe("reference target completions", () => {
639
+ it("offers Organization/ for Patient.managingOrganization.reference", async () => {
640
+ const { cc } = completionAt(
641
+ '{\n "resourceType": "Patient",\n "managingOrganization": {\n "reference": "|\n }\n}',
642
+ );
643
+ const result = await source(cc);
644
+ const l = labels(result);
645
+ expect(l).toContain("Organization/");
646
+ });
647
+
648
+ it("offers Patient/ and Group/ for Observation.subject.reference", async () => {
649
+ const { cc } = completionAt(
650
+ '{\n "resourceType": "Observation",\n "subject": {\n "reference": "|\n }\n}',
651
+ );
652
+ const result = await source(cc);
653
+ const l = labels(result);
654
+ expect(l).toContain("Patient/");
655
+ expect(l).toContain("Group/");
656
+ });
657
+ });
658
+
659
+ describe("contained resource completions", () => {
660
+ it("offers resourceType inside contained array item", async () => {
661
+ const { cc } = completionAt(
662
+ '{\n "resourceType": "Patient",\n "contained": [\n {\n |\n }\n ]\n}',
663
+ );
664
+ const result = await source(cc);
665
+ const l = labels(result);
666
+ expect(l).toContain("resourceType");
667
+ });
668
+
669
+ it("offers inner resource fields when contained has resourceType", async () => {
670
+ const { cc } = completionAt(
671
+ '{\n "resourceType": "Patient",\n "contained": [\n {\n "resourceType": "Observation",\n |\n }\n ]\n}',
672
+ );
673
+ const result = await source(cc);
674
+ const l = labels(result);
675
+ expect(l).toContain("status");
676
+ expect(l).toContain("code");
677
+ expect(l).toContain("subject");
678
+ // Should NOT contain Patient fields
679
+ expect(l).not.toContain("gender");
680
+ expect(l).not.toContain("birthDate");
681
+ });
682
+
683
+ it("offers correct reference targets for contained Observation.subject", async () => {
684
+ const { cc } = completionAt(
685
+ '{\n "resourceType": "Patient",\n "contained": [\n {\n "resourceType": "Observation",\n "subject": {\n "reference": "|\n }\n }\n ]\n}',
686
+ );
687
+ const result = await source(cc);
688
+ const l = labels(result);
689
+ expect(l).toContain("Patient/");
690
+ expect(l).toContain("Group/");
691
+ // Should NOT contain Organization/ (that's from Patient.managingOrganization)
692
+ expect(l).not.toContain("Organization/");
693
+ });
694
+ });
695
+
696
+ describe("Bundle.entry.resource completions", () => {
697
+ it("offers Observation fields inside entry.resource with explicit Bundle resourceType", async () => {
698
+ const { cc } = completionAt(
699
+ '{\n "resourceType": "Bundle",\n "entry": [\n {\n "resource": {\n "resourceType": "Observation",\n |\n }\n }\n ]\n}',
700
+ );
701
+ const result = await source(cc);
702
+ const l = labels(result);
703
+ expect(l).toContain("status");
704
+ expect(l).toContain("code");
705
+ expect(l).toContain("subject");
706
+ expect(l).not.toContain("type");
707
+ });
708
+
709
+ it("offers Observation fields when Bundle resourceType comes from hint (URL)", async () => {
710
+ const hintSource = jsonCompletionSource(
711
+ mockGetSDs,
712
+ "Bundle",
713
+ mockExpandValueSet,
714
+ );
715
+ const { cc } = completionAt(
716
+ '{\n "entry": [\n {\n "resource": {\n "resourceType": "Observation",\n |\n }\n }\n ]\n}',
717
+ );
718
+ const result = await hintSource(cc);
719
+ const l = labels(result);
720
+ expect(l).toContain("status");
721
+ expect(l).toContain("code");
722
+ expect(l).toContain("subject");
723
+ expect(l).not.toContain("type");
724
+ });
725
+ });
726
+
727
+ describe("nested object completions", () => {
728
+ it("offers HumanName fields inside name array item", async () => {
729
+ const { cc } = completionAt(
730
+ '{\n "resourceType": "Patient",\n "name": [\n {\n |\n }\n ]\n}',
731
+ );
732
+ const result = await source(cc);
733
+ const l = labels(result);
734
+ expect(l).toContain("family");
735
+ expect(l).toContain("given");
736
+ });
737
+
738
+ it("offers Reference fields inside managingOrganization", async () => {
739
+ const { cc } = completionAt(
740
+ '{\n "resourceType": "Patient",\n "managingOrganization": {\n |\n }\n}',
741
+ );
742
+ const result = await source(cc);
743
+ const l = labels(result);
744
+ expect(l).toContain("reference");
745
+ expect(l).toContain("display");
746
+ });
747
+ });
748
+
749
+ describe("Parameters completions", () => {
750
+ it("offers parameter fields inside parameter array item object", async () => {
751
+ const { cc } = completionAt(
752
+ '{\n "resourceType": "Parameters",\n "parameter": [\n {\n |\n }\n ]\n}',
753
+ );
754
+ const result = await source(cc);
755
+ const l = labels(result);
756
+ expect(l).toContain("name");
757
+ expect(l).toContain("valueString");
758
+ expect(l).toContain("valueBoolean");
759
+ expect(l).toContain("resource");
760
+ expect(l).toContain("part");
761
+ });
762
+
763
+ it("offers slice names for parameter.name from profile", async () => {
764
+ const { cc } = completionAt(
765
+ '{\n "resourceType": "Parameters",\n "meta": {\n "profile": ["http://health-samurai.io/fhir/core/StructureDefinition/fhir-package-install-parameters"]\n },\n "parameter": [\n {\n "name": "|\n }\n ]\n}',
766
+ );
767
+ const result = await source(cc);
768
+ const l = labels(result);
769
+ expect(l).toContain("package");
770
+ expect(l).toContain("registry");
771
+ });
772
+
773
+ it("offers parameter snippets in array-item position from profile", async () => {
774
+ const { cc } = completionAt(
775
+ '{\n "resourceType": "Parameters",\n "meta": {\n "profile": ["http://health-samurai.io/fhir/core/StructureDefinition/fhir-package-install-parameters"]\n },\n "parameter": [\n |\n ]\n}',
776
+ );
777
+ const result = await source(cc);
778
+ const l = labels(result);
779
+ expect(l).toContain("package");
780
+ expect(l).toContain("registry");
781
+ expect(l).toContain("parameter");
782
+ });
783
+
784
+ it("offers generic parameter template without profile", async () => {
785
+ const { cc } = completionAt(
786
+ '{\n "resourceType": "Parameters",\n "parameter": [\n |\n ]\n}',
787
+ );
788
+ const result = await source(cc);
789
+ expect(result).not.toBe(null);
790
+ const l = labels(result);
791
+ expect(l).toContain("parameter");
792
+ });
793
+
794
+ it("offers parameter fields for second array item", async () => {
795
+ const { cc } = completionAt(
796
+ '{\n "resourceType": "Parameters",\n "parameter": [\n {"name": "a", "valueString": "1"},\n {\n |\n }\n ]\n}',
797
+ );
798
+ const result = await source(cc);
799
+ const l = labels(result);
800
+ expect(l).toContain("name");
801
+ expect(l).toContain("valueString");
802
+ expect(l).not.toContain("parameter");
803
+ });
804
+
805
+ it("offers slice names for second array item name value", async () => {
806
+ const { cc } = completionAt(
807
+ '{\n "resourceType": "AidboxTopicDestination",\n "meta": {\n "profile": ["http://aidbox.app/StructureDefinition/aidboxtopicdestination-kafka-best-effort"]\n },\n "parameter": [\n {"name": "kafkaTopic", "valueString": "1"},\n {\n "name": "|\n }\n ]\n}',
808
+ );
809
+ const result = await source(cc);
810
+ const l = labels(result);
811
+ expect(l).toContain("bootstrapServers");
812
+ expect(l).toContain("batchSize");
813
+ });
814
+
815
+ it("offers part fields via contentReference", async () => {
816
+ const { cc } = completionAt(
817
+ '{\n "resourceType": "Parameters",\n "parameter": [\n {\n "name": "result",\n "part": [\n {\n |\n }\n ]\n }\n ]\n}',
818
+ );
819
+ const result = await source(cc);
820
+ const l = labels(result);
821
+ expect(l).toContain("name");
822
+ expect(l).toContain("valueString");
823
+ expect(l).toContain("part");
824
+ });
825
+
826
+ it("offers typed snippet for profile with value[x] constraint", async () => {
827
+ const typedSource = jsonCompletionSource(
828
+ mockGetSDs,
829
+ undefined,
830
+ mockExpandValueSet,
831
+ );
832
+ const { cc } = completionAt(
833
+ '{\n "resourceType": "Parameters",\n "meta": {\n "profile": ["http://example.com/StructureDefinition/typed-params"]\n },\n "parameter": [\n |\n ]\n}',
834
+ );
835
+ const result = await typedSource(cc);
836
+ const l = labels(result);
837
+ expect(l).toContain("count");
838
+ expect(l).toContain("label");
839
+ });
840
+
841
+ it("works for Parameters-derived types (AidboxTopicDestination)", async () => {
842
+ const { cc } = completionAt(
843
+ '{\n "resourceType": "AidboxTopicDestination",\n "meta": {\n "profile": ["http://aidbox.app/StructureDefinition/aidboxtopicdestination-kafka-best-effort"]\n },\n "parameter": [\n |\n ]\n}',
844
+ );
845
+ const result = await source(cc);
846
+ const l = labels(result);
847
+ expect(l).toContain("kafkaTopic");
848
+ expect(l).toContain("bootstrapServers");
849
+ expect(l).toContain("batchSize");
850
+ });
851
+
852
+ it("offers slice names for derived type parameter.name", async () => {
853
+ const { cc } = completionAt(
854
+ '{\n "resourceType": "AidboxTopicDestination",\n "meta": {\n "profile": ["http://aidbox.app/StructureDefinition/aidboxtopicdestination-kafka-best-effort"]\n },\n "parameter": [\n {\n "name": "|\n }\n ]\n}',
855
+ );
856
+ const result = await source(cc);
857
+ const l = labels(result);
858
+ expect(l).toContain("kafkaTopic");
859
+ expect(l).toContain("bootstrapServers");
860
+ expect(l).toContain("batchSize");
861
+ });
862
+
863
+ it("offers fixed value for profiled field", async () => {
864
+ const { cc } = completionAt(
865
+ '{\n "resourceType": "AidboxTopicDestination",\n "meta": {\n "profile": ["http://aidbox.app/StructureDefinition/aidboxtopicdestination-kafka-best-effort"]\n },\n "kind": "|\n}',
866
+ );
867
+ const result = await source(cc);
868
+ const l = labels(result);
869
+ expect(l).toContain("kafka-best-effort");
870
+ });
871
+
872
+ it("generic parameter snippet is offered with lowest boost", async () => {
873
+ const doc =
874
+ '{\n "resourceType": "Parameters",\n "parameter": [\n |\n ]\n}';
875
+ const { cc } = completionAt(doc);
876
+ const result = await source(cc);
877
+ const option = result?.options.find((o) => o.label === "parameter");
878
+ expect(option).toBeDefined();
879
+ expect(option?.boost).toBe(-1);
880
+ expect(option?.info).toBe("Custom parameter");
881
+ });
882
+ });
883
+
884
+ describe("HTTP mode", () => {
885
+ it("offers Patient fields in HTTP mode body", async () => {
886
+ const doc =
887
+ 'POST /fhir/Patient\nContent-Type: application/json\n\n{\n "resourceType": "Patient",\n |\n}';
888
+ const { cc } = completionAt(doc);
889
+ const result = await source(cc);
890
+ const l = labels(result);
891
+ expect(l).toContain("name");
892
+ expect(l).toContain("gender");
893
+ });
894
+
895
+ it("offers gender codes in HTTP mode body", async () => {
896
+ const doc =
897
+ 'PUT /fhir/Patient/1\n\n{\n "resourceType": "Patient",\n "gender": "|\n}';
898
+ const { cc } = completionAt(doc);
899
+ const result = await source(cc);
900
+ const l = labels(result);
901
+ expect(l).toContain("male");
902
+ expect(l).toContain("female");
903
+ });
904
+
905
+ it("offers Observation fields inside Bundle entry.resource via hint", async () => {
906
+ const hintSource = jsonCompletionSource(
907
+ mockGetSDs,
908
+ "Bundle",
909
+ mockExpandValueSet,
910
+ );
911
+ const doc =
912
+ 'POST /fhir/Bundle\nContent-Type: application/json\n\n{\n "entry": [\n {\n "resource": {\n "resourceType": "Observation",\n |\n }\n }\n ]\n}';
913
+ const { cc } = completionAt(doc);
914
+ const result = await hintSource(cc);
915
+ const l = labels(result);
916
+ expect(l).toContain("status");
917
+ expect(l).toContain("code");
918
+ expect(l).toContain("subject");
919
+ expect(l).not.toContain("type");
920
+ });
921
+ });
922
+ });
923
+
924
+ describe("buildParameterSnippet", () => {
925
+ it("inserts valueString by default when no value types", () => {
926
+ const { text, cursorOffset } = buildParameterSnippet("package", [], " ");
927
+ expect(text).toContain('"name": "package"');
928
+ expect(text).toContain('"valueString": ""');
929
+ // Cursor should be inside the empty valueString quotes
930
+ expect(text[cursorOffset - 1]).toBe('"');
931
+ expect(text[cursorOffset]).toBe('"');
932
+ });
933
+
934
+ it("inserts valueString for string-constrained type", () => {
935
+ const { text } = buildParameterSnippet("label", ["string"], " ");
936
+ expect(text).toContain('"name": "label"');
937
+ expect(text).toContain('"valueString": ""');
938
+ });
939
+
940
+ it("inserts valueCode for code-constrained type", () => {
941
+ const { text } = buildParameterSnippet("status", ["code"], " ");
942
+ expect(text).toContain('"name": "status"');
943
+ expect(text).toContain('"valueCode": ""');
944
+ });
945
+
946
+ it("inserts valueInteger for integer-constrained type", () => {
947
+ const { text, cursorOffset } = buildParameterSnippet(
948
+ "count",
949
+ ["integer"],
950
+ " ",
951
+ );
952
+ expect(text).toContain('"name": "count"');
953
+ expect(text).toContain('"valueInteger": ');
954
+ expect(text).not.toContain('"valueString"');
955
+ // Cursor should be after ": "
956
+ expect(text.slice(cursorOffset - 2, cursorOffset)).toBe(": ");
957
+ });
958
+
959
+ it("inserts valueBoolean for boolean-constrained type", () => {
960
+ const { text } = buildParameterSnippet("active", ["boolean"], " ");
961
+ expect(text).toContain('"name": "active"');
962
+ expect(text).toContain('"valueBoolean": ');
963
+ });
964
+
965
+ it("inserts complex object for CodeableConcept type", () => {
966
+ const { text } = buildParameterSnippet("code", ["CodeableConcept"], " ");
967
+ expect(text).toContain('"name": "code"');
968
+ expect(text).toContain('"valueCodeableConcept": {');
969
+ expect(text).toContain("}");
970
+ });
971
+
972
+ it("uses correct indentation", () => {
973
+ const { text } = buildParameterSnippet("test", [], " ");
974
+ const lines = text.split("\n");
975
+ // Line 0: {
976
+ expect(lines[0]).toBe("{");
977
+ // Line 1: inner indent + "name"
978
+ expect(lines[1]).toMatch(/^ {4}"name": "test",$/);
979
+ // Line 2: inner indent + "valueString"
980
+ expect(lines[2]).toMatch(/^ {4}"valueString": ""$/);
981
+ // Line 3: outer indent + }
982
+ expect(lines[3]).toBe(" }");
983
+ });
984
+
985
+ it("inserts empty name for generic template with cursor in name", () => {
986
+ const { text, cursorOffset } = buildParameterSnippet("", [], " ");
987
+ expect(text).toContain('"name": ""');
988
+ expect(text).toContain('"valueString": ""');
989
+ // Cursor should be inside the name quotes (first ""), not valueString
990
+ const nameQuoteIdx = text.indexOf('"name": ""') + '"name": "'.length;
991
+ expect(cursorOffset).toBe(nameQuoteIdx);
992
+ });
993
+ });