@databricks/appkit 0.12.0 → 0.12.2

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 (292) hide show
  1. package/CLAUDE.md +155 -147
  2. package/dist/appkit/package.js +1 -1
  3. package/dist/cli/commands/docs.js +80 -17
  4. package/dist/cli/commands/docs.js.map +1 -1
  5. package/dist/connectors/genie/client.js +2 -1
  6. package/dist/connectors/genie/client.js.map +1 -1
  7. package/dist/core/appkit.d.ts +30 -0
  8. package/dist/core/appkit.d.ts.map +1 -1
  9. package/dist/core/appkit.js +30 -0
  10. package/dist/core/appkit.js.map +1 -1
  11. package/dist/plugin/plugin.d.ts +20 -0
  12. package/dist/plugin/plugin.d.ts.map +1 -1
  13. package/dist/plugin/plugin.js +20 -0
  14. package/dist/plugin/plugin.js.map +1 -1
  15. package/docs/{docs/api → api}/appkit/Class.AppKitError.md +8 -8
  16. package/docs/{docs/api → api}/appkit/Class.AuthenticationError.md +9 -9
  17. package/docs/{docs/api → api}/appkit/Class.ConfigurationError.md +9 -9
  18. package/docs/{docs/api → api}/appkit/Class.ConnectionError.md +9 -9
  19. package/docs/{docs/api → api}/appkit/Class.ExecutionError.md +9 -9
  20. package/docs/{docs/api → api}/appkit/Class.InitializationError.md +9 -9
  21. package/docs/{docs/api → api}/appkit/Class.Plugin.md +22 -2
  22. package/docs/{docs/api → api}/appkit/Class.ResourceRegistry.md +11 -11
  23. package/docs/{docs/api → api}/appkit/Class.ServerError.md +9 -9
  24. package/docs/{docs/api → api}/appkit/Class.TunnelError.md +9 -9
  25. package/docs/{docs/api → api}/appkit/Class.ValidationError.md +9 -9
  26. package/docs/{docs/api → api}/appkit/Function.createApp.md +32 -3
  27. package/docs/{docs/api → api}/appkit/Function.createLakebasePool.md +1 -1
  28. package/docs/{docs/api → api}/appkit/Function.generateDatabaseCredential.md +2 -2
  29. package/docs/{docs/api → api}/appkit/Function.getLakebaseOrmConfig.md +1 -1
  30. package/docs/{docs/api → api}/appkit/Function.getLakebasePgConfig.md +1 -1
  31. package/docs/{docs/api → api}/appkit/Function.getPluginManifest.md +1 -1
  32. package/docs/{docs/api → api}/appkit/Function.getUsernameWithApiLookup.md +1 -1
  33. package/docs/{docs/api → api}/appkit/Function.getWorkspaceClient.md +1 -1
  34. package/docs/{docs/api → api}/appkit/Interface.ResourceEntry.md +8 -8
  35. package/docs/{docs/api → api}/appkit/Interface.ResourceRequirement.md +1 -1
  36. package/docs/{docs/api → api}/appkit-ui/styling.md +1 -1
  37. package/docs/{docs/api → api}/appkit-ui/ui/Sidebar.md +304 -37
  38. package/docs/api/appkit.md +78 -0
  39. package/docs/{docs/api.md → api.md} +4 -4
  40. package/docs/{docs/app-management.md → app-management.md} +2 -2
  41. package/docs/{docs/architecture.md → architecture.md} +6 -6
  42. package/docs/{docs/configuration.md → configuration.md} +2 -2
  43. package/docs/development/ai-assisted-development.md +88 -0
  44. package/docs/{docs/development → development}/llm-guide.md +8 -7
  45. package/docs/{docs/development → development}/local-development.md +2 -2
  46. package/docs/{docs/development → development}/project-setup.md +11 -11
  47. package/docs/{docs/development → development}/remote-bridge.md +1 -1
  48. package/docs/{docs/development → development}/type-generation.md +2 -2
  49. package/docs/development.md +22 -0
  50. package/docs/plugins/analytics.md +169 -0
  51. package/docs/{docs/plugins → plugins}/custom-plugins.md +6 -6
  52. package/docs/{docs/plugins → plugins}/server.md +1 -1
  53. package/docs/{docs/plugins.md → plugins.md} +2 -2
  54. package/{docs/docs.md → docs.md} +36 -5
  55. package/llms.txt +155 -147
  56. package/package.json +2 -1
  57. package/docs/docs/api/appkit/Class.AppKitError/index.html +0 -79
  58. package/docs/docs/api/appkit/Class.AuthenticationError/index.html +0 -110
  59. package/docs/docs/api/appkit/Class.ConfigurationError/index.html +0 -112
  60. package/docs/docs/api/appkit/Class.ConnectionError/index.html +0 -120
  61. package/docs/docs/api/appkit/Class.ExecutionError/index.html +0 -116
  62. package/docs/docs/api/appkit/Class.InitializationError/index.html +0 -104
  63. package/docs/docs/api/appkit/Class.Plugin/index.html +0 -168
  64. package/docs/docs/api/appkit/Class.ResourceRegistry/index.html +0 -150
  65. package/docs/docs/api/appkit/Class.ServerError/index.html +0 -108
  66. package/docs/docs/api/appkit/Class.TunnelError/index.html +0 -108
  67. package/docs/docs/api/appkit/Class.ValidationError/index.html +0 -106
  68. package/docs/docs/api/appkit/Enumeration.RequestedClaimsPermissionSet/index.html +0 -21
  69. package/docs/docs/api/appkit/Enumeration.ResourceType/index.html +0 -53
  70. package/docs/docs/api/appkit/Function.appKitTypesPlugin/index.html +0 -24
  71. package/docs/docs/api/appkit/Function.createApp/index.html +0 -24
  72. package/docs/docs/api/appkit/Function.createLakebasePool/index.html +0 -24
  73. package/docs/docs/api/appkit/Function.generateDatabaseCredential/index.html +0 -30
  74. package/docs/docs/api/appkit/Function.getExecutionContext/index.html +0 -26
  75. package/docs/docs/api/appkit/Function.getLakebaseOrmConfig/index.html +0 -39
  76. package/docs/docs/api/appkit/Function.getLakebasePgConfig/index.html +0 -27
  77. package/docs/docs/api/appkit/Function.getPluginManifest/index.html +0 -26
  78. package/docs/docs/api/appkit/Function.getResourceRequirements/index.html +0 -28
  79. package/docs/docs/api/appkit/Function.getUsernameWithApiLookup/index.html +0 -35
  80. package/docs/docs/api/appkit/Function.getWorkspaceClient/index.html +0 -22
  81. package/docs/docs/api/appkit/Function.isSQLTypeMarker/index.html +0 -25
  82. package/docs/docs/api/appkit/Interface.BasePluginConfig/index.html +0 -28
  83. package/docs/docs/api/appkit/Interface.CacheConfig/index.html +0 -63
  84. package/docs/docs/api/appkit/Interface.DatabaseCredential/index.html +0 -28
  85. package/docs/docs/api/appkit/Interface.GenerateDatabaseCredentialRequest/index.html +0 -32
  86. package/docs/docs/api/appkit/Interface.ITelemetry/index.html +0 -73
  87. package/docs/docs/api/appkit/Interface.LakebasePoolConfig/index.html +0 -75
  88. package/docs/docs/api/appkit/Interface.PluginManifest/index.html +0 -67
  89. package/docs/docs/api/appkit/Interface.RequestedClaims/index.html +0 -26
  90. package/docs/docs/api/appkit/Interface.RequestedResource/index.html +0 -27
  91. package/docs/docs/api/appkit/Interface.ResourceEntry/index.html +0 -83
  92. package/docs/docs/api/appkit/Interface.ResourceFieldEntry/index.html +0 -26
  93. package/docs/docs/api/appkit/Interface.ResourceRequirement/index.html +0 -51
  94. package/docs/docs/api/appkit/Interface.StreamExecutionSettings/index.html +0 -26
  95. package/docs/docs/api/appkit/Interface.TelemetryConfig/index.html +0 -32
  96. package/docs/docs/api/appkit/Interface.ValidationResult/index.html +0 -29
  97. package/docs/docs/api/appkit/TypeAlias.ConfigSchema/index.html +0 -21
  98. package/docs/docs/api/appkit/TypeAlias.IAppRouter/index.html +0 -18
  99. package/docs/docs/api/appkit/TypeAlias.ResourcePermission/index.html +0 -18
  100. package/docs/docs/api/appkit/TypeAlias.ToPlugin/index.html +0 -23
  101. package/docs/docs/api/appkit/Variable.sql/index.html +0 -98
  102. package/docs/docs/api/appkit/index.html +0 -30
  103. package/docs/docs/api/appkit-ui/data/AreaChart/index.html +0 -29
  104. package/docs/docs/api/appkit-ui/data/BarChart/index.html +0 -29
  105. package/docs/docs/api/appkit-ui/data/DataTable/index.html +0 -36
  106. package/docs/docs/api/appkit-ui/data/DonutChart/index.html +0 -29
  107. package/docs/docs/api/appkit-ui/data/HeatmapChart/index.html +0 -35
  108. package/docs/docs/api/appkit-ui/data/LineChart/index.html +0 -29
  109. package/docs/docs/api/appkit-ui/data/PieChart/index.html +0 -29
  110. package/docs/docs/api/appkit-ui/data/RadarChart/index.html +0 -29
  111. package/docs/docs/api/appkit-ui/data/ScatterChart/index.html +0 -29
  112. package/docs/docs/api/appkit-ui/genie/GenieChat/index.html +0 -26
  113. package/docs/docs/api/appkit-ui/genie/GenieChatInput/index.html +0 -24
  114. package/docs/docs/api/appkit-ui/genie/GenieChatMessage/index.html +0 -24
  115. package/docs/docs/api/appkit-ui/genie/GenieChatMessageList/index.html +0 -24
  116. package/docs/docs/api/appkit-ui/index.html +0 -23
  117. package/docs/docs/api/appkit-ui/styling/index.html +0 -74
  118. package/docs/docs/api/appkit-ui/ui/Accordion/index.html +0 -48
  119. package/docs/docs/api/appkit-ui/ui/Alert/index.html +0 -41
  120. package/docs/docs/api/appkit-ui/ui/AlertDialog/index.html +0 -97
  121. package/docs/docs/api/appkit-ui/ui/AspectRatio/index.html +0 -27
  122. package/docs/docs/api/appkit-ui/ui/Avatar/index.html +0 -41
  123. package/docs/docs/api/appkit-ui/ui/Badge/index.html +0 -27
  124. package/docs/docs/api/appkit-ui/ui/Breadcrumb/index.html +0 -69
  125. package/docs/docs/api/appkit-ui/ui/Button/index.html +0 -27
  126. package/docs/docs/api/appkit-ui/ui/ButtonGroup/index.html +0 -38
  127. package/docs/docs/api/appkit-ui/ui/Calendar/index.html +0 -34
  128. package/docs/docs/api/appkit-ui/ui/Card/index.html +0 -69
  129. package/docs/docs/api/appkit-ui/ui/Carousel/index.html +0 -55
  130. package/docs/docs/api/appkit-ui/ui/ChartContainer/index.html +0 -58
  131. package/docs/docs/api/appkit-ui/ui/Checkbox/index.html +0 -27
  132. package/docs/docs/api/appkit-ui/ui/Collapsible/index.html +0 -41
  133. package/docs/docs/api/appkit-ui/ui/Command/index.html +0 -83
  134. package/docs/docs/api/appkit-ui/ui/ContextMenu/index.html +0 -111
  135. package/docs/docs/api/appkit-ui/ui/Dialog/index.html +0 -90
  136. package/docs/docs/api/appkit-ui/ui/Drawer/index.html +0 -90
  137. package/docs/docs/api/appkit-ui/ui/DropdownMenu/index.html +0 -111
  138. package/docs/docs/api/appkit-ui/ui/Empty/index.html +0 -54
  139. package/docs/docs/api/appkit-ui/ui/Field/index.html +0 -87
  140. package/docs/docs/api/appkit-ui/ui/FormControl/index.html +0 -59
  141. package/docs/docs/api/appkit-ui/ui/HoverCard/index.html +0 -39
  142. package/docs/docs/api/appkit-ui/ui/Input/index.html +0 -27
  143. package/docs/docs/api/appkit-ui/ui/InputGroup/index.html +0 -59
  144. package/docs/docs/api/appkit-ui/ui/InputOTP/index.html +0 -48
  145. package/docs/docs/api/appkit-ui/ui/Item/index.html +0 -78
  146. package/docs/docs/api/appkit-ui/ui/Kbd/index.html +0 -30
  147. package/docs/docs/api/appkit-ui/ui/Label/index.html +0 -27
  148. package/docs/docs/api/appkit-ui/ui/Menubar/index.html +0 -117
  149. package/docs/docs/api/appkit-ui/ui/NavigationMenu/index.html +0 -76
  150. package/docs/docs/api/appkit-ui/ui/Pagination/index.html +0 -69
  151. package/docs/docs/api/appkit-ui/ui/Popover/index.html +0 -45
  152. package/docs/docs/api/appkit-ui/ui/Progress/index.html +0 -27
  153. package/docs/docs/api/appkit-ui/ui/RadioGroup/index.html +0 -33
  154. package/docs/docs/api/appkit-ui/ui/ResizableHandle/index.html +0 -41
  155. package/docs/docs/api/appkit-ui/ui/ScrollArea/index.html +0 -34
  156. package/docs/docs/api/appkit-ui/ui/Select/index.html +0 -82
  157. package/docs/docs/api/appkit-ui/ui/Separator/index.html +0 -27
  158. package/docs/docs/api/appkit-ui/ui/Sheet/index.html +0 -76
  159. package/docs/docs/api/appkit-ui/ui/Sidebar/index.html +0 -183
  160. package/docs/docs/api/appkit-ui/ui/Skeleton/index.html +0 -27
  161. package/docs/docs/api/appkit-ui/ui/Slider/index.html +0 -27
  162. package/docs/docs/api/appkit-ui/ui/Spinner/index.html +0 -24
  163. package/docs/docs/api/appkit-ui/ui/Switch/index.html +0 -27
  164. package/docs/docs/api/appkit-ui/ui/Table/index.html +0 -69
  165. package/docs/docs/api/appkit-ui/ui/Tabs/index.html +0 -48
  166. package/docs/docs/api/appkit-ui/ui/Textarea/index.html +0 -27
  167. package/docs/docs/api/appkit-ui/ui/Toaster/index.html +0 -27
  168. package/docs/docs/api/appkit-ui/ui/Toggle/index.html +0 -27
  169. package/docs/docs/api/appkit-ui/ui/ToggleGroup/index.html +0 -33
  170. package/docs/docs/api/appkit-ui/ui/Tooltip/index.html +0 -46
  171. package/docs/docs/api/appkit.md +0 -78
  172. package/docs/docs/api/index.html +0 -28
  173. package/docs/docs/app-management/index.html +0 -106
  174. package/docs/docs/architecture/index.html +0 -71
  175. package/docs/docs/category/development/index.html +0 -16
  176. package/docs/docs/category/development.md +0 -3
  177. package/docs/docs/configuration/index.html +0 -66
  178. package/docs/docs/core-principles/index.html +0 -38
  179. package/docs/docs/development/ai-assisted-development/index.html +0 -33
  180. package/docs/docs/development/ai-assisted-development.md +0 -26
  181. package/docs/docs/development/index.html +0 -35
  182. package/docs/docs/development/llm-guide/index.html +0 -84
  183. package/docs/docs/development/local-development/index.html +0 -27
  184. package/docs/docs/development/project-setup/index.html +0 -69
  185. package/docs/docs/development/remote-bridge/index.html +0 -76
  186. package/docs/docs/development/type-generation/index.html +0 -65
  187. package/docs/docs/development.md +0 -22
  188. package/docs/docs/index.html +0 -58
  189. package/docs/docs/plugins/analytics/index.html +0 -53
  190. package/docs/docs/plugins/analytics.md +0 -66
  191. package/docs/docs/plugins/caching/index.html +0 -23
  192. package/docs/docs/plugins/custom-plugins/index.html +0 -49
  193. package/docs/docs/plugins/execution-context/index.html +0 -40
  194. package/docs/docs/plugins/index.html +0 -29
  195. package/docs/docs/plugins/lakebase/index.html +0 -62
  196. package/docs/docs/plugins/plugin-management/index.html +0 -44
  197. package/docs/docs/plugins/server/index.html +0 -45
  198. /package/docs/{docs/api → api}/appkit/Enumeration.RequestedClaimsPermissionSet.md +0 -0
  199. /package/docs/{docs/api → api}/appkit/Enumeration.ResourceType.md +0 -0
  200. /package/docs/{docs/api → api}/appkit/Function.appKitTypesPlugin.md +0 -0
  201. /package/docs/{docs/api → api}/appkit/Function.getExecutionContext.md +0 -0
  202. /package/docs/{docs/api → api}/appkit/Function.getResourceRequirements.md +0 -0
  203. /package/docs/{docs/api → api}/appkit/Function.isSQLTypeMarker.md +0 -0
  204. /package/docs/{docs/api → api}/appkit/Interface.BasePluginConfig.md +0 -0
  205. /package/docs/{docs/api → api}/appkit/Interface.CacheConfig.md +0 -0
  206. /package/docs/{docs/api → api}/appkit/Interface.DatabaseCredential.md +0 -0
  207. /package/docs/{docs/api → api}/appkit/Interface.GenerateDatabaseCredentialRequest.md +0 -0
  208. /package/docs/{docs/api → api}/appkit/Interface.ITelemetry.md +0 -0
  209. /package/docs/{docs/api → api}/appkit/Interface.LakebasePoolConfig.md +0 -0
  210. /package/docs/{docs/api → api}/appkit/Interface.PluginManifest.md +0 -0
  211. /package/docs/{docs/api → api}/appkit/Interface.RequestedClaims.md +0 -0
  212. /package/docs/{docs/api → api}/appkit/Interface.RequestedResource.md +0 -0
  213. /package/docs/{docs/api → api}/appkit/Interface.ResourceFieldEntry.md +0 -0
  214. /package/docs/{docs/api → api}/appkit/Interface.StreamExecutionSettings.md +0 -0
  215. /package/docs/{docs/api → api}/appkit/Interface.TelemetryConfig.md +0 -0
  216. /package/docs/{docs/api → api}/appkit/Interface.ValidationResult.md +0 -0
  217. /package/docs/{docs/api → api}/appkit/TypeAlias.ConfigSchema.md +0 -0
  218. /package/docs/{docs/api → api}/appkit/TypeAlias.IAppRouter.md +0 -0
  219. /package/docs/{docs/api → api}/appkit/TypeAlias.ResourcePermission.md +0 -0
  220. /package/docs/{docs/api → api}/appkit/TypeAlias.ToPlugin.md +0 -0
  221. /package/docs/{docs/api → api}/appkit/Variable.sql.md +0 -0
  222. /package/docs/{docs/api → api}/appkit-ui/data/AreaChart.md +0 -0
  223. /package/docs/{docs/api → api}/appkit-ui/data/BarChart.md +0 -0
  224. /package/docs/{docs/api → api}/appkit-ui/data/DataTable.md +0 -0
  225. /package/docs/{docs/api → api}/appkit-ui/data/DonutChart.md +0 -0
  226. /package/docs/{docs/api → api}/appkit-ui/data/HeatmapChart.md +0 -0
  227. /package/docs/{docs/api → api}/appkit-ui/data/LineChart.md +0 -0
  228. /package/docs/{docs/api → api}/appkit-ui/data/PieChart.md +0 -0
  229. /package/docs/{docs/api → api}/appkit-ui/data/RadarChart.md +0 -0
  230. /package/docs/{docs/api → api}/appkit-ui/data/ScatterChart.md +0 -0
  231. /package/docs/{docs/api → api}/appkit-ui/genie/GenieChat.md +0 -0
  232. /package/docs/{docs/api → api}/appkit-ui/genie/GenieChatInput.md +0 -0
  233. /package/docs/{docs/api → api}/appkit-ui/genie/GenieChatMessage.md +0 -0
  234. /package/docs/{docs/api → api}/appkit-ui/genie/GenieChatMessageList.md +0 -0
  235. /package/docs/{docs/api → api}/appkit-ui/ui/Accordion.md +0 -0
  236. /package/docs/{docs/api → api}/appkit-ui/ui/Alert.md +0 -0
  237. /package/docs/{docs/api → api}/appkit-ui/ui/AlertDialog.md +0 -0
  238. /package/docs/{docs/api → api}/appkit-ui/ui/AspectRatio.md +0 -0
  239. /package/docs/{docs/api → api}/appkit-ui/ui/Avatar.md +0 -0
  240. /package/docs/{docs/api → api}/appkit-ui/ui/Badge.md +0 -0
  241. /package/docs/{docs/api → api}/appkit-ui/ui/Breadcrumb.md +0 -0
  242. /package/docs/{docs/api → api}/appkit-ui/ui/Button.md +0 -0
  243. /package/docs/{docs/api → api}/appkit-ui/ui/ButtonGroup.md +0 -0
  244. /package/docs/{docs/api → api}/appkit-ui/ui/Calendar.md +0 -0
  245. /package/docs/{docs/api → api}/appkit-ui/ui/Card.md +0 -0
  246. /package/docs/{docs/api → api}/appkit-ui/ui/Carousel.md +0 -0
  247. /package/docs/{docs/api → api}/appkit-ui/ui/ChartContainer.md +0 -0
  248. /package/docs/{docs/api → api}/appkit-ui/ui/Checkbox.md +0 -0
  249. /package/docs/{docs/api → api}/appkit-ui/ui/Collapsible.md +0 -0
  250. /package/docs/{docs/api → api}/appkit-ui/ui/Command.md +0 -0
  251. /package/docs/{docs/api → api}/appkit-ui/ui/ContextMenu.md +0 -0
  252. /package/docs/{docs/api → api}/appkit-ui/ui/Dialog.md +0 -0
  253. /package/docs/{docs/api → api}/appkit-ui/ui/Drawer.md +0 -0
  254. /package/docs/{docs/api → api}/appkit-ui/ui/DropdownMenu.md +0 -0
  255. /package/docs/{docs/api → api}/appkit-ui/ui/Empty.md +0 -0
  256. /package/docs/{docs/api → api}/appkit-ui/ui/Field.md +0 -0
  257. /package/docs/{docs/api → api}/appkit-ui/ui/FormControl.md +0 -0
  258. /package/docs/{docs/api → api}/appkit-ui/ui/HoverCard.md +0 -0
  259. /package/docs/{docs/api → api}/appkit-ui/ui/Input.md +0 -0
  260. /package/docs/{docs/api → api}/appkit-ui/ui/InputGroup.md +0 -0
  261. /package/docs/{docs/api → api}/appkit-ui/ui/InputOTP.md +0 -0
  262. /package/docs/{docs/api → api}/appkit-ui/ui/Item.md +0 -0
  263. /package/docs/{docs/api → api}/appkit-ui/ui/Kbd.md +0 -0
  264. /package/docs/{docs/api → api}/appkit-ui/ui/Label.md +0 -0
  265. /package/docs/{docs/api → api}/appkit-ui/ui/Menubar.md +0 -0
  266. /package/docs/{docs/api → api}/appkit-ui/ui/NavigationMenu.md +0 -0
  267. /package/docs/{docs/api → api}/appkit-ui/ui/Pagination.md +0 -0
  268. /package/docs/{docs/api → api}/appkit-ui/ui/Popover.md +0 -0
  269. /package/docs/{docs/api → api}/appkit-ui/ui/Progress.md +0 -0
  270. /package/docs/{docs/api → api}/appkit-ui/ui/RadioGroup.md +0 -0
  271. /package/docs/{docs/api → api}/appkit-ui/ui/ResizableHandle.md +0 -0
  272. /package/docs/{docs/api → api}/appkit-ui/ui/ScrollArea.md +0 -0
  273. /package/docs/{docs/api → api}/appkit-ui/ui/Select.md +0 -0
  274. /package/docs/{docs/api → api}/appkit-ui/ui/Separator.md +0 -0
  275. /package/docs/{docs/api → api}/appkit-ui/ui/Sheet.md +0 -0
  276. /package/docs/{docs/api → api}/appkit-ui/ui/Skeleton.md +0 -0
  277. /package/docs/{docs/api → api}/appkit-ui/ui/Slider.md +0 -0
  278. /package/docs/{docs/api → api}/appkit-ui/ui/Spinner.md +0 -0
  279. /package/docs/{docs/api → api}/appkit-ui/ui/Switch.md +0 -0
  280. /package/docs/{docs/api → api}/appkit-ui/ui/Table.md +0 -0
  281. /package/docs/{docs/api → api}/appkit-ui/ui/Tabs.md +0 -0
  282. /package/docs/{docs/api → api}/appkit-ui/ui/Textarea.md +0 -0
  283. /package/docs/{docs/api → api}/appkit-ui/ui/Toaster.md +0 -0
  284. /package/docs/{docs/api → api}/appkit-ui/ui/Toggle.md +0 -0
  285. /package/docs/{docs/api → api}/appkit-ui/ui/ToggleGroup.md +0 -0
  286. /package/docs/{docs/api → api}/appkit-ui/ui/Tooltip.md +0 -0
  287. /package/docs/{docs/api → api}/appkit-ui.md +0 -0
  288. /package/docs/{docs/core-principles.md → core-principles.md} +0 -0
  289. /package/docs/{docs/plugins → plugins}/caching.md +0 -0
  290. /package/docs/{docs/plugins → plugins}/execution-context.md +0 -0
  291. /package/docs/{docs/plugins → plugins}/lakebase.md +0 -0
  292. /package/docs/{docs/plugins → plugins}/plugin-management.md +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","names":[],"sources":["../../../src/connectors/genie/client.ts"],"sourcesContent":["import type { WorkspaceClient } from \"@databricks/sdk-experimental\";\nimport { Time, TimeUnits } from \"@databricks/sdk-experimental\";\nimport type { GenieMessage } from \"@databricks/sdk-experimental/dist/apis/dashboards\";\nimport type { Waiter } from \"@databricks/sdk-experimental/dist/wait\";\nimport { createLogger } from \"../../logging\";\nimport { genieConnectorDefaults } from \"./defaults\";\nimport { pollWaiter } from \"./poll-waiter\";\nimport type {\n GenieAttachmentResponse,\n GenieConversationHistoryResponse,\n GenieMessageResponse,\n GenieStreamEvent,\n} from \"./types\";\n\nconst logger = createLogger(\"connectors:genie\");\n\ntype CreateMessageWaiter = Waiter<GenieMessage, GenieMessage>;\n\nexport interface GenieConnectorConfig {\n timeout?: number;\n maxMessages?: number;\n}\n\nfunction mapAttachments(message: GenieMessage): GenieAttachmentResponse[] {\n return (\n message.attachments?.map((att) => ({\n attachmentId: att.attachment_id,\n query: att.query\n ? {\n title: att.query.title,\n description: att.query.description,\n query: att.query.query,\n statementId: att.query.statement_id,\n }\n : undefined,\n text: att.text ? { content: att.text.content } : undefined,\n suggestedQuestions: att.suggested_questions?.questions,\n })) ?? []\n );\n}\n\nfunction toMessageResponse(message: GenieMessage): GenieMessageResponse {\n return {\n messageId: message.message_id,\n conversationId: message.conversation_id,\n spaceId: message.space_id,\n status: message.status ?? \"COMPLETED\",\n content: message.content,\n attachments: mapAttachments(message),\n error: message.error?.error,\n };\n}\n\nexport class GenieConnector {\n private readonly config: Required<GenieConnectorConfig>;\n\n constructor(config: GenieConnectorConfig = {}) {\n this.config = {\n timeout: config.timeout ?? genieConnectorDefaults.timeout,\n maxMessages: config.maxMessages ?? genieConnectorDefaults.maxMessages,\n };\n }\n\n async startMessage(\n workspaceClient: WorkspaceClient,\n spaceId: string,\n content: string,\n conversationId: string | undefined,\n ): Promise<{\n messageWaiter: CreateMessageWaiter;\n conversationId: string;\n messageId: string;\n }> {\n if (conversationId) {\n const waiter = await workspaceClient.genie.createMessage({\n space_id: spaceId,\n conversation_id: conversationId,\n content,\n });\n return {\n messageWaiter: waiter,\n conversationId,\n messageId: waiter.message_id ?? \"\",\n };\n }\n const start = await workspaceClient.genie.startConversation({\n space_id: spaceId,\n content,\n });\n return {\n messageWaiter: start as unknown as CreateMessageWaiter,\n conversationId: start.conversation_id,\n messageId: start.message_id,\n };\n }\n\n async waitForMessage(\n messageWaiter: CreateMessageWaiter,\n options?: { timeout?: number },\n ): Promise<GenieMessage> {\n const timeout = options?.timeout ?? this.config.timeout;\n const waitOptions =\n timeout > 0 ? { timeout: new Time(timeout, TimeUnits.milliseconds) } : {};\n return messageWaiter.wait(waitOptions);\n }\n\n async listConversationMessages(\n workspaceClient: WorkspaceClient,\n spaceId: string,\n conversationId: string,\n options?: { maxMessages?: number },\n ): Promise<GenieMessageResponse[]> {\n const maxMessages = options?.maxMessages ?? this.config.maxMessages;\n const allMessages: GenieMessage[] = [];\n let pageToken: string | undefined;\n\n do {\n const response = await workspaceClient.genie.listConversationMessages({\n space_id: spaceId,\n conversation_id: conversationId,\n page_size: genieConnectorDefaults.pageSize,\n ...(pageToken ? { page_token: pageToken } : {}),\n });\n\n if (response.messages) {\n allMessages.push(...response.messages);\n }\n\n pageToken = response.next_page_token;\n } while (pageToken && allMessages.length < maxMessages);\n\n return allMessages.slice(0, maxMessages).reverse().map(toMessageResponse);\n }\n\n async getMessageAttachmentQueryResult(\n workspaceClient: WorkspaceClient,\n spaceId: string,\n conversationId: string,\n messageId: string,\n attachmentId: string,\n _signal?: AbortSignal,\n ): Promise<unknown> {\n const response =\n await workspaceClient.genie.getMessageAttachmentQueryResult({\n space_id: spaceId,\n conversation_id: conversationId,\n message_id: messageId,\n attachment_id: attachmentId,\n });\n return response.statement_response;\n }\n\n async *streamSendMessage(\n workspaceClient: WorkspaceClient,\n spaceId: string,\n content: string,\n conversationId: string | undefined,\n options?: { timeout?: number },\n ): AsyncGenerator<GenieStreamEvent> {\n try {\n const {\n messageWaiter,\n conversationId: resultConversationId,\n messageId: resultMessageId,\n } = await this.startMessage(\n workspaceClient,\n spaceId,\n content,\n conversationId,\n );\n\n yield {\n type: \"message_start\",\n conversationId: resultConversationId,\n messageId: resultMessageId,\n spaceId,\n };\n\n const timeout =\n options?.timeout != null ? options.timeout : this.config.timeout;\n const waitOptions =\n timeout > 0\n ? { timeout: new Time(timeout, TimeUnits.milliseconds) }\n : {};\n\n let completedMessage!: GenieMessage;\n for await (const event of pollWaiter(messageWaiter, waitOptions)) {\n if (event.type === \"progress\" && event.value.status) {\n yield { type: \"status\", status: event.value.status };\n } else if (event.type === \"completed\") {\n completedMessage = event.value;\n }\n }\n\n const messageResponse = toMessageResponse(completedMessage);\n yield { type: \"message_result\", message: messageResponse };\n\n yield* this.emitQueryResults(\n workspaceClient,\n spaceId,\n resultConversationId,\n messageResponse.messageId,\n messageResponse,\n );\n } catch (error) {\n logger.error(\"Genie message error: %O\", error);\n yield {\n type: \"error\",\n error: error instanceof Error ? error.message : \"Genie request failed\",\n };\n }\n }\n\n private async *emitQueryResults(\n workspaceClient: WorkspaceClient,\n spaceId: string,\n conversationId: string,\n messageId: string,\n messageResponse: GenieMessageResponse,\n ): AsyncGenerator<\n Extract<GenieStreamEvent, { type: \"query_result\" } | { type: \"error\" }>\n > {\n const attachments = messageResponse.attachments ?? [];\n for (const att of attachments) {\n if (!att.query?.statementId || !att.attachmentId) continue;\n try {\n const data = await this.getMessageAttachmentQueryResult(\n workspaceClient,\n spaceId,\n conversationId,\n messageId,\n att.attachmentId,\n );\n yield {\n type: \"query_result\",\n attachmentId: att.attachmentId,\n statementId: att.query.statementId,\n data,\n };\n } catch (error) {\n logger.error(\n \"Failed to fetch query result for attachment %s: %O\",\n att.attachmentId,\n error,\n );\n yield {\n type: \"error\",\n error: `Failed to fetch query result for attachment ${att.attachmentId}`,\n };\n }\n }\n }\n\n async *streamConversation(\n workspaceClient: WorkspaceClient,\n spaceId: string,\n conversationId: string,\n options?: { includeQueryResults?: boolean },\n ): AsyncGenerator<GenieStreamEvent> {\n const includeQueryResults = options?.includeQueryResults !== false;\n\n try {\n const messageResponses = await this.listConversationMessages(\n workspaceClient,\n spaceId,\n conversationId,\n );\n\n for (const messageResponse of messageResponses) {\n yield { type: \"message_result\", message: messageResponse };\n }\n\n if (includeQueryResults) {\n const queryAttachments: Array<{\n messageId: string;\n attachmentId: string;\n statementId: string;\n }> = [];\n\n for (const msg of messageResponses) {\n for (const att of msg.attachments ?? []) {\n if (att.query?.statementId && att.attachmentId) {\n queryAttachments.push({\n messageId: msg.messageId,\n attachmentId: att.attachmentId,\n statementId: att.query.statementId,\n });\n }\n }\n }\n\n const results = await Promise.allSettled(\n queryAttachments.map(async (att) => {\n const data = await this.getMessageAttachmentQueryResult(\n workspaceClient,\n spaceId,\n conversationId,\n att.messageId,\n att.attachmentId,\n );\n return {\n attachmentId: att.attachmentId,\n statementId: att.statementId,\n data,\n };\n }),\n );\n\n for (const result of results) {\n if (result.status === \"fulfilled\") {\n yield {\n type: \"query_result\",\n attachmentId: result.value.attachmentId,\n statementId: result.value.statementId,\n data: result.value.data,\n };\n } else {\n logger.error(\"Failed to fetch query result: %O\", result.reason);\n yield {\n type: \"error\",\n error:\n result.reason instanceof Error\n ? result.reason.message\n : \"Failed to fetch query result\",\n };\n }\n }\n }\n } catch (error) {\n logger.error(\"Genie getConversation error: %O\", error);\n yield {\n type: \"error\",\n error:\n error instanceof Error\n ? error.message\n : \"Failed to fetch conversation\",\n };\n }\n }\n\n async sendMessage(\n workspaceClient: WorkspaceClient,\n spaceId: string,\n content: string,\n conversationId: string | undefined,\n ): Promise<GenieMessageResponse> {\n const { messageWaiter, conversationId: resultConversationId } =\n await this.startMessage(\n workspaceClient,\n spaceId,\n content,\n conversationId,\n );\n const completedMessage = await this.waitForMessage(messageWaiter);\n const messageResponse = toMessageResponse(completedMessage);\n return {\n ...messageResponse,\n conversationId: resultConversationId,\n };\n }\n\n async getConversation(\n workspaceClient: WorkspaceClient,\n spaceId: string,\n conversationId: string,\n ): Promise<GenieConversationHistoryResponse> {\n const messages = await this.listConversationMessages(\n workspaceClient,\n spaceId,\n conversationId,\n );\n return {\n conversationId,\n spaceId,\n messages,\n };\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"client.js","names":[],"sources":["../../../src/connectors/genie/client.ts"],"sourcesContent":["import type { WorkspaceClient } from \"@databricks/sdk-experimental\";\nimport * as SDK from \"@databricks/sdk-experimental\";\nimport type { GenieMessage } from \"@databricks/sdk-experimental/dist/apis/dashboards\";\nimport type { Waiter } from \"@databricks/sdk-experimental/dist/wait\";\nimport { createLogger } from \"../../logging\";\nimport { genieConnectorDefaults } from \"./defaults\";\nimport { pollWaiter } from \"./poll-waiter\";\nimport type {\n GenieAttachmentResponse,\n GenieConversationHistoryResponse,\n GenieMessageResponse,\n GenieStreamEvent,\n} from \"./types\";\n\nconst { Time, TimeUnits } = SDK;\nconst logger = createLogger(\"connectors:genie\");\n\ntype CreateMessageWaiter = Waiter<GenieMessage, GenieMessage>;\n\nexport interface GenieConnectorConfig {\n timeout?: number;\n maxMessages?: number;\n}\n\nfunction mapAttachments(message: GenieMessage): GenieAttachmentResponse[] {\n return (\n message.attachments?.map((att) => ({\n attachmentId: att.attachment_id,\n query: att.query\n ? {\n title: att.query.title,\n description: att.query.description,\n query: att.query.query,\n statementId: att.query.statement_id,\n }\n : undefined,\n text: att.text ? { content: att.text.content } : undefined,\n suggestedQuestions: att.suggested_questions?.questions,\n })) ?? []\n );\n}\n\nfunction toMessageResponse(message: GenieMessage): GenieMessageResponse {\n return {\n messageId: message.message_id,\n conversationId: message.conversation_id,\n spaceId: message.space_id,\n status: message.status ?? \"COMPLETED\",\n content: message.content,\n attachments: mapAttachments(message),\n error: message.error?.error,\n };\n}\n\nexport class GenieConnector {\n private readonly config: Required<GenieConnectorConfig>;\n\n constructor(config: GenieConnectorConfig = {}) {\n this.config = {\n timeout: config.timeout ?? genieConnectorDefaults.timeout,\n maxMessages: config.maxMessages ?? genieConnectorDefaults.maxMessages,\n };\n }\n\n async startMessage(\n workspaceClient: WorkspaceClient,\n spaceId: string,\n content: string,\n conversationId: string | undefined,\n ): Promise<{\n messageWaiter: CreateMessageWaiter;\n conversationId: string;\n messageId: string;\n }> {\n if (conversationId) {\n const waiter = await workspaceClient.genie.createMessage({\n space_id: spaceId,\n conversation_id: conversationId,\n content,\n });\n return {\n messageWaiter: waiter,\n conversationId,\n messageId: waiter.message_id ?? \"\",\n };\n }\n const start = await workspaceClient.genie.startConversation({\n space_id: spaceId,\n content,\n });\n return {\n messageWaiter: start as unknown as CreateMessageWaiter,\n conversationId: start.conversation_id,\n messageId: start.message_id,\n };\n }\n\n async waitForMessage(\n messageWaiter: CreateMessageWaiter,\n options?: { timeout?: number },\n ): Promise<GenieMessage> {\n const timeout = options?.timeout ?? this.config.timeout;\n const waitOptions =\n timeout > 0 ? { timeout: new Time(timeout, TimeUnits.milliseconds) } : {};\n return messageWaiter.wait(waitOptions);\n }\n\n async listConversationMessages(\n workspaceClient: WorkspaceClient,\n spaceId: string,\n conversationId: string,\n options?: { maxMessages?: number },\n ): Promise<GenieMessageResponse[]> {\n const maxMessages = options?.maxMessages ?? this.config.maxMessages;\n const allMessages: GenieMessage[] = [];\n let pageToken: string | undefined;\n\n do {\n const response = await workspaceClient.genie.listConversationMessages({\n space_id: spaceId,\n conversation_id: conversationId,\n page_size: genieConnectorDefaults.pageSize,\n ...(pageToken ? { page_token: pageToken } : {}),\n });\n\n if (response.messages) {\n allMessages.push(...response.messages);\n }\n\n pageToken = response.next_page_token;\n } while (pageToken && allMessages.length < maxMessages);\n\n return allMessages.slice(0, maxMessages).reverse().map(toMessageResponse);\n }\n\n async getMessageAttachmentQueryResult(\n workspaceClient: WorkspaceClient,\n spaceId: string,\n conversationId: string,\n messageId: string,\n attachmentId: string,\n _signal?: AbortSignal,\n ): Promise<unknown> {\n const response =\n await workspaceClient.genie.getMessageAttachmentQueryResult({\n space_id: spaceId,\n conversation_id: conversationId,\n message_id: messageId,\n attachment_id: attachmentId,\n });\n return response.statement_response;\n }\n\n async *streamSendMessage(\n workspaceClient: WorkspaceClient,\n spaceId: string,\n content: string,\n conversationId: string | undefined,\n options?: { timeout?: number },\n ): AsyncGenerator<GenieStreamEvent> {\n try {\n const {\n messageWaiter,\n conversationId: resultConversationId,\n messageId: resultMessageId,\n } = await this.startMessage(\n workspaceClient,\n spaceId,\n content,\n conversationId,\n );\n\n yield {\n type: \"message_start\",\n conversationId: resultConversationId,\n messageId: resultMessageId,\n spaceId,\n };\n\n const timeout =\n options?.timeout != null ? options.timeout : this.config.timeout;\n const waitOptions =\n timeout > 0\n ? { timeout: new Time(timeout, TimeUnits.milliseconds) }\n : {};\n\n let completedMessage!: GenieMessage;\n for await (const event of pollWaiter(messageWaiter, waitOptions)) {\n if (event.type === \"progress\" && event.value.status) {\n yield { type: \"status\", status: event.value.status };\n } else if (event.type === \"completed\") {\n completedMessage = event.value;\n }\n }\n\n const messageResponse = toMessageResponse(completedMessage);\n yield { type: \"message_result\", message: messageResponse };\n\n yield* this.emitQueryResults(\n workspaceClient,\n spaceId,\n resultConversationId,\n messageResponse.messageId,\n messageResponse,\n );\n } catch (error) {\n logger.error(\"Genie message error: %O\", error);\n yield {\n type: \"error\",\n error: error instanceof Error ? error.message : \"Genie request failed\",\n };\n }\n }\n\n private async *emitQueryResults(\n workspaceClient: WorkspaceClient,\n spaceId: string,\n conversationId: string,\n messageId: string,\n messageResponse: GenieMessageResponse,\n ): AsyncGenerator<\n Extract<GenieStreamEvent, { type: \"query_result\" } | { type: \"error\" }>\n > {\n const attachments = messageResponse.attachments ?? [];\n for (const att of attachments) {\n if (!att.query?.statementId || !att.attachmentId) continue;\n try {\n const data = await this.getMessageAttachmentQueryResult(\n workspaceClient,\n spaceId,\n conversationId,\n messageId,\n att.attachmentId,\n );\n yield {\n type: \"query_result\",\n attachmentId: att.attachmentId,\n statementId: att.query.statementId,\n data,\n };\n } catch (error) {\n logger.error(\n \"Failed to fetch query result for attachment %s: %O\",\n att.attachmentId,\n error,\n );\n yield {\n type: \"error\",\n error: `Failed to fetch query result for attachment ${att.attachmentId}`,\n };\n }\n }\n }\n\n async *streamConversation(\n workspaceClient: WorkspaceClient,\n spaceId: string,\n conversationId: string,\n options?: { includeQueryResults?: boolean },\n ): AsyncGenerator<GenieStreamEvent> {\n const includeQueryResults = options?.includeQueryResults !== false;\n\n try {\n const messageResponses = await this.listConversationMessages(\n workspaceClient,\n spaceId,\n conversationId,\n );\n\n for (const messageResponse of messageResponses) {\n yield { type: \"message_result\", message: messageResponse };\n }\n\n if (includeQueryResults) {\n const queryAttachments: Array<{\n messageId: string;\n attachmentId: string;\n statementId: string;\n }> = [];\n\n for (const msg of messageResponses) {\n for (const att of msg.attachments ?? []) {\n if (att.query?.statementId && att.attachmentId) {\n queryAttachments.push({\n messageId: msg.messageId,\n attachmentId: att.attachmentId,\n statementId: att.query.statementId,\n });\n }\n }\n }\n\n const results = await Promise.allSettled(\n queryAttachments.map(async (att) => {\n const data = await this.getMessageAttachmentQueryResult(\n workspaceClient,\n spaceId,\n conversationId,\n att.messageId,\n att.attachmentId,\n );\n return {\n attachmentId: att.attachmentId,\n statementId: att.statementId,\n data,\n };\n }),\n );\n\n for (const result of results) {\n if (result.status === \"fulfilled\") {\n yield {\n type: \"query_result\",\n attachmentId: result.value.attachmentId,\n statementId: result.value.statementId,\n data: result.value.data,\n };\n } else {\n logger.error(\"Failed to fetch query result: %O\", result.reason);\n yield {\n type: \"error\",\n error:\n result.reason instanceof Error\n ? result.reason.message\n : \"Failed to fetch query result\",\n };\n }\n }\n }\n } catch (error) {\n logger.error(\"Genie getConversation error: %O\", error);\n yield {\n type: \"error\",\n error:\n error instanceof Error\n ? error.message\n : \"Failed to fetch conversation\",\n };\n }\n }\n\n async sendMessage(\n workspaceClient: WorkspaceClient,\n spaceId: string,\n content: string,\n conversationId: string | undefined,\n ): Promise<GenieMessageResponse> {\n const { messageWaiter, conversationId: resultConversationId } =\n await this.startMessage(\n workspaceClient,\n spaceId,\n content,\n conversationId,\n );\n const completedMessage = await this.waitForMessage(messageWaiter);\n const messageResponse = toMessageResponse(completedMessage);\n return {\n ...messageResponse,\n conversationId: resultConversationId,\n };\n }\n\n async getConversation(\n workspaceClient: WorkspaceClient,\n spaceId: string,\n conversationId: string,\n ): Promise<GenieConversationHistoryResponse> {\n const messages = await this.listConversationMessages(\n workspaceClient,\n spaceId,\n conversationId,\n );\n return {\n conversationId,\n spaceId,\n messages,\n };\n }\n}\n"],"mappings":";;;;;;;AAcA,MAAM,EAAE,MAAM,cAAc;AAC5B,MAAM,SAAS,aAAa,mBAAmB;AAS/C,SAAS,eAAe,SAAkD;AACxE,QACE,QAAQ,aAAa,KAAK,SAAS;EACjC,cAAc,IAAI;EAClB,OAAO,IAAI,QACP;GACE,OAAO,IAAI,MAAM;GACjB,aAAa,IAAI,MAAM;GACvB,OAAO,IAAI,MAAM;GACjB,aAAa,IAAI,MAAM;GACxB,GACD;EACJ,MAAM,IAAI,OAAO,EAAE,SAAS,IAAI,KAAK,SAAS,GAAG;EACjD,oBAAoB,IAAI,qBAAqB;EAC9C,EAAE,IAAI,EAAE;;AAIb,SAAS,kBAAkB,SAA6C;AACtE,QAAO;EACL,WAAW,QAAQ;EACnB,gBAAgB,QAAQ;EACxB,SAAS,QAAQ;EACjB,QAAQ,QAAQ,UAAU;EAC1B,SAAS,QAAQ;EACjB,aAAa,eAAe,QAAQ;EACpC,OAAO,QAAQ,OAAO;EACvB;;AAGH,IAAa,iBAAb,MAA4B;CAC1B,AAAiB;CAEjB,YAAY,SAA+B,EAAE,EAAE;AAC7C,OAAK,SAAS;GACZ,SAAS,OAAO,WAAW,uBAAuB;GAClD,aAAa,OAAO,eAAe,uBAAuB;GAC3D;;CAGH,MAAM,aACJ,iBACA,SACA,SACA,gBAKC;AACD,MAAI,gBAAgB;GAClB,MAAM,SAAS,MAAM,gBAAgB,MAAM,cAAc;IACvD,UAAU;IACV,iBAAiB;IACjB;IACD,CAAC;AACF,UAAO;IACL,eAAe;IACf;IACA,WAAW,OAAO,cAAc;IACjC;;EAEH,MAAM,QAAQ,MAAM,gBAAgB,MAAM,kBAAkB;GAC1D,UAAU;GACV;GACD,CAAC;AACF,SAAO;GACL,eAAe;GACf,gBAAgB,MAAM;GACtB,WAAW,MAAM;GAClB;;CAGH,MAAM,eACJ,eACA,SACuB;EACvB,MAAM,UAAU,SAAS,WAAW,KAAK,OAAO;EAChD,MAAM,cACJ,UAAU,IAAI,EAAE,SAAS,IAAI,KAAK,SAAS,UAAU,aAAa,EAAE,GAAG,EAAE;AAC3E,SAAO,cAAc,KAAK,YAAY;;CAGxC,MAAM,yBACJ,iBACA,SACA,gBACA,SACiC;EACjC,MAAM,cAAc,SAAS,eAAe,KAAK,OAAO;EACxD,MAAM,cAA8B,EAAE;EACtC,IAAI;AAEJ,KAAG;GACD,MAAM,WAAW,MAAM,gBAAgB,MAAM,yBAAyB;IACpE,UAAU;IACV,iBAAiB;IACjB,WAAW,uBAAuB;IAClC,GAAI,YAAY,EAAE,YAAY,WAAW,GAAG,EAAE;IAC/C,CAAC;AAEF,OAAI,SAAS,SACX,aAAY,KAAK,GAAG,SAAS,SAAS;AAGxC,eAAY,SAAS;WACd,aAAa,YAAY,SAAS;AAE3C,SAAO,YAAY,MAAM,GAAG,YAAY,CAAC,SAAS,CAAC,IAAI,kBAAkB;;CAG3E,MAAM,gCACJ,iBACA,SACA,gBACA,WACA,cACA,SACkB;AAQlB,UANE,MAAM,gBAAgB,MAAM,gCAAgC;GAC1D,UAAU;GACV,iBAAiB;GACjB,YAAY;GACZ,eAAe;GAChB,CAAC,EACY;;CAGlB,OAAO,kBACL,iBACA,SACA,SACA,gBACA,SACkC;AAClC,MAAI;GACF,MAAM,EACJ,eACA,gBAAgB,sBAChB,WAAW,oBACT,MAAM,KAAK,aACb,iBACA,SACA,SACA,eACD;AAED,SAAM;IACJ,MAAM;IACN,gBAAgB;IAChB,WAAW;IACX;IACD;GAED,MAAM,UACJ,SAAS,WAAW,OAAO,QAAQ,UAAU,KAAK,OAAO;GAC3D,MAAM,cACJ,UAAU,IACN,EAAE,SAAS,IAAI,KAAK,SAAS,UAAU,aAAa,EAAE,GACtD,EAAE;GAER,IAAI;AACJ,cAAW,MAAM,SAAS,WAAW,eAAe,YAAY,CAC9D,KAAI,MAAM,SAAS,cAAc,MAAM,MAAM,OAC3C,OAAM;IAAE,MAAM;IAAU,QAAQ,MAAM,MAAM;IAAQ;YAC3C,MAAM,SAAS,YACxB,oBAAmB,MAAM;GAI7B,MAAM,kBAAkB,kBAAkB,iBAAiB;AAC3D,SAAM;IAAE,MAAM;IAAkB,SAAS;IAAiB;AAE1D,UAAO,KAAK,iBACV,iBACA,SACA,sBACA,gBAAgB,WAChB,gBACD;WACM,OAAO;AACd,UAAO,MAAM,2BAA2B,MAAM;AAC9C,SAAM;IACJ,MAAM;IACN,OAAO,iBAAiB,QAAQ,MAAM,UAAU;IACjD;;;CAIL,OAAe,iBACb,iBACA,SACA,gBACA,WACA,iBAGA;EACA,MAAM,cAAc,gBAAgB,eAAe,EAAE;AACrD,OAAK,MAAM,OAAO,aAAa;AAC7B,OAAI,CAAC,IAAI,OAAO,eAAe,CAAC,IAAI,aAAc;AAClD,OAAI;IACF,MAAM,OAAO,MAAM,KAAK,gCACtB,iBACA,SACA,gBACA,WACA,IAAI,aACL;AACD,UAAM;KACJ,MAAM;KACN,cAAc,IAAI;KAClB,aAAa,IAAI,MAAM;KACvB;KACD;YACM,OAAO;AACd,WAAO,MACL,sDACA,IAAI,cACJ,MACD;AACD,UAAM;KACJ,MAAM;KACN,OAAO,+CAA+C,IAAI;KAC3D;;;;CAKP,OAAO,mBACL,iBACA,SACA,gBACA,SACkC;EAClC,MAAM,sBAAsB,SAAS,wBAAwB;AAE7D,MAAI;GACF,MAAM,mBAAmB,MAAM,KAAK,yBAClC,iBACA,SACA,eACD;AAED,QAAK,MAAM,mBAAmB,iBAC5B,OAAM;IAAE,MAAM;IAAkB,SAAS;IAAiB;AAG5D,OAAI,qBAAqB;IACvB,MAAM,mBAID,EAAE;AAEP,SAAK,MAAM,OAAO,iBAChB,MAAK,MAAM,OAAO,IAAI,eAAe,EAAE,CACrC,KAAI,IAAI,OAAO,eAAe,IAAI,aAChC,kBAAiB,KAAK;KACpB,WAAW,IAAI;KACf,cAAc,IAAI;KAClB,aAAa,IAAI,MAAM;KACxB,CAAC;IAKR,MAAM,UAAU,MAAM,QAAQ,WAC5B,iBAAiB,IAAI,OAAO,QAAQ;KAClC,MAAM,OAAO,MAAM,KAAK,gCACtB,iBACA,SACA,gBACA,IAAI,WACJ,IAAI,aACL;AACD,YAAO;MACL,cAAc,IAAI;MAClB,aAAa,IAAI;MACjB;MACD;MACD,CACH;AAED,SAAK,MAAM,UAAU,QACnB,KAAI,OAAO,WAAW,YACpB,OAAM;KACJ,MAAM;KACN,cAAc,OAAO,MAAM;KAC3B,aAAa,OAAO,MAAM;KAC1B,MAAM,OAAO,MAAM;KACpB;SACI;AACL,YAAO,MAAM,oCAAoC,OAAO,OAAO;AAC/D,WAAM;MACJ,MAAM;MACN,OACE,OAAO,kBAAkB,QACrB,OAAO,OAAO,UACd;MACP;;;WAIA,OAAO;AACd,UAAO,MAAM,mCAAmC,MAAM;AACtD,SAAM;IACJ,MAAM;IACN,OACE,iBAAiB,QACb,MAAM,UACN;IACP;;;CAIL,MAAM,YACJ,iBACA,SACA,SACA,gBAC+B;EAC/B,MAAM,EAAE,eAAe,gBAAgB,yBACrC,MAAM,KAAK,aACT,iBACA,SACA,SACA,eACD;AAGH,SAAO;GACL,GAFsB,kBADC,MAAM,KAAK,eAAe,cAAc,CACN;GAGzD,gBAAgB;GACjB;;CAGH,MAAM,gBACJ,iBACA,SACA,gBAC2C;AAM3C,SAAO;GACL;GACA;GACA,UARe,MAAM,KAAK,yBAC1B,iBACA,SACA,eACD;GAKA"}
@@ -7,6 +7,36 @@ import { WorkspaceClient } from "@databricks/sdk-experimental";
7
7
 
8
8
  /**
9
9
  * Bootstraps AppKit with the provided configuration.
10
+ *
11
+ * Initializes telemetry, cache, and service context, then registers plugins
12
+ * in phase order (core, normal, deferred) and awaits their setup.
13
+ * The returned object maps each plugin name to its `exports()` API,
14
+ * with an `asUser(req)` method for user-scoped execution.
15
+ *
16
+ * @returns A `PluginMap` keyed by plugin name with typed exports
17
+ *
18
+ * @example Minimal server
19
+ * ```ts
20
+ * import { createApp, server } from "@databricks/appkit";
21
+ *
22
+ * await createApp({
23
+ * plugins: [server()],
24
+ * });
25
+ * ```
26
+ *
27
+ * @example Extended Server with analytics and custom endpoint
28
+ * ```ts
29
+ * import { createApp, server, analytics } from "@databricks/appkit";
30
+ *
31
+ * const appkit = await createApp({
32
+ * plugins: [server({ autoStart: false }), analytics({})],
33
+ * });
34
+ *
35
+ * appkit.server.extend((app) => {
36
+ * app.get("/custom", (_req, res) => res.json({ ok: true }));
37
+ * });
38
+ * await appkit.server.start();
39
+ * ```
10
40
  */
11
41
  declare function createApp<T extends PluginData<PluginConstructor, unknown, string>[]>(config?: {
12
42
  plugins?: T;
@@ -1 +1 @@
1
- {"version":3,"file":"appkit.d.ts","names":[],"sources":["../../src/core/appkit.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;iBAqMsB,oBACV,WAAW;YAGT;cACE;UACJ;WACC;IAEV,QAAQ,UAAU"}
1
+ {"version":3,"file":"appkit.d.ts","names":[],"sources":["../../src/core/appkit.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAmOsB,oBACV,WAAW;YAGT;cACE;UACJ;WACC;IAEV,QAAQ,UAAU"}
@@ -92,6 +92,36 @@ var AppKit = class AppKit {
92
92
  };
93
93
  /**
94
94
  * Bootstraps AppKit with the provided configuration.
95
+ *
96
+ * Initializes telemetry, cache, and service context, then registers plugins
97
+ * in phase order (core, normal, deferred) and awaits their setup.
98
+ * The returned object maps each plugin name to its `exports()` API,
99
+ * with an `asUser(req)` method for user-scoped execution.
100
+ *
101
+ * @returns A `PluginMap` keyed by plugin name with typed exports
102
+ *
103
+ * @example Minimal server
104
+ * ```ts
105
+ * import { createApp, server } from "@databricks/appkit";
106
+ *
107
+ * await createApp({
108
+ * plugins: [server()],
109
+ * });
110
+ * ```
111
+ *
112
+ * @example Extended Server with analytics and custom endpoint
113
+ * ```ts
114
+ * import { createApp, server, analytics } from "@databricks/appkit";
115
+ *
116
+ * const appkit = await createApp({
117
+ * plugins: [server({ autoStart: false }), analytics({})],
118
+ * });
119
+ *
120
+ * appkit.server.extend((app) => {
121
+ * app.get("/custom", (_req, res) => res.json({ ok: true }));
122
+ * });
123
+ * await appkit.server.start();
124
+ * ```
95
125
  */
96
126
  async function createApp(config = {}) {
97
127
  return AppKit._createApp(config);
@@ -1 +1 @@
1
- {"version":3,"file":"appkit.js","names":["#pluginInstances","#setupPromises"],"sources":["../../src/core/appkit.ts"],"sourcesContent":["import type { WorkspaceClient } from \"@databricks/sdk-experimental\";\nimport type {\n BasePlugin,\n CacheConfig,\n InputPluginMap,\n OptionalConfigPluginDef,\n PluginConstructor,\n PluginData,\n PluginMap,\n} from \"shared\";\nimport { CacheManager } from \"../cache\";\nimport { ServiceContext } from \"../context\";\nimport { ResourceRegistry, ResourceType } from \"../registry\";\nimport type { TelemetryConfig } from \"../telemetry\";\nimport { TelemetryManager } from \"../telemetry\";\n\nexport class AppKit<TPlugins extends InputPluginMap> {\n #pluginInstances: Record<string, BasePlugin> = {};\n #setupPromises: Promise<void>[] = [];\n\n private constructor(config: { plugins: TPlugins }) {\n const { plugins, ...globalConfig } = config;\n\n const pluginEntries = Object.entries(plugins);\n\n const corePlugins = pluginEntries.filter(([_, p]) => {\n return (p?.plugin?.phase ?? \"normal\") === \"core\";\n });\n const normalPlugins = pluginEntries.filter(\n ([_, p]) => (p?.plugin?.phase ?? \"normal\") === \"normal\",\n );\n const deferredPlugins = pluginEntries.filter(\n ([_, p]) => (p?.plugin?.phase ?? \"normal\") === \"deferred\",\n );\n\n for (const [name, pluginData] of corePlugins) {\n if (pluginData) {\n this.createAndRegisterPlugin(globalConfig, name, pluginData);\n }\n }\n\n for (const [name, pluginData] of normalPlugins) {\n if (pluginData) {\n this.createAndRegisterPlugin(globalConfig, name, pluginData);\n }\n }\n\n for (const [name, pluginData] of deferredPlugins) {\n if (pluginData) {\n this.createAndRegisterPlugin(globalConfig, name, pluginData, {\n plugins: this.#pluginInstances,\n });\n }\n }\n }\n\n private createAndRegisterPlugin<T extends PluginConstructor>(\n config: Omit<{ plugins: TPlugins }, \"plugins\">,\n name: string,\n pluginData: OptionalConfigPluginDef<T>,\n extraData?: Record<string, unknown>,\n ) {\n const { plugin: Plugin, config: pluginConfig } = pluginData;\n const baseConfig = {\n ...config,\n ...Plugin.DEFAULT_CONFIG,\n ...pluginConfig,\n name,\n ...extraData,\n };\n const pluginInstance = new Plugin(baseConfig);\n\n this.#pluginInstances[name] = pluginInstance;\n\n this.#setupPromises.push(pluginInstance.setup());\n\n const self = this;\n\n Object.defineProperty(this, name, {\n get() {\n const plugin = self.#pluginInstances[name];\n return self.wrapWithAsUser(plugin);\n },\n enumerable: true,\n });\n }\n\n /**\n * Binds all function properties in an exports object to the given context.\n */\n private bindExportMethods(\n exports: Record<string, unknown>,\n context: BasePlugin,\n ) {\n for (const key in exports) {\n if (Object.hasOwn(exports, key) && typeof exports[key] === \"function\") {\n exports[key] = (exports[key] as (...args: unknown[]) => unknown).bind(\n context,\n );\n }\n }\n }\n\n /**\n * Wraps a plugin's exports with an `asUser` method that returns\n * a user-scoped version of the exports.\n */\n private wrapWithAsUser<T extends BasePlugin>(plugin: T) {\n // If plugin doesn't implement exports(), return empty object\n const pluginExports = (plugin.exports?.() ?? {}) as Record<string, unknown>;\n this.bindExportMethods(pluginExports, plugin);\n\n // If plugin doesn't support asUser (no asUser method), return exports as-is\n if (typeof (plugin as any).asUser !== \"function\") {\n return pluginExports;\n }\n\n return {\n ...pluginExports,\n /**\n * Execute operations using the user's identity from the request.\n * Returns user-scoped exports where all methods execute with the\n * user's Databricks credentials instead of the service principal.\n */\n asUser: (req: import(\"express\").Request) => {\n const userPlugin = (plugin as any).asUser(req);\n const userExports = (userPlugin.exports?.() ?? {}) as Record<\n string,\n unknown\n >;\n this.bindExportMethods(userExports, userPlugin);\n return userExports;\n },\n };\n }\n\n static async _createApp<\n T extends PluginData<PluginConstructor, unknown, string>[],\n >(\n config: {\n plugins?: T;\n telemetry?: TelemetryConfig;\n cache?: CacheConfig;\n client?: WorkspaceClient;\n } = {},\n ): Promise<PluginMap<T>> {\n // Initialize core services\n TelemetryManager.initialize(config?.telemetry);\n await CacheManager.getInstance(config?.cache);\n\n const rawPlugins = config.plugins as T;\n\n // Collect manifest resources via registry\n const registry = new ResourceRegistry();\n registry.collectResources(rawPlugins);\n\n // Derive ServiceContext needs from what manifests declared\n const needsWarehouse = registry\n .getRequired()\n .some((r) => r.type === ResourceType.SQL_WAREHOUSE);\n await ServiceContext.initialize(\n { warehouseId: needsWarehouse },\n config?.client,\n );\n\n // Validate env vars\n registry.enforceValidation();\n\n const preparedPlugins = AppKit.preparePlugins(rawPlugins);\n const mergedConfig = {\n plugins: preparedPlugins,\n };\n\n const instance = new AppKit(mergedConfig);\n\n await Promise.all(instance.#setupPromises);\n\n return instance as unknown as PluginMap<T>;\n }\n\n private static preparePlugins(\n plugins: PluginData<PluginConstructor, unknown, string>[],\n ) {\n const result: InputPluginMap = {};\n for (const currentPlugin of plugins) {\n result[currentPlugin.name] = {\n plugin: currentPlugin.plugin,\n config: currentPlugin.config as Record<string, unknown>,\n };\n }\n return result;\n }\n}\n\n/**\n * Bootstraps AppKit with the provided configuration.\n */\nexport async function createApp<\n T extends PluginData<PluginConstructor, unknown, string>[],\n>(\n config: {\n plugins?: T;\n telemetry?: TelemetryConfig;\n cache?: CacheConfig;\n client?: WorkspaceClient;\n } = {},\n): Promise<PluginMap<T>> {\n return AppKit._createApp(config);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"appkit.js","names":["#pluginInstances","#setupPromises"],"sources":["../../src/core/appkit.ts"],"sourcesContent":["import type { WorkspaceClient } from \"@databricks/sdk-experimental\";\nimport type {\n BasePlugin,\n CacheConfig,\n InputPluginMap,\n OptionalConfigPluginDef,\n PluginConstructor,\n PluginData,\n PluginMap,\n} from \"shared\";\nimport { CacheManager } from \"../cache\";\nimport { ServiceContext } from \"../context\";\nimport { ResourceRegistry, ResourceType } from \"../registry\";\nimport type { TelemetryConfig } from \"../telemetry\";\nimport { TelemetryManager } from \"../telemetry\";\n\nexport class AppKit<TPlugins extends InputPluginMap> {\n #pluginInstances: Record<string, BasePlugin> = {};\n #setupPromises: Promise<void>[] = [];\n\n private constructor(config: { plugins: TPlugins }) {\n const { plugins, ...globalConfig } = config;\n\n const pluginEntries = Object.entries(plugins);\n\n const corePlugins = pluginEntries.filter(([_, p]) => {\n return (p?.plugin?.phase ?? \"normal\") === \"core\";\n });\n const normalPlugins = pluginEntries.filter(\n ([_, p]) => (p?.plugin?.phase ?? \"normal\") === \"normal\",\n );\n const deferredPlugins = pluginEntries.filter(\n ([_, p]) => (p?.plugin?.phase ?? \"normal\") === \"deferred\",\n );\n\n for (const [name, pluginData] of corePlugins) {\n if (pluginData) {\n this.createAndRegisterPlugin(globalConfig, name, pluginData);\n }\n }\n\n for (const [name, pluginData] of normalPlugins) {\n if (pluginData) {\n this.createAndRegisterPlugin(globalConfig, name, pluginData);\n }\n }\n\n for (const [name, pluginData] of deferredPlugins) {\n if (pluginData) {\n this.createAndRegisterPlugin(globalConfig, name, pluginData, {\n plugins: this.#pluginInstances,\n });\n }\n }\n }\n\n private createAndRegisterPlugin<T extends PluginConstructor>(\n config: Omit<{ plugins: TPlugins }, \"plugins\">,\n name: string,\n pluginData: OptionalConfigPluginDef<T>,\n extraData?: Record<string, unknown>,\n ) {\n const { plugin: Plugin, config: pluginConfig } = pluginData;\n const baseConfig = {\n ...config,\n ...Plugin.DEFAULT_CONFIG,\n ...pluginConfig,\n name,\n ...extraData,\n };\n const pluginInstance = new Plugin(baseConfig);\n\n this.#pluginInstances[name] = pluginInstance;\n\n this.#setupPromises.push(pluginInstance.setup());\n\n const self = this;\n\n Object.defineProperty(this, name, {\n get() {\n const plugin = self.#pluginInstances[name];\n return self.wrapWithAsUser(plugin);\n },\n enumerable: true,\n });\n }\n\n /**\n * Binds all function properties in an exports object to the given context.\n */\n private bindExportMethods(\n exports: Record<string, unknown>,\n context: BasePlugin,\n ) {\n for (const key in exports) {\n if (Object.hasOwn(exports, key) && typeof exports[key] === \"function\") {\n exports[key] = (exports[key] as (...args: unknown[]) => unknown).bind(\n context,\n );\n }\n }\n }\n\n /**\n * Wraps a plugin's exports with an `asUser` method that returns\n * a user-scoped version of the exports.\n */\n private wrapWithAsUser<T extends BasePlugin>(plugin: T) {\n // If plugin doesn't implement exports(), return empty object\n const pluginExports = (plugin.exports?.() ?? {}) as Record<string, unknown>;\n this.bindExportMethods(pluginExports, plugin);\n\n // If plugin doesn't support asUser (no asUser method), return exports as-is\n if (typeof (plugin as any).asUser !== \"function\") {\n return pluginExports;\n }\n\n return {\n ...pluginExports,\n /**\n * Execute operations using the user's identity from the request.\n * Returns user-scoped exports where all methods execute with the\n * user's Databricks credentials instead of the service principal.\n */\n asUser: (req: import(\"express\").Request) => {\n const userPlugin = (plugin as any).asUser(req);\n const userExports = (userPlugin.exports?.() ?? {}) as Record<\n string,\n unknown\n >;\n this.bindExportMethods(userExports, userPlugin);\n return userExports;\n },\n };\n }\n\n static async _createApp<\n T extends PluginData<PluginConstructor, unknown, string>[],\n >(\n config: {\n plugins?: T;\n telemetry?: TelemetryConfig;\n cache?: CacheConfig;\n client?: WorkspaceClient;\n } = {},\n ): Promise<PluginMap<T>> {\n // Initialize core services\n TelemetryManager.initialize(config?.telemetry);\n await CacheManager.getInstance(config?.cache);\n\n const rawPlugins = config.plugins as T;\n\n // Collect manifest resources via registry\n const registry = new ResourceRegistry();\n registry.collectResources(rawPlugins);\n\n // Derive ServiceContext needs from what manifests declared\n const needsWarehouse = registry\n .getRequired()\n .some((r) => r.type === ResourceType.SQL_WAREHOUSE);\n await ServiceContext.initialize(\n { warehouseId: needsWarehouse },\n config?.client,\n );\n\n // Validate env vars\n registry.enforceValidation();\n\n const preparedPlugins = AppKit.preparePlugins(rawPlugins);\n const mergedConfig = {\n plugins: preparedPlugins,\n };\n\n const instance = new AppKit(mergedConfig);\n\n await Promise.all(instance.#setupPromises);\n\n return instance as unknown as PluginMap<T>;\n }\n\n private static preparePlugins(\n plugins: PluginData<PluginConstructor, unknown, string>[],\n ) {\n const result: InputPluginMap = {};\n for (const currentPlugin of plugins) {\n result[currentPlugin.name] = {\n plugin: currentPlugin.plugin,\n config: currentPlugin.config as Record<string, unknown>,\n };\n }\n return result;\n }\n}\n\n/**\n * Bootstraps AppKit with the provided configuration.\n *\n * Initializes telemetry, cache, and service context, then registers plugins\n * in phase order (core, normal, deferred) and awaits their setup.\n * The returned object maps each plugin name to its `exports()` API,\n * with an `asUser(req)` method for user-scoped execution.\n *\n * @returns A `PluginMap` keyed by plugin name with typed exports\n *\n * @example Minimal server\n * ```ts\n * import { createApp, server } from \"@databricks/appkit\";\n *\n * await createApp({\n * plugins: [server()],\n * });\n * ```\n *\n * @example Extended Server with analytics and custom endpoint\n * ```ts\n * import { createApp, server, analytics } from \"@databricks/appkit\";\n *\n * const appkit = await createApp({\n * plugins: [server({ autoStart: false }), analytics({})],\n * });\n *\n * appkit.server.extend((app) => {\n * app.get(\"/custom\", (_req, res) => res.json({ ok: true }));\n * });\n * await appkit.server.start();\n * ```\n */\nexport async function createApp<\n T extends PluginData<PluginConstructor, unknown, string>[],\n>(\n config: {\n plugins?: T;\n telemetry?: TelemetryConfig;\n cache?: CacheConfig;\n client?: WorkspaceClient;\n } = {},\n): Promise<PluginMap<T>> {\n return AppKit._createApp(config);\n}\n"],"mappings":"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"}
@@ -124,6 +124,26 @@ declare abstract class Plugin<TConfig extends BasePluginConfig = BasePluginConfi
124
124
  * Returns the public exports for this plugin.
125
125
  * Override this to define a custom public API.
126
126
  * By default, returns an empty object.
127
+ *
128
+ * The returned object becomes the plugin's public API on the AppKit instance
129
+ * (e.g. `appkit.myPlugin.method()`). AppKit automatically binds method context
130
+ * and adds `asUser(req)` for user-scoped execution.
131
+ *
132
+ * @example
133
+ * ```ts
134
+ * class MyPlugin extends Plugin {
135
+ * name = "myPlugin";
136
+ * private getData() { return []; }
137
+ *
138
+ * exports() {
139
+ * return { getData: this.getData };
140
+ * }
141
+ * }
142
+ *
143
+ * // After registration:
144
+ * const appkit = await createApp({ plugins: [myPlugin()] });
145
+ * appkit.myPlugin.getData();
146
+ * ```
127
147
  */
128
148
  exports(): unknown;
129
149
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.d.ts","names":[],"sources":["../../src/plugin/plugin.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;;;;AAiJA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;uBAAsB,uBACJ,mBAAmB,6BACxB;oBAyBmB;;mBAtBb;iBACF;2BACU;2BACA;uBACJ;;;;;;;;;gBAWP;;;;;sBAOgB;kBAWd,OAAA,CAAQ;WAIb;kBAEK;;;;;;;;;;;;;;;;;cA0BJ,OAAA,CAAQ;;;;;;;kCA6Db,kBACD,qBAAqB,aAChB,4CACO;qCA2DF,gBAAgB,QAAQ,aAC7B,4CAER,QAAQ;;sCA0BD,OAAA,CAAQ,gBACR"}
1
+ {"version":3,"file":"plugin.d.ts","names":[],"sources":["../../src/plugin/plugin.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;;;;AAiJA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;uBAAsB,uBACJ,mBAAmB,6BACxB;oBAyBmB;;mBAtBb;iBACF;2BACU;2BACA;uBACJ;;;;;;;;;gBAWP;;;;;sBAOgB;kBAWd,OAAA,CAAQ;WAIb;kBAEK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cA8CJ,OAAA,CAAQ;;;;;;;kCA6Db,kBACD,qBAAqB,aAChB,4CACO;qCA2DF,gBAAgB,QAAQ,aAC7B,4CAER,QAAQ;;sCA0BD,OAAA,CAAQ,gBACR"}
@@ -163,6 +163,26 @@ var Plugin = class {
163
163
  * Returns the public exports for this plugin.
164
164
  * Override this to define a custom public API.
165
165
  * By default, returns an empty object.
166
+ *
167
+ * The returned object becomes the plugin's public API on the AppKit instance
168
+ * (e.g. `appkit.myPlugin.method()`). AppKit automatically binds method context
169
+ * and adds `asUser(req)` for user-scoped execution.
170
+ *
171
+ * @example
172
+ * ```ts
173
+ * class MyPlugin extends Plugin {
174
+ * name = "myPlugin";
175
+ * private getData() { return []; }
176
+ *
177
+ * exports() {
178
+ * return { getData: this.getData };
179
+ * }
180
+ * }
181
+ *
182
+ * // After registration:
183
+ * const appkit = await createApp({ plugins: [myPlugin()] });
184
+ * appkit.myPlugin.getData();
185
+ * ```
166
186
  */
167
187
  exports() {
168
188
  return {};
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.js","names":[],"sources":["../../src/plugin/plugin.ts"],"sourcesContent":["import type express from \"express\";\nimport type {\n BasePlugin,\n BasePluginConfig,\n IAppResponse,\n PluginEndpointMap,\n PluginExecuteConfig,\n PluginExecutionSettings,\n PluginPhase,\n RouteConfig,\n StreamExecuteHandler,\n StreamExecutionSettings,\n} from \"shared\";\nimport { AppManager } from \"../app\";\nimport { CacheManager } from \"../cache\";\nimport {\n getCurrentUserId,\n runInUserContext,\n ServiceContext,\n type UserContext,\n} from \"../context\";\nimport { AuthenticationError } from \"../errors\";\nimport { createLogger } from \"../logging/logger\";\nimport { StreamManager } from \"../stream\";\nimport {\n type ITelemetry,\n normalizeTelemetryOptions,\n TelemetryManager,\n} from \"../telemetry\";\nimport { deepMerge } from \"../utils\";\nimport { DevFileReader } from \"./dev-reader\";\nimport { CacheInterceptor } from \"./interceptors/cache\";\nimport { RetryInterceptor } from \"./interceptors/retry\";\nimport { TelemetryInterceptor } from \"./interceptors/telemetry\";\nimport { TimeoutInterceptor } from \"./interceptors/timeout\";\nimport type {\n ExecutionInterceptor,\n InterceptorContext,\n} from \"./interceptors/types\";\n\nconst logger = createLogger(\"plugin\");\n\n/**\n * Methods that should not be proxied by asUser().\n * These are lifecycle/internal methods that don't make sense\n * to execute in a user context.\n */\nconst EXCLUDED_FROM_PROXY = new Set([\n // Lifecycle methods\n \"setup\",\n \"shutdown\",\n \"injectRoutes\",\n \"getEndpoints\",\n \"abortActiveOperations\",\n // asUser itself - prevent chaining like .asUser().asUser()\n \"asUser\",\n // Internal methods\n \"constructor\",\n]);\n\n/**\n * Base abstract class for creating AppKit plugins.\n *\n * All plugins must declare a static `manifest` property with their metadata\n * and resource requirements. The manifest defines:\n * - `required` resources: Always needed for the plugin to function\n * - `optional` resources: May be needed depending on plugin configuration\n *\n * ## Static vs Runtime Resource Requirements\n *\n * The manifest is static and doesn't know the plugin's runtime configuration.\n * For resources that become required based on config options, plugins can\n * implement a static `getResourceRequirements(config)` method.\n *\n * At runtime, this method is called with the actual config to determine\n * which \"optional\" resources should be treated as \"required\".\n *\n * @example Basic plugin with static requirements\n * ```typescript\n * import { Plugin, toPlugin, PluginManifest, ResourceType } from '@databricks/appkit';\n *\n * const myManifest: PluginManifest = {\n * name: 'myPlugin',\n * displayName: 'My Plugin',\n * description: 'Does something awesome',\n * resources: {\n * required: [\n * { type: ResourceType.SQL_WAREHOUSE, alias: 'warehouse', ... }\n * ],\n * optional: []\n * }\n * };\n *\n * class MyPlugin extends Plugin<MyConfig> {\n * static manifest = myManifest;\n * name = 'myPlugin';\n * }\n * ```\n *\n * @example Plugin with config-dependent resources\n * ```typescript\n * interface MyConfig extends BasePluginConfig {\n * enableCaching?: boolean;\n * }\n *\n * const myManifest: PluginManifest = {\n * name: 'myPlugin',\n * resources: {\n * required: [\n * { type: ResourceType.SQL_WAREHOUSE, alias: 'warehouse', ... }\n * ],\n * optional: [\n * // Database is optional in the static manifest\n * { type: ResourceType.DATABASE, alias: 'cache', description: 'Required if caching enabled', ... }\n * ]\n * }\n * };\n *\n * class MyPlugin extends Plugin<MyConfig> {\n * static manifest = myManifest;\n * name = 'myPlugin';\n *\n * // Runtime method: converts optional resources to required based on config\n * static getResourceRequirements(config: MyConfig) {\n * const resources = [];\n * if (config.enableCaching) {\n * // When caching is enabled, Database becomes required\n * resources.push({\n * type: ResourceType.DATABASE,\n * alias: 'cache',\n * resourceKey: 'database',\n * description: 'Cache storage for query results',\n * permission: 'CAN_CONNECT_AND_CREATE',\n * fields: {\n * instance_name: { env: 'DATABRICKS_CACHE_INSTANCE' },\n * database_name: { env: 'DATABRICKS_CACHE_DB' },\n * },\n * required: true // Mark as required at runtime\n * });\n * }\n * return resources;\n * }\n * }\n * ```\n */\nexport abstract class Plugin<\n TConfig extends BasePluginConfig = BasePluginConfig,\n> implements BasePlugin\n{\n protected isReady = false;\n protected cache: CacheManager;\n protected app: AppManager;\n protected devFileReader: DevFileReader;\n protected streamManager: StreamManager;\n protected telemetry: ITelemetry;\n\n /** Registered endpoints for this plugin */\n private registeredEndpoints: PluginEndpointMap = {};\n\n /**\n * Plugin initialization phase.\n * - 'core': Initialized first (e.g., config plugins)\n * - 'normal': Initialized second (most plugins)\n * - 'deferred': Initialized last (e.g., server plugin)\n */\n static phase: PluginPhase = \"normal\";\n\n /**\n * Plugin name identifier.\n */\n name: string;\n\n constructor(protected config: TConfig) {\n this.name = config.name ?? \"plugin\";\n this.telemetry = TelemetryManager.getProvider(this.name, config.telemetry);\n this.streamManager = new StreamManager();\n this.cache = CacheManager.getInstanceSync();\n this.app = new AppManager();\n this.devFileReader = DevFileReader.getInstance();\n\n this.isReady = true;\n }\n\n injectRoutes(_: express.Router) {\n return;\n }\n\n async setup() {}\n\n getEndpoints(): PluginEndpointMap {\n return this.registeredEndpoints;\n }\n\n abortActiveOperations(): void {\n this.streamManager.abortAll();\n }\n\n /**\n * Returns the public exports for this plugin.\n * Override this to define a custom public API.\n * By default, returns an empty object.\n */\n exports(): unknown {\n return {};\n }\n\n /**\n * Execute operations using the user's identity from the request.\n * Returns a proxy of this plugin where all method calls execute\n * with the user's Databricks credentials instead of the service principal.\n *\n * @param req - The Express request containing the user token in headers\n * @returns A proxied plugin instance that executes as the user\n * @throws Error if user token is not available in request headers\n */\n asUser(req: express.Request): this {\n const token = req.headers[\"x-forwarded-access-token\"] as string;\n const userId = req.headers[\"x-forwarded-user\"] as string;\n const isDev = process.env.NODE_ENV === \"development\";\n\n // In local development, fall back to service principal\n // since there's no user token available\n if (!token && isDev) {\n logger.warn(\n \"asUser() called without user token in development mode. Using service principal.\",\n );\n\n return this;\n }\n\n if (!token) {\n throw AuthenticationError.missingToken(\"user token\");\n }\n\n if (!userId && !isDev) {\n throw AuthenticationError.missingUserId();\n }\n\n const effectiveUserId = userId || \"dev-user\";\n\n const userContext = ServiceContext.createUserContext(\n token,\n effectiveUserId,\n );\n\n // Return a proxy that wraps method calls in user context\n return this._createUserContextProxy(userContext);\n }\n\n /**\n * Creates a proxy that wraps method calls in a user context.\n * This allows all plugin methods to automatically use the user's\n * Databricks credentials.\n */\n private _createUserContextProxy(userContext: UserContext): this {\n return new Proxy(this, {\n get: (target, prop, receiver) => {\n const value = Reflect.get(target, prop, receiver);\n\n if (typeof value !== \"function\") {\n return value;\n }\n\n if (typeof prop === \"string\" && EXCLUDED_FROM_PROXY.has(prop)) {\n return value;\n }\n\n return (...args: unknown[]) => {\n return runInUserContext(userContext, () => value.apply(target, args));\n };\n },\n }) as this;\n }\n\n // streaming execution with interceptors\n protected async executeStream<T>(\n res: IAppResponse,\n fn: StreamExecuteHandler<T>,\n options: StreamExecutionSettings,\n userKey?: string,\n ) {\n // destructure options\n const {\n stream: streamConfig,\n default: defaultConfig,\n user: userConfig,\n } = options;\n\n // build execution options\n const executeConfig = this._buildExecutionConfig({\n default: defaultConfig,\n user: userConfig,\n });\n\n // get user key from context if not provided\n const effectiveUserKey = userKey ?? getCurrentUserId();\n\n const self = this;\n\n // wrapper function to ensure it returns a generator\n const asyncWrapperFn = async function* (streamSignal?: AbortSignal) {\n // build execution context\n const context: InterceptorContext = {\n signal: streamSignal,\n metadata: new Map(),\n userKey: effectiveUserKey,\n };\n\n // build interceptors\n const interceptors = self._buildInterceptors(executeConfig);\n\n // wrap the function to ensure it returns a promise\n const wrappedFn = async () => {\n const result = await fn(context.signal);\n return result;\n };\n\n // execute the function with interceptors\n const result = await self._executeWithInterceptors(\n wrappedFn as (signal?: AbortSignal) => Promise<T>,\n interceptors,\n context,\n );\n\n // check if result is a generator\n if (self._checkIfGenerator(result)) {\n yield* result;\n } else {\n yield result;\n }\n };\n\n // stream the result to the client\n await this.streamManager.stream(res, asyncWrapperFn, streamConfig);\n }\n\n // single sync execution with interceptors\n protected async execute<T>(\n fn: (signal?: AbortSignal) => Promise<T>,\n options: PluginExecutionSettings,\n userKey?: string,\n ): Promise<T | undefined> {\n const executeConfig = this._buildExecutionConfig(options);\n\n const interceptors = this._buildInterceptors(executeConfig);\n\n // get user key from context if not provided\n const effectiveUserKey = userKey ?? getCurrentUserId();\n\n const context: InterceptorContext = {\n metadata: new Map(),\n userKey: effectiveUserKey,\n };\n\n try {\n return await this._executeWithInterceptors(fn, interceptors, context);\n } catch (_error) {\n // production-safe, don't crash sdk\n return undefined;\n }\n }\n\n protected registerEndpoint(name: string, path: string): void {\n this.registeredEndpoints[name] = path;\n }\n\n protected route<_TResponse>(\n router: express.Router,\n config: RouteConfig,\n ): void {\n const { name, method, path, handler } = config;\n\n router[method](path, handler);\n\n this.registerEndpoint(name, `/api/${this.name}${path}`);\n }\n\n // build execution options by merging defaults, plugin config, and user overrides\n private _buildExecutionConfig(\n options: PluginExecutionSettings,\n ): PluginExecuteConfig {\n const { default: methodDefaults, user: userOverride } = options;\n\n // Merge: method defaults <- plugin config <- user override (highest priority)\n return deepMerge(\n deepMerge(methodDefaults, this.config),\n userOverride ?? {},\n ) as PluginExecuteConfig;\n }\n\n // build interceptors based on execute options\n private _buildInterceptors(\n options: PluginExecuteConfig,\n ): ExecutionInterceptor[] {\n const interceptors: ExecutionInterceptor[] = [];\n\n // order matters: telemetry → timeout → retry → cache (innermost to outermost)\n\n const telemetryConfig = normalizeTelemetryOptions(this.config.telemetry);\n if (\n telemetryConfig.traces &&\n (options.telemetryInterceptor?.enabled ?? true)\n ) {\n interceptors.push(\n new TelemetryInterceptor(this.telemetry, options.telemetryInterceptor),\n );\n }\n\n if (options.timeout && options.timeout > 0) {\n interceptors.push(new TimeoutInterceptor(options.timeout));\n }\n\n if (\n options.retry?.enabled &&\n options.retry.attempts &&\n options.retry.attempts > 1\n ) {\n interceptors.push(new RetryInterceptor(options.retry));\n }\n\n if (options.cache?.enabled && options.cache.cacheKey?.length) {\n interceptors.push(new CacheInterceptor(this.cache, options.cache));\n }\n\n return interceptors;\n }\n\n // execute method wrapped with interceptors\n private async _executeWithInterceptors<T>(\n fn: (signal?: AbortSignal) => Promise<T>,\n interceptors: ExecutionInterceptor[],\n context: InterceptorContext,\n ): Promise<T> {\n // no interceptors, execute directly\n if (interceptors.length === 0) {\n return fn(context.signal);\n }\n // build nested execution chain from interceptors\n let wrappedFn = () => fn(context.signal);\n\n // wrap each interceptor around the previous function\n for (const interceptor of interceptors) {\n const previousFn = wrappedFn;\n wrappedFn = () => interceptor.intercept(previousFn, context);\n }\n\n return wrappedFn();\n }\n\n private _checkIfGenerator(\n result: any,\n ): result is AsyncGenerator<any, void, unknown> {\n return (\n result && typeof result === \"object\" && Symbol.asyncIterator in result\n );\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"plugin.js","names":[],"sources":["../../src/plugin/plugin.ts"],"sourcesContent":["import type express from \"express\";\nimport type {\n BasePlugin,\n BasePluginConfig,\n IAppResponse,\n PluginEndpointMap,\n PluginExecuteConfig,\n PluginExecutionSettings,\n PluginPhase,\n RouteConfig,\n StreamExecuteHandler,\n StreamExecutionSettings,\n} from \"shared\";\nimport { AppManager } from \"../app\";\nimport { CacheManager } from \"../cache\";\nimport {\n getCurrentUserId,\n runInUserContext,\n ServiceContext,\n type UserContext,\n} from \"../context\";\nimport { AuthenticationError } from \"../errors\";\nimport { createLogger } from \"../logging/logger\";\nimport { StreamManager } from \"../stream\";\nimport {\n type ITelemetry,\n normalizeTelemetryOptions,\n TelemetryManager,\n} from \"../telemetry\";\nimport { deepMerge } from \"../utils\";\nimport { DevFileReader } from \"./dev-reader\";\nimport { CacheInterceptor } from \"./interceptors/cache\";\nimport { RetryInterceptor } from \"./interceptors/retry\";\nimport { TelemetryInterceptor } from \"./interceptors/telemetry\";\nimport { TimeoutInterceptor } from \"./interceptors/timeout\";\nimport type {\n ExecutionInterceptor,\n InterceptorContext,\n} from \"./interceptors/types\";\n\nconst logger = createLogger(\"plugin\");\n\n/**\n * Methods that should not be proxied by asUser().\n * These are lifecycle/internal methods that don't make sense\n * to execute in a user context.\n */\nconst EXCLUDED_FROM_PROXY = new Set([\n // Lifecycle methods\n \"setup\",\n \"shutdown\",\n \"injectRoutes\",\n \"getEndpoints\",\n \"abortActiveOperations\",\n // asUser itself - prevent chaining like .asUser().asUser()\n \"asUser\",\n // Internal methods\n \"constructor\",\n]);\n\n/**\n * Base abstract class for creating AppKit plugins.\n *\n * All plugins must declare a static `manifest` property with their metadata\n * and resource requirements. The manifest defines:\n * - `required` resources: Always needed for the plugin to function\n * - `optional` resources: May be needed depending on plugin configuration\n *\n * ## Static vs Runtime Resource Requirements\n *\n * The manifest is static and doesn't know the plugin's runtime configuration.\n * For resources that become required based on config options, plugins can\n * implement a static `getResourceRequirements(config)` method.\n *\n * At runtime, this method is called with the actual config to determine\n * which \"optional\" resources should be treated as \"required\".\n *\n * @example Basic plugin with static requirements\n * ```typescript\n * import { Plugin, toPlugin, PluginManifest, ResourceType } from '@databricks/appkit';\n *\n * const myManifest: PluginManifest = {\n * name: 'myPlugin',\n * displayName: 'My Plugin',\n * description: 'Does something awesome',\n * resources: {\n * required: [\n * { type: ResourceType.SQL_WAREHOUSE, alias: 'warehouse', ... }\n * ],\n * optional: []\n * }\n * };\n *\n * class MyPlugin extends Plugin<MyConfig> {\n * static manifest = myManifest;\n * name = 'myPlugin';\n * }\n * ```\n *\n * @example Plugin with config-dependent resources\n * ```typescript\n * interface MyConfig extends BasePluginConfig {\n * enableCaching?: boolean;\n * }\n *\n * const myManifest: PluginManifest = {\n * name: 'myPlugin',\n * resources: {\n * required: [\n * { type: ResourceType.SQL_WAREHOUSE, alias: 'warehouse', ... }\n * ],\n * optional: [\n * // Database is optional in the static manifest\n * { type: ResourceType.DATABASE, alias: 'cache', description: 'Required if caching enabled', ... }\n * ]\n * }\n * };\n *\n * class MyPlugin extends Plugin<MyConfig> {\n * static manifest = myManifest;\n * name = 'myPlugin';\n *\n * // Runtime method: converts optional resources to required based on config\n * static getResourceRequirements(config: MyConfig) {\n * const resources = [];\n * if (config.enableCaching) {\n * // When caching is enabled, Database becomes required\n * resources.push({\n * type: ResourceType.DATABASE,\n * alias: 'cache',\n * resourceKey: 'database',\n * description: 'Cache storage for query results',\n * permission: 'CAN_CONNECT_AND_CREATE',\n * fields: {\n * instance_name: { env: 'DATABRICKS_CACHE_INSTANCE' },\n * database_name: { env: 'DATABRICKS_CACHE_DB' },\n * },\n * required: true // Mark as required at runtime\n * });\n * }\n * return resources;\n * }\n * }\n * ```\n */\nexport abstract class Plugin<\n TConfig extends BasePluginConfig = BasePluginConfig,\n> implements BasePlugin\n{\n protected isReady = false;\n protected cache: CacheManager;\n protected app: AppManager;\n protected devFileReader: DevFileReader;\n protected streamManager: StreamManager;\n protected telemetry: ITelemetry;\n\n /** Registered endpoints for this plugin */\n private registeredEndpoints: PluginEndpointMap = {};\n\n /**\n * Plugin initialization phase.\n * - 'core': Initialized first (e.g., config plugins)\n * - 'normal': Initialized second (most plugins)\n * - 'deferred': Initialized last (e.g., server plugin)\n */\n static phase: PluginPhase = \"normal\";\n\n /**\n * Plugin name identifier.\n */\n name: string;\n\n constructor(protected config: TConfig) {\n this.name = config.name ?? \"plugin\";\n this.telemetry = TelemetryManager.getProvider(this.name, config.telemetry);\n this.streamManager = new StreamManager();\n this.cache = CacheManager.getInstanceSync();\n this.app = new AppManager();\n this.devFileReader = DevFileReader.getInstance();\n\n this.isReady = true;\n }\n\n injectRoutes(_: express.Router) {\n return;\n }\n\n async setup() {}\n\n getEndpoints(): PluginEndpointMap {\n return this.registeredEndpoints;\n }\n\n abortActiveOperations(): void {\n this.streamManager.abortAll();\n }\n\n /**\n * Returns the public exports for this plugin.\n * Override this to define a custom public API.\n * By default, returns an empty object.\n *\n * The returned object becomes the plugin's public API on the AppKit instance\n * (e.g. `appkit.myPlugin.method()`). AppKit automatically binds method context\n * and adds `asUser(req)` for user-scoped execution.\n *\n * @example\n * ```ts\n * class MyPlugin extends Plugin {\n * name = \"myPlugin\";\n * private getData() { return []; }\n *\n * exports() {\n * return { getData: this.getData };\n * }\n * }\n *\n * // After registration:\n * const appkit = await createApp({ plugins: [myPlugin()] });\n * appkit.myPlugin.getData();\n * ```\n */\n exports(): unknown {\n return {};\n }\n\n /**\n * Execute operations using the user's identity from the request.\n * Returns a proxy of this plugin where all method calls execute\n * with the user's Databricks credentials instead of the service principal.\n *\n * @param req - The Express request containing the user token in headers\n * @returns A proxied plugin instance that executes as the user\n * @throws Error if user token is not available in request headers\n */\n asUser(req: express.Request): this {\n const token = req.headers[\"x-forwarded-access-token\"] as string;\n const userId = req.headers[\"x-forwarded-user\"] as string;\n const isDev = process.env.NODE_ENV === \"development\";\n\n // In local development, fall back to service principal\n // since there's no user token available\n if (!token && isDev) {\n logger.warn(\n \"asUser() called without user token in development mode. Using service principal.\",\n );\n\n return this;\n }\n\n if (!token) {\n throw AuthenticationError.missingToken(\"user token\");\n }\n\n if (!userId && !isDev) {\n throw AuthenticationError.missingUserId();\n }\n\n const effectiveUserId = userId || \"dev-user\";\n\n const userContext = ServiceContext.createUserContext(\n token,\n effectiveUserId,\n );\n\n // Return a proxy that wraps method calls in user context\n return this._createUserContextProxy(userContext);\n }\n\n /**\n * Creates a proxy that wraps method calls in a user context.\n * This allows all plugin methods to automatically use the user's\n * Databricks credentials.\n */\n private _createUserContextProxy(userContext: UserContext): this {\n return new Proxy(this, {\n get: (target, prop, receiver) => {\n const value = Reflect.get(target, prop, receiver);\n\n if (typeof value !== \"function\") {\n return value;\n }\n\n if (typeof prop === \"string\" && EXCLUDED_FROM_PROXY.has(prop)) {\n return value;\n }\n\n return (...args: unknown[]) => {\n return runInUserContext(userContext, () => value.apply(target, args));\n };\n },\n }) as this;\n }\n\n // streaming execution with interceptors\n protected async executeStream<T>(\n res: IAppResponse,\n fn: StreamExecuteHandler<T>,\n options: StreamExecutionSettings,\n userKey?: string,\n ) {\n // destructure options\n const {\n stream: streamConfig,\n default: defaultConfig,\n user: userConfig,\n } = options;\n\n // build execution options\n const executeConfig = this._buildExecutionConfig({\n default: defaultConfig,\n user: userConfig,\n });\n\n // get user key from context if not provided\n const effectiveUserKey = userKey ?? getCurrentUserId();\n\n const self = this;\n\n // wrapper function to ensure it returns a generator\n const asyncWrapperFn = async function* (streamSignal?: AbortSignal) {\n // build execution context\n const context: InterceptorContext = {\n signal: streamSignal,\n metadata: new Map(),\n userKey: effectiveUserKey,\n };\n\n // build interceptors\n const interceptors = self._buildInterceptors(executeConfig);\n\n // wrap the function to ensure it returns a promise\n const wrappedFn = async () => {\n const result = await fn(context.signal);\n return result;\n };\n\n // execute the function with interceptors\n const result = await self._executeWithInterceptors(\n wrappedFn as (signal?: AbortSignal) => Promise<T>,\n interceptors,\n context,\n );\n\n // check if result is a generator\n if (self._checkIfGenerator(result)) {\n yield* result;\n } else {\n yield result;\n }\n };\n\n // stream the result to the client\n await this.streamManager.stream(res, asyncWrapperFn, streamConfig);\n }\n\n // single sync execution with interceptors\n protected async execute<T>(\n fn: (signal?: AbortSignal) => Promise<T>,\n options: PluginExecutionSettings,\n userKey?: string,\n ): Promise<T | undefined> {\n const executeConfig = this._buildExecutionConfig(options);\n\n const interceptors = this._buildInterceptors(executeConfig);\n\n // get user key from context if not provided\n const effectiveUserKey = userKey ?? getCurrentUserId();\n\n const context: InterceptorContext = {\n metadata: new Map(),\n userKey: effectiveUserKey,\n };\n\n try {\n return await this._executeWithInterceptors(fn, interceptors, context);\n } catch (_error) {\n // production-safe, don't crash sdk\n return undefined;\n }\n }\n\n protected registerEndpoint(name: string, path: string): void {\n this.registeredEndpoints[name] = path;\n }\n\n protected route<_TResponse>(\n router: express.Router,\n config: RouteConfig,\n ): void {\n const { name, method, path, handler } = config;\n\n router[method](path, handler);\n\n this.registerEndpoint(name, `/api/${this.name}${path}`);\n }\n\n // build execution options by merging defaults, plugin config, and user overrides\n private _buildExecutionConfig(\n options: PluginExecutionSettings,\n ): PluginExecuteConfig {\n const { default: methodDefaults, user: userOverride } = options;\n\n // Merge: method defaults <- plugin config <- user override (highest priority)\n return deepMerge(\n deepMerge(methodDefaults, this.config),\n userOverride ?? {},\n ) as PluginExecuteConfig;\n }\n\n // build interceptors based on execute options\n private _buildInterceptors(\n options: PluginExecuteConfig,\n ): ExecutionInterceptor[] {\n const interceptors: ExecutionInterceptor[] = [];\n\n // order matters: telemetry → timeout → retry → cache (innermost to outermost)\n\n const telemetryConfig = normalizeTelemetryOptions(this.config.telemetry);\n if (\n telemetryConfig.traces &&\n (options.telemetryInterceptor?.enabled ?? true)\n ) {\n interceptors.push(\n new TelemetryInterceptor(this.telemetry, options.telemetryInterceptor),\n );\n }\n\n if (options.timeout && options.timeout > 0) {\n interceptors.push(new TimeoutInterceptor(options.timeout));\n }\n\n if (\n options.retry?.enabled &&\n options.retry.attempts &&\n options.retry.attempts > 1\n ) {\n interceptors.push(new RetryInterceptor(options.retry));\n }\n\n if (options.cache?.enabled && options.cache.cacheKey?.length) {\n interceptors.push(new CacheInterceptor(this.cache, options.cache));\n }\n\n return interceptors;\n }\n\n // execute method wrapped with interceptors\n private async _executeWithInterceptors<T>(\n fn: (signal?: AbortSignal) => Promise<T>,\n interceptors: ExecutionInterceptor[],\n context: InterceptorContext,\n ): Promise<T> {\n // no interceptors, execute directly\n if (interceptors.length === 0) {\n return fn(context.signal);\n }\n // build nested execution chain from interceptors\n let wrappedFn = () => fn(context.signal);\n\n // wrap each interceptor around the previous function\n for (const interceptor of interceptors) {\n const previousFn = wrappedFn;\n wrappedFn = () => interceptor.intercept(previousFn, context);\n }\n\n return wrappedFn();\n }\n\n private _checkIfGenerator(\n result: any,\n ): result is AsyncGenerator<any, void, unknown> {\n return (\n result && typeof result === \"object\" && Symbol.asyncIterator in result\n );\n }\n}\n"],"mappings":"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"}
@@ -27,14 +27,14 @@ console.error(error.toJSON()); // Safe for logging, sensitive values redacted
27
27
 
28
28
  ## Extended by[​](#extended-by "Direct link to Extended by")
29
29
 
30
- * [`AuthenticationError`](/appkit/docs/api/appkit/Class.AuthenticationError.md)
31
- * [`ConfigurationError`](/appkit/docs/api/appkit/Class.ConfigurationError.md)
32
- * [`ConnectionError`](/appkit/docs/api/appkit/Class.ConnectionError.md)
33
- * [`ExecutionError`](/appkit/docs/api/appkit/Class.ExecutionError.md)
34
- * [`InitializationError`](/appkit/docs/api/appkit/Class.InitializationError.md)
35
- * [`ServerError`](/appkit/docs/api/appkit/Class.ServerError.md)
36
- * [`TunnelError`](/appkit/docs/api/appkit/Class.TunnelError.md)
37
- * [`ValidationError`](/appkit/docs/api/appkit/Class.ValidationError.md)
30
+ * [`AuthenticationError`](./docs/api/appkit/Class.AuthenticationError.md)
31
+ * [`ConfigurationError`](./docs/api/appkit/Class.ConfigurationError.md)
32
+ * [`ConnectionError`](./docs/api/appkit/Class.ConnectionError.md)
33
+ * [`ExecutionError`](./docs/api/appkit/Class.ExecutionError.md)
34
+ * [`InitializationError`](./docs/api/appkit/Class.InitializationError.md)
35
+ * [`ServerError`](./docs/api/appkit/Class.ServerError.md)
36
+ * [`TunnelError`](./docs/api/appkit/Class.TunnelError.md)
37
+ * [`ValidationError`](./docs/api/appkit/Class.ValidationError.md)
38
38
 
39
39
  ## Constructors[​](#constructors "Direct link to Constructors")
40
40
 
@@ -12,7 +12,7 @@ throw new AuthenticationError("Failed to generate credentials", { cause: origina
12
12
 
13
13
  ## Extends[​](#extends "Direct link to Extends")
14
14
 
15
- * [`AppKitError`](/appkit/docs/api/appkit/Class.AppKitError.md)
15
+ * [`AppKitError`](./docs/api/appkit/Class.AppKitError.md)
16
16
 
17
17
  ## Constructors[​](#constructors "Direct link to Constructors")
18
18
 
@@ -41,7 +41,7 @@ new AuthenticationError(message: string, options?: {
41
41
 
42
42
  #### Inherited from[​](#inherited-from "Direct link to Inherited from")
43
43
 
44
- [`AppKitError`](/appkit/docs/api/appkit/Class.AppKitError.md).[`constructor`](/appkit/docs/api/appkit/Class.AppKitError.md#constructor)
44
+ [`AppKitError`](./docs/api/appkit/Class.AppKitError.md).[`constructor`](./docs/api/appkit/Class.AppKitError.md#constructor)
45
45
 
46
46
  ## Properties[​](#properties "Direct link to Properties")
47
47
 
@@ -56,7 +56,7 @@ Optional cause of the error
56
56
 
57
57
  #### Inherited from[​](#inherited-from-1 "Direct link to Inherited from")
58
58
 
59
- [`AppKitError`](/appkit/docs/api/appkit/Class.AppKitError.md).[`cause`](/appkit/docs/api/appkit/Class.AppKitError.md#cause)
59
+ [`AppKitError`](./docs/api/appkit/Class.AppKitError.md).[`cause`](./docs/api/appkit/Class.AppKitError.md#cause)
60
60
 
61
61
  ***
62
62
 
@@ -71,7 +71,7 @@ Error code for programmatic error handling
71
71
 
72
72
  #### Overrides[​](#overrides "Direct link to Overrides")
73
73
 
74
- [`AppKitError`](/appkit/docs/api/appkit/Class.AppKitError.md).[`code`](/appkit/docs/api/appkit/Class.AppKitError.md#code)
74
+ [`AppKitError`](./docs/api/appkit/Class.AppKitError.md).[`code`](./docs/api/appkit/Class.AppKitError.md#code)
75
75
 
76
76
  ***
77
77
 
@@ -86,7 +86,7 @@ Additional context for the error
86
86
 
87
87
  #### Inherited from[​](#inherited-from-2 "Direct link to Inherited from")
88
88
 
89
- [`AppKitError`](/appkit/docs/api/appkit/Class.AppKitError.md).[`context`](/appkit/docs/api/appkit/Class.AppKitError.md#context)
89
+ [`AppKitError`](./docs/api/appkit/Class.AppKitError.md).[`context`](./docs/api/appkit/Class.AppKitError.md#context)
90
90
 
91
91
  ***
92
92
 
@@ -101,7 +101,7 @@ Whether this error type is generally safe to retry
101
101
 
102
102
  #### Overrides[​](#overrides-1 "Direct link to Overrides")
103
103
 
104
- [`AppKitError`](/appkit/docs/api/appkit/Class.AppKitError.md).[`isRetryable`](/appkit/docs/api/appkit/Class.AppKitError.md#isretryable)
104
+ [`AppKitError`](./docs/api/appkit/Class.AppKitError.md).[`isRetryable`](./docs/api/appkit/Class.AppKitError.md#isretryable)
105
105
 
106
106
  ***
107
107
 
@@ -116,7 +116,7 @@ HTTP status code suggestion (can be overridden)
116
116
 
117
117
  #### Overrides[​](#overrides-2 "Direct link to Overrides")
118
118
 
119
- [`AppKitError`](/appkit/docs/api/appkit/Class.AppKitError.md).[`statusCode`](/appkit/docs/api/appkit/Class.AppKitError.md#statuscode)
119
+ [`AppKitError`](./docs/api/appkit/Class.AppKitError.md).[`statusCode`](./docs/api/appkit/Class.AppKitError.md#statuscode)
120
120
 
121
121
  ## Methods[​](#methods "Direct link to Methods")
122
122
 
@@ -135,7 +135,7 @@ Convert error to JSON for logging/serialization. Sensitive values in context are
135
135
 
136
136
  #### Inherited from[​](#inherited-from-3 "Direct link to Inherited from")
137
137
 
138
- [`AppKitError`](/appkit/docs/api/appkit/Class.AppKitError.md).[`toJSON`](/appkit/docs/api/appkit/Class.AppKitError.md#tojson)
138
+ [`AppKitError`](./docs/api/appkit/Class.AppKitError.md).[`toJSON`](./docs/api/appkit/Class.AppKitError.md#tojson)
139
139
 
140
140
  ***
141
141
 
@@ -154,7 +154,7 @@ Create a human-readable string representation
154
154
 
155
155
  #### Inherited from[​](#inherited-from-4 "Direct link to Inherited from")
156
156
 
157
- [`AppKitError`](/appkit/docs/api/appkit/Class.AppKitError.md).[`toString`](/appkit/docs/api/appkit/Class.AppKitError.md#tostring)
157
+ [`AppKitError`](./docs/api/appkit/Class.AppKitError.md).[`toString`](./docs/api/appkit/Class.AppKitError.md#tostring)
158
158
 
159
159
  ***
160
160
 
@@ -12,7 +12,7 @@ throw new ConfigurationError("Warehouse ID not found", { context: { env: "produc
12
12
 
13
13
  ## Extends[​](#extends "Direct link to Extends")
14
14
 
15
- * [`AppKitError`](/appkit/docs/api/appkit/Class.AppKitError.md)
15
+ * [`AppKitError`](./docs/api/appkit/Class.AppKitError.md)
16
16
 
17
17
  ## Constructors[​](#constructors "Direct link to Constructors")
18
18
 
@@ -41,7 +41,7 @@ new ConfigurationError(message: string, options?: {
41
41
 
42
42
  #### Inherited from[​](#inherited-from "Direct link to Inherited from")
43
43
 
44
- [`AppKitError`](/appkit/docs/api/appkit/Class.AppKitError.md).[`constructor`](/appkit/docs/api/appkit/Class.AppKitError.md#constructor)
44
+ [`AppKitError`](./docs/api/appkit/Class.AppKitError.md).[`constructor`](./docs/api/appkit/Class.AppKitError.md#constructor)
45
45
 
46
46
  ## Properties[​](#properties "Direct link to Properties")
47
47
 
@@ -56,7 +56,7 @@ Optional cause of the error
56
56
 
57
57
  #### Inherited from[​](#inherited-from-1 "Direct link to Inherited from")
58
58
 
59
- [`AppKitError`](/appkit/docs/api/appkit/Class.AppKitError.md).[`cause`](/appkit/docs/api/appkit/Class.AppKitError.md#cause)
59
+ [`AppKitError`](./docs/api/appkit/Class.AppKitError.md).[`cause`](./docs/api/appkit/Class.AppKitError.md#cause)
60
60
 
61
61
  ***
62
62
 
@@ -71,7 +71,7 @@ Error code for programmatic error handling
71
71
 
72
72
  #### Overrides[​](#overrides "Direct link to Overrides")
73
73
 
74
- [`AppKitError`](/appkit/docs/api/appkit/Class.AppKitError.md).[`code`](/appkit/docs/api/appkit/Class.AppKitError.md#code)
74
+ [`AppKitError`](./docs/api/appkit/Class.AppKitError.md).[`code`](./docs/api/appkit/Class.AppKitError.md#code)
75
75
 
76
76
  ***
77
77
 
@@ -86,7 +86,7 @@ Additional context for the error
86
86
 
87
87
  #### Inherited from[​](#inherited-from-2 "Direct link to Inherited from")
88
88
 
89
- [`AppKitError`](/appkit/docs/api/appkit/Class.AppKitError.md).[`context`](/appkit/docs/api/appkit/Class.AppKitError.md#context)
89
+ [`AppKitError`](./docs/api/appkit/Class.AppKitError.md).[`context`](./docs/api/appkit/Class.AppKitError.md#context)
90
90
 
91
91
  ***
92
92
 
@@ -101,7 +101,7 @@ Whether this error type is generally safe to retry
101
101
 
102
102
  #### Overrides[​](#overrides-1 "Direct link to Overrides")
103
103
 
104
- [`AppKitError`](/appkit/docs/api/appkit/Class.AppKitError.md).[`isRetryable`](/appkit/docs/api/appkit/Class.AppKitError.md#isretryable)
104
+ [`AppKitError`](./docs/api/appkit/Class.AppKitError.md).[`isRetryable`](./docs/api/appkit/Class.AppKitError.md#isretryable)
105
105
 
106
106
  ***
107
107
 
@@ -116,7 +116,7 @@ HTTP status code suggestion (can be overridden)
116
116
 
117
117
  #### Overrides[​](#overrides-2 "Direct link to Overrides")
118
118
 
119
- [`AppKitError`](/appkit/docs/api/appkit/Class.AppKitError.md).[`statusCode`](/appkit/docs/api/appkit/Class.AppKitError.md#statuscode)
119
+ [`AppKitError`](./docs/api/appkit/Class.AppKitError.md).[`statusCode`](./docs/api/appkit/Class.AppKitError.md#statuscode)
120
120
 
121
121
  ## Methods[​](#methods "Direct link to Methods")
122
122
 
@@ -135,7 +135,7 @@ Convert error to JSON for logging/serialization. Sensitive values in context are
135
135
 
136
136
  #### Inherited from[​](#inherited-from-3 "Direct link to Inherited from")
137
137
 
138
- [`AppKitError`](/appkit/docs/api/appkit/Class.AppKitError.md).[`toJSON`](/appkit/docs/api/appkit/Class.AppKitError.md#tojson)
138
+ [`AppKitError`](./docs/api/appkit/Class.AppKitError.md).[`toJSON`](./docs/api/appkit/Class.AppKitError.md#tojson)
139
139
 
140
140
  ***
141
141
 
@@ -154,7 +154,7 @@ Create a human-readable string representation
154
154
 
155
155
  #### Inherited from[​](#inherited-from-4 "Direct link to Inherited from")
156
156
 
157
- [`AppKitError`](/appkit/docs/api/appkit/Class.AppKitError.md).[`toString`](/appkit/docs/api/appkit/Class.AppKitError.md#tostring)
157
+ [`AppKitError`](./docs/api/appkit/Class.AppKitError.md).[`toString`](./docs/api/appkit/Class.AppKitError.md#tostring)
158
158
 
159
159
  ***
160
160
 
@@ -12,7 +12,7 @@ throw new ConnectionError("No response received from SQL Warehouse API");
12
12
 
13
13
  ## Extends[​](#extends "Direct link to Extends")
14
14
 
15
- * [`AppKitError`](/appkit/docs/api/appkit/Class.AppKitError.md)
15
+ * [`AppKitError`](./docs/api/appkit/Class.AppKitError.md)
16
16
 
17
17
  ## Constructors[​](#constructors "Direct link to Constructors")
18
18
 
@@ -41,7 +41,7 @@ new ConnectionError(message: string, options?: {
41
41
 
42
42
  #### Inherited from[​](#inherited-from "Direct link to Inherited from")
43
43
 
44
- [`AppKitError`](/appkit/docs/api/appkit/Class.AppKitError.md).[`constructor`](/appkit/docs/api/appkit/Class.AppKitError.md#constructor)
44
+ [`AppKitError`](./docs/api/appkit/Class.AppKitError.md).[`constructor`](./docs/api/appkit/Class.AppKitError.md#constructor)
45
45
 
46
46
  ## Properties[​](#properties "Direct link to Properties")
47
47
 
@@ -56,7 +56,7 @@ Optional cause of the error
56
56
 
57
57
  #### Inherited from[​](#inherited-from-1 "Direct link to Inherited from")
58
58
 
59
- [`AppKitError`](/appkit/docs/api/appkit/Class.AppKitError.md).[`cause`](/appkit/docs/api/appkit/Class.AppKitError.md#cause)
59
+ [`AppKitError`](./docs/api/appkit/Class.AppKitError.md).[`cause`](./docs/api/appkit/Class.AppKitError.md#cause)
60
60
 
61
61
  ***
62
62
 
@@ -71,7 +71,7 @@ Error code for programmatic error handling
71
71
 
72
72
  #### Overrides[​](#overrides "Direct link to Overrides")
73
73
 
74
- [`AppKitError`](/appkit/docs/api/appkit/Class.AppKitError.md).[`code`](/appkit/docs/api/appkit/Class.AppKitError.md#code)
74
+ [`AppKitError`](./docs/api/appkit/Class.AppKitError.md).[`code`](./docs/api/appkit/Class.AppKitError.md#code)
75
75
 
76
76
  ***
77
77
 
@@ -86,7 +86,7 @@ Additional context for the error
86
86
 
87
87
  #### Inherited from[​](#inherited-from-2 "Direct link to Inherited from")
88
88
 
89
- [`AppKitError`](/appkit/docs/api/appkit/Class.AppKitError.md).[`context`](/appkit/docs/api/appkit/Class.AppKitError.md#context)
89
+ [`AppKitError`](./docs/api/appkit/Class.AppKitError.md).[`context`](./docs/api/appkit/Class.AppKitError.md#context)
90
90
 
91
91
  ***
92
92
 
@@ -101,7 +101,7 @@ Whether this error type is generally safe to retry
101
101
 
102
102
  #### Overrides[​](#overrides-1 "Direct link to Overrides")
103
103
 
104
- [`AppKitError`](/appkit/docs/api/appkit/Class.AppKitError.md).[`isRetryable`](/appkit/docs/api/appkit/Class.AppKitError.md#isretryable)
104
+ [`AppKitError`](./docs/api/appkit/Class.AppKitError.md).[`isRetryable`](./docs/api/appkit/Class.AppKitError.md#isretryable)
105
105
 
106
106
  ***
107
107
 
@@ -116,7 +116,7 @@ HTTP status code suggestion (can be overridden)
116
116
 
117
117
  #### Overrides[​](#overrides-2 "Direct link to Overrides")
118
118
 
119
- [`AppKitError`](/appkit/docs/api/appkit/Class.AppKitError.md).[`statusCode`](/appkit/docs/api/appkit/Class.AppKitError.md#statuscode)
119
+ [`AppKitError`](./docs/api/appkit/Class.AppKitError.md).[`statusCode`](./docs/api/appkit/Class.AppKitError.md#statuscode)
120
120
 
121
121
  ## Methods[​](#methods "Direct link to Methods")
122
122
 
@@ -135,7 +135,7 @@ Convert error to JSON for logging/serialization. Sensitive values in context are
135
135
 
136
136
  #### Inherited from[​](#inherited-from-3 "Direct link to Inherited from")
137
137
 
138
- [`AppKitError`](/appkit/docs/api/appkit/Class.AppKitError.md).[`toJSON`](/appkit/docs/api/appkit/Class.AppKitError.md#tojson)
138
+ [`AppKitError`](./docs/api/appkit/Class.AppKitError.md).[`toJSON`](./docs/api/appkit/Class.AppKitError.md#tojson)
139
139
 
140
140
  ***
141
141
 
@@ -154,7 +154,7 @@ Create a human-readable string representation
154
154
 
155
155
  #### Inherited from[​](#inherited-from-4 "Direct link to Inherited from")
156
156
 
157
- [`AppKitError`](/appkit/docs/api/appkit/Class.AppKitError.md).[`toString`](/appkit/docs/api/appkit/Class.AppKitError.md#tostring)
157
+ [`AppKitError`](./docs/api/appkit/Class.AppKitError.md).[`toString`](./docs/api/appkit/Class.AppKitError.md#tostring)
158
158
 
159
159
  ***
160
160