@standardbeagle/edit-db 0.4.494 → 0.4.581

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 (92) hide show
  1. package/dist/common/saved-objects.d.ts +40 -0
  2. package/dist/common/schema-queries.d.ts +1 -0
  3. package/dist/components/bulk-edit-dialog.d.ts +18 -0
  4. package/dist/components/content-viewer.d.ts +8 -1
  5. package/dist/components/data-table.d.ts +49 -2
  6. package/dist/components/detail-panel.d.ts +2 -2
  7. package/dist/components/export-button.d.ts +19 -0
  8. package/dist/components/export-button.test.d.ts +1 -0
  9. package/dist/components/filters/number-filter.d.ts +8 -1
  10. package/dist/components/fk-cell-popover.d.ts +5 -5
  11. package/dist/components/form-runner-host.d.ts +14 -0
  12. package/dist/components/form-runner.d.ts +43 -0
  13. package/dist/components/form-subform.d.ts +11 -0
  14. package/dist/components/form-subform.test.d.ts +0 -0
  15. package/dist/components/grouped-grid-summary.d.ts +17 -0
  16. package/dist/components/grouped-grid-summary.test.d.ts +0 -0
  17. package/dist/components/m2m-panel.d.ts +4 -5
  18. package/dist/components/ui/table.test.d.ts +1 -0
  19. package/dist/data-edit.d.ts +17 -4
  20. package/dist/data-panel.d.ts +0 -11
  21. package/dist/edit-db.css +1 -1
  22. package/dist/editor.d.ts +22 -1
  23. package/dist/editor.es.js +6822 -4695
  24. package/dist/editor.stories.d.ts +0 -1
  25. package/dist/editor.umd.cjs +41 -27
  26. package/dist/hooks/useColumnNav.d.ts +3 -3
  27. package/dist/hooks/useColumnSizingPersistence.d.ts +19 -0
  28. package/dist/hooks/useColumnVisibilityPersistence.d.ts +34 -0
  29. package/dist/hooks/useColumnVisibilityPersistence.test.d.ts +1 -0
  30. package/dist/hooks/useCompositeTableRef.d.ts +2 -2
  31. package/dist/hooks/useDataTable.d.ts +46 -5
  32. package/dist/hooks/useDebouncedCommit.test.d.ts +1 -0
  33. package/dist/hooks/useDeltaMutation.d.ts +20 -0
  34. package/dist/hooks/useDeltaMutation.test.d.ts +0 -0
  35. package/dist/hooks/useEditorConfig.d.ts +27 -0
  36. package/dist/hooks/useFitMode.d.ts +23 -0
  37. package/dist/hooks/useFitMode.test.d.ts +1 -0
  38. package/dist/hooks/usePanelSize.d.ts +28 -0
  39. package/dist/hooks/usePanelSize.test.d.ts +1 -0
  40. package/dist/hooks/usePath.d.ts +1 -0
  41. package/dist/hooks/useRowHoverActions.d.ts +26 -0
  42. package/dist/hooks/useSchema.d.ts +8 -2
  43. package/dist/hooks/useSchemaFilter.test.d.ts +1 -0
  44. package/dist/hooks/useTableExport.d.ts +13 -0
  45. package/dist/hooks/useTableMutation.d.ts +1 -4
  46. package/dist/hooks/useTableRef.d.ts +3 -3
  47. package/dist/hooks/useTableStats.d.ts +0 -24
  48. package/dist/index.d.ts +13 -1
  49. package/dist/lib/column-order.d.ts +17 -0
  50. package/dist/lib/column-order.test.d.ts +1 -0
  51. package/dist/lib/content-detect.d.ts +34 -0
  52. package/dist/lib/content-detect.sniff.test.d.ts +1 -0
  53. package/dist/lib/drill-stack.d.ts +19 -2
  54. package/dist/lib/export.d.ts +122 -0
  55. package/dist/lib/export.test.d.ts +1 -0
  56. package/dist/lib/field-validation.d.ts +16 -0
  57. package/dist/lib/fk.d.ts +13 -0
  58. package/dist/lib/form-definition.d.ts +57 -0
  59. package/dist/lib/form-definition.test.d.ts +1 -0
  60. package/dist/lib/form-runner-nav.d.ts +19 -0
  61. package/dist/lib/form-runner-nav.test.d.ts +1 -0
  62. package/dist/lib/form-subform.d.ts +12 -0
  63. package/dist/lib/form-subform.test.d.ts +1 -0
  64. package/dist/lib/form-widget.d.ts +36 -0
  65. package/dist/lib/form-widget.test.d.ts +1 -0
  66. package/dist/lib/format-value.d.ts +26 -0
  67. package/dist/lib/grid-grouping.d.ts +63 -0
  68. package/dist/lib/grid-grouping.test.d.ts +1 -0
  69. package/dist/lib/m2m.d.ts +26 -1
  70. package/dist/lib/mutation-payload.d.ts +37 -0
  71. package/dist/lib/mutation-payload.test.d.ts +1 -0
  72. package/dist/lib/query-builder.d.ts +116 -9
  73. package/dist/lib/row-id.d.ts +11 -0
  74. package/dist/lib/rows-by-pk-query.test.d.ts +1 -0
  75. package/dist/lib/scalar-types.d.ts +30 -0
  76. package/dist/lib/scalar-types.test.d.ts +1 -0
  77. package/dist/lib/table-action.d.ts +24 -0
  78. package/dist/{tableList.d.ts → table-list.d.ts} +1 -1
  79. package/dist/table-list.test.d.ts +0 -0
  80. package/dist/table-view.chart.test.d.ts +1 -0
  81. package/dist/table-view.d.ts +22 -0
  82. package/dist/table-view.test.d.ts +0 -0
  83. package/dist/types/schema.d.ts +45 -10
  84. package/package.json +2 -2
  85. package/dist/common/schema.d.ts +0 -2
  86. package/dist/data-data-table.d.ts +0 -17
  87. /package/dist/common/{schema.test.d.ts → saved-objects.test.d.ts} +0 -0
  88. /package/dist/{components/filters/use-debounced-commit.test.d.ts → common/schema-queries.test.d.ts} +0 -0
  89. /package/dist/{data-data-table.test.d.ts → components/bulk-edit-dialog.test.d.ts} +0 -0
  90. /package/dist/components/{table-dimensions.test.d.ts → content-viewer.test.d.ts} +0 -0
  91. /package/dist/{tableList.test.d.ts → components/form-runner.test.d.ts} +0 -0
  92. /package/dist/{components/filters/use-debounced-commit.d.ts → hooks/useDebouncedCommit.d.ts} +0 -0
@@ -1,7 +1,7 @@
1
1
  import { ReactNode } from 'react';
2
- import { ColumnPanel } from '../data-panel';
2
+ import { DrillFrame } from '../lib/drill-stack';
3
3
  interface ColumnNavEntry {
4
- panel: ColumnPanel;
4
+ panel: DrillFrame;
5
5
  element: HTMLElement | null;
6
6
  }
7
7
  interface ColumnNavState {
@@ -13,7 +13,7 @@ interface ColumnNavState {
13
13
  }
14
14
  interface ColumnNavRegistration {
15
15
  mainTable: string | null;
16
- columns: ColumnPanel[];
16
+ columns: DrillFrame[];
17
17
  columnRefs: Map<number, HTMLElement | null>;
18
18
  onClose: (index: number) => void;
19
19
  }
@@ -0,0 +1,19 @@
1
+ import { ColumnSizingState } from '@tanstack/react-table';
2
+ export declare const COL_MIN_WIDTH = 60;
3
+ export declare const COL_MAX_AUTO_WIDTH = 450;
4
+ export declare const COL_DEFAULT_WIDTH = 150;
5
+ export interface UseColumnSizingPersistenceResult {
6
+ columnSizing: ColumnSizingState;
7
+ setColumnSizing: React.Dispatch<React.SetStateAction<ColumnSizingState>>;
8
+ }
9
+ /**
10
+ * Owns per-table column sizing, persisted to localStorage.
11
+ *
12
+ * Writes are debounced so a live ('onChange') resize drag doesn't write on every
13
+ * mousemove. `skipPersistRef` suppresses the first run after mount/table-switch,
14
+ * which would only write back the sizing just loaded from storage.
15
+ * `pendingSizingRef` carries the latest unsaved state so a table switch or
16
+ * unmount flushes it instead of dropping a resize made less than the debounce
17
+ * window ago.
18
+ */
19
+ export declare function useColumnSizingPersistence(tableName?: string): UseColumnSizingPersistenceResult;
@@ -0,0 +1,34 @@
1
+ import { VisibilityState } from '@tanstack/react-table';
2
+ /**
3
+ * Read a stored selection. Returns null — not `{}` — when there is nothing
4
+ * stored, because "no stored preference" (fall back to the host defaults) and
5
+ * "stored: everything visible" are different states.
6
+ */
7
+ export declare function loadColumnVisibility(tableName: string): VisibilityState | null;
8
+ export declare function saveColumnVisibility(tableName: string, visibility: VisibilityState): void;
9
+ export declare function clearColumnVisibility(tableName: string): void;
10
+ /**
11
+ * Turn a host's list of columns to show into table state: everything named is
12
+ * visible, everything else in `allColumnIds` is hidden. Columns the host names
13
+ * that this table doesn't have are ignored, so one config can cover a schema
14
+ * that varies between deployments.
15
+ */
16
+ export declare function visibilityFromDefaults(allColumnIds: string[], defaultVisible?: string[]): VisibilityState;
17
+ export interface UseColumnVisibilityPersistenceResult {
18
+ columnVisibility: VisibilityState;
19
+ setColumnVisibility: React.Dispatch<React.SetStateAction<VisibilityState>>;
20
+ /** Drop the stored selection and go back to the host defaults for this table. */
21
+ resetColumnVisibility: () => void;
22
+ }
23
+ /**
24
+ * Owns which columns a table shows, persisted per table to localStorage.
25
+ *
26
+ * A viewer picking columns is a durable preference, not a per-visit one: the
27
+ * selection survives reload and return visits. Host defaults apply until the
28
+ * viewer makes a choice, and `resetColumnVisibility` puts them back.
29
+ *
30
+ * Only a change through the returned setter is written. Merely opening a table
31
+ * must not store its defaults — that would freeze today's defaults into every
32
+ * viewer's storage and make a later change to them invisible.
33
+ */
34
+ export declare function useColumnVisibilityPersistence(tableName: string | undefined, defaultVisibility: VisibilityState): UseColumnVisibilityPersistenceResult;
@@ -1,4 +1,4 @@
1
- import { Schema } from '../types/schema';
1
+ import { SchemaContextValue } from '../types/schema';
2
2
  export interface CompositeTableRefValue {
3
3
  /** Route-encoded composite key (`v1::v2`) suitable as a Select value. */
4
4
  route: string;
@@ -34,4 +34,4 @@ export interface CompositeTableRefOptions {
34
34
  * and the currently-selected row is resolved via a single-row lookup when it lies
35
35
  * outside the fetched window so it stays selectable instead of showing blank.
36
36
  */
37
- export declare function useCompositeTableRef(schema: Schema, destTableName: string, destColumnNames: string[], options?: CompositeTableRefOptions): CompositeTableRef;
37
+ export declare function useCompositeTableRef(schema: SchemaContextValue, destTableName: string, destColumnNames: string[], options?: CompositeTableRefOptions): CompositeTableRef;
@@ -1,6 +1,8 @@
1
- import { Table, Join } from '../types/schema';
1
+ import { Table, Column, Join } from '../types/schema';
2
2
  import { ColumnDef, ColumnFiltersState, SortingState } from '@tanstack/react-table';
3
- import { ColumnPanel } from '../data-panel';
3
+ import { DrillFrame } from '../lib/drill-stack';
4
+ import { ExportRunner } from '../lib/export';
5
+ import { GridGroupMemberRequest, GroupingRow, GroupingSort } from '../lib/grid-grouping';
4
6
  export { getFilterOperators } from '../lib/query-builder';
5
7
  export type { ColumnFilterValue } from '../lib/query-builder';
6
8
  interface RowData {
@@ -25,6 +27,17 @@ export declare function clampPageIndex(pageIndex: number, pageCount: number): nu
25
27
  */
26
28
  export declare function reconcileColumnFiltersFromUrl(prev: ColumnFiltersState, cfParam: string): ColumnFiltersState;
27
29
  export declare function getMultiJoinRows(row: RowData, join: Join): RowData[];
30
+ /**
31
+ * Reads the joined parent object a single-link column renders.
32
+ *
33
+ * Keyed on the join's FIELD name, not its destination table: a table that
34
+ * references the same target through several foreign keys has one field per key
35
+ * (billing_address, shipping_address) and no field named for the table, so a
36
+ * lookup by table name finds nothing and the cell renders as null. Mirrors
37
+ * getMultiJoinRows, which has always had to do this for aliased child
38
+ * collections.
39
+ */
40
+ export declare function getSingleJoinRow(row: RowData, join: Join): RowData | undefined;
28
41
  export declare function getMultiJoinTotal(row: RowData, join: Join): number;
29
42
  /**
30
43
  * Return type for the useDataTable hook.
@@ -47,8 +60,33 @@ interface UseDataTableResult {
47
60
  pageCount: number;
48
61
  /** Current page data rows */
49
62
  rows: RowData[];
63
+ /** Total matching rows for the active filter/sort (across all pages). */
64
+ totalRows: number;
65
+ /** Server aggregate rows for URL-selected grouping; never derived from the page. */
66
+ grouping: {
67
+ column: Column;
68
+ sumColumn: Column | null;
69
+ rows: GroupingRow[];
70
+ loading: boolean;
71
+ error: Error | null;
72
+ sort: GroupingSort;
73
+ onSortChange: (sort: GroupingSort) => void;
74
+ memberRequest: (value: unknown) => GridGroupMemberRequest;
75
+ } | null;
76
+ /**
77
+ * Export the FULL result set for the current filters + sort, paging through
78
+ * the same fetcher/query — not just the visible page. Null when there is no
79
+ * active query/table to export.
80
+ */
81
+ exportRows: ExportRunner;
50
82
  /** Whether data is currently loading (no rows to show yet) */
51
83
  loading: boolean;
84
+ /**
85
+ * A refresh is in flight while previous rows remain on screen as
86
+ * placeholder data (page turn, sort, filter change). Drives the grid's
87
+ * in-flight indicator; `loading` alone blanks the rows.
88
+ */
89
+ fetching: boolean;
52
90
  /** Error object if the query failed */
53
91
  error: Error | null;
54
92
  /** Update sorting state */
@@ -59,6 +97,9 @@ interface UseDataTableResult {
59
97
  onPageIndexChange: (pageIndex: number) => void;
60
98
  /** Update page size */
61
99
  onPageSizeChange: (pageSize: number) => void;
100
+ /** Rewrites only the URL-owned grouping parameter. */
101
+ onGroupingChange: (columnName: string | null) => void;
102
+ onGroupingSumChange: (columnName: string | null) => void;
62
103
  }
63
104
  /**
64
105
  * Hook for managing data table state including sorting, filtering, and pagination.
@@ -77,15 +118,15 @@ interface UseDataTableResult {
77
118
  * pageCount,
78
119
  * onSortingChange,
79
120
  * onPageIndexChange,
80
- * } = useDataTable(table, recordId, parentTable);
121
+ * } = useDataTable(table, id, filterTable);
81
122
  * ```
82
123
  *
83
124
  * @param table - Table schema definition
84
- * @param id - Optional record ID for filtering to a specific row
125
+ * @param id - Optional row ID for filtering to a specific row
85
126
  * @param filterTable - Optional parent table name for relationship filtering
86
127
  * @param filterColumn - Optional column name for explicit FK filtering
87
128
  * @param onExpandContent - Callback when content expansion is requested
88
129
  * @param onOpenColumn - Callback when opening a side panel column
89
130
  * @returns Data table state and control functions
90
131
  */
91
- export declare function useDataTable(table: Table | null, id?: string, filterTable?: string, filterColumn?: string, onExpandContent?: (rowIndex: number, columnName: string) => void, onOpenColumn?: (panel: ColumnPanel) => void): UseDataTableResult;
132
+ export declare function useDataTable(table: Table | null, id?: string, filterTable?: string, filterColumn?: string, onExpandContent?: (rowIndex: number, columnName: string) => void, onOpenColumn?: (panel: DrillFrame) => void): UseDataTableResult;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,20 @@
1
+ import { Table } from '../types/schema';
2
+ /**
3
+ * The server's collection-diff save shape (`<t>_delta`): three optional lists
4
+ * that apply in inserted → updated → deleted order inside ONE transaction — a
5
+ * failure anywhere applies nothing — and ride the server's set-based bulk fast
6
+ * path at batch scale. Payloads must already be wire-ready (coerceDetail /
7
+ * delete key payloads); this hook only carries the document.
8
+ */
9
+ export interface DeltaDocument {
10
+ inserted?: Record<string, unknown>[];
11
+ updated?: Record<string, unknown>[];
12
+ deleted?: Record<string, unknown>[];
13
+ }
14
+ export interface UseDeltaMutationResult {
15
+ saveDelta: (delta: DeltaDocument) => Promise<unknown>;
16
+ isPending: boolean;
17
+ error: Error | null;
18
+ }
19
+ export declare function deltaChangeCount(delta: DeltaDocument): number;
20
+ export declare function useDeltaMutation(table: Table): UseDeltaMutationResult;
File without changes
@@ -1,4 +1,5 @@
1
1
  import { ReactNode } from 'react';
2
+ import { TableAction } from '../lib/table-action';
2
3
  /**
3
4
  * Optional, opt-in editor features. Kept tiny and separate from the data/schema
4
5
  * contexts so feature flags don't force those providers to re-render and so
@@ -11,6 +12,32 @@ export interface EditorConfig {
11
12
  * may not want on every connect. Hosts opt in via `<Editor showStats />`.
12
13
  */
13
14
  showStats: boolean;
15
+ /**
16
+ * Restrict the editor to these tables, by GraphQL name or db name. Undefined
17
+ * exposes everything the server returns — which on a managed host also means
18
+ * its own bookkeeping tables (Azure SQL surfaces firewall rules this way).
19
+ * Filtering here rather than in the sidebar keeps excluded tables out of
20
+ * routing and FK lookups too, not just out of the list.
21
+ */
22
+ tables?: string[];
23
+ /**
24
+ * Columns visible by default per table, keyed by table name; every other
25
+ * column starts hidden. Only the starting point — a viewer's own choices are
26
+ * stored per table and win from then on.
27
+ */
28
+ defaultColumns?: Record<string, string[]>;
29
+ /**
30
+ * Columns to move to the right end of every grid, in this order. For audit
31
+ * stamps (created/modified) that are read far less often than the data they
32
+ * annotate but sit in the middle of the natural column order.
33
+ */
34
+ trailingColumns?: string[];
35
+ /**
36
+ * Host-contributed actions on each table in the navigation list, rendered in
37
+ * the table's kebab menu AFTER the built-in Download actions. The host owns
38
+ * what an action does; edit-db just invokes it with the schema table.
39
+ */
40
+ tableActions?: TableAction[];
14
41
  }
15
42
  export declare function EditorConfigProvider({ config, children }: {
16
43
  config: EditorConfig;
@@ -0,0 +1,23 @@
1
+ import { RefObject } from 'react';
2
+ /** Sentinel page-size value meaning "fit as many rows as the viewport allows". */
3
+ export declare const FIT_SENTINEL = -1;
4
+ /**
5
+ * Rows that fit a container of `containerHeight` px: header subtracted, floor
6
+ * to whole rows, never below 5. The single source of the fit formula — the
7
+ * hook and its tests both use this.
8
+ */
9
+ export declare function computeFitRowCount(containerHeight: number): number;
10
+ export interface UseFitModeResult {
11
+ fitMode: boolean;
12
+ setFitMode: React.Dispatch<React.SetStateAction<boolean>>;
13
+ /** Rows that fit the current scroll container height. */
14
+ computeFitSize: () => number;
15
+ }
16
+ /**
17
+ * "Fit" page-sizing: derive the page size from the scroll container's height so
18
+ * the grid shows exactly as many rows as fit, re-fitting when the container
19
+ * resizes. The resize path is debounced so dragging a splitter/window doesn't
20
+ * fire a burst of queries (each distinct page size is a new query key) — only
21
+ * the settled size runs.
22
+ */
23
+ export declare function useFitMode(scrollRef: RefObject<HTMLDivElement>, onPageSizeChange: (pageSize: number) => void): UseFitModeResult;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Persistent, drag-resizable panel dimension.
3
+ *
4
+ * Returns the current size plus a pointerdown handler to put on a separator
5
+ * element. Dragging follows the pointer along the given axis; the size is
6
+ * clamped to [min, max] and persisted per `key` so a layout survives reload.
7
+ * `invert` flips the drag direction for separators that sit BEFORE the panel
8
+ * they size (e.g. a bottom panel resized by the handle above it: dragging the
9
+ * handle UP must grow the panel).
10
+ *
11
+ * The separator also supports keyboard resizing (arrow keys, 16px steps) via
12
+ * the returned onKeyDown — a drag-only separator is unreachable to keyboard
13
+ * users. Callers should render the handle with role="separator" and an
14
+ * aria-orientation matching the axis.
15
+ */
16
+ export interface PanelSizeOptions {
17
+ key: string;
18
+ initial: number;
19
+ min: number;
20
+ max: number;
21
+ axis: 'x' | 'y';
22
+ invert?: boolean;
23
+ }
24
+ export declare function usePanelSize({ key, initial, min, max, axis, invert }: PanelSizeOptions): {
25
+ size: number;
26
+ onPointerDown: (e: React.PointerEvent<HTMLElement>) => void;
27
+ onKeyDown: (e: React.KeyboardEvent<HTMLElement>) => void;
28
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -63,5 +63,6 @@ export declare function Route({ path, element }: {
63
63
  path: string;
64
64
  element: ReactElement;
65
65
  }): ReactElement;
66
+ export declare const combinePaths: (current: string, newPath: string) => string;
66
67
  export declare const matchPath: (route: string, path: string) => PathMatch;
67
68
  export {};
@@ -0,0 +1,26 @@
1
+ import { PointerEvent, MutableRefObject } from 'react';
2
+ export interface HoveredRow {
3
+ rowId: string;
4
+ el: HTMLElement;
5
+ }
6
+ export interface UseRowHoverActionsResult {
7
+ hoveredRow: HoveredRow | null;
8
+ hoverRow: (rowId: string, el: HTMLElement) => void;
9
+ scheduleDismiss: () => void;
10
+ cancelDismiss: () => void;
11
+ /** Suppresses the click that follows a long-press so it doesn't also select the row. */
12
+ suppressClick: MutableRefObject<boolean>;
13
+ startPress: (rowId: string, el: HTMLElement, e: PointerEvent) => void;
14
+ onPressMove: () => void;
15
+ cancelPress: () => void;
16
+ }
17
+ /**
18
+ * Row hover/long-press action tracking for the data grid.
19
+ *
20
+ * Mouse: hovering a row opens its action toolbar (with a small dismiss delay so
21
+ * moving onto the toolbar doesn't close it). Touch: a long-press (hold) opens
22
+ * the same actions since hover doesn't exist on touch; a finger move (scroll)
23
+ * cancels the press, and a fired press suppresses the click that follows the
24
+ * lift so it doesn't also select.
25
+ */
26
+ export declare function useRowHoverActions(): UseRowHoverActionsResult;
@@ -1,5 +1,5 @@
1
1
  import { ReactNode } from 'react';
2
- import { Schema } from '../types/schema';
2
+ import { SchemaContextValue, Table } from '../types/schema';
3
3
  /**
4
4
  * Provider component for database schema context.
5
5
  * Fetches schema via GraphQL and makes it available to child components.
@@ -28,4 +28,10 @@ export declare const SchemaProvider: ({ children }: {
28
28
  *
29
29
  * @returns Schema context value with tables and metadata
30
30
  */
31
- export declare function useSchema(): Schema;
31
+ export declare function useSchema(): SchemaContextValue;
32
+ /**
33
+ * Keep only the tables a host allow-listed, matching on either name and ignoring
34
+ * case so a host can list them the way they read in its own docs. An empty or
35
+ * absent list means no restriction.
36
+ */
37
+ export declare function filterAllowedTables(tables: Table[], allowed?: string[]): Table[];
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,13 @@
1
+ import { Table } from '../types/schema';
2
+ import { ExportFormat, ExportResult } from '../lib/export';
3
+ /**
4
+ * Downloads a whole table WITHOUT opening it: the navigation-level counterpart
5
+ * of the grid toolbar's export. Reuses the grid's export projection
6
+ * (`buildQuery` with `fields: 'export'` — long text included, non-PK binary
7
+ * excluded, no join blocks), the shared page-draining serializer, and the same
8
+ * browser download path, so the two exports cannot drift. Unfiltered by design:
9
+ * a filtered export belongs to the grid, where the filters live.
10
+ * <see cref="DEFAULT_ROW_CAP"/> bounds the drain; the result reports
11
+ * `truncated` so the caller can warn instead of silently shipping a partial file.
12
+ */
13
+ export declare function useTableExport(): (table: Table, format: ExportFormat) => Promise<ExportResult>;
@@ -1,7 +1,5 @@
1
1
  import { Table, Column } from '../types/schema';
2
- interface ColumnJoin {
3
- column: Column;
4
- }
2
+ import { ColumnJoin } from '../lib/mutation-payload';
5
3
  export interface UseTableMutationResult {
6
4
  update: (detail: Record<string, unknown>) => Promise<unknown>;
7
5
  insert: (detail: Record<string, unknown>) => Promise<unknown>;
@@ -9,4 +7,3 @@ export interface UseTableMutationResult {
9
7
  error: Error | null;
10
8
  }
11
9
  export declare function useTableMutation(table: Table, editColumns: ColumnJoin[], idColumns: Column[], editId?: string): UseTableMutationResult;
12
- export {};
@@ -1,4 +1,4 @@
1
- import { Schema } from '../types/schema';
1
+ import { SchemaContextValue } from '../types/schema';
2
2
  export interface TableRefValue {
3
3
  key: string;
4
4
  label: string;
@@ -17,7 +17,7 @@ export interface TableRef {
17
17
  * list is narrowed server-side, so parents beyond the fetch window stay
18
18
  * findable; otherwise one window is fetched and the caller filters it.
19
19
  */
20
- export declare function useTableRef(schema: Schema, tableName: string, columnName: string, search?: string, enabled?: boolean): TableRef;
20
+ export declare function useTableRef(schema: SchemaContextValue, tableName: string, columnName: string, search?: string, enabled?: boolean): TableRef;
21
21
  export interface TableRefLookup {
22
22
  loading: boolean;
23
23
  error: unknown;
@@ -29,4 +29,4 @@ export interface TableRefLookup {
29
29
  * Select can still display the stored value instead of a misleading
30
30
  * placeholder. Pass `key` as null/'' to disable the lookup.
31
31
  */
32
- export declare function useTableRefValue(schema: Schema, tableName: string, columnName: string, key: unknown): TableRefLookup;
32
+ export declare function useTableRefValue(schema: SchemaContextValue, tableName: string, columnName: string, key: unknown): TableRefLookup;
@@ -57,27 +57,3 @@ export declare function buildRowCountQuery(tableNames: string[]): string | null;
57
57
  * @returns Table statistics map and loading state
58
58
  */
59
59
  export declare function useTableStats(enabled?: boolean): UseTableStatsResult;
60
- /**
61
- * Formats a number into an abbreviated string representation.
62
- *
63
- * @example
64
- * ```typescript
65
- * abbreviateNumber(12) // "12"
66
- * abbreviateNumber(1200) // "1.2k"
67
- * abbreviateNumber(45000) // "45k"
68
- * abbreviateNumber(1200000) // "1.2M"
69
- * ```
70
- *
71
- * @param num - Number to abbreviate
72
- * @returns Abbreviated string representation
73
- */
74
- export declare function abbreviateNumber(num: number | null): string;
75
- /**
76
- * Calculates a visual bar width (1-10) based on row count.
77
- * Used for sparkline visualization.
78
- *
79
- * @param count - Row count
80
- * @param maxCount - Maximum row count across all tables for scaling
81
- * @returns Width value from 1-10
82
- */
83
- export declare function calculateBarWidth(count: number | null, maxCount: number): number;
package/dist/index.d.ts CHANGED
@@ -2,6 +2,18 @@ import { Editor } from './editor';
2
2
  export default Editor;
3
3
  export { Editor };
4
4
  export type { GraphQLFetcher } from './common/fetcher';
5
- export { HttpGraphQLFetcher } from './common/fetcher';
5
+ export { HttpGraphQLFetcher, GraphQLRequestError } from './common/fetcher';
6
6
  export { useTableMutation } from './hooks/useTableMutation';
7
7
  export type { UseTableMutationResult } from './hooks/useTableMutation';
8
+ export { createSavedObjectsClient, parseSavedObject, SavedObjectConflictError, SAVED_OBJECTS_PATH, } from './common/saved-objects';
9
+ export type { SavedObject, SavedObjectType, SavedObjectsClient, } from './common/saved-objects';
10
+ export { FormRunner, FormRunnerView, resolveDefinitionTable } from './components/form-runner';
11
+ export { FormRunnerHost } from './components/form-runner-host';
12
+ export { parseFormDefinition, visibleFields } from './lib/form-definition';
13
+ export type { FormDefinition, FormField, FormControlType } from './lib/form-definition';
14
+ export type { FieldWidgetHint } from './lib/form-widget';
15
+ export { buildCsv, buildJson, formatCsvCell, exportAllRows, downloadTextFile, filenameFor, mimeFor, UTF8_BOM, DEFAULT_ROW_CAP, } from './lib/export';
16
+ export type { ExportFormat, JsonMode, CsvOptions, JsonOptions, ExportPage, ExportResult, ExportRunner, RunExportOptions, } from './lib/export';
17
+ export { serializeColumnFilters, deserializeColumnFilters } from './lib/query-builder';
18
+ export type { TableAction } from './lib/table-action';
19
+ export type { Table, Column } from './types/schema';
@@ -0,0 +1,17 @@
1
+ import { ColumnDef } from '@tanstack/react-table';
2
+ export interface ColumnOrderConfig {
3
+ /** Columns to place first, in this order. */
4
+ leading?: string[];
5
+ /** Columns to place last, in this order. */
6
+ trailing?: string[];
7
+ }
8
+ /**
9
+ * Reorder columns around a host's preferences: named leading columns first in the
10
+ * order named, named trailing columns last in the order named, everything else
11
+ * keeping its schema order in between. Names the table doesn't have are skipped,
12
+ * so one host config can cover tables that don't all carry the same columns.
13
+ *
14
+ * Order is independent of visibility: a column the viewer switches back on lands
15
+ * in its configured place rather than at the end.
16
+ */
17
+ export declare function orderColumns<TData>(columns: ColumnDef<TData, unknown>[], { leading, trailing }: ColumnOrderConfig): ColumnDef<TData, unknown>[];
@@ -0,0 +1 @@
1
+ export {};
@@ -11,6 +11,18 @@ export declare function isJsonColumn(col: {
11
11
  }): boolean;
12
12
  /** Check if a dbType is a long text type (text, ntext, varchar(max), xml) */
13
13
  export declare function isLongTextDbType(dbType: string): boolean;
14
+ /**
15
+ * Column-level "large value" check for fetch-on-demand decisions (grid SELECT
16
+ * exclusion, sortability, content-viewer cells). Prefers the server's
17
+ * dialect-decided `dbColumnSchema.isLargeValue` flag; the dbType-name fallback
18
+ * exists only for servers that predate the flag. The name heuristic is WRONG on
19
+ * PostgreSQL and SQLite — `text` is their ordinary string type, not a LOB — which
20
+ * is exactly why the server flag is authoritative when present.
21
+ */
22
+ export declare function isLargeValueColumn(col: {
23
+ dbType: string;
24
+ isLargeValue?: boolean;
25
+ }): boolean;
14
26
  /** Detect content kind from a string value and optional dbType hint */
15
27
  export declare function detectContentKind(value: string, dbType?: string): ContentKind;
16
28
  /** Max characters to show in a table cell before truncating */
@@ -19,3 +31,25 @@ export declare const CELL_TRUNCATE = 80;
19
31
  export declare function truncateForCell(value: string): string;
20
32
  /** Format binary data (base64 string) for display */
21
33
  export declare function formatBinaryPreview(value: string): string;
34
+ /** What a binary (base64) value actually IS, sniffed from its magic bytes. */
35
+ export type SniffedBinary = {
36
+ kind: 'image';
37
+ mime: string;
38
+ extension: string;
39
+ } | {
40
+ kind: 'pdf';
41
+ mime: 'application/pdf';
42
+ extension: '.pdf';
43
+ } | {
44
+ kind: 'unknown';
45
+ mime: 'application/octet-stream';
46
+ extension: '.bin';
47
+ };
48
+ /**
49
+ * Sniffs an image/document type from the FIRST BYTES of a base64 value — never
50
+ * from a column name or a user-supplied mime string, so a mislabeled blob can
51
+ * only ever downgrade to the generic binary rendering, not upgrade to <img>.
52
+ */
53
+ export declare function sniffBinaryContent(base64: string): SniffedBinary;
54
+ /** A data: URL for an inline binary preview (only call for sniffed images). */
55
+ export declare function binaryDataUrl(base64: string, mime: string): string;
@@ -0,0 +1 @@
1
+ export {};
@@ -1,8 +1,25 @@
1
- import { ColumnPanel } from '../data-panel';
1
+ /**
2
+ * @module lib/drill-stack
3
+ *
4
+ * Pure-logic helpers for the stackable parent/child drill-down used by the
5
+ * edit-db data panel. Each entry in the stack describes a side column: a
6
+ * target table plus an optional filter (FK column + parent row id) that
7
+ * scopes the child rows to those related to a row in the previous level.
8
+ *
9
+ * Kept dependency-free so it can be unit-tested without React or the DOM.
10
+ */
2
11
  /**
3
12
  * A single frame in the drill navigation chain, visible as one side column.
13
+ * `filterTable` + `filterId` + `filterColumn` describe the FK scoping applied
14
+ * to `tableName`'s rows — they're optional so the same shape can also
15
+ * represent a simple "open table X" panel.
4
16
  */
5
- export type DrillFrame = ColumnPanel;
17
+ export interface DrillFrame {
18
+ tableName: string;
19
+ filterTable?: string;
20
+ filterId?: string;
21
+ filterColumn?: string;
22
+ }
6
23
  /**
7
24
  * Is `frame` the same drill target as `other` (same table + same filter)?
8
25
  *