@flanksource/clicky-ui 0.3.18 → 0.3.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (191) hide show
  1. package/dist/components/ComboboxMenu.cjs +5 -1
  2. package/dist/components/ComboboxMenu.cjs.map +1 -1
  3. package/dist/components/ComboboxMenu.d.ts.map +1 -1
  4. package/dist/components/ComboboxMenu.js +5 -1
  5. package/dist/components/ComboboxMenu.js.map +1 -1
  6. package/dist/components/EndpointSelector.model.cjs +96 -0
  7. package/dist/components/EndpointSelector.model.cjs.map +1 -0
  8. package/dist/components/EndpointSelector.model.d.ts +2 -0
  9. package/dist/components/EndpointSelector.model.d.ts.map +1 -1
  10. package/dist/components/EndpointSelector.model.js +96 -0
  11. package/dist/components/EndpointSelector.model.js.map +1 -0
  12. package/dist/components/FilterBar.cjs +52 -2
  13. package/dist/components/FilterBar.cjs.map +1 -1
  14. package/dist/components/FilterBar.d.ts +20 -2
  15. package/dist/components/FilterBar.d.ts.map +1 -1
  16. package/dist/components/FilterBar.js +52 -2
  17. package/dist/components/FilterBar.js.map +1 -1
  18. package/dist/components/JSONPathField.cjs +87 -66
  19. package/dist/components/JSONPathField.cjs.map +1 -1
  20. package/dist/components/JSONPathField.d.ts +26 -9
  21. package/dist/components/JSONPathField.d.ts.map +1 -1
  22. package/dist/components/JSONPathField.js +88 -67
  23. package/dist/components/JSONPathField.js.map +1 -1
  24. package/dist/components/JSONPathPlayground.cjs +225 -0
  25. package/dist/components/JSONPathPlayground.cjs.map +1 -0
  26. package/dist/components/JSONPathPlayground.d.ts +59 -0
  27. package/dist/components/JSONPathPlayground.d.ts.map +1 -0
  28. package/dist/components/JSONPathPlayground.js +225 -0
  29. package/dist/components/JSONPathPlayground.js.map +1 -0
  30. package/dist/components/OnePasswordSelector.cjs +178 -0
  31. package/dist/components/OnePasswordSelector.cjs.map +1 -0
  32. package/dist/components/OnePasswordSelector.d.ts +8 -0
  33. package/dist/components/OnePasswordSelector.d.ts.map +1 -0
  34. package/dist/components/OnePasswordSelector.js +178 -0
  35. package/dist/components/OnePasswordSelector.js.map +1 -0
  36. package/dist/components/OnePasswordSelector.model.cjs +31 -0
  37. package/dist/components/OnePasswordSelector.model.cjs.map +1 -0
  38. package/dist/components/OnePasswordSelector.model.d.ts +27 -0
  39. package/dist/components/OnePasswordSelector.model.d.ts.map +1 -0
  40. package/dist/components/OnePasswordSelector.model.js +31 -0
  41. package/dist/components/OnePasswordSelector.model.js.map +1 -0
  42. package/dist/components/SecretFormField.cjs +142 -0
  43. package/dist/components/SecretFormField.cjs.map +1 -0
  44. package/dist/components/SecretFormField.d.ts +9 -0
  45. package/dist/components/SecretFormField.d.ts.map +1 -0
  46. package/dist/components/SecretFormField.js +142 -0
  47. package/dist/components/SecretFormField.js.map +1 -0
  48. package/dist/components/SecretKeySelector.cjs +20 -14
  49. package/dist/components/SecretKeySelector.cjs.map +1 -1
  50. package/dist/components/SecretKeySelector.d.ts +4 -1
  51. package/dist/components/SecretKeySelector.d.ts.map +1 -1
  52. package/dist/components/SecretKeySelector.js +20 -14
  53. package/dist/components/SecretKeySelector.js.map +1 -1
  54. package/dist/components/TreePickerField.cjs +55 -29
  55. package/dist/components/TreePickerField.cjs.map +1 -1
  56. package/dist/components/TreePickerField.d.ts +10 -1
  57. package/dist/components/TreePickerField.d.ts.map +1 -1
  58. package/dist/components/TreePickerField.js +56 -30
  59. package/dist/components/TreePickerField.js.map +1 -1
  60. package/dist/components/combobox-types.d.ts +9 -0
  61. package/dist/components/combobox-types.d.ts.map +1 -1
  62. package/dist/components/filter-bar-utils.cjs +7 -0
  63. package/dist/components/filter-bar-utils.cjs.map +1 -1
  64. package/dist/components/filter-bar-utils.d.ts.map +1 -1
  65. package/dist/components/filter-bar-utils.js +7 -0
  66. package/dist/components/filter-bar-utils.js.map +1 -1
  67. package/dist/components/jotai-bindings-core.cjs.map +1 -1
  68. package/dist/components/jotai-bindings-core.d.ts +4 -1
  69. package/dist/components/jotai-bindings-core.d.ts.map +1 -1
  70. package/dist/components/jotai-bindings-core.js.map +1 -1
  71. package/dist/components/json-schema-form-render.cjs +2 -1
  72. package/dist/components/json-schema-form-render.cjs.map +1 -1
  73. package/dist/components/json-schema-form-render.d.ts.map +1 -1
  74. package/dist/components/json-schema-form-render.js +2 -1
  75. package/dist/components/json-schema-form-render.js.map +1 -1
  76. package/dist/components/json-schema-form-types.d.ts +9 -0
  77. package/dist/components/json-schema-form-types.d.ts.map +1 -1
  78. package/dist/components/jsonPathTree.cjs +189 -0
  79. package/dist/components/jsonPathTree.cjs.map +1 -0
  80. package/dist/components/jsonPathTree.d.ts +92 -0
  81. package/dist/components/jsonPathTree.d.ts.map +1 -0
  82. package/dist/components/jsonPathTree.js +189 -0
  83. package/dist/components/jsonPathTree.js.map +1 -0
  84. package/dist/components/secret-form-extension.cjs +30 -0
  85. package/dist/components/secret-form-extension.cjs.map +1 -0
  86. package/dist/components/secret-form-extension.d.ts +23 -0
  87. package/dist/components/secret-form-extension.d.ts.map +1 -0
  88. package/dist/components/secret-form-extension.js +30 -0
  89. package/dist/components/secret-form-extension.js.map +1 -0
  90. package/dist/components.cjs +16 -0
  91. package/dist/components.cjs.map +1 -1
  92. package/dist/components.d.ts +6 -0
  93. package/dist/components.d.ts.map +1 -1
  94. package/dist/components.js +16 -0
  95. package/dist/components.js.map +1 -1
  96. package/dist/data/TaskExecDetails.cjs +40 -0
  97. package/dist/data/TaskExecDetails.cjs.map +1 -0
  98. package/dist/data/TaskExecDetails.d.ts +5 -0
  99. package/dist/data/TaskExecDetails.d.ts.map +1 -0
  100. package/dist/data/TaskExecDetails.js +40 -0
  101. package/dist/data/TaskExecDetails.js.map +1 -0
  102. package/dist/data/TaskProgress.cjs +9 -3
  103. package/dist/data/TaskProgress.cjs.map +1 -1
  104. package/dist/data/TaskProgress.d.ts.map +1 -1
  105. package/dist/data/TaskProgress.js +9 -3
  106. package/dist/data/TaskProgress.js.map +1 -1
  107. package/dist/data/TaskSnapshot.cjs.map +1 -1
  108. package/dist/data/TaskSnapshot.d.ts +12 -1
  109. package/dist/data/TaskSnapshot.d.ts.map +1 -1
  110. package/dist/data/TaskSnapshot.js.map +1 -1
  111. package/dist/data/TreeNode.cjs +3 -0
  112. package/dist/data/TreeNode.cjs.map +1 -1
  113. package/dist/data/TreeNode.d.ts.map +1 -1
  114. package/dist/data/TreeNode.js +3 -0
  115. package/dist/data/TreeNode.js.map +1 -1
  116. package/dist/data/data-table-filter-values.cjs +20 -0
  117. package/dist/data/data-table-filter-values.cjs.map +1 -1
  118. package/dist/data/data-table-filter-values.d.ts +16 -0
  119. package/dist/data/data-table-filter-values.d.ts.map +1 -1
  120. package/dist/data/data-table-filter-values.js +20 -0
  121. package/dist/data/data-table-filter-values.js.map +1 -1
  122. package/dist/data/data-table-server-filters.cjs +23 -29
  123. package/dist/data/data-table-server-filters.cjs.map +1 -1
  124. package/dist/data/data-table-server-filters.d.ts.map +1 -1
  125. package/dist/data/data-table-server-filters.js +21 -27
  126. package/dist/data/data-table-server-filters.js.map +1 -1
  127. package/dist/data/query-browser/QueryBrowser.cjs +129 -157
  128. package/dist/data/query-browser/QueryBrowser.cjs.map +1 -1
  129. package/dist/data/query-browser/QueryBrowser.d.ts +1 -71
  130. package/dist/data/query-browser/QueryBrowser.d.ts.map +1 -1
  131. package/dist/data/query-browser/QueryBrowser.editor.cjs +88 -0
  132. package/dist/data/query-browser/QueryBrowser.editor.cjs.map +1 -0
  133. package/dist/data/query-browser/QueryBrowser.editor.d.ts +12 -0
  134. package/dist/data/query-browser/QueryBrowser.editor.d.ts.map +1 -0
  135. package/dist/data/query-browser/QueryBrowser.editor.js +88 -0
  136. package/dist/data/query-browser/QueryBrowser.editor.js.map +1 -0
  137. package/dist/data/query-browser/QueryBrowser.js +130 -158
  138. package/dist/data/query-browser/QueryBrowser.js.map +1 -1
  139. package/dist/data/query-browser/QueryBrowser.types.cjs +11 -0
  140. package/dist/data/query-browser/QueryBrowser.types.cjs.map +1 -0
  141. package/dist/data/query-browser/QueryBrowser.types.d.ts +92 -0
  142. package/dist/data/query-browser/QueryBrowser.types.d.ts.map +1 -0
  143. package/dist/data/query-browser/QueryBrowser.types.js +11 -0
  144. package/dist/data/query-browser/QueryBrowser.types.js.map +1 -0
  145. package/dist/data/query-browser/QueryBrowserDiagnosticsPanel.cjs +56 -0
  146. package/dist/data/query-browser/QueryBrowserDiagnosticsPanel.cjs.map +1 -0
  147. package/dist/data/query-browser/QueryBrowserDiagnosticsPanel.d.ts +5 -0
  148. package/dist/data/query-browser/QueryBrowserDiagnosticsPanel.d.ts.map +1 -0
  149. package/dist/data/query-browser/QueryBrowserDiagnosticsPanel.js +56 -0
  150. package/dist/data/query-browser/QueryBrowserDiagnosticsPanel.js.map +1 -0
  151. package/dist/data/query-browser/QueryBrowserResults.cjs +80 -0
  152. package/dist/data/query-browser/QueryBrowserResults.cjs.map +1 -0
  153. package/dist/data/query-browser/QueryBrowserResults.d.ts +16 -0
  154. package/dist/data/query-browser/QueryBrowserResults.d.ts.map +1 -0
  155. package/dist/data/query-browser/QueryBrowserResults.js +80 -0
  156. package/dist/data/query-browser/QueryBrowserResults.js.map +1 -0
  157. package/dist/data/query-browser/index.d.ts +2 -1
  158. package/dist/data/query-browser/index.d.ts.map +1 -1
  159. package/dist/data/task-exec-details.cjs +9 -0
  160. package/dist/data/task-exec-details.cjs.map +1 -0
  161. package/dist/data/task-exec-details.d.ts +3 -0
  162. package/dist/data/task-exec-details.d.ts.map +1 -0
  163. package/dist/data/task-exec-details.js +9 -0
  164. package/dist/data/task-exec-details.js.map +1 -0
  165. package/dist/data/version-info.cjs +3 -3
  166. package/dist/data/version-info.js +3 -3
  167. package/dist/data.cjs +2 -0
  168. package/dist/data.cjs.map +1 -1
  169. package/dist/data.d.ts +1 -1
  170. package/dist/data.d.ts.map +1 -1
  171. package/dist/data.js +2 -0
  172. package/dist/data.js.map +1 -1
  173. package/dist/index.cjs +18 -0
  174. package/dist/index.cjs.map +1 -1
  175. package/dist/index.js +18 -0
  176. package/dist/index.js.map +1 -1
  177. package/dist/rpc/FilterForm.cjs +20 -0
  178. package/dist/rpc/FilterForm.cjs.map +1 -1
  179. package/dist/rpc/FilterForm.js +20 -0
  180. package/dist/rpc/FilterForm.js.map +1 -1
  181. package/dist/rpc/formMetadata.cjs +34 -0
  182. package/dist/rpc/formMetadata.cjs.map +1 -1
  183. package/dist/rpc/formMetadata.d.ts.map +1 -1
  184. package/dist/rpc/formMetadata.js +35 -1
  185. package/dist/rpc/formMetadata.js.map +1 -1
  186. package/dist/rpc/types.cjs.map +1 -1
  187. package/dist/rpc/types.d.ts +9 -1
  188. package/dist/rpc/types.d.ts.map +1 -1
  189. package/dist/rpc/types.js.map +1 -1
  190. package/dist/styles.css +1 -1
  191. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"QueryBrowser.js","sources":["../../../src/data/query-browser/QueryBrowser.tsx"],"sourcesContent":["import { history, historyKeymap } from \"@codemirror/commands\";\nimport { autocompletion } from \"@codemirror/autocomplete\";\nimport { json } from \"@codemirror/lang-json\";\nimport { sql } from \"@codemirror/lang-sql\";\nimport { Compartment, EditorState, type Extension } from \"@codemirror/state\";\nimport { EditorView, keymap } from \"@codemirror/view\";\nimport {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n type ReactNode,\n} from \"react\";\nimport { Button } from \"../../components/button\";\nimport { JsonSchemaForm } from \"../../components/JsonSchemaForm\";\nimport type { JsonSchemaObject } from \"../../components/json-schema-form-types\";\nimport { cn } from \"../../lib/utils\";\nimport { SplitPane } from \"../../layout/SplitPane\";\nimport { Icon } from \"../Icon\";\nimport { UiPlay } from \"../../icons\";\nimport { DataTable } from \"../DataTable\";\nimport { inferColumns } from \"../data-table-utils\";\nimport type { DataTableFilterSelection } from \"../data-table-filter-values\";\nimport {\n serverColumnsToDataTableColumns,\n serverFiltersToFilterBar,\n type DataTableFilterLookup,\n type DataTableFilterLookupRequest,\n type DataTableFilterLookupResult,\n type DataTableServerColumn,\n} from \"../data-table-server-filters\";\nimport { ErrorDetails } from \"../diagnostics/ErrorDetails\";\nimport { Properties } from \"../Properties\";\nimport {\n dialectFor,\n openSearchJSONCompletionSource,\n sqlCompletionNamespace,\n type QueryBrowserCompletion,\n} from \"./QueryBrowser.completion\";\n\nexport type QueryBrowserResult = {\n rows?: Record<string, unknown>[];\n /**\n * How the source describes the columns it returned, including which of them\n * it can narrow on. Present columns replace the ones inferred from the rows,\n * so a filterable result is described rather than guessed at.\n */\n columns?: DataTableServerColumn[];\n affectedRows?: number;\n durationMs?: number;\n message?: string;\n truncated?: boolean;\n /** Where a truncated read stopped, so the bound can be named rather than\n * merely hinted at with a trailing \"+\". */\n limit?: number;\n metadata?: Record<string, unknown>;\n};\n\nexport type QueryBrowserRequest = {\n query: string;\n options: Record<string, unknown>;\n /** The filter pills the user picked, if the last result described any. */\n filters?: DataTableFilterSelection;\n /**\n * The columns the last result described, echoed back so a filter binds to\n * what the source offered rather than to whatever the narrowed result\n * describes. Sources that have a catalog of their own ignore it.\n */\n columns?: DataTableServerColumn[];\n};\n\n/**\n * A filter value type-ahead, carrying the context the source needs to scope its\n * suggestions: the last *executed* query and the rest of the selection, so a\n * value list only offers values that would still return rows.\n */\nexport type QueryBrowserFilterLookupRequest = DataTableFilterLookupRequest & {\n query: string;\n options: Record<string, unknown>;\n filters: DataTableFilterSelection;\n columns?: DataTableServerColumn[];\n};\n\nexport type QueryBrowserFilterLookup = (\n request: QueryBrowserFilterLookupRequest,\n) => Promise<DataTableFilterLookupResult>;\n\nexport type QueryBrowserResultContext = {\n result: QueryBrowserResult;\n defaultView: ReactNode;\n};\n\nexport type QueryBrowserProps = {\n id: string;\n title?: string;\n language?: \"sql\" | \"json\" | \"text\";\n initialQuery?: string;\n queryLabel?: string;\n optionsSchema?: JsonSchemaObject;\n initialOptions?: Record<string, unknown>;\n completion?: QueryBrowserCompletion;\n onQueryChange?: (query: string) => void;\n onOptionsChange?: (options: Record<string, unknown>) => void;\n navigator?: ReactNode;\n execute: (request: QueryBrowserRequest) => Promise<QueryBrowserResult>;\n /**\n * Answers a filter's value type-ahead. Absent leaves every described filter\n * showing only the options the result carried.\n */\n lookupFilterValues?: QueryBrowserFilterLookup;\n renderResults?: (context: QueryBrowserResultContext) => ReactNode;\n className?: string;\n};\n\ntype HistoryEntry = { query: string; at: number };\n\nconst MAX_HISTORY = 50;\n\nfunction historyKey(id: string) {\n return `clicky-ui:query-browser:${id}:history`;\n}\n\nfunction readHistory(id: string): HistoryEntry[] {\n if (typeof window === \"undefined\") return [];\n try {\n const value = JSON.parse(\n window.localStorage.getItem(historyKey(id)) ?? \"[]\",\n );\n return Array.isArray(value) ? value.slice(0, MAX_HISTORY) : [];\n } catch {\n return [];\n }\n}\n\nfunction rememberQuery(id: string, query: string): HistoryEntry[] {\n const entries = readHistory(id).filter((entry) => entry.query !== query);\n const next = [{ query, at: Date.now() }, ...entries].slice(0, MAX_HISTORY);\n if (typeof window !== \"undefined\") {\n window.localStorage.setItem(historyKey(id), JSON.stringify(next));\n }\n return next;\n}\n\nfunction editorExtensions(\n execute: () => void,\n onQueryChange: (query: string) => void,\n languageExtension: Extension,\n) {\n return [\n history(),\n keymap.of([\n {\n key: \"Mod-Enter\",\n run: () => {\n execute();\n return true;\n },\n },\n ...historyKeymap,\n ]),\n EditorView.lineWrapping,\n EditorView.updateListener.of((update) => {\n if (update.docChanged) onQueryChange(update.state.doc.toString());\n }),\n EditorView.theme({\n \"&\": { height: \"100%\", fontSize: \"13px\", background: \"transparent\" },\n \".cm-scroller\": {\n fontFamily: \"ui-monospace, SFMono-Regular, Menlo, monospace\",\n },\n \".cm-content\": { padding: \"12px 0\" },\n \".cm-gutters\": { background: \"transparent\", border: \"none\" },\n \"&.cm-focused\": { outline: \"none\" },\n }),\n languageExtension,\n ];\n}\n\nfunction languageExtension(\n language: QueryBrowserProps[\"language\"],\n completion?: QueryBrowserCompletion,\n): Extension {\n if (language === \"sql\") {\n if (completion?.kind !== \"sql\") return sql();\n return sql({\n dialect: dialectFor(completion.dialect),\n schema: sqlCompletionNamespace(completion.schemas),\n upperCaseKeywords: true,\n ...(completion.defaultSchema\n ? { defaultSchema: completion.defaultSchema }\n : {}),\n });\n }\n if (language === \"json\") {\n if (completion?.kind !== \"json-fields\") return json();\n return [\n json(),\n autocompletion({\n override: [openSearchJSONCompletionSource(completion.fields)],\n }),\n ];\n }\n return [];\n}\n\nexport function QueryBrowser({\n id,\n title,\n language = \"text\",\n initialQuery = \"\",\n queryLabel = \"Query\",\n optionsSchema,\n initialOptions,\n completion,\n onQueryChange,\n onOptionsChange,\n navigator,\n execute,\n lookupFilterValues,\n renderResults,\n className,\n}: QueryBrowserProps) {\n const editorHost = useRef<HTMLDivElement | null>(null);\n const editor = useRef<EditorView | null>(null);\n const languageConfig = useRef(new Compartment());\n const executeRef = useRef<() => void>(() => undefined);\n const onQueryChangeRef = useRef(onQueryChange);\n const [options, setOptions] = useState<Record<string, unknown>>(\n initialOptions ?? {},\n );\n const [result, setResult] = useState<QueryBrowserResult | null>(null);\n const [error, setError] = useState<string | null>(null);\n const [pending, setPending] = useState(false);\n const [entries, setEntries] = useState<HistoryEntry[]>(() => readHistory(id));\n const [filters, setFilters] = useState<DataTableFilterSelection>({});\n // What the displayed result came from. A filter re-runs *this*, never the\n // editor's current text — otherwise changing a pill would execute a\n // half-typed edit nobody asked to run.\n const lastRun = useRef<{\n query: string;\n options: Record<string, unknown>;\n columns?: DataTableServerColumn[];\n } | null>(null);\n const executedFilters = useRef<DataTableFilterSelection>({});\n\n // Every run goes through here so the record a filter re-runs from is refreshed\n // in one place: the query, its options, and the columns the source described,\n // which are what a subsequent selection binds to.\n const runRequest = useCallback(\n async (request: QueryBrowserRequest) => {\n setPending(true);\n setError(null);\n const started = performance.now();\n try {\n const next = await execute(request);\n setResult({\n ...next,\n durationMs: next.durationMs ?? performance.now() - started,\n });\n lastRun.current = {\n query: request.query,\n options: request.options,\n ...(next.columns ? { columns: next.columns } : {}),\n };\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err));\n } finally {\n setPending(false);\n }\n },\n [execute],\n );\n\n const currentQuery = useCallback(() => {\n const view = editor.current;\n if (!view) return initialQuery;\n const selection = view.state.selection.main;\n if (!selection.empty)\n return view.state.sliceDoc(selection.from, selection.to);\n return view.state.doc.toString();\n }, [initialQuery]);\n\n const run = useCallback(async () => {\n const query = currentQuery().trim();\n if (!query || pending) return;\n setEntries(rememberQuery(id, query));\n // A different statement is a different result set, so neither its filters\n // nor the columns they bind to survive: both name columns the new query may\n // not return.\n const repeat = lastRun.current?.query === query ? lastRun.current : null;\n const carried = repeat ? filters : {};\n if (carried !== filters) setFilters(carried);\n lastRun.current = { query, options };\n executedFilters.current = carried;\n await runRequest({\n query,\n options,\n ...(Object.keys(carried).length > 0 ? { filters: carried } : {}),\n ...(repeat?.columns ? { columns: repeat.columns } : {}),\n });\n }, [currentQuery, filters, id, options, pending, runRequest]);\n\n // A filter pill is not a draft the way query text is: it commits a discrete\n // value on selection, and the bar already debounces its free-text fields. So\n // a change re-runs the last executed query immediately rather than waiting\n // for Run, which is also how the profile catalog behaves.\n const rerunWithFilters = useCallback(\n async (selection: DataTableFilterSelection) => {\n const previous = lastRun.current;\n if (!previous) {\n throw new Error(\"QueryBrowser: a filter changed before any query had run\");\n }\n await runRequest({ ...previous, filters: selection });\n },\n [runRequest],\n );\n\n useEffect(() => {\n if (!lastRun.current) return;\n if (filters === executedFilters.current) return;\n executedFilters.current = filters;\n void rerunWithFilters(filters);\n }, [filters, rerunWithFilters]);\n\n executeRef.current = () => void run();\n onQueryChangeRef.current = onQueryChange;\n\n useEffect(() => {\n if (!editorHost.current) return;\n const view = new EditorView({\n parent: editorHost.current,\n state: EditorState.create({\n doc: initialQuery,\n extensions: editorExtensions(\n () => executeRef.current(),\n (query) => onQueryChangeRef.current?.(query),\n languageConfig.current.of(languageExtension(language, completion)),\n ),\n }),\n });\n editor.current = view;\n return () => {\n editor.current = null;\n view.destroy();\n };\n }, [id, language]);\n\n useEffect(() => {\n const view = editor.current;\n if (!view) return;\n view.dispatch({\n effects: languageConfig.current.reconfigure(\n languageExtension(language, completion),\n ),\n });\n }, [completion, language]);\n\n useEffect(() => {\n const view = editor.current;\n if (!view || view.state.doc.toString() === initialQuery) return;\n view.dispatch({\n changes: { from: 0, to: view.state.doc.length, insert: initialQuery },\n });\n }, [initialQuery]);\n\n useEffect(() => {\n setOptions(initialOptions ?? {});\n }, [initialOptions]);\n\n const updateOptions = useCallback(\n (next: Record<string, unknown>) => {\n setOptions(next);\n onOptionsChange?.(next);\n },\n [onOptionsChange],\n );\n\n useEffect(() => {\n setEntries(readHistory(id));\n setResult(null);\n setError(null);\n setFilters({});\n lastRun.current = null;\n executedFilters.current = {};\n }, [id]);\n\n const rows = result?.rows ?? [];\n const described = result?.columns ?? [];\n const columns = useMemo(\n () =>\n described.length > 0\n ? serverColumnsToDataTableColumns<Record<string, unknown>>(described)\n : inferColumns(rows, { literalKeys: true }),\n [described, rows],\n );\n const lookupValues = useMemo<DataTableFilterLookup | undefined>(() => {\n if (!lookupFilterValues) return undefined;\n return (request) => {\n const previous = lastRun.current;\n if (!previous) {\n throw new Error(\"QueryBrowser: a filter lookup ran before any query had\");\n }\n return lookupFilterValues({ ...request, ...previous, filters });\n };\n }, [filters, lookupFilterValues]);\n const filterConfig = useMemo(\n () =>\n serverFiltersToFilterBar(\n described,\n filters,\n setFilters,\n lookupValues ? { lookupValues } : {},\n ),\n [described, filters, lookupValues],\n );\n const serverFiltered =\n filterConfig.filters.length > 0 || filterConfig.timeRange !== undefined;\n const defaultResults = result ? (\n <div className=\"flex min-h-0 flex-1 flex-col gap-2\">\n <div className=\"flex flex-wrap items-center gap-3 text-xs text-muted-foreground\">\n <span>\n {rows.length.toLocaleString()} rows{result.truncated ? \"+\" : \"\"}\n </span>\n {/* A \"+\" says there is more without saying the console stopped, which\n reads as a small table rather than a bounded read. Naming the bound\n is what makes the difference visible. */}\n {result.truncated && (\n <span className=\"text-amber-600 [[data-theme=dark]_&]:text-amber-400\">\n stopped at the console's {(result.limit ?? rows.length).toLocaleString()}-row bound;\n narrow the query to see the rest\n </span>\n )}\n {result.affectedRows !== undefined && (\n <span>{result.affectedRows.toLocaleString()} affected</span>\n )}\n {result.durationMs !== undefined && (\n <span>{Math.round(result.durationMs)} ms</span>\n )}\n {result.message && <span>{result.message}</span>}\n </div>\n {/* A described result keeps its table at zero rows: a filter that\n excluded everything must not unmount the bar that would undo it. */}\n {rows.length > 0 || described.length > 0 ? (\n <DataTable\n data={rows}\n columns={columns}\n loading={pending}\n autoFilter={false}\n {...(serverFiltered\n ? {\n manualFilter: true,\n externalFilters: filterConfig.filters,\n ...(filterConfig.timeRange ? { externalTimeRange: filterConfig.timeRange } : {}),\n }\n : { showGlobalFilter: true })}\n showFullscreenControl\n fullscreenTitle={title ?? queryLabel}\n detailStyle=\"dialog\"\n detailDialogTitle=\"Row details\"\n renderExpandedRow={(row) => (\n <Properties\n items={Object.entries(row).map(([key, value]) => ({\n key,\n value,\n }))}\n renderLabel={(key) => key}\n density=\"compact\"\n />\n )}\n className=\"min-h-0 flex-1\"\n />\n ) : (\n <div className=\"rounded-md border border-dashed p-6 text-sm text-muted-foreground\">\n {result.message ?? \"Statement completed with no rows.\"}\n </div>\n )}\n </div>\n ) : (\n <div className=\"grid min-h-40 place-items-center text-sm text-muted-foreground\">\n Run a query to see results.\n </div>\n );\n\n const workspace = (\n <div className=\"flex h-full min-h-0 flex-col overflow-hidden rounded-xl border bg-card\">\n <div className=\"flex flex-wrap items-center gap-2 border-b px-3 py-2\">\n <div className=\"min-w-0 flex-1\">\n {title && <h2 className=\"truncate text-sm font-semibold\">{title}</h2>}\n <p className=\"text-xs text-muted-foreground\">{queryLabel}</p>\n </div>\n {entries.length > 0 && (\n <select\n aria-label=\"Query history\"\n defaultValue=\"\"\n onChange={(event) => {\n const query = event.target.value;\n const view = editor.current;\n if (!view || !query) return;\n view.dispatch({\n changes: { from: 0, to: view.state.doc.length, insert: query },\n });\n event.target.value = \"\";\n }}\n className=\"h-8 max-w-52 rounded-md border bg-background px-2 text-xs\"\n >\n <option value=\"\">History</option>\n {entries.map((entry) => (\n <option key={`${entry.at}:${entry.query}`} value={entry.query}>\n {entry.query.replace(/\\s+/g, \" \").slice(0, 80)}\n </option>\n ))}\n </select>\n )}\n <Button\n size=\"sm\"\n onClick={() => void run()}\n loading={pending}\n loadingLabel={pending ? \"Running\" : undefined}\n >\n <Icon icon={UiPlay} className=\"size-4\" />\n Run\n </Button>\n </div>\n {optionsSchema &&\n Object.keys(optionsSchema.properties ?? {}).length > 0 && (\n <div className=\"border-b px-3 py-2\">\n <JsonSchemaForm\n schema={optionsSchema}\n value={options}\n onChange={updateOptions}\n size=\"sm\"\n inline\n showPreferencesMenu={false}\n persistPreferences={false}\n />\n </div>\n )}\n <div ref={editorHost} className=\"h-[34%] min-h-44 border-b\" />\n <div className=\"flex min-h-0 flex-1 flex-col overflow-auto p-3\">\n {error ? (\n <ErrorDetails\n diagnostics={{\n message: error,\n context: [\n [\"Query\", currentQuery()],\n [\"Language\", language],\n ],\n }}\n />\n ) : result && renderResults ? (\n renderResults({ result, defaultView: defaultResults })\n ) : (\n defaultResults\n )}\n </div>\n </div>\n );\n\n return (\n <div className={cn(\"h-[calc(100vh-15rem)] min-h-[32rem]\", className)}>\n {navigator ? (\n <SplitPane defaultSplit={28} left={navigator} right={workspace} />\n ) : (\n workspace\n )}\n </div>\n );\n}\n"],"names":["languageExtension"],"mappings":"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"}
1
+ {"version":3,"file":"QueryBrowser.js","sources":["../../../src/data/query-browser/QueryBrowser.tsx"],"sourcesContent":["import { Compartment, EditorState } from \"@codemirror/state\";\nimport { EditorView } from \"@codemirror/view\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { Button } from \"../../components/button\";\nimport { JsonSchemaForm } from \"../../components/JsonSchemaForm\";\nimport { cn } from \"../../lib/utils\";\nimport { SplitPane } from \"../../layout/SplitPane\";\nimport { Icon } from \"../Icon\";\nimport { UiDebug, UiPlay } from \"../../icons\";\nimport type { DataTablePagination } from \"../DataTable\";\nimport { inferColumns } from \"../data-table-utils\";\nimport type { DataTableFilterSelection } from \"../data-table-filter-values\";\nimport {\n serverColumnsToDataTableColumns,\n serverFiltersToFilterBar,\n type DataTableFilterLookup,\n type DataTableServerColumn,\n} from \"../data-table-server-filters\";\nimport { ErrorDetails } from \"../diagnostics/ErrorDetails\";\nimport {\n queryBrowserEditorExtensions,\n queryBrowserLanguageExtension,\n readQueryBrowserHistory,\n rememberQueryBrowserQuery,\n type QueryBrowserHistoryEntry,\n} from \"./QueryBrowser.editor\";\nimport { QueryBrowserDiagnosticsPanel } from \"./QueryBrowserDiagnosticsPanel\";\nimport { QueryBrowserResults } from \"./QueryBrowserResults\";\nimport {\n QueryBrowserExecutionError,\n type QueryBrowserDiagnostics,\n type QueryBrowserProps,\n type QueryBrowserRequest,\n type QueryBrowserResult,\n} from \"./QueryBrowser.types\";\n\nexport function QueryBrowser({\n id,\n title,\n language = \"text\",\n initialQuery = \"\",\n queryLabel = \"Query\",\n optionsSchema,\n initialOptions,\n completion,\n onQueryChange,\n onOptionsChange,\n navigator,\n execute,\n lookupFilterValues,\n renderResults,\n className,\n}: QueryBrowserProps) {\n const editorHost = useRef<HTMLDivElement | null>(null);\n const editor = useRef<EditorView | null>(null);\n const languageConfig = useRef(new Compartment());\n const executeRef = useRef<() => void>(() => undefined);\n const onQueryChangeRef = useRef(onQueryChange);\n const [options, setOptions] = useState<Record<string, unknown>>(\n initialOptions ?? {},\n );\n const [result, setResult] = useState<QueryBrowserResult | null>(null);\n const [error, setError] = useState<{\n message: string;\n query: string;\n diagnostics?: QueryBrowserDiagnostics;\n } | null>(null);\n const [pending, setPending] = useState(false);\n const [debug, setDebug] = useState(false);\n const [entries, setEntries] = useState<QueryBrowserHistoryEntry[]>(() =>\n readQueryBrowserHistory(id),\n );\n const [filters, setFilters] = useState<DataTableFilterSelection>({});\n // What the displayed result came from. A filter re-runs *this*, never the\n // editor's current text — otherwise changing a pill would execute a\n // half-typed edit nobody asked to run.\n const lastRun = useRef<{\n query: string;\n options: Record<string, unknown>;\n filters?: DataTableFilterSelection;\n columns?: DataTableServerColumn[];\n } | null>(null);\n const executedFilters = useRef<DataTableFilterSelection>({});\n\n // Every run goes through here so the record a filter re-runs from is refreshed\n // in one place: the query, its options, and the columns the source described,\n // which are what a subsequent selection binds to.\n const runRequest = useCallback(\n async (request: QueryBrowserRequest) => {\n setPending(true);\n setError(null);\n const started = performance.now();\n try {\n const next = await execute(request);\n setResult({\n ...next,\n durationMs: next.durationMs ?? performance.now() - started,\n });\n lastRun.current = {\n query: request.query,\n options: request.options,\n ...(request.filters ? { filters: request.filters } : {}),\n ...(next.columns ? { columns: next.columns } : {}),\n };\n } catch (err) {\n setError({\n message: err instanceof Error ? err.message : String(err),\n query: request.query,\n ...(err instanceof QueryBrowserExecutionError && err.diagnostics\n ? { diagnostics: err.diagnostics }\n : {}),\n });\n } finally {\n setPending(false);\n }\n },\n [execute],\n );\n\n const currentQuery = useCallback(() => {\n const view = editor.current;\n if (!view) return initialQuery;\n const selection = view.state.selection.main;\n if (!selection.empty)\n return view.state.sliceDoc(selection.from, selection.to);\n return view.state.doc.toString();\n }, [initialQuery]);\n\n const run = useCallback(async () => {\n const query = currentQuery().trim();\n if (!query || pending) return;\n setEntries(rememberQueryBrowserQuery(id, query));\n // A different statement is a different result set, so neither its filters\n // nor the columns they bind to survive: both name columns the new query may\n // not return.\n const repeat = lastRun.current?.query === query ? lastRun.current : null;\n const carried = repeat ? filters : {};\n if (carried !== filters) setFilters(carried);\n lastRun.current = { query, options };\n executedFilters.current = carried;\n await runRequest({\n query,\n options,\n ...(Object.keys(carried).length > 0 ? { filters: carried } : {}),\n ...(repeat?.columns ? { columns: repeat.columns } : {}),\n ...(debug ? { debug: true } : {}),\n });\n }, [currentQuery, debug, filters, id, options, pending, runRequest]);\n\n // A filter pill is not a draft the way query text is: it commits a discrete\n // value on selection, and the bar already debounces its free-text fields. So\n // a change re-runs the last executed query immediately rather than waiting\n // for Run, which is also how the profile catalog behaves.\n const rerunWithFilters = useCallback(\n async (selection: DataTableFilterSelection) => {\n const previous = lastRun.current;\n if (!previous) {\n throw new Error(\n \"QueryBrowser: a filter changed before any query had run\",\n );\n }\n await runRequest({\n ...previous,\n filters: selection,\n ...(result?.pagination\n ? { pagination: { limit: result.pagination.limit } }\n : {}),\n ...(debug ? { debug: true } : {}),\n });\n },\n [debug, result?.pagination, runRequest],\n );\n\n const rerunAt = useCallback(\n async (pagination: NonNullable<QueryBrowserRequest[\"pagination\"]>) => {\n const previous = lastRun.current;\n if (!previous) {\n throw new Error(\n \"QueryBrowser: pagination changed before any query had run\",\n );\n }\n await runRequest({\n ...previous,\n pagination,\n ...(debug ? { debug: true } : {}),\n });\n },\n [debug, runRequest],\n );\n\n useEffect(() => {\n if (!lastRun.current) return;\n if (filters === executedFilters.current) return;\n executedFilters.current = filters;\n void rerunWithFilters(filters);\n }, [filters, rerunWithFilters]);\n\n executeRef.current = () => void run();\n onQueryChangeRef.current = onQueryChange;\n\n useEffect(() => {\n if (!editorHost.current) return;\n const view = new EditorView({\n parent: editorHost.current,\n state: EditorState.create({\n doc: initialQuery,\n extensions: queryBrowserEditorExtensions(\n () => executeRef.current(),\n (query) => onQueryChangeRef.current?.(query),\n languageConfig.current.of(\n queryBrowserLanguageExtension(language, completion),\n ),\n ),\n }),\n });\n editor.current = view;\n return () => {\n editor.current = null;\n view.destroy();\n };\n }, [id, language]);\n\n useEffect(() => {\n const view = editor.current;\n if (!view) return;\n view.dispatch({\n effects: languageConfig.current.reconfigure(\n queryBrowserLanguageExtension(language, completion),\n ),\n });\n }, [completion, language]);\n\n useEffect(() => {\n const view = editor.current;\n if (!view || view.state.doc.toString() === initialQuery) return;\n view.dispatch({\n changes: { from: 0, to: view.state.doc.length, insert: initialQuery },\n });\n }, [initialQuery]);\n\n useEffect(() => {\n setOptions(initialOptions ?? {});\n }, [initialOptions]);\n\n const updateOptions = useCallback(\n (next: Record<string, unknown>) => {\n setOptions(next);\n onOptionsChange?.(next);\n },\n [onOptionsChange],\n );\n\n useEffect(() => {\n setEntries(readQueryBrowserHistory(id));\n setResult(null);\n setError(null);\n setFilters({});\n setDebug(false);\n lastRun.current = null;\n executedFilters.current = {};\n }, [id]);\n\n const rows = result?.rows ?? [];\n const described = result?.columns ?? [];\n const columns = useMemo(\n () =>\n described.length > 0\n ? serverColumnsToDataTableColumns<Record<string, unknown>>(described)\n : inferColumns(rows, { literalKeys: true }),\n [described, rows],\n );\n const lookupValues = useMemo<DataTableFilterLookup | undefined>(() => {\n if (!lookupFilterValues) return undefined;\n return (request) => {\n const previous = lastRun.current;\n if (!previous) {\n throw new Error(\n \"QueryBrowser: a filter lookup ran before any query had\",\n );\n }\n return lookupFilterValues({ ...request, ...previous, filters });\n };\n }, [filters, lookupFilterValues]);\n const filterConfig = useMemo(\n () =>\n serverFiltersToFilterBar(\n described,\n filters,\n setFilters,\n lookupValues ? { lookupValues } : {},\n ),\n [described, filters, lookupValues],\n );\n const serverFiltered =\n filterConfig.filters.length > 0 || filterConfig.timeRange !== undefined;\n const tablePagination = useMemo<DataTablePagination | undefined>(() => {\n const pagination = result?.pagination;\n if (!pagination) return undefined;\n const shared = {\n pageSize: pagination.limit,\n ...(pagination.total !== undefined ? { total: pagination.total } : {}),\n ...(pagination.totalRelation === \"eq\" ||\n pagination.totalRelation === \"gte\"\n ? { totalRelation: pagination.totalRelation }\n : {}),\n hasMore: pagination.hasMore,\n onPageSizeChange: (limit: number) => void rerunAt({ limit }),\n };\n if (pagination.mode === \"cursor\") {\n return {\n ...shared,\n page: 0,\n cursor: {\n ...(pagination.cursor ? { current: pagination.cursor } : {}),\n ...(pagination.nextCursor ? { next: pagination.nextCursor } : {}),\n onCursorChange: (cursor: string | undefined) =>\n void rerunAt({\n limit: pagination.limit,\n ...(cursor ? { cursor } : {}),\n }),\n },\n };\n }\n const page = Math.floor((pagination.offset ?? 0) / pagination.limit);\n return {\n ...shared,\n page,\n onPageChange: (nextPage: number) =>\n void rerunAt({\n limit: pagination.limit,\n offset: nextPage * pagination.limit,\n }),\n };\n }, [rerunAt, result?.pagination]);\n const defaultResults = (\n <QueryBrowserResults\n result={result}\n pending={pending}\n {...(title ? { title } : {})}\n queryLabel={queryLabel}\n columns={columns}\n filterConfig={filterConfig}\n serverFiltered={serverFiltered}\n {...(tablePagination ? { pagination: tablePagination } : {})}\n />\n );\n\n const workspace = (\n <div className=\"flex h-full min-h-0 flex-col overflow-hidden rounded-xl border bg-card\">\n <div className=\"flex flex-wrap items-center gap-2 border-b px-3 py-2\">\n <div className=\"min-w-0 flex-1\">\n {title && <h2 className=\"truncate text-sm font-semibold\">{title}</h2>}\n <p className=\"text-xs text-muted-foreground\">{queryLabel}</p>\n </div>\n {entries.length > 0 && (\n <select\n aria-label=\"Query history\"\n defaultValue=\"\"\n onChange={(event) => {\n const query = event.target.value;\n const view = editor.current;\n if (!view || !query) return;\n view.dispatch({\n changes: { from: 0, to: view.state.doc.length, insert: query },\n });\n event.target.value = \"\";\n }}\n className=\"h-8 max-w-52 rounded-md border bg-background px-2 text-xs\"\n >\n <option value=\"\">History</option>\n {entries.map((entry) => (\n <option key={`${entry.at}:${entry.query}`} value={entry.query}>\n {entry.query.replace(/\\s+/g, \" \").slice(0, 80)}\n </option>\n ))}\n </select>\n )}\n <Button\n size=\"sm\"\n variant={debug ? \"secondary\" : \"outline\"}\n aria-pressed={debug}\n onClick={() => setDebug((enabled) => !enabled)}\n >\n <Icon icon={UiDebug} className=\"size-4\" />\n Debug\n </Button>\n <Button\n size=\"sm\"\n onClick={() => void run()}\n loading={pending}\n loadingLabel={pending ? \"Running\" : undefined}\n >\n <Icon icon={UiPlay} className=\"size-4\" />\n Run\n </Button>\n </div>\n {optionsSchema &&\n Object.keys(optionsSchema.properties ?? {}).length > 0 && (\n <div className=\"border-b px-3 py-2\">\n <JsonSchemaForm\n schema={optionsSchema}\n value={options}\n onChange={updateOptions}\n size=\"sm\"\n inline\n showPreferencesMenu={false}\n persistPreferences={false}\n />\n </div>\n )}\n <div ref={editorHost} className=\"h-[34%] min-h-44 border-b\" />\n <div className=\"flex min-h-0 flex-1 flex-col overflow-auto p-3\">\n {error ? (\n <div className=\"space-y-3\">\n <ErrorDetails\n diagnostics={{\n message: error.message,\n context: [\n [\"Query\", error.query],\n [\"Language\", language],\n ],\n }}\n />\n {error.diagnostics && (\n <QueryBrowserDiagnosticsPanel diagnostics={error.diagnostics} />\n )}\n </div>\n ) : result && renderResults ? (\n renderResults({ result, defaultView: defaultResults })\n ) : (\n defaultResults\n )}\n </div>\n </div>\n );\n\n return (\n <div className={cn(\"h-[calc(100vh-15rem)] min-h-[32rem]\", className)}>\n {navigator ? (\n <SplitPane defaultSplit={28} left={navigator} right={workspace} />\n ) : (\n workspace\n )}\n </div>\n );\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ class QueryBrowserExecutionError extends Error {
4
+ constructor(message, diagnostics) {
5
+ super(message);
6
+ this.diagnostics = diagnostics;
7
+ this.name = "QueryBrowserExecutionError";
8
+ }
9
+ }
10
+ exports.QueryBrowserExecutionError = QueryBrowserExecutionError;
11
+ //# sourceMappingURL=QueryBrowser.types.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"QueryBrowser.types.cjs","sources":["../../../src/data/query-browser/QueryBrowser.types.ts"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport type { JsonSchemaObject } from \"../../components/json-schema-form-types\";\nimport type { DataTableFilterSelection } from \"../data-table-filter-values\";\nimport type {\n DataTableFilterLookupRequest,\n DataTableFilterLookupResult,\n DataTableServerColumn,\n} from \"../data-table-server-filters\";\nimport type { QueryBrowserCompletion } from \"./QueryBrowser.completion\";\nimport type { QueryBrowserLanguage } from \"./QueryBrowser.editor\";\n\nexport type QueryBrowserPagination = {\n mode: \"offset\" | \"cursor\";\n limit: number;\n offset?: number;\n cursor?: string;\n nextCursor?: string;\n hasMore: boolean;\n total?: number;\n totalRelation: \"eq\" | \"gte\" | \"unknown\";\n consistency: \"live\" | \"snapshot\";\n};\n\nexport type QueryBrowserDiagnostics = {\n provider: string;\n request: {\n query?: string;\n arguments?: unknown[];\n options?: Record<string, unknown>;\n details?: Record<string, unknown>;\n };\n response?: {\n durationMs?: number;\n returnedRows?: number;\n details?: Record<string, unknown>;\n preview?: string;\n contentType?: string;\n truncated?: boolean;\n };\n error?: string;\n};\n\nexport class QueryBrowserExecutionError extends Error {\n constructor(\n message: string,\n readonly diagnostics?: QueryBrowserDiagnostics,\n ) {\n super(message);\n this.name = \"QueryBrowserExecutionError\";\n }\n}\n\nexport type QueryBrowserResult = {\n rows?: Record<string, unknown>[];\n columns?: DataTableServerColumn[];\n affectedRows?: number;\n durationMs?: number;\n message?: string;\n truncated?: boolean;\n limit?: number;\n metadata?: Record<string, unknown>;\n pagination?: QueryBrowserPagination;\n diagnostics?: QueryBrowserDiagnostics;\n};\n\nexport type QueryBrowserRequest = {\n query: string;\n options: Record<string, unknown>;\n filters?: DataTableFilterSelection;\n columns?: DataTableServerColumn[];\n pagination?: { limit: number; offset?: number; cursor?: string };\n debug?: boolean;\n};\n\nexport type QueryBrowserFilterLookupRequest = DataTableFilterLookupRequest & {\n query: string;\n options: Record<string, unknown>;\n filters: DataTableFilterSelection;\n columns?: DataTableServerColumn[];\n};\n\nexport type QueryBrowserFilterLookup = (\n request: QueryBrowserFilterLookupRequest,\n) => Promise<DataTableFilterLookupResult>;\n\nexport type QueryBrowserResultContext = {\n result: QueryBrowserResult;\n defaultView: ReactNode;\n};\n\nexport type QueryBrowserProps = {\n id: string;\n title?: string;\n language?: QueryBrowserLanguage;\n initialQuery?: string;\n queryLabel?: string;\n optionsSchema?: JsonSchemaObject;\n initialOptions?: Record<string, unknown>;\n completion?: QueryBrowserCompletion;\n onQueryChange?: (query: string) => void;\n onOptionsChange?: (options: Record<string, unknown>) => void;\n navigator?: ReactNode;\n execute: (request: QueryBrowserRequest) => Promise<QueryBrowserResult>;\n lookupFilterValues?: QueryBrowserFilterLookup;\n renderResults?: (context: QueryBrowserResultContext) => ReactNode;\n className?: string;\n};\n"],"names":[],"mappings":";;AA0CO,MAAM,mCAAmC,MAAM;AAAA,EACpD,YACE,SACS,aACT;AACA,UAAM,OAAO;AAFJ,SAAA,cAAA;AAGT,SAAK,OAAO;AAAA,EACd;AACF;;"}
@@ -0,0 +1,92 @@
1
+ import { ReactNode } from 'react';
2
+ import { JsonSchemaObject } from '../../components/json-schema-form-types';
3
+ import { DataTableFilterSelection } from '../data-table-filter-values';
4
+ import { DataTableFilterLookupRequest, DataTableFilterLookupResult, DataTableServerColumn } from '../data-table-server-filters';
5
+ import { QueryBrowserCompletion } from './QueryBrowser.completion';
6
+ import { QueryBrowserLanguage } from './QueryBrowser.editor';
7
+ export type QueryBrowserPagination = {
8
+ mode: "offset" | "cursor";
9
+ limit: number;
10
+ offset?: number;
11
+ cursor?: string;
12
+ nextCursor?: string;
13
+ hasMore: boolean;
14
+ total?: number;
15
+ totalRelation: "eq" | "gte" | "unknown";
16
+ consistency: "live" | "snapshot";
17
+ };
18
+ export type QueryBrowserDiagnostics = {
19
+ provider: string;
20
+ request: {
21
+ query?: string;
22
+ arguments?: unknown[];
23
+ options?: Record<string, unknown>;
24
+ details?: Record<string, unknown>;
25
+ };
26
+ response?: {
27
+ durationMs?: number;
28
+ returnedRows?: number;
29
+ details?: Record<string, unknown>;
30
+ preview?: string;
31
+ contentType?: string;
32
+ truncated?: boolean;
33
+ };
34
+ error?: string;
35
+ };
36
+ export declare class QueryBrowserExecutionError extends Error {
37
+ readonly diagnostics?: QueryBrowserDiagnostics | undefined;
38
+ constructor(message: string, diagnostics?: QueryBrowserDiagnostics | undefined);
39
+ }
40
+ export type QueryBrowserResult = {
41
+ rows?: Record<string, unknown>[];
42
+ columns?: DataTableServerColumn[];
43
+ affectedRows?: number;
44
+ durationMs?: number;
45
+ message?: string;
46
+ truncated?: boolean;
47
+ limit?: number;
48
+ metadata?: Record<string, unknown>;
49
+ pagination?: QueryBrowserPagination;
50
+ diagnostics?: QueryBrowserDiagnostics;
51
+ };
52
+ export type QueryBrowserRequest = {
53
+ query: string;
54
+ options: Record<string, unknown>;
55
+ filters?: DataTableFilterSelection;
56
+ columns?: DataTableServerColumn[];
57
+ pagination?: {
58
+ limit: number;
59
+ offset?: number;
60
+ cursor?: string;
61
+ };
62
+ debug?: boolean;
63
+ };
64
+ export type QueryBrowserFilterLookupRequest = DataTableFilterLookupRequest & {
65
+ query: string;
66
+ options: Record<string, unknown>;
67
+ filters: DataTableFilterSelection;
68
+ columns?: DataTableServerColumn[];
69
+ };
70
+ export type QueryBrowserFilterLookup = (request: QueryBrowserFilterLookupRequest) => Promise<DataTableFilterLookupResult>;
71
+ export type QueryBrowserResultContext = {
72
+ result: QueryBrowserResult;
73
+ defaultView: ReactNode;
74
+ };
75
+ export type QueryBrowserProps = {
76
+ id: string;
77
+ title?: string;
78
+ language?: QueryBrowserLanguage;
79
+ initialQuery?: string;
80
+ queryLabel?: string;
81
+ optionsSchema?: JsonSchemaObject;
82
+ initialOptions?: Record<string, unknown>;
83
+ completion?: QueryBrowserCompletion;
84
+ onQueryChange?: (query: string) => void;
85
+ onOptionsChange?: (options: Record<string, unknown>) => void;
86
+ navigator?: ReactNode;
87
+ execute: (request: QueryBrowserRequest) => Promise<QueryBrowserResult>;
88
+ lookupFilterValues?: QueryBrowserFilterLookup;
89
+ renderResults?: (context: QueryBrowserResultContext) => ReactNode;
90
+ className?: string;
91
+ };
92
+ //# sourceMappingURL=QueryBrowser.types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"QueryBrowser.types.d.ts","sourceRoot":"","sources":["../../../src/data/query-browser/QueryBrowser.types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ class QueryBrowserExecutionError extends Error {
2
+ constructor(message, diagnostics) {
3
+ super(message);
4
+ this.diagnostics = diagnostics;
5
+ this.name = "QueryBrowserExecutionError";
6
+ }
7
+ }
8
+ export {
9
+ QueryBrowserExecutionError
10
+ };
11
+ //# sourceMappingURL=QueryBrowser.types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"QueryBrowser.types.js","sources":["../../../src/data/query-browser/QueryBrowser.types.ts"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport type { JsonSchemaObject } from \"../../components/json-schema-form-types\";\nimport type { DataTableFilterSelection } from \"../data-table-filter-values\";\nimport type {\n DataTableFilterLookupRequest,\n DataTableFilterLookupResult,\n DataTableServerColumn,\n} from \"../data-table-server-filters\";\nimport type { QueryBrowserCompletion } from \"./QueryBrowser.completion\";\nimport type { QueryBrowserLanguage } from \"./QueryBrowser.editor\";\n\nexport type QueryBrowserPagination = {\n mode: \"offset\" | \"cursor\";\n limit: number;\n offset?: number;\n cursor?: string;\n nextCursor?: string;\n hasMore: boolean;\n total?: number;\n totalRelation: \"eq\" | \"gte\" | \"unknown\";\n consistency: \"live\" | \"snapshot\";\n};\n\nexport type QueryBrowserDiagnostics = {\n provider: string;\n request: {\n query?: string;\n arguments?: unknown[];\n options?: Record<string, unknown>;\n details?: Record<string, unknown>;\n };\n response?: {\n durationMs?: number;\n returnedRows?: number;\n details?: Record<string, unknown>;\n preview?: string;\n contentType?: string;\n truncated?: boolean;\n };\n error?: string;\n};\n\nexport class QueryBrowserExecutionError extends Error {\n constructor(\n message: string,\n readonly diagnostics?: QueryBrowserDiagnostics,\n ) {\n super(message);\n this.name = \"QueryBrowserExecutionError\";\n }\n}\n\nexport type QueryBrowserResult = {\n rows?: Record<string, unknown>[];\n columns?: DataTableServerColumn[];\n affectedRows?: number;\n durationMs?: number;\n message?: string;\n truncated?: boolean;\n limit?: number;\n metadata?: Record<string, unknown>;\n pagination?: QueryBrowserPagination;\n diagnostics?: QueryBrowserDiagnostics;\n};\n\nexport type QueryBrowserRequest = {\n query: string;\n options: Record<string, unknown>;\n filters?: DataTableFilterSelection;\n columns?: DataTableServerColumn[];\n pagination?: { limit: number; offset?: number; cursor?: string };\n debug?: boolean;\n};\n\nexport type QueryBrowserFilterLookupRequest = DataTableFilterLookupRequest & {\n query: string;\n options: Record<string, unknown>;\n filters: DataTableFilterSelection;\n columns?: DataTableServerColumn[];\n};\n\nexport type QueryBrowserFilterLookup = (\n request: QueryBrowserFilterLookupRequest,\n) => Promise<DataTableFilterLookupResult>;\n\nexport type QueryBrowserResultContext = {\n result: QueryBrowserResult;\n defaultView: ReactNode;\n};\n\nexport type QueryBrowserProps = {\n id: string;\n title?: string;\n language?: QueryBrowserLanguage;\n initialQuery?: string;\n queryLabel?: string;\n optionsSchema?: JsonSchemaObject;\n initialOptions?: Record<string, unknown>;\n completion?: QueryBrowserCompletion;\n onQueryChange?: (query: string) => void;\n onOptionsChange?: (options: Record<string, unknown>) => void;\n navigator?: ReactNode;\n execute: (request: QueryBrowserRequest) => Promise<QueryBrowserResult>;\n lookupFilterValues?: QueryBrowserFilterLookup;\n renderResults?: (context: QueryBrowserResultContext) => ReactNode;\n className?: string;\n};\n"],"names":[],"mappings":"AA0CO,MAAM,mCAAmC,MAAM;AAAA,EACpD,YACE,SACS,aACT;AACA,UAAM,OAAO;AAFJ,SAAA,cAAA;AAGT,SAAK,OAAO;AAAA,EACd;AACF;"}
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const jsxRuntime = require("react/jsx-runtime");
4
+ function JSONBlock({ label, value }) {
5
+ if (value == null) return null;
6
+ if (Array.isArray(value) && value.length === 0) return null;
7
+ if (typeof value === "object" && !Array.isArray(value) && Object.keys(value).length === 0) {
8
+ return null;
9
+ }
10
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0", children: [
11
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-1 text-[11px] font-medium uppercase tracking-wide text-muted-foreground", children: label }),
12
+ /* @__PURE__ */ jsxRuntime.jsx("pre", { className: "max-h-56 overflow-auto whitespace-pre-wrap break-all rounded-md bg-muted/60 p-2 text-xs", children: JSON.stringify(value, null, 2) })
13
+ ] });
14
+ }
15
+ function QueryBrowserDiagnosticsPanel({
16
+ diagnostics
17
+ }) {
18
+ var _a;
19
+ return /* @__PURE__ */ jsxRuntime.jsxs("details", { open: true, className: "shrink-0 rounded-md border bg-background", children: [
20
+ /* @__PURE__ */ jsxRuntime.jsxs("summary", { className: "cursor-pointer px-3 py-2 text-sm font-medium", children: [
21
+ "Provider debug",
22
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-2 font-normal text-muted-foreground", children: diagnostics.provider })
23
+ ] }),
24
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid gap-3 border-t p-3 lg:grid-cols-2", children: [
25
+ /* @__PURE__ */ jsxRuntime.jsxs("section", { className: "min-w-0 space-y-2", "aria-label": "Provider request", children: [
26
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-xs font-semibold uppercase tracking-wide text-muted-foreground", children: "Request" }),
27
+ /* @__PURE__ */ jsxRuntime.jsx(
28
+ "pre",
29
+ {
30
+ "aria-label": "Provider query",
31
+ className: "max-h-72 overflow-auto whitespace-pre-wrap break-all rounded-md bg-muted/60 p-2 text-xs",
32
+ children: diagnostics.request.query || "(no query text)"
33
+ }
34
+ ),
35
+ /* @__PURE__ */ jsxRuntime.jsx(JSONBlock, { label: "Arguments", value: diagnostics.request.arguments }),
36
+ /* @__PURE__ */ jsxRuntime.jsx(JSONBlock, { label: "Options", value: diagnostics.request.options }),
37
+ /* @__PURE__ */ jsxRuntime.jsx(JSONBlock, { label: "Details", value: diagnostics.request.details })
38
+ ] }),
39
+ /* @__PURE__ */ jsxRuntime.jsxs("section", { className: "min-w-0 space-y-2", "aria-label": "Provider response", children: [
40
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-xs font-semibold uppercase tracking-wide text-muted-foreground", children: "Response" }),
41
+ diagnostics.error && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-md border border-destructive/40 bg-destructive/5 p-2 text-xs text-destructive", children: diagnostics.error }),
42
+ /* @__PURE__ */ jsxRuntime.jsx(JSONBlock, { label: "Summary", value: diagnostics.response }),
43
+ ((_a = diagnostics.response) == null ? void 0 : _a.preview) && /* @__PURE__ */ jsxRuntime.jsx(
44
+ "pre",
45
+ {
46
+ "aria-label": "Provider response preview",
47
+ className: "max-h-72 overflow-auto whitespace-pre-wrap break-all rounded-md bg-muted/60 p-2 text-xs",
48
+ children: diagnostics.response.preview
49
+ }
50
+ )
51
+ ] })
52
+ ] })
53
+ ] });
54
+ }
55
+ exports.QueryBrowserDiagnosticsPanel = QueryBrowserDiagnosticsPanel;
56
+ //# sourceMappingURL=QueryBrowserDiagnosticsPanel.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"QueryBrowserDiagnosticsPanel.cjs","sources":["../../../src/data/query-browser/QueryBrowserDiagnosticsPanel.tsx"],"sourcesContent":["import type { QueryBrowserDiagnostics } from \"./QueryBrowser.types\";\n\nfunction JSONBlock({ label, value }: { label: string; value: unknown }) {\n if (value == null) return null;\n if (Array.isArray(value) && value.length === 0) return null;\n if (\n typeof value === \"object\" &&\n !Array.isArray(value) &&\n Object.keys(value).length === 0\n ) {\n return null;\n }\n return (\n <div className=\"min-w-0\">\n <div className=\"mb-1 text-[11px] font-medium uppercase tracking-wide text-muted-foreground\">\n {label}\n </div>\n <pre className=\"max-h-56 overflow-auto whitespace-pre-wrap break-all rounded-md bg-muted/60 p-2 text-xs\">\n {JSON.stringify(value, null, 2)}\n </pre>\n </div>\n );\n}\n\nexport function QueryBrowserDiagnosticsPanel({\n diagnostics,\n}: {\n diagnostics: QueryBrowserDiagnostics;\n}) {\n return (\n <details open className=\"shrink-0 rounded-md border bg-background\">\n <summary className=\"cursor-pointer px-3 py-2 text-sm font-medium\">\n Provider debug\n <span className=\"ml-2 font-normal text-muted-foreground\">\n {diagnostics.provider}\n </span>\n </summary>\n <div className=\"grid gap-3 border-t p-3 lg:grid-cols-2\">\n <section className=\"min-w-0 space-y-2\" aria-label=\"Provider request\">\n <h3 className=\"text-xs font-semibold uppercase tracking-wide text-muted-foreground\">\n Request\n </h3>\n <pre\n aria-label=\"Provider query\"\n className=\"max-h-72 overflow-auto whitespace-pre-wrap break-all rounded-md bg-muted/60 p-2 text-xs\"\n >\n {diagnostics.request.query || \"(no query text)\"}\n </pre>\n <JSONBlock label=\"Arguments\" value={diagnostics.request.arguments} />\n <JSONBlock label=\"Options\" value={diagnostics.request.options} />\n <JSONBlock label=\"Details\" value={diagnostics.request.details} />\n </section>\n <section className=\"min-w-0 space-y-2\" aria-label=\"Provider response\">\n <h3 className=\"text-xs font-semibold uppercase tracking-wide text-muted-foreground\">\n Response\n </h3>\n {diagnostics.error && (\n <div className=\"rounded-md border border-destructive/40 bg-destructive/5 p-2 text-xs text-destructive\">\n {diagnostics.error}\n </div>\n )}\n <JSONBlock label=\"Summary\" value={diagnostics.response} />\n {diagnostics.response?.preview && (\n <pre\n aria-label=\"Provider response preview\"\n className=\"max-h-72 overflow-auto whitespace-pre-wrap break-all rounded-md bg-muted/60 p-2 text-xs\"\n >\n {diagnostics.response.preview}\n </pre>\n )}\n </section>\n </div>\n </details>\n );\n}\n"],"names":["jsxs","jsx"],"mappings":";;;AAEA,SAAS,UAAU,EAAE,OAAO,SAA4C;AACtE,MAAI,SAAS,KAAM,QAAO;AAC1B,MAAI,MAAM,QAAQ,KAAK,KAAK,MAAM,WAAW,EAAG,QAAO;AACvD,MACE,OAAO,UAAU,YACjB,CAAC,MAAM,QAAQ,KAAK,KACpB,OAAO,KAAK,KAAK,EAAE,WAAW,GAC9B;AACA,WAAO;AAAA,EACT;AACA,SACEA,2BAAAA,KAAC,OAAA,EAAI,WAAU,WACb,UAAA;AAAA,IAAAC,2BAAAA,IAAC,OAAA,EAAI,WAAU,8EACZ,UAAA,OACH;AAAA,IACAA,2BAAAA,IAAC,SAAI,WAAU,2FACZ,eAAK,UAAU,OAAO,MAAM,CAAC,EAAA,CAChC;AAAA,EAAA,GACF;AAEJ;AAEO,SAAS,6BAA6B;AAAA,EAC3C;AACF,GAEG;;AACD,SACED,2BAAAA,KAAC,WAAA,EAAQ,MAAI,MAAC,WAAU,4CACtB,UAAA;AAAA,IAAAA,2BAAAA,KAAC,WAAA,EAAQ,WAAU,gDAA+C,UAAA;AAAA,MAAA;AAAA,MAEhEC,2BAAAA,IAAC,QAAA,EAAK,WAAU,0CACb,sBAAY,SAAA,CACf;AAAA,IAAA,GACF;AAAA,IACAD,2BAAAA,KAAC,OAAA,EAAI,WAAU,0CACb,UAAA;AAAA,MAAAA,2BAAAA,KAAC,WAAA,EAAQ,WAAU,qBAAoB,cAAW,oBAChD,UAAA;AAAA,QAAAC,2BAAAA,IAAC,MAAA,EAAG,WAAU,uEAAsE,UAAA,WAEpF;AAAA,QACAA,2BAAAA;AAAAA,UAAC;AAAA,UAAA;AAAA,YACC,cAAW;AAAA,YACX,WAAU;AAAA,YAET,UAAA,YAAY,QAAQ,SAAS;AAAA,UAAA;AAAA,QAAA;AAAA,uCAE/B,WAAA,EAAU,OAAM,aAAY,OAAO,YAAY,QAAQ,WAAW;AAAA,uCAClE,WAAA,EAAU,OAAM,WAAU,OAAO,YAAY,QAAQ,SAAS;AAAA,uCAC9D,WAAA,EAAU,OAAM,WAAU,OAAO,YAAY,QAAQ,QAAA,CAAS;AAAA,MAAA,GACjE;AAAA,MACAD,2BAAAA,KAAC,WAAA,EAAQ,WAAU,qBAAoB,cAAW,qBAChD,UAAA;AAAA,QAAAC,2BAAAA,IAAC,MAAA,EAAG,WAAU,uEAAsE,UAAA,YAEpF;AAAA,QACC,YAAY,SACXA,2BAAAA,IAAC,SAAI,WAAU,yFACZ,sBAAY,OACf;AAAA,uCAED,WAAA,EAAU,OAAM,WAAU,OAAO,YAAY,UAAU;AAAA,UACvD,iBAAY,aAAZ,mBAAsB,YACrBA,2BAAAA;AAAAA,UAAC;AAAA,UAAA;AAAA,YACC,cAAW;AAAA,YACX,WAAU;AAAA,YAET,sBAAY,SAAS;AAAA,UAAA;AAAA,QAAA;AAAA,MACxB,EAAA,CAEJ;AAAA,IAAA,EAAA,CACF;AAAA,EAAA,GACF;AAEJ;;"}
@@ -0,0 +1,5 @@
1
+ import { QueryBrowserDiagnostics } from './QueryBrowser.types';
2
+ export declare function QueryBrowserDiagnosticsPanel({ diagnostics, }: {
3
+ diagnostics: QueryBrowserDiagnostics;
4
+ }): import("react/jsx-runtime").JSX.Element;
5
+ //# sourceMappingURL=QueryBrowserDiagnosticsPanel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"QueryBrowserDiagnosticsPanel.d.ts","sourceRoot":"","sources":["../../../src/data/query-browser/QueryBrowserDiagnosticsPanel.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAwBpE,wBAAgB,4BAA4B,CAAC,EAC3C,WAAW,GACZ,EAAE;IACD,WAAW,EAAE,uBAAuB,CAAC;CACtC,2CA8CA"}
@@ -0,0 +1,56 @@
1
+ import { jsxs, jsx } from "react/jsx-runtime";
2
+ function JSONBlock({ label, value }) {
3
+ if (value == null) return null;
4
+ if (Array.isArray(value) && value.length === 0) return null;
5
+ if (typeof value === "object" && !Array.isArray(value) && Object.keys(value).length === 0) {
6
+ return null;
7
+ }
8
+ return /* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
9
+ /* @__PURE__ */ jsx("div", { className: "mb-1 text-[11px] font-medium uppercase tracking-wide text-muted-foreground", children: label }),
10
+ /* @__PURE__ */ jsx("pre", { className: "max-h-56 overflow-auto whitespace-pre-wrap break-all rounded-md bg-muted/60 p-2 text-xs", children: JSON.stringify(value, null, 2) })
11
+ ] });
12
+ }
13
+ function QueryBrowserDiagnosticsPanel({
14
+ diagnostics
15
+ }) {
16
+ var _a;
17
+ return /* @__PURE__ */ jsxs("details", { open: true, className: "shrink-0 rounded-md border bg-background", children: [
18
+ /* @__PURE__ */ jsxs("summary", { className: "cursor-pointer px-3 py-2 text-sm font-medium", children: [
19
+ "Provider debug",
20
+ /* @__PURE__ */ jsx("span", { className: "ml-2 font-normal text-muted-foreground", children: diagnostics.provider })
21
+ ] }),
22
+ /* @__PURE__ */ jsxs("div", { className: "grid gap-3 border-t p-3 lg:grid-cols-2", children: [
23
+ /* @__PURE__ */ jsxs("section", { className: "min-w-0 space-y-2", "aria-label": "Provider request", children: [
24
+ /* @__PURE__ */ jsx("h3", { className: "text-xs font-semibold uppercase tracking-wide text-muted-foreground", children: "Request" }),
25
+ /* @__PURE__ */ jsx(
26
+ "pre",
27
+ {
28
+ "aria-label": "Provider query",
29
+ className: "max-h-72 overflow-auto whitespace-pre-wrap break-all rounded-md bg-muted/60 p-2 text-xs",
30
+ children: diagnostics.request.query || "(no query text)"
31
+ }
32
+ ),
33
+ /* @__PURE__ */ jsx(JSONBlock, { label: "Arguments", value: diagnostics.request.arguments }),
34
+ /* @__PURE__ */ jsx(JSONBlock, { label: "Options", value: diagnostics.request.options }),
35
+ /* @__PURE__ */ jsx(JSONBlock, { label: "Details", value: diagnostics.request.details })
36
+ ] }),
37
+ /* @__PURE__ */ jsxs("section", { className: "min-w-0 space-y-2", "aria-label": "Provider response", children: [
38
+ /* @__PURE__ */ jsx("h3", { className: "text-xs font-semibold uppercase tracking-wide text-muted-foreground", children: "Response" }),
39
+ diagnostics.error && /* @__PURE__ */ jsx("div", { className: "rounded-md border border-destructive/40 bg-destructive/5 p-2 text-xs text-destructive", children: diagnostics.error }),
40
+ /* @__PURE__ */ jsx(JSONBlock, { label: "Summary", value: diagnostics.response }),
41
+ ((_a = diagnostics.response) == null ? void 0 : _a.preview) && /* @__PURE__ */ jsx(
42
+ "pre",
43
+ {
44
+ "aria-label": "Provider response preview",
45
+ className: "max-h-72 overflow-auto whitespace-pre-wrap break-all rounded-md bg-muted/60 p-2 text-xs",
46
+ children: diagnostics.response.preview
47
+ }
48
+ )
49
+ ] })
50
+ ] })
51
+ ] });
52
+ }
53
+ export {
54
+ QueryBrowserDiagnosticsPanel
55
+ };
56
+ //# sourceMappingURL=QueryBrowserDiagnosticsPanel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"QueryBrowserDiagnosticsPanel.js","sources":["../../../src/data/query-browser/QueryBrowserDiagnosticsPanel.tsx"],"sourcesContent":["import type { QueryBrowserDiagnostics } from \"./QueryBrowser.types\";\n\nfunction JSONBlock({ label, value }: { label: string; value: unknown }) {\n if (value == null) return null;\n if (Array.isArray(value) && value.length === 0) return null;\n if (\n typeof value === \"object\" &&\n !Array.isArray(value) &&\n Object.keys(value).length === 0\n ) {\n return null;\n }\n return (\n <div className=\"min-w-0\">\n <div className=\"mb-1 text-[11px] font-medium uppercase tracking-wide text-muted-foreground\">\n {label}\n </div>\n <pre className=\"max-h-56 overflow-auto whitespace-pre-wrap break-all rounded-md bg-muted/60 p-2 text-xs\">\n {JSON.stringify(value, null, 2)}\n </pre>\n </div>\n );\n}\n\nexport function QueryBrowserDiagnosticsPanel({\n diagnostics,\n}: {\n diagnostics: QueryBrowserDiagnostics;\n}) {\n return (\n <details open className=\"shrink-0 rounded-md border bg-background\">\n <summary className=\"cursor-pointer px-3 py-2 text-sm font-medium\">\n Provider debug\n <span className=\"ml-2 font-normal text-muted-foreground\">\n {diagnostics.provider}\n </span>\n </summary>\n <div className=\"grid gap-3 border-t p-3 lg:grid-cols-2\">\n <section className=\"min-w-0 space-y-2\" aria-label=\"Provider request\">\n <h3 className=\"text-xs font-semibold uppercase tracking-wide text-muted-foreground\">\n Request\n </h3>\n <pre\n aria-label=\"Provider query\"\n className=\"max-h-72 overflow-auto whitespace-pre-wrap break-all rounded-md bg-muted/60 p-2 text-xs\"\n >\n {diagnostics.request.query || \"(no query text)\"}\n </pre>\n <JSONBlock label=\"Arguments\" value={diagnostics.request.arguments} />\n <JSONBlock label=\"Options\" value={diagnostics.request.options} />\n <JSONBlock label=\"Details\" value={diagnostics.request.details} />\n </section>\n <section className=\"min-w-0 space-y-2\" aria-label=\"Provider response\">\n <h3 className=\"text-xs font-semibold uppercase tracking-wide text-muted-foreground\">\n Response\n </h3>\n {diagnostics.error && (\n <div className=\"rounded-md border border-destructive/40 bg-destructive/5 p-2 text-xs text-destructive\">\n {diagnostics.error}\n </div>\n )}\n <JSONBlock label=\"Summary\" value={diagnostics.response} />\n {diagnostics.response?.preview && (\n <pre\n aria-label=\"Provider response preview\"\n className=\"max-h-72 overflow-auto whitespace-pre-wrap break-all rounded-md bg-muted/60 p-2 text-xs\"\n >\n {diagnostics.response.preview}\n </pre>\n )}\n </section>\n </div>\n </details>\n );\n}\n"],"names":[],"mappings":";AAEA,SAAS,UAAU,EAAE,OAAO,SAA4C;AACtE,MAAI,SAAS,KAAM,QAAO;AAC1B,MAAI,MAAM,QAAQ,KAAK,KAAK,MAAM,WAAW,EAAG,QAAO;AACvD,MACE,OAAO,UAAU,YACjB,CAAC,MAAM,QAAQ,KAAK,KACpB,OAAO,KAAK,KAAK,EAAE,WAAW,GAC9B;AACA,WAAO;AAAA,EACT;AACA,SACE,qBAAC,OAAA,EAAI,WAAU,WACb,UAAA;AAAA,IAAA,oBAAC,OAAA,EAAI,WAAU,8EACZ,UAAA,OACH;AAAA,IACA,oBAAC,SAAI,WAAU,2FACZ,eAAK,UAAU,OAAO,MAAM,CAAC,EAAA,CAChC;AAAA,EAAA,GACF;AAEJ;AAEO,SAAS,6BAA6B;AAAA,EAC3C;AACF,GAEG;;AACD,SACE,qBAAC,WAAA,EAAQ,MAAI,MAAC,WAAU,4CACtB,UAAA;AAAA,IAAA,qBAAC,WAAA,EAAQ,WAAU,gDAA+C,UAAA;AAAA,MAAA;AAAA,MAEhE,oBAAC,QAAA,EAAK,WAAU,0CACb,sBAAY,SAAA,CACf;AAAA,IAAA,GACF;AAAA,IACA,qBAAC,OAAA,EAAI,WAAU,0CACb,UAAA;AAAA,MAAA,qBAAC,WAAA,EAAQ,WAAU,qBAAoB,cAAW,oBAChD,UAAA;AAAA,QAAA,oBAAC,MAAA,EAAG,WAAU,uEAAsE,UAAA,WAEpF;AAAA,QACA;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,cAAW;AAAA,YACX,WAAU;AAAA,YAET,UAAA,YAAY,QAAQ,SAAS;AAAA,UAAA;AAAA,QAAA;AAAA,4BAE/B,WAAA,EAAU,OAAM,aAAY,OAAO,YAAY,QAAQ,WAAW;AAAA,4BAClE,WAAA,EAAU,OAAM,WAAU,OAAO,YAAY,QAAQ,SAAS;AAAA,4BAC9D,WAAA,EAAU,OAAM,WAAU,OAAO,YAAY,QAAQ,QAAA,CAAS;AAAA,MAAA,GACjE;AAAA,MACA,qBAAC,WAAA,EAAQ,WAAU,qBAAoB,cAAW,qBAChD,UAAA;AAAA,QAAA,oBAAC,MAAA,EAAG,WAAU,uEAAsE,UAAA,YAEpF;AAAA,QACC,YAAY,SACX,oBAAC,SAAI,WAAU,yFACZ,sBAAY,OACf;AAAA,4BAED,WAAA,EAAU,OAAM,WAAU,OAAO,YAAY,UAAU;AAAA,UACvD,iBAAY,aAAZ,mBAAsB,YACrB;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,cAAW;AAAA,YACX,WAAU;AAAA,YAET,sBAAY,SAAS;AAAA,UAAA;AAAA,QAAA;AAAA,MACxB,EAAA,CAEJ;AAAA,IAAA,EAAA,CACF;AAAA,EAAA,GACF;AAEJ;"}
@@ -0,0 +1,80 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const jsxRuntime = require("react/jsx-runtime");
4
+ const DataTable = require("../DataTable.cjs");
5
+ const Properties = require("../Properties.cjs");
6
+ const QueryBrowserDiagnosticsPanel = require("./QueryBrowserDiagnosticsPanel.cjs");
7
+ function QueryBrowserResults({
8
+ result,
9
+ pending,
10
+ title,
11
+ queryLabel,
12
+ columns,
13
+ filterConfig,
14
+ serverFiltered,
15
+ pagination
16
+ }) {
17
+ if (!result) {
18
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid min-h-40 place-items-center text-sm text-muted-foreground", children: "Run a query to see results." });
19
+ }
20
+ const rows = result.rows ?? [];
21
+ const described = result.columns ?? [];
22
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-h-0 flex-1 flex-col gap-2", children: [
23
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-3 text-xs text-muted-foreground", children: [
24
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
25
+ rows.length.toLocaleString(),
26
+ " rows",
27
+ result.truncated ? "+" : ""
28
+ ] }),
29
+ result.truncated && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-amber-600 [[data-theme=dark]_&]:text-amber-400", children: [
30
+ "stopped at the console's",
31
+ " ",
32
+ (result.limit ?? rows.length).toLocaleString(),
33
+ "-row bound; narrow the query to see the rest"
34
+ ] }),
35
+ result.affectedRows !== void 0 && /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
36
+ result.affectedRows.toLocaleString(),
37
+ " affected"
38
+ ] }),
39
+ result.durationMs !== void 0 && /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
40
+ Math.round(result.durationMs),
41
+ " ms"
42
+ ] }),
43
+ result.message && /* @__PURE__ */ jsxRuntime.jsx("span", { children: result.message })
44
+ ] }),
45
+ rows.length > 0 || described.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(
46
+ DataTable.DataTable,
47
+ {
48
+ data: rows,
49
+ columns,
50
+ loading: pending,
51
+ autoFilter: false,
52
+ ...serverFiltered ? {
53
+ manualFilter: true,
54
+ externalFilters: filterConfig.filters,
55
+ ...filterConfig.timeRange ? { externalTimeRange: filterConfig.timeRange } : {}
56
+ } : { showGlobalFilter: true },
57
+ showFullscreenControl: true,
58
+ fullscreenTitle: title ?? queryLabel,
59
+ detailStyle: "dialog",
60
+ detailDialogTitle: "Row details",
61
+ renderExpandedRow: (row) => /* @__PURE__ */ jsxRuntime.jsx(
62
+ Properties.Properties,
63
+ {
64
+ items: Object.entries(row).map(([key, value]) => ({
65
+ key,
66
+ value
67
+ })),
68
+ renderLabel: (key) => key,
69
+ density: "compact"
70
+ }
71
+ ),
72
+ ...pagination ? { pagination } : {},
73
+ className: "min-h-72 flex-1"
74
+ }
75
+ ) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-md border border-dashed p-6 text-sm text-muted-foreground", children: result.message ?? "Statement completed with no rows." }),
76
+ result.diagnostics && /* @__PURE__ */ jsxRuntime.jsx(QueryBrowserDiagnosticsPanel.QueryBrowserDiagnosticsPanel, { diagnostics: result.diagnostics })
77
+ ] });
78
+ }
79
+ exports.QueryBrowserResults = QueryBrowserResults;
80
+ //# sourceMappingURL=QueryBrowserResults.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"QueryBrowserResults.cjs","sources":["../../../src/data/query-browser/QueryBrowserResults.tsx"],"sourcesContent":["import {\n DataTable,\n type DataTableColumn,\n type DataTablePagination,\n} from \"../DataTable\";\nimport { Properties } from \"../Properties\";\nimport type { serverFiltersToFilterBar } from \"../data-table-server-filters\";\nimport type { QueryBrowserResult } from \"./QueryBrowser.types\";\nimport { QueryBrowserDiagnosticsPanel } from \"./QueryBrowserDiagnosticsPanel\";\n\ntype QueryBrowserResultsProps = {\n result: QueryBrowserResult | null;\n pending: boolean;\n title?: string;\n queryLabel: string;\n columns: DataTableColumn<Record<string, unknown>>[];\n filterConfig: ReturnType<typeof serverFiltersToFilterBar>;\n serverFiltered: boolean;\n pagination?: DataTablePagination;\n};\n\nexport function QueryBrowserResults({\n result,\n pending,\n title,\n queryLabel,\n columns,\n filterConfig,\n serverFiltered,\n pagination,\n}: QueryBrowserResultsProps) {\n if (!result) {\n return (\n <div className=\"grid min-h-40 place-items-center text-sm text-muted-foreground\">\n Run a query to see results.\n </div>\n );\n }\n const rows = result.rows ?? [];\n const described = result.columns ?? [];\n return (\n <div className=\"flex min-h-0 flex-1 flex-col gap-2\">\n <div className=\"flex flex-wrap items-center gap-3 text-xs text-muted-foreground\">\n <span>\n {rows.length.toLocaleString()} rows{result.truncated ? \"+\" : \"\"}\n </span>\n {result.truncated && (\n <span className=\"text-amber-600 [[data-theme=dark]_&]:text-amber-400\">\n stopped at the console&apos;s{\" \"}\n {(result.limit ?? rows.length).toLocaleString()}-row bound; narrow\n the query to see the rest\n </span>\n )}\n {result.affectedRows !== undefined && (\n <span>{result.affectedRows.toLocaleString()} affected</span>\n )}\n {result.durationMs !== undefined && (\n <span>{Math.round(result.durationMs)} ms</span>\n )}\n {result.message && <span>{result.message}</span>}\n </div>\n {rows.length > 0 || described.length > 0 ? (\n <DataTable\n data={rows}\n columns={columns}\n loading={pending}\n autoFilter={false}\n {...(serverFiltered\n ? {\n manualFilter: true,\n externalFilters: filterConfig.filters,\n ...(filterConfig.timeRange\n ? { externalTimeRange: filterConfig.timeRange }\n : {}),\n }\n : { showGlobalFilter: true })}\n showFullscreenControl\n fullscreenTitle={title ?? queryLabel}\n detailStyle=\"dialog\"\n detailDialogTitle=\"Row details\"\n renderExpandedRow={(row) => (\n <Properties\n items={Object.entries(row).map(([key, value]) => ({\n key,\n value,\n }))}\n renderLabel={(key) => key}\n density=\"compact\"\n />\n )}\n {...(pagination ? { pagination } : {})}\n className=\"min-h-72 flex-1\"\n />\n ) : (\n <div className=\"rounded-md border border-dashed p-6 text-sm text-muted-foreground\">\n {result.message ?? \"Statement completed with no rows.\"}\n </div>\n )}\n {result.diagnostics && (\n <QueryBrowserDiagnosticsPanel diagnostics={result.diagnostics} />\n )}\n </div>\n );\n}\n"],"names":["jsx","jsxs","DataTable","Properties","QueryBrowserDiagnosticsPanel"],"mappings":";;;;;;AAqBO,SAAS,oBAAoB;AAAA,EAClC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAA6B;AAC3B,MAAI,CAAC,QAAQ;AACX,WACEA,2BAAAA,IAAC,OAAA,EAAI,WAAU,kEAAiE,UAAA,+BAEhF;AAAA,EAEJ;AACA,QAAM,OAAO,OAAO,QAAQ,CAAA;AAC5B,QAAM,YAAY,OAAO,WAAW,CAAA;AACpC,SACEC,2BAAAA,KAAC,OAAA,EAAI,WAAU,sCACb,UAAA;AAAA,IAAAA,2BAAAA,KAAC,OAAA,EAAI,WAAU,mEACb,UAAA;AAAA,MAAAA,gCAAC,QAAA,EACE,UAAA;AAAA,QAAA,KAAK,OAAO,eAAA;AAAA,QAAiB;AAAA,QAAM,OAAO,YAAY,MAAM;AAAA,MAAA,GAC/D;AAAA,MACC,OAAO,aACNA,gCAAC,QAAA,EAAK,WAAU,uDAAsD,UAAA;AAAA,QAAA;AAAA,QACtC;AAAA,SAC5B,OAAO,SAAS,KAAK,QAAQ,eAAA;AAAA,QAAiB;AAAA,MAAA,GAElD;AAAA,MAED,OAAO,iBAAiB,UACvBA,2BAAAA,KAAC,QAAA,EAAM,UAAA;AAAA,QAAA,OAAO,aAAa,eAAA;AAAA,QAAiB;AAAA,MAAA,GAAS;AAAA,MAEtD,OAAO,eAAe,UACrBA,2BAAAA,KAAC,QAAA,EAAM,UAAA;AAAA,QAAA,KAAK,MAAM,OAAO,UAAU;AAAA,QAAE;AAAA,MAAA,GAAG;AAAA,MAEzC,OAAO,WAAWD,+BAAC,QAAA,EAAM,iBAAO,QAAA,CAAQ;AAAA,IAAA,GAC3C;AAAA,IACC,KAAK,SAAS,KAAK,UAAU,SAAS,IACrCA,2BAAAA;AAAAA,MAACE,UAAAA;AAAAA,MAAA;AAAA,QACC,MAAM;AAAA,QACN;AAAA,QACA,SAAS;AAAA,QACT,YAAY;AAAA,QACX,GAAI,iBACD;AAAA,UACE,cAAc;AAAA,UACd,iBAAiB,aAAa;AAAA,UAC9B,GAAI,aAAa,YACb,EAAE,mBAAmB,aAAa,UAAA,IAClC,CAAA;AAAA,QAAC,IAEP,EAAE,kBAAkB,KAAA;AAAA,QACxB,uBAAqB;AAAA,QACrB,iBAAiB,SAAS;AAAA,QAC1B,aAAY;AAAA,QACZ,mBAAkB;AAAA,QAClB,mBAAmB,CAAC,QAClBF,2BAAAA;AAAAA,UAACG,WAAAA;AAAAA,UAAA;AAAA,YACC,OAAO,OAAO,QAAQ,GAAG,EAAE,IAAI,CAAC,CAAC,KAAK,KAAK,OAAO;AAAA,cAChD;AAAA,cACA;AAAA,YAAA,EACA;AAAA,YACF,aAAa,CAAC,QAAQ;AAAA,YACtB,SAAQ;AAAA,UAAA;AAAA,QAAA;AAAA,QAGX,GAAI,aAAa,EAAE,WAAA,IAAe,CAAA;AAAA,QACnC,WAAU;AAAA,MAAA;AAAA,IAAA,IAGZH,2BAAAA,IAAC,OAAA,EAAI,WAAU,qEACZ,UAAA,OAAO,WAAW,qCACrB;AAAA,IAED,OAAO,eACNA,+BAACI,6BAAAA,8BAAA,EAA6B,aAAa,OAAO,YAAA,CAAa;AAAA,EAAA,GAEnE;AAEJ;;"}
@@ -0,0 +1,16 @@
1
+ import { DataTableColumn, DataTablePagination } from '../DataTable';
2
+ import { serverFiltersToFilterBar } from '../data-table-server-filters';
3
+ import { QueryBrowserResult } from './QueryBrowser.types';
4
+ type QueryBrowserResultsProps = {
5
+ result: QueryBrowserResult | null;
6
+ pending: boolean;
7
+ title?: string;
8
+ queryLabel: string;
9
+ columns: DataTableColumn<Record<string, unknown>>[];
10
+ filterConfig: ReturnType<typeof serverFiltersToFilterBar>;
11
+ serverFiltered: boolean;
12
+ pagination?: DataTablePagination;
13
+ };
14
+ export declare function QueryBrowserResults({ result, pending, title, queryLabel, columns, filterConfig, serverFiltered, pagination, }: QueryBrowserResultsProps): import("react/jsx-runtime").JSX.Element;
15
+ export {};
16
+ //# sourceMappingURL=QueryBrowserResults.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"QueryBrowserResults.d.ts","sourceRoot":"","sources":["../../../src/data/query-browser/QueryBrowserResults.tsx"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,eAAe,EACpB,KAAK,mBAAmB,EACzB,MAAM,cAAc,CAAC;AAEtB,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AAC7E,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAG/D,KAAK,wBAAwB,GAAG;IAC9B,MAAM,EAAE,kBAAkB,GAAG,IAAI,CAAC;IAClC,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,eAAe,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EAAE,CAAC;IACpD,YAAY,EAAE,UAAU,CAAC,OAAO,wBAAwB,CAAC,CAAC;IAC1D,cAAc,EAAE,OAAO,CAAC;IACxB,UAAU,CAAC,EAAE,mBAAmB,CAAC;CAClC,CAAC;AAEF,wBAAgB,mBAAmB,CAAC,EAClC,MAAM,EACN,OAAO,EACP,KAAK,EACL,UAAU,EACV,OAAO,EACP,YAAY,EACZ,cAAc,EACd,UAAU,GACX,EAAE,wBAAwB,2CAyE1B"}