@dockstat/sqlite-wrapper 1.1.3 → 1.2.1

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.
package/package.json CHANGED
@@ -1,30 +1,18 @@
1
1
  {
2
2
  "name": "@dockstat/sqlite-wrapper",
3
- "version": "1.1.3",
3
+ "version": "1.2.1",
4
4
  "description": "A TypeScript wrapper around bun:sqlite with type-safe query building",
5
5
  "type": "module",
6
- "main": "./dist/index.js",
7
- "types": "./dist/index.d.ts",
8
- "exports": {
9
- ".": {
10
- "types": "./dist/index.d.ts",
11
- "import": "./dist/index.js",
12
- "default": "./dist/index.js"
13
- }
14
- },
15
- "files": [
16
- "dist/**/*",
17
- "README.md"
18
- ],
6
+ "main": "./index.ts",
7
+ "types": "./index.ts",
8
+ "files": ["index.ts", "src/**/*", "README.md", "types.ts"],
19
9
  "scripts": {
20
- "build": "bun run ./build.ts",
21
10
  "dev": "bun build index.ts",
22
11
  "lint": "biome lint .",
23
12
  "lint:fix": "biome lint --write .",
13
+ "lint:gh": "turbo run lint -- --reporter=github",
24
14
  "check-types": "bunx tsc --noEmit",
25
- "test": "bun run test.ts",
26
- "clean": "rm -rf dist",
27
- "prepublishOnly": "npm run clean && npm run build"
15
+ "test": "bun run test.ts"
28
16
  },
29
17
  "keywords": [
30
18
  "sqlite",
@@ -48,6 +36,9 @@
48
36
  "engines": {
49
37
  "bun": ">=1.0.0"
50
38
  },
39
+ "dependencies": {
40
+ "@dockstat/logger": "^1.0.0"
41
+ },
51
42
  "peerDependencies": {
52
43
  "typescript": "^5"
53
44
  },
package/types.ts ADDED
@@ -0,0 +1,620 @@
1
+ // Enhanced types.ts with comprehensive SQLite support
2
+ import type { Database, SQLQueryBindings } from "bun:sqlite";
3
+
4
+ /**
5
+ * All SQLite data types including affinity types
6
+ */
7
+ export const SQLiteTypes = {
8
+ // Standard SQLite types
9
+ INTEGER: "INTEGER" as const,
10
+ TEXT: "TEXT" as const,
11
+ REAL: "REAL" as const,
12
+ BLOB: "BLOB" as const,
13
+ NUMERIC: "NUMERIC" as const,
14
+
15
+ // Common type aliases and variations
16
+ INT: "INT" as const,
17
+ TINYINT: "TINYINT" as const,
18
+ SMALLINT: "SMALLINT" as const,
19
+ MEDIUMINT: "MEDIUMINT" as const,
20
+ BIGINT: "BIGINT" as const,
21
+
22
+ // Text variations
23
+ VARCHAR: "VARCHAR" as const,
24
+ CHAR: "CHAR" as const,
25
+ CHARACTER: "CHARACTER" as const,
26
+ NCHAR: "NCHAR" as const,
27
+ NVARCHAR: "NVARCHAR" as const,
28
+ CLOB: "CLOB" as const,
29
+
30
+ // Numeric variations
31
+ DOUBLE: "DOUBLE" as const,
32
+ FLOAT: "FLOAT" as const,
33
+ DECIMAL: "DECIMAL" as const,
34
+
35
+ // Date/Time (stored as TEXT, INTEGER, or REAL)
36
+ DATE: "DATE" as const,
37
+ DATETIME: "DATETIME" as const,
38
+ TIMESTAMP: "TIMESTAMP" as const,
39
+ TIME: "TIME" as const,
40
+
41
+ // Boolean (stored as INTEGER)
42
+ BOOLEAN: "BOOLEAN" as const,
43
+
44
+ // JSON (stored as TEXT)
45
+ JSON: "JSON" as const,
46
+ } as const;
47
+
48
+ export type SQLiteType = (typeof SQLiteTypes)[keyof typeof SQLiteTypes];
49
+
50
+ /**
51
+ * SQLite built-in scalar functions
52
+ */
53
+ export const SQLiteFunctions = {
54
+ // Date/Time functions
55
+ DATE: (expr: string) => `DATE(${expr})`,
56
+ TIME: (expr: string) => `TIME(${expr})`,
57
+ DATETIME: (expr: string) => `DATETIME(${expr})`,
58
+ JULIANDAY: (expr: string) => `JULIANDAY(${expr})`,
59
+ STRFTIME: (format: string, expr: string) => `STRFTIME('${format}', ${expr})`,
60
+
61
+ // String functions
62
+ LENGTH: (expr: string) => `LENGTH(${expr})`,
63
+ LOWER: (expr: string) => `LOWER(${expr})`,
64
+ UPPER: (expr: string) => `UPPER(${expr})`,
65
+ TRIM: (expr: string, chars?: string) =>
66
+ chars ? `TRIM(${expr}, '${chars}')` : `TRIM(${expr})`,
67
+ LTRIM: (expr: string, chars?: string) =>
68
+ chars ? `LTRIM(${expr}, '${chars}')` : `LTRIM(${expr})`,
69
+ RTRIM: (expr: string, chars?: string) =>
70
+ chars ? `RTRIM(${expr}, '${chars}')` : `RTRIM(${expr})`,
71
+ SUBSTR: (expr: string, start: number, length?: number) =>
72
+ length
73
+ ? `SUBSTR(${expr}, ${start}, ${length})`
74
+ : `SUBSTR(${expr}, ${start})`,
75
+ SUBSTRING: (expr: string, start: number, length?: number) =>
76
+ length
77
+ ? `SUBSTRING(${expr}, ${start}, ${length})`
78
+ : `SUBSTRING(${expr}, ${start})`,
79
+ REPLACE: (expr: string, old: string, replacement: string) =>
80
+ `REPLACE(${expr}, '${old}', '${replacement}')`,
81
+ PRINTF: (format: string, ...args: string[]) =>
82
+ `PRINTF('${format}', ${args.join(", ")})`,
83
+
84
+ // Math functions
85
+ ABS: (expr: string) => `ABS(${expr})`,
86
+ ROUND: (expr: string, digits?: number) =>
87
+ digits !== undefined ? `ROUND(${expr}, ${digits})` : `ROUND(${expr})`,
88
+ RANDOM: () => "RANDOM()",
89
+ MIN: (...exprs: string[]) => `MIN(${exprs.join(", ")})`,
90
+ MAX: (...exprs: string[]) => `MAX(${exprs.join(", ")})`,
91
+
92
+ // Type conversion
93
+ CAST: (expr: string, type: string) => `CAST(${expr} AS ${type})`,
94
+ TYPEOF: (expr: string) => `TYPEOF(${expr})`,
95
+
96
+ // Conditional
97
+ COALESCE: (...exprs: string[]) => `COALESCE(${exprs.join(", ")})`,
98
+ IFNULL: (expr: string, replacement: string) =>
99
+ `IFNULL(${expr}, ${replacement})`,
100
+ NULLIF: (expr1: string, expr2: string) => `NULLIF(${expr1}, ${expr2})`,
101
+ IIF: (condition: string, trueValue: string, falseValue: string) =>
102
+ `IIF(${condition}, ${trueValue}, ${falseValue})`,
103
+
104
+ // Aggregate functions (for use in expressions)
105
+ COUNT: (expr?: string) => (expr ? `COUNT(${expr})` : "COUNT(*)"),
106
+ SUM: (expr: string) => `SUM(${expr})`,
107
+ AVG: (expr: string) => `AVG(${expr})`,
108
+ TOTAL: (expr: string) => `TOTAL(${expr})`,
109
+ GROUP_CONCAT: (expr: string, separator?: string) =>
110
+ separator
111
+ ? `GROUP_CONCAT(${expr}, '${separator}')`
112
+ : `GROUP_CONCAT(${expr})`,
113
+
114
+ // JSON functions (SQLite 3.45+)
115
+ JSON: (expr: string) => `JSON(${expr})`,
116
+ JSON_EXTRACT: (json: string, path: string) =>
117
+ `JSON_EXTRACT(${json}, '${path}')`,
118
+ JSON_TYPE: (json: string, path?: string) =>
119
+ path ? `JSON_TYPE(${json}, '${path}')` : `JSON_TYPE(${json})`,
120
+ JSON_VALID: (expr: string) => `JSON_VALID(${expr})`,
121
+ JSON_ARRAY: (...values: string[]) => `JSON_ARRAY(${values.join(", ")})`,
122
+ JSON_OBJECT: (...pairs: string[]) => `JSON_OBJECT(${pairs.join(", ")})`,
123
+ } as const;
124
+
125
+ /**
126
+ * SQLite keywords and special values
127
+ */
128
+ export const SQLiteKeywords = {
129
+ // Special values
130
+ NULL: "NULL" as const,
131
+ CURRENT_TIME: "CURRENT_TIME" as const,
132
+ CURRENT_DATE: "CURRENT_DATE" as const,
133
+ CURRENT_TIMESTAMP: "CURRENT_TIMESTAMP" as const,
134
+
135
+ // Boolean values (as integers)
136
+ TRUE: "1" as const,
137
+ FALSE: "0" as const,
138
+
139
+ // Conflict resolution
140
+ ROLLBACK: "ROLLBACK" as const,
141
+ ABORT: "ABORT" as const,
142
+ FAIL: "FAIL" as const,
143
+ IGNORE: "IGNORE" as const,
144
+ REPLACE: "REPLACE" as const,
145
+ } as const;
146
+
147
+ /**
148
+ * Foreign key actions
149
+ */
150
+ export type ForeignKeyAction =
151
+ | "CASCADE"
152
+ | "SET NULL"
153
+ | "RESTRICT"
154
+ | "NO ACTION"
155
+ | "SET DEFAULT";
156
+
157
+ /**
158
+ * Column constraint options with comprehensive support
159
+ */
160
+ export interface ColumnConstraints {
161
+ /** Column is PRIMARY KEY */
162
+ primaryKey?: boolean;
163
+ /** Column has AUTOINCREMENT (only valid with INTEGER PRIMARY KEY) */
164
+ autoincrement?: boolean;
165
+ /** Column is NOT NULL */
166
+ notNull?: boolean;
167
+ /** Column has UNIQUE constraint */
168
+ unique?: boolean;
169
+ /** Default value - can be literal value, function call, or keyword */
170
+ default?: string | number | boolean | null | DefaultExpression;
171
+ /** Custom check constraint */
172
+ check?: string;
173
+ /** Collation sequence */
174
+ collate?: "BINARY" | "NOCASE" | "RTRIM" | string;
175
+ /** References another table (foreign key) */
176
+ references?: {
177
+ table: string;
178
+ column: string;
179
+ onDelete?: ForeignKeyAction;
180
+ onUpdate?: ForeignKeyAction;
181
+ };
182
+ /** Generated column expression (GENERATED ALWAYS AS) */
183
+ generated?: {
184
+ expression: string;
185
+ stored?: boolean; // true for STORED, false/undefined for VIRTUAL
186
+ };
187
+ /** Column comment (stored as metadata, not in schema) */
188
+ comment?: string;
189
+ }
190
+
191
+ /**
192
+ * Type-safe default value expressions
193
+ */
194
+ export type DefaultExpression = {
195
+ _type: "expression";
196
+ expression: string;
197
+ };
198
+
199
+ /**
200
+ * Helper to create default expressions
201
+ */
202
+ export const defaultExpr = (expression: string): DefaultExpression => ({
203
+ _type: "expression",
204
+ expression,
205
+ });
206
+
207
+ /**
208
+ * Type-safe column definition
209
+ */
210
+ export interface ColumnDefinition extends ColumnConstraints {
211
+ /** SQLite data type */
212
+ type: SQLiteType;
213
+ /** Optional type parameters (e.g., VARCHAR(255)) */
214
+ length?: number;
215
+ /** Precision for DECIMAL/NUMERIC types */
216
+ precision?: number;
217
+ /** Scale for DECIMAL/NUMERIC types */
218
+ scale?: number;
219
+ }
220
+
221
+ /**
222
+ * Type-safe table schema definition
223
+ */
224
+ export type TableSchema = Record<string, ColumnDefinition>;
225
+
226
+ /**
227
+ * Table constraint types
228
+ */
229
+ export interface TableConstraints {
230
+ /** PRIMARY KEY constraint on multiple columns */
231
+ primaryKey?: string[];
232
+ /** UNIQUE constraints */
233
+ unique?: string[] | string[][];
234
+ /** CHECK constraints */
235
+ check?: string[];
236
+ /** FOREIGN KEY constraints */
237
+ foreignKeys?: Array<{
238
+ columns: string[];
239
+ references: {
240
+ table: string;
241
+ columns: string[];
242
+ onDelete?: ForeignKeyAction;
243
+ onUpdate?: ForeignKeyAction;
244
+ };
245
+ }>;
246
+ }
247
+
248
+ /**
249
+ * Enhanced table options
250
+ */
251
+ export interface TableOptions {
252
+ /** Add IF NOT EXISTS clause */
253
+ ifNotExists?: boolean;
254
+ /** Create WITHOUT ROWID table */
255
+ withoutRowId?: boolean;
256
+ /** Table constraints */
257
+ constraints?: TableConstraints;
258
+ /** Temporary table */
259
+ temporary?: boolean;
260
+ /** Table comment */
261
+ comment?: string;
262
+ }
263
+
264
+ /**
265
+ * Comprehensive column helper functions with full type support
266
+ */
267
+ export const column = {
268
+ /**
269
+ * Create an INTEGER column with optional size specification
270
+ */
271
+ integer: (
272
+ constraints?: ColumnConstraints & {
273
+ size?: "TINYINT" | "SMALLINT" | "MEDIUMINT" | "BIGINT";
274
+ },
275
+ ): ColumnDefinition => ({
276
+ type: constraints?.size || SQLiteTypes.INTEGER,
277
+ ...constraints,
278
+ }),
279
+
280
+ /**
281
+ * Create a TEXT column with optional length
282
+ */
283
+ text: (
284
+ constraints?: ColumnConstraints & {
285
+ length?: number;
286
+ variant?: "VARCHAR" | "CHAR" | "CLOB" | "NCHAR" | "NVARCHAR";
287
+ },
288
+ ): ColumnDefinition => ({
289
+ type: constraints?.variant || SQLiteTypes.TEXT,
290
+ length: constraints?.length,
291
+ ...constraints,
292
+ }),
293
+
294
+ /**
295
+ * Create a REAL column
296
+ */
297
+ real: (
298
+ constraints?: ColumnConstraints & { variant?: "DOUBLE" | "FLOAT" },
299
+ ): ColumnDefinition => ({
300
+ type: constraints?.variant || SQLiteTypes.REAL,
301
+ ...constraints,
302
+ }),
303
+
304
+ /**
305
+ * Create a BLOB column
306
+ */
307
+ blob: (constraints?: ColumnConstraints): ColumnDefinition => ({
308
+ type: SQLiteTypes.BLOB,
309
+ ...constraints,
310
+ }),
311
+
312
+ /**
313
+ * Create a NUMERIC/DECIMAL column with precision and scale
314
+ */
315
+ numeric: (
316
+ constraints?: ColumnConstraints & {
317
+ precision?: number;
318
+ scale?: number;
319
+ variant?: "DECIMAL";
320
+ },
321
+ ): ColumnDefinition => ({
322
+ type: constraints?.variant || SQLiteTypes.NUMERIC,
323
+ precision: constraints?.precision,
324
+ scale: constraints?.scale,
325
+ ...constraints,
326
+ }),
327
+
328
+ /**
329
+ * Create a DATE column (stored as TEXT)
330
+ */
331
+ date: (constraints?: ColumnConstraints): ColumnDefinition => ({
332
+ type: SQLiteTypes.DATE,
333
+ ...constraints,
334
+ }),
335
+
336
+ /**
337
+ * Create a DATETIME column (stored as TEXT)
338
+ */
339
+ datetime: (constraints?: ColumnConstraints): ColumnDefinition => ({
340
+ type: SQLiteTypes.DATETIME,
341
+ ...constraints,
342
+ }),
343
+
344
+ /**
345
+ * Create a TIMESTAMP column (stored as INTEGER by default)
346
+ */
347
+ timestamp: (
348
+ constraints?: ColumnConstraints & { asText?: boolean },
349
+ ): ColumnDefinition => ({
350
+ type: constraints?.asText ? SQLiteTypes.TEXT : SQLiteTypes.INTEGER,
351
+ ...constraints,
352
+ }),
353
+
354
+ /**
355
+ * Create a TIME column (stored as TEXT)
356
+ */
357
+ time: (constraints?: ColumnConstraints): ColumnDefinition => ({
358
+ type: SQLiteTypes.TIME,
359
+ ...constraints,
360
+ }),
361
+
362
+ /**
363
+ * Create a BOOLEAN column (stored as INTEGER)
364
+ */
365
+ boolean: (constraints?: ColumnConstraints): ColumnDefinition => ({
366
+ type: SQLiteTypes.BOOLEAN,
367
+ check: constraints?.check || "{{COLUMN}} IN (0, 1)", // Placeholder for column name
368
+ ...constraints,
369
+ }),
370
+
371
+ /**
372
+ * Create a JSON column (stored as TEXT)
373
+ */
374
+ json: (
375
+ constraints?: ColumnConstraints & { validateJson?: boolean },
376
+ ): ColumnDefinition => ({
377
+ type: SQLiteTypes.JSON,
378
+ check: constraints?.validateJson
379
+ ? "JSON_VALID({{COLUMN}})"
380
+ : constraints?.check,
381
+ ...constraints,
382
+ }),
383
+
384
+ /**
385
+ * Create a VARCHAR column with specified length
386
+ */
387
+ varchar: (
388
+ length: number,
389
+ constraints?: ColumnConstraints,
390
+ ): ColumnDefinition => ({
391
+ type: SQLiteTypes.VARCHAR,
392
+ length,
393
+ ...constraints,
394
+ }),
395
+
396
+ /**
397
+ * Create a CHAR column with specified length
398
+ */
399
+ char: (
400
+ length: number,
401
+ constraints?: ColumnConstraints,
402
+ ): ColumnDefinition => ({
403
+ type: SQLiteTypes.CHAR,
404
+ length,
405
+ ...constraints,
406
+ }),
407
+
408
+ /**
409
+ * Create an auto-incrementing primary key column
410
+ */
411
+ id: (
412
+ constraints?: Omit<
413
+ ColumnConstraints,
414
+ "primaryKey" | "autoincrement" | "notNull"
415
+ >,
416
+ ): ColumnDefinition => ({
417
+ type: SQLiteTypes.INTEGER,
418
+ primaryKey: true,
419
+ autoincrement: true,
420
+ notNull: true,
421
+ ...constraints,
422
+ }),
423
+
424
+ /**
425
+ * Create a UUID column (stored as TEXT)
426
+ */
427
+ uuid: (
428
+ constraints?: ColumnConstraints & { generateDefault?: boolean },
429
+ ): ColumnDefinition => ({
430
+ type: SQLiteTypes.TEXT,
431
+ length: 36,
432
+ default: constraints?.generateDefault
433
+ ? defaultExpr(
434
+ "lower(hex(randomblob(4))) || '-' || lower(hex(randomblob(2))) || '-4' || substr(lower(hex(randomblob(2))),2) || '-' || substr('89ab',abs(random()) % 4 + 1, 1) || substr(lower(hex(randomblob(2))),2) || '-' || lower(hex(randomblob(6)))",
435
+ )
436
+ : constraints?.default,
437
+ ...constraints,
438
+ }),
439
+
440
+ /**
441
+ * Create a created_at timestamp column
442
+ */
443
+ createdAt: (
444
+ constraints?: Omit<ColumnConstraints, "default" | "notNull"> & {
445
+ asText?: boolean;
446
+ },
447
+ ): ColumnDefinition => ({
448
+ type: constraints?.asText ? SQLiteTypes.DATETIME : SQLiteTypes.INTEGER,
449
+ notNull: true,
450
+ default: constraints?.asText
451
+ ? defaultExpr("datetime('now')")
452
+ : defaultExpr("strftime('%s', 'now')"),
453
+ ...constraints,
454
+ }),
455
+
456
+ /**
457
+ * Create an updated_at timestamp column
458
+ */
459
+ updatedAt: (
460
+ constraints?: Omit<ColumnConstraints, "default"> & { asText?: boolean },
461
+ ): ColumnDefinition => ({
462
+ type: constraints?.asText ? SQLiteTypes.DATETIME : SQLiteTypes.INTEGER,
463
+ default: constraints?.asText
464
+ ? defaultExpr("datetime('now')")
465
+ : defaultExpr("strftime('%s', 'now')"),
466
+ ...constraints,
467
+ }),
468
+
469
+ /**
470
+ * Create a foreign key reference column
471
+ */
472
+ foreignKey: (
473
+ refTable: string,
474
+ refColumn = "id",
475
+ constraints?: ColumnConstraints & {
476
+ onDelete?: ForeignKeyAction;
477
+ onUpdate?: ForeignKeyAction;
478
+ type?: SQLiteType;
479
+ },
480
+ ): ColumnDefinition => ({
481
+ type: constraints?.type || SQLiteTypes.INTEGER,
482
+ references: {
483
+ table: refTable,
484
+ column: refColumn,
485
+ onDelete: constraints?.onDelete,
486
+ onUpdate: constraints?.onUpdate,
487
+ },
488
+ ...constraints,
489
+ }),
490
+
491
+ /**
492
+ * Create an enum column (with CHECK constraint)
493
+ */
494
+ enum: (
495
+ values: string[],
496
+ constraints?: ColumnConstraints,
497
+ ): ColumnDefinition => ({
498
+ type: SQLiteTypes.TEXT,
499
+ check: `{{COLUMN}} IN (${values.map((v) => `'${v}'`).join(", ")})`,
500
+ ...constraints,
501
+ }),
502
+ };
503
+
504
+ /**
505
+ * SQL function helpers for use in defaults and expressions
506
+ */
507
+ export const sql = {
508
+ // Current date/time
509
+ now: () => defaultExpr("datetime('now')"),
510
+ currentTime: () => defaultExpr("time('now')"),
511
+ currentDate: () => defaultExpr("date('now')"),
512
+ currentTimestamp: () => defaultExpr("datetime('now')"),
513
+ unixTimestamp: () => defaultExpr("strftime('%s', 'now')"),
514
+
515
+ // Functions
516
+ ...SQLiteFunctions,
517
+
518
+ // Raw expression
519
+ raw: (expression: string) => defaultExpr(expression),
520
+
521
+ // Literals
522
+ null: () => null,
523
+ true: () => 1,
524
+ false: () => 0,
525
+ };
526
+
527
+ /**
528
+ * Enhanced createTable method signature
529
+ */
530
+ export type CreateTableColumns = string | Record<string, string> | TableSchema;
531
+
532
+ /**
533
+ * Query builder state interface
534
+ */
535
+ export interface QueryBuilderState<T extends Record<string, unknown>> {
536
+ db: Database; // Database instance from bun:sqlite
537
+ tableName: string;
538
+ whereConditions: string[];
539
+ whereParams: SQLQueryBindings[];
540
+ regexConditions: Array<{
541
+ column: keyof T;
542
+ regex: RegExp;
543
+ }>;
544
+ jsonColumns?: Array<keyof T>;
545
+ }
546
+
547
+ /**
548
+ * Column names type for SELECT operations
549
+ */
550
+ export type ColumnNames<T> = ["*"] | Array<keyof T>;
551
+
552
+ /**
553
+ * Order direction for ORDER BY clauses
554
+ */
555
+ export type OrderDirection = "ASC" | "DESC";
556
+
557
+ /**
558
+ * WHERE condition object type
559
+ */
560
+ export type WhereCondition<T> = Partial<T>;
561
+
562
+ /**
563
+ * Regex condition object type
564
+ */
565
+ export type RegexCondition<T> = Partial<Record<keyof T, RegExp | string>>;
566
+
567
+ /**
568
+ * Insert result interface
569
+ */
570
+ export interface InsertResult {
571
+ insertId: number;
572
+ changes: number;
573
+ }
574
+
575
+ /**
576
+ * Update result interface
577
+ */
578
+ export interface UpdateResult {
579
+ changes: number;
580
+ }
581
+
582
+ /**
583
+ * Delete result interface
584
+ */
585
+ export interface DeleteResult {
586
+ changes: number;
587
+ }
588
+
589
+ /**
590
+ * Insert options interface
591
+ */
592
+ export interface InsertOptions {
593
+ orIgnore?: boolean;
594
+ orReplace?: boolean;
595
+ orAbort?: boolean;
596
+ orFail?: boolean;
597
+ orRollback?: boolean;
598
+ }
599
+
600
+ /**
601
+ * JSON column configuration
602
+ */
603
+ export interface JsonColumnConfig<T> {
604
+ jsonColumns?: Array<keyof T>;
605
+ }
606
+
607
+ /**
608
+ * Generic database row type
609
+ */
610
+ export type DatabaseRow = Record<string, unknown>;
611
+
612
+ /**
613
+ * SQL parameter type
614
+ */
615
+ export type SqlParameter = SQLQueryBindings;
616
+
617
+ /**
618
+ * Database row with unknown structure
619
+ */
620
+ export type DatabaseRowData = Record<string, SQLQueryBindings>;