@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.
- package/AGENTS.md +1179 -0
- package/CLAUDE.md +1178 -2
- package/NOTICE.md +2 -0
- package/bin/setup-claude.js +1 -1
- package/dist/js/arrow/arrow-client.js.map +1 -1
- package/dist/js/arrow/lazy-arrow.js.map +1 -1
- package/dist/js/sse/connect-sse.js.map +1 -1
- package/dist/react/charts/area/index.d.ts +2 -2
- package/dist/react/charts/bar/index.d.ts +2 -2
- package/dist/react/charts/base.d.ts +2 -2
- package/dist/react/charts/base.js.map +1 -1
- package/dist/react/charts/create-chart.d.ts +2 -2
- package/dist/react/charts/create-chart.js +2 -1
- package/dist/react/charts/create-chart.js.map +1 -1
- package/dist/react/charts/heatmap/index.d.ts +2 -2
- package/dist/react/charts/line/index.d.ts +2 -2
- package/dist/react/charts/normalize.d.ts +1 -1
- package/dist/react/charts/normalize.js +1 -1
- package/dist/react/charts/normalize.js.map +1 -1
- package/dist/react/charts/pie/index.d.ts +3 -3
- package/dist/react/charts/radar/index.d.ts +2 -2
- package/dist/react/charts/scatter/index.d.ts +2 -2
- package/dist/react/charts/theme.js.map +1 -1
- package/dist/react/charts/types.d.ts +5 -0
- package/dist/react/charts/types.d.ts.map +1 -1
- package/dist/react/charts/types.js.map +1 -1
- package/dist/react/charts/utils.js.map +1 -1
- package/dist/react/charts/wrapper.d.ts +4 -2
- package/dist/react/charts/wrapper.d.ts.map +1 -1
- package/dist/react/charts/wrapper.js +4 -2
- package/dist/react/charts/wrapper.js.map +1 -1
- package/dist/react/hooks/types.d.ts +2 -0
- package/dist/react/hooks/types.d.ts.map +1 -1
- package/dist/react/hooks/use-analytics-query.js +9 -3
- package/dist/react/hooks/use-analytics-query.js.map +1 -1
- package/dist/react/hooks/use-chart-data.d.ts +2 -0
- package/dist/react/hooks/use-chart-data.d.ts.map +1 -1
- package/dist/react/hooks/use-chart-data.js +3 -2
- package/dist/react/hooks/use-chart-data.js.map +1 -1
- package/dist/react/table/data-table.d.ts +2 -2
- package/dist/react/table/data-table.d.ts.map +1 -1
- package/dist/react/table/table-wrapper.js +3 -2
- package/dist/react/table/table-wrapper.js.map +1 -1
- package/dist/react/table/types.d.ts.map +1 -1
- package/dist/react/ui/accordion.d.ts +5 -5
- package/dist/react/ui/alert-dialog.d.ts +12 -12
- package/dist/react/ui/alert-dialog.d.ts.map +1 -1
- package/dist/react/ui/alert.d.ts +4 -4
- package/dist/react/ui/aspect-ratio.d.ts +2 -2
- package/dist/react/ui/avatar.d.ts +4 -4
- package/dist/react/ui/badge.d.ts +2 -2
- package/dist/react/ui/breadcrumb.d.ts +8 -8
- package/dist/react/ui/button-group.d.ts +4 -4
- package/dist/react/ui/button.d.ts +2 -2
- package/dist/react/ui/calendar.d.ts +3 -3
- package/dist/react/ui/card.d.ts +8 -8
- package/dist/react/ui/carousel.d.ts +6 -6
- package/dist/react/ui/chart.d.ts +5 -5
- package/dist/react/ui/chart.d.ts.map +1 -1
- package/dist/react/ui/chart.js.map +1 -1
- package/dist/react/ui/checkbox.d.ts +2 -2
- package/dist/react/ui/collapsible.d.ts +4 -4
- package/dist/react/ui/command.d.ts +10 -10
- package/dist/react/ui/context-menu.d.ts +16 -16
- package/dist/react/ui/dialog.d.ts +11 -11
- package/dist/react/ui/drawer.d.ts +11 -11
- package/dist/react/ui/dropdown-menu.d.ts +16 -16
- package/dist/react/ui/dropdown-menu.d.ts.map +1 -1
- package/dist/react/ui/empty.d.ts +7 -7
- package/dist/react/ui/field.d.ts +11 -11
- package/dist/react/ui/form.d.ts +7 -7
- package/dist/react/ui/hover-card.d.ts +4 -4
- package/dist/react/ui/input-group.d.ts +7 -7
- package/dist/react/ui/input-otp.d.ts +5 -5
- package/dist/react/ui/input.d.ts +2 -2
- package/dist/react/ui/item.d.ts +11 -11
- package/dist/react/ui/kbd.d.ts +3 -3
- package/dist/react/ui/label.d.ts +2 -2
- package/dist/react/ui/menubar.d.ts +17 -17
- package/dist/react/ui/navigation-menu.d.ts +9 -9
- package/dist/react/ui/pagination.d.ts +8 -8
- package/dist/react/ui/popover.d.ts +5 -5
- package/dist/react/ui/progress.d.ts +2 -2
- package/dist/react/ui/radio-group.d.ts +3 -3
- package/dist/react/ui/resizable.d.ts +4 -4
- package/dist/react/ui/scroll-area.d.ts +3 -3
- package/dist/react/ui/select.d.ts +11 -11
- package/dist/react/ui/separator.d.ts +2 -2
- package/dist/react/ui/sheet.d.ts +9 -9
- package/dist/react/ui/sidebar.d.ts +24 -24
- package/dist/react/ui/skeleton.d.ts +2 -2
- package/dist/react/ui/slider.d.ts +2 -2
- package/dist/react/ui/sonner.d.ts +2 -2
- package/dist/react/ui/spinner.d.ts +2 -2
- package/dist/react/ui/switch.d.ts +2 -2
- package/dist/react/ui/table.d.ts +9 -9
- package/dist/react/ui/tabs.d.ts +5 -5
- package/dist/react/ui/textarea.d.ts +2 -2
- package/dist/react/ui/toggle-group.d.ts +3 -3
- package/dist/react/ui/toggle.d.ts +2 -2
- package/dist/react/ui/tooltip.d.ts +5 -5
- package/dist/react/ui/tooltip.d.ts.map +1 -1
- package/dist/shared/src/sql/helpers.js.map +1 -1
- package/llms.txt +160 -58
- package/package.json +3 -2
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import * as
|
|
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">):
|
|
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
|
|
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>):
|
|
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
|
package/dist/react/ui/table.d.ts
CHANGED
|
@@ -1,39 +1,39 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
-
import * as
|
|
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">):
|
|
8
|
+
}: React.ComponentProps<"table">): react_jsx_runtime253.JSX.Element;
|
|
9
9
|
declare function TableHeader({
|
|
10
10
|
className,
|
|
11
11
|
...props
|
|
12
|
-
}: React.ComponentProps<"thead">):
|
|
12
|
+
}: React.ComponentProps<"thead">): react_jsx_runtime253.JSX.Element;
|
|
13
13
|
declare function TableBody({
|
|
14
14
|
className,
|
|
15
15
|
...props
|
|
16
|
-
}: React.ComponentProps<"tbody">):
|
|
16
|
+
}: React.ComponentProps<"tbody">): react_jsx_runtime253.JSX.Element;
|
|
17
17
|
declare function TableFooter({
|
|
18
18
|
className,
|
|
19
19
|
...props
|
|
20
|
-
}: React.ComponentProps<"tfoot">):
|
|
20
|
+
}: React.ComponentProps<"tfoot">): react_jsx_runtime253.JSX.Element;
|
|
21
21
|
declare function TableRow({
|
|
22
22
|
className,
|
|
23
23
|
...props
|
|
24
|
-
}: React.ComponentProps<"tr">):
|
|
24
|
+
}: React.ComponentProps<"tr">): react_jsx_runtime253.JSX.Element;
|
|
25
25
|
declare function TableHead({
|
|
26
26
|
className,
|
|
27
27
|
...props
|
|
28
|
-
}: React.ComponentProps<"th">):
|
|
28
|
+
}: React.ComponentProps<"th">): react_jsx_runtime253.JSX.Element;
|
|
29
29
|
declare function TableCell({
|
|
30
30
|
className,
|
|
31
31
|
...props
|
|
32
|
-
}: React.ComponentProps<"td">):
|
|
32
|
+
}: React.ComponentProps<"td">): react_jsx_runtime253.JSX.Element;
|
|
33
33
|
declare function TableCaption({
|
|
34
34
|
className,
|
|
35
35
|
...props
|
|
36
|
-
}: React.ComponentProps<"caption">):
|
|
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
|
package/dist/react/ui/tabs.d.ts
CHANGED
|
@@ -1,24 +1,24 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
-
import * as
|
|
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>):
|
|
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>):
|
|
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>):
|
|
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>):
|
|
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
|
|
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">):
|
|
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
|
|
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
|
-
}):
|
|
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>):
|
|
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
|
|
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>):
|
|
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
|
|
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>):
|
|
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>):
|
|
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>):
|
|
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>):
|
|
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,
|
|
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":";;;;AAaA,MAAa,MAAM;CAiBjB,KAAK,OAAqC;EACxC,IAAIA,YAAoB;AAGxB,MAAI,iBAAiB,KACnB,aAAY,MAAM,aAAa,CAAC,MAAM,IAAI,CAAC;WAGpC,OAAO,UAAU,UAAU;AAElC,OAAI,CAAC,sBAAsB,KAAK,MAAM,CACpC,OAAM,IAAI,MACR,wEAAwE,QACzE;AAEH,eAAY;QAIZ,OAAM,IAAI,MACR,wEAAwE,OAAO,QAChF;AAGH,SAAO;GACL,YAAY;GACZ,OAAO;GACR;;CAwBH,UAAU,OAAmD;EAC3D,IAAIC,iBAAyB;AAE7B,MAAI,iBAAiB,KACnB,kBAAiB,MAAM,aAAa,CAAC,QAAQ,iBAAiB,KAAK;WAC1D,OAAO,UAAU,UAAU;AAGpC,OAAI,CADF,wEACY,KAAK,MAAM,CACvB,OAAM,IAAI,MACR,kHAAkH,QACnH;AAEH,oBAAiB;aACR,OAAO,UAAU,SAE1B,kBADa,IAAI,KAAK,QAAQ,eAAO,QAAQ,QAAQ,IAAK,CACpC,aAAa,CAAC,QAAQ,iBAAiB,KAAK;MAElE,OAAM,IAAI,MACR,sFAAsF,OAAO,QAC9F;AAGH,SAAO;GACL,YAAY;GACZ,OAAO;GACR;;CAmBH,OAAO,OAAyC;EAC9C,IAAIC,WAAmB;AAGvB,MAAI,OAAO,UAAU,SACnB,YAAW,MAAM,UAAU;WAGpB,OAAO,UAAU,UAAU;AAClC,OAAI,UAAU,MAAM,OAAO,MAAM,OAAO,MAAM,CAAC,CAC7C,OAAM,IAAI,MACR,uDAAuD,UAAU,KAAK,iBAAiB,QACxF;AAEH,cAAW;QAIX,OAAM,IAAI,MACR,uDAAuD,OAAO,QAC/D;AAGH,SAAO;GACL,YAAY;GACZ,OAAO;GACR;;CAwBH,OAAO,OAAmD;AACxD,MACE,OAAO,UAAU,YACjB,OAAO,UAAU,YACjB,OAAO,UAAU,UAEjB,OAAM,IAAI,MACR,0DAA0D,OAAO,QAClE;EAGH,IAAIC,cAAsB;AAE1B,MAAI,OAAO,UAAU,SACnB,eAAc;MAEd,eAAc,MAAM,UAAU;AAGhC,SAAO;GACL,YAAY;GACZ,OAAO;GACR;;CAmCH,QAAQ,OAAoD;AAC1D,MACE,OAAO,UAAU,aACjB,OAAO,UAAU,YACjB,OAAO,UAAU,SAEjB,OAAM,IAAI,MACR,oFAAoF,OAAO,QAC5F;EAGH,IAAIC,eAAuB;AAE3B,MAAI,OAAO,UAAU,UACnB,gBAAe,MAAM,UAAU;WAGxB,OAAO,UAAU,UAAU;AAClC,OAAI,UAAU,KAAK,UAAU,EAC3B,OAAM,IAAI,MACR,oFAAoF,QACrF;AAEH,kBAAe,UAAU,IAAI,SAAS;aAG/B,OAAO,UAAU,UAAU;AAClC,OAAI,UAAU,UAAU,UAAU,QAChC,OAAM,IAAI,MACR,oFAAoF,QACrF;AAEH,kBAAe;;AAGjB,SAAO;GACL,YAAY;GACZ,OAAO;GACR;;CAwBH,OAAO,OAA2D;EAChE,IAAIC,WAAmB;AAEvB,MAAI,iBAAiB,WAEnB,YAAW,MAAM,KAAK,MAAM,CACzB,KAAK,MAAM,EAAE,SAAS,GAAG,CAAC,SAAS,GAAG,IAAI,CAAC,aAAa,CAAC,CACzD,KAAK,GAAG;WACF,iBAAiB,YAE1B,YAAW,MAAM,KAAK,IAAI,WAAW,MAAM,CAAC,CACzC,KAAK,MAAM,EAAE,SAAS,GAAG,CAAC,SAAS,GAAG,IAAI,CAAC,aAAa,CAAC,CACzD,KAAK,GAAG;WACF,OAAO,UAAU,UAAU;AAEpC,OAAI,CAAC,iBAAiB,KAAK,MAAM,CAC/B,OAAM,IAAI,MACR,iFAAiF,QAClF;AAEH,cAAW,MAAM,aAAa;QAE9B,OAAM,IAAI,MACR,qEAAqE,OAAO,QAC7E;AAGH,SAAO;GACL,YAAY;GACZ,OAAO;GACR;;CAEJ;;;;;;;;;;;;;;;AAgBD,SAAgB,gBAAgB,OAAoC;AAClE,QACE,UAAU,QACV,OAAO,UAAU,YACjB,gBAAgB,SAChB,WAAW,SACX,OAAO,MAAM,eAAe,YAC5B,OAAO,MAAM,UAAU"}
|
|
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":";;;;AAaA,MAAa,MAAM;CAiBjB,KAAK,OAAqC;EACxC,IAAI,YAAoB;AAGxB,MAAI,iBAAiB,KACnB,aAAY,MAAM,aAAa,CAAC,MAAM,IAAI,CAAC;WAGpC,OAAO,UAAU,UAAU;AAElC,OAAI,CAAC,sBAAsB,KAAK,MAAM,CACpC,OAAM,IAAI,MACR,wEAAwE,QACzE;AAEH,eAAY;QAIZ,OAAM,IAAI,MACR,wEAAwE,OAAO,QAChF;AAGH,SAAO;GACL,YAAY;GACZ,OAAO;GACR;;CAwBH,UAAU,OAAmD;EAC3D,IAAI,iBAAyB;AAE7B,MAAI,iBAAiB,KACnB,kBAAiB,MAAM,aAAa,CAAC,QAAQ,iBAAiB,KAAK;WAC1D,OAAO,UAAU,UAAU;AAGpC,OAAI,CADF,wEACY,KAAK,MAAM,CACvB,OAAM,IAAI,MACR,kHAAkH,QACnH;AAEH,oBAAiB;aACR,OAAO,UAAU,SAE1B,kBADa,IAAI,KAAK,QAAQ,eAAO,QAAQ,QAAQ,IAAK,CACpC,aAAa,CAAC,QAAQ,iBAAiB,KAAK;MAElE,OAAM,IAAI,MACR,sFAAsF,OAAO,QAC9F;AAGH,SAAO;GACL,YAAY;GACZ,OAAO;GACR;;CAmBH,OAAO,OAAyC;EAC9C,IAAI,WAAmB;AAGvB,MAAI,OAAO,UAAU,SACnB,YAAW,MAAM,UAAU;WAGpB,OAAO,UAAU,UAAU;AAClC,OAAI,UAAU,MAAM,OAAO,MAAM,OAAO,MAAM,CAAC,CAC7C,OAAM,IAAI,MACR,uDAAuD,UAAU,KAAK,iBAAiB,QACxF;AAEH,cAAW;QAIX,OAAM,IAAI,MACR,uDAAuD,OAAO,QAC/D;AAGH,SAAO;GACL,YAAY;GACZ,OAAO;GACR;;CAwBH,OAAO,OAAmD;AACxD,MACE,OAAO,UAAU,YACjB,OAAO,UAAU,YACjB,OAAO,UAAU,UAEjB,OAAM,IAAI,MACR,0DAA0D,OAAO,QAClE;EAGH,IAAI,cAAsB;AAE1B,MAAI,OAAO,UAAU,SACnB,eAAc;MAEd,eAAc,MAAM,UAAU;AAGhC,SAAO;GACL,YAAY;GACZ,OAAO;GACR;;CAmCH,QAAQ,OAAoD;AAC1D,MACE,OAAO,UAAU,aACjB,OAAO,UAAU,YACjB,OAAO,UAAU,SAEjB,OAAM,IAAI,MACR,oFAAoF,OAAO,QAC5F;EAGH,IAAI,eAAuB;AAE3B,MAAI,OAAO,UAAU,UACnB,gBAAe,MAAM,UAAU;WAGxB,OAAO,UAAU,UAAU;AAClC,OAAI,UAAU,KAAK,UAAU,EAC3B,OAAM,IAAI,MACR,oFAAoF,QACrF;AAEH,kBAAe,UAAU,IAAI,SAAS;aAG/B,OAAO,UAAU,UAAU;AAClC,OAAI,UAAU,UAAU,UAAU,QAChC,OAAM,IAAI,MACR,oFAAoF,QACrF;AAEH,kBAAe;;AAGjB,SAAO;GACL,YAAY;GACZ,OAAO;GACR;;CAwBH,OAAO,OAA2D;EAChE,IAAI,WAAmB;AAEvB,MAAI,iBAAiB,WAEnB,YAAW,MAAM,KAAK,MAAM,CACzB,KAAK,MAAM,EAAE,SAAS,GAAG,CAAC,SAAS,GAAG,IAAI,CAAC,aAAa,CAAC,CACzD,KAAK,GAAG;WACF,iBAAiB,YAE1B,YAAW,MAAM,KAAK,IAAI,WAAW,MAAM,CAAC,CACzC,KAAK,MAAM,EAAE,SAAS,GAAG,CAAC,SAAS,GAAG,IAAI,CAAC,aAAa,CAAC,CACzD,KAAK,GAAG;WACF,OAAO,UAAU,UAAU;AAEpC,OAAI,CAAC,iBAAiB,KAAK,MAAM,CAC/B,OAAM,IAAI,MACR,iFAAiF,QAClF;AAEH,cAAW,MAAM,aAAa;QAE9B,OAAM,IAAI,MACR,qEAAqE,OAAO,QAC7E;AAGH,SAAO;GACL,YAAY;GACZ,OAAO;GACR;;CAEJ;;;;;;;;;;;;;;;AAgBD,SAAgB,gBAAgB,OAAoC;AAClE,QACE,UAAU,QACV,OAAO,UAAU,YACjB,gBAAgB,SAChB,WAAW,SACX,OAAO,MAAM,eAAe,YAC5B,OAAO,MAAM,UAAU"}
|
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": "
|
|
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.
|
|
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": "^
|
|
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": "
|
|
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
|
|
287
|
+
**Option 1: Databricks CLI Auth (recommended)**
|
|
316
288
|
|
|
317
289
|
```bash
|
|
318
290
|
# Configure once
|
|
319
|
-
databricks
|
|
291
|
+
databricks auth login --host [host] --profile [profile-name]
|
|
320
292
|
|
|
321
|
-
#
|
|
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 “
|
|
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
|
-
|
|
445
|
+
AppKit manages Databricks authentication via two contexts:
|
|
468
446
|
|
|
469
|
-
|
|
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`:
|
|
453
|
+
- `x-forwarded-access-token`: required for user token passthrough
|
|
475
454
|
|
|
476
|
-
|
|
455
|
+
**Using `asUser(req)` for user-scoped operations:**
|
|
477
456
|
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
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.
|
|
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
|
},
|