@calliopelabs/ui 0.14.0 → 0.18.0

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 (127) hide show
  1. package/README.md +235 -1
  2. package/dist/agent/AgentChat.d.ts +8 -1
  3. package/dist/agent/AgentChat.js +43 -2
  4. package/dist/agent/WorkflowRenderers.d.ts +61 -0
  5. package/dist/agent/WorkflowRenderers.js +102 -0
  6. package/dist/agent/controller.d.ts +19 -0
  7. package/dist/agent/controller.js +33 -0
  8. package/dist/agent/copilotkit/CopilotKitAgentProvider.js +2 -2
  9. package/dist/agent/index.d.ts +4 -2
  10. package/dist/agent/index.js +3 -1
  11. package/dist/agent/mock.d.ts +26 -4
  12. package/dist/agent/mock.js +68 -37
  13. package/dist/agent/renderers.d.ts +49 -0
  14. package/dist/agent/renderers.js +27 -0
  15. package/dist/appearance/brands.d.ts +17 -0
  16. package/dist/appearance/brands.js +14 -0
  17. package/dist/chat/MessageBubble.js +1 -1
  18. package/dist/chat/MessageList.d.ts +9 -2
  19. package/dist/chat/MessageList.js +11 -8
  20. package/dist/css/appearance.js +1 -1
  21. package/dist/css/calliope.css +5 -0
  22. package/dist/css/tokens.css +5 -0
  23. package/dist/index.d.ts +9 -1
  24. package/dist/index.js +8 -1
  25. package/dist/primitives/Badge.d.ts +14 -0
  26. package/dist/primitives/Badge.js +25 -0
  27. package/dist/primitives/ContextMenu.d.ts +18 -0
  28. package/dist/primitives/ContextMenu.js +34 -0
  29. package/dist/primitives/Menubar.d.ts +21 -0
  30. package/dist/primitives/Menubar.js +43 -0
  31. package/dist/primitives/ScrollArea.d.ts +16 -0
  32. package/dist/primitives/ScrollArea.js +11 -0
  33. package/dist/primitives/Toast.d.ts +37 -0
  34. package/dist/primitives/Toast.js +43 -0
  35. package/dist/primitives/Tooltip.d.ts +16 -0
  36. package/dist/primitives/Tooltip.js +26 -0
  37. package/dist/provider/messages.d.ts +217 -0
  38. package/dist/provider/messages.js +238 -0
  39. package/dist/shell/RailPanel.js +1 -1
  40. package/dist/theme/css-layer.js +2 -1
  41. package/dist/theme/tokens.generated.d.ts +3 -0
  42. package/dist/theme/tokens.generated.js +3 -0
  43. package/dist/workbench/ActivityBar.d.ts +37 -0
  44. package/dist/workbench/ActivityBar.js +57 -0
  45. package/dist/workbench/BottomPanel.d.ts +30 -0
  46. package/dist/workbench/BottomPanel.js +20 -0
  47. package/dist/workbench/CodeEditor.d.ts +48 -0
  48. package/dist/workbench/CodeEditor.js +153 -0
  49. package/dist/workbench/CommandPalette.d.ts +49 -0
  50. package/dist/workbench/CommandPalette.js +114 -0
  51. package/dist/workbench/DataChart.d.ts +45 -0
  52. package/dist/workbench/DataChart.js +146 -0
  53. package/dist/workbench/DataGrid.d.ts +89 -0
  54. package/dist/workbench/DataGrid.js +590 -0
  55. package/dist/workbench/DataProfile.d.ts +17 -0
  56. package/dist/workbench/DataProfile.js +51 -0
  57. package/dist/workbench/EditorTabs.d.ts +62 -0
  58. package/dist/workbench/EditorTabs.js +115 -0
  59. package/dist/workbench/FileBrowser.d.ts +62 -0
  60. package/dist/workbench/FileBrowser.js +117 -0
  61. package/dist/workbench/FileGrid.d.ts +13 -0
  62. package/dist/workbench/FileGrid.js +114 -0
  63. package/dist/workbench/FileIcon.d.ts +10 -0
  64. package/dist/workbench/FileIcon.js +24 -0
  65. package/dist/workbench/FileList.d.ts +35 -0
  66. package/dist/workbench/FileList.js +160 -0
  67. package/dist/workbench/FilePreview.d.ts +66 -0
  68. package/dist/workbench/FilePreview.js +108 -0
  69. package/dist/workbench/FileTree.d.ts +37 -0
  70. package/dist/workbench/FileTree.js +218 -0
  71. package/dist/workbench/GridCell.d.ts +19 -0
  72. package/dist/workbench/GridCell.js +50 -0
  73. package/dist/workbench/GridDetails.d.ts +31 -0
  74. package/dist/workbench/GridDetails.js +78 -0
  75. package/dist/workbench/MenuBar.d.ts +49 -0
  76. package/dist/workbench/MenuBar.js +25 -0
  77. package/dist/workbench/PaneGroup.d.ts +50 -0
  78. package/dist/workbench/PaneGroup.js +146 -0
  79. package/dist/workbench/PendingChangesBar.d.ts +20 -0
  80. package/dist/workbench/PendingChangesBar.js +19 -0
  81. package/dist/workbench/Shortcuts.d.ts +50 -0
  82. package/dist/workbench/Shortcuts.js +109 -0
  83. package/dist/workbench/SqlEditor.d.ts +21 -0
  84. package/dist/workbench/SqlEditor.js +79 -0
  85. package/dist/workbench/StatusBar.d.ts +28 -0
  86. package/dist/workbench/StatusBar.js +26 -0
  87. package/dist/workbench/TruncationBanner.d.ts +11 -0
  88. package/dist/workbench/TruncationBanner.js +12 -0
  89. package/dist/workbench/UploadDropzone.d.ts +52 -0
  90. package/dist/workbench/UploadDropzone.js +115 -0
  91. package/dist/workbench/WorkbenchShell.d.ts +36 -0
  92. package/dist/workbench/WorkbenchShell.js +20 -0
  93. package/dist/workbench/dnd.d.ts +17 -0
  94. package/dist/workbench/dnd.js +77 -0
  95. package/dist/workbench/download.d.ts +11 -0
  96. package/dist/workbench/download.js +28 -0
  97. package/dist/workbench/editor-theme.d.ts +42 -0
  98. package/dist/workbench/editor-theme.js +113 -0
  99. package/dist/workbench/grid-format.d.ts +59 -0
  100. package/dist/workbench/grid-format.js +169 -0
  101. package/dist/workbench/grid-model.d.ts +75 -0
  102. package/dist/workbench/grid-model.js +259 -0
  103. package/dist/workbench/grid-selection.d.ts +69 -0
  104. package/dist/workbench/grid-selection.js +183 -0
  105. package/dist/workbench/grid-stats.d.ts +58 -0
  106. package/dist/workbench/grid-stats.js +185 -0
  107. package/dist/workbench/index.d.ts +44 -0
  108. package/dist/workbench/index.js +47 -0
  109. package/dist/workbench/keys.d.ts +23 -0
  110. package/dist/workbench/keys.js +105 -0
  111. package/dist/workbench/model.d.ts +72 -0
  112. package/dist/workbench/model.js +214 -0
  113. package/dist/workbench/palette.d.ts +17 -0
  114. package/dist/workbench/palette.js +45 -0
  115. package/dist/workbench/pending.d.ts +92 -0
  116. package/dist/workbench/pending.js +207 -0
  117. package/dist/workbench/selection.d.ts +16 -0
  118. package/dist/workbench/selection.js +46 -0
  119. package/dist/workbench/sql-completion.d.ts +107 -0
  120. package/dist/workbench/sql-completion.js +475 -0
  121. package/dist/workbench/typeahead.d.ts +15 -0
  122. package/dist/workbench/typeahead.js +22 -0
  123. package/dist/workflow/WorkflowRuntimeControls.d.ts +21 -0
  124. package/dist/workflow/WorkflowRuntimeControls.js +54 -0
  125. package/dist/workflow/runtime-controls.d.ts +29 -0
  126. package/dist/workflow/runtime-controls.js +10 -0
  127. package/package.json +17 -2
@@ -0,0 +1,207 @@
1
+ /**
2
+ * The grid's pending changes, as pure data: cell edits, inserted rows and
3
+ * deleted rows the person has made but not committed. The grid keeps one of
4
+ * these; the host's `onCommit` receives it as a `ChangeSet` and does the
5
+ * writing. Generalized from Loadr's data editor (and Chat Studio's fork,
6
+ * which turned the same model into SQL: `changeSetToSql`).
7
+ *
8
+ * Rows are keyed by their source index (`rows[key]`); an inserted row has a
9
+ * negative key (-1, -2, ...) so it never collides with a source row.
10
+ */
11
+ import { sqlLiteral, quoteIdentifier } from "./grid-format.js";
12
+ import { isNumericType } from "./grid-model.js";
13
+ export const NO_CHANGES = { rows: new Map(), inserted: 0 };
14
+ function withRow(changes, key, row) {
15
+ const rows = new Map(changes.rows);
16
+ if (row)
17
+ rows.set(key, row);
18
+ else
19
+ rows.delete(key);
20
+ return { ...changes, rows };
21
+ }
22
+ function differs(row) {
23
+ return Object.keys(row.values).some((c) => !Object.is(row.values[c], row.original[c]));
24
+ }
25
+ /**
26
+ * Sets one cell. `source` is the row as read (unused for an inserted row).
27
+ * An edit back to the original value drops the row's entry.
28
+ */
29
+ export function editCell(changes, key, column, value, source) {
30
+ const existing = changes.rows.get(key);
31
+ if (existing?.state === "deleted")
32
+ return changes;
33
+ if (existing) {
34
+ const next = { ...existing, values: { ...existing.values, [column]: value } };
35
+ return withRow(changes, key, next.state === "modified" && !differs(next) ? null : next);
36
+ }
37
+ if (!source || Object.is(source[column], value))
38
+ return changes;
39
+ return withRow(changes, key, {
40
+ state: "modified",
41
+ original: { ...source },
42
+ values: { ...source, [column]: value },
43
+ });
44
+ }
45
+ /** Inserts a row of NULLs, or a copy of `from` (duplicate). Returns the new row's key. */
46
+ export function addRow(changes, columns, from) {
47
+ const key = -(changes.inserted + 1);
48
+ const empty = Object.fromEntries(columns.map((c) => [c, null]));
49
+ const row = {
50
+ state: "added",
51
+ original: empty,
52
+ values: from ? { ...empty, ...from } : { ...empty },
53
+ };
54
+ return { changes: { ...withRow(changes, key, row), inserted: changes.inserted + 1 }, key };
55
+ }
56
+ /** Marks rows deleted; an inserted row is simply dropped. */
57
+ export function deleteRows(changes, keys, sourceOf) {
58
+ let next = changes;
59
+ for (const key of keys) {
60
+ const existing = next.rows.get(key);
61
+ if (existing?.state === "added") {
62
+ next = withRow(next, key, null);
63
+ continue;
64
+ }
65
+ const source = existing?.original ?? sourceOf(key);
66
+ if (!source)
67
+ continue;
68
+ next = withRow(next, key, {
69
+ state: "deleted",
70
+ original: { ...source },
71
+ values: existing?.values ?? { ...source },
72
+ });
73
+ }
74
+ return next;
75
+ }
76
+ /** Forgets every change to one row (an inserted row disappears). */
77
+ export function revertRow(changes, key) {
78
+ return changes.rows.has(key) ? withRow(changes, key, null) : changes;
79
+ }
80
+ /** The value a cell shows: the pending value when there is one. */
81
+ export function pendingValue(changes, key, column, source) {
82
+ const row = changes.rows.get(key);
83
+ return row ? row.values[column] : source?.[column];
84
+ }
85
+ /** True when the cell will be written: every cell of an inserted row, the edited cells of a modified one. */
86
+ export function isCellChanged(changes, key, column) {
87
+ const row = changes.rows.get(key);
88
+ if (!row || row.state === "deleted")
89
+ return false;
90
+ return row.state === "added" || !Object.is(row.values[column], row.original[column]);
91
+ }
92
+ /** The keys of the inserted rows, in the order they were added. */
93
+ export function insertedKeys(changes) {
94
+ return [...changes.rows.entries()]
95
+ .filter(([, row]) => row.state === "added")
96
+ .map(([key]) => key)
97
+ .sort((a, b) => b - a);
98
+ }
99
+ export function pendingCounts(changes) {
100
+ let inserts = 0;
101
+ let updates = 0;
102
+ let deletes = 0;
103
+ for (const row of changes.rows.values()) {
104
+ if (row.state === "added")
105
+ inserts++;
106
+ else if (row.state === "deleted")
107
+ deletes++;
108
+ else if (differs(row))
109
+ updates++;
110
+ }
111
+ return { inserts, updates, deletes, total: inserts + updates + deletes };
112
+ }
113
+ /**
114
+ * The pending changes as a batch to write. Updates and deletes are keyed on
115
+ * `primaryKeys`; without one they cannot name a row, and the grid only
116
+ * offers inserts.
117
+ */
118
+ export function toChangeSet(changes, options) {
119
+ const out = { inserts: [], updates: [], deletes: [] };
120
+ const entries = [...changes.rows.entries()].sort((a, b) => a[0] < 0 && b[0] < 0 ? b[0] - a[0] : a[0] - b[0]);
121
+ for (const [key, row] of entries) {
122
+ if (row.state === "added") {
123
+ const values = {};
124
+ for (const column of options.columns) {
125
+ const value = row.values[column];
126
+ if (value === undefined || (value === null && row.original[column] === null))
127
+ continue;
128
+ values[column] = value;
129
+ }
130
+ out.inserts.push({ key, values });
131
+ continue;
132
+ }
133
+ const primaryKey = Object.fromEntries(options.primaryKeys.map((pk) => [pk, row.original[pk]]));
134
+ if (row.state === "deleted") {
135
+ out.deletes.push({ key, primaryKey });
136
+ continue;
137
+ }
138
+ const values = {};
139
+ const expected = {};
140
+ for (const column of options.columns) {
141
+ if (Object.is(row.values[column], row.original[column]))
142
+ continue;
143
+ values[column] = row.values[column];
144
+ const old = row.original[column];
145
+ if (old === null || typeof old !== "object")
146
+ expected[column] = old;
147
+ }
148
+ if (Object.keys(values).length > 0)
149
+ out.updates.push({ key, primaryKey, values, expected });
150
+ }
151
+ return out;
152
+ }
153
+ /**
154
+ * A change set as SQL statements, for a host that runs SQL rather than an
155
+ * apply endpoint: INSERT, UPDATE ... WHERE <primary key>, DELETE ... WHERE
156
+ * <primary key>. Literals are quoted by `sqlLiteral`; dialect differences
157
+ * beyond ANSI quoting are the host's.
158
+ */
159
+ export function changeSetToSql(changeSet, options) {
160
+ const table = quoteIdentifier(options.table);
161
+ const where = (primaryKey) => Object.entries(primaryKey)
162
+ .map(([c, v]) => v === null || v === undefined
163
+ ? `${quoteIdentifier(c)} IS NULL`
164
+ : `${quoteIdentifier(c)} = ${sqlLiteral(v)}`)
165
+ .join(" AND ");
166
+ const statements = [];
167
+ for (const insert of changeSet.inserts) {
168
+ const cols = Object.keys(insert.values);
169
+ statements.push(cols.length === 0
170
+ ? `INSERT INTO ${table} DEFAULT VALUES;`
171
+ : `INSERT INTO ${table} (${cols.map(quoteIdentifier).join(", ")}) VALUES (${cols
172
+ .map((c) => sqlLiteral(insert.values[c]))
173
+ .join(", ")});`);
174
+ }
175
+ for (const update of changeSet.updates) {
176
+ const set = Object.entries(update.values)
177
+ .map(([c, v]) => `${quoteIdentifier(c)} = ${sqlLiteral(v)}`)
178
+ .join(", ");
179
+ statements.push(`UPDATE ${table} SET ${set} WHERE ${where(update.primaryKey)};`);
180
+ }
181
+ for (const del of changeSet.deletes) {
182
+ statements.push(`DELETE FROM ${table} WHERE ${where(del.primaryKey)};`);
183
+ }
184
+ return statements;
185
+ }
186
+ /**
187
+ * What a typed cell means: empty or "NULL" is NULL; a number or boolean
188
+ * column (by its type, or the original value's) keeps its type when the
189
+ * text parses as one.
190
+ */
191
+ export function parseCellInput(text, original, type) {
192
+ if (text === "" || text.toUpperCase() === "NULL")
193
+ return null;
194
+ if (typeof original === "number" || (type !== undefined && isNumericType(type))) {
195
+ const num = Number(text);
196
+ if (text.trim() !== "" && !Number.isNaN(num))
197
+ return num;
198
+ }
199
+ if (typeof original === "boolean" || type === "boolean") {
200
+ const lower = text.toLowerCase();
201
+ if (lower === "true" || text === "1")
202
+ return true;
203
+ if (lower === "false" || text === "0")
204
+ return false;
205
+ }
206
+ return text;
207
+ }
@@ -0,0 +1,16 @@
1
+ export type SelectMode = "replace" | "toggle" | "range";
2
+ /**
3
+ * Finder-style selection over an ordered listing: a plain click or arrow
4
+ * selects one, Cmd or Ctrl toggles, Shift selects the range from the
5
+ * anchor (the last item chosen without Shift). The set is the host's.
6
+ */
7
+ export declare function useSelectionModel(order: readonly string[], selection: ReadonlySet<string>, onSelectionChange: (next: Set<string>) => void): {
8
+ select(path: string, mode: SelectMode): void;
9
+ selectAll(): void;
10
+ clear(): void;
11
+ };
12
+ export declare function modeOf(event: {
13
+ shiftKey: boolean;
14
+ metaKey: boolean;
15
+ ctrlKey: boolean;
16
+ }): SelectMode;
@@ -0,0 +1,46 @@
1
+ "use client";
2
+ import * as React from "react";
3
+ /**
4
+ * Finder-style selection over an ordered listing: a plain click or arrow
5
+ * selects one, Cmd or Ctrl toggles, Shift selects the range from the
6
+ * anchor (the last item chosen without Shift). The set is the host's.
7
+ */
8
+ export function useSelectionModel(order, selection, onSelectionChange) {
9
+ const anchor = React.useRef(null);
10
+ return React.useMemo(() => ({
11
+ select(path, mode) {
12
+ if (mode === "range") {
13
+ const from = order.indexOf(anchor.current ?? path);
14
+ const to = order.indexOf(path);
15
+ const [a, b] = from < 0 ? [to, to] : from < to ? [from, to] : [to, from];
16
+ onSelectionChange(new Set(order.slice(a, b + 1)));
17
+ return;
18
+ }
19
+ anchor.current = path;
20
+ if (mode === "toggle") {
21
+ const next = new Set(selection);
22
+ if (next.has(path))
23
+ next.delete(path);
24
+ else
25
+ next.add(path);
26
+ onSelectionChange(next);
27
+ }
28
+ else
29
+ onSelectionChange(new Set([path]));
30
+ },
31
+ selectAll() {
32
+ onSelectionChange(new Set(order));
33
+ },
34
+ clear() {
35
+ anchor.current = null;
36
+ onSelectionChange(new Set());
37
+ },
38
+ }), [order, selection, onSelectionChange]);
39
+ }
40
+ export function modeOf(event) {
41
+ if (event.shiftKey)
42
+ return "range";
43
+ if (event.metaKey || event.ctrlKey)
44
+ return "toggle";
45
+ return "replace";
46
+ }
@@ -0,0 +1,107 @@
1
+ /**
2
+ * Schema-aware SQL completion, without Monaco: what to suggest at a cursor,
3
+ * given the text and a host-provided schema. `SqlEditor` turns the result
4
+ * into Monaco completion items; anything else (a plain textarea, a test) can
5
+ * use it as it is. Pure.
6
+ */
7
+ export interface SqlColumn {
8
+ name: string;
9
+ type?: string;
10
+ nullable?: boolean;
11
+ }
12
+ export interface SqlTable {
13
+ name: string;
14
+ /** The schema it lives in, when the database has several. */
15
+ schema?: string;
16
+ /** Leave out while unknown; the host can load it on `onSchemaRequest`. */
17
+ columns?: readonly SqlColumn[];
18
+ }
19
+ /** What the editor knows about the database the query runs against. */
20
+ export interface SqlSchema {
21
+ tables: readonly SqlTable[];
22
+ /** Schema names on this database, for `schema.` completion. */
23
+ schemas?: readonly string[];
24
+ /** Other databases on the same server, for `USE` and `db.` completion. */
25
+ databases?: readonly string[];
26
+ /** Tables of other databases, by database name, once the host has them. */
27
+ otherDatabases?: Readonly<Record<string, readonly SqlTable[]>>;
28
+ }
29
+ /** Something the completion wanted but the schema does not have yet. */
30
+ export type SqlSchemaRequest = {
31
+ kind: "columns";
32
+ table: string;
33
+ schema?: string;
34
+ } | {
35
+ kind: "database";
36
+ database: string;
37
+ };
38
+ export type SqlCompletionKind = "keyword" | "function" | "snippet" | "table" | "column" | "schema" | "database";
39
+ export interface SqlCompletion {
40
+ label: string;
41
+ kind: SqlCompletionKind;
42
+ insertText: string;
43
+ /** `insertText` is a snippet with `${1:placeholder}` stops. */
44
+ snippet?: boolean;
45
+ detail?: string;
46
+ /** Lower sorts first. */
47
+ sortText: string;
48
+ }
49
+ export declare const SQL_KEYWORDS: readonly ["SELECT", "FROM", "WHERE", "AND", "OR", "NOT", "IN", "BETWEEN", "LIKE", "IS", "NULL", "AS", "ON", "JOIN", "INNER", "LEFT", "RIGHT", "FULL", "OUTER", "CROSS", "GROUP BY", "ORDER BY", "HAVING", "LIMIT", "OFFSET", "UNION", "ALL", "DISTINCT", "INSERT INTO", "VALUES", "UPDATE", "SET", "DELETE", "CREATE TABLE", "ALTER TABLE", "DROP TABLE", "CREATE INDEX", "DROP INDEX", "TRUNCATE", "EXISTS", "CASE", "WHEN", "THEN", "ELSE", "END", "CAST", "COALESCE", "NULLIF", "WITH", "RECURSIVE", "ASC", "DESC", "TRUE", "FALSE", "DEFAULT", "PRIMARY KEY", "FOREIGN KEY", "REFERENCES", "CONSTRAINT", "UNIQUE", "CHECK", "INDEX", "USE", "FETCH FIRST", "ROWS ONLY", "PERCENT", "TOP", "WINDOW"];
50
+ export declare const SQL_FUNCTIONS: readonly ["COUNT", "SUM", "AVG", "MIN", "MAX", "ROUND", "UPPER", "LOWER", "TRIM", "LENGTH", "SUBSTRING", "REPLACE", "CONCAT", "NOW", "CURRENT_TIMESTAMP", "CURRENT_DATE", "DATE", "EXTRACT", "COALESCE", "NULLIF", "CAST", "CONVERT", "ROW_NUMBER", "RANK", "DENSE_RANK", "LAG", "LEAD", "FIRST_VALUE", "LAST_VALUE", "NTILE", "PERCENT_RANK", "CUME_DIST", "NTH_VALUE", "ARRAY_AGG", "STRING_AGG", "JSON_AGG", "JSONB_AGG", "ABS", "CEIL", "FLOOR", "MOD", "POWER", "SQRT", "LOG", "EXP", "LEFT", "RIGHT", "LPAD", "RPAD", "LTRIM", "RTRIM", "REVERSE", "DATE_TRUNC", "DATE_PART", "AGE", "INTERVAL", "TO_CHAR", "TO_DATE", "TO_NUMBER", "TO_TIMESTAMP", "GREATEST", "LEAST", "GENERATE_SERIES"];
51
+ /** Case-insensitive substring match; an empty input matches everything. */
52
+ export declare function sqlMatch(input: string, candidate: string): boolean;
53
+ export type SqlCursorContext = {
54
+ context: "table" | "column" | "database" | "general";
55
+ } | {
56
+ context: "dot";
57
+ prefix: string;
58
+ word: string;
59
+ };
60
+ /** What the cursor is in, from the text before it: after FROM, after SELECT, after `alias.`. */
61
+ export declare function sqlCursorContext(textBeforeCursor: string): SqlCursorContext;
62
+ /**
63
+ * The statement around `offset` in a buffer of several. Semicolons inside
64
+ * string literals and line comments do not split, so aliases resolve against
65
+ * the statement being written, never an earlier one.
66
+ */
67
+ export declare function statementAt(text: string, offset: number): string;
68
+ export interface SqlTableRef {
69
+ /** Lower-cased. */
70
+ table: string;
71
+ schema?: string;
72
+ alias?: string;
73
+ }
74
+ /** The tables a statement's FROM, JOIN, UPDATE and INTO name, with their aliases. */
75
+ export declare function extractTableRefs(statement: string): SqlTableRef[];
76
+ export type SqlDotTarget = {
77
+ kind: "columns";
78
+ table: string;
79
+ } | {
80
+ kind: "schema";
81
+ schema: string;
82
+ } | {
83
+ kind: "database";
84
+ database: string;
85
+ } | {
86
+ kind: "unknown";
87
+ };
88
+ /**
89
+ * What `prefix.` refers to: an alias in this statement first, then a table
90
+ * the statement names, a known table, a known schema, a known database. An
91
+ * unrecognised prefix is unknown, and nothing should be requested for it.
92
+ */
93
+ export declare function resolveSqlDot(prefix: string, statement: string, schema: SqlSchema): SqlDotTarget;
94
+ /** Column names that more than one table has, which completion qualifies. */
95
+ export declare function ambiguousColumns(tables: readonly SqlTable[]): Set<string>;
96
+ /** True when a statement changes the schema, so a host's cached schema is stale. */
97
+ export declare function isDdlStatement(sql: string): boolean;
98
+ export interface SqlCompletionResult {
99
+ items: SqlCompletion[];
100
+ /** Ask the host for these, so the next keystroke can offer them. */
101
+ requests: SqlSchemaRequest[];
102
+ }
103
+ /**
104
+ * The completions at `offset` in `text`, from the schema the host gave.
105
+ * Never waits for anything: what the schema lacks comes back as `requests`.
106
+ */
107
+ export declare function sqlCompletions(text: string, offset: number, schema: SqlSchema): SqlCompletionResult;