@rozenite/sqlite-plugin 1.13.0 → 2.1.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 (46) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/dist/devtools/assets/panel-BarPLQ4-.css +1 -0
  3. package/dist/devtools/assets/{panel-DjRs5NTl.js → panel-BsdCagVv.js} +45 -44
  4. package/dist/devtools/panel.html +2 -2
  5. package/dist/react-native/chunks/index.require.js +4 -16
  6. package/dist/react-native/chunks/sql.require.js +1 -3
  7. package/dist/react-native/chunks/useRozeniteSqlitePlugin.require.js +92 -110
  8. package/dist/react-native/index.d.ts +2 -2
  9. package/dist/rozenite.json +1 -1
  10. package/package.json +27 -31
  11. package/react-native.ts +7 -14
  12. package/src/react-native/adapters/__tests__/expo-sqlite.test.ts +4 -14
  13. package/src/react-native/adapters/expo-sqlite.ts +11 -40
  14. package/src/react-native/adapters/generic.ts +5 -13
  15. package/src/react-native/adapters/index.ts +1 -4
  16. package/src/react-native/sqlite-view.ts +2 -8
  17. package/src/react-native/useRozeniteSqlitePlugin.ts +110 -130
  18. package/src/react-native/useSqliteAgentTools.ts +5 -14
  19. package/src/shared/__tests__/bridge-values.test.ts +6 -11
  20. package/src/shared/__tests__/sql.test.ts +4 -8
  21. package/src/shared/bridge-values.ts +2 -5
  22. package/src/shared/sql.ts +3 -7
  23. package/src/ui/__tests__/sql-editor-utils.test.ts +1 -5
  24. package/src/ui/__tests__/sqlite-drop-mutations.test.ts +138 -0
  25. package/src/ui/__tests__/sqlite-row-mutations.test.ts +1 -3
  26. package/src/ui/__tests__/sqlite-table-column-order.test.ts +4 -19
  27. package/src/ui/cell-detail-drawer.tsx +1 -6
  28. package/src/ui/globals.css +26 -65
  29. package/src/ui/panel.tsx +442 -568
  30. package/src/ui/query-result-table.tsx +8 -26
  31. package/src/ui/sql-editor-utils.ts +24 -55
  32. package/src/ui/sql-editor.tsx +13 -46
  33. package/src/ui/sqlite-data-table.tsx +11 -28
  34. package/src/ui/sqlite-drop-modal.tsx +193 -0
  35. package/src/ui/sqlite-drop-mutations.ts +53 -0
  36. package/src/ui/sqlite-introspection.ts +9 -25
  37. package/src/ui/sqlite-row-delete-modal.tsx +5 -12
  38. package/src/ui/sqlite-row-edit-modal.tsx +22 -64
  39. package/src/ui/sqlite-row-edit-value.ts +2 -11
  40. package/src/ui/sqlite-row-mutations.ts +10 -32
  41. package/src/ui/sqlite-table-column-order.ts +8 -23
  42. package/src/ui/use-sqlite-requests.ts +46 -86
  43. package/src/ui/utils.ts +1 -5
  44. package/src/ui/value-utils.tsx +3 -11
  45. package/dist/devtools/assets/panel-CIU0JBOs.css +0 -1
  46. package/postcss.config.js +0 -6
@@ -0,0 +1,53 @@
1
+ import { quoteSqlIdentifier } from '../shared/sql';
2
+ import type { SqliteEntity } from './sqlite-introspection';
3
+
4
+ export type SqliteDropTarget = Pick<SqliteEntity, 'schemaName' | 'name' | 'type'>;
5
+
6
+ const buildQualifiedEntityName = (schemaName: string, entityName: string) =>
7
+ `${quoteSqlIdentifier(schemaName)}.${quoteSqlIdentifier(entityName)}`;
8
+
9
+ /**
10
+ * Builds a single `DROP TABLE` / `DROP VIEW` statement for the given entity.
11
+ * Identifiers are quoted (never parameterized, since SQLite does not support
12
+ * parameter binding for identifiers), so this is the only place that needs to
13
+ * get quoting right.
14
+ */
15
+ export const buildDropEntitySql = (entity: SqliteDropTarget): string => {
16
+ const keyword = entity.type === 'view' ? 'VIEW' : 'TABLE';
17
+ return `DROP ${keyword} ${buildQualifiedEntityName(entity.schemaName, entity.name)}`;
18
+ };
19
+
20
+ /**
21
+ * Orders entities so that views are dropped before tables, preserving the
22
+ * relative order within each group. This keeps a view that references a
23
+ * table from ever being left dangling mid-sweep.
24
+ */
25
+ export const orderEntitiesForDrop = (entities: SqliteDropTarget[]): SqliteDropTarget[] => [
26
+ ...entities.filter((entity) => entity.type === 'view'),
27
+ ...entities.filter((entity) => entity.type === 'table'),
28
+ ];
29
+
30
+ /**
31
+ * Builds the full drop-everything script for a database sweep: every view,
32
+ * then every table, each as its own statement. Returns an empty string when
33
+ * there is nothing to drop.
34
+ */
35
+ export const buildDropAllEntitiesSql = (entities: SqliteDropTarget[]): string =>
36
+ orderEntitiesForDrop(entities)
37
+ .map((entity) => `${buildDropEntitySql(entity)};`)
38
+ .join('\n');
39
+
40
+ export const SQLITE_READ_FOREIGN_KEYS_SQL = 'PRAGMA foreign_keys';
41
+
42
+ /**
43
+ * `PRAGMA foreign_keys` is per-connection and not parameterizable; the value
44
+ * is always a literal 0/1 keyword, never user input, so this is safe to
45
+ * inline directly.
46
+ */
47
+ export const buildSetForeignKeysSql = (enabled: boolean): string =>
48
+ `PRAGMA foreign_keys = ${enabled ? 'ON' : 'OFF'}`;
49
+
50
+ export const isForeignKeysEnabled = (rows: Record<string, unknown>[]): boolean => {
51
+ const rawValue = rows[0]?.foreign_keys;
52
+ return Number(rawValue) === 1;
53
+ };
@@ -54,13 +54,10 @@ export type SqliteIndexColumnInfo = {
54
54
  const buildQualifiedEntityName = (schemaName: string, entityName: string) =>
55
55
  `${quoteSqlIdentifier(schemaName)}.${quoteSqlIdentifier(entityName)}`;
56
56
 
57
- const buildPragmaPrefix = (schemaName: string) =>
58
- `${quoteSqlIdentifier(schemaName)}.`;
57
+ const buildPragmaPrefix = (schemaName: string) => `${quoteSqlIdentifier(schemaName)}.`;
59
58
 
60
- const asString = (value: unknown) =>
61
- typeof value === 'string' ? value : String(value ?? '');
62
- const asNullableString = (value: unknown) =>
63
- value == null ? null : String(value);
59
+ const asString = (value: unknown) => (typeof value === 'string' ? value : String(value ?? ''));
60
+ const asNullableString = (value: unknown) => (value == null ? null : String(value));
64
61
  const asNumber = (value: unknown) => {
65
62
  const parsed = Number(value ?? 0);
66
63
  return Number.isNaN(parsed) ? 0 : parsed;
@@ -93,10 +90,7 @@ export const buildBrowseEntitySql = (
93
90
  export const buildEntityCountSql = (schemaName: string, entityName: string) =>
94
91
  `SELECT COUNT(*) AS count FROM ${buildQualifiedEntityName(schemaName, entityName)}`;
95
92
 
96
- export const buildCreateSqlLookup = (
97
- schemaName: string,
98
- entityName: string,
99
- ) => `
93
+ export const buildCreateSqlLookup = (schemaName: string, entityName: string) => `
100
94
  SELECT sql
101
95
  FROM ${quoteSqlIdentifier(schemaName)}.sqlite_schema
102
96
  WHERE type IN ('table', 'view')
@@ -125,17 +119,12 @@ export const parseSchemas = (result: SqliteQueryResult): SqliteSchema[] =>
125
119
  }))
126
120
  .filter((schema) => !!schema.name);
127
121
 
128
- export const parseEntities = (
129
- result: SqliteQueryResult,
130
- schemaName: string,
131
- ): SqliteEntity[] =>
122
+ export const parseEntities = (result: SqliteQueryResult, schemaName: string): SqliteEntity[] =>
132
123
  result.rows
133
124
  .map((row) => ({
134
125
  schemaName,
135
126
  name: asString(row.name),
136
- type: (asString(row.type) === 'view'
137
- ? 'view'
138
- : 'table') as SqliteEntityType,
127
+ type: (asString(row.type) === 'view' ? 'view' : 'table') as SqliteEntityType,
139
128
  sql: asNullableString(row.sql),
140
129
  }))
141
130
  .filter((entity) => !!entity.name);
@@ -151,9 +140,7 @@ export const parseColumns = (result: SqliteQueryResult): SqliteColumnInfo[] =>
151
140
  hidden: asNumber(row.hidden),
152
141
  }));
153
142
 
154
- export const parseForeignKeys = (
155
- result: SqliteQueryResult,
156
- ): SqliteForeignKeyInfo[] =>
143
+ export const parseForeignKeys = (result: SqliteQueryResult): SqliteForeignKeyInfo[] =>
157
144
  result.rows.map((row) => ({
158
145
  id: asNumber(row.id),
159
146
  seq: asNumber(row.seq),
@@ -174,9 +161,7 @@ export const parseIndexes = (result: SqliteQueryResult): SqliteIndexInfo[] =>
174
161
  partial: asNumber(row.partial) === 1,
175
162
  }));
176
163
 
177
- export const parseIndexColumns = (
178
- result: SqliteQueryResult,
179
- ): SqliteIndexColumnInfo[] =>
164
+ export const parseIndexColumns = (result: SqliteQueryResult): SqliteIndexColumnInfo[] =>
180
165
  result.rows
181
166
  .map((row) => ({
182
167
  seqno: asNumber(row.seqno),
@@ -185,5 +170,4 @@ export const parseIndexColumns = (
185
170
  }))
186
171
  .filter((column) => !!column.name);
187
172
 
188
- export const parseCount = (result: SqliteQueryResult) =>
189
- asNumber(result.rows[0]?.count);
173
+ export const parseCount = (result: SqliteQueryResult) => asNumber(result.rows[0]?.count);
@@ -1,10 +1,7 @@
1
1
  import { Modal, useOverlayState } from '@heroui/react';
2
2
  import { AlertTriangle, Trash2 } from 'lucide-react';
3
3
  import { useEffect, useState } from 'react';
4
- import {
5
- SqliteModalCloseButton,
6
- sqliteSecondaryButtonClassName,
7
- } from './sqlite-modal-controls';
4
+ import { SqliteModalCloseButton, sqliteSecondaryButtonClassName } from './sqlite-modal-controls';
8
5
 
9
6
  type SqliteRowDeleteModalProps = {
10
7
  isOpen: boolean;
@@ -50,9 +47,7 @@ export const SqliteRowDeleteModal = ({
50
47
  await onDelete();
51
48
  onClose();
52
49
  } catch (nextError) {
53
- setError(
54
- nextError instanceof Error ? nextError.message : String(nextError),
55
- );
50
+ setError(nextError instanceof Error ? nextError.message : String(nextError));
56
51
  } finally {
57
52
  setDeleting(false);
58
53
  }
@@ -76,9 +71,7 @@ export const SqliteRowDeleteModal = ({
76
71
  <AlertTriangle aria-hidden="true" className="h-5 w-5" />
77
72
  </div>
78
73
  <div>
79
- <h2 className="text-lg font-semibold text-white">
80
- Delete Row {rowNumber}
81
- </h2>
74
+ <h2 className="text-lg font-semibold text-white">Delete Row {rowNumber}</h2>
82
75
  <p className="mt-1 text-sm text-slate-400">{entityName}</p>
83
76
  </div>
84
77
  </div>
@@ -88,8 +81,8 @@ export const SqliteRowDeleteModal = ({
88
81
  <Modal.Body className="space-y-0 p-0">
89
82
  <div className="space-y-5 px-5 py-5">
90
83
  <p className="text-sm leading-6 text-slate-300">
91
- This will permanently delete the selected row and immediately
92
- refetch the current page.
84
+ This will permanently delete the selected row and immediately refetch the current
85
+ page.
93
86
  </p>
94
87
 
95
88
  {error ? (
@@ -74,10 +74,7 @@ const stringifyDraftValue = (value: unknown, kind: EditableValueKind) => {
74
74
  return String(value);
75
75
  };
76
76
 
77
- const createFieldDraft = (
78
- column: SqliteColumnInfo,
79
- value: unknown,
80
- ): EditableFieldDraft => {
77
+ const createFieldDraft = (column: SqliteColumnInfo, value: unknown): EditableFieldDraft => {
81
78
  const compatibleKinds = getCompatibleValueKinds(column, value);
82
79
  const kind = compatibleKinds[0] ?? 'text';
83
80
 
@@ -104,10 +101,7 @@ export const SqliteRowEditModal = ({
104
101
  }
105
102
  },
106
103
  });
107
- const primaryKeyColumns = useMemo(
108
- () => getPrimaryKeyColumns(columns),
109
- [columns],
110
- );
104
+ const primaryKeyColumns = useMemo(() => getPrimaryKeyColumns(columns), [columns]);
111
105
  const editableColumns = useMemo(() => getEditableColumns(columns), [columns]);
112
106
  const [drafts, setDrafts] = useState<Record<string, EditableFieldDraft>>({});
113
107
  const [submitting, setSubmitting] = useState(false);
@@ -123,10 +117,7 @@ export const SqliteRowEditModal = ({
123
117
 
124
118
  setDrafts(
125
119
  Object.fromEntries(
126
- editableColumns.map((column) => [
127
- column.name,
128
- createFieldDraft(column, row[column.name]),
129
- ]),
120
+ editableColumns.map((column) => [column.name, createFieldDraft(column, row[column.name])]),
130
121
  ),
131
122
  );
132
123
  setSubmitting(false);
@@ -134,9 +125,7 @@ export const SqliteRowEditModal = ({
134
125
  }, [editableColumns, isOpen, row]);
135
126
 
136
127
  const handleKindChange = (columnName: string, kind: EditableValueKind) => {
137
- const column = editableColumns.find(
138
- (candidate) => candidate.name === columnName,
139
- );
128
+ const column = editableColumns.find((candidate) => candidate.name === columnName);
140
129
 
141
130
  setDrafts((current) => ({
142
131
  ...current,
@@ -151,16 +140,12 @@ export const SqliteRowEditModal = ({
151
140
  ? '{}'
152
141
  : kind === 'null'
153
142
  ? ''
154
- : kind === 'number' &&
155
- current[columnName]?.rawValue === 'true'
143
+ : kind === 'number' && current[columnName]?.rawValue === 'true'
156
144
  ? '1'
157
- : kind === 'number' &&
158
- current[columnName]?.rawValue === 'false'
145
+ : kind === 'number' && current[columnName]?.rawValue === 'false'
159
146
  ? '0'
160
147
  : (current[columnName]?.rawValue ??
161
- (column
162
- ? createFieldDraft(column, null).rawValue
163
- : '')),
148
+ (column ? createFieldDraft(column, null).rawValue : '')),
164
149
  },
165
150
  }));
166
151
  };
@@ -186,9 +171,7 @@ export const SqliteRowEditModal = ({
186
171
  await onSave(nextValues);
187
172
  onClose();
188
173
  } catch (nextError) {
189
- setError(
190
- nextError instanceof Error ? nextError.message : String(nextError),
191
- );
174
+ setError(nextError instanceof Error ? nextError.message : String(nextError));
192
175
  } finally {
193
176
  setSubmitting(false);
194
177
  }
@@ -210,9 +193,7 @@ export const SqliteRowEditModal = ({
210
193
  <div>
211
194
  <div className="flex items-center gap-2">
212
195
  <Pencil aria-hidden="true" className="h-4 w-4 text-sky-300" />
213
- <h2 className="text-lg font-semibold text-white">
214
- Edit Row {rowNumber}
215
- </h2>
196
+ <h2 className="text-lg font-semibold text-white">Edit Row {rowNumber}</h2>
216
197
  </div>
217
198
  <p className="mt-1 text-sm text-slate-400">{entityName}</p>
218
199
  </div>
@@ -224,12 +205,9 @@ export const SqliteRowEditModal = ({
224
205
  {primaryKeyColumns.length > 0 ? (
225
206
  <section className="space-y-3">
226
207
  <div>
227
- <h3 className="text-sm font-medium text-slate-200">
228
- Row Identifier
229
- </h3>
208
+ <h3 className="text-sm font-medium text-slate-200">Row Identifier</h3>
230
209
  <p className="mt-1 text-xs text-slate-400">
231
- Primary-key fields are shown for reference and cannot be
232
- edited.
210
+ Primary-key fields are shown for reference and cannot be edited.
233
211
  </p>
234
212
  </div>
235
213
  <div className="grid gap-3 md:grid-cols-2">
@@ -240,16 +218,12 @@ export const SqliteRowEditModal = ({
240
218
  >
241
219
  <div className="flex items-center justify-between gap-3">
242
220
  <div>
243
- <p className="text-sm font-medium text-white">
244
- {column.name}
245
- </p>
221
+ <p className="text-sm font-medium text-white">{column.name}</p>
246
222
  <p className="text-xs uppercase tracking-[0.24em] text-slate-500">
247
223
  {column.type || 'value'}
248
224
  </p>
249
225
  </div>
250
- <span className="sqlite-chip sqlite-chip-static">
251
- PK
252
- </span>
226
+ <span className="sqlite-chip sqlite-chip-static">PK</span>
253
227
  </div>
254
228
  <p className="mt-3 break-all font-mono text-sm text-slate-200">
255
229
  {getValuePreview(row?.[column.name])}
@@ -265,36 +239,27 @@ export const SqliteRowEditModal = ({
265
239
 
266
240
  <section className="space-y-3">
267
241
  <div>
268
- <h3 className="text-sm font-medium text-slate-200">
269
- Editable Values
270
- </h3>
242
+ <h3 className="text-sm font-medium text-slate-200">Editable Values</h3>
271
243
  <p className="mt-1 text-xs text-slate-400">
272
- Update any non-primary-key column and save to write the
273
- row back to SQLite.
244
+ Update any non-primary-key column and save to write the row back to SQLite.
274
245
  </p>
275
246
  </div>
276
247
 
277
248
  {editableColumns.length === 0 ? (
278
249
  <div className="rounded-2xl border border-white/8 bg-white/[0.03] p-4 text-sm text-slate-300">
279
- This row does not expose editable, non-primary-key
280
- columns.
250
+ This row does not expose editable, non-primary-key columns.
281
251
  </div>
282
252
  ) : (
283
253
  <div className="space-y-4">
284
254
  {editableColumns.map((column) => {
285
255
  const draft =
286
- drafts[column.name] ??
287
- createFieldDraft(column, row?.[column.name]);
288
- const compatibleKinds = getCompatibleValueKinds(
289
- column,
290
- row?.[column.name],
291
- );
256
+ drafts[column.name] ?? createFieldDraft(column, row?.[column.name]);
257
+ const compatibleKinds = getCompatibleValueKinds(column, row?.[column.name]);
292
258
  const allowNull = canColumnBeNull(column);
293
259
  const shouldUseTextArea =
294
260
  draft.kind === 'blob-ish' ||
295
261
  draft.kind === 'json' ||
296
- (draft.kind === 'text' &&
297
- draft.rawValue.includes('\n'));
262
+ (draft.kind === 'text' && draft.rawValue.includes('\n'));
298
263
 
299
264
  return (
300
265
  <div
@@ -347,9 +312,7 @@ export const SqliteRowEditModal = ({
347
312
  : 'Text'}
348
313
  </option>
349
314
  ))}
350
- {allowNull ? (
351
- <option value="null">NULL</option>
352
- ) : null}
315
+ {allowNull ? <option value="null">NULL</option> : null}
353
316
  </select>
354
317
  </div>
355
318
  ) : (
@@ -428,16 +391,11 @@ export const SqliteRowEditModal = ({
428
391
  </div>
429
392
 
430
393
  <p className="mt-2 text-xs text-slate-500">
431
- Current value:{' '}
432
- {getValuePreview(row?.[column.name])} (
394
+ Current value: {getValuePreview(row?.[column.name])} (
433
395
  {getValueKind(row?.[column.name])}) · Compatible:{' '}
434
396
  {compatibleKinds
435
397
  .map((kind) =>
436
- kind === 'blob-ish'
437
- ? 'blob'
438
- : kind === 'json'
439
- ? 'json'
440
- : kind,
398
+ kind === 'blob-ish' ? 'blob' : kind === 'json' ? 'json' : kind,
441
399
  )
442
400
  .join(', ')}
443
401
  {allowNull ? ', null' : ''}
@@ -1,10 +1,4 @@
1
- export type EditableValueKind =
2
- | 'null'
3
- | 'text'
4
- | 'number'
5
- | 'boolean'
6
- | 'blob-ish'
7
- | 'json';
1
+ export type EditableValueKind = 'null' | 'text' | 'number' | 'boolean' | 'blob-ish' | 'json';
8
2
 
9
3
  export type EditableFieldDraft = {
10
4
  kind: EditableValueKind;
@@ -36,10 +30,7 @@ export const parseEditableFieldValue = (draft: EditableFieldDraft): unknown => {
36
30
  case 'blob-ish': {
37
31
  const parsed = JSON.parse(draft.rawValue);
38
32
 
39
- if (
40
- !Array.isArray(parsed) ||
41
- !parsed.every((item) => typeof item === 'number')
42
- ) {
33
+ if (!Array.isArray(parsed) || !parsed.every((item) => typeof item === 'number')) {
43
34
  throw new Error('Blob values must be JSON arrays of numbers.');
44
35
  }
45
36
 
@@ -9,12 +9,7 @@ const SQLITE_ROWID_IDENTIFIERS = ['rowid', '_rowid_', 'oid'] as const;
9
9
 
10
10
  export type SqliteRowIdIdentifier = (typeof SQLITE_ROWID_IDENTIFIERS)[number];
11
11
 
12
- export type SqliteEditableValueKind =
13
- | 'text'
14
- | 'number'
15
- | 'boolean'
16
- | 'blob-ish'
17
- | 'json';
12
+ export type SqliteEditableValueKind = 'text' | 'number' | 'boolean' | 'blob-ish' | 'json';
18
13
 
19
14
  export type SqliteRowMutationDescriptor =
20
15
  | {
@@ -57,16 +52,11 @@ export const getPrimaryKeyColumns = (columns: SqliteColumnInfo[]) =>
57
52
  .sort((left, right) => left.primaryKeyOrder - right.primaryKeyOrder);
58
53
 
59
54
  export const getEditableColumns = (columns: SqliteColumnInfo[]) =>
60
- columns.filter(
61
- (column) => column.primaryKeyOrder === 0 && column.hidden === 0,
62
- );
55
+ columns.filter((column) => column.primaryKeyOrder === 0 && column.hidden === 0);
63
56
 
64
- const getNormalizedColumnType = (column: SqliteColumnInfo) =>
65
- column.type.trim().toLowerCase();
57
+ const getNormalizedColumnType = (column: SqliteColumnInfo) => column.type.trim().toLowerCase();
66
58
 
67
- const inferValueKindFromRuntimeValue = (
68
- value: unknown,
69
- ): SqliteEditableValueKind => {
59
+ const inferValueKindFromRuntimeValue = (value: unknown): SqliteEditableValueKind => {
70
60
  if (typeof value === 'number') {
71
61
  return 'number';
72
62
  }
@@ -76,9 +66,7 @@ const inferValueKindFromRuntimeValue = (
76
66
  }
77
67
 
78
68
  if (Array.isArray(value)) {
79
- return value.every((item) => typeof item === 'number')
80
- ? 'blob-ish'
81
- : 'json';
69
+ return value.every((item) => typeof item === 'number') ? 'blob-ish' : 'json';
82
70
  }
83
71
 
84
72
  if (value && typeof value === 'object') {
@@ -135,14 +123,10 @@ export const canColumnBeNull = (column: SqliteColumnInfo) => !column.notNull;
135
123
  export const getAvailableRowIdIdentifier = (
136
124
  columns: SqliteColumnInfo[],
137
125
  ): SqliteRowIdIdentifier | null => {
138
- const lowerCaseColumnNames = new Set(
139
- columns.map((column) => column.name.toLowerCase()),
140
- );
126
+ const lowerCaseColumnNames = new Set(columns.map((column) => column.name.toLowerCase()));
141
127
 
142
128
  return (
143
- SQLITE_ROWID_IDENTIFIERS.find(
144
- (identifier) => !lowerCaseColumnNames.has(identifier),
145
- ) ?? null
129
+ SQLITE_ROWID_IDENTIFIERS.find((identifier) => !lowerCaseColumnNames.has(identifier)) ?? null
146
130
  );
147
131
  };
148
132
 
@@ -182,9 +166,7 @@ const buildWhereClause = (
182
166
  descriptor: SqliteRowMutationDescriptor,
183
167
  ) => {
184
168
  if (descriptor.mode === 'primary-key') {
185
- const params = descriptor.primaryKeyColumns.map(
186
- (column) => row[column.name],
187
- );
169
+ const params = descriptor.primaryKeyColumns.map((column) => row[column.name]);
188
170
  const clause = descriptor.primaryKeyColumns
189
171
  .map((column) => `${quoteSqlIdentifier(column.name)} = ?`)
190
172
  .join(' AND ');
@@ -210,9 +192,7 @@ export const buildRowUpdateMutation = ({
210
192
  }: BuildRowUpdateMutationInput): SqliteMutationResult => {
211
193
  const updateColumnNames = getEditableColumns(columns)
212
194
  .map((column) => column.name)
213
- .filter((columnName) =>
214
- Object.prototype.hasOwnProperty.call(nextValues, columnName),
215
- );
195
+ .filter((columnName) => Object.prototype.hasOwnProperty.call(nextValues, columnName));
216
196
 
217
197
  if (updateColumnNames.length === 0) {
218
198
  throw new Error('No editable columns are available for this row.');
@@ -221,9 +201,7 @@ export const buildRowUpdateMutation = ({
221
201
  const assignments = updateColumnNames.map(
222
202
  (columnName) => `${quoteSqlIdentifier(columnName)} = ?`,
223
203
  );
224
- const assignmentParams = updateColumnNames.map(
225
- (columnName) => nextValues[columnName],
226
- );
204
+ const assignmentParams = updateColumnNames.map((columnName) => nextValues[columnName]);
227
205
  const where = buildWhereClause(row, descriptor);
228
206
 
229
207
  return {
@@ -17,13 +17,8 @@ type ReorderTableColumnOrderInput = NormalizeTableColumnOrderInput & {
17
17
  overColumnId: string;
18
18
  };
19
19
 
20
- const applyUpdater = <TValue>(
21
- updater: Updater<TValue>,
22
- currentValue: TValue,
23
- ): TValue =>
24
- typeof updater === 'function'
25
- ? (updater as (old: TValue) => TValue)(currentValue)
26
- : updater;
20
+ const applyUpdater = <TValue>(updater: Updater<TValue>, currentValue: TValue): TValue =>
21
+ typeof updater === 'function' ? (updater as (old: TValue) => TValue)(currentValue) : updater;
27
22
 
28
23
  export const getDefaultTableColumnOrder = (
29
24
  columnIds: string[],
@@ -95,9 +90,7 @@ export const reorderTableColumnOrder = ({
95
90
  return normalizedOrder;
96
91
  }
97
92
 
98
- const movableColumnOrder = normalizedOrder.filter(
99
- (columnId) => !fixedColumnIds.has(columnId),
100
- );
93
+ const movableColumnOrder = normalizedOrder.filter((columnId) => !fixedColumnIds.has(columnId));
101
94
  const activeIndex = movableColumnOrder.indexOf(activeColumnId);
102
95
  const overIndex = movableColumnOrder.indexOf(overColumnId);
103
96
 
@@ -131,24 +124,16 @@ export const resolveTableColumnOrderUpdate = ({
131
124
  });
132
125
  };
133
126
 
134
- export const areColumnOrdersEqual = (
135
- leftColumnOrder: string[],
136
- rightColumnOrder: string[],
137
- ) =>
127
+ export const areColumnOrdersEqual = (leftColumnOrder: string[], rightColumnOrder: string[]) =>
138
128
  leftColumnOrder.length === rightColumnOrder.length &&
139
- leftColumnOrder.every(
140
- (columnId, columnIndex) => columnId === rightColumnOrder[columnIndex],
141
- );
129
+ leftColumnOrder.every((columnId, columnIndex) => columnId === rightColumnOrder[columnIndex]);
142
130
 
143
131
  export const buildEntityTableId = (
144
132
  scope: 'data' | 'structure-columns' | 'structure-indexes',
145
133
  databaseId: string | null,
146
134
  schemaName: string | null,
147
135
  entityName: string | null,
148
- ) =>
149
- `${scope}:${databaseId ?? 'unknown'}:${schemaName ?? 'unknown'}:${entityName ?? 'unknown'}`;
136
+ ) => `${scope}:${databaseId ?? 'unknown'}:${schemaName ?? 'unknown'}:${entityName ?? 'unknown'}`;
150
137
 
151
- export const buildQueryTableId = (
152
- databaseId: string | null,
153
- columnIds: string[],
154
- ) => `query:${databaseId ?? 'unknown'}:${JSON.stringify(columnIds)}`;
138
+ export const buildQueryTableId = (databaseId: string | null, columnIds: string[]) =>
139
+ `query:${databaseId ?? 'unknown'}:${JSON.stringify(columnIds)}`;