ydb-embedded-ui 3.4.5 → 3.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (31) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/dist/components/InfoViewer/formatters/table.ts +6 -0
  3. package/dist/components/TruncatedQuery/TruncatedQuery.js +1 -1
  4. package/dist/components/TruncatedQuery/TruncatedQuery.scss +7 -3
  5. package/dist/containers/Node/{NodePages.js → NodePages.ts} +1 -1
  6. package/dist/containers/Tablet/TabletControls/TabletControls.tsx +2 -2
  7. package/dist/containers/Tenant/Diagnostics/Overview/Overview.tsx +11 -43
  8. package/dist/containers/Tenant/Diagnostics/Overview/TableInfo/TableInfo.tsx +19 -17
  9. package/dist/containers/Tenant/Diagnostics/Overview/TableInfo/prepareTableInfo.ts +192 -37
  10. package/dist/containers/Tenant/Diagnostics/TopQueries/TopQueries.scss +20 -14
  11. package/dist/containers/Tenant/Diagnostics/TopQueries/TopQueries.tsx +49 -12
  12. package/dist/containers/Tenant/Diagnostics/TopShards/TopShards.tsx +37 -18
  13. package/dist/containers/Tenant/QueryEditor/QueryEditor.js +1 -0
  14. package/dist/routes.ts +1 -1
  15. package/dist/services/api.js +3 -3
  16. package/dist/store/reducers/{executeQuery.js → executeQuery.ts} +51 -21
  17. package/dist/store/reducers/executeTopQueries.ts +5 -1
  18. package/dist/store/reducers/{olapStats.js → olapStats.ts} +8 -18
  19. package/dist/store/reducers/settings.js +1 -1
  20. package/dist/store/reducers/storage.js +5 -7
  21. package/dist/types/api/query.ts +4 -1
  22. package/dist/types/api/schema.ts +523 -3
  23. package/dist/types/common.ts +1 -0
  24. package/dist/types/store/executeQuery.ts +42 -0
  25. package/dist/types/store/olapStats.ts +14 -0
  26. package/dist/utils/query.test.ts +42 -29
  27. package/dist/utils/query.ts +34 -22
  28. package/dist/utils/timeParsers/formatDuration.ts +30 -12
  29. package/dist/utils/timeParsers/i18n/en.json +4 -0
  30. package/dist/utils/timeParsers/i18n/ru.json +4 -0
  31. package/package.json +1 -1
@@ -1,5 +1,7 @@
1
1
  import {useCallback, useEffect, useRef, useState} from 'react';
2
2
  import {useDispatch} from 'react-redux';
3
+ import {useHistory, useLocation} from 'react-router';
4
+ import qs from 'qs';
3
5
  import cn from 'bem-cn-lite';
4
6
 
5
7
  import DataTable, {Column, Settings} from '@gravity-ui/react-data-table';
@@ -21,13 +23,14 @@ import type {EPathType} from '../../../../types/api/schema';
21
23
  import type {ITopQueriesFilters} from '../../../../types/store/executeTopQueries';
22
24
  import type {IQueryResult} from '../../../../types/store/query';
23
25
 
24
- import {formatDateTime} from '../../../../utils';
26
+ import {formatDateTime, formatNumber} from '../../../../utils';
25
27
  import {DEFAULT_TABLE_SETTINGS, HOUR_IN_SECONDS} from '../../../../utils/constants';
26
28
  import {useAutofetcher, useTypedSelector} from '../../../../utils/hooks';
27
29
  import {prepareQueryError} from '../../../../utils/query';
30
+ import routes, {createHref} from '../../../../routes';
28
31
 
29
32
  import {isColumnEntityType} from '../../utils/schema';
30
- import {TenantGeneralTabsIds} from '../../TenantPages';
33
+ import {TenantGeneralTabsIds, TenantTabsGroups} from '../../TenantPages';
31
34
 
32
35
  import i18n from './i18n';
33
36
  import './TopQueries.scss';
@@ -43,19 +46,41 @@ const MAX_QUERY_HEIGHT = 10;
43
46
  const COLUMNS: Column<KeyValueRow>[] = [
44
47
  {
45
48
  name: 'CPUTimeUs',
46
- width: 140,
47
- sortAccessor: (row) => Number(row['CPUTimeUs']),
49
+ sortAccessor: (row) => Number(row.CPUTimeUs),
50
+ align: DataTable.RIGHT,
48
51
  },
49
52
  {
50
53
  name: 'QueryText',
51
54
  width: 500,
52
55
  sortable: false,
53
- render: ({value}) => <TruncatedQuery value={value} maxQueryHeight={MAX_QUERY_HEIGHT} />,
56
+ render: ({row}) => (
57
+ <div className={b('query')}>
58
+ <TruncatedQuery value={row.QueryText} maxQueryHeight={MAX_QUERY_HEIGHT} />
59
+ </div>
60
+ ),
61
+ },
62
+ {
63
+ name: 'EndTime',
64
+ render: ({row}) => formatDateTime(new Date(row.EndTime as string).getTime()),
65
+ align: DataTable.RIGHT,
66
+ },
67
+ {
68
+ name: 'ReadRows',
69
+ render: ({row}) => formatNumber(row.ReadRows),
70
+ sortAccessor: (row) => Number(row.ReadRows),
71
+ align: DataTable.RIGHT,
72
+ },
73
+ {
74
+ name: 'ReadBytes',
75
+ render: ({row}) => formatNumber(row.ReadBytes),
76
+ sortAccessor: (row) => Number(row.ReadBytes),
77
+ align: DataTable.RIGHT,
54
78
  },
55
79
  {
56
- name: 'IntervalEnd',
57
- width: 140,
58
- render: ({value}) => formatDateTime(new Date(value as string).getTime()),
80
+ name: 'UserSID',
81
+ render: ({row}) => <div className={b('user-sid')}>{row.UserSID || '–'}</div>,
82
+ sortAccessor: (row) => String(row.UserSID),
83
+ align: DataTable.LEFT,
59
84
  },
60
85
  ];
61
86
 
@@ -65,8 +90,10 @@ interface TopQueriesProps {
65
90
  type?: EPathType;
66
91
  }
67
92
 
68
- export const TopQueries = ({path, type, changeSchemaTab}: TopQueriesProps) => {
93
+ export const TopQueries = ({path, type}: TopQueriesProps) => {
69
94
  const dispatch = useDispatch();
95
+ const location = useLocation();
96
+ const history = useHistory();
70
97
 
71
98
  const {autorefresh} = useTypedSelector((state) => state.schema);
72
99
 
@@ -144,9 +171,19 @@ export const TopQueries = ({path, type, changeSchemaTab}: TopQueriesProps) => {
144
171
  const {QueryText: input} = row;
145
172
 
146
173
  dispatch(changeUserInput({input}));
147
- changeSchemaTab(TenantGeneralTabsIds.query);
174
+
175
+ const queryParams = qs.parse(location.search, {
176
+ ignoreQueryPrefix: true,
177
+ });
178
+
179
+ const queryPath = createHref(routes.tenant, undefined, {
180
+ ...queryParams,
181
+ [TenantTabsGroups.general]: TenantGeneralTabsIds.query,
182
+ });
183
+
184
+ history.push(queryPath);
148
185
  },
149
- [changeSchemaTab, dispatch],
186
+ [dispatch, history, location],
150
187
  );
151
188
 
152
189
  const handleTextSearchUpdate = (text: string) => {
@@ -179,7 +216,7 @@ export const TopQueries = ({path, type, changeSchemaTab}: TopQueriesProps) => {
179
216
  }
180
217
 
181
218
  return (
182
- <div className={b('result')}>
219
+ <div className={b('table')}>
183
220
  <DataTable
184
221
  columns={COLUMNS}
185
222
  data={data}
@@ -20,6 +20,7 @@ import {setCurrentSchemaPath, getSchema} from '../../../../store/reducers/schema
20
20
  import {EShardsWorkloadMode, IShardsWorkloadFilters} from '../../../../types/store/shardsWorkload';
21
21
 
22
22
  import type {EPathType} from '../../../../types/api/schema';
23
+ import type {CellValue, KeyValueRow} from '../../../../types/api/query';
23
24
 
24
25
  import {formatDateTime, formatNumber} from '../../../../utils';
25
26
  import {DEFAULT_TABLE_SETTINGS, HOUR_IN_SECONDS} from '../../../../utils/constants';
@@ -57,10 +58,17 @@ const tableColumnsNames = {
57
58
  IntervalEnd: 'IntervalEnd',
58
59
  };
59
60
 
60
- function prepareCPUWorkloadValue(value: string) {
61
+ function prepareCPUWorkloadValue(value: string | number) {
61
62
  return `${(Number(value) * 100).toFixed(2)}%`;
62
63
  }
63
64
 
65
+ function prepareDateTimeValue(value: CellValue) {
66
+ if (!value) {
67
+ return '–';
68
+ }
69
+ return formatDateTime(new Date(value).getTime());
70
+ }
71
+
64
72
  function stringToDataTableSortOrder(value: string): SortOrder[] | undefined {
65
73
  return value
66
74
  ? value.split(',').map((columnId) => ({
@@ -190,16 +198,17 @@ export const TopShards = ({tenantPath, type}: TopShardsProps) => {
190
198
  };
191
199
  };
192
200
 
193
- const columns: Column<any>[] = [
201
+ const columns: Column<KeyValueRow>[] = [
194
202
  {
195
203
  name: tableColumnsNames.Path,
196
- render: ({value: relativeNodePath}) => {
204
+ render: ({row}) => {
205
+ // row.Path - relative schema path
197
206
  return (
198
207
  <span
199
- onClick={onSchemaClick(tenantPath + relativeNodePath)}
208
+ onClick={onSchemaClick(tenantPath + row.Path)}
200
209
  className={bLink({view: 'normal'})}
201
210
  >
202
- {relativeNodePath as string}
211
+ {row.Path}
203
212
  </span>
204
213
  );
205
214
  },
@@ -207,25 +216,28 @@ export const TopShards = ({tenantPath, type}: TopShardsProps) => {
207
216
  },
208
217
  {
209
218
  name: tableColumnsNames.CPUCores,
210
- render: ({value}) => {
211
- return prepareCPUWorkloadValue(value as string);
219
+ render: ({row}) => {
220
+ return prepareCPUWorkloadValue(row.CPUCores || 0);
212
221
  },
213
222
  align: DataTable.RIGHT,
214
223
  },
215
224
  {
216
225
  name: tableColumnsNames.DataSize,
217
226
  header: 'DataSize (B)',
218
- render: ({value}) => {
219
- return formatNumber(value as number);
227
+ render: ({row}) => {
228
+ return formatNumber(row.DataSize);
220
229
  },
221
230
  align: DataTable.RIGHT,
222
231
  },
223
232
  {
224
233
  name: tableColumnsNames.TabletId,
225
- render: ({value}) => {
234
+ render: ({row}) => {
235
+ if (!row.TabletId) {
236
+ return '–';
237
+ }
226
238
  return (
227
- <InternalLink to={createHref(routes.tablet, {id: value})}>
228
- {value as string}
239
+ <InternalLink to={createHref(routes.tablet, {id: row.TabletId})}>
240
+ {row.TabletId}
229
241
  </InternalLink>
230
242
  );
231
243
  },
@@ -233,10 +245,13 @@ export const TopShards = ({tenantPath, type}: TopShardsProps) => {
233
245
  },
234
246
  {
235
247
  name: tableColumnsNames.NodeId,
236
- render: ({value: nodeId}) => {
248
+ render: ({row}) => {
249
+ if (!row.NodeId) {
250
+ return '–';
251
+ }
237
252
  return (
238
- <InternalLink to={getDefaultNodePath(nodeId as string)}>
239
- {nodeId as string}
253
+ <InternalLink to={getDefaultNodePath(row.NodeId)}>
254
+ {row.NodeId}
240
255
  </InternalLink>
241
256
  );
242
257
  },
@@ -245,7 +260,7 @@ export const TopShards = ({tenantPath, type}: TopShardsProps) => {
245
260
  },
246
261
  {
247
262
  name: tableColumnsNames.InFlightTxCount,
248
- render: ({value}) => formatNumber(value as number),
263
+ render: ({row}) => formatNumber(row.InFlightTxCount),
249
264
  align: DataTable.RIGHT,
250
265
  sortable: false,
251
266
  },
@@ -255,12 +270,16 @@ export const TopShards = ({tenantPath, type}: TopShardsProps) => {
255
270
  // after NodeId
256
271
  columns.splice(5, 0, {
257
272
  name: tableColumnsNames.PeakTime,
258
- render: ({value}) => formatDateTime(new Date(value as string).valueOf()),
273
+ render: ({row}) => {
274
+ return prepareDateTimeValue(row.PeakTime);
275
+ },
259
276
  sortable: false,
260
277
  });
261
278
  columns.push({
262
279
  name: tableColumnsNames.IntervalEnd,
263
- render: ({value}) => formatDateTime(new Date(value as string).getTime()),
280
+ render: ({row}) => {
281
+ return prepareDateTimeValue(row.IntervalEnd);
282
+ },
264
283
  });
265
284
  }
266
285
 
@@ -544,6 +544,7 @@ function QueryEditor(props) {
544
544
  </Button>
545
545
  <DropdownMenu
546
546
  items={menuItems}
547
+ popupClassName={b('select-query-action-popup')}
547
548
  switcher={
548
549
  <Button
549
550
  view="action"
package/dist/routes.ts CHANGED
@@ -28,7 +28,7 @@ export const CLUSTER_PAGES = {
28
28
 
29
29
  export function createHref(
30
30
  route: string,
31
- params?: object,
31
+ params?: Record<string, string | number>,
32
32
  query: Record<string | number, string | number | string[] | number[] | undefined> = {},
33
33
  ) {
34
34
  let extendedQuery = query;
@@ -96,9 +96,9 @@ export class YdbEmbeddedAPI extends AxiosWrapper {
96
96
  enums: true,
97
97
  backup: false,
98
98
  private: true,
99
- partition_config: false,
100
- partition_stats: false,
101
- partitioning_info: false,
99
+ partition_config: true,
100
+ partition_stats: true,
101
+ partitioning_info: true,
102
102
  subs: 1,
103
103
  },
104
104
  {concurrentId: concurrentId || `getSchema|${path}`},
@@ -1,13 +1,25 @@
1
- import {createRequestActionTypes, createApiRequest} from '../utils';
2
- import '../../services/api';
1
+ import type {Reducer} from 'redux';
2
+
3
+ import type {Actions} from '../../types/api/query';
4
+ import type {
5
+ ExecuteQueryAction,
6
+ ExecuteQueryState,
7
+ MonacoHotKeyAction,
8
+ RunAction,
9
+ } from '../../types/store/executeQuery';
3
10
  import {getValueFromLS, parseJson} from '../../utils/utils';
4
11
  import {QUERIES_HISTORY_KEY, QUERY_INITIAL_RUN_ACTION_KEY} from '../../utils/constants';
5
12
  import {parseQueryAPIExecuteResponse} from '../../utils/query';
13
+ import '../../services/api';
14
+
15
+ import {createRequestActionTypes, createApiRequest} from '../utils';
16
+
6
17
  import {readSavedSettingsValue} from './settings';
7
18
 
8
19
  const MAXIMUM_QUERIES_IN_HISTORY = 20;
9
20
 
10
- const SEND_QUERY = createRequestActionTypes('query', 'SEND_QUERY');
21
+ export const SEND_QUERY = createRequestActionTypes('query', 'SEND_QUERY');
22
+
11
23
  const CHANGE_USER_INPUT = 'query/CHANGE_USER_INPUT';
12
24
  const SAVE_QUERY_TO_HISTORY = 'query/SAVE_QUERY_TO_HISTORY';
13
25
  const GO_TO_PREVIOUS_QUERY = 'query/GO_TO_PREVIOUS_QUERY';
@@ -15,21 +27,21 @@ const GO_TO_NEXT_QUERY = 'query/GO_TO_NEXT_QUERY';
15
27
  const SELECT_RUN_ACTION = 'query/SELECT_RUN_ACTION';
16
28
  const MONACO_HOT_KEY = 'query/MONACO_HOT_KEY';
17
29
 
18
- const queriesHistoryInitial = parseJson(getValueFromLS(QUERIES_HISTORY_KEY, '[]'));
30
+ const queriesHistoryInitial: string[] = parseJson(getValueFromLS(QUERIES_HISTORY_KEY, '[]'));
19
31
 
20
32
  const sliceLimit = queriesHistoryInitial.length - MAXIMUM_QUERIES_IN_HISTORY;
21
33
 
22
34
  export const RUN_ACTIONS_VALUES = {
23
35
  script: 'execute-script',
24
36
  scan: 'execute-scan',
25
- };
37
+ } as const;
26
38
 
27
39
  export const MONACO_HOT_KEY_ACTIONS = {
28
40
  sendQuery: 'sendQuery',
29
41
  goPrev: 'goPrev',
30
42
  goNext: 'goNext',
31
43
  getExplain: 'getExplain',
32
- };
44
+ } as const;
33
45
 
34
46
  const initialState = {
35
47
  loading: false,
@@ -45,7 +57,10 @@ const initialState = {
45
57
  monacoHotKey: null,
46
58
  };
47
59
 
48
- const executeQuery = (state = initialState, action) => {
60
+ const executeQuery: Reducer<ExecuteQueryState, ExecuteQueryAction> = (
61
+ state = initialState,
62
+ action,
63
+ ) => {
49
64
  switch (action.type) {
50
65
  case SEND_QUERY.REQUEST: {
51
66
  return {
@@ -141,51 +156,66 @@ const executeQuery = (state = initialState, action) => {
141
156
  }
142
157
  };
143
158
 
144
- export const sendQuery = ({query, database, action}) => {
159
+ export const sendQuery = ({
160
+ query,
161
+ database,
162
+ action,
163
+ }: {
164
+ query: string;
165
+ database: string;
166
+ action: Actions;
167
+ }) => {
145
168
  return createApiRequest({
146
- request: window.api.sendQuery({schema: 'modern', query, database, action, stats: 'profile'}),
169
+ request: window.api.sendQuery({
170
+ schema: 'modern',
171
+ query,
172
+ database,
173
+ action,
174
+ stats: 'profile',
175
+ }),
147
176
  actions: SEND_QUERY,
148
177
  dataHandler: parseQueryAPIExecuteResponse,
149
178
  });
150
179
  };
151
180
 
152
- export const saveQueryToHistory = (query) => {
181
+ export const saveQueryToHistory = (query: string) => {
153
182
  return {
154
183
  type: SAVE_QUERY_TO_HISTORY,
155
184
  data: query,
156
- };
185
+ } as const;
157
186
  };
158
187
 
159
- export const selectRunAction = (value) => {
188
+ export const selectRunAction = (value: RunAction) => {
160
189
  return {
161
190
  type: SELECT_RUN_ACTION,
162
191
  data: value,
163
- };
192
+ } as const;
164
193
  };
165
194
 
166
195
  export const goToPreviousQuery = () => {
167
196
  return {
168
197
  type: GO_TO_PREVIOUS_QUERY,
169
- };
198
+ } as const;
170
199
  };
171
200
 
172
201
  export const goToNextQuery = () => {
173
202
  return {
174
203
  type: GO_TO_NEXT_QUERY,
175
- };
204
+ } as const;
176
205
  };
177
206
 
178
- export const changeUserInput = ({input}) => {
179
- return (dispatch) => {
180
- dispatch({type: CHANGE_USER_INPUT, data: {input}});
181
- };
207
+ export const changeUserInput = ({input}: {input: string}) => {
208
+ return {
209
+ type: CHANGE_USER_INPUT,
210
+ data: {input},
211
+ } as const;
182
212
  };
183
213
 
184
- export const setMonacoHotKey = (value) => {
214
+ export const setMonacoHotKey = (value: MonacoHotKeyAction) => {
185
215
  return {
186
216
  type: MONACO_HOT_KEY,
187
217
  data: value,
188
- };
218
+ } as const;
189
219
  };
190
220
 
191
221
  export default executeQuery;
@@ -66,7 +66,11 @@ const getQueryText = (path: string, filters?: ITopQueriesFilters) => {
66
66
  SELECT
67
67
  CPUTime as CPUTimeUs,
68
68
  QueryText,
69
- IntervalEnd
69
+ IntervalEnd,
70
+ EndTime,
71
+ ReadRows,
72
+ ReadBytes,
73
+ UserSID
70
74
  FROM \`${path}/.sys/top_queries_by_cpu_time_one_hour\`
71
75
  WHERE ${filterConditions || 'true'}
72
76
  `;
@@ -1,11 +1,13 @@
1
- import '../../services/api';
1
+ import type {Reducer} from 'redux';
2
+
3
+ import type {OlapStatsAction, OlapStatsState} from '../../types/store/olapStats';
2
4
 
5
+ import '../../services/api';
3
6
  import {parseQueryAPIExecuteResponse} from '../../utils/query';
4
7
 
5
8
  import {createRequestActionTypes, createApiRequest} from '../utils';
6
9
 
7
- const FETCH_OLAP_STATS = createRequestActionTypes('query', 'SEND_OLAP_STATS_QUERY');
8
- const SET_OLAP_STATS_OPTIONS = createRequestActionTypes('query', 'SET_OLAP_STATS_OPTIONS');
10
+ export const FETCH_OLAP_STATS = createRequestActionTypes('query', 'SEND_OLAP_STATS_QUERY');
9
11
  const RESET_LOADING_STATE = 'olapStats/RESET_LOADING_STATE';
10
12
 
11
13
  const initialState = {
@@ -13,13 +15,13 @@ const initialState = {
13
15
  wasLoaded: false,
14
16
  };
15
17
 
16
- function createOlatStatsQuery(path) {
18
+ function createOlatStatsQuery(path: string) {
17
19
  return `SELECT * FROM \`${path}/.sys/primary_index_stats\``;
18
20
  }
19
21
 
20
22
  const queryAction = 'execute-scan';
21
23
 
22
- const olapStats = (state = initialState, action) => {
24
+ const olapStats: Reducer<OlapStatsState, OlapStatsAction> = (state = initialState, action) => {
23
25
  switch (action.type) {
24
26
  case FETCH_OLAP_STATS.REQUEST: {
25
27
  return {
@@ -44,11 +46,6 @@ const olapStats = (state = initialState, action) => {
44
46
  loading: false,
45
47
  };
46
48
  }
47
- case SET_OLAP_STATS_OPTIONS:
48
- return {
49
- ...state,
50
- ...action.data,
51
- };
52
49
  case RESET_LOADING_STATE: {
53
50
  return {
54
51
  ...state,
@@ -73,17 +70,10 @@ export const getOlapStats = ({path = ''}) => {
73
70
  });
74
71
  };
75
72
 
76
- export function setOlapStatsOptions(options) {
77
- return {
78
- type: SET_OLAP_STATS_OPTIONS,
79
- data: options,
80
- };
81
- }
82
-
83
73
  export function resetLoadingState() {
84
74
  return {
85
75
  type: RESET_LOADING_STATE,
86
- };
76
+ } as const;
87
77
  }
88
78
 
89
79
  export default olapStats;
@@ -38,7 +38,7 @@ export const initialState = {
38
38
  problemFilter: ALL,
39
39
  userSettings: {
40
40
  ...userSettings,
41
- [THEME_KEY]: readSavedSettingsValue(THEME_KEY, 'light'),
41
+ [THEME_KEY]: readSavedSettingsValue(THEME_KEY, 'system'),
42
42
  [INVERTED_DISKS_KEY]: readSavedSettingsValue(INVERTED_DISKS_KEY, 'false'),
43
43
  [USE_NODES_ENDPOINT_IN_DIAGNOSTICS_KEY]: readSavedSettingsValue(
44
44
  USE_NODES_ENDPOINT_IN_DIAGNOSTICS_KEY,
@@ -243,13 +243,11 @@ export const getFlatListStorageGroups = createSelector([getStoragePools], (stora
243
243
  const limitSizeBytes = _.reduce(
244
244
  group.VDisks,
245
245
  (acc, vDisk) => {
246
- return (
247
- acc +
248
- (Number(vDisk.AvailableSize) ||
249
- Number(vDisk.PDisk?.AvailableSize) ||
250
- 0) +
251
- (Number(vDisk.AllocatedSize) || 0)
252
- );
246
+ const {AvailableSize, AllocatedSize, PDisk} = vDisk;
247
+ const available = (AvailableSize ?? PDisk?.AvailableSize) || 0;
248
+ const allocated = AllocatedSize || 0;
249
+
250
+ return acc + Number(available) + Number(allocated);
253
251
  },
254
252
  0,
255
253
  );
@@ -30,7 +30,7 @@ export type Schemas = 'classic' | 'modern' | 'ydb' | undefined;
30
30
 
31
31
  // common types
32
32
 
33
- type CellValue = string | number | null | undefined;
33
+ export type CellValue = string | number | null | undefined;
34
34
 
35
35
  export type KeyValueRow<T = CellValue> = {
36
36
  [key: string]: T;
@@ -63,6 +63,7 @@ export type ExecuteYdbResponse = {
63
63
  result: KeyValueRow[];
64
64
  } & CommonFields;
65
65
 
66
+ // prettier-ignore
66
67
  type ExecuteResponse<Schema extends Schemas> =
67
68
  | CommonFields // result can be undefined for queries like `insert into`
68
69
  | (Schema extends 'modern'
@@ -102,6 +103,7 @@ type ExplainResponse = CommonFields;
102
103
 
103
104
  // deprecated response from older versions, backward compatibility
104
105
 
106
+ // prettier-ignore
105
107
  type DeprecatedExplainResponse<Action extends ExplainActions> =
106
108
  Action extends 'explain-ast'
107
109
  ? ({result: {ast: AST}} & Required<DeprecatedCommonFields>) | {ast: AST}
@@ -121,6 +123,7 @@ export type QueryAPIExplainResponse<Action extends ExplainActions> =
121
123
  | DeprecatedExplainResponse<Action>
122
124
  | null;
123
125
 
126
+ // prettier-ignore
124
127
  export type QueryAPIResponse<Action extends Actions, Schema extends Schemas = undefined> =
125
128
  Action extends ExecuteActions
126
129
  ? QueryAPIExecuteResponse<Schema>