local-lite 0.0.4 → 0.0.5
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/dist/adapters/remote/supabase.d.ts +2 -2
- package/dist/config/types.d.ts +1 -1
- package/dist/core/client.d.ts +52 -7
- package/dist/core/client.js +125 -122
- package/dist/core/index.d.ts +1 -0
- package/dist/core/index.js +1 -0
- package/dist/core/query-builder.d.ts +119 -0
- package/dist/core/query-builder.js +372 -0
- package/dist/core/schema-manager.js +51 -16
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/react/SyncInspector.js +0 -70
- package/dist/react/index.d.ts +39 -0
- package/dist/react/index.js +189 -4
- package/dist/schema/generator.d.ts +49 -0
- package/dist/schema/generator.js +209 -0
- package/dist/schema/index.d.ts +1 -0
- package/dist/schema/index.js +17 -0
- package/package.json +7 -2
|
@@ -15,8 +15,8 @@ export interface SupabaseAdapterOptions {
|
|
|
15
15
|
updatedAtColumn?: string;
|
|
16
16
|
/**
|
|
17
17
|
* Optional subset of tables to which dynamic `syncScope` filters should apply.
|
|
18
|
-
* If provided, scope filters (like `
|
|
19
|
-
* Tables not in this list (e.g.
|
|
18
|
+
* If provided, scope filters (like `tenant_id` or `org_id`) will only be attached to queries for these tables.
|
|
19
|
+
* Tables not in this list (e.g. global tables, user profiles) will be fetched without the scope filter.
|
|
20
20
|
*/
|
|
21
21
|
scopedTables?: string[];
|
|
22
22
|
/**
|
package/dist/config/types.d.ts
CHANGED
|
@@ -178,7 +178,7 @@ export interface LocalLiteConfig {
|
|
|
178
178
|
*/
|
|
179
179
|
autoHydrateJSON?: boolean;
|
|
180
180
|
/**
|
|
181
|
-
* Scoped synchronization filter (e.g. {
|
|
181
|
+
* Scoped synchronization filter (e.g. { org_id: '...' } or dynamic resolver callback).
|
|
182
182
|
*/
|
|
183
183
|
syncScope?: Record<string, any> | (() => Record<string, any> | Promise<Record<string, any>>);
|
|
184
184
|
}
|
package/dist/core/client.d.ts
CHANGED
|
@@ -2,9 +2,10 @@ import { LocalDBAdapter, LocalTransaction } from '../adapters/local/index.js';
|
|
|
2
2
|
import { RemoteDBAdapter } from '../adapters/remote/index.js';
|
|
3
3
|
import { EventEmitter } from '../reactive/event-emitter.js';
|
|
4
4
|
import { SyncWorker } from './sync-worker.js';
|
|
5
|
-
import { SchemaManager
|
|
6
|
-
import { BatchMutation, ConflictResolver, ConflictStrategy, MutateOptions, NetworkStatusProvider, OutboxRecord, OutboxStatus, QueryOptions, RetryConfig, SyncMetrics, SyncOp, TableChangeEvent } from './types.js';
|
|
5
|
+
import { SchemaManager } from './schema-manager.js';
|
|
6
|
+
import { BatchMutation, ConflictResolver, ConflictStrategy, MutateOptions, NetworkStatusProvider, OutboxRecord, OutboxStatus, QueryOptions, RetryConfig, SyncMetrics, SyncOp, TableChangeEvent, WhereFilter } from './types.js';
|
|
7
7
|
import { SyncLogger, CustomLogger, LogLevel } from '../utils/logger.js';
|
|
8
|
+
import { QueryBuilder, AggregateSpec, AggregateResult } from './query-builder.js';
|
|
8
9
|
export interface LocalFirstClientConfig {
|
|
9
10
|
local: LocalDBAdapter;
|
|
10
11
|
remote: RemoteDBAdapter;
|
|
@@ -51,6 +52,8 @@ export declare class TransactionalClient {
|
|
|
51
52
|
includeDeleted?: boolean;
|
|
52
53
|
}): Promise<T[]>;
|
|
53
54
|
findMany<T = any>(tableName: string, options?: QueryOptions): Promise<T[]>;
|
|
55
|
+
query<T = any>(sql: string, params?: any[]): Promise<T[]>;
|
|
56
|
+
from<T = any>(tableName: string): QueryBuilder<T>;
|
|
54
57
|
get rawTx(): LocalTransaction;
|
|
55
58
|
}
|
|
56
59
|
export declare class LocalFirstClient {
|
|
@@ -149,15 +152,57 @@ export declare class LocalFirstClient {
|
|
|
149
152
|
* Pushes simple equality where clauses down to SQLite for high performance, with memory fallback.
|
|
150
153
|
* Gracefully returns [] if table or columns have not been populated yet on empty schemas.
|
|
151
154
|
*
|
|
155
|
+
/**
|
|
156
|
+
* Executes a raw relational SQL query with parameters directly against SQLite.
|
|
157
|
+
* Enables complex multi-table JOINs, GROUP BY aggregations (COUNT, SUM, AVG), CTEs, and window functions.
|
|
158
|
+
*/
|
|
159
|
+
query<T = any>(sql: string, params?: any[]): Promise<T[]>;
|
|
160
|
+
/**
|
|
161
|
+
* Returns a fluent SQL QueryBuilder for the specified table.
|
|
162
|
+
* Allows writing clean JavaScript method chains (select, join, leftJoin, where, orderBy, groupBy)
|
|
163
|
+
* that automatically compile into optimized native SQLite queries.
|
|
164
|
+
*
|
|
152
165
|
* Example:
|
|
153
|
-
* const
|
|
154
|
-
*
|
|
166
|
+
* const activeRentals = await client
|
|
167
|
+
* .from('contracts')
|
|
168
|
+
* .join('houses', 'contracts.house_id', 'houses.id')
|
|
169
|
+
* .leftJoin('tenants', 'contracts.tenant_id', 'tenants.id')
|
|
170
|
+
* .where({ 'contracts.business_id': bizId, 'contracts.status': 'ACTIVE' })
|
|
171
|
+
* .select('contracts.id', 'contracts.rent_amount', 'houses.house_number', 'tenants.name')
|
|
172
|
+
* .execute();
|
|
155
173
|
*/
|
|
156
|
-
|
|
174
|
+
from<T = any>(tableName: string): QueryBuilder<T>;
|
|
175
|
+
/**
|
|
176
|
+
* Executes a native SQLite COUNT(*) query and returns the count directly.
|
|
177
|
+
*/
|
|
178
|
+
count(tableName: string, options?: {
|
|
179
|
+
where?: WhereFilter;
|
|
180
|
+
}): Promise<number>;
|
|
157
181
|
/**
|
|
158
|
-
*
|
|
182
|
+
* Executes a native SQLite SUM(column) query and returns the sum directly.
|
|
159
183
|
*/
|
|
160
|
-
|
|
184
|
+
sum(tableName: string, column: string, options?: {
|
|
185
|
+
where?: WhereFilter;
|
|
186
|
+
}): Promise<number>;
|
|
187
|
+
/**
|
|
188
|
+
* Executes a native SQLite AVG(column) query and returns the average directly.
|
|
189
|
+
*/
|
|
190
|
+
avg(tableName: string, column: string, options?: {
|
|
191
|
+
where?: WhereFilter;
|
|
192
|
+
}): Promise<number | null>;
|
|
193
|
+
/**
|
|
194
|
+
* Executes native multi-metric SQLite aggregation in a single query.
|
|
195
|
+
*
|
|
196
|
+
* Example:
|
|
197
|
+
* const stats = await client.aggregate('receipts', {
|
|
198
|
+
* where: { business_id: bizId },
|
|
199
|
+
* count: true,
|
|
200
|
+
* sum: ['amount', 'refunded_amount'],
|
|
201
|
+
* avg: ['amount']
|
|
202
|
+
* });
|
|
203
|
+
*/
|
|
204
|
+
aggregate(tableName: string, spec: AggregateSpec): Promise<AggregateResult>;
|
|
205
|
+
findMany<T = any>(tableName: string, options?: QueryOptions): Promise<T[]>;
|
|
161
206
|
/**
|
|
162
207
|
* Finds a single record by primary key.
|
|
163
208
|
*
|
package/dist/core/client.js
CHANGED
|
@@ -10,6 +10,7 @@ const schema_manager_js_1 = require("./schema-manager.js");
|
|
|
10
10
|
const uuid_js_1 = require("../utils/uuid.js");
|
|
11
11
|
const sql_js_1 = require("../utils/sql.js");
|
|
12
12
|
const query_js_1 = require("./query.js");
|
|
13
|
+
const query_builder_js_1 = require("./query-builder.js");
|
|
13
14
|
class TransactionalClient {
|
|
14
15
|
parent;
|
|
15
16
|
tx;
|
|
@@ -110,7 +111,14 @@ class TransactionalClient {
|
|
|
110
111
|
}
|
|
111
112
|
}
|
|
112
113
|
async findMany(tableName, options) {
|
|
113
|
-
|
|
114
|
+
const rows = await this.from(tableName).applyOptions(options).execute();
|
|
115
|
+
return (0, query_js_1.applyQueryOptions)(rows, options);
|
|
116
|
+
}
|
|
117
|
+
async query(sql, params = []) {
|
|
118
|
+
return (await this.tx.execute(sql, params));
|
|
119
|
+
}
|
|
120
|
+
from(tableName) {
|
|
121
|
+
return new query_builder_js_1.QueryBuilder(this, tableName);
|
|
114
122
|
}
|
|
115
123
|
get rawTx() {
|
|
116
124
|
return this.tx;
|
|
@@ -492,142 +500,137 @@ class LocalFirstClient {
|
|
|
492
500
|
* Pushes simple equality where clauses down to SQLite for high performance, with memory fallback.
|
|
493
501
|
* Gracefully returns [] if table or columns have not been populated yet on empty schemas.
|
|
494
502
|
*
|
|
503
|
+
/**
|
|
504
|
+
* Executes a raw relational SQL query with parameters directly against SQLite.
|
|
505
|
+
* Enables complex multi-table JOINs, GROUP BY aggregations (COUNT, SUM, AVG), CTEs, and window functions.
|
|
506
|
+
*/
|
|
507
|
+
async query(sql, params = []) {
|
|
508
|
+
return (await this.db.execute(sql, params));
|
|
509
|
+
}
|
|
510
|
+
/**
|
|
511
|
+
* Returns a fluent SQL QueryBuilder for the specified table.
|
|
512
|
+
* Allows writing clean JavaScript method chains (select, join, leftJoin, where, orderBy, groupBy)
|
|
513
|
+
* that automatically compile into optimized native SQLite queries.
|
|
514
|
+
*
|
|
495
515
|
* Example:
|
|
496
|
-
* const
|
|
497
|
-
*
|
|
516
|
+
* const activeRentals = await client
|
|
517
|
+
* .from('contracts')
|
|
518
|
+
* .join('houses', 'contracts.house_id', 'houses.id')
|
|
519
|
+
* .leftJoin('tenants', 'contracts.tenant_id', 'tenants.id')
|
|
520
|
+
* .where({ 'contracts.business_id': bizId, 'contracts.status': 'ACTIVE' })
|
|
521
|
+
* .select('contracts.id', 'contracts.rent_amount', 'houses.house_number', 'tenants.name')
|
|
522
|
+
* .execute();
|
|
498
523
|
*/
|
|
499
|
-
|
|
500
|
-
return
|
|
524
|
+
from(tableName) {
|
|
525
|
+
return new query_builder_js_1.QueryBuilder(this, tableName);
|
|
501
526
|
}
|
|
502
527
|
/**
|
|
503
|
-
*
|
|
528
|
+
* Executes a native SQLite COUNT(*) query and returns the count directly.
|
|
504
529
|
*/
|
|
505
|
-
async
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
if (ops.$gt !== undefined) {
|
|
549
|
-
whereClauses.push(`${safeCol} > ?`);
|
|
550
|
-
params.push(ops.$gt);
|
|
551
|
-
}
|
|
552
|
-
if (ops.$gte !== undefined) {
|
|
553
|
-
whereClauses.push(`${safeCol} >= ?`);
|
|
554
|
-
params.push(ops.$gte);
|
|
555
|
-
}
|
|
556
|
-
if (ops.$lt !== undefined) {
|
|
557
|
-
whereClauses.push(`${safeCol} < ?`);
|
|
558
|
-
params.push(ops.$lt);
|
|
559
|
-
}
|
|
560
|
-
if (ops.$lte !== undefined) {
|
|
561
|
-
whereClauses.push(`${safeCol} <= ?`);
|
|
562
|
-
params.push(ops.$lte);
|
|
563
|
-
}
|
|
564
|
-
if (Array.isArray(ops.$in) && ops.$in.length > 0) {
|
|
565
|
-
const placeholders = ops.$in.map(() => '?').join(', ');
|
|
566
|
-
whereClauses.push(`${safeCol} IN (${placeholders})`);
|
|
567
|
-
params.push(...ops.$in.map((v) => (typeof v === 'boolean' ? (v ? 1 : 0) : v)));
|
|
568
|
-
}
|
|
569
|
-
if (Array.isArray(ops.$nin) && ops.$nin.length > 0) {
|
|
570
|
-
const placeholders = ops.$nin.map(() => '?').join(', ');
|
|
571
|
-
whereClauses.push(`${safeCol} NOT IN (${placeholders})`);
|
|
572
|
-
params.push(...ops.$nin.map((v) => (typeof v === 'boolean' ? (v ? 1 : 0) : v)));
|
|
573
|
-
}
|
|
574
|
-
if (ops.$null !== undefined) {
|
|
575
|
-
whereClauses.push(ops.$null ? `${safeCol} IS NULL` : `${safeCol} IS NOT NULL`);
|
|
576
|
-
}
|
|
577
|
-
if (ops.$contains !== undefined) {
|
|
578
|
-
whereClauses.push(`${safeCol} LIKE ?`);
|
|
579
|
-
params.push(`%${ops.$contains}%`);
|
|
580
|
-
}
|
|
581
|
-
if (ops.$startsWith !== undefined) {
|
|
582
|
-
whereClauses.push(`${safeCol} LIKE ?`);
|
|
583
|
-
params.push(`${ops.$startsWith}%`);
|
|
584
|
-
}
|
|
585
|
-
if (ops.$endsWith !== undefined) {
|
|
586
|
-
whereClauses.push(`${safeCol} LIKE ?`);
|
|
587
|
-
params.push(`%${ops.$endsWith}`);
|
|
588
|
-
}
|
|
589
|
-
}
|
|
530
|
+
async count(tableName, options) {
|
|
531
|
+
const qb = this.from(tableName);
|
|
532
|
+
if (options?.where)
|
|
533
|
+
qb.where(options.where);
|
|
534
|
+
return qb.count();
|
|
535
|
+
}
|
|
536
|
+
/**
|
|
537
|
+
* Executes a native SQLite SUM(column) query and returns the sum directly.
|
|
538
|
+
*/
|
|
539
|
+
async sum(tableName, column, options) {
|
|
540
|
+
const qb = this.from(tableName);
|
|
541
|
+
if (options?.where)
|
|
542
|
+
qb.where(options.where);
|
|
543
|
+
return qb.sum(column);
|
|
544
|
+
}
|
|
545
|
+
/**
|
|
546
|
+
* Executes a native SQLite AVG(column) query and returns the average directly.
|
|
547
|
+
*/
|
|
548
|
+
async avg(tableName, column, options) {
|
|
549
|
+
const qb = this.from(tableName);
|
|
550
|
+
if (options?.where)
|
|
551
|
+
qb.where(options.where);
|
|
552
|
+
return qb.avg(column);
|
|
553
|
+
}
|
|
554
|
+
/**
|
|
555
|
+
* Executes native multi-metric SQLite aggregation in a single query.
|
|
556
|
+
*
|
|
557
|
+
* Example:
|
|
558
|
+
* const stats = await client.aggregate('receipts', {
|
|
559
|
+
* where: { business_id: bizId },
|
|
560
|
+
* count: true,
|
|
561
|
+
* sum: ['amount', 'refunded_amount'],
|
|
562
|
+
* avg: ['amount']
|
|
563
|
+
* });
|
|
564
|
+
*/
|
|
565
|
+
async aggregate(tableName, spec) {
|
|
566
|
+
const projections = [];
|
|
567
|
+
if (spec.count) {
|
|
568
|
+
projections.push('COUNT(*) AS "_count"');
|
|
569
|
+
}
|
|
570
|
+
if (spec.sum) {
|
|
571
|
+
for (const col of spec.sum) {
|
|
572
|
+
projections.push(`COALESCE(SUM("${col.replace(/"/g, '""')}"), 0) AS "sum_${col}"`);
|
|
590
573
|
}
|
|
591
|
-
|
|
592
|
-
|
|
574
|
+
}
|
|
575
|
+
if (spec.avg) {
|
|
576
|
+
for (const col of spec.avg) {
|
|
577
|
+
projections.push(`AVG("${col.replace(/"/g, '""')}") AS "avg_${col}"`);
|
|
593
578
|
}
|
|
594
579
|
}
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
const dir = options.order && String(options.order).toLowerCase() === 'desc' ? 'DESC' : 'ASC';
|
|
599
|
-
sql += ` ORDER BY ${safeCol} ${dir}`;
|
|
600
|
-
}
|
|
601
|
-
// Push down LIMIT & OFFSET
|
|
602
|
-
if (typeof options?.limit === 'number' && options.limit > 0) {
|
|
603
|
-
sql += ` LIMIT ?`;
|
|
604
|
-
params.push(options.limit);
|
|
605
|
-
if (typeof options.offset === 'number' && options.offset > 0) {
|
|
606
|
-
sql += ` OFFSET ?`;
|
|
607
|
-
params.push(options.offset);
|
|
580
|
+
if (spec.min) {
|
|
581
|
+
for (const col of spec.min) {
|
|
582
|
+
projections.push(`MIN("${col.replace(/"/g, '""')}") AS "min_${col}"`);
|
|
608
583
|
}
|
|
609
584
|
}
|
|
610
|
-
|
|
611
|
-
|
|
585
|
+
if (spec.max) {
|
|
586
|
+
for (const col of spec.max) {
|
|
587
|
+
projections.push(`MAX("${col.replace(/"/g, '""')}") AS "max_${col}"`);
|
|
588
|
+
}
|
|
612
589
|
}
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
590
|
+
if (projections.length === 0) {
|
|
591
|
+
return {};
|
|
592
|
+
}
|
|
593
|
+
const qb = this.from(tableName).select(...projections);
|
|
594
|
+
if (spec.where) {
|
|
595
|
+
qb.where(spec.where);
|
|
596
|
+
}
|
|
597
|
+
const rows = await qb.execute();
|
|
598
|
+
const row = rows[0] || {};
|
|
599
|
+
const result = {};
|
|
600
|
+
if (spec.count) {
|
|
601
|
+
result.count = typeof row._count === 'number' ? row._count : Number(row._count) || 0;
|
|
602
|
+
}
|
|
603
|
+
if (spec.sum) {
|
|
604
|
+
result.sum = {};
|
|
605
|
+
for (const col of spec.sum) {
|
|
606
|
+
const val = row[`sum_${col}`];
|
|
607
|
+
result.sum[col] = typeof val === 'number' ? val : Number(val) || 0;
|
|
617
608
|
}
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
609
|
+
}
|
|
610
|
+
if (spec.avg) {
|
|
611
|
+
result.avg = {};
|
|
612
|
+
for (const col of spec.avg) {
|
|
613
|
+
const val = row[`avg_${col}`];
|
|
614
|
+
result.avg[col] = val === null || val === undefined ? null : Number(val) || 0;
|
|
621
615
|
}
|
|
622
|
-
|
|
623
|
-
|
|
616
|
+
}
|
|
617
|
+
if (spec.min) {
|
|
618
|
+
result.min = {};
|
|
619
|
+
for (const col of spec.min) {
|
|
620
|
+
result.min[col] = row[`min_${col}`];
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
if (spec.max) {
|
|
624
|
+
result.max = {};
|
|
625
|
+
for (const col of spec.max) {
|
|
626
|
+
result.max[col] = row[`max_${col}`];
|
|
624
627
|
}
|
|
625
628
|
}
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
return (0, query_js_1.applyQueryOptions)(
|
|
629
|
+
return result;
|
|
630
|
+
}
|
|
631
|
+
async findMany(tableName, options) {
|
|
632
|
+
const rows = await this.from(tableName).applyOptions(options).execute();
|
|
633
|
+
return (0, query_js_1.applyQueryOptions)(rows, options);
|
|
631
634
|
}
|
|
632
635
|
/**
|
|
633
636
|
* Finds a single record by primary key.
|
package/dist/core/index.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ export * from './outbox-store.js';
|
|
|
7
7
|
export * from './meta-store.js';
|
|
8
8
|
export * from './table-manager.js';
|
|
9
9
|
export * from './schema-manager.js';
|
|
10
|
+
export * from './query-builder.js';
|
|
10
11
|
export * from '../reactive/event-emitter.js';
|
|
11
12
|
export * from '../adapters/network/index.js';
|
|
12
13
|
export type { LocalDBAdapter, LocalTransaction } from '../adapters/local/index.js';
|
package/dist/core/index.js
CHANGED
|
@@ -24,6 +24,7 @@ __exportStar(require("./outbox-store.js"), exports);
|
|
|
24
24
|
__exportStar(require("./meta-store.js"), exports);
|
|
25
25
|
__exportStar(require("./table-manager.js"), exports);
|
|
26
26
|
__exportStar(require("./schema-manager.js"), exports);
|
|
27
|
+
__exportStar(require("./query-builder.js"), exports);
|
|
27
28
|
__exportStar(require("../reactive/event-emitter.js"), exports);
|
|
28
29
|
__exportStar(require("../adapters/network/index.js"), exports);
|
|
29
30
|
__exportStar(require("../utils/logger.js"), exports);
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { LocalFirstClient, TransactionalClient } from './client.js';
|
|
2
|
+
import { QueryOptions, WhereFilter } from './types.js';
|
|
3
|
+
type ClientLike = LocalFirstClient | TransactionalClient;
|
|
4
|
+
/**
|
|
5
|
+
* Escapes an identifier or compound identifier (e.g. 'table.column' or 'table.col as alias').
|
|
6
|
+
*/
|
|
7
|
+
export declare function formatColumnIdentifier(col: string): string;
|
|
8
|
+
export interface JoinDefinition {
|
|
9
|
+
type: 'INNER' | 'LEFT' | 'CROSS';
|
|
10
|
+
table: string;
|
|
11
|
+
firstCol: string;
|
|
12
|
+
secondCol: string;
|
|
13
|
+
}
|
|
14
|
+
export interface AggregateSpec {
|
|
15
|
+
where?: WhereFilter;
|
|
16
|
+
count?: boolean;
|
|
17
|
+
sum?: string[];
|
|
18
|
+
avg?: string[];
|
|
19
|
+
min?: string[];
|
|
20
|
+
max?: string[];
|
|
21
|
+
}
|
|
22
|
+
export interface AggregateResult {
|
|
23
|
+
count?: number;
|
|
24
|
+
sum?: Record<string, number>;
|
|
25
|
+
avg?: Record<string, number | null>;
|
|
26
|
+
min?: Record<string, any>;
|
|
27
|
+
max?: Record<string, any>;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Fluent, type-safe SQL Query Builder for local-first SQLite operations.
|
|
31
|
+
* Allows writing expressive JavaScript code that compiles and executes high-performance SQL under the hood.
|
|
32
|
+
*/
|
|
33
|
+
export declare class QueryBuilder<T = any> {
|
|
34
|
+
private client;
|
|
35
|
+
private tableName;
|
|
36
|
+
private selectCols;
|
|
37
|
+
private joins;
|
|
38
|
+
private whereConditions;
|
|
39
|
+
private orderColumn?;
|
|
40
|
+
private orderDirection;
|
|
41
|
+
private limitCount?;
|
|
42
|
+
private offsetCount?;
|
|
43
|
+
private groupByCols;
|
|
44
|
+
private includeDeleted;
|
|
45
|
+
constructor(client: ClientLike, tableName: string);
|
|
46
|
+
/**
|
|
47
|
+
* Specifies which columns to select.
|
|
48
|
+
* Supports column aliases (e.g. ['id', 'contracts.rent_amount AS rent', 'houses.house_number']).
|
|
49
|
+
*/
|
|
50
|
+
select(...columns: Array<string | string[]>): this;
|
|
51
|
+
/**
|
|
52
|
+
* Inner joins another SQLite table on a matching column expression.
|
|
53
|
+
*/
|
|
54
|
+
join(table: string, firstCol: string, secondCol: string): this;
|
|
55
|
+
/**
|
|
56
|
+
* Left joins another SQLite table on a matching column expression.
|
|
57
|
+
*/
|
|
58
|
+
leftJoin(table: string, firstCol: string, secondCol: string): this;
|
|
59
|
+
/**
|
|
60
|
+
* Adds WHERE criteria to filter results.
|
|
61
|
+
* Supports:
|
|
62
|
+
* - where({ status: 'ACTIVE' })
|
|
63
|
+
* - where('status', 'ACTIVE')
|
|
64
|
+
* - where('end_date', '>=', today)
|
|
65
|
+
*/
|
|
66
|
+
where(columnOrFilter: string | WhereFilter, operatorOrValue?: any, value?: any): this;
|
|
67
|
+
/**
|
|
68
|
+
* Orders query results by column and direction.
|
|
69
|
+
*/
|
|
70
|
+
orderBy(column: string, direction?: 'asc' | 'desc' | 'ASC' | 'DESC'): this;
|
|
71
|
+
/**
|
|
72
|
+
* Groups rows by one or more columns for aggregation.
|
|
73
|
+
*/
|
|
74
|
+
groupBy(...columns: Array<string | string[]>): this;
|
|
75
|
+
/**
|
|
76
|
+
* Limits the number of returned records.
|
|
77
|
+
*/
|
|
78
|
+
limit(count: number): this;
|
|
79
|
+
/**
|
|
80
|
+
* Offsets the starting record position.
|
|
81
|
+
*/
|
|
82
|
+
offset(count: number): this;
|
|
83
|
+
/**
|
|
84
|
+
* Includes soft-deleted rows in results.
|
|
85
|
+
*/
|
|
86
|
+
withDeleted(include?: boolean): this;
|
|
87
|
+
/**
|
|
88
|
+
* Applies standard QueryOptions (select, where, orderBy, limit, offset, includeDeleted) to this query.
|
|
89
|
+
*/
|
|
90
|
+
applyOptions(options?: QueryOptions): this;
|
|
91
|
+
/**
|
|
92
|
+
* Compiles the current builder state into an executable SQL string and parameter list.
|
|
93
|
+
*/
|
|
94
|
+
toSQL(): {
|
|
95
|
+
sql: string;
|
|
96
|
+
params: any[];
|
|
97
|
+
};
|
|
98
|
+
/**
|
|
99
|
+
* Executes the compiled SQL query against SQLite and returns rows.
|
|
100
|
+
*/
|
|
101
|
+
execute(): Promise<T[]>;
|
|
102
|
+
/**
|
|
103
|
+
* Returns the first matching record or null if not found.
|
|
104
|
+
*/
|
|
105
|
+
first(): Promise<T | null>;
|
|
106
|
+
/**
|
|
107
|
+
* Executes a COUNT(*) in SQLite and returns the numeric count directly.
|
|
108
|
+
*/
|
|
109
|
+
count(): Promise<number>;
|
|
110
|
+
/**
|
|
111
|
+
* Executes a SUM(column) in SQLite and returns the numeric total directly.
|
|
112
|
+
*/
|
|
113
|
+
sum(column: string): Promise<number>;
|
|
114
|
+
/**
|
|
115
|
+
* Executes an AVG(column) in SQLite and returns the average directly.
|
|
116
|
+
*/
|
|
117
|
+
avg(column: string): Promise<number | null>;
|
|
118
|
+
}
|
|
119
|
+
export {};
|