@upstash/react-redis-browser 0.2.14-rc.9 → 0.2.14

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/dist/index.js CHANGED
@@ -2665,6 +2665,48 @@ function formatTime(seconds) {
2665
2665
  return parts.slice(0, 1).join(" ");
2666
2666
  }
2667
2667
  var isTest = typeof window !== "undefined" && window.__PLAYWRIGHT__ === true;
2668
+ var jsonToJsLiteral = (json) => {
2669
+ return json.replaceAll(/"([$A-Z_a-z][\w$]*)"\s*:/g, "$1:");
2670
+ };
2671
+ var MAX_INLINE_KEYS = 2;
2672
+ var isInlineable = (value) => {
2673
+ if (typeof value !== "object" || value === null) return true;
2674
+ if (Array.isArray(value)) return value.every((v) => typeof v !== "object" || v === null);
2675
+ const entries = Object.entries(value);
2676
+ return entries.length <= MAX_INLINE_KEYS && entries.every(([, v]) => typeof v !== "object" || v === null);
2677
+ };
2678
+ var prettyPrint = (value, indent) => {
2679
+ if (value === void 0 || value === null) return String(value);
2680
+ if (typeof value !== "object") return JSON.stringify(value);
2681
+ const prefix = " ".repeat(indent);
2682
+ const childPrefix = " ".repeat(indent + 1);
2683
+ if (Array.isArray(value)) {
2684
+ if (value.length === 0) return "[]";
2685
+ if (value.every((v) => isInlineable(v))) {
2686
+ const inline = `[${value.map((v) => prettyPrint(v, 0)).join(", ")}]`;
2687
+ if (!inline.includes("\n")) return inline;
2688
+ }
2689
+ const items = value.map((v) => `${childPrefix}${prettyPrint(v, indent + 1)}`);
2690
+ return `[
2691
+ ${items.join(",\n")}
2692
+ ${prefix}]`;
2693
+ }
2694
+ const entries = Object.entries(value);
2695
+ if (entries.length === 0) return "{}";
2696
+ if (indent > 0 && entries.length <= MAX_INLINE_KEYS && entries.every(([, v]) => isInlineable(v))) {
2697
+ const inline = `{ ${entries.map(([k, v]) => `${JSON.stringify(k)}: ${prettyPrint(v, 0)}`).join(", ")} }`;
2698
+ if (!inline.includes("\n")) return inline;
2699
+ }
2700
+ const parts = entries.map(
2701
+ ([k, v]) => `${childPrefix}${JSON.stringify(k)}: ${prettyPrint(v, indent + 1)}`
2702
+ );
2703
+ return `{
2704
+ ${parts.join(",\n")}
2705
+ ${prefix}}`;
2706
+ };
2707
+ var toJsLiteral = (obj) => {
2708
+ return jsonToJsLiteral(prettyPrint(obj, 0));
2709
+ };
2668
2710
  var formatUpstashErrorMessage = (error) => {
2669
2711
  if (error.name !== "UpstashError") return error.message;
2670
2712
  let message = error.message;
@@ -2795,7 +2837,7 @@ var DatabrowserProvider = ({
2795
2837
  removeItem: () => {
2796
2838
  }
2797
2839
  },
2798
- version: 7,
2840
+ version: 8,
2799
2841
  migrate: (originalState, version) => {
2800
2842
  const state = originalState;
2801
2843
  if (version <= 1) {
@@ -2827,9 +2869,12 @@ var DatabrowserProvider = ({
2827
2869
  if (version <= 6) {
2828
2870
  state.tabs = state.tabs.map(([id, data]) => [
2829
2871
  id,
2830
- { ...data, valuesSearch: { index: "", queries: {} } }
2872
+ { ...data, valuesSearch: { index: "", queries: {}, queryBuilderMode: "ui" } }
2831
2873
  ]);
2832
2874
  }
2875
+ if (version <= 7) {
2876
+ state.aiDataSharingConsent = _nullishCoalesce(state.aiDataSharingConsent, () => ( false));
2877
+ }
2833
2878
  return state;
2834
2879
  }
2835
2880
  })
@@ -2861,7 +2906,7 @@ var storeCreator = (set, get) => ({
2861
2906
  id,
2862
2907
  selectedKeys: [],
2863
2908
  search: { key: "", type: void 0 },
2864
- valuesSearch: { index: "", queries: {} },
2909
+ valuesSearch: { index: "", queries: {}, queryBuilderMode: "ui" },
2865
2910
  isValuesSearchSelected: false,
2866
2911
  pinned: false
2867
2912
  };
@@ -3078,9 +3123,29 @@ var storeCreator = (set, get) => ({
3078
3123
  return { ...old, tabs: newTabs };
3079
3124
  });
3080
3125
  },
3126
+ setQueryBuilderMode: (tabId, mode) => {
3127
+ set((old) => {
3128
+ const tabIndex = old.tabs.findIndex(([id]) => id === tabId);
3129
+ if (tabIndex === -1) return old;
3130
+ const newTabs = [...old.tabs];
3131
+ const [, tabData] = newTabs[tabIndex];
3132
+ newTabs[tabIndex] = [
3133
+ tabId,
3134
+ {
3135
+ ...tabData,
3136
+ valuesSearch: { ...tabData.valuesSearch, queryBuilderMode: mode }
3137
+ }
3138
+ ];
3139
+ return { ...old, tabs: newTabs };
3140
+ });
3141
+ },
3081
3142
  searchHistory: [],
3082
3143
  addSearchHistory: (key) => {
3083
3144
  set((old) => ({ ...old, searchHistory: [key, ...old.searchHistory] }));
3145
+ },
3146
+ aiDataSharingConsent: false,
3147
+ setAiDataSharingConsent: (consent) => {
3148
+ set({ aiDataSharingConsent: consent });
3084
3149
  }
3085
3150
  });
3086
3151
 
@@ -3111,7 +3176,8 @@ var useTab = () => {
3111
3176
  setValuesSearch,
3112
3177
  setValuesSearchIndex,
3113
3178
  setValuesSearchQuery,
3114
- setIsValuesSearchSelected
3179
+ setIsValuesSearchSelected,
3180
+ setQueryBuilderMode
3115
3181
  } = useDatabrowserStore();
3116
3182
  const tabId = useTabId();
3117
3183
  const tabData = _react.useMemo.call(void 0, () => _optionalChain([tabs, 'access', _20 => _20.find, 'call', _21 => _21(([id]) => id === tabId), 'optionalAccess', _22 => _22[1]]), [tabs, tabId]);
@@ -3130,6 +3196,7 @@ var useTab = () => {
3130
3196
  query: _nullishCoalesce(tabData.valuesSearch.queries[tabData.valuesSearch.index], () => ( ""))
3131
3197
  },
3132
3198
  isValuesSearchSelected: tabData.isValuesSearchSelected,
3199
+ queryBuilderMode: _nullishCoalesce(tabData.valuesSearch.queryBuilderMode, () => ( "ui")),
3133
3200
  pinned: tabData.pinned,
3134
3201
  setSelectedKey: (key) => setSelectedKey(tabId, key),
3135
3202
  setSelectedKeys: (keys) => setSelectedKeys(tabId, keys),
@@ -3140,7 +3207,8 @@ var useTab = () => {
3140
3207
  setValuesSearch: (search) => setValuesSearch(tabId, search),
3141
3208
  setValuesSearchIndex: (index) => setValuesSearchIndex(tabId, index),
3142
3209
  setValuesSearchQuery: (query) => setValuesSearchQuery(tabId, query),
3143
- setIsValuesSearchSelected: (isSelected) => setIsValuesSearchSelected(tabId, isSelected)
3210
+ setIsValuesSearchSelected: (isSelected) => setIsValuesSearchSelected(tabId, isSelected),
3211
+ setQueryBuilderMode: (mode) => setQueryBuilderMode(tabId, mode)
3144
3212
  }),
3145
3213
  [selectedTab, tabs, tabId]
3146
3214
  );
@@ -3170,6 +3238,29 @@ var portalWrapper = wrapper;
3170
3238
 
3171
3239
  var _reactresizablepanels = require('react-resizable-panels');
3172
3240
 
3241
+ // src/components/ui/resize-handle.tsx
3242
+
3243
+
3244
+ var ResizeHandle = ({
3245
+ direction = "horizontal"
3246
+ }) => {
3247
+ const isHorizontal = direction === "horizontal";
3248
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
3249
+ _reactresizablepanels.PanelResizeHandle,
3250
+ {
3251
+ className: cn(
3252
+ "group flex items-center justify-center gap-1 rounded-md transition-colors hover:bg-zinc-300/10",
3253
+ isHorizontal ? "mx-[2px] h-full flex-col px-[8px]" : "my-[2px] w-full flex-row py-[8px]"
3254
+ ),
3255
+ children: [
3256
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "h-[3px] w-[3px] rounded-full bg-zinc-300" }),
3257
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "h-[3px] w-[3px] rounded-full bg-zinc-300" }),
3258
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "h-[3px] w-[3px] rounded-full bg-zinc-300" })
3259
+ ]
3260
+ }
3261
+ );
3262
+ };
3263
+
3173
3264
  // src/components/ui/segmented.tsx
3174
3265
 
3175
3266
  var Segmented = ({
@@ -3181,21 +3272,30 @@ var Segmented = ({
3181
3272
  selectedClassName,
3182
3273
  unselectedClassName
3183
3274
  }) => {
3184
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: cn("flex w-fit gap-[2px] rounded-lg bg-zinc-200 p-[2px] text-sm", className), children: options.map((option) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
3185
- "button",
3275
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
3276
+ "div",
3186
3277
  {
3187
3278
  className: cn(
3188
- "h-7 rounded-md px-3 transition-all",
3189
- value === option.key ? _nullishCoalesce(selectedClassName, () => ( "bg-white text-zinc-950")) : _nullishCoalesce(unselectedClassName, () => ( "text-zinc-700")),
3190
- buttonClassName
3279
+ "flex w-fit select-none gap-[2px] rounded-lg bg-zinc-200 p-[2px] text-sm",
3280
+ className
3191
3281
  ),
3192
- onClick: () => {
3193
- _optionalChain([onChange, 'optionalCall', _25 => _25(option.key)]);
3194
- },
3195
- children: option.label
3196
- },
3197
- option.key
3198
- )) });
3282
+ children: options.map((option) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
3283
+ "button",
3284
+ {
3285
+ className: cn(
3286
+ "h-7 rounded-md px-3 transition-all",
3287
+ value === option.key ? _nullishCoalesce(selectedClassName, () => ( "bg-white text-zinc-950")) : _nullishCoalesce(unselectedClassName, () => ( "text-zinc-700")),
3288
+ buttonClassName
3289
+ ),
3290
+ onClick: () => {
3291
+ _optionalChain([onChange, 'optionalCall', _25 => _25(option.key)]);
3292
+ },
3293
+ children: option.label
3294
+ },
3295
+ option.key
3296
+ ))
3297
+ }
3298
+ );
3199
3299
  };
3200
3300
 
3201
3301
  // src/components/ui/toaster.tsx
@@ -3367,6 +3467,33 @@ function Toaster() {
3367
3467
 
3368
3468
  // src/components/databrowser/hooks/use-fetch-search-indexes.tsx
3369
3469
 
3470
+
3471
+ // src/lib/scan-keys.ts
3472
+ async function scanKeys(redis, {
3473
+ match,
3474
+ type,
3475
+ count: count2 = 100,
3476
+ limit
3477
+ } = {}) {
3478
+ let cursor = "0";
3479
+ const result = [];
3480
+ while (true) {
3481
+ const [newCursor, keys] = await redis.scan(cursor, {
3482
+ count: count2,
3483
+ type,
3484
+ match
3485
+ });
3486
+ result.push(...keys);
3487
+ if (limit && result.length >= limit) {
3488
+ return result.slice(0, limit);
3489
+ }
3490
+ if (newCursor === "0") break;
3491
+ cursor = newCursor;
3492
+ }
3493
+ return result;
3494
+ }
3495
+
3496
+ // src/components/databrowser/hooks/use-fetch-search-indexes.tsx
3370
3497
  var FETCH_SEARCH_INDEXES_QUERY_KEY = "fetch-search-indexes";
3371
3498
  var useFetchSearchIndexes = ({
3372
3499
  match,
@@ -3376,21 +3503,7 @@ var useFetchSearchIndexes = ({
3376
3503
  return _reactquery.useQuery.call(void 0, {
3377
3504
  queryKey: [FETCH_SEARCH_INDEXES_QUERY_KEY],
3378
3505
  enabled: _nullishCoalesce(enabled, () => ( true)),
3379
- queryFn: async () => {
3380
- let cursor = "0";
3381
- const finalResult = [];
3382
- while (true) {
3383
- const [newCursor, results] = await redis.scan(cursor, {
3384
- count: 100,
3385
- type: "search",
3386
- match
3387
- });
3388
- finalResult.push(...results);
3389
- if (newCursor === "0") break;
3390
- cursor = newCursor;
3391
- }
3392
- return finalResult;
3393
- }
3506
+ queryFn: () => scanKeys(redis, { match, type: "search" })
3394
3507
  });
3395
3508
  };
3396
3509
 
@@ -3677,6 +3790,7 @@ Label.displayName = LabelPrimitive.Root.displayName;
3677
3790
  // src/components/ui/select.tsx
3678
3791
 
3679
3792
  var _reactselect = require('@radix-ui/react-select'); var SelectPrimitive = _interopRequireWildcard(_reactselect);
3793
+ var _reactdom = require('react-dom'); var ReactDOM = _interopRequireWildcard(_reactdom);
3680
3794
 
3681
3795
  var Select = SelectPrimitive.Root;
3682
3796
  var SelectGroup = SelectPrimitive.Group;
@@ -3732,7 +3846,7 @@ var SelectContent = React6.forwardRef(({ className, children, position = "popper
3732
3846
  SelectPrimitive.Viewport,
3733
3847
  {
3734
3848
  className: cn(
3735
- "p-1",
3849
+ "max-h-[min(var(--radix-select-content-available-height),20rem)] overflow-y-auto p-1",
3736
3850
  position === "popper" && "h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]"
3737
3851
  ),
3738
3852
  children
@@ -3750,40 +3864,76 @@ var SelectLabel = React6.forwardRef(({ className, ...props }, ref) => /* @__PURE
3750
3864
  }
3751
3865
  ));
3752
3866
  SelectLabel.displayName = SelectPrimitive.Label.displayName;
3753
- var SelectItem = React6.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
3754
- SelectPrimitive.Item,
3755
- {
3756
- ref,
3757
- className: cn(
3758
- "relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-2 pr-8 text-sm outline-none hover:bg-zinc-100 focus:bg-zinc-100 focus:text-zinc-900 data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
3759
- className
3867
+ var SelectItemTooltip = ({
3868
+ description,
3869
+ itemRef
3870
+ }) => {
3871
+ const [pos, setPos] = React6.useState();
3872
+ React6.useEffect(() => {
3873
+ const el = itemRef.current;
3874
+ if (!el) return;
3875
+ const rect = el.getBoundingClientRect();
3876
+ setPos({ top: rect.top + rect.height / 2, left: rect.right + 8 });
3877
+ }, [itemRef]);
3878
+ if (!pos) return;
3879
+ return ReactDOM.createPortal(
3880
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
3881
+ "div",
3882
+ {
3883
+ className: "pointer-events-none fixed z-[100] -translate-y-1/2 whitespace-nowrap rounded-md bg-zinc-900 px-3 py-1.5 text-xs text-zinc-50 shadow-md animate-in fade-in-0",
3884
+ style: { top: pos.top, left: pos.left },
3885
+ children: description
3886
+ }
3760
3887
  ),
3761
- ...props,
3762
- children: [
3763
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "absolute right-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, SelectPrimitive.ItemIndicator, { children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
3764
- "svg",
3765
- {
3766
- width: "15",
3767
- height: "15",
3768
- viewBox: "0 0 15 15",
3769
- fill: "none",
3770
- xmlns: "http://www.w3.org/2000/svg",
3771
- className: "h-4 w-4",
3772
- children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
3773
- "path",
3774
- {
3775
- d: "M11.4669 3.72684C11.7558 3.91574 11.8369 4.30308 11.648 4.59198L7.39799 11.092C7.29783 11.2452 7.13556 11.3467 6.95402 11.3699C6.77247 11.3931 6.58989 11.3355 6.45446 11.2124L3.70446 8.71241C3.44905 8.48022 3.43023 8.08494 3.66242 7.82953C3.89461 7.57412 4.28989 7.55529 4.5453 7.78749L6.75292 9.79441L10.6018 3.90792C10.7907 3.61902 11.178 3.53795 11.4669 3.72684Z",
3776
- fill: "currentColor",
3777
- fillRule: "evenodd",
3778
- clipRule: "evenodd"
3779
- }
3780
- )
3781
- }
3782
- ) }) }),
3783
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, SelectPrimitive.ItemText, { children })
3784
- ]
3785
- }
3786
- ));
3888
+ _nullishCoalesce(portalRoot, () => ( document.body))
3889
+ );
3890
+ };
3891
+ var SelectItem = React6.forwardRef(({ className, children, description, ...props }, ref) => {
3892
+ const [isHovered, setIsHovered] = React6.useState(false);
3893
+ const itemRef = React6.useRef(null);
3894
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
3895
+ SelectPrimitive.Item,
3896
+ {
3897
+ ref: (node) => {
3898
+ ;
3899
+ itemRef.current = node;
3900
+ if (typeof ref === "function") ref(node);
3901
+ else if (ref) ref.current = node;
3902
+ },
3903
+ className: cn(
3904
+ "relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-2 pr-8 text-sm outline-none hover:bg-zinc-100 focus:bg-zinc-100 focus:text-zinc-900 data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
3905
+ className
3906
+ ),
3907
+ onMouseEnter: () => setIsHovered(true),
3908
+ onMouseLeave: () => setIsHovered(false),
3909
+ ...props,
3910
+ children: [
3911
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "absolute right-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, SelectPrimitive.ItemIndicator, { children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
3912
+ "svg",
3913
+ {
3914
+ width: "15",
3915
+ height: "15",
3916
+ viewBox: "0 0 15 15",
3917
+ fill: "none",
3918
+ xmlns: "http://www.w3.org/2000/svg",
3919
+ className: "h-4 w-4",
3920
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
3921
+ "path",
3922
+ {
3923
+ d: "M11.4669 3.72684C11.7558 3.91574 11.8369 4.30308 11.648 4.59198L7.39799 11.092C7.29783 11.2452 7.13556 11.3467 6.95402 11.3699C6.77247 11.3931 6.58989 11.3355 6.45446 11.2124L3.70446 8.71241C3.44905 8.48022 3.43023 8.08494 3.66242 7.82953C3.89461 7.57412 4.28989 7.55529 4.5453 7.78749L6.75292 9.79441L10.6018 3.90792C10.7907 3.61902 11.178 3.53795 11.4669 3.72684Z",
3924
+ fill: "currentColor",
3925
+ fillRule: "evenodd",
3926
+ clipRule: "evenodd"
3927
+ }
3928
+ )
3929
+ }
3930
+ ) }) }),
3931
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, SelectPrimitive.ItemText, { children }),
3932
+ description && isHovered && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, SelectItemTooltip, { description, itemRef })
3933
+ ]
3934
+ }
3935
+ );
3936
+ });
3787
3937
  SelectItem.displayName = SelectPrimitive.Item.displayName;
3788
3938
  var SelectSeparator = React6.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
3789
3939
  SelectPrimitive.Separator,
@@ -3890,16 +4040,22 @@ function parseFields(content, prefix, flatSchema) {
3890
4040
  if (fieldName.startsWith('"') && fieldName.endsWith('"') || fieldName.startsWith("'") && fieldName.endsWith("'")) {
3891
4041
  fieldName = fieldName.slice(1, -1);
3892
4042
  }
4043
+ if (fieldName.length === 0) {
4044
+ throw new Error("Field name cannot be empty");
4045
+ }
3893
4046
  const valueStr = entry.slice(colonIndex + 1).trim();
3894
4047
  const fullKey = prefix ? `${prefix}.${fieldName}` : fieldName;
3895
4048
  if (valueStr.startsWith("s.object(")) {
3896
4049
  const nestedContent = extractObjectContent(valueStr);
3897
- if (nestedContent !== null) {
3898
- parseFields(nestedContent, fullKey, flatSchema);
3899
- continue;
4050
+ if (nestedContent === void 0) {
4051
+ throw new Error(
4052
+ `Malformed s.object() for field "${fullKey}": missing closing brace or parenthesis`
4053
+ );
3900
4054
  }
4055
+ parseFields(nestedContent, fullKey, flatSchema);
4056
+ continue;
3901
4057
  }
3902
- const fieldValue = parseFieldBuilder(valueStr);
4058
+ const fieldValue = parseFieldBuilder(valueStr, fullKey);
3903
4059
  if (fieldValue) {
3904
4060
  flatSchema[fullKey] = fieldValue;
3905
4061
  }
@@ -3960,15 +4116,15 @@ function findColonIndex(entry) {
3960
4116
  }
3961
4117
  function extractObjectContent(str) {
3962
4118
  const match = str.match(/^s\.object\s*\(\s*{([\S\s]*)}\s*\)/);
3963
- return match ? match[1] : null;
4119
+ return match ? match[1] : void 0;
3964
4120
  }
3965
4121
  function extractFromValue(str) {
3966
4122
  const fromIndex = str.indexOf(".from(");
3967
- if (fromIndex === -1) return null;
4123
+ if (fromIndex === -1) return void 0;
3968
4124
  const start = fromIndex + 6;
3969
- if (start >= str.length) return null;
4125
+ if (start >= str.length) return void 0;
3970
4126
  const quoteChar = str[start];
3971
- if (quoteChar !== '"' && quoteChar !== "'") return null;
4127
+ if (quoteChar !== '"' && quoteChar !== "'") return void 0;
3972
4128
  let result = "";
3973
4129
  let i = start + 1;
3974
4130
  while (i < str.length) {
@@ -3984,151 +4140,61 @@ function extractFromValue(str) {
3984
4140
  result += char;
3985
4141
  i++;
3986
4142
  }
3987
- return null;
4143
+ return void 0;
3988
4144
  }
3989
- function parseFieldBuilder(str) {
4145
+ function parseFieldBuilder(str, fieldName) {
3990
4146
  str = str.trim().replace(/,\s*$/, "");
3991
4147
  if (str.startsWith("s.string()")) {
3992
4148
  const noTokenize = str.includes(".noTokenize()");
3993
4149
  const noStem = str.includes(".noStem()");
3994
4150
  const fromValue = extractFromValue(str);
3995
- if (!noTokenize && !noStem && fromValue === null) return "TEXT";
4151
+ if (!noTokenize && !noStem && fromValue === void 0) return "TEXT";
3996
4152
  return {
3997
4153
  type: "TEXT",
3998
4154
  ...noTokenize && { noTokenize: true },
3999
4155
  ...noStem && { noStem: true },
4000
- ...fromValue !== null && { from: fromValue }
4156
+ ...fromValue !== void 0 && { from: fromValue }
4001
4157
  };
4002
4158
  }
4003
4159
  if (str.startsWith("s.number(")) {
4004
4160
  const typeMatch = str.match(/s\.number\(\s*["']?(U64|I64|F64)?["']?\s*\)/);
4005
4161
  const numType = _optionalChain([typeMatch, 'optionalAccess', _31 => _31[1]]) || "F64";
4006
4162
  const fromValue = extractFromValue(str);
4007
- if (fromValue === null) return numType;
4163
+ if (fromValue === void 0) return numType;
4008
4164
  return { type: numType, from: fromValue };
4009
4165
  }
4010
4166
  if (str.startsWith("s.boolean()")) {
4011
4167
  const fast = str.includes(".fast()");
4012
4168
  const fromValue = extractFromValue(str);
4013
- if (!fast && fromValue === null) return "BOOL";
4169
+ if (!fast && fromValue === void 0) return "BOOL";
4014
4170
  return {
4015
4171
  type: "BOOL",
4016
4172
  ...fast && { fast: true },
4017
- ...fromValue !== null && { from: fromValue }
4173
+ ...fromValue !== void 0 && { from: fromValue }
4018
4174
  };
4019
4175
  }
4020
4176
  if (str.startsWith("s.date()")) {
4021
4177
  const fast = str.includes(".fast()");
4022
4178
  const fromValue = extractFromValue(str);
4023
- if (!fast && fromValue === null) return "DATE";
4179
+ if (!fast && fromValue === void 0) return "DATE";
4024
4180
  return {
4025
4181
  type: "DATE",
4026
4182
  ...fast && { fast: true },
4027
- ...fromValue !== null && { from: fromValue }
4183
+ ...fromValue !== void 0 && { from: fromValue }
4028
4184
  };
4029
4185
  }
4030
- return null;
4031
- }
4032
- function schemaToEditorValue(flatSchema) {
4033
- const nested = unflattenSchema(flatSchema);
4034
- const body = renderObject(nested, 1);
4035
- return `const schema: Schema = s.object({
4036
- ${body}})`;
4037
- }
4038
- function unflattenSchema(flat) {
4039
- const result = {};
4040
- for (const [key, value] of Object.entries(flat)) {
4041
- const parts = key.split(".");
4042
- let current = result;
4043
- for (let i = 0; i < parts.length - 1; i++) {
4044
- const part = parts[i];
4045
- if (!current[part] || typeof current[part] !== "object") {
4046
- current[part] = {};
4047
- }
4048
- current = current[part];
4049
- }
4050
- current[parts.at(-1)] = value;
4051
- }
4052
- return result;
4053
- }
4054
- function renderObject(obj, indent) {
4055
- const pad = " ".repeat(indent);
4056
- const lines = [];
4057
- for (const [key, value] of Object.entries(obj)) {
4058
- if (isFieldValue(value)) {
4059
- lines.push(`${pad}${key}: ${fieldToBuilder(value)},`);
4060
- } else {
4061
- const nested = renderObject(value, indent + 1);
4062
- lines.push(`${pad}${key}: s.object({`);
4063
- lines.push(nested.trimEnd());
4064
- lines.push(`${pad}}),`);
4065
- }
4066
- }
4067
- return lines.join("\n") + "\n";
4068
- }
4069
- function isFieldValue(value) {
4070
- if (typeof value === "string") return true;
4071
- if (typeof value === "object" && value !== null) {
4072
- return "type" in value;
4073
- }
4074
- return false;
4075
- }
4076
- function fieldToBuilder(value) {
4077
- if (typeof value === "string") {
4078
- switch (value) {
4079
- case "TEXT": {
4080
- return "s.string()";
4081
- }
4082
- case "BOOL": {
4083
- return "s.boolean()";
4084
- }
4085
- case "DATE": {
4086
- return "s.date()";
4087
- }
4088
- case "U64":
4089
- case "I64":
4090
- case "F64": {
4091
- return `s.number("${value}")`;
4092
- }
4093
- default: {
4094
- return "s.string()";
4095
- }
4096
- }
4186
+ if (str.startsWith("s.keyword()")) {
4187
+ return "KEYWORD";
4097
4188
  }
4098
- const v = value;
4099
- const type = v.type;
4100
- let builder = "";
4101
- switch (type) {
4102
- case "TEXT": {
4103
- builder = "s.string()";
4104
- if (v.noTokenize) builder += ".noTokenize()";
4105
- if (v.noStem) builder += ".noStem()";
4106
- break;
4107
- }
4108
- case "U64":
4109
- case "I64":
4110
- case "F64": {
4111
- builder = `s.number("${type}")`;
4112
- break;
4113
- }
4114
- case "BOOL": {
4115
- builder = "s.boolean()";
4116
- if (v.fast) builder += ".fast()";
4117
- break;
4118
- }
4119
- case "DATE": {
4120
- builder = "s.date()";
4121
- if (v.fast) builder += ".fast()";
4122
- break;
4123
- }
4124
- default: {
4125
- builder = "s.string()";
4126
- }
4189
+ if (str.startsWith("s.facet()")) {
4190
+ return "FACET";
4127
4191
  }
4128
- if (v.from) {
4129
- builder += `.from("${v.from}")`;
4192
+ if (str.startsWith("s.")) {
4193
+ const typeMatch = str.match(/^s\.(\w+)\(/);
4194
+ const typeName = _nullishCoalesce(_optionalChain([typeMatch, 'optionalAccess', _32 => _32[1]]), () => ( "unknown"));
4195
+ throw new Error(`Unknown field type "s.${typeName}()" for field "${fieldName}"`);
4130
4196
  }
4131
- return builder;
4197
+ return void 0;
4132
4198
  }
4133
4199
 
4134
4200
  // src/components/databrowser/hooks/use-create-search-index-schema.tsx
@@ -4168,37 +4234,113 @@ var useCreateSearchIndexSchema = () => {
4168
4234
  // src/components/databrowser/components/display/display-header.tsx
4169
4235
 
4170
4236
 
4171
- // src/components/ui/tooltip.tsx
4172
-
4237
+ // src/components/ui/scroll-area.tsx
4173
4238
 
4239
+ var _reactscrollarea = require('@radix-ui/react-scroll-area'); var ScrollAreaPrimitive = _interopRequireWildcard(_reactscrollarea);
4174
4240
 
4175
- var Tooltip = TooltipPrimitive.Root;
4176
- var TooltipTrigger = TooltipPrimitive.Trigger;
4177
- var TooltipContent = React7.forwardRef(({ className, sideOffset = 4, ...props }, ref) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, TooltipPrimitive.Portal, { container: portalRoot, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
4178
- TooltipPrimitive.Content,
4179
- {
4180
- ref,
4181
- sideOffset,
4182
- className: cn(
4183
- "z-50 overflow-hidden rounded-md bg-zinc-900 px-3 py-1.5 text-xs text-zinc-50 animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
4184
- className
4185
- ),
4241
+ var ScrollArea = React7.forwardRef(
4242
+ ({
4243
+ className,
4244
+ scrollBarClassName,
4245
+ scrollBarForceMount,
4246
+ children,
4247
+ onScroll,
4248
+ disableRoundedInherit = false,
4249
+ orientation = "vertical",
4186
4250
  ...props
4187
- }
4188
- ) }));
4189
- TooltipContent.displayName = TooltipPrimitive.Content.displayName;
4190
- var SimpleTooltip = ({
4191
- content,
4192
- children,
4193
- variant = "default"
4194
- }) => {
4195
- if (!content) return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _jsxruntime.Fragment, { children });
4196
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, Tooltip, { delayDuration: 100, children: [
4197
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, TooltipTrigger, { asChild: true, children }),
4198
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
4199
- TooltipContent,
4200
- {
4201
- side: "top",
4251
+ }, ref) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
4252
+ ScrollAreaPrimitive.Root,
4253
+ {
4254
+ ref,
4255
+ className: cn("relative overflow-hidden", className),
4256
+ ...props,
4257
+ children: [
4258
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
4259
+ ScrollAreaPrimitive.Viewport,
4260
+ {
4261
+ onScroll,
4262
+ className: cn(
4263
+ "h-full w-full [&>div]:!block",
4264
+ !disableRoundedInherit && "rounded-[inherit]"
4265
+ ),
4266
+ children
4267
+ }
4268
+ ),
4269
+ (orientation === "vertical" || orientation === "both") && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
4270
+ ScrollBar,
4271
+ {
4272
+ className: scrollBarClassName,
4273
+ forceMount: scrollBarForceMount,
4274
+ orientation: "vertical"
4275
+ }
4276
+ ),
4277
+ (orientation === "horizontal" || orientation === "both") && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
4278
+ ScrollBar,
4279
+ {
4280
+ className: scrollBarClassName,
4281
+ forceMount: scrollBarForceMount,
4282
+ orientation: "horizontal"
4283
+ }
4284
+ ),
4285
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ScrollAreaPrimitive.Corner, {})
4286
+ ]
4287
+ }
4288
+ )
4289
+ );
4290
+ ScrollArea.displayName = ScrollAreaPrimitive.Root.displayName;
4291
+ var ScrollBar = React7.forwardRef(({ className, orientation = "vertical", ...props }, ref) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
4292
+ ScrollAreaPrimitive.ScrollAreaScrollbar,
4293
+ {
4294
+ ref,
4295
+ orientation,
4296
+ className: cn(
4297
+ "flex touch-none select-none transition-colors",
4298
+ orientation === "vertical" && "mr-1 h-full w-2",
4299
+ orientation === "horizontal" && "mb-1 h-2 w-full flex-col",
4300
+ className
4301
+ ),
4302
+ ...props,
4303
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
4304
+ ScrollAreaPrimitive.ScrollAreaThumb,
4305
+ {
4306
+ className: cn("relative flex-1 rounded-full bg-zinc-400/70")
4307
+ }
4308
+ )
4309
+ }
4310
+ ));
4311
+ ScrollBar.displayName = ScrollAreaPrimitive.ScrollAreaScrollbar.displayName;
4312
+
4313
+ // src/components/ui/tooltip.tsx
4314
+
4315
+
4316
+
4317
+ var Tooltip = TooltipPrimitive.Root;
4318
+ var TooltipTrigger = TooltipPrimitive.Trigger;
4319
+ var TooltipContent = React8.forwardRef(({ className, sideOffset = 4, ...props }, ref) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, TooltipPrimitive.Portal, { container: portalRoot, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
4320
+ TooltipPrimitive.Content,
4321
+ {
4322
+ ref,
4323
+ sideOffset,
4324
+ className: cn(
4325
+ "z-50 overflow-hidden rounded-md bg-zinc-900 px-3 py-1.5 text-xs text-zinc-50 animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
4326
+ className
4327
+ ),
4328
+ ...props
4329
+ }
4330
+ ) }));
4331
+ TooltipContent.displayName = TooltipPrimitive.Content.displayName;
4332
+ var SimpleTooltip = ({
4333
+ content,
4334
+ children,
4335
+ variant = "default"
4336
+ }) => {
4337
+ if (!content) return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _jsxruntime.Fragment, { children });
4338
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, Tooltip, { delayDuration: 100, children: [
4339
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, TooltipTrigger, { asChild: true, children }),
4340
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
4341
+ TooltipContent,
4342
+ {
4343
+ side: "top",
4202
4344
  className: variant === "error" ? "bg-white text-red-500 shadow-md" : void 0,
4203
4345
  children: content
4204
4346
  }
@@ -4429,7 +4571,7 @@ var useFetchListItems = ({ dataKey, type }) => {
4429
4571
  // +1 since first message is the last one
4430
4572
  LIST_DISPLAY_PAGE_SIZE + 1
4431
4573
  );
4432
- const lastMessageId = messages.length > 0 ? _optionalChain([messages, 'access', _32 => _32.at, 'call', _33 => _33(-1), 'optionalAccess', _34 => _34[0]]) : void 0;
4574
+ const lastMessageId = messages.length > 0 ? _optionalChain([messages, 'access', _33 => _33.at, 'call', _34 => _34(-1), 'optionalAccess', _35 => _35[0]]) : void 0;
4433
4575
  return {
4434
4576
  cursor: messages.length < LIST_DISPLAY_PAGE_SIZE ? void 0 : lastMessageId,
4435
4577
  keys: messages.map(([id, fields]) => ({
@@ -4466,7 +4608,6 @@ function transformArray(inputArray) {
4466
4608
  var FETCH_SIMPLE_KEY_QUERY_KEY = "fetch-simple-key";
4467
4609
  var useFetchSimpleKey = (dataKey, type) => {
4468
4610
  const { redisNoPipeline: redis } = useRedis();
4469
- const { deleteKeyCache } = useDeleteKeyCache();
4470
4611
  return _reactquery.useQuery.call(void 0, {
4471
4612
  queryKey: [FETCH_SIMPLE_KEY_QUERY_KEY, dataKey],
4472
4613
  queryFn: async () => {
@@ -4476,7 +4617,6 @@ var useFetchSimpleKey = (dataKey, type) => {
4476
4617
  else throw new Error(`Invalid type when fetching simple key: ${type}`);
4477
4618
  if (type === "json" && result !== null)
4478
4619
  result = JSON.stringify(sortObject(JSON.parse(result)));
4479
- if (result === null) deleteKeyCache(dataKey);
4480
4620
  return result;
4481
4621
  }
4482
4622
  });
@@ -4492,10 +4632,9 @@ var sortObject = (obj) => {
4492
4632
 
4493
4633
  // src/components/databrowser/hooks/use-delete-key-cache.ts
4494
4634
  var useDeleteKeyCache = () => {
4495
- const { setSelectedKey } = useTab();
4635
+ const { isValuesSearchSelected, valuesSearch } = useTab();
4496
4636
  const deleteKeyCache = _react.useCallback.call(void 0,
4497
4637
  (key) => {
4498
- setSelectedKey(void 0);
4499
4638
  queryClient.invalidateQueries({
4500
4639
  queryKey: [FETCH_KEYS_QUERY_KEY]
4501
4640
  });
@@ -4508,22 +4647,39 @@ var useDeleteKeyCache = () => {
4508
4647
  queryClient.invalidateQueries({
4509
4648
  queryKey: [FETCH_KEY_TYPE_QUERY_KEY, key]
4510
4649
  });
4650
+ queryClient.invalidateQueries({
4651
+ queryKey: [FETCH_SEARCH_INDEX_QUERY_KEY, key]
4652
+ });
4653
+ queryClient.invalidateQueries({
4654
+ queryKey: [FETCH_SEARCH_INDEXES_QUERY_KEY]
4655
+ });
4656
+ if (isValuesSearchSelected && valuesSearch.index) {
4657
+ queryClient.invalidateQueries({
4658
+ queryKey: [FETCH_SEARCH_INDEX_QUERY_KEY, valuesSearch.index]
4659
+ });
4660
+ }
4511
4661
  },
4512
- [setSelectedKey]
4662
+ [isValuesSearchSelected, valuesSearch.index]
4513
4663
  );
4514
4664
  return { deleteKeyCache };
4515
4665
  };
4516
4666
 
4517
4667
  // src/components/databrowser/hooks/use-delete-key.ts
4518
4668
  var useDeleteKey = () => {
4519
- const { redis } = useRedis();
4669
+ const { redis, redisNoPipeline } = useRedis();
4520
4670
  const { deleteKeyCache } = useDeleteKeyCache();
4671
+ const { isValuesSearchSelected, valuesSearch } = useTab();
4521
4672
  const deleteKey = _reactquery.useMutation.call(void 0, {
4522
- mutationFn: async (key) => {
4523
- return Boolean(await redis.del(key));
4673
+ mutationFn: async ({ keys, reindex }) => {
4674
+ await Promise.all(keys.map((key) => redis.del(key)));
4675
+ if (reindex && isValuesSearchSelected && valuesSearch.index) {
4676
+ await redisNoPipeline.search.index({ name: valuesSearch.index }).waitIndexing();
4677
+ }
4524
4678
  },
4525
- onSuccess: (_, key) => {
4526
- deleteKeyCache(key);
4679
+ onSuccess: (_, { keys }) => {
4680
+ for (const key of keys) {
4681
+ deleteKeyCache(key);
4682
+ }
4527
4683
  }
4528
4684
  });
4529
4685
  return deleteKey;
@@ -4590,7 +4746,7 @@ var useEditListItem = () => {
4590
4746
  }
4591
4747
  case "stream": {
4592
4748
  if (!isNew || !newKey) throw new Error("Stream data type is not mutable");
4593
- const opts = transformArray(_nullishCoalesce(_optionalChain([newValue, 'optionalAccess', _35 => _35.split, 'call', _36 => _36("\n")]), () => ( []))).map(
4749
+ const opts = transformArray(_nullishCoalesce(_optionalChain([newValue, 'optionalAccess', _36 => _36.split, 'call', _37 => _37("\n")]), () => ( []))).map(
4594
4750
  ({ key, value }) => [key, value]
4595
4751
  );
4596
4752
  pipe.xadd(dataKey, newKey, Object.fromEntries(opts));
@@ -4628,7 +4784,7 @@ var _reactpopover = require('@radix-ui/react-popover'); var PopoverPrimitive = _
4628
4784
 
4629
4785
  var Popover = PopoverPrimitive.Root;
4630
4786
  var PopoverTrigger = PopoverPrimitive.Trigger;
4631
- var PopoverContent = React8.forwardRef(({ className, align = "center", sideOffset = 4, ...props }, ref) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, PopoverPrimitive.Portal, { container: portalRoot, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
4787
+ var PopoverContent = React9.forwardRef(({ className, align = "center", sideOffset = 4, ...props }, ref) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, PopoverPrimitive.Portal, { container: portalRoot, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
4632
4788
  PopoverPrimitive.Content,
4633
4789
  {
4634
4790
  ref,
@@ -4897,7 +5053,7 @@ var LengthBadge = ({
4897
5053
  content
4898
5054
  }) => {
4899
5055
  const { data, isLoading } = useFetchKeyLength({ dataKey, type });
4900
- const length = _nullishCoalesce(_optionalChain([content, 'optionalAccess', _37 => _37.length]), () => ( data));
5056
+ const length = _nullishCoalesce(_optionalChain([content, 'optionalAccess', _38 => _38.length]), () => ( data));
4901
5057
  return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Badge, { label: "Length:", children: isLoading ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Skeleton, { className: "ml-1 h-3 w-10 rounded-md opacity-50" }) : length });
4902
5058
  };
4903
5059
  var SizeBadge = ({ dataKey }) => {
@@ -4918,8 +5074,8 @@ var HeaderTTLBadge = ({ dataKey }) => {
4918
5074
  }
4919
5075
  );
4920
5076
  };
4921
- var Badge = ({ children, label }) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex h-[26px] items-center gap-0.5 whitespace-nowrap rounded-md bg-zinc-200 px-2 text-xs text-zinc-700 dark:bg-zinc-200", children: [
4922
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-zinc-500 dark:text-zinc-500", children: label }),
5077
+ var Badge = ({ children, label }) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex h-[26px] items-center gap-0.5 whitespace-nowrap rounded-md bg-zinc-200 px-2 text-xs text-zinc-700 dark:bg-zinc-300", children: [
5078
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-zinc-500 dark:text-zinc-600", children: label }),
4923
5079
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "font-medium", children })
4924
5080
  ] });
4925
5081
 
@@ -4933,7 +5089,7 @@ var _reactdropdownmenu = require('@radix-ui/react-dropdown-menu'); var DropdownM
4933
5089
 
4934
5090
  var DropdownMenu = DropdownMenuPrimitive.Root;
4935
5091
  var DropdownMenuTrigger = DropdownMenuPrimitive.Trigger;
4936
- var DropdownMenuSubTrigger = React9.forwardRef(({ className, inset, children, ...props }, ref) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
5092
+ var DropdownMenuSubTrigger = React10.forwardRef(({ className, inset, children, ...props }, ref) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
4937
5093
  DropdownMenuPrimitive.SubTrigger,
4938
5094
  {
4939
5095
  ref,
@@ -4950,7 +5106,7 @@ var DropdownMenuSubTrigger = React9.forwardRef(({ className, inset, children, ..
4950
5106
  }
4951
5107
  ));
4952
5108
  DropdownMenuSubTrigger.displayName = DropdownMenuPrimitive.SubTrigger.displayName;
4953
- var DropdownMenuSubContent = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
5109
+ var DropdownMenuSubContent = React10.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
4954
5110
  DropdownMenuPrimitive.SubContent,
4955
5111
  {
4956
5112
  ref,
@@ -4962,7 +5118,7 @@ var DropdownMenuSubContent = React9.forwardRef(({ className, ...props }, ref) =>
4962
5118
  }
4963
5119
  ));
4964
5120
  DropdownMenuSubContent.displayName = DropdownMenuPrimitive.SubContent.displayName;
4965
- var DropdownMenuContent = React9.forwardRef(({ className, sideOffset = 4, ...props }, ref) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, DropdownMenuPrimitive.Portal, { container: portalRoot, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
5121
+ var DropdownMenuContent = React10.forwardRef(({ className, sideOffset = 4, ...props }, ref) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, DropdownMenuPrimitive.Portal, { container: portalRoot, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
4966
5122
  DropdownMenuPrimitive.Content,
4967
5123
  {
4968
5124
  ref,
@@ -4976,7 +5132,7 @@ var DropdownMenuContent = React9.forwardRef(({ className, sideOffset = 4, ...pro
4976
5132
  }
4977
5133
  ) }));
4978
5134
  DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName;
4979
- var DropdownMenuItem = React9.forwardRef(({ className, inset, ...props }, ref) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
5135
+ var DropdownMenuItem = React10.forwardRef(({ className, inset, ...props }, ref) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
4980
5136
  DropdownMenuPrimitive.Item,
4981
5137
  {
4982
5138
  ref,
@@ -4989,7 +5145,7 @@ var DropdownMenuItem = React9.forwardRef(({ className, inset, ...props }, ref) =
4989
5145
  }
4990
5146
  ));
4991
5147
  DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName;
4992
- var DropdownMenuCheckboxItem = React9.forwardRef(({ className, children, checked, ...props }, ref) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
5148
+ var DropdownMenuCheckboxItem = React10.forwardRef(({ className, children, checked, ...props }, ref) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
4993
5149
  DropdownMenuPrimitive.CheckboxItem,
4994
5150
  {
4995
5151
  ref,
@@ -5006,7 +5162,7 @@ var DropdownMenuCheckboxItem = React9.forwardRef(({ className, children, checked
5006
5162
  }
5007
5163
  ));
5008
5164
  DropdownMenuCheckboxItem.displayName = DropdownMenuPrimitive.CheckboxItem.displayName;
5009
- var DropdownMenuRadioItem = React9.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
5165
+ var DropdownMenuRadioItem = React10.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
5010
5166
  DropdownMenuPrimitive.RadioItem,
5011
5167
  {
5012
5168
  ref,
@@ -5022,7 +5178,7 @@ var DropdownMenuRadioItem = React9.forwardRef(({ className, children, ...props }
5022
5178
  }
5023
5179
  ));
5024
5180
  DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName;
5025
- var DropdownMenuLabel = React9.forwardRef(({ className, inset, ...props }, ref) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
5181
+ var DropdownMenuLabel = React10.forwardRef(({ className, inset, ...props }, ref) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
5026
5182
  DropdownMenuPrimitive.Label,
5027
5183
  {
5028
5184
  ref,
@@ -5031,7 +5187,7 @@ var DropdownMenuLabel = React9.forwardRef(({ className, inset, ...props }, ref)
5031
5187
  }
5032
5188
  ));
5033
5189
  DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName;
5034
- var DropdownMenuSeparator = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
5190
+ var DropdownMenuSeparator = React10.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
5035
5191
  DropdownMenuPrimitive.Separator,
5036
5192
  {
5037
5193
  ref,
@@ -5045,80 +5201,134 @@ var DropdownMenuShortcut = ({ className, ...props }) => {
5045
5201
  };
5046
5202
  DropdownMenuShortcut.displayName = "DropdownMenuShortcut";
5047
5203
 
5048
- // src/components/ui/alert-dialog.tsx
5204
+ // src/components/databrowser/components/delete-key-modal.tsx
5205
+
5049
5206
 
5050
- var _reactalertdialog = require('@radix-ui/react-alert-dialog'); var AlertDialogPrimitive = _interopRequireWildcard(_reactalertdialog);
5207
+ // src/components/ui/dialog.tsx
5208
+
5209
+ var _reactdialog = require('@radix-ui/react-dialog'); var DialogPrimitive = _interopRequireWildcard(_reactdialog);
5051
5210
 
5052
- var AlertDialog = AlertDialogPrimitive.Root;
5053
- var AlertDialogTrigger = AlertDialogPrimitive.Trigger;
5054
- var AlertDialogPortal = ({ ...props }) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, AlertDialogPrimitive.Portal, { container: portalRoot, ...props });
5055
- AlertDialogPortal.displayName = AlertDialogPrimitive.Portal.displayName;
5056
- var AlertDialogOverlay = React10.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
5057
- AlertDialogPrimitive.Overlay,
5211
+ var Dialog = DialogPrimitive.Root;
5212
+ var DialogTrigger = DialogPrimitive.Trigger;
5213
+ var DialogPortal = (props) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, DialogPrimitive.Portal, { container: portalRoot, ...props });
5214
+ DialogPortal.displayName = DialogPrimitive.Portal.displayName;
5215
+ var DialogOverlay = React11.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
5216
+ DialogPrimitive.Overlay,
5058
5217
  {
5218
+ ref,
5059
5219
  className: cn(
5060
- "fixed inset-0 z-50 bg-white/80 backdrop-blur-sm data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
5220
+ "data-[state=open]:animate-in data-[state=closed]:animate-out",
5221
+ "data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
5222
+ "fixed inset-0 z-50 bg-black/50 backdrop-blur-sm",
5061
5223
  className
5062
5224
  ),
5063
- ...props,
5064
- ref
5225
+ ...props
5065
5226
  }
5066
5227
  ));
5067
- AlertDialogOverlay.displayName = AlertDialogPrimitive.Overlay.displayName;
5068
- var AlertDialogContent = React10.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, AlertDialogPortal, { children: [
5069
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, AlertDialogOverlay, {}),
5070
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
5071
- AlertDialogPrimitive.Content,
5228
+ DialogOverlay.displayName = DialogPrimitive.Overlay.displayName;
5229
+ var DialogContent = React11.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, DialogPortal, { children: [
5230
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, DialogOverlay, {}),
5231
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
5232
+ DialogPrimitive.Content,
5072
5233
  {
5073
5234
  ref,
5074
5235
  className: cn(
5075
- "antialiased data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:slide-in-from-top-[48%]sm:rounded-lg fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border border-zinc-200 bg-white p-6 shadow-lg duration-200 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 md:w-full",
5236
+ "antialiased",
5237
+ "data-[state=open]:animate-in data-[state=closed]:animate-out ",
5238
+ "data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 ",
5239
+ "data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 ",
5240
+ "data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%]",
5241
+ "data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%]",
5242
+ "fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg ",
5243
+ "translate-x-[-50%] translate-y-[-50%] gap-4",
5244
+ "bg-white p-8 shadow-lg duration-200 ",
5245
+ "rounded-2xl md:w-full",
5076
5246
  className
5077
5247
  ),
5078
- ...props
5248
+ ...props,
5249
+ children: [
5250
+ children,
5251
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, DialogPrimitive.Close, { className: "absolute right-4 top-4 text-zinc-400 transition-colors hover:text-zinc-600 focus:outline-none disabled:pointer-events-none", children: [
5252
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
5253
+ "svg",
5254
+ {
5255
+ width: "20",
5256
+ height: "20",
5257
+ viewBox: "0 0 15 15",
5258
+ fill: "none",
5259
+ xmlns: "http://www.w3.org/2000/svg",
5260
+ className: "size-5",
5261
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
5262
+ "path",
5263
+ {
5264
+ d: "M11.7816 4.03157C12.0062 3.80702 12.0062 3.44295 11.7816 3.2184C11.5571 2.99385 11.193 2.99385 10.9685 3.2184L7.50005 6.68682L4.03164 3.2184C3.80708 2.99385 3.44301 2.99385 3.21846 3.2184C2.99391 3.44295 2.99391 3.80702 3.21846 4.03157L6.68688 7.49999L3.21846 10.9684C2.99391 11.193 2.99391 11.557 3.21846 11.7816C3.44301 12.0061 3.80708 12.0061 4.03164 11.7816L7.50005 8.31316L10.9685 11.7816C11.193 12.0061 11.5571 12.0061 11.7816 11.7816C12.0062 11.557 12.0062 11.193 11.7816 10.9684L8.31322 7.49999L11.7816 4.03157Z",
5265
+ fill: "currentColor",
5266
+ fillRule: "evenodd",
5267
+ clipRule: "evenodd"
5268
+ }
5269
+ )
5270
+ }
5271
+ ),
5272
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "sr-only", children: "Close" })
5273
+ ] })
5274
+ ]
5079
5275
  }
5080
5276
  )
5081
5277
  ] }));
5082
- AlertDialogContent.displayName = AlertDialogPrimitive.Content.displayName;
5083
- var AlertDialogHeader = ({ className, ...props }) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: cn("flex flex-col space-y-2 text-center sm:text-left", className), ...props });
5084
- AlertDialogHeader.displayName = "AlertDialogHeader";
5085
- var AlertDialogFooter = ({ className, ...props }) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
5278
+ DialogContent.displayName = DialogPrimitive.Content.displayName;
5279
+ var DialogHeader = ({ className, ...props }) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: cn("flex flex-col space-y-1.5 text-center sm:text-left", className), ...props });
5280
+ DialogHeader.displayName = "DialogHeader";
5281
+ var DialogFooter = ({ className, ...props }) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
5086
5282
  "div",
5087
5283
  {
5088
5284
  className: cn("flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2", className),
5089
5285
  ...props
5090
5286
  }
5091
5287
  );
5092
- AlertDialogFooter.displayName = "AlertDialogFooter";
5093
- var AlertDialogTitle = React10.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
5094
- AlertDialogPrimitive.Title,
5288
+ DialogFooter.displayName = "DialogFooter";
5289
+ var DialogTitle = React11.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
5290
+ DialogPrimitive.Title,
5095
5291
  {
5096
5292
  ref,
5097
- className: cn("text-lg font-semibold", className),
5293
+ className: cn("text-base font-semibold text-zinc-950", className),
5098
5294
  ...props
5099
5295
  }
5100
5296
  ));
5101
- AlertDialogTitle.displayName = AlertDialogPrimitive.Title.displayName;
5102
- var AlertDialogDescription = React10.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
5103
- AlertDialogPrimitive.Description,
5297
+ DialogTitle.displayName = DialogPrimitive.Title.displayName;
5298
+ var DialogDescription = React11.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
5299
+ DialogPrimitive.Description,
5104
5300
  {
5105
5301
  ref,
5106
5302
  className: cn("text-sm text-zinc-500", className),
5107
5303
  ...props
5108
5304
  }
5109
5305
  ));
5110
- AlertDialogDescription.displayName = AlertDialogPrimitive.Description.displayName;
5111
- var AlertDialogAction = React10.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, AlertDialogPrimitive.Action, { ref, className: cn(buttonVariants(), className), ...props }));
5112
- AlertDialogAction.displayName = AlertDialogPrimitive.Action.displayName;
5113
- var AlertDialogCancel = React10.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
5114
- AlertDialogPrimitive.Cancel,
5306
+ DialogDescription.displayName = DialogPrimitive.Description.displayName;
5307
+
5308
+ // src/components/ui/switch.tsx
5309
+
5310
+ var _reactswitch = require('@radix-ui/react-switch'); var SwitchPrimitives = _interopRequireWildcard(_reactswitch);
5311
+
5312
+ var Switch = React12.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
5313
+ SwitchPrimitives.Root,
5115
5314
  {
5315
+ className: cn(
5316
+ "peer inline-flex h-5 w-9 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent shadow-sm transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-neutral-950 focus-visible:ring-offset-2 focus-visible:ring-offset-white disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-neutral-900 data-[state=unchecked]:bg-neutral-200 dark:focus-visible:ring-neutral-300 dark:focus-visible:ring-offset-neutral-950 dark:data-[state=checked]:bg-neutral-50 dark:data-[state=unchecked]:bg-neutral-800",
5317
+ className
5318
+ ),
5319
+ ...props,
5116
5320
  ref,
5117
- className: cn(buttonVariants({ variant: "outline" }), "mt-2 sm:!mt-0", className),
5118
- ...props
5321
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
5322
+ SwitchPrimitives.Thumb,
5323
+ {
5324
+ className: cn(
5325
+ "pointer-events-none block h-4 w-4 rounded-full bg-white shadow-lg ring-0 transition-transform data-[state=checked]:translate-x-4 data-[state=unchecked]:translate-x-0 dark:bg-neutral-950"
5326
+ )
5327
+ }
5328
+ )
5119
5329
  }
5120
5330
  ));
5121
- AlertDialogCancel.displayName = AlertDialogPrimitive.Cancel.displayName;
5331
+ Switch.displayName = SwitchPrimitives.Root.displayName;
5122
5332
 
5123
5333
  // src/components/databrowser/components/delete-key-modal.tsx
5124
5334
 
@@ -5128,17 +5338,24 @@ function DeleteKeyModal({
5128
5338
  open,
5129
5339
  onOpenChange,
5130
5340
  deletionType,
5131
- count: count2 = 1
5341
+ count: count2 = 1,
5342
+ showReindex
5132
5343
  }) {
5133
5344
  const isPlural = count2 > 1;
5134
5345
  const itemLabel = deletionType === "item" ? "Item" : "Key";
5135
5346
  const itemsLabel = deletionType === "item" ? "Items" : "Keys";
5136
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, AlertDialog, { open, onOpenChange, children: [
5137
- children && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, AlertDialogTrigger, { asChild: true, children }),
5138
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, AlertDialogContent, { children: [
5139
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, AlertDialogHeader, { children: [
5140
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, AlertDialogTitle, { children: isPlural ? `Delete ${count2} ${itemsLabel}` : `Delete ${itemLabel}` }),
5141
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, AlertDialogDescription, { className: "mt-5", children: [
5347
+ const [internalOpen, setInternalOpen] = _react.useState.call(void 0, false);
5348
+ const [reindex, setReindex] = _react.useState.call(void 0, true);
5349
+ const [isPending, setIsPending] = _react.useState.call(void 0, false);
5350
+ const isControlled = open !== void 0;
5351
+ const isOpen = isControlled ? open : internalOpen;
5352
+ const setIsOpen = isControlled ? onOpenChange : setInternalOpen;
5353
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, Dialog, { open: isOpen, onOpenChange: setIsOpen, children: [
5354
+ children && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, DialogTrigger, { asChild: true, children }),
5355
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, DialogContent, { children: [
5356
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, DialogHeader, { children: [
5357
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, DialogTitle, { children: isPlural ? `Delete ${count2} ${itemsLabel}` : `Delete ${itemLabel}` }),
5358
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, DialogDescription, { className: "mt-5", children: [
5142
5359
  "Are you sure you want to delete",
5143
5360
  " ",
5144
5361
  isPlural ? `these ${count2} ${deletionType}s` : `this ${deletionType}`,
@@ -5147,14 +5364,44 @@ function DeleteKeyModal({
5147
5364
  "This action cannot be undone."
5148
5365
  ] })
5149
5366
  ] }),
5150
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, AlertDialogFooter, { children: [
5151
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, AlertDialogCancel, { type: "button", children: "Cancel" }),
5367
+ showReindex && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center gap-2", children: [
5368
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
5369
+ Switch,
5370
+ {
5371
+ id: "reindex",
5372
+ checked: reindex,
5373
+ onCheckedChange: setReindex,
5374
+ disabled: isPending
5375
+ }
5376
+ ),
5377
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Label, { htmlFor: "reindex", className: "cursor-pointer text-sm text-zinc-700", children: "Reindex after deletion" })
5378
+ ] }),
5379
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, DialogFooter, { children: [
5380
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
5381
+ Button,
5382
+ {
5383
+ type: "button",
5384
+ variant: "outline",
5385
+ disabled: isPending,
5386
+ onClick: () => _optionalChain([setIsOpen, 'optionalCall', _39 => _39(false)]),
5387
+ children: "Cancel"
5388
+ }
5389
+ ),
5152
5390
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
5153
- AlertDialogAction,
5391
+ Button,
5154
5392
  {
5393
+ variant: "primary",
5155
5394
  className: "bg-red-500 text-zinc-50 hover:bg-red-600",
5156
- onClick: onDeleteConfirm,
5157
- children: "Yes, Delete"
5395
+ disabled: isPending,
5396
+ onClick: async (e) => {
5397
+ setIsPending(true);
5398
+ try {
5399
+ await onDeleteConfirm(e, { reindex });
5400
+ } finally {
5401
+ setIsPending(false);
5402
+ }
5403
+ },
5404
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Spinner, { isLoading: isPending, isLoadingText: "Deleting", children: "Yes, Delete" })
5158
5405
  }
5159
5406
  )
5160
5407
  ] })
@@ -5164,8 +5411,13 @@ function DeleteKeyModal({
5164
5411
 
5165
5412
  // src/components/databrowser/components/display/key-actions.tsx
5166
5413
 
5167
- function KeyActions({ dataKey, content }) {
5414
+ function KeyActions({
5415
+ dataKey,
5416
+ content,
5417
+ type
5418
+ }) {
5168
5419
  const { mutateAsync: deleteKey } = useDeleteKey();
5420
+ const { isValuesSearchSelected } = useTab();
5169
5421
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, DropdownMenu, { modal: false, children: [
5170
5422
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Button, { size: "icon-sm", "aria-label": "Key actions", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
5171
5423
  _iconsreact.IconDotsVertical,
@@ -5196,14 +5448,24 @@ function KeyActions({ dataKey, content }) {
5196
5448
  children: "Copy key"
5197
5449
  }
5198
5450
  ),
5199
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, DeleteKeyModal, { deletionType: "key", onDeleteConfirm: async () => await deleteKey(dataKey), children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
5200
- DropdownMenuItem,
5451
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
5452
+ DeleteKeyModal,
5201
5453
  {
5202
- className: "text-red-500 focus:bg-red-500 focus:text-white",
5203
- onSelect: (e) => e.preventDefault(),
5204
- children: "Delete key"
5454
+ deletionType: "key",
5455
+ showReindex: isValuesSearchSelected && type !== "search",
5456
+ onDeleteConfirm: async (_e, options) => {
5457
+ await deleteKey({ keys: [dataKey], reindex: _optionalChain([options, 'optionalAccess', _40 => _40.reindex]) });
5458
+ },
5459
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
5460
+ DropdownMenuItem,
5461
+ {
5462
+ className: "text-red-500 focus:bg-red-500 focus:text-white",
5463
+ onSelect: (e) => e.preventDefault(),
5464
+ children: "Delete key"
5465
+ }
5466
+ )
5205
5467
  }
5206
- ) })
5468
+ )
5207
5469
  ] })
5208
5470
  ] });
5209
5471
  }
@@ -5225,142 +5487,69 @@ var DisplayHeader = ({
5225
5487
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h2", { className: "grow truncate text-sm", children: dataKey.trim() === "" ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "ml-1 text-zinc-500", children: "(Empty Key)" }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "font-medium text-zinc-950", children: dataKey }) }),
5226
5488
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center gap-1", children: [
5227
5489
  type !== "string" && type !== "json" && type !== "search" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, SimpleTooltip, { content: "Add item", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Button, { onClick: handleAddItem, size: "icon-sm", "aria-label": "Add item", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _iconsreact.IconPlus, { className: "size-4 text-zinc-500 dark:text-zinc-600" }) }) }),
5228
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, KeyActions, { dataKey, content })
5490
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, KeyActions, { dataKey, content, type })
5229
5491
  ] })
5230
5492
  ] }),
5231
- type === "search" && hideTypeTag ? void 0 : /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex h-10 items-center gap-1.5 overflow-scroll", children: [
5493
+ type === "search" && hideTypeTag ? void 0 : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ScrollArea, { orientation: "horizontal", className: "w-full whitespace-nowrap", children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex w-max items-center gap-1.5 pb-2 pt-1", children: [
5232
5494
  !hideTypeTag && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, TypeTag, { variant: type, type: "badge" }),
5233
5495
  type !== "search" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, SizeBadge, { dataKey }),
5234
5496
  type !== "search" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, LengthBadge, { dataKey, type, content }),
5235
5497
  type !== "search" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, HeaderTTLBadge, { dataKey })
5236
- ] })
5498
+ ] }) })
5237
5499
  ] });
5238
5500
  };
5239
5501
 
5502
+ // src/components/databrowser/components/display/key-deleted.tsx
5503
+
5504
+ var KeyDeleted = () => {
5505
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex h-full items-center justify-center rounded-md border border-dashed border-zinc-300", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-zinc-500", children: "This key has been deleted" }) });
5506
+ };
5507
+
5508
+ // src/components/databrowser/components/docs-link.tsx
5509
+
5510
+
5511
+ var DocsLink = ({ href, className }) => {
5512
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
5513
+ "a",
5514
+ {
5515
+ href,
5516
+ target: "_blank",
5517
+ rel: "noopener noreferrer",
5518
+ className: cn(
5519
+ "inline-flex items-center gap-1 px-1 text-xs text-zinc-400 transition-colors hover:text-zinc-600",
5520
+ className
5521
+ ),
5522
+ children: [
5523
+ "Docs",
5524
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _iconsreact.IconExternalLink, { size: 12 })
5525
+ ]
5526
+ }
5527
+ );
5528
+ };
5529
+
5240
5530
  // src/components/databrowser/components/search/save-schema-modal.tsx
5241
5531
 
5242
5532
 
5243
- // src/components/ui/dialog.tsx
5533
+ // src/components/ui/progress.tsx
5244
5534
 
5245
- var _reactdialog = require('@radix-ui/react-dialog'); var DialogPrimitive = _interopRequireWildcard(_reactdialog);
5535
+ var _reactprogress = require('@radix-ui/react-progress'); var ProgressPrimitive = _interopRequireWildcard(_reactprogress);
5246
5536
 
5247
- var Dialog = DialogPrimitive.Root;
5248
- var DialogTrigger = DialogPrimitive.Trigger;
5249
- var DialogPortal = (props) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, DialogPrimitive.Portal, { container: portalRoot, ...props });
5250
- DialogPortal.displayName = DialogPrimitive.Portal.displayName;
5251
- var DialogOverlay = React11.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
5252
- DialogPrimitive.Overlay,
5537
+ var Progress = React13.forwardRef(({ className, value, ...props }, ref) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
5538
+ ProgressPrimitive.Root,
5253
5539
  {
5254
5540
  ref,
5255
5541
  className: cn(
5256
- "data-[state=open]:animate-in data-[state=closed]:animate-out",
5257
- "data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
5258
- "fixed inset-0 z-50 bg-black/50 backdrop-blur-sm",
5542
+ "relative h-2 w-full overflow-hidden rounded-full bg-neutral-900/20 dark:bg-neutral-50/20",
5259
5543
  className
5260
5544
  ),
5261
- ...props
5262
- }
5263
- ));
5264
- DialogOverlay.displayName = DialogPrimitive.Overlay.displayName;
5265
- var DialogContent = React11.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, DialogPortal, { children: [
5266
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, DialogOverlay, {}),
5267
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
5268
- DialogPrimitive.Content,
5269
- {
5270
- ref,
5271
- className: cn(
5272
- "antialiased",
5273
- "data-[state=open]:animate-in data-[state=closed]:animate-out ",
5274
- "data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 ",
5275
- "data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 ",
5276
- "data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%]",
5277
- "data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%]",
5278
- "fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg ",
5279
- "translate-x-[-50%] translate-y-[-50%] gap-4",
5280
- "bg-white p-6 shadow-lg duration-200 ",
5281
- "sm:rounded-lg md:w-full",
5282
- className
5283
- ),
5284
- ...props,
5285
- children: [
5286
- children,
5287
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, DialogPrimitive.Close, { className: "absolute right-4 top-4 rounded-sm opacity-70 ring-offset-white transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-zinc-950 focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-zinc-100 data-[state=open]:text-zinc-500", children: [
5288
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
5289
- "svg",
5290
- {
5291
- width: "15",
5292
- height: "15",
5293
- viewBox: "0 0 15 15",
5294
- fill: "none",
5295
- xmlns: "http://www.w3.org/2000/svg",
5296
- className: "h-4 w-4",
5297
- children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
5298
- "path",
5299
- {
5300
- d: "M11.7816 4.03157C12.0062 3.80702 12.0062 3.44295 11.7816 3.2184C11.5571 2.99385 11.193 2.99385 10.9685 3.2184L7.50005 6.68682L4.03164 3.2184C3.80708 2.99385 3.44301 2.99385 3.21846 3.2184C2.99391 3.44295 2.99391 3.80702 3.21846 4.03157L6.68688 7.49999L3.21846 10.9684C2.99391 11.193 2.99391 11.557 3.21846 11.7816C3.44301 12.0061 3.80708 12.0061 4.03164 11.7816L7.50005 8.31316L10.9685 11.7816C11.193 12.0061 11.5571 12.0061 11.7816 11.7816C12.0062 11.557 12.0062 11.193 11.7816 10.9684L8.31322 7.49999L11.7816 4.03157Z",
5301
- fill: "currentColor",
5302
- fillRule: "evenodd",
5303
- clipRule: "evenodd"
5304
- }
5305
- )
5306
- }
5307
- ),
5308
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "sr-only", children: "Close" })
5309
- ] })
5310
- ]
5311
- }
5312
- )
5313
- ] }));
5314
- DialogContent.displayName = DialogPrimitive.Content.displayName;
5315
- var DialogHeader = ({ className, ...props }) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: cn("flex flex-col space-y-1.5 text-center sm:text-left", className), ...props });
5316
- DialogHeader.displayName = "DialogHeader";
5317
- var DialogFooter = ({ className, ...props }) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
5318
- "div",
5319
- {
5320
- className: cn("flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2", className),
5321
- ...props
5322
- }
5323
- );
5324
- DialogFooter.displayName = "DialogFooter";
5325
- var DialogTitle = React11.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
5326
- DialogPrimitive.Title,
5327
- {
5328
- ref,
5329
- className: cn("text-lg font-semibold leading-none tracking-tight", className),
5330
- ...props
5331
- }
5332
- ));
5333
- DialogTitle.displayName = DialogPrimitive.Title.displayName;
5334
- var DialogDescription = React11.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
5335
- DialogPrimitive.Description,
5336
- {
5337
- ref,
5338
- className: cn("text-sm text-zinc-500", className),
5339
- ...props
5340
- }
5341
- ));
5342
- DialogDescription.displayName = DialogPrimitive.Description.displayName;
5343
-
5344
- // src/components/ui/progress.tsx
5345
-
5346
- var _reactprogress = require('@radix-ui/react-progress'); var ProgressPrimitive = _interopRequireWildcard(_reactprogress);
5347
-
5348
- var Progress = React12.forwardRef(({ className, value, ...props }, ref) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
5349
- ProgressPrimitive.Root,
5350
- {
5351
- ref,
5352
- className: cn(
5353
- "relative h-2 w-full overflow-hidden rounded-full bg-neutral-900/20 dark:bg-neutral-50/20",
5354
- className
5355
- ),
5356
- ...props,
5357
- children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
5358
- ProgressPrimitive.Indicator,
5359
- {
5360
- className: "h-full w-full flex-1 bg-neutral-900 transition-all dark:bg-neutral-50",
5361
- style: { transform: `translateX(-${100 - (value || 0)}%)` }
5362
- }
5363
- )
5545
+ ...props,
5546
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
5547
+ ProgressPrimitive.Indicator,
5548
+ {
5549
+ className: "h-full w-full flex-1 bg-neutral-900 transition-all dark:bg-neutral-50",
5550
+ style: { transform: `translateX(-${100 - (value || 0)}%)` }
5551
+ }
5552
+ )
5364
5553
  }
5365
5554
  ));
5366
5555
  Progress.displayName = ProgressPrimitive.Root.displayName;
@@ -5491,16 +5680,18 @@ var MonacoEditorWithTypes = ({
5491
5680
  const monaco = _react2.useMonaco.call(void 0, );
5492
5681
  const editorRef = _react.useRef.call(void 0, null);
5493
5682
  const extraLibRef = _react.useRef.call(void 0, null);
5683
+ const valueRef = _react.useRef.call(void 0, value);
5684
+ valueRef.current = value;
5494
5685
  const theme = useTheme();
5495
5686
  _react.useEffect.call(void 0, () => {
5496
5687
  if (!monaco) return;
5497
- _optionalChain([extraLibRef, 'access', _38 => _38.current, 'optionalAccess', _39 => _39.dispose, 'call', _40 => _40()]);
5688
+ _optionalChain([extraLibRef, 'access', _41 => _41.current, 'optionalAccess', _42 => _42.dispose, 'call', _43 => _43()]);
5498
5689
  extraLibRef.current = monaco.languages.typescript.typescriptDefaults.addExtraLib(
5499
5690
  typeDefinitions,
5500
5691
  `file:///${filePath.replace(".ts", "-types.d.ts")}`
5501
5692
  );
5502
5693
  requestAnimationFrame(() => {
5503
- const model = _optionalChain([editorRef, 'access', _41 => _41.current, 'optionalAccess', _42 => _42.getModel, 'optionalCall', _43 => _43()]);
5694
+ const model = _optionalChain([editorRef, 'access', _44 => _44.current, 'optionalAccess', _45 => _45.getModel, 'optionalCall', _46 => _46()]);
5504
5695
  if (model) {
5505
5696
  const currentValue = model.getValue();
5506
5697
  model.setValue(currentValue);
@@ -5509,10 +5700,10 @@ var MonacoEditorWithTypes = ({
5509
5700
  }, [monaco, typeDefinitions, filePath]);
5510
5701
  _react.useEffect.call(void 0, () => {
5511
5702
  return () => {
5512
- _optionalChain([extraLibRef, 'access', _44 => _44.current, 'optionalAccess', _45 => _45.dispose, 'call', _46 => _46()]);
5703
+ _optionalChain([extraLibRef, 'access', _47 => _47.current, 'optionalAccess', _48 => _48.dispose, 'call', _49 => _49()]);
5513
5704
  if (monaco) {
5514
5705
  const model = monaco.editor.getModel(monaco.Uri.parse(filePath));
5515
- _optionalChain([model, 'optionalAccess', _47 => _47.dispose, 'call', _48 => _48()]);
5706
+ _optionalChain([model, 'optionalAccess', _50 => _50.dispose, 'call', _51 => _51()]);
5516
5707
  }
5517
5708
  };
5518
5709
  }, [monaco, filePath]);
@@ -5522,12 +5713,12 @@ var MonacoEditorWithTypes = ({
5522
5713
  } else if (newValue.trim() === "") {
5523
5714
  onChange(defaultValue);
5524
5715
  } else {
5525
- _optionalChain([editorRef, 'access', _49 => _49.current, 'optionalAccess', _50 => _50.setValue, 'optionalCall', _51 => _51(value)]);
5716
+ _optionalChain([editorRef, 'access', _52 => _52.current, 'optionalAccess', _53 => _53.setValue, 'optionalCall', _54 => _54(valueRef.current)]);
5526
5717
  }
5527
5718
  };
5528
5719
  _react.useEffect.call(void 0, () => {
5529
5720
  if (!validateValue(value)) onChange(defaultValue);
5530
- }, [value, editorRef.current, onChange, validateValue, defaultValue]);
5721
+ }, [value, onChange, validateValue, defaultValue]);
5531
5722
  return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
5532
5723
  "div",
5533
5724
  {
@@ -5664,7 +5855,7 @@ type TextFieldBuild<TNoTokenize extends Record<"noTokenize", boolean>, TNoStem e
5664
5855
  } : {}) : TFrom["from"] extends string ? {
5665
5856
  type: "TEXT";
5666
5857
  from: TFrom["from"];
5667
- } : "TEXT";
5858
+ } : { type: "TEXT" };
5668
5859
  declare const BUILD: unique symbol;
5669
5860
  declare class TextFieldBuilder<TNoTokenize extends Record<"noTokenize", boolean> = {
5670
5861
  noTokenize: false;
@@ -5732,7 +5923,7 @@ declare class BoolFieldBuilder<Fast extends Record<"fast", boolean> = {
5732
5923
  } : TFrom["from"] extends string ? {
5733
5924
  type: "BOOL";
5734
5925
  from: TFrom["from"];
5735
- } : "BOOL";
5926
+ } : { type: "BOOL" };
5736
5927
  }
5737
5928
  declare class DateFieldBuilder<Fast extends Record<"fast", boolean> = {
5738
5929
  fast: false;
@@ -5760,7 +5951,13 @@ declare class DateFieldBuilder<Fast extends Record<"fast", boolean> = {
5760
5951
  } : TFrom["from"] extends string ? {
5761
5952
  type: "DATE";
5762
5953
  from: TFrom["from"];
5763
- } : "DATE";
5954
+ } : { type: "DATE" };
5955
+ }
5956
+ declare class KeywordFieldBuilder {
5957
+ [BUILD](): { type: "KEYWORD" };
5958
+ }
5959
+ declare class FacetFieldBuilder {
5960
+ [BUILD](): { type: "FACET" };
5764
5961
  }
5765
5962
  type FieldBuilder = TextFieldBuilder<{
5766
5963
  noTokenize: boolean;
@@ -5778,12 +5975,14 @@ type FieldBuilder = TextFieldBuilder<{
5778
5975
  fast: boolean;
5779
5976
  }, {
5780
5977
  from: string | null;
5781
- }>;
5978
+ }> | KeywordFieldBuilder | FacetFieldBuilder;
5782
5979
  declare const s: {
5783
5980
  string(): TextFieldBuilder;
5784
5981
  number<T extends NumericField["type"] = "F64">(type?: T): NumericFieldBuilder<T>;
5785
5982
  boolean(): BoolFieldBuilder;
5786
5983
  date(): DateFieldBuilder;
5984
+ keyword(): KeywordFieldBuilder;
5985
+ facet(): FacetFieldBuilder;
5787
5986
  object<T extends ObjectFieldRecord<T>>(fields: T): { [K in keyof T]: T[K] extends FieldBuilder ? ReturnType<T[K][typeof BUILD]> : T[K]; };
5788
5987
  };
5789
5988
  type ObjectFieldRecord<T> = {
@@ -5804,7 +6003,7 @@ type Schema = NestedIndexSchema | FlatIndexSchema;
5804
6003
 
5805
6004
  var SCHEMA_PREFIX = "const schema: Schema = s.object({";
5806
6005
  var SCHEMA_SUFFIX = "})";
5807
- var SCHEMA_DEFAULT = "const schema: Schema = s.object({\n \n})";
6006
+ var SCHEMA_DEFAULT = "const schema: Schema = s.object({\n name: s.string(),\n})";
5808
6007
  var isSchemaStringValid = (value) => {
5809
6008
  return value.startsWith(SCHEMA_PREFIX) && value.endsWith(SCHEMA_SUFFIX);
5810
6009
  };
@@ -5826,6 +6025,123 @@ var SchemaEditor = ({ value, onChange, height }) => {
5826
6025
  );
5827
6026
  };
5828
6027
 
6028
+ // src/components/databrowser/components/search/schema-stringify.ts
6029
+ function schemaToEditorValue(flatSchema) {
6030
+ const nested = unflattenSchema(flatSchema);
6031
+ const body = renderObject(nested, 1);
6032
+ return `const schema: Schema = s.object({
6033
+ ${body}})`;
6034
+ }
6035
+ function unflattenSchema(flat) {
6036
+ const result = {};
6037
+ for (const [key, value] of Object.entries(flat)) {
6038
+ const parts = key.split(".");
6039
+ let current = result;
6040
+ for (let i = 0; i < parts.length - 1; i++) {
6041
+ const part = parts[i];
6042
+ if (!current[part] || typeof current[part] !== "object") {
6043
+ current[part] = {};
6044
+ }
6045
+ current = current[part];
6046
+ }
6047
+ current[parts.at(-1)] = value;
6048
+ }
6049
+ return result;
6050
+ }
6051
+ function renderObject(obj, indent) {
6052
+ const pad = " ".repeat(indent);
6053
+ const lines = [];
6054
+ for (const [key, value] of Object.entries(obj)) {
6055
+ if (isFieldValue(value)) {
6056
+ lines.push(`${pad}${key}: ${fieldToBuilder(value)},`);
6057
+ } else {
6058
+ const nested = renderObject(value, indent + 1);
6059
+ lines.push(`${pad}${key}: s.object({`);
6060
+ lines.push(nested.trimEnd());
6061
+ lines.push(`${pad}}),`);
6062
+ }
6063
+ }
6064
+ return lines.join("\n") + "\n";
6065
+ }
6066
+ function isFieldValue(value) {
6067
+ if (typeof value === "string") return true;
6068
+ if (typeof value === "object" && value !== null) {
6069
+ return "type" in value;
6070
+ }
6071
+ return false;
6072
+ }
6073
+ function fieldToBuilder(value) {
6074
+ if (typeof value === "string") {
6075
+ switch (value) {
6076
+ case "TEXT": {
6077
+ return "s.string()";
6078
+ }
6079
+ case "BOOL": {
6080
+ return "s.boolean()";
6081
+ }
6082
+ case "DATE": {
6083
+ return "s.date()";
6084
+ }
6085
+ case "U64":
6086
+ case "I64":
6087
+ case "F64": {
6088
+ return `s.number("${value}")`;
6089
+ }
6090
+ case "KEYWORD": {
6091
+ return "s.keyword()";
6092
+ }
6093
+ case "FACET": {
6094
+ return "s.facet()";
6095
+ }
6096
+ default: {
6097
+ return "s.string()";
6098
+ }
6099
+ }
6100
+ }
6101
+ const v = value;
6102
+ const type = v.type;
6103
+ let builder = "";
6104
+ switch (type) {
6105
+ case "TEXT": {
6106
+ builder = "s.string()";
6107
+ if (v.noTokenize) builder += ".noTokenize()";
6108
+ if (v.noStem) builder += ".noStem()";
6109
+ break;
6110
+ }
6111
+ case "U64":
6112
+ case "I64":
6113
+ case "F64": {
6114
+ builder = `s.number("${type}")`;
6115
+ break;
6116
+ }
6117
+ case "BOOL": {
6118
+ builder = "s.boolean()";
6119
+ if (v.fast) builder += ".fast()";
6120
+ break;
6121
+ }
6122
+ case "DATE": {
6123
+ builder = "s.date()";
6124
+ if (v.fast) builder += ".fast()";
6125
+ break;
6126
+ }
6127
+ case "KEYWORD": {
6128
+ builder = "s.keyword()";
6129
+ break;
6130
+ }
6131
+ case "FACET": {
6132
+ builder = "s.facet()";
6133
+ break;
6134
+ }
6135
+ default: {
6136
+ builder = "s.string()";
6137
+ }
6138
+ }
6139
+ if (v.from) {
6140
+ builder += `.from("${v.from}")`;
6141
+ }
6142
+ return builder;
6143
+ }
6144
+
5829
6145
  // src/components/databrowser/components/search/display-search.tsx
5830
6146
 
5831
6147
  var SearchDisplay = ({
@@ -5853,6 +6169,7 @@ var SearchDisplay = ({
5853
6169
  const currentIndexName = watch("indexName");
5854
6170
  const effectiveIndexName = isCreateModal ? currentIndexName : _nullishCoalesce(indexName, () => ( ""));
5855
6171
  const [pendingFormValues, setPendingFormValues] = _react.useState.call(void 0, );
6172
+ const [parseError, setParseError] = _react.useState.call(void 0, );
5856
6173
  const { data, isLoading } = useFetchSearchIndex(indexName, {
5857
6174
  enabled: !isCreateModal
5858
6175
  });
@@ -5863,11 +6180,12 @@ var SearchDisplay = ({
5863
6180
  indexName: _nullishCoalesce(indexName, () => ( "")),
5864
6181
  editorValue: data.schema ? schemaToEditorValue(data.schema) : SCHEMA_DEFAULT,
5865
6182
  dataType: data.dataType || "string",
5866
- prefixes: _optionalChain([data, 'access', _52 => _52.prefixes, 'optionalAccess', _53 => _53.join, 'call', _54 => _54(", ")]) || "",
6183
+ prefixes: _optionalChain([data, 'access', _55 => _55.prefixes, 'optionalAccess', _56 => _56.join, 'call', _57 => _57(", ")]) || "",
5867
6184
  language: data.language || "english"
5868
6185
  });
5869
6186
  }, [data, reset, indexName]);
5870
6187
  const onSubmit = (values) => {
6188
+ setParseError(void 0);
5871
6189
  if (isCreateModal) {
5872
6190
  createSchema.mutate(
5873
6191
  {
@@ -5882,6 +6200,11 @@ var SearchDisplay = ({
5882
6200
  }
5883
6201
  );
5884
6202
  } else {
6203
+ const result = parseSchemaFromEditorValue(values.editorValue);
6204
+ if (!result.success) {
6205
+ setParseError(result.error);
6206
+ return;
6207
+ }
5885
6208
  setPendingFormValues({ ...values, indexName });
5886
6209
  }
5887
6210
  };
@@ -5889,11 +6212,14 @@ var SearchDisplay = ({
5889
6212
  createSchema.reset();
5890
6213
  reset();
5891
6214
  };
5892
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex h-full w-full min-w-0 flex-col gap-2", children: [
6215
+ if (!isCreateModal && !isLoading && (data === null || data === void 0)) {
6216
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, KeyDeleted, {});
6217
+ }
6218
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex h-full min-h-0 w-full min-w-0 flex-col gap-2", children: [
5893
6219
  !isCreateModal && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, DisplayHeader, { dataKey: effectiveIndexName, type: "search", hideTypeTag: isEditModal }),
5894
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex h-full min-w-0 grow flex-col gap-2 rounded-md", children: !isCreateModal && isLoading ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Spinner, { isLoadingText: "", isLoading: true }) : !isCreateModal && (data === null || data === void 0) ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex h-full items-center justify-center", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-zinc-500", children: "No data found" }) }) : /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex h-full w-full flex-col gap-3", children: [
6220
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex min-h-0 min-w-0 grow flex-col gap-2 rounded-md", children: !isCreateModal && isLoading ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Spinner, { isLoadingText: "", isLoading: true }) : /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex min-h-0 w-full flex-1 flex-col gap-3", children: [
5895
6221
  isCreateModal && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col gap-1.5", children: [
5896
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Label, { htmlFor: "index-name", children: "Key" }),
6222
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Label, { htmlFor: "index-name", children: "Index Key" }),
5897
6223
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
5898
6224
  Input,
5899
6225
  {
@@ -5904,9 +6230,9 @@ var SearchDisplay = ({
5904
6230
  ),
5905
6231
  errors.indexName && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-xs text-red-500", children: errors.indexName.message })
5906
6232
  ] }),
5907
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "rounded-md border border-zinc-300 bg-white p-3", children: [
6233
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "shrink-0 rounded-md border border-zinc-300 bg-white p-3", children: [
5908
6234
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex items-center justify-between", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { className: "text-sm font-medium text-zinc-700", children: "Config" }) }),
5909
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "mt-2 grid grid-cols-4 gap-4 text-sm", children: [
6235
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "mt-2 grid grid-cols-2 gap-4 text-sm lg:grid-cols-4", children: [
5910
6236
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { children: [
5911
6237
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "mb-1.5 block text-xs font-medium text-zinc-500", children: "Data Type" }),
5912
6238
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
@@ -5930,7 +6256,7 @@ var SearchDisplay = ({
5930
6256
  control,
5931
6257
  render: ({ field }) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, Select, { value: field.value, onValueChange: field.onChange, children: [
5932
6258
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, SelectTrigger, { className: "h-8", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, SelectValue, { placeholder: "Select language" }) }),
5933
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, SelectContent, { children: LANGUAGES.map((lang) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, SelectItem, { value: lang, children: lang }, lang)) })
6259
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, SelectContent, { children: LANGUAGES.map((lang) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, SelectItem, { value: lang, children: lang.charAt(0).toUpperCase() + lang.slice(1) }, lang)) })
5934
6260
  ] })
5935
6261
  }
5936
6262
  )
@@ -5949,7 +6275,7 @@ var SearchDisplay = ({
5949
6275
  ] })
5950
6276
  ] })
5951
6277
  ] }),
5952
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex min-h-0 flex-1 flex-col rounded-md border border-zinc-300 bg-white", children: [
6278
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "relative flex min-h-0 flex-1 flex-col rounded-md border border-zinc-300 bg-white", children: [
5953
6279
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex items-center justify-between border-b border-zinc-200 px-3 py-2", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { className: "text-sm font-medium text-zinc-700", children: "Schema" }) }),
5954
6280
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "min-h-0 flex-1", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "h-full px-1", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
5955
6281
  _reacthookform.Controller,
@@ -5965,9 +6291,17 @@ var SearchDisplay = ({
5965
6291
  }
5966
6292
  )
5967
6293
  }
5968
- ) }) })
6294
+ ) }) }),
6295
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
6296
+ DocsLink,
6297
+ {
6298
+ className: "absolute bottom-2 right-2 text-sm",
6299
+ href: "https://upstash-search.mintlify.app/redis/search/schema-definition"
6300
+ }
6301
+ )
5969
6302
  ] }),
5970
6303
  isCreateModal && createSchema.error && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "w-full break-words text-xs text-red-500", children: createSchema.error.message.startsWith("ERR syntax error") ? "Invalid schema" : formatUpstashErrorMessage(createSchema.error) }),
6304
+ parseError && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "w-full break-words text-xs text-red-500", children: parseError }),
5971
6305
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex shrink-0 items-center gap-2", children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "ml-auto flex gap-2", children: [
5972
6306
  (isDirty || isCreateModal || isEditModal) && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
5973
6307
  Button,
@@ -5990,7 +6324,6 @@ var SearchDisplay = ({
5990
6324
  values: pendingFormValues,
5991
6325
  onClose: () => {
5992
6326
  setPendingFormValues(void 0);
5993
- reset();
5994
6327
  if (isEditModal && onClose) onClose();
5995
6328
  }
5996
6329
  }
@@ -6027,63 +6360,6 @@ var LANGUAGES = [
6027
6360
 
6028
6361
 
6029
6362
 
6030
- // src/components/ui/scroll-area.tsx
6031
-
6032
- var _reactscrollarea = require('@radix-ui/react-scroll-area'); var ScrollAreaPrimitive = _interopRequireWildcard(_reactscrollarea);
6033
-
6034
- var ScrollArea = React13.forwardRef(
6035
- ({
6036
- className,
6037
- scrollBarClassName,
6038
- scrollBarForceMount,
6039
- children,
6040
- onScroll,
6041
- disableRoundedInherit = false,
6042
- ...props
6043
- }, ref) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
6044
- ScrollAreaPrimitive.Root,
6045
- {
6046
- ref,
6047
- className: cn("relative overflow-hidden", className),
6048
- ...props,
6049
- children: [
6050
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
6051
- ScrollAreaPrimitive.Viewport,
6052
- {
6053
- onScroll,
6054
- className: cn(
6055
- "h-full w-full [&>div]:!block",
6056
- !disableRoundedInherit && "rounded-[inherit]"
6057
- ),
6058
- children
6059
- }
6060
- ),
6061
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ScrollBar, { className: scrollBarClassName, forceMount: scrollBarForceMount }),
6062
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ScrollAreaPrimitive.Corner, {})
6063
- ]
6064
- }
6065
- )
6066
- );
6067
- ScrollArea.displayName = ScrollAreaPrimitive.Root.displayName;
6068
- var ScrollBar = React13.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
6069
- ScrollAreaPrimitive.ScrollAreaScrollbar,
6070
- {
6071
- ref,
6072
- orientation: "vertical",
6073
- className: cn("mr-1 flex h-full w-2 touch-none select-none transition-colors", className),
6074
- ...props,
6075
- children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
6076
- ScrollAreaPrimitive.ScrollAreaThumb,
6077
- {
6078
- className: cn("relative flex-1 rounded-full bg-zinc-400/70")
6079
- }
6080
- )
6081
- }
6082
- ));
6083
- ScrollBar.displayName = ScrollAreaPrimitive.ScrollAreaScrollbar.displayName;
6084
-
6085
- // src/components/common/infinite-scroll.tsx
6086
-
6087
6363
  var InfiniteScroll = ({
6088
6364
  query,
6089
6365
  children,
@@ -6121,7 +6397,7 @@ var InfiniteScroll = ({
6121
6397
  type: "always",
6122
6398
  onScroll: handleScroll,
6123
6399
  ...props,
6124
- className: cn("block h-full w-full overflow-visible transition-all", props.className),
6400
+ className: cn("block h-full min-h-0 w-full overflow-hidden transition-all", props.className),
6125
6401
  ref: scrollRef,
6126
6402
  children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { ref: contentRef, children: [
6127
6403
  children,
@@ -6277,7 +6553,7 @@ var ItemContextMenu = ({
6277
6553
  editItem({
6278
6554
  type,
6279
6555
  dataKey,
6280
- itemKey: _optionalChain([data, 'optionalAccess', _55 => _55.key]),
6556
+ itemKey: _optionalChain([data, 'optionalAccess', _58 => _58.key]),
6281
6557
  // For deletion
6282
6558
  newKey: void 0
6283
6559
  });
@@ -6312,7 +6588,7 @@ var ItemContextMenu = ({
6312
6588
  {
6313
6589
  onClick: () => {
6314
6590
  if (!data) return;
6315
- navigator.clipboard.writeText(_optionalChain([data, 'optionalAccess', _56 => _56.key]));
6591
+ navigator.clipboard.writeText(_optionalChain([data, 'optionalAccess', _59 => _59.key]));
6316
6592
  toast({
6317
6593
  description: "Key copied to clipboard"
6318
6594
  });
@@ -6324,11 +6600,11 @@ var ItemContextMenu = ({
6324
6600
  ]
6325
6601
  }
6326
6602
  ),
6327
- _optionalChain([data, 'optionalAccess', _57 => _57.value]) && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
6603
+ _optionalChain([data, 'optionalAccess', _60 => _60.value]) && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
6328
6604
  ContextMenuItem,
6329
6605
  {
6330
6606
  onClick: () => {
6331
- navigator.clipboard.writeText(_nullishCoalesce(_optionalChain([data, 'optionalAccess', _58 => _58.value]), () => ( "")));
6607
+ navigator.clipboard.writeText(_nullishCoalesce(_optionalChain([data, 'optionalAccess', _61 => _61.value]), () => ( "")));
6332
6608
  toast({
6333
6609
  description: "Value copied to clipboard"
6334
6610
  });
@@ -6440,7 +6716,7 @@ var useSetHashTTL = () => {
6440
6716
  var HashFieldTTLBadge = ({ dataKey, field }) => {
6441
6717
  const { data } = useFetchHashFieldExpires({ dataKey, fields: [field] });
6442
6718
  const { mutate: setTTL, isPending } = useSetHashTTL();
6443
- const expireAt = _optionalChain([data, 'optionalAccess', _59 => _59[field]]);
6719
+ const expireAt = _optionalChain([data, 'optionalAccess', _62 => _62[field]]);
6444
6720
  return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
6445
6721
  TTLBadge,
6446
6722
  {
@@ -6537,7 +6813,7 @@ var MonacoEditor = ({
6537
6813
  if (!active || !monaco || !editorRef.current) {
6538
6814
  return;
6539
6815
  }
6540
- _optionalChain([monaco, 'optionalAccess', _60 => _60.editor, 'access', _61 => _61.setModelLanguage, 'call', _62 => _62(editorRef.current.getModel(), language)]);
6816
+ _optionalChain([monaco, 'optionalAccess', _63 => _63.editor, 'access', _64 => _64.setModelLanguage, 'call', _65 => _65(editorRef.current.getModel(), language)]);
6541
6817
  }, [monaco, language, active]);
6542
6818
  const editor = /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
6543
6819
  _react2.Editor,
@@ -6662,6 +6938,13 @@ var useField = ({
6662
6938
  }
6663
6939
  }
6664
6940
  };
6941
+ _react.useLayoutEffect.call(void 0, () => {
6942
+ if (!fieldState.isDirty && contentType === "JSON" && checkIsValidJSON(data)) {
6943
+ form.setValue(name, formatJSON(data), {
6944
+ shouldDirty: false
6945
+ });
6946
+ }
6947
+ }, [data, fieldState.isDirty]);
6665
6948
  return {
6666
6949
  selector: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ContentTypeSelect, { value: contentType, onChange: handleTypeChange, data: field.value }),
6667
6950
  editor: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _jsxruntime.Fragment, { children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
@@ -6694,7 +6977,7 @@ var ListEditDisplay = ({
6694
6977
  type,
6695
6978
  item
6696
6979
  }) => {
6697
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "grow rounded-md bg-zinc-100", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ListEditForm, { item, type, dataKey }, item.key) });
6980
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "min-h-0 grow rounded-md", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ListEditForm, { item, type, dataKey }, item.key) });
6698
6981
  };
6699
6982
  var ListEditForm = ({
6700
6983
  type,
@@ -6706,7 +6989,7 @@ var ListEditForm = ({
6706
6989
  dataKey
6707
6990
  });
6708
6991
  const findValue = () => {
6709
- for (const page of _nullishCoalesce(_optionalChain([query, 'access', _63 => _63.data, 'optionalAccess', _64 => _64.pages]), () => ( []))) {
6992
+ for (const page of _nullishCoalesce(_optionalChain([query, 'access', _66 => _66.data, 'optionalAccess', _67 => _67.pages]), () => ( []))) {
6710
6993
  const item = page.keys.find((item2) => item2.key === itemKey);
6711
6994
  if (item && "value" in item) return item.value;
6712
6995
  }
@@ -6733,8 +7016,8 @@ var ListEditForm = ({
6733
7016
  });
6734
7017
  setSelectedListItem(void 0);
6735
7018
  });
6736
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _reacthookform.FormProvider, { ...form, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "form", { onSubmit, className: "flex h-full flex-col gap-2", children: [
6737
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex grow flex-col gap-2", children: [
7019
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _reacthookform.FormProvider, { ...form, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "form", { onSubmit, className: "flex h-full min-h-0 flex-col gap-2", children: [
7020
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex min-h-0 grow flex-col gap-2", children: [
6738
7021
  type === "zset" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, NumberFormItem, { name: "value", label: valueLabel }),
6739
7022
  type !== "list" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, FormItem, { readOnly: type === "stream", name: "key", label: keyLabel, data: itemKey }),
6740
7023
  type !== "set" && type !== "zset" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
@@ -6798,7 +7081,7 @@ var NumberFormItem = ({ name, label }) => {
6798
7081
  render: ({ field }) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
6799
7082
  "input",
6800
7083
  {
6801
- className: "plain-input rounded-md border border-zinc-300 px-3 py-1 shadow-sm",
7084
+ className: "plain-input rounded-md border border-zinc-300 bg-white px-3 py-1 shadow-sm [appearance:textfield] [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none",
6802
7085
  type: "number",
6803
7086
  ...field
6804
7087
  }
@@ -6823,7 +7106,7 @@ var FormItem = ({
6823
7106
  readOnly,
6824
7107
  data
6825
7108
  });
6826
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: cn("flex flex-col gap-1", !height && "h-full"), children: [
7109
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: cn("flex flex-col gap-1", !height && "h-full min-h-0"), children: [
6827
7110
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center gap-1 text-xs", children: [
6828
7111
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "font-medium text-zinc-700", children: label }),
6829
7112
  " ",
@@ -6835,7 +7118,7 @@ var FormItem = ({
6835
7118
  {
6836
7119
  className: cn(
6837
7120
  "overflow-hidden rounded-md border border-zinc-300 bg-white p-2 shadow-sm",
6838
- !height && "h-full"
7121
+ !height && "h-full min-h-0"
6839
7122
  ),
6840
7123
  children: editor
6841
7124
  }
@@ -6852,7 +7135,7 @@ var HashFieldTTLInfo = ({
6852
7135
  fields
6853
7136
  }) => {
6854
7137
  const { data } = useFetchHashFieldExpires({ dataKey, fields });
6855
- const expireAt = _optionalChain([data, 'optionalAccess', _65 => _65[field]]);
7138
+ const expireAt = _optionalChain([data, 'optionalAccess', _68 => _68[field]]);
6856
7139
  const [ttl, setTTL] = _react.useState.call(void 0, () => calculateTTL(expireAt));
6857
7140
  _react.useEffect.call(void 0, () => {
6858
7141
  setTTL(calculateTTL(expireAt));
@@ -6877,7 +7160,11 @@ var headerLabels = {
6877
7160
  var ListDisplay = ({ dataKey, type }) => {
6878
7161
  const { selectedListItem } = useTab();
6879
7162
  const query = useFetchListItems({ dataKey, type });
6880
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex h-full flex-col gap-2", children: [
7163
+ const isEmpty = query.isFetched && _optionalChain([query, 'access', _69 => _69.data, 'optionalAccess', _70 => _70.pages, 'access', _71 => _71.every, 'call', _72 => _72((page) => page.keys.length === 0)]);
7164
+ if (isEmpty) {
7165
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, KeyDeleted, {});
7166
+ }
7167
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex h-full min-h-0 flex-col gap-2 overflow-hidden", children: [
6881
7168
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, DisplayHeader, { dataKey, type }),
6882
7169
  selectedListItem && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ListEditDisplay, { dataKey, type, item: selectedListItem }),
6883
7170
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: cn("min-h-0 grow", selectedListItem && "hidden"), children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, InfiniteScroll, { query, className: "rounded-lg border border-zinc-200 bg-white", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "table", { className: "w-full", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ItemContextMenu, { dataKey, type, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "tbody", { children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ListItems, { dataKey, type, query }) }) }) }) }) })
@@ -6889,7 +7176,7 @@ var ListItems = ({
6889
7176
  dataKey
6890
7177
  }) => {
6891
7178
  const { setSelectedListItem } = useTab();
6892
- const keys = _react.useMemo.call(void 0, () => _nullishCoalesce(_optionalChain([query, 'access', _66 => _66.data, 'optionalAccess', _67 => _67.pages, 'access', _68 => _68.flatMap, 'call', _69 => _69((page) => page.keys)]), () => ( [])), [query.data]);
7179
+ const keys = _react.useMemo.call(void 0, () => _nullishCoalesce(_optionalChain([query, 'access', _73 => _73.data, 'optionalAccess', _74 => _74.pages, 'access', _75 => _75.flatMap, 'call', _76 => _76((page) => page.keys)]), () => ( [])), [query.data]);
6893
7180
  const fields = _react.useMemo.call(void 0, () => keys.map((key) => key.key), [keys]);
6894
7181
  const { mutate: editItem } = useEditListItem();
6895
7182
  return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _jsxruntime.Fragment, { children: keys.map(({ key, value }, i) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
@@ -6928,7 +7215,7 @@ var ListItems = ({
6928
7215
  onClick: (e) => {
6929
7216
  e.stopPropagation();
6930
7217
  },
6931
- children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center justify-end gap-2", children: [
7218
+ children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center justify-end gap-2 pr-2", children: [
6932
7219
  type === "hash" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, HashFieldTTLInfo, { dataKey, field: key, fields }),
6933
7220
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
6934
7221
  DeleteKeyModal,
@@ -6971,9 +7258,12 @@ var ListItems = ({
6971
7258
 
6972
7259
  var EditorDisplay = ({ dataKey, type }) => {
6973
7260
  const { data } = useFetchSimpleKey(dataKey, type);
6974
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex h-full w-full flex-col gap-2", children: [
7261
+ if (data === null) {
7262
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, KeyDeleted, {});
7263
+ }
7264
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex h-full min-h-0 w-full flex-col gap-2 overflow-hidden", children: [
6975
7265
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, DisplayHeader, { dataKey, type, content: _nullishCoalesce(data, () => ( void 0)) }),
6976
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex h-full grow flex-col gap-2 rounded-md", children: data === void 0 ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Spinner, { isLoadingText: "", isLoading: true }) : data === null ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _jsxruntime.Fragment, {}) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, EditorDisplayForm, { dataKey, type, data }, dataKey) })
7266
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex min-h-0 grow flex-col gap-2 rounded-md", children: data === void 0 ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Spinner, { isLoadingText: "", isLoading: true }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, EditorDisplayForm, { dataKey, type, data }, dataKey) })
6977
7267
  ] });
6978
7268
  };
6979
7269
  var EditorDisplayForm = ({
@@ -6990,12 +7280,12 @@ var EditorDisplayForm = ({
6990
7280
  const { editor, selector } = useField({ name: "value", form, data });
6991
7281
  const { mutateAsync: setKey, isPending: isSettingKey } = useSetSimpleKey(dataKey, type);
6992
7282
  const handleCancel = () => {
6993
- form.reset({ value: data });
7283
+ form.reset();
6994
7284
  };
6995
7285
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
6996
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex grow flex-col gap-1", children: [
7286
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex min-h-0 grow flex-col gap-1", children: [
6997
7287
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex shrink-0 items-center gap-2", children: type === "json" ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", {}) : selector }),
6998
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "grow rounded-md border border-zinc-300 bg-white p-2", children: editor })
7288
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "min-h-0 grow rounded-md border border-zinc-300 bg-white p-2", children: editor })
6999
7289
  ] }),
7000
7290
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex shrink-0 items-center gap-2", children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "ml-auto flex gap-2", children: [
7001
7291
  form.formState.isDirty && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Button, { onClick: handleCancel, children: "Cancel" }),
@@ -7036,33 +7326,6 @@ var DataDisplay = () => {
7036
7326
 
7037
7327
 
7038
7328
 
7039
- // src/components/common/reload-button.tsx
7040
-
7041
-
7042
-
7043
- var ReloadButton = ({
7044
- onClick,
7045
- isLoading: isLoadingProp
7046
- }) => {
7047
- const [isLoading, setIsLoading] = _react.useState.call(void 0, false);
7048
- const handleClick = () => {
7049
- setIsLoading(true);
7050
- onClick();
7051
- setTimeout(() => {
7052
- setIsLoading(false);
7053
- }, 350);
7054
- };
7055
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, SimpleTooltip, { content: "Refresh", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
7056
- Button,
7057
- {
7058
- variant: "outline",
7059
- size: "icon",
7060
- onClick: handleClick,
7061
- disabled: isLoading || isLoadingProp,
7062
- children: isLoading ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _iconsreact.IconLoader2, { className: "size-5 animate-spin text-zinc-500" }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _iconsreact.IconRefresh, { className: "size-5 text-zinc-500 dark:text-zinc-600" })
7063
- }
7064
- ) }) });
7065
- };
7066
7329
 
7067
7330
  // src/components/databrowser/components/add-key-modal.tsx
7068
7331
 
@@ -7085,7 +7348,7 @@ function AddKeyModal() {
7085
7348
  setSelectedKey(key);
7086
7349
  setOpen(false);
7087
7350
  setTimeout(() => {
7088
- _optionalChain([window, 'access', _70 => _70.document, 'access', _71 => _71.querySelector, 'call', _72 => _72(`[data-key="${key}"]`), 'optionalAccess', _73 => _73.scrollIntoView, 'call', _74 => _74({
7351
+ _optionalChain([window, 'access', _77 => _77.document, 'access', _78 => _78.querySelector, 'call', _79 => _79(`[data-key="${key}"]`), 'optionalAccess', _80 => _80.scrollIntoView, 'call', _81 => _81({
7089
7352
  behavior: "smooth",
7090
7353
  block: "start",
7091
7354
  inline: "nearest"
@@ -7106,7 +7369,7 @@ function AddKeyModal() {
7106
7369
  {
7107
7370
  variant: "primary",
7108
7371
  "data-testid": "add-key-button",
7109
- className: "flex h-8 items-center gap-1 rounded-lg pl-2 pr-3 text-sm font-medium",
7372
+ className: "flex h-8 select-none items-center gap-1 rounded-lg pl-2 pr-3 text-sm font-medium",
7110
7373
  children: [
7111
7374
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _iconsreact.IconPlus, { className: "size-5" }),
7112
7375
  "Key"
@@ -7141,7 +7404,7 @@ function AddKeyModal() {
7141
7404
  }
7142
7405
  )
7143
7406
  ] }),
7144
- formState.errors.key && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "mb-3 mt-2 text-xs text-red-500", children: _optionalChain([formState, 'access', _75 => _75.errors, 'access', _76 => _76.key, 'optionalAccess', _77 => _77.message]) }),
7407
+ formState.errors.key && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "mb-3 mt-2 text-xs text-red-500", children: _optionalChain([formState, 'access', _82 => _82.errors, 'access', _83 => _83.key, 'optionalAccess', _84 => _84.message]) }),
7145
7408
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "mt-2 text-xs text-zinc-500", children: "After creating the key, you can edit the value" }),
7146
7409
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "mt-6 flex justify-end gap-2", children: [
7147
7410
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
@@ -7164,427 +7427,84 @@ function AddKeyModal() {
7164
7427
  );
7165
7428
  }
7166
7429
 
7167
- // src/components/databrowser/components/search/create-index-modal.tsx
7168
-
7169
- var CreateIndexModal = ({
7170
- open,
7171
- onOpenChange
7172
- }) => {
7173
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Dialog, { open, onOpenChange, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, DialogContent, { className: "max-w-2xl", children: [
7174
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, DialogHeader, { children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, DialogTitle, { children: "Create new Index" }) }),
7175
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "sr-only", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, DialogDescription, { children: "Create new search index" }) }),
7176
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, SearchDisplay, { isCreateModal: true, onClose: () => onOpenChange(false) })
7177
- ] }) });
7178
- };
7430
+ // src/components/databrowser/components/query-wizard/query-wizard-popover.tsx
7179
7431
 
7180
- // src/components/databrowser/components/search/edit-index-modal.tsx
7181
7432
 
7182
- var EditIndexModal = ({
7183
- open,
7184
- onOpenChange,
7185
- indexName
7186
- }) => {
7187
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Dialog, { open, onOpenChange, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, DialogContent, { className: "max-w-2xl", children: [
7188
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, DialogHeader, { children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, DialogTitle, { children: "Edit Index" }) }),
7189
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "sr-only", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, DialogDescription, { children: "Edit search index schema" }) }),
7190
- indexName && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, SearchDisplay, { indexName, isEditModal: true, onClose: () => onOpenChange(false) })
7191
- ] }) });
7192
- };
7193
7433
 
7194
- // src/components/databrowser/components/header/search-input.tsx
7195
7434
 
7435
+ // src/components/databrowser/components/query-wizard/consent-prompt.tsx
7196
7436
 
7197
7437
 
7198
- var dedupeSearchHistory = (history) => {
7199
- const seen = /* @__PURE__ */ new Set();
7200
- return history.filter((item) => {
7201
- if (!item || seen.has(item)) return false;
7202
- seen.add(item);
7203
- return true;
7204
- });
7205
- };
7206
- var SearchInput = () => {
7207
- const { setSearchKey, search } = useTab();
7208
- const { searchHistory, addSearchHistory } = useDatabrowserStore();
7209
- const [state, setState] = _react.useState.call(void 0, search.key);
7210
- const [isFocus, setIsFocus] = _react.useState.call(void 0, false);
7211
- const [focusedIndex, setFocusedIndex] = _react.useState.call(void 0, -1);
7212
- const inputRef = _react.useRef.call(void 0, null);
7213
- const historyItemRefs = _react.useRef.call(void 0, []);
7214
- const handleSubmit = (value) => {
7215
- if (value.trim() !== "" && !value.includes("*")) value = `${value}*`;
7216
- addSearchHistory(value);
7217
- setSearchKey(value);
7218
- setState(value);
7219
- };
7220
- const filteredHistory = dedupeSearchHistory(
7221
- searchHistory.filter((item) => item.trim() !== "" && item.trim() !== "*").filter((item) => item.includes(state) && item !== state)
7222
- ).slice(0, 5).map((item) => item.endsWith("*") ? item.slice(0, -1) : item);
7223
- _react.useEffect.call(void 0, () => {
7224
- setFocusedIndex(-1);
7225
- }, [filteredHistory.length]);
7226
- const handleKeyDown = (e) => {
7227
- if (e.key === "Enter") {
7228
- const text = focusedIndex >= 0 && focusedIndex < filteredHistory.length ? filteredHistory[focusedIndex] : e.currentTarget.value;
7229
- handleSubmit(text);
7230
- } else if (e.key === "Escape") {
7231
- setState("");
7232
- setFocusedIndex(-1);
7233
- _optionalChain([inputRef, 'access', _78 => _78.current, 'optionalAccess', _79 => _79.blur, 'call', _80 => _80()]);
7234
- } else if (e.key === "ArrowDown" || e.key === "Tab" && !e.shiftKey) {
7235
- e.preventDefault();
7236
- if (focusedIndex < filteredHistory.length - 1) {
7237
- setFocusedIndex(focusedIndex + 1);
7238
- } else if (filteredHistory.length > 0) {
7239
- setFocusedIndex(0);
7240
- }
7241
- } else if (e.key === "ArrowUp" || e.key === "Tab" && e.shiftKey) {
7242
- e.preventDefault();
7243
- if (focusedIndex > 0) {
7244
- setFocusedIndex(focusedIndex - 1);
7245
- } else if (filteredHistory.length > 0 && focusedIndex === 0) {
7246
- setFocusedIndex(-1);
7247
- _optionalChain([inputRef, 'access', _81 => _81.current, 'optionalAccess', _82 => _82.focus, 'call', _83 => _83()]);
7248
- } else if (filteredHistory.length > 0) {
7249
- setFocusedIndex(filteredHistory.length - 1);
7250
- }
7251
- }
7438
+ var ConsentPrompt = ({ onClose }) => {
7439
+ const store = useDatabrowserStore();
7440
+ const handleContinue = () => {
7441
+ store.setAiDataSharingConsent(true);
7252
7442
  };
7253
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "relative grow", children: [
7254
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, Popover, { open: isFocus && filteredHistory.length > 0, children: [
7255
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, PopoverTrigger, { asChild: true, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "h-8 rounded-md border border-zinc-300 font-normal", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
7256
- Input,
7443
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex max-w-[500px] flex-col gap-6 rounded-2xl p-6 shadow-lg", children: [
7444
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center gap-2", children: [
7445
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { className: "text-base font-semibold text-zinc-950", children: "AI Query Builder" }),
7446
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex items-center justify-center rounded-md bg-purple-100 px-1.5 py-0.5", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-sm font-medium text-purple-700", children: "BETA" }) })
7447
+ ] }),
7448
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex gap-3 rounded-xl border border-yellow-300 bg-yellow-50 p-5", children: [
7449
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _iconsreact.IconAlertCircleFilled, { className: "size-5 shrink-0 text-yellow-800" }),
7450
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col gap-1.5", children: [
7451
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-sm font-semibold text-yellow-800", children: "AI Query Builder requires data sharing" }),
7452
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "p", { className: "text-sm text-yellow-800", children: [
7453
+ "To generate accurate queries, we'll send your",
7454
+ " ",
7455
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "font-semibold", children: "index schema" }),
7456
+ " and a",
7457
+ " ",
7458
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "font-semibold", children: "small sample of your data" }),
7459
+ " to AI models. This may include field names and example values."
7460
+ ] }),
7461
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-sm text-yellow-800", children: "Only used to generate the query you request." })
7462
+ ] })
7463
+ ] }),
7464
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center justify-end gap-2", children: [
7465
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
7466
+ "button",
7257
7467
  {
7258
- ref: inputRef,
7259
- placeholder: "Search",
7260
- className: "h-full border-none pr-6",
7261
- onKeyDown: handleKeyDown,
7262
- onChange: (e) => {
7263
- setState(e.currentTarget.value);
7264
- if (e.currentTarget.value.trim() === "") handleSubmit("");
7265
- },
7266
- value: state,
7267
- onFocus: () => {
7268
- setIsFocus(true);
7269
- setFocusedIndex(-1);
7270
- },
7271
- onBlur: () => setIsFocus(false)
7468
+ onClick: onClose,
7469
+ className: "flex h-8 items-center justify-center rounded-md border border-zinc-300 bg-white px-4 text-sm text-zinc-950 hover:bg-zinc-50",
7470
+ children: "Cancel"
7272
7471
  }
7273
- ) }) }),
7472
+ ),
7274
7473
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
7275
- PopoverContent,
7474
+ "button",
7276
7475
  {
7277
- className: "w-[--radix-popover-trigger-width] divide-y px-3 py-2 text-[13px] text-zinc-900",
7278
- autoFocus: false,
7279
- onOpenAutoFocus: (e) => {
7280
- e.preventDefault();
7281
- e.stopPropagation();
7282
- },
7283
- children: filteredHistory.map((item, index) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "w-full py-[3px]", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
7284
- "button",
7285
- {
7286
- ref: (el) => {
7287
- historyItemRefs.current[index] = el;
7288
- },
7289
- onClick: () => handleSubmit(item),
7290
- onMouseEnter: () => setFocusedIndex(index),
7291
- className: `block w-full truncate rounded-sm p-1 text-left transition-colors ${focusedIndex === index ? "bg-zinc-100" : "hover:bg-zinc-100"}`,
7292
- children: item
7293
- }
7294
- ) }, item))
7476
+ onClick: handleContinue,
7477
+ className: "flex h-8 items-center justify-center rounded-md bg-purple-500 px-4 text-sm text-white hover:bg-purple-600",
7478
+ children: "I agree & Continue"
7295
7479
  }
7296
7480
  )
7297
- ] }),
7298
- state && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
7299
- Button,
7300
- {
7301
- type: "button",
7302
- variant: "link",
7303
- size: "icon",
7304
- className: "absolute right-1 top-1/2 h-5 w-5 -translate-y-1/2 text-zinc-500 hover:text-zinc-900",
7305
- onClick: () => {
7306
- setSearchKey("");
7307
- setState("");
7308
- },
7309
- children: [
7310
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _iconsreact.IconX, { size: 16 }),
7311
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "sr-only", children: "Clear" })
7312
- ]
7313
- }
7314
- ),
7315
- " "
7481
+ ] })
7316
7482
  ] });
7317
7483
  };
7318
7484
 
7319
- // src/components/databrowser/components/header/type-selector.tsx
7485
+ // src/components/databrowser/components/query-wizard/use-query-wizard.tsx
7320
7486
 
7321
- var ALL_TYPES_KEY = "all";
7322
- function DataTypeSelector({ allowSearch }) {
7323
- const { search, setSearchType } = useTab();
7324
- const entries = [
7325
- [ALL_TYPES_KEY, "All Types"],
7326
- ...Object.entries(DATA_TYPE_NAMES).filter(([key]) => allowSearch || key !== "search")
7327
- ];
7328
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
7329
- Select,
7330
- {
7331
- onValueChange: (type) => {
7332
- if (type === ALL_TYPES_KEY) {
7333
- setSearchType(void 0);
7334
- } else {
7335
- setSearchType(type);
7336
- }
7337
- },
7338
- value: search.type === void 0 ? ALL_TYPES_KEY : search.type,
7339
- children: [
7340
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, SelectTrigger, { className: "!w-auto shrink-0 select-none whitespace-nowrap border-zinc-300 pr-8", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, SelectValue, {}) }),
7341
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, SelectContent, { children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, SelectGroup, { children: entries.map(([key, value]) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, SelectItem, { value: key, children: value }, key)) }) })
7342
- ]
7343
- }
7344
- );
7345
- }
7346
7487
 
7347
- // src/components/databrowser/components/header/index.tsx
7348
7488
 
7349
- var Header = ({ tabType, allowSearch }) => {
7350
- const { isValuesSearchSelected, setIsValuesSearchSelected } = useTab();
7351
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center justify-between gap-1.5", children: [
7352
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex grow items-center gap-1.5", children: [
7353
- tabType === "all" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
7354
- Segmented,
7355
- {
7356
- options: [
7357
- {
7358
- key: "keys",
7359
- label: "Keys"
7360
- },
7361
- {
7362
- key: "values",
7363
- label: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center gap-1", children: [
7364
- "Search",
7365
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex h-[18px] items-center rounded-md bg-emerald-100 px-[5px] text-[11px] text-emerald-700", children: "NEW" })
7366
- ] })
7367
- }
7368
- ],
7369
- value: isValuesSearchSelected ? "values" : "keys",
7370
- onChange: (value) => {
7371
- setIsValuesSearchSelected(value === "values");
7372
- },
7373
- className: "bg-emerald-800",
7374
- unselectedClassName: "text-emerald-100",
7375
- selectedClassName: "bg-emerald-50 text-emerald-800"
7376
- }
7377
- ),
7378
- isValuesSearchSelected ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, IndexSelector, {}) : /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
7379
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, DataTypeSelector, { allowSearch }),
7380
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, SearchInput, {})
7381
- ] })
7382
- ] }),
7383
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center gap-1.5", children: [
7384
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, RefreshButton, {}),
7385
- isValuesSearchSelected ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, AddIndexButton, {}) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, AddKeyModal, {})
7386
- ] })
7387
- ] });
7388
- };
7389
- var IndexSelector = () => {
7390
- const {
7391
- valuesSearch: { index },
7392
- setValuesSearchIndex
7393
- } = useTab();
7394
- const { data: indexes, isLoading } = useFetchSearchIndexes();
7395
- const [open, setOpen] = _react.useState.call(void 0, false);
7396
- _react.useEffect.call(void 0, () => {
7397
- if (!indexes || isLoading) return;
7398
- if (index && !indexes.includes(index)) {
7399
- setValuesSearchIndex("");
7400
- }
7401
- }, [indexes, index, isLoading, setValuesSearchIndex]);
7402
- const [search, setSearch] = _react.useState.call(void 0, "");
7403
- const [editingIndex, setEditingIndex] = _react.useState.call(void 0, null);
7404
- const filteredIndexes = _optionalChain([indexes, 'optionalAccess', _84 => _84.filter, 'call', _85 => _85((idx) => idx.toLowerCase().includes(search.toLowerCase()))]);
7405
- const handleEditIndex = (indexName) => {
7406
- setOpen(false);
7407
- setEditingIndex(indexName);
7408
- };
7409
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex", children: [
7410
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex items-center rounded-l-lg border border-r-0 border-zinc-300 bg-white px-3 text-sm text-zinc-700", children: "Index" }),
7411
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
7412
- Popover,
7413
- {
7414
- open,
7415
- onOpenChange: (isOpen) => {
7416
- setOpen(isOpen);
7417
- if (!isOpen) setSearch("");
7418
- },
7419
- modal: false,
7420
- children: [
7421
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, PopoverTrigger, { asChild: true, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "button", { className: "flex min-w-[140px] items-center justify-between gap-2 rounded-r-lg border border-zinc-300 bg-emerald-50 px-3 py-[5px] text-sm font-medium text-emerald-800 transition-colors hover:bg-emerald-100", children: [
7422
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "truncate", children: index || "Select an index" }),
7423
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _iconsreact.IconChevronDown, { className: "size-4 shrink-0 opacity-50" })
7424
- ] }) }),
7425
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, PopoverContent, { className: "p-2", align: "center", children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col gap-2", children: [
7426
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, CreateIndexButton, {}),
7427
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "h-px bg-zinc-100" }),
7428
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex h-9 items-center rounded-md border border-zinc-300 px-2", children: [
7429
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _iconsreact.IconSearch, { className: "size-5 text-zinc-400" }),
7430
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
7431
- "input",
7432
- {
7433
- value: search,
7434
- onChange: (e) => setSearch(e.target.value),
7435
- placeholder: "Search Index",
7436
- className: "flex h-full w-full bg-transparent px-2 py-3 text-sm outline-none placeholder:text-zinc-400"
7437
- }
7438
- )
7439
- ] }),
7440
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "max-h-[200px] overflow-y-auto", children: [
7441
- _optionalChain([filteredIndexes, 'optionalAccess', _86 => _86.length]) === 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "py-4 text-center text-sm text-zinc-500", children: "No indexes found" }),
7442
- _optionalChain([filteredIndexes, 'optionalAccess', _87 => _87.map, 'call', _88 => _88((idx) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
7443
- "div",
7444
- {
7445
- className: "flex h-9 items-center rounded-md px-2 transition-colors hover:bg-zinc-100",
7446
- children: [
7447
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
7448
- "button",
7449
- {
7450
- onClick: () => {
7451
- setValuesSearchIndex(idx);
7452
- setOpen(false);
7453
- },
7454
- className: "flex flex-1 items-center gap-2 text-left text-sm",
7455
- children: [
7456
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
7457
- "span",
7458
- {
7459
- className: cn(
7460
- "flex size-5 items-center justify-center",
7461
- idx === index ? "text-emerald-600" : "text-transparent"
7462
- ),
7463
- children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _iconsreact.IconCircleCheck, { className: "size-5" })
7464
- }
7465
- ),
7466
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "truncate", children: idx })
7467
- ]
7468
- }
7469
- ),
7470
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
7471
- "button",
7472
- {
7473
- onClick: (event) => {
7474
- event.stopPropagation();
7475
- event.preventDefault();
7476
- handleEditIndex(idx);
7477
- },
7478
- className: "ml-2 text-sm text-zinc-500 underline hover:text-zinc-700",
7479
- children: "Edit"
7480
- }
7481
- )
7482
- ]
7483
- },
7484
- idx
7485
- ))])
7486
- ] })
7487
- ] }) })
7488
- ]
7489
- }
7490
- ),
7491
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
7492
- EditIndexModal,
7493
- {
7494
- open: Boolean(editingIndex),
7495
- onOpenChange: (isOpen) => !isOpen && setEditingIndex(null),
7496
- indexName: editingIndex
7497
- }
7498
- )
7499
- ] });
7500
- };
7501
- var CreateIndexButton = () => {
7502
- const [open, setOpen] = _react.useState.call(void 0, false);
7503
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
7504
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
7505
- "button",
7506
- {
7507
- onClick: (e) => {
7508
- e.stopPropagation();
7509
- setOpen(true);
7510
- },
7511
- className: "flex h-9 w-full items-center gap-2 rounded-md px-2 text-sm text-emerald-600 transition-colors hover:bg-zinc-50",
7512
- children: [
7513
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _iconsreact.IconCirclePlus, { className: "size-5" }),
7514
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "underline", children: "Create a new Index" })
7515
- ]
7516
- }
7517
- ),
7518
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, CreateIndexModal, { open, onOpenChange: setOpen })
7519
- ] });
7520
- };
7521
- var AddIndexButton = () => {
7522
- const [open, setOpen] = _react.useState.call(void 0, false);
7523
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
7524
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, SimpleTooltip, { content: "Add index", children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
7525
- Button,
7526
- {
7527
- variant: "primary",
7528
- onClick: () => setOpen(true),
7529
- className: "flex h-8 items-center gap-1 rounded-lg pl-2 pr-3 text-sm font-medium",
7530
- children: [
7531
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _iconsreact.IconPlus, { className: "size-5" }),
7532
- "Index"
7533
- ]
7534
- }
7535
- ) }),
7536
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, CreateIndexModal, { open, onOpenChange: setOpen })
7537
- ] });
7538
- };
7539
- var RefreshButton = () => {
7540
- const { query } = useKeys();
7541
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
7542
- ReloadButton,
7543
- {
7544
- onClick: () => {
7545
- queryClient.invalidateQueries({
7546
- queryKey: [FETCH_KEYS_QUERY_KEY]
7547
- });
7548
- queryClient.invalidateQueries({
7549
- queryKey: [FETCH_LIST_ITEMS_QUERY_KEY]
7550
- });
7551
- queryClient.invalidateQueries({
7552
- queryKey: [FETCH_SIMPLE_KEY_QUERY_KEY]
7553
- });
7554
- queryClient.invalidateQueries({
7555
- queryKey: [FETCH_KEY_TYPE_QUERY_KEY]
7556
- });
7557
- },
7558
- isLoading: query.isFetching
7559
- }
7560
- );
7561
- };
7562
-
7563
- // src/components/databrowser/components/header-error.tsx
7564
-
7565
- var HeaderError = () => {
7566
- const { query } = useKeys();
7567
- if (!query.error) return null;
7568
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-sm text-red-600 dark:text-red-400", children: formatUpstashErrorMessage(query.error) });
7569
- };
7570
-
7571
- // src/components/databrowser/components/query-builder.tsx
7572
-
7573
-
7574
- // src/components/databrowser/components/search/query-editor.tsx
7575
-
7576
-
7577
- // src/components/databrowser/components/search/search-types-file.ts
7578
- var SEARCH_TYPES = `
7579
-
7580
- export const FIELD_TYPES = ["TEXT", "U64", "I64", "F64", "BOOL", "DATE"] as const;
7581
- export type FieldType = (typeof FIELD_TYPES)[number];
7582
-
7583
- export type TextField = {
7584
- type: "TEXT";
7585
- noTokenize?: boolean;
7586
- noStem?: boolean;
7587
- from?: string;
7489
+ // src/components/databrowser/components/search/search-types-file.ts
7490
+ var SEARCH_TYPES = `
7491
+ export const FIELD_TYPES = [
7492
+ "TEXT",
7493
+ "U64",
7494
+ "I64",
7495
+ "F64",
7496
+ "BOOL",
7497
+ "DATE",
7498
+ "KEYWORD",
7499
+ "FACET",
7500
+ ] as const;
7501
+ export type FieldType = (typeof FIELD_TYPES)[number];
7502
+
7503
+ export type TextField = {
7504
+ type: "TEXT";
7505
+ noTokenize?: boolean;
7506
+ noStem?: boolean;
7507
+ from?: string;
7588
7508
  };
7589
7509
 
7590
7510
  export type NumericField = {
@@ -7605,7 +7525,21 @@ export type DateField = {
7605
7525
  from?: string;
7606
7526
  };
7607
7527
 
7608
- export type DetailedField = TextField | NumericField | BoolField | DateField;
7528
+ export type KeywordField = {
7529
+ type: "KEYWORD";
7530
+ };
7531
+
7532
+ export type FacetField = {
7533
+ type: "FACET";
7534
+ };
7535
+
7536
+ export type DetailedField =
7537
+ | TextField
7538
+ | NumericField
7539
+ | BoolField
7540
+ | DateField
7541
+ | KeywordField
7542
+ | FacetField;
7609
7543
  export type NestedIndexSchema = {
7610
7544
  [key: string]: FieldType | DetailedField | NestedIndexSchema;
7611
7545
  };
@@ -7653,7 +7587,11 @@ type FieldValueType<T extends FieldType> = T extends "TEXT"
7653
7587
  ? boolean
7654
7588
  : T extends "DATE"
7655
7589
  ? string
7656
- : never;
7590
+ : T extends "KEYWORD"
7591
+ ? string
7592
+ : T extends "FACET"
7593
+ ? string
7594
+ : never;
7657
7595
 
7658
7596
  type GetFieldValueType<TSchema, Path extends string> =
7659
7597
  GetFieldAtPath<TSchema, Path> extends infer Field
@@ -7760,7 +7698,7 @@ type PathToNestedObject<
7760
7698
  TSchema,
7761
7699
  Path extends string,
7762
7700
  Value,
7763
- > = Path extends \`\${ infer First }.\${ infer Rest }\`
7701
+ > = Path extends \`\${infer First}.\${infer Rest}\`
7764
7702
  ? { [K in First]: PathToNestedObject<TSchema, Rest, Value> }
7765
7703
  : { [K in Path]: Value };
7766
7704
 
@@ -7837,7 +7775,6 @@ export type PublicQueryResult<
7837
7775
  // These are the operations that can be used for each field type
7838
7776
  type StringOperationMap<T extends string> = {
7839
7777
  $eq: T;
7840
- $ne: T;
7841
7778
  $in: T[];
7842
7779
  $fuzzy: T | { value: T; distance?: number; transpositionCostOne?: boolean };
7843
7780
  $phrase:
@@ -7851,7 +7788,15 @@ type StringOperationMap<T extends string> = {
7851
7788
 
7852
7789
  type NumberOperationMap<T extends number> = {
7853
7790
  $eq: T;
7854
- $ne: T;
7791
+ $in: T[];
7792
+ $gt: T;
7793
+ $gte: T;
7794
+ $lt: T;
7795
+ $lte: T;
7796
+ };
7797
+
7798
+ type KeywordOperationMap<T extends string> = {
7799
+ $eq: T;
7855
7800
  $in: T[];
7856
7801
  $gt: T;
7857
7802
  $gte: T;
@@ -7861,13 +7806,11 @@ type NumberOperationMap<T extends number> = {
7861
7806
 
7862
7807
  type BooleanOperationMap<T extends boolean> = {
7863
7808
  $eq: T;
7864
- $ne: T;
7865
7809
  $in: T[];
7866
7810
  };
7867
7811
 
7868
7812
  type DateOperationMap<T extends string | Date> = {
7869
7813
  $eq: T;
7870
- $ne: T;
7871
7814
  $in: T[];
7872
7815
  $gt: T;
7873
7816
  $gte: T;
@@ -7875,6 +7818,11 @@ type DateOperationMap<T extends string | Date> = {
7875
7818
  $lt: T;
7876
7819
  };
7877
7820
 
7821
+ type FacetOperationMap<T extends string> = {
7822
+ $eq: T;
7823
+ $in: T[];
7824
+ };
7825
+
7878
7826
  // Create union types for each field type
7879
7827
  type StringOperations = {
7880
7828
  [K in keyof StringOperationMap<string>]: { [P in K]: StringOperationMap<string>[K] } & {
@@ -7900,6 +7848,18 @@ type DateOperations = {
7900
7848
  };
7901
7849
  }[keyof DateOperationMap<string | Date>];
7902
7850
 
7851
+ type KeywordOperations = {
7852
+ [K in keyof KeywordOperationMap<string>]: { [P in K]: KeywordOperationMap<string>[K] } & {
7853
+ $boost?: number;
7854
+ };
7855
+ }[keyof KeywordOperationMap<string>];
7856
+
7857
+ type FacetOperations = {
7858
+ [K in keyof FacetOperationMap<string>]: { [P in K]: FacetOperationMap<string>[K] } & {
7859
+ $boost?: number;
7860
+ };
7861
+ }[keyof FacetOperationMap<string>];
7862
+
7903
7863
  // Create a union type for all operations for a given field type
7904
7864
  type OperationsForFieldType<T extends FieldType> = T extends "TEXT"
7905
7865
  ? StringOperations
@@ -7909,7 +7869,11 @@ type OperationsForFieldType<T extends FieldType> = T extends "TEXT"
7909
7869
  ? BooleanOperations
7910
7870
  : T extends "DATE"
7911
7871
  ? DateOperations
7912
- : never;
7872
+ : T extends "KEYWORD"
7873
+ ? KeywordOperations
7874
+ : T extends "FACET"
7875
+ ? FacetOperations
7876
+ : never;
7913
7877
 
7914
7878
  // Create a union type for all operations for a given path
7915
7879
  type PathOperations<TSchema, TPath extends string> =
@@ -8077,45 +8041,1016 @@ type RootOrNode<TSchema extends NestedIndexSchema | FlatIndexSchema> = {
8077
8041
  $and?: never;
8078
8042
  $must?: never;
8079
8043
  $should?: never;
8080
- $mustNot?: never;
8044
+ $mustNot?: QueryFilter<TSchema> | QueryFilter<TSchema>[];
8045
+ };
8046
+
8047
+ export type DescribeFieldInfo = {
8048
+ type: FieldType;
8049
+ noTokenize?: boolean;
8050
+ noStem?: boolean;
8051
+ fast?: boolean;
8052
+ };
8053
+
8054
+ export type IndexDescription<TSchema extends NestedIndexSchema | FlatIndexSchema> = {
8055
+ name: string;
8056
+ dataType: "hash" | "string" | "json";
8057
+ prefixes: string[];
8058
+ language?: Language;
8059
+ schema: Record<SchemaPaths<TSchema>, DescribeFieldInfo>;
8060
+ };
8061
+
8062
+ export type Language =
8063
+ | "english"
8064
+ | "arabic"
8065
+ | "danish"
8066
+ | "dutch"
8067
+ | "finnish"
8068
+ | "french"
8069
+ | "german"
8070
+ | "greek"
8071
+ | "hungarian"
8072
+ | "italian"
8073
+ | "norwegian"
8074
+ | "portuguese"
8075
+ | "romanian"
8076
+ | "russian"
8077
+ | "spanish"
8078
+ | "swedish"
8079
+ | "tamil"
8080
+ | "turkish";
8081
+
8082
+ // Helper type to extract only FACET field paths from schema
8083
+ export type FacetPaths<T, Prefix extends string = ""> = {
8084
+ [K in keyof T]: K extends string
8085
+ ? T[K] extends "FACET" | { type: "FACET" }
8086
+ ? Prefix extends ""
8087
+ ? K
8088
+ : \`\${Prefix}\${K}\`
8089
+ : T[K] extends FieldType | DetailedField
8090
+ ? never
8091
+ : T[K] extends object
8092
+ ? FacetPaths<T[K], \`\${Prefix}\${K}.\`>
8093
+ : never
8094
+ : never;
8095
+ }[keyof T];
8096
+
8097
+ // Aggregate Types
8098
+ export type AggregateOptions<TSchema extends NestedIndexSchema | FlatIndexSchema> = {
8099
+ filter?: RootQueryFilter<TSchema>;
8100
+ aggregations: {
8101
+ [key: string]: Aggregation<TSchema>;
8102
+ };
8103
+ };
8104
+
8105
+ export type Aggregation<TSchema extends NestedIndexSchema | FlatIndexSchema> =
8106
+ | TermsAggregation<TSchema>
8107
+ | RangeAggregation<TSchema>
8108
+ | HistogramAggregation<TSchema>
8109
+ | StatsAggregation<TSchema>
8110
+ | AvgAggregation<TSchema>
8111
+ | SumAggregation<TSchema>
8112
+ | MinAggregation<TSchema>
8113
+ | MaxAggregation<TSchema>
8114
+ | CountAggregation<TSchema>
8115
+ | ExtendedStatsAggregation<TSchema>
8116
+ | PercentilesAggregation<TSchema>
8117
+ | CardinalityAggregation<TSchema>
8118
+ | FacetAggregation<TSchema>;
8119
+
8120
+ type BaseAggregation<TSchema extends NestedIndexSchema | FlatIndexSchema> = {
8121
+ $aggs?: {
8122
+ [key: string]: Aggregation<TSchema>;
8123
+ };
8124
+ };
8125
+
8126
+ export type TermsAggregation<TSchema extends NestedIndexSchema | FlatIndexSchema> =
8127
+ BaseAggregation<TSchema> & {
8128
+ $terms: {
8129
+ field: SchemaPaths<TSchema>;
8130
+ size?: number;
8131
+ };
8132
+ };
8133
+
8134
+ export type RangeAggregation<TSchema extends NestedIndexSchema | FlatIndexSchema> =
8135
+ BaseAggregation<TSchema> & {
8136
+ $range: {
8137
+ field: SchemaPaths<TSchema>;
8138
+ ranges: { from?: number; to?: number }[];
8139
+ };
8140
+ };
8141
+
8142
+ export type HistogramAggregation<TSchema extends NestedIndexSchema | FlatIndexSchema> =
8143
+ BaseAggregation<TSchema> & {
8144
+ $histogram: {
8145
+ field: SchemaPaths<TSchema>;
8146
+ interval: number;
8147
+ };
8148
+ };
8149
+
8150
+ export type StatsAggregation<TSchema extends NestedIndexSchema | FlatIndexSchema> =
8151
+ BaseAggregation<TSchema> & {
8152
+ $stats: {
8153
+ field: SchemaPaths<TSchema>;
8154
+ missing?: number;
8155
+ };
8156
+ };
8157
+
8158
+ export type AvgAggregation<TSchema extends NestedIndexSchema | FlatIndexSchema> =
8159
+ BaseAggregation<TSchema> & {
8160
+ $avg: {
8161
+ field: SchemaPaths<TSchema>;
8162
+ missing?: number;
8163
+ };
8164
+ };
8165
+
8166
+ export type SumAggregation<TSchema extends NestedIndexSchema | FlatIndexSchema> =
8167
+ BaseAggregation<TSchema> & {
8168
+ $sum: {
8169
+ field: SchemaPaths<TSchema>;
8170
+ missing?: number;
8171
+ };
8172
+ };
8173
+
8174
+ export type MinAggregation<TSchema extends NestedIndexSchema | FlatIndexSchema> =
8175
+ BaseAggregation<TSchema> & {
8176
+ $min: {
8177
+ field: SchemaPaths<TSchema>;
8178
+ missing?: number;
8179
+ };
8180
+ };
8181
+
8182
+ export type MaxAggregation<TSchema extends NestedIndexSchema | FlatIndexSchema> =
8183
+ BaseAggregation<TSchema> & {
8184
+ $max: {
8185
+ field: SchemaPaths<TSchema>;
8186
+ missing?: number;
8187
+ };
8188
+ };
8189
+
8190
+ export type CountAggregation<TSchema extends NestedIndexSchema | FlatIndexSchema> =
8191
+ BaseAggregation<TSchema> & {
8192
+ $count: {
8193
+ field: SchemaPaths<TSchema>;
8194
+ };
8195
+ };
8196
+
8197
+ export type ExtendedStatsAggregation<TSchema extends NestedIndexSchema | FlatIndexSchema> =
8198
+ BaseAggregation<TSchema> & {
8199
+ $extendedStats: {
8200
+ field: SchemaPaths<TSchema>;
8201
+ sigma?: number;
8202
+ missing?: number;
8203
+ };
8204
+ };
8205
+
8206
+ export type PercentilesAggregation<TSchema extends NestedIndexSchema | FlatIndexSchema> =
8207
+ BaseAggregation<TSchema> & {
8208
+ $percentiles: {
8209
+ field: SchemaPaths<TSchema>;
8210
+ percents?: number[];
8211
+ keyed?: boolean;
8212
+ missing?: number;
8213
+ };
8214
+ };
8215
+
8216
+ export type CardinalityAggregation<TSchema extends NestedIndexSchema | FlatIndexSchema> =
8217
+ BaseAggregation<TSchema> & {
8218
+ $cardinality: {
8219
+ field: SchemaPaths<TSchema>;
8220
+ };
8221
+ };
8222
+
8223
+ export type FacetAggregation<TSchema extends NestedIndexSchema | FlatIndexSchema> =
8224
+ BaseAggregation<TSchema> & {
8225
+ $facet: {
8226
+ field: FacetPaths<TSchema>;
8227
+ path: string;
8228
+ depth?: number;
8229
+ size?: number;
8230
+ minDocCount?: number;
8231
+ order?: { count: "desc" | "asc" };
8232
+ };
8233
+ };
8234
+
8235
+ export type AggregateResult<
8236
+ TSchema extends NestedIndexSchema | FlatIndexSchema,
8237
+ TOpts extends AggregateOptions<TSchema>,
8238
+ > = BuildAggregateResult<TSchema, TOpts["aggregations"]>;
8239
+
8240
+ type BuildAggregateResult<
8241
+ TSchema extends NestedIndexSchema | FlatIndexSchema,
8242
+ TAggs extends { [key: string]: Aggregation<TSchema> },
8243
+ > = {
8244
+ [K in keyof TAggs]: TAggs[K] extends TermsAggregation<TSchema>
8245
+ ? TermsResult<TSchema, TAggs[K]>
8246
+ : TAggs[K] extends RangeAggregation<TSchema>
8247
+ ? RangeResult<TSchema, TAggs[K]>
8248
+ : TAggs[K] extends HistogramAggregation<TSchema>
8249
+ ? HistogramResult<TSchema, TAggs[K]>
8250
+ : TAggs[K] extends StatsAggregation<TSchema>
8251
+ ? StatsResult
8252
+ : TAggs[K] extends AvgAggregation<TSchema>
8253
+ ? MetricValueResult
8254
+ : TAggs[K] extends SumAggregation<TSchema>
8255
+ ? MetricValueResult
8256
+ : TAggs[K] extends MinAggregation<TSchema>
8257
+ ? MetricValueResult
8258
+ : TAggs[K] extends MaxAggregation<TSchema>
8259
+ ? MetricValueResult
8260
+ : TAggs[K] extends CountAggregation<TSchema>
8261
+ ? MetricValueResult
8262
+ : TAggs[K] extends CardinalityAggregation<TSchema>
8263
+ ? MetricValueResult
8264
+ : TAggs[K] extends ExtendedStatsAggregation<TSchema>
8265
+ ? ExtendedStatsResult<TAggs[K]>
8266
+ : TAggs[K] extends PercentilesAggregation<TSchema>
8267
+ ? PercentilesResult<TAggs[K]>
8268
+ : TAggs[K] extends FacetAggregation<TSchema>
8269
+ ? FacetResult
8270
+ : never;
8271
+ };
8272
+
8273
+ type Bucket<T> = {
8274
+ key: T;
8275
+ docCount: number;
8276
+ from?: number;
8277
+ to?: number;
8278
+ };
8279
+
8280
+ type TermsResult<
8281
+ TSchema extends NestedIndexSchema | FlatIndexSchema,
8282
+ TAgg extends TermsAggregation<TSchema>,
8283
+ > = TAgg["$aggs"] extends { [key: string]: Aggregation<TSchema> }
8284
+ ? {
8285
+ buckets: (Bucket<GetFieldValueType<TSchema, TAgg["$terms"]["field"]>> &
8286
+ BuildAggregateResult<TSchema, TAgg["$aggs"]>)[];
8287
+ sumOtherDocCount: number;
8288
+ docCountErrorUpperBound: number;
8289
+ }
8290
+ : {
8291
+ buckets: Bucket<GetFieldValueType<TSchema, TAgg["$terms"]["field"]>>[];
8292
+ sumOtherDocCount: number;
8293
+ docCountErrorUpperBound: number;
8294
+ };
8295
+
8296
+ type RangeResult<
8297
+ TSchema extends NestedIndexSchema | FlatIndexSchema,
8298
+ TAgg extends RangeAggregation<TSchema>,
8299
+ > = TAgg["$aggs"] extends { [key: string]: Aggregation<TSchema> }
8300
+ ? {
8301
+ buckets: (Bucket<string> & BuildAggregateResult<TSchema, TAgg["$aggs"]>)[];
8302
+ }
8303
+ : {
8304
+ buckets: Bucket<string>[];
8305
+ };
8306
+
8307
+ type HistogramResult<
8308
+ TSchema extends NestedIndexSchema | FlatIndexSchema,
8309
+ TAgg extends HistogramAggregation<TSchema>,
8310
+ > = TAgg["$aggs"] extends { [key: string]: Aggregation<TSchema> }
8311
+ ? {
8312
+ buckets: (Bucket<number> & BuildAggregateResult<TSchema, TAgg["$aggs"]>)[];
8313
+ }
8314
+ : {
8315
+ buckets: Bucket<number>[];
8316
+ };
8317
+
8318
+ type MetricValueResult = {
8319
+ value: number;
8320
+ };
8321
+
8322
+ type StatsResult = {
8323
+ count: number;
8324
+ min: number;
8325
+ max: number;
8326
+ sum: number;
8327
+ avg: number;
8328
+ };
8329
+
8330
+ type ExtendedStatsResult<_TAgg> = {
8331
+ count: number;
8332
+ min: number;
8333
+ max: number;
8334
+ avg: number;
8335
+ sum: number;
8336
+ sumOfSquares: number;
8337
+ variance: number;
8338
+ variancePopulation: number;
8339
+ varianceSampling: number;
8340
+ stdDeviation: number;
8341
+ stdDeviationPopulation: number;
8342
+ stdDeviationSampling: number;
8343
+ stdDeviationBounds: {
8344
+ upper: number;
8345
+ lower: number;
8346
+ upperSampling: number;
8347
+ lowerSampling: number;
8348
+ upperPopulation: number;
8349
+ lowerPopulation: number;
8350
+ };
8351
+ };
8352
+
8353
+ type PercentilesResult<TAgg> = TAgg extends { $percentiles: { keyed: false } }
8354
+ ? {
8355
+ values: Array<{ key: number; value: number }>;
8356
+ }
8357
+ : {
8358
+ values: { [key: string]: number };
8359
+ };
8360
+
8361
+ type FacetChildNode = {
8362
+ path: string;
8363
+ docCount: number;
8364
+ sumOtherDocCount: number;
8365
+ children?: FacetChildNode[];
8366
+ };
8367
+
8368
+ type FacetResult = {
8369
+ path: string;
8370
+ sumOtherDocCount: number;
8371
+ children: FacetChildNode[];
8372
+ };
8373
+
8374
+ `;
8375
+
8376
+ // src/components/databrowser/components/query-wizard/use-query-wizard.tsx
8377
+ var QueryWizardContext = _react.createContext.call(void 0, void 0);
8378
+ var QueryWizardProvider = QueryWizardContext.Provider;
8379
+ var useQueryWizardFn = () => {
8380
+ return _react.useContext.call(void 0, QueryWizardContext);
8381
+ };
8382
+ var useGenerateQuery = () => {
8383
+ const queryWizard = useQueryWizardFn();
8384
+ return _reactquery.useMutation.call(void 0, {
8385
+ mutationFn: async ({
8386
+ prompt,
8387
+ searchIndex,
8388
+ sampleData
8389
+ }) => {
8390
+ if (!queryWizard) {
8391
+ throw new Error(
8392
+ "Query Wizard is not configured. Please provide a useQueryWizard prop to RedisBrowser component."
8393
+ );
8394
+ }
8395
+ const result = await queryWizard({
8396
+ prompt,
8397
+ searchIndex,
8398
+ sampleData,
8399
+ searchTypes: SEARCH_TYPES
8400
+ });
8401
+ return result;
8402
+ }
8403
+ });
8404
+ };
8405
+
8406
+ // src/components/databrowser/components/query-wizard/query-wizard-popover.tsx
8407
+
8408
+ var QueryWizardPopover = ({ onClose }) => {
8409
+ const { valuesSearch, setValuesSearchQuery, setQueryBuilderMode } = useTab();
8410
+ const { redisNoPipeline: redis } = useRedis();
8411
+ const [input, setInput] = _react.useState.call(void 0, "");
8412
+ const [sampleData, setSampleData] = _react.useState.call(void 0, []);
8413
+ const [showIndexFields, setShowIndexFields] = _react.useState.call(void 0, false);
8414
+ const { aiDataSharingConsent } = useDatabrowserStore();
8415
+ const { data: indexData, isLoading: isLoadingIndex } = useFetchSearchIndex(valuesSearch.index);
8416
+ const generateQuery = useGenerateQuery();
8417
+ const fetchSampleKeys = _reactquery.useMutation.call(void 0, {
8418
+ mutationFn: async (index) => {
8419
+ const firstTenKeys = await scanKeys(redis, {
8420
+ match: `${_optionalChain([index, 'access', _85 => _85.prefixes, 'optionalAccess', _86 => _86[0]])}*`,
8421
+ type: index.dataType,
8422
+ limit: 10
8423
+ });
8424
+ const dataPromises = firstTenKeys.map(async (key) => {
8425
+ try {
8426
+ if (index.dataType === "json") {
8427
+ const data = await redis.json.get(key);
8428
+ return { key, data };
8429
+ } else if (index.dataType === "hash") {
8430
+ const data = await redis.hgetall(key);
8431
+ return { key, data };
8432
+ } else {
8433
+ const data = await redis.get(key);
8434
+ return { key, data };
8435
+ }
8436
+ } catch (e5) {
8437
+ return null;
8438
+ }
8439
+ });
8440
+ const results = await Promise.all(dataPromises);
8441
+ const filtered = results.filter(Boolean);
8442
+ setSampleData(filtered);
8443
+ return filtered;
8444
+ }
8445
+ });
8446
+ const handleGenerate = async () => {
8447
+ if (!input.trim() || !valuesSearch.index) return;
8448
+ try {
8449
+ let samples = sampleData;
8450
+ if (samples.length === 0 && _optionalChain([indexData, 'optionalAccess', _87 => _87.prefixes, 'optionalAccess', _88 => _88[0]])) {
8451
+ samples = await fetchSampleKeys.mutateAsync(indexData);
8452
+ }
8453
+ const result = await generateQuery.mutateAsync({
8454
+ prompt: input,
8455
+ searchIndex: _nullishCoalesce(indexData, () => ( void 0)),
8456
+ sampleData: samples
8457
+ });
8458
+ const queryString = toJsLiteral(result.query);
8459
+ setValuesSearchQuery(queryString);
8460
+ setQueryBuilderMode("code");
8461
+ _optionalChain([onClose, 'optionalCall', _89 => _89()]);
8462
+ } catch (error) {
8463
+ console.error("Error generating query:", error);
8464
+ }
8465
+ };
8466
+ if (isLoadingIndex) {
8467
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex h-[100px] w-[340px] items-center justify-center rounded-2xl bg-white", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Spinner, { isLoading: true, isLoadingText: "Loading index..." }) });
8468
+ }
8469
+ if (!valuesSearch.index) {
8470
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex w-[340px] flex-col items-center gap-2 rounded-2xl bg-white p-8", children: [
8471
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-sm font-medium text-zinc-700", children: "No index selected" }),
8472
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-center text-xs text-zinc-500", children: "Create a new index to use the Query Wizard." })
8473
+ ] });
8474
+ }
8475
+ if (aiDataSharingConsent === false) {
8476
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ConsentPrompt, { onClose });
8477
+ }
8478
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex w-[500px] flex-col gap-6 rounded-2xl bg-white p-6", children: [
8479
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center gap-2", children: [
8480
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { className: "text-base font-semibold text-zinc-950", children: "AI Query Builder" }),
8481
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex items-center justify-center rounded-md bg-purple-100 px-1.5 py-0.5", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "!text-sm font-medium text-purple-700", children: "BETA" }) })
8482
+ ] }),
8483
+ generateQuery.error && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "mt-2 rounded-md border border-yellow-300 bg-yellow-50 p-4", children: [
8484
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "!text-sm font-medium !text-yellow-800", children: generateQuery.error.name }),
8485
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "mt-0.5 !text-sm !text-yellow-800 opacity-90", children: generateQuery.error.message })
8486
+ ] }),
8487
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col gap-5", children: [
8488
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
8489
+ "button",
8490
+ {
8491
+ onClick: () => setShowIndexFields(!showIndexFields),
8492
+ className: "flex h-8 items-center gap-1.5 rounded-md border border-zinc-300 bg-zinc-50 px-3 hover:bg-zinc-100",
8493
+ children: [
8494
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
8495
+ _iconsreact.IconChevronRight,
8496
+ {
8497
+ className: `size-5 text-zinc-700 transition-transform ${showIndexFields ? "rotate-90" : ""}`
8498
+ }
8499
+ ),
8500
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-sm font-medium text-zinc-700", children: "Show Index fields" })
8501
+ ]
8502
+ }
8503
+ ),
8504
+ showIndexFields && indexData && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "rounded-md border border-zinc-200 bg-zinc-50 p-3", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "pre", { className: "max-h-40 overflow-auto text-xs text-zinc-700", children: JSON.stringify(indexData.schema, null, 2) }) }),
8505
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col gap-1", children: [
8506
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Label, { htmlFor: "query-input", className: "text-sm font-medium text-zinc-950", children: "Describe" }),
8507
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
8508
+ "textarea",
8509
+ {
8510
+ id: "query-input",
8511
+ value: input,
8512
+ onChange: (e) => setInput(e.target.value),
8513
+ placeholder: "",
8514
+ className: "h-[58px] w-full resize-none rounded-md border border-zinc-300 bg-white px-3 py-3 text-sm text-zinc-950 shadow-sm focus:border-purple-500 focus:outline-none focus:ring-1 focus:ring-purple-500 disabled:cursor-not-allowed disabled:opacity-50",
8515
+ disabled: generateQuery.isPending || fetchSampleKeys.isPending,
8516
+ autoFocus: true
8517
+ }
8518
+ ),
8519
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { children: [
8520
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-xs text-zinc-500", children: 'Example: Find people named "John", boost if older than 20.' }),
8521
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, DocsLink, { href: "https://upstash-search.mintlify.app/redis/search/query-operators/boolean-operators/overview" })
8522
+ ] })
8523
+ ] })
8524
+ ] }),
8525
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center justify-end gap-2", children: [
8526
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
8527
+ "button",
8528
+ {
8529
+ onClick: onClose,
8530
+ disabled: generateQuery.isPending || fetchSampleKeys.isPending,
8531
+ className: "flex h-8 items-center justify-center rounded-md border border-zinc-300 bg-white px-4 text-sm text-zinc-950 shadow-[0_1px_1px_rgba(0,0,0,0.05)] hover:bg-zinc-50 disabled:cursor-not-allowed disabled:opacity-50",
8532
+ children: "Cancel"
8533
+ }
8534
+ ),
8535
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
8536
+ "button",
8537
+ {
8538
+ onClick: handleGenerate,
8539
+ disabled: !input.trim() || generateQuery.isPending || fetchSampleKeys.isPending,
8540
+ className: "flex h-8 items-center justify-center gap-2 rounded-md bg-purple-500 px-4 text-sm text-white shadow-[0_1px_1px_rgba(0,0,0,0.05)] hover:bg-purple-600 disabled:cursor-not-allowed disabled:opacity-50 disabled:hover:bg-purple-500",
8541
+ children: fetchSampleKeys.isPending ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
8542
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Spinner, { isLoading: true }),
8543
+ "Sampling keys..."
8544
+ ] }) : generateQuery.isPending ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
8545
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Spinner, { isLoading: true }),
8546
+ "Generating..."
8547
+ ] }) : "Generate Query"
8548
+ }
8549
+ )
8550
+ ] })
8551
+ ] });
8552
+ };
8553
+
8554
+ // src/components/databrowser/components/search/create-index-modal.tsx
8555
+
8556
+ var CreateIndexModal = ({
8557
+ open,
8558
+ onOpenChange
8559
+ }) => {
8560
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Dialog, { open, onOpenChange, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
8561
+ DialogContent,
8562
+ {
8563
+ className: "max-w-2xl",
8564
+ onEscapeKeyDown: (e) => {
8565
+ const active = document.activeElement;
8566
+ if (_optionalChain([active, 'optionalAccess', _90 => _90.closest, 'call', _91 => _91(".monaco-editor")]) || _optionalChain([active, 'optionalAccess', _92 => _92.tagName]) === "TEXTAREA") {
8567
+ e.preventDefault();
8568
+ }
8569
+ },
8570
+ children: [
8571
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, DialogHeader, { children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, DialogTitle, { children: "Create new Index" }) }),
8572
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "sr-only", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, DialogDescription, { children: "Create new search index" }) }),
8573
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, SearchDisplay, { isCreateModal: true, onClose: () => onOpenChange(false) })
8574
+ ]
8575
+ }
8576
+ ) });
8577
+ };
8578
+
8579
+ // src/components/databrowser/components/search/edit-index-modal.tsx
8580
+
8581
+
8582
+ var EditIndexModal = ({
8583
+ open,
8584
+ onOpenChange,
8585
+ indexName
8586
+ }) => {
8587
+ const { data: indexData, isLoading: isIndexLoading } = useFetchSearchIndex(indexName, {
8588
+ enabled: open
8589
+ });
8590
+ _react.useEffect.call(void 0, () => {
8591
+ if (open && !isIndexLoading && indexData === null) {
8592
+ onOpenChange(false);
8593
+ }
8594
+ }, [indexData, onOpenChange, isIndexLoading, open]);
8595
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Dialog, { open, onOpenChange, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
8596
+ DialogContent,
8597
+ {
8598
+ className: "min-h-[500px] max-w-2xl",
8599
+ onEscapeKeyDown: (e) => {
8600
+ const active = document.activeElement;
8601
+ if (_optionalChain([active, 'optionalAccess', _93 => _93.closest, 'call', _94 => _94(".monaco-editor")]) || _optionalChain([active, 'optionalAccess', _95 => _95.tagName]) === "TEXTAREA") {
8602
+ e.preventDefault();
8603
+ }
8604
+ },
8605
+ children: [
8606
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, DialogHeader, { children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, DialogTitle, { children: "Edit Index" }) }),
8607
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "sr-only", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, DialogDescription, { children: "Edit search index schema" }) }),
8608
+ indexName && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, SearchDisplay, { indexName, isEditModal: true, onClose: () => onOpenChange(false) })
8609
+ ]
8610
+ }
8611
+ ) });
8612
+ };
8613
+
8614
+ // src/components/databrowser/components/header/refresh-button.tsx
8615
+
8616
+
8617
+ // src/components/common/reload-button.tsx
8618
+
8619
+
8620
+
8621
+ var ReloadButton = ({
8622
+ onClick,
8623
+ isLoading: isLoadingProp,
8624
+ tooltip = "Refresh"
8625
+ }) => {
8626
+ const [isLoading, setIsLoading] = _react.useState.call(void 0, false);
8627
+ const handleClick = () => {
8628
+ setIsLoading(true);
8629
+ onClick();
8630
+ setTimeout(() => {
8631
+ setIsLoading(false);
8632
+ }, 350);
8633
+ };
8634
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, SimpleTooltip, { content: tooltip, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
8635
+ Button,
8636
+ {
8637
+ variant: "outline",
8638
+ size: "icon",
8639
+ onClick: handleClick,
8640
+ disabled: isLoading || isLoadingProp,
8641
+ children: isLoading ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _iconsreact.IconLoader2, { className: "size-5 animate-spin text-zinc-500" }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _iconsreact.IconRefresh, { className: "size-5 text-zinc-500 dark:text-zinc-600" })
8642
+ }
8643
+ ) }) });
8644
+ };
8645
+
8646
+ // src/components/databrowser/components/header/refresh-button.tsx
8647
+
8648
+ var invalidateAll = () => {
8649
+ queryClient.invalidateQueries({ queryKey: [FETCH_KEYS_QUERY_KEY] });
8650
+ queryClient.invalidateQueries({ queryKey: [FETCH_LIST_ITEMS_QUERY_KEY] });
8651
+ queryClient.invalidateQueries({ queryKey: [FETCH_SIMPLE_KEY_QUERY_KEY] });
8652
+ queryClient.invalidateQueries({ queryKey: [FETCH_KEY_TYPE_QUERY_KEY] });
8653
+ };
8654
+ var RefreshButton = () => {
8655
+ const { query } = useKeys();
8656
+ const { isValuesSearchSelected, valuesSearch } = useTab();
8657
+ const { redisNoPipeline: redis } = useRedis();
8658
+ const reindex = _reactquery.useMutation.call(void 0, {
8659
+ mutationFn: async () => {
8660
+ if (isValuesSearchSelected && valuesSearch.index) {
8661
+ await redis.search.index({ name: valuesSearch.index }).waitIndexing();
8662
+ }
8663
+ },
8664
+ onSettled: invalidateAll
8665
+ });
8666
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
8667
+ ReloadButton,
8668
+ {
8669
+ onClick: () => reindex.mutate(),
8670
+ isLoading: query.isFetching || reindex.isPending,
8671
+ tooltip: isValuesSearchSelected ? "Reindex & Refresh Query" : "Refresh Scan"
8672
+ }
8673
+ );
8674
+ };
8675
+
8676
+ // src/components/databrowser/components/header/search-input.tsx
8677
+
8678
+
8679
+
8680
+ var dedupeSearchHistory = (history) => {
8681
+ const seen = /* @__PURE__ */ new Set();
8682
+ return history.filter((item) => {
8683
+ if (!item || seen.has(item)) return false;
8684
+ seen.add(item);
8685
+ return true;
8686
+ });
8687
+ };
8688
+ var SearchInput = () => {
8689
+ const { setSearchKey, search } = useTab();
8690
+ const { searchHistory, addSearchHistory } = useDatabrowserStore();
8691
+ const [state, setState] = _react.useState.call(void 0, search.key);
8692
+ const [isFocus, setIsFocus] = _react.useState.call(void 0, false);
8693
+ const [focusedIndex, setFocusedIndex] = _react.useState.call(void 0, -1);
8694
+ const inputRef = _react.useRef.call(void 0, null);
8695
+ const historyItemRefs = _react.useRef.call(void 0, []);
8696
+ const handleSubmit = (value) => {
8697
+ if (value.trim() !== "" && !value.includes("*")) value = `${value}*`;
8698
+ addSearchHistory(value);
8699
+ setSearchKey(value);
8700
+ setState(value);
8701
+ };
8702
+ const filteredHistory = dedupeSearchHistory(
8703
+ searchHistory.filter((item) => item.trim() !== "" && item.trim() !== "*").filter((item) => item.includes(state) && item !== state)
8704
+ ).slice(0, 5).map((item) => item.endsWith("*") ? item.slice(0, -1) : item);
8705
+ _react.useEffect.call(void 0, () => {
8706
+ setFocusedIndex(-1);
8707
+ }, [filteredHistory.length]);
8708
+ const handleKeyDown = (e) => {
8709
+ if (e.key === "Enter") {
8710
+ const text = focusedIndex >= 0 && focusedIndex < filteredHistory.length ? filteredHistory[focusedIndex] : e.currentTarget.value;
8711
+ handleSubmit(text);
8712
+ } else if (e.key === "Escape") {
8713
+ setState("");
8714
+ setFocusedIndex(-1);
8715
+ _optionalChain([inputRef, 'access', _96 => _96.current, 'optionalAccess', _97 => _97.blur, 'call', _98 => _98()]);
8716
+ } else if (e.key === "ArrowDown" || e.key === "Tab" && !e.shiftKey) {
8717
+ e.preventDefault();
8718
+ if (focusedIndex < filteredHistory.length - 1) {
8719
+ setFocusedIndex(focusedIndex + 1);
8720
+ } else if (filteredHistory.length > 0) {
8721
+ setFocusedIndex(0);
8722
+ }
8723
+ } else if (e.key === "ArrowUp" || e.key === "Tab" && e.shiftKey) {
8724
+ e.preventDefault();
8725
+ if (focusedIndex > 0) {
8726
+ setFocusedIndex(focusedIndex - 1);
8727
+ } else if (filteredHistory.length > 0 && focusedIndex === 0) {
8728
+ setFocusedIndex(-1);
8729
+ _optionalChain([inputRef, 'access', _99 => _99.current, 'optionalAccess', _100 => _100.focus, 'call', _101 => _101()]);
8730
+ } else if (filteredHistory.length > 0) {
8731
+ setFocusedIndex(filteredHistory.length - 1);
8732
+ }
8733
+ }
8734
+ };
8735
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "relative grow", children: [
8736
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, Popover, { open: isFocus && filteredHistory.length > 0, children: [
8737
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, PopoverTrigger, { asChild: true, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "h-8 rounded-md border border-zinc-300 font-normal", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
8738
+ Input,
8739
+ {
8740
+ ref: inputRef,
8741
+ placeholder: "Search",
8742
+ className: "h-full border-none pr-6",
8743
+ onKeyDown: handleKeyDown,
8744
+ onChange: (e) => {
8745
+ setState(e.currentTarget.value);
8746
+ if (e.currentTarget.value.trim() === "") handleSubmit("");
8747
+ },
8748
+ value: state,
8749
+ onFocus: () => {
8750
+ setIsFocus(true);
8751
+ setFocusedIndex(-1);
8752
+ },
8753
+ onBlur: () => setIsFocus(false)
8754
+ }
8755
+ ) }) }),
8756
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
8757
+ PopoverContent,
8758
+ {
8759
+ className: "w-[--radix-popover-trigger-width] divide-y px-3 py-2 text-[13px] text-zinc-900",
8760
+ autoFocus: false,
8761
+ onOpenAutoFocus: (e) => {
8762
+ e.preventDefault();
8763
+ e.stopPropagation();
8764
+ },
8765
+ children: filteredHistory.map((item, index) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "w-full py-[3px]", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
8766
+ "button",
8767
+ {
8768
+ ref: (el) => {
8769
+ historyItemRefs.current[index] = el;
8770
+ },
8771
+ onClick: () => handleSubmit(item),
8772
+ onMouseEnter: () => setFocusedIndex(index),
8773
+ className: `block w-full truncate rounded-sm p-1 text-left transition-colors ${focusedIndex === index ? "bg-zinc-100" : "hover:bg-zinc-100"}`,
8774
+ children: item
8775
+ }
8776
+ ) }, item))
8777
+ }
8778
+ )
8779
+ ] }),
8780
+ state && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
8781
+ Button,
8782
+ {
8783
+ type: "button",
8784
+ variant: "link",
8785
+ size: "icon",
8786
+ className: "absolute right-1 top-1/2 h-5 w-5 -translate-y-1/2 text-zinc-500 hover:text-zinc-900",
8787
+ onClick: () => {
8788
+ setSearchKey("");
8789
+ setState("");
8790
+ },
8791
+ children: [
8792
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _iconsreact.IconX, { size: 16 }),
8793
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "sr-only", children: "Clear" })
8794
+ ]
8795
+ }
8796
+ ),
8797
+ " "
8798
+ ] });
8799
+ };
8800
+
8801
+ // src/components/databrowser/components/header/type-selector.tsx
8802
+
8803
+ var ALL_TYPES_KEY = "all";
8804
+ function DataTypeSelector({ allowSearch }) {
8805
+ const { search, setSearchType } = useTab();
8806
+ const entries = [
8807
+ [ALL_TYPES_KEY, "All Types"],
8808
+ ...Object.entries(DATA_TYPE_NAMES).filter(([key]) => allowSearch || key !== "search")
8809
+ ];
8810
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
8811
+ Select,
8812
+ {
8813
+ onValueChange: (type) => {
8814
+ if (type === ALL_TYPES_KEY) {
8815
+ setSearchType(void 0);
8816
+ } else {
8817
+ setSearchType(type);
8818
+ }
8819
+ },
8820
+ value: search.type === void 0 ? ALL_TYPES_KEY : search.type,
8821
+ children: [
8822
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, SelectTrigger, { className: "!w-auto shrink-0 select-none whitespace-nowrap border-zinc-300 pr-8", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, SelectValue, {}) }),
8823
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, SelectContent, { children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, SelectGroup, { children: entries.map(([key, value]) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, SelectItem, { value: key, children: value }, key)) }) })
8824
+ ]
8825
+ }
8826
+ );
8827
+ }
8828
+
8829
+ // src/components/databrowser/components/header/index.tsx
8830
+
8831
+ var Header = ({ tabType, allowSearch }) => {
8832
+ const { isValuesSearchSelected, setIsValuesSearchSelected } = useTab();
8833
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center justify-between gap-1.5", children: [
8834
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex grow items-center gap-1.5", children: [
8835
+ tabType === "all" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
8836
+ Segmented,
8837
+ {
8838
+ options: [
8839
+ {
8840
+ key: "keys",
8841
+ label: "Keys"
8842
+ },
8843
+ {
8844
+ key: "values",
8845
+ label: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center gap-1", children: [
8846
+ "Search",
8847
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex h-[18px] items-center rounded-md bg-emerald-100 px-[5px] text-[11px] text-emerald-700", children: "NEW" })
8848
+ ] })
8849
+ }
8850
+ ],
8851
+ value: isValuesSearchSelected ? "values" : "keys",
8852
+ onChange: (value) => {
8853
+ setIsValuesSearchSelected(value === "values");
8854
+ },
8855
+ className: "bg-emerald-800",
8856
+ unselectedClassName: "text-emerald-100",
8857
+ selectedClassName: "bg-emerald-50 text-emerald-800"
8858
+ }
8859
+ ),
8860
+ isValuesSearchSelected ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, IndexSelector, {}) : /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
8861
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, DataTypeSelector, { allowSearch }),
8862
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, SearchInput, {})
8863
+ ] })
8864
+ ] }),
8865
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center gap-1.5", children: [
8866
+ isValuesSearchSelected && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, WizardButton, {}),
8867
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, RefreshButton, {}),
8868
+ isValuesSearchSelected ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, AddIndexButton, {}) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, AddKeyModal, {})
8869
+ ] })
8870
+ ] });
8871
+ };
8872
+ var IndexSelector = () => {
8873
+ const {
8874
+ valuesSearch: { index },
8875
+ setValuesSearchIndex
8876
+ } = useTab();
8877
+ const { data: indexes, isLoading } = useFetchSearchIndexes();
8878
+ const [open, setOpen] = _react.useState.call(void 0, false);
8879
+ _react.useEffect.call(void 0, () => {
8880
+ if (!indexes || isLoading) return;
8881
+ if (index && !indexes.includes(index)) {
8882
+ setValuesSearchIndex("");
8883
+ } else if (!index && indexes.length > 0) {
8884
+ setValuesSearchIndex(indexes[0]);
8885
+ }
8886
+ }, [indexes, index, isLoading, setValuesSearchIndex]);
8887
+ const [search, setSearch] = _react.useState.call(void 0, "");
8888
+ const [editingIndex, setEditingIndex] = _react.useState.call(void 0, );
8889
+ const filteredIndexes = _optionalChain([indexes, 'optionalAccess', _102 => _102.filter, 'call', _103 => _103((idx) => idx.toLowerCase().includes(search.toLowerCase()))]);
8890
+ const handleEditIndex = (indexName) => {
8891
+ setOpen(false);
8892
+ setEditingIndex(indexName);
8893
+ };
8894
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex", children: [
8895
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex items-center rounded-l-lg border border-r-0 border-zinc-300 bg-white px-3 text-sm text-zinc-700", children: "Index" }),
8896
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
8897
+ Popover,
8898
+ {
8899
+ open,
8900
+ onOpenChange: (isOpen) => {
8901
+ setOpen(isOpen);
8902
+ if (!isOpen) setSearch("");
8903
+ },
8904
+ modal: false,
8905
+ children: [
8906
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, PopoverTrigger, { asChild: true, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "button", { className: "flex min-w-[140px] items-center justify-between gap-2 rounded-r-lg border border-zinc-300 bg-emerald-50 px-3 py-[5px] text-sm font-medium text-emerald-800 transition-colors hover:bg-emerald-100", children: [
8907
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "truncate", children: index || "Select an index" }),
8908
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _iconsreact.IconChevronDown, { className: "size-4 shrink-0 opacity-50" })
8909
+ ] }) }),
8910
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, PopoverContent, { className: "p-2", align: "center", children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col gap-2", children: [
8911
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, CreateIndexButton, {}),
8912
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "h-px bg-zinc-100" }),
8913
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex h-9 items-center rounded-md border border-zinc-300 px-2", children: [
8914
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _iconsreact.IconSearch, { className: "size-5 text-zinc-400" }),
8915
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
8916
+ "input",
8917
+ {
8918
+ value: search,
8919
+ onChange: (e) => setSearch(e.target.value),
8920
+ placeholder: "Search Index",
8921
+ className: "flex h-full w-full bg-transparent px-2 py-3 text-sm outline-none placeholder:text-zinc-400"
8922
+ }
8923
+ )
8924
+ ] }),
8925
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "max-h-[200px] overflow-y-auto", children: [
8926
+ _optionalChain([filteredIndexes, 'optionalAccess', _104 => _104.length]) === 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "py-4 text-center text-sm text-zinc-500", children: "No indexes found" }),
8927
+ _optionalChain([filteredIndexes, 'optionalAccess', _105 => _105.map, 'call', _106 => _106((idx) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
8928
+ "div",
8929
+ {
8930
+ className: "flex h-9 items-center rounded-md px-2 transition-colors hover:bg-zinc-100 dark:hover:bg-zinc-200",
8931
+ children: [
8932
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
8933
+ "button",
8934
+ {
8935
+ onClick: () => {
8936
+ setValuesSearchIndex(idx);
8937
+ setOpen(false);
8938
+ },
8939
+ className: "flex flex-1 items-center gap-2 text-left text-sm",
8940
+ children: [
8941
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
8942
+ "span",
8943
+ {
8944
+ className: cn(
8945
+ "flex size-5 items-center justify-center",
8946
+ idx === index ? "text-emerald-600" : "text-transparent"
8947
+ ),
8948
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _iconsreact.IconCircleCheck, { className: "size-5" })
8949
+ }
8950
+ ),
8951
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "truncate", children: idx })
8952
+ ]
8953
+ }
8954
+ ),
8955
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
8956
+ "button",
8957
+ {
8958
+ onClick: (event) => {
8959
+ event.stopPropagation();
8960
+ event.preventDefault();
8961
+ handleEditIndex(idx);
8962
+ },
8963
+ className: "ml-2 text-sm text-zinc-500 underline hover:text-zinc-700",
8964
+ children: "Edit"
8965
+ }
8966
+ )
8967
+ ]
8968
+ },
8969
+ idx
8970
+ ))])
8971
+ ] })
8972
+ ] }) })
8973
+ ]
8974
+ }
8975
+ ),
8976
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
8977
+ EditIndexModal,
8978
+ {
8979
+ open: Boolean(editingIndex),
8980
+ onOpenChange: (isOpen) => !isOpen && setEditingIndex(void 0),
8981
+ indexName: editingIndex
8982
+ }
8983
+ )
8984
+ ] });
8985
+ };
8986
+ var CreateIndexButton = () => {
8987
+ const [open, setOpen] = _react.useState.call(void 0, false);
8988
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
8989
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
8990
+ "button",
8991
+ {
8992
+ onClick: (e) => {
8993
+ e.stopPropagation();
8994
+ setOpen(true);
8995
+ },
8996
+ className: "flex h-9 w-full items-center gap-2 rounded-md px-2 text-sm text-emerald-600 transition-colors hover:bg-zinc-100 dark:hover:bg-zinc-200",
8997
+ children: [
8998
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _iconsreact.IconCirclePlus, { className: "size-5" }),
8999
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "underline", children: "Create a new Index" })
9000
+ ]
9001
+ }
9002
+ ),
9003
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, CreateIndexModal, { open, onOpenChange: setOpen })
9004
+ ] });
8081
9005
  };
8082
-
8083
- export type DescribeFieldInfo = {
8084
- type: FieldType;
8085
- noTokenize?: boolean;
8086
- noStem?: boolean;
8087
- fast?: boolean;
9006
+ var AddIndexButton = () => {
9007
+ const [open, setOpen] = _react.useState.call(void 0, false);
9008
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
9009
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, SimpleTooltip, { content: "Create new Index", children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
9010
+ Button,
9011
+ {
9012
+ variant: "primary",
9013
+ onClick: () => setOpen(true),
9014
+ className: "flex h-8 select-none items-center gap-1 rounded-lg pl-2 pr-3 text-sm font-medium",
9015
+ children: [
9016
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _iconsreact.IconPlus, { className: "size-5" }),
9017
+ "Index"
9018
+ ]
9019
+ }
9020
+ ) }),
9021
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, CreateIndexModal, { open, onOpenChange: setOpen })
9022
+ ] });
9023
+ };
9024
+ var WizardButton = () => {
9025
+ const queryWizard = useQueryWizardFn();
9026
+ const [open, setOpen] = _react.useState.call(void 0, false);
9027
+ if (!queryWizard) return null;
9028
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, Popover, { open, onOpenChange: setOpen, modal: false, children: [
9029
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, SimpleTooltip, { content: "Query Wizard", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, PopoverTrigger, { asChild: true, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Button, { size: "icon", "aria-label": "Query Wizard", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _iconsreact.IconSparkles, { className: "size-4 text-zinc-500" }) }) }) }),
9030
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
9031
+ PopoverContent,
9032
+ {
9033
+ side: "bottom",
9034
+ align: "end",
9035
+ alignOffset: -124,
9036
+ avoidCollisions: false,
9037
+ className: "w-auto p-0",
9038
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, QueryWizardPopover, { onClose: () => setOpen(false) })
9039
+ }
9040
+ )
9041
+ ] });
8088
9042
  };
8089
9043
 
8090
- export type IndexDescription<TSchema extends NestedIndexSchema | FlatIndexSchema> = {
8091
- name: string;
8092
- dataType: "hash" | "string" | "json";
8093
- prefixes: string[];
8094
- language?: Language;
8095
- schema: Record<SchemaPaths<TSchema>, DescribeFieldInfo>;
9044
+ // src/components/databrowser/components/header-error.tsx
9045
+
9046
+ var HeaderError = () => {
9047
+ const { query } = useKeys();
9048
+ if (!query.error) return null;
9049
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-sm text-red-600 dark:text-red-400", children: formatUpstashErrorMessage(query.error) });
8096
9050
  };
8097
9051
 
8098
- export type Language =
8099
- | "english"
8100
- | "arabic"
8101
- | "danish"
8102
- | "dutch"
8103
- | "finnish"
8104
- | "french"
8105
- | "german"
8106
- | "greek"
8107
- | "hungarian"
8108
- | "italian"
8109
- | "norwegian"
8110
- | "portuguese"
8111
- | "romanian"
8112
- | "russian"
8113
- | "spanish"
8114
- | "swedish"
8115
- | "tamil"
8116
- | "turkish";
9052
+ // src/components/databrowser/components/search/query-editor.tsx
8117
9053
 
8118
- `;
8119
9054
 
8120
9055
  // src/components/databrowser/components/search/generate-query-type-definitions.tsx
8121
9056
  var buildNestedSchema = (flatSchema) => {
@@ -8148,7 +9083,7 @@ var generateNestedInterface = (obj, indent = " ") => {
8148
9083
  var toAmbientTypes = (types) => types.replaceAll(/export const (\w+) = (\[.*?]) as const;/g, "declare const $1: readonly $2;").replaceAll("export ", "");
8149
9084
  var generateTypeDefinitions = (schema) => {
8150
9085
  let schemaFieldsInterface = "";
8151
- const schemaFields = _optionalChain([schema, 'optionalAccess', _89 => _89.schema]);
9086
+ const schemaFields = _optionalChain([schema, 'optionalAccess', _107 => _107.schema]);
8152
9087
  if (schemaFields && Object.keys(schemaFields).length > 0) {
8153
9088
  const nested = buildNestedSchema(schemaFields);
8154
9089
  const fieldLines = generateNestedInterface(nested);
@@ -8203,32 +9138,57 @@ var QueryBuilder = () => {
8203
9138
  const { valuesSearch, setValuesSearchQuery } = useTab();
8204
9139
  const { data: indexDetails } = useFetchSearchIndex(valuesSearch.index);
8205
9140
  const editorValue = PREFIX + (valuesSearch.query || "{}");
8206
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex h-full flex-col rounded-lg border border-zinc-300 bg-white px-[6px]", children: [
8207
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "min-h-0 flex-1", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
8208
- QueryEditor,
8209
- {
8210
- value: editorValue,
8211
- onChange: (value) => {
8212
- const queryPart = value.slice(PREFIX.length);
8213
- setValuesSearchQuery(queryPart);
8214
- },
8215
- schema: indexDetails
8216
- }
8217
- ) }),
8218
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex items-center justify-end px-2 pb-1.5", children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
8219
- "a",
8220
- {
8221
- href: "https://upstash-search.mintlify.app/redis/search/query-operators/boolean-operators/overview",
8222
- target: "_blank",
8223
- rel: "noopener noreferrer",
8224
- className: "flex items-center gap-1 text-xs text-zinc-400 transition-colors hover:text-zinc-600",
8225
- children: [
8226
- "Docs",
8227
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _iconsreact.IconExternalLink, { size: 12 })
8228
- ]
9141
+ if (!indexDetails) return;
9142
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex h-full flex-col rounded-lg border border-zinc-300 bg-white px-[6px]", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "relative min-h-0 flex-1", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "absolute inset-0", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
9143
+ QueryEditor,
9144
+ {
9145
+ value: editorValue,
9146
+ onChange: (value) => {
9147
+ const queryPart = value.slice(PREFIX.length);
9148
+ setValuesSearchQuery(queryPart);
9149
+ },
9150
+ schema: indexDetails
9151
+ }
9152
+ ) }) }) });
9153
+ };
9154
+
9155
+ // src/components/databrowser/components/query-builder-error.tsx
9156
+
9157
+
9158
+ var ERROR_TIMEOUT = 5e3;
9159
+ var QueryBuilderError = ({
9160
+ error,
9161
+ autoHide
9162
+ }) => {
9163
+ const [visible, setVisible] = _react.useState.call(void 0, false);
9164
+ const [displayedError, setDisplayedError] = _react.useState.call(void 0, );
9165
+ _react.useEffect.call(void 0, () => {
9166
+ let timeout;
9167
+ if (error) {
9168
+ setDisplayedError(error);
9169
+ setVisible(true);
9170
+ if (autoHide) {
9171
+ timeout = setTimeout(() => setVisible(false), ERROR_TIMEOUT);
8229
9172
  }
8230
- ) })
8231
- ] });
9173
+ } else {
9174
+ setVisible(false);
9175
+ }
9176
+ return () => clearTimeout(timeout);
9177
+ }, [error, autoHide]);
9178
+ if (!displayedError) return;
9179
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
9180
+ "p",
9181
+ {
9182
+ className: cn(
9183
+ "absolute bottom-2 left-2 z-[2] max-w-[70%] rounded-md bg-red-50 px-3 py-1.5 text-sm text-red-600 shadow-sm",
9184
+ visible ? "duration-200 animate-in fade-in slide-in-from-bottom-1" : "duration-200 animate-out fade-out slide-out-to-bottom-1 fill-mode-forwards"
9185
+ ),
9186
+ onAnimationEnd: () => {
9187
+ if (!visible) setDisplayedError(void 0);
9188
+ },
9189
+ children: displayedError
9190
+ }
9191
+ );
8232
9192
  };
8233
9193
 
8234
9194
  // src/components/databrowser/components/search-empty-state.tsx
@@ -8389,7 +9349,7 @@ var ImportSampleDatasetModal = ({
8389
9349
  if (await index.describe()) {
8390
9350
  await index.drop();
8391
9351
  }
8392
- } catch (e5) {
9352
+ } catch (e6) {
8393
9353
  }
8394
9354
  await redis.search.createIndex({
8395
9355
  dataType: "string",
@@ -8483,7 +9443,7 @@ var ImportSampleDatasetModal = ({
8483
9443
 
8484
9444
  var SearchEmptyState = () => {
8485
9445
  const [importModalOpen, setImportModalOpen] = _react.useState.call(void 0, false);
8486
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "mx-auto flex h-full max-w-4xl gap-8 rounded-xl border border-zinc-200 bg-gradient-to-b from-zinc-50 to-white p-8", children: [
9446
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "mx-auto flex h-full w-full gap-8 rounded-xl border border-zinc-200 bg-gradient-to-b from-zinc-50 to-white p-8", children: [
8487
9447
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ImportSampleDatasetModal, { open: importModalOpen, onOpenChange: setImportModalOpen }),
8488
9448
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex-1", children: [
8489
9449
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h2", { className: "mb-2 text-lg font-semibold text-zinc-900", children: "Redis Search" }),
@@ -8525,7 +9485,7 @@ var SearchEmptyState = () => {
8525
9485
  }
8526
9486
  )
8527
9487
  ] }),
8528
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex w-72 flex-col items-center justify-center rounded-lg border bg-gradient-to-b from-zinc-50 to-white p-6 shadow-sm", children: [
9488
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex w-[350px] flex-col items-center justify-center rounded-lg border bg-gradient-to-b from-zinc-50 to-white p-6 shadow-sm", children: [
8529
9489
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "mb-4 flex h-12 w-12 items-center justify-center rounded-xl bg-emerald-100 text-emerald-600", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _iconsreact.IconSparkles, { size: 24 }) }),
8530
9490
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { className: "mb-1 text-sm font-medium text-zinc-900", children: "Try it out" }),
8531
9491
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "mb-4 text-center text-xs text-zinc-500", children: "Load a sample dataset to explore Redis Search" }),
@@ -8560,7 +9520,7 @@ var Empty = () => {
8560
9520
 
8561
9521
 
8562
9522
  var SidebarContextMenu = ({ children }) => {
8563
- const { mutate: deleteKey } = useDeleteKey();
9523
+ const { mutateAsync: deleteKey } = useDeleteKey();
8564
9524
  const [isAlertOpen, setAlertOpen] = _react.useState.call(void 0, false);
8565
9525
  const [contextKeys, setContextKeys] = _react.useState.call(void 0, []);
8566
9526
  const {
@@ -8569,7 +9529,7 @@ var SidebarContextMenu = ({ children }) => {
8569
9529
  selectTab,
8570
9530
  setSearch
8571
9531
  } = useDatabrowserStore();
8572
- const { search: currentSearch, selectedKeys } = useTab();
9532
+ const { search: currentSearch, selectedKeys, isValuesSearchSelected } = useTab();
8573
9533
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
8574
9534
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
8575
9535
  DeleteKeyModal,
@@ -8578,11 +9538,10 @@ var SidebarContextMenu = ({ children }) => {
8578
9538
  count: contextKeys.length,
8579
9539
  open: isAlertOpen,
8580
9540
  onOpenChange: setAlertOpen,
8581
- onDeleteConfirm: (e) => {
9541
+ showReindex: isValuesSearchSelected,
9542
+ onDeleteConfirm: async (e, options) => {
8582
9543
  e.stopPropagation();
8583
- for (const key of contextKeys) {
8584
- deleteKey(key);
8585
- }
9544
+ await deleteKey({ keys: contextKeys, reindex: _optionalChain([options, 'optionalAccess', _108 => _108.reindex]) });
8586
9545
  setAlertOpen(false);
8587
9546
  }
8588
9547
  }
@@ -8745,14 +9704,14 @@ var LoadingSkeleton = () => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div",
8745
9704
 
8746
9705
  function Sidebar() {
8747
9706
  const { keys, query } = useKeys();
8748
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex h-full flex-col gap-2", children: query.isLoading && keys.length === 0 ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, LoadingSkeleton, {}) : keys.length > 0 ? (
9707
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "relative flex h-full flex-col gap-2", children: query.isLoading && keys.length === 0 ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, LoadingSkeleton, {}) : keys.length > 0 ? (
8749
9708
  // Infinite scroll already has a loader at the bottom
8750
9709
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
8751
9710
  InfiniteScroll,
8752
9711
  {
8753
9712
  query,
8754
9713
  disableRoundedInherit: true,
8755
- className: "min-h-0 rounded-xl bg-zinc-100 px-2 py-5 pr-4 dark:bg-zinc-200",
9714
+ className: "h-full min-h-0 rounded-xl bg-zinc-100 px-2 py-5 pr-4 dark:bg-zinc-200",
8756
9715
  scrollBarClassName: "py-5",
8757
9716
  children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, KeysList, {})
8758
9717
  }
@@ -8767,21 +9726,13 @@ function Sidebar() {
8767
9726
 
8768
9727
 
8769
9728
  // src/components/databrowser/components/ui-query-builder/types.ts
8770
- var STRING_OPERATORS = [
8771
- "eq",
8772
- "ne",
8773
- "in",
8774
- "phrase",
8775
- "regex",
8776
- "fuzzy",
8777
- "smart"
8778
- ];
8779
- var NUMBER_OPERATORS = ["eq", "ne", "gt", "gte", "lt", "lte", "in"];
8780
- var BOOLEAN_OPERATORS = ["eq", "ne", "in"];
8781
- var DATE_OPERATORS = ["eq", "ne", "gt", "gte", "lt", "lte", "in"];
9729
+ var STRING_OPERATORS = ["smart", "eq", "in", "phrase", "regex", "fuzzy"];
9730
+ var NUMBER_OPERATORS = ["eq", "gt", "gte", "lt", "lte"];
9731
+ var BOOLEAN_OPERATORS = ["eq"];
9732
+ var DATE_OPERATORS = NUMBER_OPERATORS;
8782
9733
  var ALL_OPERATORS = [
9734
+ "smart",
8783
9735
  "eq",
8784
- "ne",
8785
9736
  "gt",
8786
9737
  "gte",
8787
9738
  "lt",
@@ -8789,12 +9740,23 @@ var ALL_OPERATORS = [
8789
9740
  "in",
8790
9741
  "phrase",
8791
9742
  "regex",
8792
- "fuzzy",
8793
- "smart"
9743
+ "fuzzy"
8794
9744
  ];
9745
+ var OPERATOR_DESCRIPTIONS = {
9746
+ eq: "Equals",
9747
+ gt: "Greater than",
9748
+ gte: "Greater than or equal",
9749
+ lt: "Less than",
9750
+ lte: "Less than or equal",
9751
+ in: "Matches any of the given values, comma separated",
9752
+ phrase: "Matches an exact phrase",
9753
+ regex: "Matches a regular expression pattern",
9754
+ fuzzy: "Approximate match with custom edit distance",
9755
+ smart: "Default opinionated matching algorithm"
9756
+ };
8795
9757
  var OPERATOR_OPTIONS = [
9758
+ { value: "smart", label: "smart" },
8796
9759
  { value: "eq", label: "eq" },
8797
- { value: "ne", label: "ne" },
8798
9760
  { value: "gt", label: "gt" },
8799
9761
  { value: "gte", label: "gte" },
8800
9762
  { value: "lt", label: "lt" },
@@ -8802,8 +9764,7 @@ var OPERATOR_OPTIONS = [
8802
9764
  { value: "in", label: "in" },
8803
9765
  { value: "phrase", label: "phrase" },
8804
9766
  { value: "regex", label: "regex" },
8805
- { value: "fuzzy", label: "fuzzy" },
8806
- { value: "smart", label: "smart" }
9767
+ { value: "fuzzy", label: "fuzzy" }
8807
9768
  ];
8808
9769
  var getOperatorsForFieldType = (fieldType) => {
8809
9770
  switch (fieldType) {
@@ -8845,7 +9806,7 @@ var hasMustShouldCombination = (queryString) => {
8845
9806
  const obj = parseJSObjectLiteral(queryString);
8846
9807
  if (!obj) return false;
8847
9808
  return hasMustShouldCombinationInObject(obj);
8848
- } catch (e6) {
9809
+ } catch (e7) {
8849
9810
  return false;
8850
9811
  }
8851
9812
  };
@@ -8871,12 +9832,13 @@ var isFieldConditionObject = (obj) => {
8871
9832
  };
8872
9833
  var parseFieldCondition = (field, fieldValue) => {
8873
9834
  if (!isFieldConditionObject(fieldValue)) {
9835
+ const operator2 = typeof fieldValue === "boolean" || typeof fieldValue === "number" ? "eq" : "smart";
8874
9836
  return {
8875
9837
  id: generateId(),
8876
9838
  type: "condition",
8877
9839
  condition: {
8878
9840
  field,
8879
- operator: "eq",
9841
+ operator: operator2,
8880
9842
  value: fieldValue
8881
9843
  }
8882
9844
  };
@@ -8907,20 +9869,23 @@ var parseFieldCondition = (field, fieldValue) => {
8907
9869
  break;
8908
9870
  }
8909
9871
  }
9872
+ if (operator === "smart" && (typeof value === "boolean" || typeof value === "number")) {
9873
+ operator = "eq";
9874
+ }
8910
9875
  if ("$boost" in fieldObj) {
8911
9876
  boost = fieldObj.$boost;
8912
9877
  }
8913
9878
  return {
8914
9879
  id: generateId(),
8915
9880
  type: "condition",
9881
+ boost,
8916
9882
  condition: {
8917
9883
  field,
8918
9884
  operator,
8919
9885
  value,
8920
9886
  fuzzyDistance,
8921
9887
  phraseSlop,
8922
- phrasePrefix,
8923
- boost
9888
+ phrasePrefix
8924
9889
  }
8925
9890
  };
8926
9891
  };
@@ -8930,6 +9895,10 @@ var parseMultiFieldObject = (obj, operator) => {
8930
9895
  for (const [key, value] of Object.entries(obj)) {
8931
9896
  if (key === "$boost") {
8932
9897
  boost = value;
9898
+ } else if (key === "$and" || key === "$or") {
9899
+ const nestedOp = key === "$and" ? "and" : "or";
9900
+ const nestedGroup = parseGroup(value, nestedOp);
9901
+ if (nestedGroup) children.push(nestedGroup);
8933
9902
  } else if (!isOperatorKey(key)) {
8934
9903
  children.push(parseFieldCondition(key, value));
8935
9904
  }
@@ -9000,11 +9969,29 @@ var objectToQueryNode = (obj) => {
9000
9969
  const operator = "$and" in obj ? "and" : "or";
9001
9970
  const groupValue = _nullishCoalesce(obj["$and"], () => ( obj["$or"]));
9002
9971
  const boost = "$boost" in obj ? obj.$boost : void 0;
9003
- const groupNode = parseGroup(groupValue, operator, boost);
9972
+ const groupNode = parseGroup(
9973
+ groupValue,
9974
+ operator,
9975
+ nonOperatorKeys.length === 0 ? boost : void 0
9976
+ );
9004
9977
  if (groupNode && groupNode.type === "group" && hasMustNot) {
9005
9978
  addMustNotChildren(groupNode, obj.$mustNot);
9006
9979
  }
9007
- return groupNode;
9980
+ if (!groupNode || nonOperatorKeys.length === 0) {
9981
+ return groupNode;
9982
+ }
9983
+ const fieldChildren = nonOperatorKeys.map((key) => parseFieldCondition(key, obj[key]));
9984
+ const group = {
9985
+ id: generateId(),
9986
+ type: "group",
9987
+ groupOperator: "and",
9988
+ children: [...fieldChildren, groupNode],
9989
+ boost
9990
+ };
9991
+ if (hasMustNot) {
9992
+ addMustNotChildren(group, obj.$mustNot);
9993
+ }
9994
+ return group;
9008
9995
  }
9009
9996
  if (hasMustNot) {
9010
9997
  if (nonOperatorKeys.length > 0) {
@@ -9053,7 +10040,7 @@ var parseQueryStringWithError = (queryString) => {
9053
10040
  }
9054
10041
  return { success: true, state: { root: root2 } };
9055
10042
  }
9056
- } catch (e7) {
10043
+ } catch (e8) {
9057
10044
  }
9058
10045
  return { success: false, error: "Failed to parse query" };
9059
10046
  };
@@ -9240,8 +10227,7 @@ var moveNodeInTree = (root2, nodeId, newParentId, newIndex) => {
9240
10227
 
9241
10228
 
9242
10229
 
9243
- // src/components/databrowser/components/ui-query-builder/condition-common.tsx
9244
-
10230
+ // src/components/databrowser/components/ui-query-builder/boost-badge.tsx
9245
10231
 
9246
10232
 
9247
10233
  // src/components/databrowser/components/ui-query-builder/dynamic-width-input.tsx
@@ -9294,7 +10280,7 @@ var DynamicWidthInput = ({
9294
10280
  );
9295
10281
  };
9296
10282
 
9297
- // src/components/databrowser/components/ui-query-builder/condition-common.tsx
10283
+ // src/components/databrowser/components/ui-query-builder/boost-badge.tsx
9298
10284
 
9299
10285
  var BoostBadge = ({
9300
10286
  node,
@@ -9325,7 +10311,13 @@ var BoostBadge = ({
9325
10311
  const labelBg = isNegative ? "bg-red-50" : "bg-purple-50";
9326
10312
  const textColor = isNegative ? "text-red-800" : "text-purple-800";
9327
10313
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { className: "relative flex h-[26px] items-center overflow-hidden rounded-md border border-zinc-300 text-sm font-medium", children: [
9328
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: `flex h-full items-center px-2 ${labelBg} ${textColor}`, children: isNegative ? "Demote" : "Boost" }),
10314
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, Tooltip, { delayDuration: 200, children: [
10315
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, TooltipTrigger, { asChild: true, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: `flex h-full cursor-default items-center px-2 ${labelBg} ${textColor}`, children: isNegative ? "Demote" : "Boost" }) }),
10316
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, TooltipContent, { side: "bottom", className: "max-w-xs", children: [
10317
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { children: isNegative ? `Multiplies this condition's score by ${_nullishCoalesce(node.boost, () => ( 0))}, subtracting from the total.` : `Multiplies this condition's score by ${_nullishCoalesce(node.boost, () => ( 0))}.` }),
10318
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, DocsLink, { href: "https://upstash-search.mintlify.app/redis/search/query-operators/boolean-operators/boost" })
10319
+ ] })
10320
+ ] }),
9329
10321
  isStatic ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: `px-2 ${textColor}`, children: node.boost }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "flex h-full items-center bg-white px-2", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
9330
10322
  DynamicWidthInput,
9331
10323
  {
@@ -9339,7 +10331,33 @@ var BoostBadge = ({
9339
10331
  ) })
9340
10332
  ] });
9341
10333
  };
10334
+
10335
+ // src/components/databrowser/components/ui-query-builder/dnd-context.tsx
10336
+
10337
+
10338
+
10339
+
10340
+
10341
+
10342
+
10343
+ var _core = require('@dnd-kit/core');
10344
+
10345
+ // src/components/databrowser/components/ui-query-builder/drag-overlay.tsx
10346
+
10347
+
10348
+
10349
+ // src/components/databrowser/components/ui-query-builder/not-badge.tsx
10350
+
9342
10351
  var NotBadge = () => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "flex h-[26px] items-center rounded-md border border-zinc-300 bg-amber-50 px-2 text-sm font-medium text-amber-800", children: "Not" });
10352
+
10353
+ // src/components/databrowser/components/ui-query-builder/query-condition.tsx
10354
+
10355
+
10356
+
10357
+ // src/components/databrowser/components/ui-query-builder/node-actions-menu.tsx
10358
+
10359
+
10360
+
9343
10361
  var NodeActionsMenu = ({ node }) => {
9344
10362
  const { updateNode } = useQueryBuilderUI();
9345
10363
  const [open, setOpen] = _react.useState.call(void 0, false);
@@ -9393,24 +10411,8 @@ var NodeActionsMenu = ({ node }) => {
9393
10411
  ] });
9394
10412
  };
9395
10413
 
9396
- // src/components/databrowser/components/ui-query-builder/dnd-context.tsx
9397
-
9398
-
9399
-
9400
-
9401
-
9402
-
9403
-
9404
- var _core = require('@dnd-kit/core');
9405
-
9406
- // src/components/databrowser/components/ui-query-builder/drag-overlay.tsx
9407
-
9408
-
9409
-
9410
10414
  // src/components/databrowser/components/ui-query-builder/query-condition.tsx
9411
10415
 
9412
-
9413
-
9414
10416
  var formatValueForDisplay = (value) => {
9415
10417
  if (Array.isArray(value)) {
9416
10418
  return value.join(", ");
@@ -9435,7 +10437,7 @@ var QueryCondition = ({
9435
10437
  setLocalValue(formattedConditionValue);
9436
10438
  }
9437
10439
  const currentFieldInfo = fieldInfos.find((f) => f.name === condition.field);
9438
- const currentFieldType = _nullishCoalesce(_optionalChain([currentFieldInfo, 'optionalAccess', _90 => _90.type]), () => ( "unknown"));
10440
+ const currentFieldType = _nullishCoalesce(_optionalChain([currentFieldInfo, 'optionalAccess', _109 => _109.type]), () => ( "unknown"));
9439
10441
  const isUnknownField = condition.field && !fieldNames.includes(condition.field);
9440
10442
  const getValueTypeError = () => {
9441
10443
  if (isUnknownField || currentFieldType === "unknown" || currentFieldType === "string") {
@@ -9493,8 +10495,8 @@ var QueryCondition = ({
9493
10495
  }
9494
10496
  }, [currentFieldType, condition.value]);
9495
10497
  const handleFieldChange = (value) => {
9496
- const newFieldInfo = _optionalChain([fieldInfos, 'optionalAccess', _91 => _91.find, 'call', _92 => _92((f) => f.name === value)]);
9497
- const newFieldType = _nullishCoalesce(_optionalChain([newFieldInfo, 'optionalAccess', _93 => _93.type]), () => ( "unknown"));
10498
+ const newFieldInfo = _optionalChain([fieldInfos, 'optionalAccess', _110 => _110.find, 'call', _111 => _111((f) => f.name === value)]);
10499
+ const newFieldType = _nullishCoalesce(_optionalChain([newFieldInfo, 'optionalAccess', _112 => _112.type]), () => ( "unknown"));
9498
10500
  const validOperators = getOperatorsForFieldType(newFieldType);
9499
10501
  const isOperatorValid = validOperators.includes(condition.operator);
9500
10502
  let newValue = condition.value;
@@ -9635,10 +10637,10 @@ var QueryCondition = ({
9635
10637
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
9636
10638
  "div",
9637
10639
  {
9638
- ref: _optionalChain([dragHandleProps, 'optionalAccess', _94 => _94.ref]),
10640
+ ref: _optionalChain([dragHandleProps, 'optionalAccess', _113 => _113.ref]),
9639
10641
  className: "flex cursor-grab items-center px-1 text-zinc-400 hover:text-zinc-600",
9640
- ..._optionalChain([dragHandleProps, 'optionalAccess', _95 => _95.attributes]),
9641
- ..._optionalChain([dragHandleProps, 'optionalAccess', _96 => _96.listeners]),
10642
+ ..._optionalChain([dragHandleProps, 'optionalAccess', _114 => _114.attributes]),
10643
+ ..._optionalChain([dragHandleProps, 'optionalAccess', _115 => _115.listeners]),
9642
10644
  children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _iconsreact.IconGripVertical, { size: 16 })
9643
10645
  }
9644
10646
  ),
@@ -9681,7 +10683,15 @@ var QueryCondition = ({
9681
10683
  },
9682
10684
  condition.operator
9683
10685
  ),
9684
- filteredOperators.map((op) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, SelectItem, { value: op.value, children: op.label }, op.value))
10686
+ filteredOperators.map((op) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
10687
+ SelectItem,
10688
+ {
10689
+ value: op.value,
10690
+ description: OPERATOR_DESCRIPTIONS[op.value],
10691
+ children: op.label
10692
+ },
10693
+ op.value
10694
+ ))
9685
10695
  ] })
9686
10696
  ] }),
9687
10697
  currentFieldType === "boolean" && condition.operator === "in" ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex h-[26px] items-center gap-2 rounded-none rounded-r-md border border-zinc-200 bg-white px-2 text-sm", children: [
@@ -9763,8 +10773,15 @@ var QueryCondition = ({
9763
10773
  children: [
9764
10774
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, SelectTrigger, { className: "h-[26px] w-16 gap-3 border-zinc-200 bg-white px-2 text-sm", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, SelectValue, {}) }),
9765
10775
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, SelectContent, { children: [
9766
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, SelectItem, { value: "1", children: "1" }),
9767
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, SelectItem, { value: "2", children: "2" })
10776
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
10777
+ SelectItem,
10778
+ {
10779
+ value: "1",
10780
+ description: "Matches words with 1 character edit (e.g. 'teh' \u2192 'the')",
10781
+ children: "1"
10782
+ }
10783
+ ),
10784
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, SelectItem, { value: "2", description: "Matches words with up to 2 character edits", children: "2" })
9768
10785
  ] })
9769
10786
  ]
9770
10787
  }
@@ -9773,9 +10790,23 @@ var QueryCondition = ({
9773
10790
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, Select, { value: phraseMode, onValueChange: handlePhraseModeChange, children: [
9774
10791
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, SelectTrigger, { className: "h-[26px] w-20 gap-3 border-zinc-200 bg-white px-2 text-sm font-normal", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, SelectValue, {}) }),
9775
10792
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, SelectContent, { children: [
9776
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, SelectItem, { value: "exact", children: "exact" }),
9777
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, SelectItem, { value: "slop", children: "slop" }),
9778
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, SelectItem, { value: "prefix", children: "prefix" })
10793
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, SelectItem, { value: "exact", description: "Terms must appear adjacent to each other", children: "exact" }),
10794
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
10795
+ SelectItem,
10796
+ {
10797
+ value: "slop",
10798
+ description: "Allow custom number of intervening words between terms",
10799
+ children: "slop"
10800
+ }
10801
+ ),
10802
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
10803
+ SelectItem,
10804
+ {
10805
+ value: "prefix",
10806
+ description: "Last term matches as a prefix (e.g. 'wireless head' \u2192 'headphones')",
10807
+ children: "prefix"
10808
+ }
10809
+ )
9779
10810
  ] })
9780
10811
  ] }),
9781
10812
  phraseMode === "slop" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
@@ -9791,6 +10822,7 @@ var QueryCondition = ({
9791
10822
  }
9792
10823
  )
9793
10824
  ] }),
10825
+ node.not && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, NotBadge, {}),
9794
10826
  node.boost !== void 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, BoostBadge, { node }),
9795
10827
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
9796
10828
  "div",
@@ -10027,6 +11059,7 @@ var DraggableItem = ({
10027
11059
  // src/components/databrowser/components/ui-query-builder/drop-zone.tsx
10028
11060
 
10029
11061
 
11062
+
10030
11063
  var DropIndicator = ({ id, isOver }) => {
10031
11064
  const { setNodeRef } = _core.useDroppable.call(void 0, { id });
10032
11065
  return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { ref: setNodeRef, className: `relative flex h-2 items-center`, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
@@ -10039,14 +11072,26 @@ var DropIndicator = ({ id, isOver }) => {
10039
11072
  }
10040
11073
  ) });
10041
11074
  };
10042
- var EmptyGroupDropZone = ({ groupId, isOver }) => {
11075
+ var EmptyGroupDropZone = ({
11076
+ groupId,
11077
+ isOver,
11078
+ onAddCondition
11079
+ }) => {
10043
11080
  const { setNodeRef } = _core.useDroppable.call(void 0, { id: `drop-${groupId}-end` });
10044
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
10045
- "div",
11081
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
11082
+ "button",
10046
11083
  {
11084
+ type: "button",
10047
11085
  ref: setNodeRef,
10048
- className: `mt-2 flex h-8 items-center justify-center rounded-md border border-dashed text-sm transition-all ${isOver ? "border-blue-500 bg-blue-50 text-blue-600" : "border-zinc-300 text-zinc-400"}`,
10049
- children: "Add a condition to start"
11086
+ onClick: onAddCondition,
11087
+ className: cn(
11088
+ "mt-2 flex h-8 w-full items-center justify-center gap-1.5 rounded-md border border-dashed text-sm transition-all",
11089
+ isOver ? "border-blue-500 bg-blue-50 text-blue-600" : "border-zinc-300 text-zinc-400 hover:border-zinc-400 hover:bg-zinc-50 hover:text-zinc-500"
11090
+ ),
11091
+ children: [
11092
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _iconsreact.IconPlus, { size: 14 }),
11093
+ "Add a condition"
11094
+ ]
10050
11095
  }
10051
11096
  );
10052
11097
  };
@@ -10093,9 +11138,7 @@ var InnerGroup = ({
10093
11138
  addChildToGroup(node.id, createEmptyCondition(fieldInfos));
10094
11139
  };
10095
11140
  const handleAddGroup = () => {
10096
- const newGroup = createEmptyGroup("and");
10097
- newGroup.children = [createEmptyCondition(fieldInfos)];
10098
- addChildToGroup(node.id, newGroup);
11141
+ addChildToGroup(node.id, createEmptyGroup("and"));
10099
11142
  };
10100
11143
  const handleDeleteGroup = () => {
10101
11144
  deleteNode(node.id);
@@ -10105,10 +11148,10 @@ var InnerGroup = ({
10105
11148
  !isRoot && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
10106
11149
  "div",
10107
11150
  {
10108
- ref: _optionalChain([dragHandleProps, 'optionalAccess', _97 => _97.ref]),
11151
+ ref: _optionalChain([dragHandleProps, 'optionalAccess', _116 => _116.ref]),
10109
11152
  className: "flex cursor-grab items-center px-1 text-zinc-400",
10110
- ..._optionalChain([dragHandleProps, 'optionalAccess', _98 => _98.attributes]),
10111
- ..._optionalChain([dragHandleProps, 'optionalAccess', _99 => _99.listeners]),
11153
+ ..._optionalChain([dragHandleProps, 'optionalAccess', _117 => _117.attributes]),
11154
+ ..._optionalChain([dragHandleProps, 'optionalAccess', _118 => _118.listeners]),
10112
11155
  children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _iconsreact.IconGripVertical, { size: 16 })
10113
11156
  }
10114
11157
  ),
@@ -10134,6 +11177,7 @@ var InnerGroup = ({
10134
11177
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, DropdownMenuItem, { onClick: handleAddGroup, children: "Add Group" })
10135
11178
  ] })
10136
11179
  ] }),
11180
+ node.not && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, NotBadge, {}),
10137
11181
  node.boost !== void 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, BoostBadge, { node }),
10138
11182
  !isRoot && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
10139
11183
  "div",
@@ -10154,7 +11198,14 @@ var InnerGroup = ({
10154
11198
  }
10155
11199
  )
10156
11200
  ] }),
10157
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: `min-h-[20px] ${isRoot ? "" : "ml-[15px] border-l-2 border-zinc-200 pl-3"}`, children: node.children.length === 0 ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, EmptyGroupDropZone, { groupId: node.id, isOver: activeOverId === `drop-${node.id}-end` }) : /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
11201
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: `min-h-[20px] ${isRoot ? "" : "ml-[15px] border-l-2 border-zinc-200 pl-3"}`, children: node.children.length === 0 ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
11202
+ EmptyGroupDropZone,
11203
+ {
11204
+ groupId: node.id,
11205
+ isOver: activeOverId === `drop-${node.id}-end`,
11206
+ onAddCondition: fieldInfos.length > 0 ? handleAddCondition : void 0
11207
+ }
11208
+ ) : /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
10158
11209
  node.children.map(
10159
11210
  (child) => !child.not && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
10160
11211
  ChildRow,
@@ -10170,20 +11221,10 @@ var InnerGroup = ({
10170
11221
  ),
10171
11222
  node.children.some((child) => child.not) && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, Tooltip, { delayDuration: 200, children: [
10172
11223
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, TooltipTrigger, { asChild: true, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "ml-2 mt-2 flex h-[26px] w-fit cursor-default select-none items-center rounded-md border border-zinc-300 bg-amber-50 px-2 text-sm font-medium capitalize text-amber-800", children: "Must Not" }) }),
10173
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, TooltipContent, { side: "right", className: "max-w-xs", children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "p", { children: [
10174
- "Keys matching any of the conditions below are excluded from the results.",
10175
- " ",
10176
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
10177
- "a",
10178
- {
10179
- href: "https://upstash-search.mintlify.app/redis/search/query-operators/boolean-operators/must-not",
10180
- target: "_blank",
10181
- rel: "noopener noreferrer",
10182
- className: "underline",
10183
- children: "Learn more"
10184
- }
10185
- )
10186
- ] }) })
11224
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, TooltipContent, { side: "right", className: "max-w-xs", children: [
11225
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { children: "Keys matching any of the conditions below are excluded from the results." }),
11226
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, DocsLink, { href: "https://upstash-search.mintlify.app/redis/search/query-operators/boolean-operators/must-not" })
11227
+ ] })
10187
11228
  ] }),
10188
11229
  node.children.map(
10189
11230
  (child) => child.not && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
@@ -10248,12 +11289,6 @@ var QueryGroup = ({ node, isRoot = false, depth }) => {
10248
11289
 
10249
11290
 
10250
11291
  // src/components/databrowser/components/ui-query-builder/query-stringify.ts
10251
- var jsonToJsLiteral = (json) => {
10252
- return json.replaceAll(/"([$A-Z_a-z][\w$]*)"\s*:/g, "$1:");
10253
- };
10254
- var toJsLiteral = (obj) => {
10255
- return jsonToJsLiteral(JSON.stringify(obj, null, 2));
10256
- };
10257
11292
  var buildOperatorValue = (operator, value, fuzzyDistance, phraseSlop, phrasePrefix) => {
10258
11293
  if (operator === "fuzzy" && fuzzyDistance) {
10259
11294
  return { value, distance: fuzzyDistance };
@@ -10279,7 +11314,8 @@ var conditionToObject = (node) => {
10279
11314
  phrasePrefix
10280
11315
  } = node.condition;
10281
11316
  const effectiveBoost = _nullishCoalesce(node.boost, () => ( conditionBoost));
10282
- if (operator === "eq" && !effectiveBoost) {
11317
+ const isCollapsibleEq = operator === "eq" && (typeof value === "boolean" || typeof value === "number");
11318
+ if ((operator === "smart" || isCollapsibleEq) && !effectiveBoost) {
10283
11319
  return { [field]: value };
10284
11320
  }
10285
11321
  const fieldCondition = {
@@ -10292,15 +11328,15 @@ var conditionToObject = (node) => {
10292
11328
  return { [field]: fieldCondition };
10293
11329
  };
10294
11330
  var canMergeChildren = (children) => {
10295
- return children.every(
10296
- (child) => child.type === "condition" && !child.not && !child.boost && child.condition.operator === "eq" && !child.condition.boost
10297
- );
11331
+ if (!children.every((child) => child.type === "condition" && !child.not)) return false;
11332
+ const fields = children.map((c) => c.condition.field);
11333
+ return new Set(fields).size === fields.length;
10298
11334
  };
10299
11335
  var mergeConditions = (children, boost) => {
10300
11336
  const merged = {};
10301
11337
  for (const child of children) {
10302
11338
  if (child.type === "condition") {
10303
- merged[child.condition.field] = child.condition.value;
11339
+ Object.assign(merged, conditionToObject(child));
10304
11340
  }
10305
11341
  }
10306
11342
  if (boost && boost !== 1) {
@@ -10308,7 +11344,14 @@ var mergeConditions = (children, boost) => {
10308
11344
  }
10309
11345
  return merged;
10310
11346
  };
10311
- var groupToObject = (node, isRoot) => {
11347
+ var buildMustNot = (negatedChildren) => {
11348
+ const negatedObjects = negatedChildren.map((child) => {
11349
+ const withoutNot = { ...child, not: void 0 };
11350
+ return queryNodeToObject(withoutNot, false);
11351
+ });
11352
+ return negatedObjects.length === 1 ? negatedObjects[0] : negatedObjects;
11353
+ };
11354
+ var groupToObject = (node, isRoot, forArray = false) => {
10312
11355
  const { groupOperator, children, boost, not } = node;
10313
11356
  const normalChildren = children.filter((c) => !c.not);
10314
11357
  const negatedChildren = children.filter((c) => c.not);
@@ -10324,41 +11367,84 @@ var groupToObject = (node, isRoot) => {
10324
11367
  }
10325
11368
  return { $mustNot: [inner] };
10326
11369
  }
10327
- if (isRoot && groupOperator === "and" && normalChildren.length === 1 && negatedChildren.length === 0 && !boost) {
10328
- return queryNodeToObject(normalChildren[0], false);
11370
+ if (isRoot && groupOperator === "and" && negatedChildren.length === 0) {
11371
+ if (normalChildren.length === 1) {
11372
+ const result2 = queryNodeToObject(normalChildren[0], false);
11373
+ if (boost && boost !== 1) result2.$boost = boost;
11374
+ return result2;
11375
+ }
11376
+ const conditionChildren = normalChildren.filter((c) => c.type === "condition");
11377
+ const groupChildren = normalChildren.filter((c) => c.type === "group");
11378
+ const hasConflictingGroupChild = groupChildren.some(
11379
+ (c) => c.groupOperator === groupOperator && c.children.length > 1 && c.boost
11380
+ );
11381
+ if (!hasConflictingGroupChild) {
11382
+ const fields = conditionChildren.map(
11383
+ (c) => c.condition.field
11384
+ );
11385
+ const groupOps = groupChildren.map((c) => `$${c.groupOperator}`);
11386
+ const allKeys = [...fields, ...groupOps];
11387
+ const hasConflicts = new Set(allKeys).size !== allKeys.length;
11388
+ if (!hasConflicts) {
11389
+ const result2 = {};
11390
+ for (const child of conditionChildren) {
11391
+ Object.assign(result2, conditionToObject(child));
11392
+ }
11393
+ for (const child of groupChildren) {
11394
+ Object.assign(result2, groupToObject(child, false));
11395
+ }
11396
+ if (boost && boost !== 1) result2.$boost = boost;
11397
+ return result2;
11398
+ }
11399
+ }
10329
11400
  }
10330
- if (normalChildren.length > 0 && negatedChildren.length === 0 && canMergeChildren(normalChildren)) {
10331
- const merged = mergeConditions(normalChildren, boost);
10332
- if (isRoot && groupOperator === "and") {
10333
- return merged;
11401
+ if (normalChildren.length > 0 && canMergeChildren(normalChildren)) {
11402
+ if (isRoot && groupOperator === "and" && negatedChildren.length === 0) {
11403
+ return mergeConditions(normalChildren, boost);
11404
+ }
11405
+ const result2 = {};
11406
+ if (forArray) {
11407
+ result2[`$${groupOperator}`] = mergeConditions(normalChildren);
11408
+ if (boost && boost !== 1) result2.$boost = boost;
11409
+ } else {
11410
+ result2[`$${groupOperator}`] = mergeConditions(normalChildren, boost);
10334
11411
  }
10335
- const result2 = { [`$${groupOperator}`]: merged };
10336
- if (boost && boost !== 1) {
10337
- result2.$boost = boost;
11412
+ if (negatedChildren.length > 0) {
11413
+ result2.$mustNot = buildMustNot(negatedChildren);
10338
11414
  }
10339
11415
  return result2;
10340
11416
  }
10341
11417
  const result = {};
10342
11418
  if (normalChildren.length > 0) {
10343
- result[`$${groupOperator}`] = normalChildren.map((child) => queryNodeToObject(child, false));
11419
+ result[`$${groupOperator}`] = normalChildren.map((child) => {
11420
+ if (child.type === "group") {
11421
+ const groupChild = child;
11422
+ const gc = groupChild.children;
11423
+ const gcNormal = gc.filter((c) => !c.not);
11424
+ const gcNegated = gc.filter((c) => c.not);
11425
+ if (groupChild.groupOperator === groupOperator && gc.length > 1 && gcNegated.length === 0 && canMergeChildren(gcNormal)) {
11426
+ return mergeConditions(gcNormal, groupChild.boost);
11427
+ }
11428
+ }
11429
+ return queryNodeToObject(child, false, true);
11430
+ });
11431
+ } else if (negatedChildren.length > 0) {
11432
+ result[`$${groupOperator}`] = {};
10344
11433
  }
10345
11434
  if (negatedChildren.length > 0) {
10346
- result.$mustNot = negatedChildren.map((child) => {
10347
- const withoutNot = { ...child, not: void 0 };
10348
- return queryNodeToObject(withoutNot, false);
10349
- });
11435
+ result.$mustNot = buildMustNot(negatedChildren);
10350
11436
  }
10351
11437
  if (boost && boost !== 1) {
10352
11438
  result.$boost = boost;
10353
11439
  }
10354
11440
  return result;
10355
11441
  };
10356
- var queryNodeToObject = (node, isRoot = false) => {
11442
+ var queryNodeToObject = (node, isRoot = false, forArray = false) => {
10357
11443
  if (node.type === "condition") {
10358
11444
  return conditionToObject(node);
10359
11445
  }
10360
11446
  if (node.type === "group") {
10361
- return groupToObject(node, isRoot);
11447
+ return groupToObject(node, isRoot, forArray);
10362
11448
  }
10363
11449
  return {};
10364
11450
  };
@@ -10414,7 +11500,7 @@ var UIQueryBuilder = () => {
10414
11500
  const { valuesSearch } = useTab();
10415
11501
  const { data: indexDetails } = useFetchSearchIndex(valuesSearch.index);
10416
11502
  const { queryState, setQueryState } = useQueryStateSync();
10417
- const fieldInfos = _optionalChain([indexDetails, 'optionalAccess', _100 => _100.schema]) ? extractFieldInfo(indexDetails.schema) : [];
11503
+ const fieldInfos = _optionalChain([indexDetails, 'optionalAccess', _119 => _119.schema]) ? extractFieldInfo(indexDetails.schema) : [];
10418
11504
  const hasNormalized = _react.useRef.call(void 0, false);
10419
11505
  _react.useEffect.call(void 0, () => {
10420
11506
  if (hasNormalized.current || fieldInfos.length === 0) return;
@@ -10433,7 +11519,7 @@ var UIQueryBuilder = () => {
10433
11519
  setHasBottomShadow(scrollTop + clientHeight < scrollHeight - 1);
10434
11520
  }, []);
10435
11521
  _react.useEffect.call(void 0, () => {
10436
- viewportRef.current = _optionalChain([scrollAreaRef, 'access', _101 => _101.current, 'optionalAccess', _102 => _102.querySelector, 'call', _103 => _103(
11522
+ viewportRef.current = _optionalChain([scrollAreaRef, 'access', _120 => _120.current, 'optionalAccess', _121 => _121.querySelector, 'call', _122 => _122(
10437
11523
  "[data-radix-scroll-area-viewport]"
10438
11524
  )]);
10439
11525
  recomputeShadows();
@@ -10443,7 +11529,7 @@ var UIQueryBuilder = () => {
10443
11529
  obs.observe(el);
10444
11530
  return () => obs.disconnect();
10445
11531
  }, [recomputeShadows]);
10446
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, QueryBuilderUIProvider, { fieldInfos, setQueryState, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "relative h-full rounded-lg bg-zinc-50", children: [
11532
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, QueryBuilderUIProvider, { fieldInfos, setQueryState, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "relative h-full min-h-0 rounded-lg bg-zinc-50 dark:bg-zinc-50/40", children: [
10447
11533
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
10448
11534
  "div",
10449
11535
  {
@@ -10539,41 +11625,47 @@ var extractFieldInfo = (schema) => {
10539
11625
 
10540
11626
  var PREFIX = "const query: Query = ";
10541
11627
  var QueryBuilderContent = () => {
10542
- const { valuesSearch } = useTab();
10543
- const [mode, setMode] = _react.useState.call(void 0, "builder");
10544
- const [switchError, setSwitchError] = _react.useState.call(void 0, null);
11628
+ const { valuesSearch, queryBuilderMode, setQueryBuilderMode } = useTab();
11629
+ const { query } = useKeys();
11630
+ const [switchError, setSwitchError] = _react.useState.call(void 0, );
10545
11631
  const handleModeChange = (value) => {
10546
11632
  const newMode = value;
10547
- if (newMode === "builder") {
11633
+ if (newMode === "ui") {
10548
11634
  if (hasMustShouldCombination(valuesSearch.query)) {
10549
11635
  setSwitchError(
10550
11636
  "Queries using both $must and $should are not supported in the UI query builder"
10551
11637
  );
10552
11638
  return;
10553
11639
  }
10554
- setSwitchError(null);
11640
+ setSwitchError(void 0);
10555
11641
  } else {
10556
- setSwitchError(null);
11642
+ setSwitchError(void 0);
10557
11643
  }
10558
- setMode(newMode);
11644
+ setQueryBuilderMode(newMode);
10559
11645
  };
10560
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { children: [
10561
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "relative h-[200px] max-h-[40vh] min-h-[150px] resize-y overflow-hidden", children: [
10562
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "absolute right-4 top-4 z-10", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
10563
- Segmented,
10564
- {
10565
- options: [
10566
- { key: "builder", label: "Query Builder" },
10567
- { key: "code", label: "Code Editor" }
10568
- ],
10569
- value: mode,
10570
- onChange: handleModeChange,
10571
- buttonClassName: "h-6"
10572
- }
10573
- ) }),
10574
- mode === "builder" ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, UIQueryBuilder, {}) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, QueryBuilder, {})
10575
- ] }),
10576
- switchError && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "mt-3 text-sm text-red-500", children: switchError })
11646
+ const errorMessage = _nullishCoalesce(switchError, () => ( (query.error ? formatUpstashErrorMessage(query.error) : void 0)));
11647
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "relative flex h-full min-h-0 flex-col", children: [
11648
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "absolute right-4 top-4 z-[2]", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
11649
+ Segmented,
11650
+ {
11651
+ options: [
11652
+ { key: "ui", label: "Query Builder" },
11653
+ { key: "code", label: "Code Editor" }
11654
+ ],
11655
+ value: queryBuilderMode,
11656
+ onChange: handleModeChange,
11657
+ buttonClassName: "h-6"
11658
+ }
11659
+ ) }),
11660
+ queryBuilderMode === "ui" ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, UIQueryBuilder, {}) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, QueryBuilder, {}),
11661
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, QueryBuilderError, { error: errorMessage, autoHide: Boolean(switchError) }),
11662
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
11663
+ DocsLink,
11664
+ {
11665
+ className: "absolute bottom-2 right-2 text-sm",
11666
+ href: "https://upstash-search.mintlify.app/redis/search/query-operators/boolean-operators/overview"
11667
+ }
11668
+ )
10577
11669
  ] });
10578
11670
  };
10579
11671
  var SearchContent = () => {
@@ -10590,7 +11682,7 @@ var DatabrowserInstance = ({
10590
11682
  tabType,
10591
11683
  allowSearch
10592
11684
  }) => {
10593
- const { isValuesSearchSelected, setIsValuesSearchSelected } = useTab();
11685
+ const { isValuesSearchSelected, queryBuilderMode, setIsValuesSearchSelected } = useTab();
10594
11686
  const { data: indexes, isLoading } = useFetchSearchIndexes({
10595
11687
  enabled: tabType === "search"
10596
11688
  });
@@ -10606,16 +11698,40 @@ var DatabrowserInstance = ({
10606
11698
  "div",
10607
11699
  {
10608
11700
  className: cn(
10609
- "flex min-h-0 grow flex-col rounded-md bg-white px-5 pb-5",
11701
+ "flex min-h-0 grow flex-col rounded-[10px] bg-white px-5 pb-5",
10610
11702
  hidden && "hidden"
10611
11703
  ),
10612
11704
  children: [
10613
11705
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "space-y-3 py-5", children: [
10614
11706
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Header, { tabType, allowSearch }),
10615
- isValuesSearchSelected && !showEmptyState && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, SearchContent, {}),
10616
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, HeaderError, {})
11707
+ !isValuesSearchSelected && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, HeaderError, {})
10617
11708
  ] }),
10618
- showEmptyState ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, SearchEmptyState, {}) : /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
11709
+ showEmptyState ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, SearchEmptyState, {}) : isValuesSearchSelected ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
11710
+ _reactresizablepanels.PanelGroup,
11711
+ {
11712
+ autoSaveId: "search-layout",
11713
+ direction: "vertical",
11714
+ className: "h-full w-full !overflow-visible text-sm antialiased",
11715
+ children: [
11716
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
11717
+ _reactresizablepanels.Panel,
11718
+ {
11719
+ defaultSize: 30,
11720
+ minSize: 15,
11721
+ maxSize: 60,
11722
+ className: queryBuilderMode === "code" ? "!overflow-visible" : "",
11723
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, SearchContent, {})
11724
+ }
11725
+ ),
11726
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ResizeHandle, { direction: "vertical" }),
11727
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _reactresizablepanels.Panel, { minSize: 30, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _reactresizablepanels.PanelGroup, { autoSaveId: "persistence", direction: "horizontal", className: "h-full w-full", children: [
11728
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _reactresizablepanels.Panel, { defaultSize: 30, minSize: 30, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Sidebar, {}) }),
11729
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ResizeHandle, {}),
11730
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _reactresizablepanels.Panel, { minSize: 40, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, DataDisplay, {}) })
11731
+ ] }) })
11732
+ ]
11733
+ }
11734
+ ) : /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
10619
11735
  _reactresizablepanels.PanelGroup,
10620
11736
  {
10621
11737
  autoSaveId: "persistence",
@@ -10623,11 +11739,7 @@ var DatabrowserInstance = ({
10623
11739
  className: "h-full w-full text-sm antialiased",
10624
11740
  children: [
10625
11741
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _reactresizablepanels.Panel, { defaultSize: 30, minSize: 30, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Sidebar, {}) }),
10626
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _reactresizablepanels.PanelResizeHandle, { className: "group mx-[2px] flex h-full flex-col items-center justify-center gap-1 rounded-md px-[8px] transition-colors hover:bg-zinc-300/10", children: [
10627
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "h-[3px] w-[3px] rounded-full bg-zinc-300" }),
10628
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "h-[3px] w-[3px] rounded-full bg-zinc-300" }),
10629
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "h-[3px] w-[3px] rounded-full bg-zinc-300" })
10630
- ] }),
11742
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ResizeHandle, {}),
10631
11743
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _reactresizablepanels.Panel, { minSize: 40, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, DataDisplay, {}) })
10632
11744
  ]
10633
11745
  }
@@ -10756,7 +11868,7 @@ var useOverflow = () => {
10756
11868
  }
10757
11869
  if (!node) return;
10758
11870
  observerRef.current = new ResizeObserver((entries) => {
10759
- const el = _optionalChain([entries, 'access', _104 => _104.at, 'call', _105 => _105(0), 'optionalAccess', _106 => _106.target]);
11871
+ const el = _optionalChain([entries, 'access', _123 => _123.at, 'call', _124 => _124(0), 'optionalAccess', _125 => _125.target]);
10760
11872
  if (!el) return;
10761
11873
  setIsOverflow(el.scrollWidth > el.clientWidth);
10762
11874
  });
@@ -10764,7 +11876,7 @@ var useOverflow = () => {
10764
11876
  }, []);
10765
11877
  _react.useEffect.call(void 0, () => {
10766
11878
  return () => {
10767
- _optionalChain([observerRef, 'access', _107 => _107.current, 'optionalAccess', _108 => _108.disconnect, 'call', _109 => _109()]);
11879
+ _optionalChain([observerRef, 'access', _126 => _126.current, 'optionalAccess', _127 => _127.disconnect, 'call', _128 => _128()]);
10768
11880
  };
10769
11881
  }, []);
10770
11882
  return { ref, isOverflow };
@@ -10882,8 +11994,8 @@ var SortableTab = ({ id }) => {
10882
11994
  const [originalWidth, setOriginalWidth] = _react.useState.call(void 0, null);
10883
11995
  const textRef = _react.useRef.call(void 0, null);
10884
11996
  const { tabs } = useDatabrowserStore();
10885
- const tabData = _optionalChain([tabs, 'access', _110 => _110.find, 'call', _111 => _111(([tabId]) => tabId === id), 'optionalAccess', _112 => _112[1]]);
10886
- const isPinned = _optionalChain([tabData, 'optionalAccess', _113 => _113.pinned]);
11997
+ const tabData = _optionalChain([tabs, 'access', _129 => _129.find, 'call', _130 => _130(([tabId]) => tabId === id), 'optionalAccess', _131 => _131[1]]);
11998
+ const isPinned = _optionalChain([tabData, 'optionalAccess', _132 => _132.pinned]);
10887
11999
  const { attributes, listeners: listeners2, setNodeRef, transform, transition, isDragging } = _sortable.useSortable.call(void 0, {
10888
12000
  id,
10889
12001
  disabled: isPinned,
@@ -11028,7 +12140,7 @@ var DatabrowserTabs = ({ onFullScreenClick }) => {
11028
12140
  reorderTabs(oldIndex, newIndex);
11029
12141
  }
11030
12142
  };
11031
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "relative shrink-0 overflow-hidden rounded-t-lg bg-zinc-300", children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center gap-1", children: [
12143
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "relative shrink-0 overflow-hidden rounded-t-[10px] bg-zinc-300", children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center gap-1", children: [
11032
12144
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "relative min-w-0 flex-1", children: [
11033
12145
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
11034
12146
  "div",
@@ -11076,7 +12188,7 @@ var DatabrowserTabs = ({ onFullScreenClick }) => {
11076
12188
  }
11077
12189
  )
11078
12190
  ] }),
11079
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center gap-1 pl-1", children: [
12191
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center gap-1 px-1", children: [
11080
12192
  isOverflow && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, AddTabButton, {}),
11081
12193
  tabs.length > 1 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, TabsListButton, { tabs, onSelectTab: selectTab }),
11082
12194
  onFullScreenClick && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
@@ -11084,9 +12196,8 @@ var DatabrowserTabs = ({ onFullScreenClick }) => {
11084
12196
  {
11085
12197
  "aria-label": "Toggle fullscreen",
11086
12198
  variant: "secondary",
11087
- size: "icon-sm",
11088
12199
  onClick: onFullScreenClick,
11089
- className: "flex-shrink-0 bg-white text-zinc-500 dark:bg-zinc-100",
12200
+ className: "h-[34px] w-[34px] flex-shrink-0 rounded-lg bg-white text-zinc-500 dark:bg-zinc-100",
11090
12201
  children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _iconsreact.IconWindowMaximize, { size: 16 })
11091
12202
  }
11092
12203
  )
@@ -11100,7 +12211,7 @@ function AddTabButton() {
11100
12211
  const tabsId = addTab();
11101
12212
  selectTab(tabsId);
11102
12213
  setTimeout(() => {
11103
- const tab = _optionalChain([rootRef, 'optionalAccess', _114 => _114.current, 'optionalAccess', _115 => _115.querySelector, 'call', _116 => _116(`#tab-${tabsId}`)]);
12214
+ const tab = _optionalChain([rootRef, 'optionalAccess', _133 => _133.current, 'optionalAccess', _134 => _134.querySelector, 'call', _135 => _135(`#tab-${tabsId}`)]);
11104
12215
  if (!tab) return;
11105
12216
  tab.scrollIntoView({ behavior: "smooth" });
11106
12217
  }, 20);
@@ -11134,7 +12245,7 @@ function TabsListButton({
11134
12245
  onSelectTab(id);
11135
12246
  setOpen(false);
11136
12247
  setTimeout(() => {
11137
- const tab = _optionalChain([rootRef, 'optionalAccess', _117 => _117.current, 'optionalAccess', _118 => _118.querySelector, 'call', _119 => _119(`#tab-${id}`)]);
12248
+ const tab = _optionalChain([rootRef, 'optionalAccess', _136 => _136.current, 'optionalAccess', _137 => _137.querySelector, 'call', _138 => _138(`#tab-${id}`)]);
11138
12249
  if (!tab) return;
11139
12250
  tab.scrollIntoView({ behavior: "smooth" });
11140
12251
  }, 20);
@@ -11144,8 +12255,7 @@ function TabsListButton({
11144
12255
  Button,
11145
12256
  {
11146
12257
  variant: "secondary",
11147
- size: "sm",
11148
- className: "gap-1 bg-white px-2",
12258
+ className: "h-[34px] gap-1 rounded-lg bg-white px-2",
11149
12259
  "aria-label": "Search in tabs",
11150
12260
  children: [
11151
12261
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-xs text-zinc-600", children: tabs.length }),
@@ -11184,14 +12294,15 @@ var RedisBrowser = ({
11184
12294
  disableTelemetry,
11185
12295
  onFullScreenClick,
11186
12296
  theme = "light",
11187
- allowSearch = false
12297
+ allowSearch = false,
12298
+ useQueryWizard
11188
12299
  }) => {
11189
12300
  const credentials = _react.useMemo.call(void 0, () => ({ token, url }), [token, url]);
11190
12301
  const rootRef = _react.useRef.call(void 0, null);
11191
12302
  _react.useEffect.call(void 0, () => {
11192
12303
  queryClient.resetQueries();
11193
12304
  }, [credentials.url]);
11194
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _reactquery.QueryClientProvider, { client: queryClient, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, RedisProvider, { redisCredentials: credentials, telemetry: !disableTelemetry, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, DarkModeProvider, { theme, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, DatabrowserProvider, { storage, rootRef, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _reacttooltip.TooltipProvider, { children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
12305
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _reactquery.QueryClientProvider, { client: queryClient, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, RedisProvider, { redisCredentials: credentials, telemetry: !disableTelemetry, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, DarkModeProvider, { theme, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, DatabrowserProvider, { storage, rootRef, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, QueryWizardProvider, { value: useQueryWizard, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _reacttooltip.TooltipProvider, { children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
11195
12306
  RedisBrowserRoot,
11196
12307
  {
11197
12308
  allowSearch,
@@ -11200,7 +12311,7 @@ var RedisBrowser = ({
11200
12311
  rootRef,
11201
12312
  onFullScreenClick
11202
12313
  }
11203
- ) }) }) }) }) });
12314
+ ) }) }) }) }) }) });
11204
12315
  };
11205
12316
  var RedisBrowserRoot = ({
11206
12317
  hideTabs,
@@ -11222,7 +12333,7 @@ var RedisBrowserRoot = ({
11222
12333
  className: `ups-db ${theme === "dark" ? "dark" : ""}`,
11223
12334
  style: { height: "100%" },
11224
12335
  ref: rootRef,
11225
- children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex h-full flex-col overflow-hidden rounded-[14px] border-[4px] border-zinc-300 text-zinc-700", children: [
12336
+ children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex h-full flex-col rounded-[14px] border-[4px] border-zinc-300 text-zinc-700", children: [
11226
12337
  !hideTabs && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, DatabrowserTabs, { onFullScreenClick }),
11227
12338
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, DatabrowserInstances, { tabType, allowSearch })
11228
12339
  ] })