@databricks/appkit-ui 0.1.3 → 0.1.5

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 (105) hide show
  1. package/AGENTS.md +1179 -0
  2. package/CLAUDE.md +1178 -2
  3. package/NOTICE.md +2 -0
  4. package/bin/setup-claude.js +1 -1
  5. package/dist/js/arrow/arrow-client.js.map +1 -1
  6. package/dist/js/arrow/lazy-arrow.js.map +1 -1
  7. package/dist/js/sse/connect-sse.js.map +1 -1
  8. package/dist/react/charts/area/index.d.ts +2 -2
  9. package/dist/react/charts/bar/index.d.ts +2 -2
  10. package/dist/react/charts/base.d.ts +2 -2
  11. package/dist/react/charts/base.js.map +1 -1
  12. package/dist/react/charts/create-chart.d.ts +2 -2
  13. package/dist/react/charts/create-chart.js +2 -1
  14. package/dist/react/charts/create-chart.js.map +1 -1
  15. package/dist/react/charts/heatmap/index.d.ts +2 -2
  16. package/dist/react/charts/line/index.d.ts +2 -2
  17. package/dist/react/charts/normalize.d.ts +1 -1
  18. package/dist/react/charts/normalize.js +1 -1
  19. package/dist/react/charts/normalize.js.map +1 -1
  20. package/dist/react/charts/pie/index.d.ts +3 -3
  21. package/dist/react/charts/radar/index.d.ts +2 -2
  22. package/dist/react/charts/scatter/index.d.ts +2 -2
  23. package/dist/react/charts/theme.js.map +1 -1
  24. package/dist/react/charts/types.d.ts +5 -0
  25. package/dist/react/charts/types.d.ts.map +1 -1
  26. package/dist/react/charts/types.js.map +1 -1
  27. package/dist/react/charts/utils.js.map +1 -1
  28. package/dist/react/charts/wrapper.d.ts +4 -2
  29. package/dist/react/charts/wrapper.d.ts.map +1 -1
  30. package/dist/react/charts/wrapper.js +4 -2
  31. package/dist/react/charts/wrapper.js.map +1 -1
  32. package/dist/react/hooks/types.d.ts +2 -0
  33. package/dist/react/hooks/types.d.ts.map +1 -1
  34. package/dist/react/hooks/use-analytics-query.js +9 -3
  35. package/dist/react/hooks/use-analytics-query.js.map +1 -1
  36. package/dist/react/hooks/use-chart-data.d.ts +2 -0
  37. package/dist/react/hooks/use-chart-data.d.ts.map +1 -1
  38. package/dist/react/hooks/use-chart-data.js +3 -2
  39. package/dist/react/hooks/use-chart-data.js.map +1 -1
  40. package/dist/react/table/data-table.d.ts +2 -2
  41. package/dist/react/table/data-table.d.ts.map +1 -1
  42. package/dist/react/table/table-wrapper.js +3 -2
  43. package/dist/react/table/table-wrapper.js.map +1 -1
  44. package/dist/react/table/types.d.ts.map +1 -1
  45. package/dist/react/ui/accordion.d.ts +5 -5
  46. package/dist/react/ui/alert-dialog.d.ts +12 -12
  47. package/dist/react/ui/alert-dialog.d.ts.map +1 -1
  48. package/dist/react/ui/alert.d.ts +4 -4
  49. package/dist/react/ui/aspect-ratio.d.ts +2 -2
  50. package/dist/react/ui/avatar.d.ts +4 -4
  51. package/dist/react/ui/badge.d.ts +2 -2
  52. package/dist/react/ui/breadcrumb.d.ts +8 -8
  53. package/dist/react/ui/button-group.d.ts +4 -4
  54. package/dist/react/ui/button.d.ts +2 -2
  55. package/dist/react/ui/calendar.d.ts +3 -3
  56. package/dist/react/ui/card.d.ts +8 -8
  57. package/dist/react/ui/carousel.d.ts +6 -6
  58. package/dist/react/ui/chart.d.ts +5 -5
  59. package/dist/react/ui/chart.d.ts.map +1 -1
  60. package/dist/react/ui/chart.js.map +1 -1
  61. package/dist/react/ui/checkbox.d.ts +2 -2
  62. package/dist/react/ui/collapsible.d.ts +4 -4
  63. package/dist/react/ui/command.d.ts +10 -10
  64. package/dist/react/ui/context-menu.d.ts +16 -16
  65. package/dist/react/ui/dialog.d.ts +11 -11
  66. package/dist/react/ui/drawer.d.ts +11 -11
  67. package/dist/react/ui/dropdown-menu.d.ts +16 -16
  68. package/dist/react/ui/dropdown-menu.d.ts.map +1 -1
  69. package/dist/react/ui/empty.d.ts +7 -7
  70. package/dist/react/ui/field.d.ts +11 -11
  71. package/dist/react/ui/form.d.ts +7 -7
  72. package/dist/react/ui/hover-card.d.ts +4 -4
  73. package/dist/react/ui/input-group.d.ts +7 -7
  74. package/dist/react/ui/input-otp.d.ts +5 -5
  75. package/dist/react/ui/input.d.ts +2 -2
  76. package/dist/react/ui/item.d.ts +11 -11
  77. package/dist/react/ui/kbd.d.ts +3 -3
  78. package/dist/react/ui/label.d.ts +2 -2
  79. package/dist/react/ui/menubar.d.ts +17 -17
  80. package/dist/react/ui/navigation-menu.d.ts +9 -9
  81. package/dist/react/ui/pagination.d.ts +8 -8
  82. package/dist/react/ui/popover.d.ts +5 -5
  83. package/dist/react/ui/progress.d.ts +2 -2
  84. package/dist/react/ui/radio-group.d.ts +3 -3
  85. package/dist/react/ui/resizable.d.ts +4 -4
  86. package/dist/react/ui/scroll-area.d.ts +3 -3
  87. package/dist/react/ui/select.d.ts +11 -11
  88. package/dist/react/ui/separator.d.ts +2 -2
  89. package/dist/react/ui/sheet.d.ts +9 -9
  90. package/dist/react/ui/sidebar.d.ts +24 -24
  91. package/dist/react/ui/skeleton.d.ts +2 -2
  92. package/dist/react/ui/slider.d.ts +2 -2
  93. package/dist/react/ui/sonner.d.ts +2 -2
  94. package/dist/react/ui/spinner.d.ts +2 -2
  95. package/dist/react/ui/switch.d.ts +2 -2
  96. package/dist/react/ui/table.d.ts +9 -9
  97. package/dist/react/ui/tabs.d.ts +5 -5
  98. package/dist/react/ui/textarea.d.ts +2 -2
  99. package/dist/react/ui/toggle-group.d.ts +3 -3
  100. package/dist/react/ui/toggle.d.ts +2 -2
  101. package/dist/react/ui/tooltip.d.ts +5 -5
  102. package/dist/react/ui/tooltip.d.ts.map +1 -1
  103. package/dist/shared/src/sql/helpers.js.map +1 -1
  104. package/llms.txt +160 -58
  105. package/package.json +3 -2
@@ -1,10 +1,10 @@
1
- import * as react_jsx_runtime256 from "react/jsx-runtime";
1
+ import * as react_jsx_runtime251 from "react/jsx-runtime";
2
2
 
3
3
  //#region src/react/ui/spinner.d.ts
4
4
  declare function Spinner({
5
5
  className,
6
6
  ...props
7
- }: React.ComponentProps<"svg">): react_jsx_runtime256.JSX.Element;
7
+ }: React.ComponentProps<"svg">): react_jsx_runtime251.JSX.Element;
8
8
  //#endregion
9
9
  export { Spinner };
10
10
  //# sourceMappingURL=spinner.d.ts.map
@@ -1,12 +1,12 @@
1
1
  import * as React from "react";
2
- import * as react_jsx_runtime257 from "react/jsx-runtime";
2
+ import * as react_jsx_runtime252 from "react/jsx-runtime";
3
3
  import * as SwitchPrimitive from "@radix-ui/react-switch";
4
4
 
5
5
  //#region src/react/ui/switch.d.ts
6
6
  declare function Switch({
7
7
  className,
8
8
  ...props
9
- }: React.ComponentProps<typeof SwitchPrimitive.Root>): react_jsx_runtime257.JSX.Element;
9
+ }: React.ComponentProps<typeof SwitchPrimitive.Root>): react_jsx_runtime252.JSX.Element;
10
10
  //#endregion
11
11
  export { Switch };
12
12
  //# sourceMappingURL=switch.d.ts.map
@@ -1,39 +1,39 @@
1
1
  import * as React from "react";
2
- import * as react_jsx_runtime258 from "react/jsx-runtime";
2
+ import * as react_jsx_runtime253 from "react/jsx-runtime";
3
3
 
4
4
  //#region src/react/ui/table.d.ts
5
5
  declare function Table({
6
6
  className,
7
7
  ...props
8
- }: React.ComponentProps<"table">): react_jsx_runtime258.JSX.Element;
8
+ }: React.ComponentProps<"table">): react_jsx_runtime253.JSX.Element;
9
9
  declare function TableHeader({
10
10
  className,
11
11
  ...props
12
- }: React.ComponentProps<"thead">): react_jsx_runtime258.JSX.Element;
12
+ }: React.ComponentProps<"thead">): react_jsx_runtime253.JSX.Element;
13
13
  declare function TableBody({
14
14
  className,
15
15
  ...props
16
- }: React.ComponentProps<"tbody">): react_jsx_runtime258.JSX.Element;
16
+ }: React.ComponentProps<"tbody">): react_jsx_runtime253.JSX.Element;
17
17
  declare function TableFooter({
18
18
  className,
19
19
  ...props
20
- }: React.ComponentProps<"tfoot">): react_jsx_runtime258.JSX.Element;
20
+ }: React.ComponentProps<"tfoot">): react_jsx_runtime253.JSX.Element;
21
21
  declare function TableRow({
22
22
  className,
23
23
  ...props
24
- }: React.ComponentProps<"tr">): react_jsx_runtime258.JSX.Element;
24
+ }: React.ComponentProps<"tr">): react_jsx_runtime253.JSX.Element;
25
25
  declare function TableHead({
26
26
  className,
27
27
  ...props
28
- }: React.ComponentProps<"th">): react_jsx_runtime258.JSX.Element;
28
+ }: React.ComponentProps<"th">): react_jsx_runtime253.JSX.Element;
29
29
  declare function TableCell({
30
30
  className,
31
31
  ...props
32
- }: React.ComponentProps<"td">): react_jsx_runtime258.JSX.Element;
32
+ }: React.ComponentProps<"td">): react_jsx_runtime253.JSX.Element;
33
33
  declare function TableCaption({
34
34
  className,
35
35
  ...props
36
- }: React.ComponentProps<"caption">): react_jsx_runtime258.JSX.Element;
36
+ }: React.ComponentProps<"caption">): react_jsx_runtime253.JSX.Element;
37
37
  //#endregion
38
38
  export { Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow };
39
39
  //# sourceMappingURL=table.d.ts.map
@@ -1,24 +1,24 @@
1
1
  import * as React from "react";
2
- import * as react_jsx_runtime266 from "react/jsx-runtime";
2
+ import * as react_jsx_runtime261 from "react/jsx-runtime";
3
3
  import * as TabsPrimitive from "@radix-ui/react-tabs";
4
4
 
5
5
  //#region src/react/ui/tabs.d.ts
6
6
  declare function Tabs({
7
7
  className,
8
8
  ...props
9
- }: React.ComponentProps<typeof TabsPrimitive.Root>): react_jsx_runtime266.JSX.Element;
9
+ }: React.ComponentProps<typeof TabsPrimitive.Root>): react_jsx_runtime261.JSX.Element;
10
10
  declare function TabsList({
11
11
  className,
12
12
  ...props
13
- }: React.ComponentProps<typeof TabsPrimitive.List>): react_jsx_runtime266.JSX.Element;
13
+ }: React.ComponentProps<typeof TabsPrimitive.List>): react_jsx_runtime261.JSX.Element;
14
14
  declare function TabsTrigger({
15
15
  className,
16
16
  ...props
17
- }: React.ComponentProps<typeof TabsPrimitive.Trigger>): react_jsx_runtime266.JSX.Element;
17
+ }: React.ComponentProps<typeof TabsPrimitive.Trigger>): react_jsx_runtime261.JSX.Element;
18
18
  declare function TabsContent({
19
19
  className,
20
20
  ...props
21
- }: React.ComponentProps<typeof TabsPrimitive.Content>): react_jsx_runtime266.JSX.Element;
21
+ }: React.ComponentProps<typeof TabsPrimitive.Content>): react_jsx_runtime261.JSX.Element;
22
22
  //#endregion
23
23
  export { Tabs, TabsContent, TabsList, TabsTrigger };
24
24
  //# sourceMappingURL=tabs.d.ts.map
@@ -1,11 +1,11 @@
1
1
  import * as React from "react";
2
- import * as react_jsx_runtime270 from "react/jsx-runtime";
2
+ import * as react_jsx_runtime265 from "react/jsx-runtime";
3
3
 
4
4
  //#region src/react/ui/textarea.d.ts
5
5
  declare function Textarea({
6
6
  className,
7
7
  ...props
8
- }: React.ComponentProps<"textarea">): react_jsx_runtime270.JSX.Element;
8
+ }: React.ComponentProps<"textarea">): react_jsx_runtime265.JSX.Element;
9
9
  //#endregion
10
10
  export { Textarea };
11
11
  //# sourceMappingURL=textarea.d.ts.map
@@ -1,6 +1,6 @@
1
1
  import { toggleVariants } from "./toggle.js";
2
2
  import * as React from "react";
3
- import * as react_jsx_runtime272 from "react/jsx-runtime";
3
+ import * as react_jsx_runtime267 from "react/jsx-runtime";
4
4
  import { VariantProps } from "class-variance-authority";
5
5
  import * as ToggleGroupPrimitive from "@radix-ui/react-toggle-group";
6
6
 
@@ -14,14 +14,14 @@ declare function ToggleGroup({
14
14
  ...props
15
15
  }: React.ComponentProps<typeof ToggleGroupPrimitive.Root> & VariantProps<typeof toggleVariants> & {
16
16
  spacing?: number;
17
- }): react_jsx_runtime272.JSX.Element;
17
+ }): react_jsx_runtime267.JSX.Element;
18
18
  declare function ToggleGroupItem({
19
19
  className,
20
20
  children,
21
21
  variant,
22
22
  size,
23
23
  ...props
24
- }: React.ComponentProps<typeof ToggleGroupPrimitive.Item> & VariantProps<typeof toggleVariants>): react_jsx_runtime272.JSX.Element;
24
+ }: React.ComponentProps<typeof ToggleGroupPrimitive.Item> & VariantProps<typeof toggleVariants>): react_jsx_runtime267.JSX.Element;
25
25
  //#endregion
26
26
  export { ToggleGroup, ToggleGroupItem };
27
27
  //# sourceMappingURL=toggle-group.d.ts.map
@@ -1,5 +1,5 @@
1
1
  import * as React from "react";
2
- import * as react_jsx_runtime271 from "react/jsx-runtime";
2
+ import * as react_jsx_runtime266 from "react/jsx-runtime";
3
3
  import { VariantProps } from "class-variance-authority";
4
4
  import * as TogglePrimitive from "@radix-ui/react-toggle";
5
5
  import * as class_variance_authority_types11 from "class-variance-authority/types";
@@ -14,7 +14,7 @@ declare function Toggle({
14
14
  variant,
15
15
  size,
16
16
  ...props
17
- }: React.ComponentProps<typeof TogglePrimitive.Root> & VariantProps<typeof toggleVariants>): react_jsx_runtime271.JSX.Element;
17
+ }: React.ComponentProps<typeof TogglePrimitive.Root> & VariantProps<typeof toggleVariants>): react_jsx_runtime266.JSX.Element;
18
18
  //#endregion
19
19
  export { Toggle, toggleVariants };
20
20
  //# sourceMappingURL=toggle.d.ts.map
@@ -1,24 +1,24 @@
1
1
  import * as React from "react";
2
- import * as react_jsx_runtime0 from "react/jsx-runtime";
2
+ import * as react_jsx_runtime269 from "react/jsx-runtime";
3
3
  import * as TooltipPrimitive from "@radix-ui/react-tooltip";
4
4
 
5
5
  //#region src/react/ui/tooltip.d.ts
6
6
  declare function TooltipProvider({
7
7
  delayDuration,
8
8
  ...props
9
- }: React.ComponentProps<typeof TooltipPrimitive.Provider>): react_jsx_runtime0.JSX.Element;
9
+ }: React.ComponentProps<typeof TooltipPrimitive.Provider>): react_jsx_runtime269.JSX.Element;
10
10
  declare function Tooltip({
11
11
  ...props
12
- }: React.ComponentProps<typeof TooltipPrimitive.Root>): react_jsx_runtime0.JSX.Element;
12
+ }: React.ComponentProps<typeof TooltipPrimitive.Root>): react_jsx_runtime269.JSX.Element;
13
13
  declare function TooltipTrigger({
14
14
  ...props
15
- }: React.ComponentProps<typeof TooltipPrimitive.Trigger>): react_jsx_runtime0.JSX.Element;
15
+ }: React.ComponentProps<typeof TooltipPrimitive.Trigger>): react_jsx_runtime269.JSX.Element;
16
16
  declare function TooltipContent({
17
17
  className,
18
18
  sideOffset,
19
19
  children,
20
20
  ...props
21
- }: React.ComponentProps<typeof TooltipPrimitive.Content>): react_jsx_runtime0.JSX.Element;
21
+ }: React.ComponentProps<typeof TooltipPrimitive.Content>): react_jsx_runtime269.JSX.Element;
22
22
  //#endregion
23
23
  export { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger };
24
24
  //# sourceMappingURL=tooltip.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"tooltip.d.ts","names":[],"sources":["../../../src/react/ui/tooltip.tsx"],"sourcesContent":[],"mappings":";;;;;iBAOS,eAAA;;;GAGN,KAAA,CAAM,sBAAsB,gBAAA,CAAiB,YAAS,kBAAA,CAAA,GAAA,CAAA;iBAUhD,OAAA;;GAEN,KAAA,CAAM,sBAAsB,gBAAA,CAAiB,QAAK,kBAAA,CAAA,GAAA,CAAA;iBAQ5C,cAAA;;GAEN,KAAA,CAAM,sBAAsB,gBAAA,CAAiB,WAAQ,kBAAA,CAAA,GAAA,CAAA;AA7BI,iBAiCnD,cAAA,CA7Be;EAAA,SAAA;EAAA,UAAA;EAAA,QAAA;EAAA,GAAA;AAAA,CAAA,EAkCrB,KAAA,CAAM,cAlCe,CAAA,OAkCO,gBAAA,CAAiB,OAlCxB,CAAA,CAAA,EAkCgC,kBAAA,CAAA,GAAA,CAAA,OAlChC"}
1
+ {"version":3,"file":"tooltip.d.ts","names":[],"sources":["../../../src/react/ui/tooltip.tsx"],"sourcesContent":[],"mappings":";;;;;iBAOS,eAAA;;;GAGN,KAAA,CAAM,sBAAsB,gBAAA,CAAiB,YAAS,oBAAA,CAAA,GAAA,CAAA;iBAUhD,OAAA;;GAEN,KAAA,CAAM,sBAAsB,gBAAA,CAAiB,QAAK,oBAAA,CAAA,GAAA,CAAA;iBAQ5C,cAAA;;GAEN,KAAA,CAAM,sBAAsB,gBAAA,CAAiB,WAAQ,oBAAA,CAAA,GAAA,CAAA;AA7BI,iBAiCnD,cAAA,CA7Be;EAAA,SAAA;EAAA,UAAA;EAAA,QAAA;EAAA,GAAA;AAAA,CAAA,EAkCrB,KAAA,CAAM,cAlCe,CAAA,OAkCO,gBAAA,CAAiB,OAlCxB,CAAA,CAAA,EAkCgC,oBAAA,CAAA,GAAA,CAAA,OAlChC"}
@@ -1 +1 @@
1
- {"version":3,"file":"helpers.js","names":["dateValue: string","timestampValue: string","numValue: string","stringValue: string","booleanValue: string","hexValue: string"],"sources":["../../../../../shared/src/sql/helpers.ts"],"sourcesContent":["import type {\n SQLBinaryMarker,\n SQLBooleanMarker,\n SQLDateMarker,\n SQLNumberMarker,\n SQLStringMarker,\n SQLTimestampMarker,\n SQLTypeMarker,\n} from \"./types\";\n\n/**\n * SQL helper namespace\n */\nexport const sql = {\n /**\n * Creates a DATE type parameter\n * Accepts Date objects or ISO date strings (YYYY-MM-DD format)\n * @param value - Date object or ISO date string\n * @returns Marker object for DATE type parameter\n * @example\n * ```typescript\n * const params = { startDate: sql.date(new Date(\"2024-01-01\")) };\n * params = { startDate: \"2024-01-01\" }\n * ```\n * @example\n * ```typescript\n * const params = { startDate: sql.date(\"2024-01-01\") };\n * params = { startDate: \"2024-01-01\" }\n * ```\n */\n date(value: Date | string): SQLDateMarker {\n let dateValue: string = \"\";\n\n // check if value is a Date object\n if (value instanceof Date) {\n dateValue = value.toISOString().split(\"T\")[0];\n }\n // check if value is a string\n else if (typeof value === \"string\") {\n // validate format\n if (!/^\\d{4}-\\d{2}-\\d{2}$/.test(value)) {\n throw new Error(\n `sql.date() expects Date or ISO date string (YYYY-MM-DD format), got: ${value}`,\n );\n }\n dateValue = value;\n }\n // if value is not a Date object or string, throw an error\n else {\n throw new Error(\n `sql.date() expects Date or ISO date string (YYYY-MM-DD format), got: ${typeof value}`,\n );\n }\n\n return {\n __sql_type: \"DATE\",\n value: dateValue,\n };\n },\n\n /**\n * Creates a TIMESTAMP type parameter\n * Accepts Date objects, ISO timestamp strings, or Unix timestamp numbers\n * @param value - Date object, ISO timestamp string, or Unix timestamp number\n * @returns Marker object for TIMESTAMP type parameter\n * @example\n * ```typescript\n * const params = { createdTime: sql.timestamp(new Date(\"2024-01-01T12:00:00Z\")) };\n * params = { createdTime: \"2024-01-01T12:00:00Z\" }\n * ```\n * @example\n * ```typescript\n * const params = { createdTime: sql.timestamp(\"2024-01-01T12:00:00Z\") };\n * params = { createdTime: \"2024-01-01T12:00:00Z\" }\n * ```\n * @example\n * ```typescript\n * const params = { createdTime: sql.timestamp(1704110400000) };\n * params = { createdTime: \"2024-01-01T12:00:00Z\" }\n * ```\n */\n timestamp(value: Date | string | number): SQLTimestampMarker {\n let timestampValue: string = \"\";\n\n if (value instanceof Date) {\n timestampValue = value.toISOString().replace(/\\.000(Z|[+-])/, \"$1\");\n } else if (typeof value === \"string\") {\n const isoRegex =\n /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d{1,9})?(Z|[+-]\\d{2}:\\d{2})?$/;\n if (!isoRegex.test(value)) {\n throw new Error(\n `sql.timestamp() expects ISO timestamp string (YYYY-MM-DDTHH:MM:SS.mmmZ or YYYY-MM-DDTHH:MM:SS.mmm+HH:MM), got: ${value}`,\n );\n }\n timestampValue = value;\n } else if (typeof value === \"number\") {\n const date = new Date(value > 1e12 ? value : value * 1000);\n timestampValue = date.toISOString().replace(/\\.000(Z|[+-])/, \"$1\");\n } else {\n throw new Error(\n `sql.timestamp() expects Date, ISO timestamp string, or Unix timestamp number, got: ${typeof value}`,\n );\n }\n\n return {\n __sql_type: \"TIMESTAMP\",\n value: timestampValue,\n };\n },\n\n /**\n * Creates a NUMERIC type parameter\n * Accepts numbers or numeric strings\n * @param value - Number or numeric string\n * @returns Marker object for NUMERIC type parameter\n * @example\n * ```typescript\n * const params = { userId: sql.number(123) };\n * params = { userId: \"123\" }\n * ```\n * @example\n * ```typescript\n * const params = { userId: sql.number(\"123\") };\n * params = { userId: \"123\" }\n * ```\n */\n number(value: number | string): SQLNumberMarker {\n let numValue: string = \"\";\n\n // check if value is a number\n if (typeof value === \"number\") {\n numValue = value.toString();\n }\n // check if value is a string\n else if (typeof value === \"string\") {\n if (value === \"\" || Number.isNaN(Number(value))) {\n throw new Error(\n `sql.number() expects number or numeric string, got: ${value === \"\" ? \"empty string\" : value}`,\n );\n }\n numValue = value;\n }\n // if value is not a number or string, throw an error\n else {\n throw new Error(\n `sql.number() expects number or numeric string, got: ${typeof value}`,\n );\n }\n\n return {\n __sql_type: \"NUMERIC\",\n value: numValue,\n };\n },\n\n /**\n * Creates a STRING type parameter\n * Accepts strings, numbers, or booleans\n * @param value - String, number, or boolean\n * @returns Marker object for STRING type parameter\n * @example\n * ```typescript\n * const params = { name: sql.string(\"John\") };\n * params = { name: \"John\" }\n * ```\n * @example\n * ```typescript\n * const params = { name: sql.string(123) };\n * params = { name: \"123\" }\n * ```\n * @example\n * ```typescript\n * const params = { name: sql.string(true) };\n * params = { name: \"true\" }\n * ```\n */\n string(value: string | number | boolean): SQLStringMarker {\n if (\n typeof value !== \"string\" &&\n typeof value !== \"number\" &&\n typeof value !== \"boolean\"\n ) {\n throw new Error(\n `sql.string() expects string or number or boolean, got: ${typeof value}`,\n );\n }\n\n let stringValue: string = \"\";\n\n if (typeof value === \"string\") {\n stringValue = value;\n } else {\n stringValue = value.toString();\n }\n\n return {\n __sql_type: \"STRING\",\n value: stringValue,\n };\n },\n\n /**\n * Create a BOOLEAN type parameter\n * Accepts booleans, strings, or numbers\n * @param value - Boolean, string, or number\n * @returns Marker object for BOOLEAN type parameter\n * @example\n * ```typescript\n * const params = { isActive: sql.boolean(true) };\n * params = { isActive: \"true\" }\n * ```\n * @example\n * ```typescript\n * const params = { isActive: sql.boolean(\"true\") };\n * params = { isActive: \"true\" }\n * ```\n * @example\n * ```typescript\n * const params = { isActive: sql.boolean(1) };\n * params = { isActive: \"true\" }\n * ```\n * @example\n * ```typescript\n * const params = { isActive: sql.boolean(\"false\") };\n * params = { isActive: \"false\" }\n * ```\n * @example\n * ```typescript\n * const params = { isActive: sql.boolean(0) };\n * params = { isActive: \"false\" }\n * ```\n * @returns\n */\n boolean(value: boolean | string | number): SQLBooleanMarker {\n if (\n typeof value !== \"boolean\" &&\n typeof value !== \"string\" &&\n typeof value !== \"number\"\n ) {\n throw new Error(\n `sql.boolean() expects boolean or string (true or false) or number (1 or 0), got: ${typeof value}`,\n );\n }\n\n let booleanValue: string = \"\";\n\n if (typeof value === \"boolean\") {\n booleanValue = value.toString();\n }\n // check if value is a number\n else if (typeof value === \"number\") {\n if (value !== 1 && value !== 0) {\n throw new Error(\n `sql.boolean() expects boolean or string (true or false) or number (1 or 0), got: ${value}`,\n );\n }\n booleanValue = value === 1 ? \"true\" : \"false\";\n }\n // check if value is a string\n else if (typeof value === \"string\") {\n if (value !== \"true\" && value !== \"false\") {\n throw new Error(\n `sql.boolean() expects boolean or string (true or false) or number (1 or 0), got: ${value}`,\n );\n }\n booleanValue = value;\n }\n\n return {\n __sql_type: \"BOOLEAN\",\n value: booleanValue,\n };\n },\n\n /**\n * Creates a BINARY parameter as hex-encoded STRING\n * Accepts Uint8Array, ArrayBuffer, or hex string\n * Note: Databricks SQL Warehouse doesn't support BINARY as parameter type,\n * so this helper returns a STRING with hex encoding. Use UNHEX(:param) in your SQL.\n * @param value - Uint8Array, ArrayBuffer, or hex string\n * @returns Marker object with STRING type and hex-encoded value\n * @example\n * ```typescript\n * // From Uint8Array:\n * const params = { data: sql.binary(new Uint8Array([0x53, 0x70, 0x61, 0x72, 0x6b])) };\n * // Returns: { __sql_type: \"STRING\", value: \"537061726B\" }\n * // SQL: SELECT UNHEX(:data) as binary_value\n * ```\n * @example\n * ```typescript\n * // From hex string:\n * const params = { data: sql.binary(\"537061726B\") };\n * // Returns: { __sql_type: \"STRING\", value: \"537061726B\" }\n * ```\n */\n binary(value: Uint8Array | ArrayBuffer | string): SQLBinaryMarker {\n let hexValue: string = \"\";\n\n if (value instanceof Uint8Array) {\n // if value is a Uint8Array, convert it to a hex string\n hexValue = Array.from(value)\n .map((b) => b.toString(16).padStart(2, \"0\").toUpperCase())\n .join(\"\");\n } else if (value instanceof ArrayBuffer) {\n // if value is an ArrayBuffer, convert it to a hex string\n hexValue = Array.from(new Uint8Array(value))\n .map((b) => b.toString(16).padStart(2, \"0\").toUpperCase())\n .join(\"\");\n } else if (typeof value === \"string\") {\n // validate hex string\n if (!/^[0-9A-Fa-f]*$/.test(value)) {\n throw new Error(\n `sql.binary() expects Uint8Array, ArrayBuffer, or hex string, got invalid hex: ${value}`,\n );\n }\n hexValue = value.toUpperCase();\n } else {\n throw new Error(\n `sql.binary() expects Uint8Array, ArrayBuffer, or hex string, got: ${typeof value}`,\n );\n }\n\n return {\n __sql_type: \"STRING\",\n value: hexValue,\n };\n },\n};\n\n/**\n * Type guard to check if a value is a SQL type marker\n * @param value - Value to check\n * @returns True if the value is a SQL type marker, false otherwise\n * @example\n * ```typescript\n * const value = {\n * __sql_type: \"DATE\",\n * value: \"2024-01-01\",\n * };\n * const isSQLTypeMarker = isSQLTypeMarker(value);\n * console.log(isSQLTypeMarker); // true\n * ```\n */\nexport function isSQLTypeMarker(value: any): value is SQLTypeMarker {\n return (\n value !== null &&\n typeof value === \"object\" &&\n \"__sql_type\" in value &&\n \"value\" in value &&\n typeof value.__sql_type === \"string\" &&\n typeof value.value === \"string\"\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"helpers.js","names":[],"sources":["../../../../../shared/src/sql/helpers.ts"],"sourcesContent":["import type {\n SQLBinaryMarker,\n SQLBooleanMarker,\n SQLDateMarker,\n SQLNumberMarker,\n SQLStringMarker,\n SQLTimestampMarker,\n SQLTypeMarker,\n} from \"./types\";\n\n/**\n * SQL helper namespace\n */\nexport const sql = {\n /**\n * Creates a DATE type parameter\n * Accepts Date objects or ISO date strings (YYYY-MM-DD format)\n * @param value - Date object or ISO date string\n * @returns Marker object for DATE type parameter\n * @example\n * ```typescript\n * const params = { startDate: sql.date(new Date(\"2024-01-01\")) };\n * params = { startDate: \"2024-01-01\" }\n * ```\n * @example\n * ```typescript\n * const params = { startDate: sql.date(\"2024-01-01\") };\n * params = { startDate: \"2024-01-01\" }\n * ```\n */\n date(value: Date | string): SQLDateMarker {\n let dateValue: string = \"\";\n\n // check if value is a Date object\n if (value instanceof Date) {\n dateValue = value.toISOString().split(\"T\")[0];\n }\n // check if value is a string\n else if (typeof value === \"string\") {\n // validate format\n if (!/^\\d{4}-\\d{2}-\\d{2}$/.test(value)) {\n throw new Error(\n `sql.date() expects Date or ISO date string (YYYY-MM-DD format), got: ${value}`,\n );\n }\n dateValue = value;\n }\n // if value is not a Date object or string, throw an error\n else {\n throw new Error(\n `sql.date() expects Date or ISO date string (YYYY-MM-DD format), got: ${typeof value}`,\n );\n }\n\n return {\n __sql_type: \"DATE\",\n value: dateValue,\n };\n },\n\n /**\n * Creates a TIMESTAMP type parameter\n * Accepts Date objects, ISO timestamp strings, or Unix timestamp numbers\n * @param value - Date object, ISO timestamp string, or Unix timestamp number\n * @returns Marker object for TIMESTAMP type parameter\n * @example\n * ```typescript\n * const params = { createdTime: sql.timestamp(new Date(\"2024-01-01T12:00:00Z\")) };\n * params = { createdTime: \"2024-01-01T12:00:00Z\" }\n * ```\n * @example\n * ```typescript\n * const params = { createdTime: sql.timestamp(\"2024-01-01T12:00:00Z\") };\n * params = { createdTime: \"2024-01-01T12:00:00Z\" }\n * ```\n * @example\n * ```typescript\n * const params = { createdTime: sql.timestamp(1704110400000) };\n * params = { createdTime: \"2024-01-01T12:00:00Z\" }\n * ```\n */\n timestamp(value: Date | string | number): SQLTimestampMarker {\n let timestampValue: string = \"\";\n\n if (value instanceof Date) {\n timestampValue = value.toISOString().replace(/\\.000(Z|[+-])/, \"$1\");\n } else if (typeof value === \"string\") {\n const isoRegex =\n /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d{1,9})?(Z|[+-]\\d{2}:\\d{2})?$/;\n if (!isoRegex.test(value)) {\n throw new Error(\n `sql.timestamp() expects ISO timestamp string (YYYY-MM-DDTHH:MM:SS.mmmZ or YYYY-MM-DDTHH:MM:SS.mmm+HH:MM), got: ${value}`,\n );\n }\n timestampValue = value;\n } else if (typeof value === \"number\") {\n const date = new Date(value > 1e12 ? value : value * 1000);\n timestampValue = date.toISOString().replace(/\\.000(Z|[+-])/, \"$1\");\n } else {\n throw new Error(\n `sql.timestamp() expects Date, ISO timestamp string, or Unix timestamp number, got: ${typeof value}`,\n );\n }\n\n return {\n __sql_type: \"TIMESTAMP\",\n value: timestampValue,\n };\n },\n\n /**\n * Creates a NUMERIC type parameter\n * Accepts numbers or numeric strings\n * @param value - Number or numeric string\n * @returns Marker object for NUMERIC type parameter\n * @example\n * ```typescript\n * const params = { userId: sql.number(123) };\n * params = { userId: \"123\" }\n * ```\n * @example\n * ```typescript\n * const params = { userId: sql.number(\"123\") };\n * params = { userId: \"123\" }\n * ```\n */\n number(value: number | string): SQLNumberMarker {\n let numValue: string = \"\";\n\n // check if value is a number\n if (typeof value === \"number\") {\n numValue = value.toString();\n }\n // check if value is a string\n else if (typeof value === \"string\") {\n if (value === \"\" || Number.isNaN(Number(value))) {\n throw new Error(\n `sql.number() expects number or numeric string, got: ${value === \"\" ? \"empty string\" : value}`,\n );\n }\n numValue = value;\n }\n // if value is not a number or string, throw an error\n else {\n throw new Error(\n `sql.number() expects number or numeric string, got: ${typeof value}`,\n );\n }\n\n return {\n __sql_type: \"NUMERIC\",\n value: numValue,\n };\n },\n\n /**\n * Creates a STRING type parameter\n * Accepts strings, numbers, or booleans\n * @param value - String, number, or boolean\n * @returns Marker object for STRING type parameter\n * @example\n * ```typescript\n * const params = { name: sql.string(\"John\") };\n * params = { name: \"John\" }\n * ```\n * @example\n * ```typescript\n * const params = { name: sql.string(123) };\n * params = { name: \"123\" }\n * ```\n * @example\n * ```typescript\n * const params = { name: sql.string(true) };\n * params = { name: \"true\" }\n * ```\n */\n string(value: string | number | boolean): SQLStringMarker {\n if (\n typeof value !== \"string\" &&\n typeof value !== \"number\" &&\n typeof value !== \"boolean\"\n ) {\n throw new Error(\n `sql.string() expects string or number or boolean, got: ${typeof value}`,\n );\n }\n\n let stringValue: string = \"\";\n\n if (typeof value === \"string\") {\n stringValue = value;\n } else {\n stringValue = value.toString();\n }\n\n return {\n __sql_type: \"STRING\",\n value: stringValue,\n };\n },\n\n /**\n * Create a BOOLEAN type parameter\n * Accepts booleans, strings, or numbers\n * @param value - Boolean, string, or number\n * @returns Marker object for BOOLEAN type parameter\n * @example\n * ```typescript\n * const params = { isActive: sql.boolean(true) };\n * params = { isActive: \"true\" }\n * ```\n * @example\n * ```typescript\n * const params = { isActive: sql.boolean(\"true\") };\n * params = { isActive: \"true\" }\n * ```\n * @example\n * ```typescript\n * const params = { isActive: sql.boolean(1) };\n * params = { isActive: \"true\" }\n * ```\n * @example\n * ```typescript\n * const params = { isActive: sql.boolean(\"false\") };\n * params = { isActive: \"false\" }\n * ```\n * @example\n * ```typescript\n * const params = { isActive: sql.boolean(0) };\n * params = { isActive: \"false\" }\n * ```\n * @returns\n */\n boolean(value: boolean | string | number): SQLBooleanMarker {\n if (\n typeof value !== \"boolean\" &&\n typeof value !== \"string\" &&\n typeof value !== \"number\"\n ) {\n throw new Error(\n `sql.boolean() expects boolean or string (true or false) or number (1 or 0), got: ${typeof value}`,\n );\n }\n\n let booleanValue: string = \"\";\n\n if (typeof value === \"boolean\") {\n booleanValue = value.toString();\n }\n // check if value is a number\n else if (typeof value === \"number\") {\n if (value !== 1 && value !== 0) {\n throw new Error(\n `sql.boolean() expects boolean or string (true or false) or number (1 or 0), got: ${value}`,\n );\n }\n booleanValue = value === 1 ? \"true\" : \"false\";\n }\n // check if value is a string\n else if (typeof value === \"string\") {\n if (value !== \"true\" && value !== \"false\") {\n throw new Error(\n `sql.boolean() expects boolean or string (true or false) or number (1 or 0), got: ${value}`,\n );\n }\n booleanValue = value;\n }\n\n return {\n __sql_type: \"BOOLEAN\",\n value: booleanValue,\n };\n },\n\n /**\n * Creates a BINARY parameter as hex-encoded STRING\n * Accepts Uint8Array, ArrayBuffer, or hex string\n * Note: Databricks SQL Warehouse doesn't support BINARY as parameter type,\n * so this helper returns a STRING with hex encoding. Use UNHEX(:param) in your SQL.\n * @param value - Uint8Array, ArrayBuffer, or hex string\n * @returns Marker object with STRING type and hex-encoded value\n * @example\n * ```typescript\n * // From Uint8Array:\n * const params = { data: sql.binary(new Uint8Array([0x53, 0x70, 0x61, 0x72, 0x6b])) };\n * // Returns: { __sql_type: \"STRING\", value: \"537061726B\" }\n * // SQL: SELECT UNHEX(:data) as binary_value\n * ```\n * @example\n * ```typescript\n * // From hex string:\n * const params = { data: sql.binary(\"537061726B\") };\n * // Returns: { __sql_type: \"STRING\", value: \"537061726B\" }\n * ```\n */\n binary(value: Uint8Array | ArrayBuffer | string): SQLBinaryMarker {\n let hexValue: string = \"\";\n\n if (value instanceof Uint8Array) {\n // if value is a Uint8Array, convert it to a hex string\n hexValue = Array.from(value)\n .map((b) => b.toString(16).padStart(2, \"0\").toUpperCase())\n .join(\"\");\n } else if (value instanceof ArrayBuffer) {\n // if value is an ArrayBuffer, convert it to a hex string\n hexValue = Array.from(new Uint8Array(value))\n .map((b) => b.toString(16).padStart(2, \"0\").toUpperCase())\n .join(\"\");\n } else if (typeof value === \"string\") {\n // validate hex string\n if (!/^[0-9A-Fa-f]*$/.test(value)) {\n throw new Error(\n `sql.binary() expects Uint8Array, ArrayBuffer, or hex string, got invalid hex: ${value}`,\n );\n }\n hexValue = value.toUpperCase();\n } else {\n throw new Error(\n `sql.binary() expects Uint8Array, ArrayBuffer, or hex string, got: ${typeof value}`,\n );\n }\n\n return {\n __sql_type: \"STRING\",\n value: hexValue,\n };\n },\n};\n\n/**\n * Type guard to check if a value is a SQL type marker\n * @param value - Value to check\n * @returns True if the value is a SQL type marker, false otherwise\n * @example\n * ```typescript\n * const value = {\n * __sql_type: \"DATE\",\n * value: \"2024-01-01\",\n * };\n * const isSQLTypeMarker = isSQLTypeMarker(value);\n * console.log(isSQLTypeMarker); // true\n * ```\n */\nexport function isSQLTypeMarker(value: any): value is SQLTypeMarker {\n return (\n value !== null &&\n typeof value === \"object\" &&\n \"__sql_type\" in value &&\n \"value\" in value &&\n typeof value.__sql_type === \"string\" &&\n typeof value.value === \"string\"\n );\n}\n"],"mappings":"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"}
package/llms.txt CHANGED
@@ -75,46 +75,24 @@ Why this layout:
75
75
  "dev": "NODE_ENV=development tsx watch server/index.ts",
76
76
  "build": "npm run build:server && npm run build:client",
77
77
  "build:server": "tsdown --out-dir build server/index.ts",
78
- "build:client": "cd client && npm run build",
78
+ "build:client": "tsc -b && vite build --config client/vite.config.ts",
79
79
  "start": "node build/index.mjs"
80
80
  },
81
81
  "dependencies": {
82
- "@databricks/appkit": "^0.0.2"
82
+ "@databricks/appkit": "^0.1.2"
83
+ "@databricks/appkit-ui": "^0.1.2",
84
+ "react": "^19.2.3",
85
+ "react-dom": "^19.2.3"
83
86
  },
84
87
  "devDependencies": {
85
88
  "@types/node": "^20.0.0",
89
+ "@types/react": "^19.0.0",
90
+ "@types/react-dom": "^19.0.0",
91
+ "@vitejs/plugin-react": "^5.1.1",
86
92
  "tsdown": "^0.15.7",
87
93
  "tsx": "^4.19.0",
88
- "typescript": "~5.6.0"
89
- }
90
- }
91
- ```
92
-
93
- ### `client/package.json`
94
-
95
- ```json
96
- {
97
- "name": "client",
98
- "private": true,
99
- "version": "0.0.0",
100
- "type": "module",
101
- "scripts": {
102
- "dev": "vite",
103
- "build": "vite build",
104
- "preview": "vite preview"
105
- },
106
- "dependencies": {
107
- "@databricks/appkit-ui": "^0.0.2",
108
- "react": "^18.0.0",
109
- "react-dom": "^18.0.0",
110
- "recharts": "^3.0.0"
111
- },
112
- "devDependencies": {
113
- "@types/react": "^18.0.0",
114
- "@types/react-dom": "^18.0.0",
115
- "@vitejs/plugin-react": "^5.0.0",
116
94
  "typescript": "~5.6.0",
117
- "vite": "^6.0.0"
95
+ "vite": "^7.2.4"
118
96
  }
119
97
  }
120
98
  ```
@@ -208,7 +186,6 @@ await createApp({
208
186
  ```bash
209
187
  # Install dependencies
210
188
  npm install
211
- cd client && npm install && cd ..
212
189
 
213
190
  # Development (starts backend + Vite dev server)
214
191
  npm run dev
@@ -225,19 +202,14 @@ If you already have a React/Vite app and want to add AppKit:
225
202
  ### 1. Install dependencies
226
203
 
227
204
  ```bash
228
- npm install @databricks/appkit
229
- npm install -D tsx tsdown
205
+ npm install @databricks/appkit @databricks/appkit-ui react react-dom
206
+ npm install -D tsx tsdown vite @vitejs/plugin-react typescript
230
207
 
231
208
  # If you don't already have a client/ folder, create one and move your Vite app into it:
232
209
  # - move index.html -> client/index.html
233
210
  # - move vite.config.ts -> client/vite.config.ts
234
211
  # - move src/ -> client/src/
235
212
  #
236
- # Then install client deps:
237
- cd client
238
- npm install @databricks/appkit-ui react react-dom recharts
239
- npm install -D vite @vitejs/plugin-react typescript
240
- cd ..
241
213
  ```
242
214
 
243
215
  ### 2. Create `server/index.ts` (new file)
@@ -258,7 +230,7 @@ await createApp({
258
230
  "dev": "NODE_ENV=development tsx watch server/index.ts",
259
231
  "build": "npm run build:server && npm run build:client",
260
232
  "build:server": "tsdown --out-dir build server/index.ts",
261
- "build:client": "cd client && npm run build",
233
+ "build:client": "tsc -b && vite build --config client/vite.config.ts",
262
234
  "start": "node build/index.mjs"
263
235
  }
264
236
  }
@@ -276,7 +248,7 @@ await createApp({
276
248
  import { createApp, server, analytics } from "@databricks/appkit";
277
249
 
278
250
  await createApp({
279
- plugins: [server(), analytics({})],
251
+ plugins: [server(), analytics()],
280
252
  });
281
253
  ```
282
254
 
@@ -312,13 +284,17 @@ These are typically **provided by Databricks Apps runtime** (exact set can vary
312
284
 
313
285
  For local development, you need to authenticate with Databricks. Options:
314
286
 
315
- **Option 1: Databricks CLI profile (recommended)**
287
+ **Option 1: Databricks CLI Auth (recommended)**
316
288
 
317
289
  ```bash
318
290
  # Configure once
319
- databricks configure --profile my-profile
291
+ databricks auth login --host [host] --profile [profile-name]
320
292
 
321
- # Then run with profile
293
+ # If you used `DEFAULT` as the profile name then you can just run
294
+
295
+ `npm run dev`
296
+
297
+ # To run with a specific profile
322
298
  DATABRICKS_CONFIG_PROFILE=my-profile npm run dev
323
299
  # If your Databricks SDK expects a different variable name, try:
324
300
  # DATABRICKS_PROFILE=my-profile npm run dev
@@ -462,25 +438,51 @@ HTTP endpoints exposed (mounted under `/api/analytics`):
462
438
  Formats:
463
439
 
464
440
  - `format: "JSON"` (default) returns JSON rows
465
- - `format: "ARROW"` returns an Arrow “external links” payload over SSE, then the client fetches binary Arrow from `/api/analytics/arrow-result/:jobId`
441
+ - `format: "ARROW"` returns an Arrow “statement_id” payload over SSE, then the client fetches binary Arrow from `/api/analytics/arrow-result/:jobId`
442
+
443
+ ### Execution context and `asUser(req)`
466
444
 
467
- ### Request context (`getRequestContext()`)
445
+ AppKit manages Databricks authentication via two contexts:
468
446
 
469
- If a plugin sets `requiresDatabricksClient = true`, AppKit adds middleware that provides request context.
447
+ - **ServiceContext** (singleton): Initialized at app startup with service principal credentials
448
+ - **ExecutionContext**: Determined at runtime - either service principal or user context
470
449
 
471
- Headers used:
450
+ **Headers used for user context:**
472
451
 
473
452
  - `x-forwarded-user`: required in production; identifies the user
474
- - `x-forwarded-access-token`: optional; enables **user token passthrough** if `DATABRICKS_HOST` is set
453
+ - `x-forwarded-access-token`: required for user token passthrough
475
454
 
476
- Context fields (real behavior):
455
+ **Using `asUser(req)` for user-scoped operations:**
477
456
 
478
- - `userId`: derived from `x-forwarded-user` (in development it falls back to `serviceUserId`)
479
- - `serviceUserId`: service principal/user ID
480
- - `warehouseId`: `Promise<string>` (from `DATABRICKS_WAREHOUSE_ID`, or auto-selected in development)
481
- - `workspaceId`: `Promise<string>` (from `DATABRICKS_WORKSPACE_ID` or fetched)
482
- - `userDatabricksClient`: present only when passthrough is available (or in dev it equals service client)
483
- - `serviceDatabricksClient`: always present
457
+ The `asUser(req)` pattern allows plugins to execute operations using the requesting user's credentials:
458
+
459
+ ```ts
460
+ // In a custom plugin route handler
461
+ router.post("/users/me/data", async (req, res) => {
462
+ // Execute as the user (uses their Databricks permissions)
463
+ const result = await this.asUser(req).query("SELECT ...");
464
+ res.json(result);
465
+ });
466
+
467
+ // Service principal execution (default)
468
+ router.post("/system/data", async (req, res) => {
469
+ const result = await this.query("SELECT ...");
470
+ res.json(result);
471
+ });
472
+ ```
473
+
474
+ **Context helper functions (exported from `@databricks/appkit`):**
475
+
476
+ - `getExecutionContext()`: Returns current context (user or service)
477
+ - `getCurrentUserId()`: Returns user ID in user context, service user ID otherwise
478
+ - `getWorkspaceClient()`: Returns the appropriate WorkspaceClient for current context
479
+ - `getWarehouseId()`: `Promise<string>` (from `DATABRICKS_WAREHOUSE_ID` or auto-selected in dev)
480
+ - `getWorkspaceId()`: `Promise<string>` (from `DATABRICKS_WORKSPACE_ID` or fetched)
481
+ - `isInUserContext()`: Returns `true` if currently executing in user context
482
+
483
+ **Development mode behavior:**
484
+
485
+ In local development (`NODE_ENV=development`), if `asUser(req)` is called without a user token, it logs a warning and falls back to the service principal.
484
486
 
485
487
  ### Custom plugins (backend)
486
488
 
@@ -493,7 +495,6 @@ import type express from "express";
493
495
  class MyPlugin extends Plugin {
494
496
  name = "my-plugin";
495
497
  envVars = []; // list required env vars here
496
- requiresDatabricksClient = false; // set true if you need getRequestContext()
497
498
 
498
499
  injectRoutes(router: express.Router) {
499
500
  this.route(router, {
@@ -980,6 +981,108 @@ function LoadingCard() {
980
981
  }
981
982
  ```
982
983
 
984
+ ## Stylesheet
985
+
986
+ In the main css file import the following
987
+
988
+ ```css
989
+ @import "@databricks/appkit-ui/styles.css";
990
+ ```
991
+
992
+ That will provide a default theme for the app using css variables.
993
+
994
+ ### Customizing theme (light/dark mode)
995
+
996
+ - Full list of variables to customize the theme.
997
+
998
+ ```css
999
+ @import "@databricks/appkit-ui/styles.css";
1000
+
1001
+ :root {
1002
+ --radius: 0.625rem;
1003
+ --background: oklch(1 0 0);
1004
+ --foreground: oklch(0.141 0.005 285.823);
1005
+ --card: oklch(1 0 0);
1006
+ --card-foreground: oklch(0.141 0.005 285.823);
1007
+ --popover: oklch(1 0 0);
1008
+ --popover-foreground: oklch(0.141 0.005 285.823);
1009
+ --primary: oklch(0.21 0.006 285.885);
1010
+ --primary-foreground: oklch(0.985 0 0);
1011
+ --secondary: oklch(0.967 0.001 286.375);
1012
+ --secondary-foreground: oklch(0.21 0.006 285.885);
1013
+ --muted: oklch(0.967 0.001 286.375);
1014
+ --muted-foreground: oklch(0.552 0.016 285.938);
1015
+ --accent: oklch(0.967 0.001 286.375);
1016
+ --accent-foreground: oklch(0.21 0.006 285.885);
1017
+ --destructive: oklch(0.577 0.245 27.325);
1018
+ --destructive-foreground: oklch(0.985 0 0);
1019
+ --success: oklch(0.603 0.135 166.892);
1020
+ --success-foreground: oklch(1 0 0);
1021
+ --warning: oklch(0.795 0.157 78.748);
1022
+ --warning-foreground: oklch(0.199 0.027 238.732);
1023
+ --border: oklch(0.92 0.004 286.32);
1024
+ --input: oklch(0.92 0.004 286.32);
1025
+ --ring: oklch(0.705 0.015 286.067);
1026
+ --chart-1: oklch(0.646 0.222 41.116);
1027
+ --chart-2: oklch(0.6 0.118 184.704);
1028
+ --chart-3: oklch(0.398 0.07 227.392);
1029
+ --chart-4: oklch(0.828 0.189 84.429);
1030
+ --chart-5: oklch(0.769 0.188 70.08);
1031
+ --sidebar: oklch(0.985 0 0);
1032
+ --sidebar-foreground: oklch(0.141 0.005 285.823);
1033
+ --sidebar-primary: oklch(0.21 0.006 285.885);
1034
+ --sidebar-primary-foreground: oklch(0.985 0 0);
1035
+ --sidebar-accent: oklch(0.967 0.001 286.375);
1036
+ --sidebar-accent-foreground: oklch(0.21 0.006 285.885);
1037
+ --sidebar-border: oklch(0.92 0.004 286.32);
1038
+ --sidebar-ring: oklch(0.705 0.015 286.067);
1039
+ }
1040
+
1041
+ @media (prefers-color-scheme: dark) {
1042
+ :root {
1043
+ --background: oklch(0.141 0.005 285.823);
1044
+ --foreground: oklch(0.985 0 0);
1045
+ --card: oklch(0.21 0.006 285.885);
1046
+ --card-foreground: oklch(0.985 0 0);
1047
+ --popover: oklch(0.21 0.006 285.885);
1048
+ --popover-foreground: oklch(0.985 0 0);
1049
+ --primary: oklch(0.92 0.004 286.32);
1050
+ --primary-foreground: oklch(0.21 0.006 285.885);
1051
+ --secondary: oklch(0.274 0.006 286.033);
1052
+ --secondary-foreground: oklch(0.985 0 0);
1053
+ --muted: oklch(0.274 0.006 286.033);
1054
+ --muted-foreground: oklch(0.705 0.015 286.067);
1055
+ --accent: oklch(0.274 0.006 286.033);
1056
+ --accent-foreground: oklch(0.985 0 0);
1057
+ --destructive: oklch(0.704 0.191 22.216);
1058
+ --destructive-foreground: oklch(0.985 0 0);
1059
+ --success: oklch(0.67 0.12 167);
1060
+ --success-foreground: oklch(1 0 0);
1061
+ --warning: oklch(0.83 0.165 85);
1062
+ --warning-foreground: oklch(0.199 0.027 238.732);
1063
+ --border: oklch(1 0 0 / 10%);
1064
+ --input: oklch(1 0 0 / 15%);
1065
+ --ring: oklch(0.552 0.016 285.938);
1066
+ --chart-1: oklch(0.488 0.243 264.376);
1067
+ --chart-2: oklch(0.696 0.17 162.48);
1068
+ --chart-3: oklch(0.769 0.188 70.08);
1069
+ --chart-4: oklch(0.627 0.265 303.9);
1070
+ --chart-5: oklch(0.645 0.246 16.439);
1071
+ --sidebar: oklch(0.21 0.006 285.885);
1072
+ --sidebar-foreground: oklch(0.985 0 0);
1073
+ --sidebar-primary: oklch(0.488 0.243 264.376);
1074
+ --sidebar-primary-foreground: oklch(0.985 0 0);
1075
+ --sidebar-accent: oklch(0.274 0.006 286.033);
1076
+ --sidebar-accent-foreground: oklch(0.985 0 0);
1077
+ --sidebar-border: oklch(1 0 0 / 10%);
1078
+ --sidebar-ring: oklch(0.552 0.016 285.938);
1079
+ }
1080
+ }
1081
+
1082
+ ```
1083
+
1084
+ - If any variable is changed, it must be changed for both light and dark mode.
1085
+
983
1086
  ## Type generation (QueryRegistry + IntelliSense)
984
1087
 
985
1088
  Goal: generate `client/src/appKitTypes.d.ts` so query keys, params, and result rows are type-safe.
@@ -1054,7 +1157,6 @@ env:
1054
1157
  - `tsx` is in devDependencies for dev server
1055
1158
  - `dev` script uses `NODE_ENV=development tsx watch server/index.ts`
1056
1159
  - `client/index.html` exists with `<div id="root"></div>` and script pointing to `client/src/main.tsx`
1057
- - `client/package.json` exists and includes `@databricks/appkit-ui`
1058
1160
 
1059
1161
  - **Backend**
1060
1162
  - `await createApp({ plugins: [...] })` is used (or `void createApp` with intent)
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@databricks/appkit-ui",
3
3
  "type": "module",
4
- "version": "0.1.3",
4
+ "version": "0.1.5",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "git+https://github.com/databricks/appkit.git"
@@ -12,6 +12,7 @@
12
12
  "bin",
13
13
  "scripts",
14
14
  "CLAUDE.md",
15
+ "AGENTS.md",
15
16
  "llms.txt",
16
17
  "README.md",
17
18
  "DCO",
@@ -29,7 +30,7 @@
29
30
  "clean:full": "rm -rf dist node_modules tmp",
30
31
  "clean": "rm -rf dist tmp",
31
32
  "dist": "tsx ../../tools/dist.ts",
32
- "tarball": "tsx ../../tools/dist.ts && npm pack ./tmp --pack-destination ./tmp",
33
+ "tarball": "rm -rf tmp && tsx ../../tools/dist.ts && npm pack ./tmp --pack-destination ./tmp",
33
34
  "typecheck": "tsc --noEmit",
34
35
  "postinstall": "node scripts/postinstall.js"
35
36
  },