@forgebase/sdk 0.0.1 → 0.0.3
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/README.md +88 -299
- package/dist/cjs/database/client/client.d.ts +50 -55
- package/dist/cjs/database/client/client.d.ts.map +1 -1
- package/dist/cjs/database/client/client.js +6 -56
- package/dist/cjs/database/client/client.js.map +1 -1
- package/dist/cjs/database/client/test_inference_comprehensive.d.ts +2 -0
- package/dist/cjs/database/client/test_inference_comprehensive.d.ts.map +1 -0
- package/dist/cjs/database/client/test_inference_comprehensive.js +91 -0
- package/dist/cjs/database/client/test_inference_comprehensive.js.map +1 -0
- package/dist/cjs/database/examples.d.ts +33 -9
- package/dist/cjs/database/examples.d.ts.map +1 -1
- package/dist/cjs/database/examples.js.map +1 -1
- package/dist/esm/database/client/client.d.ts +50 -55
- package/dist/esm/database/client/client.d.ts.map +1 -1
- package/dist/esm/database/client/client.js +6 -56
- package/dist/esm/database/client/client.js.map +1 -1
- package/dist/esm/database/client/test_inference_comprehensive.d.ts +2 -0
- package/dist/esm/database/client/test_inference_comprehensive.d.ts.map +1 -0
- package/dist/esm/database/client/test_inference_comprehensive.js +89 -0
- package/dist/esm/database/client/test_inference_comprehensive.js.map +1 -0
- package/dist/esm/database/examples.d.ts +33 -9
- package/dist/esm/database/examples.d.ts.map +1 -1
- package/dist/esm/database/examples.js.map +1 -1
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -1,64 +1,27 @@
|
|
|
1
1
|
# ForgeBase TypeScript SDK
|
|
2
2
|
|
|
3
|
-
A powerful, type-safe TypeScript SDK for interacting with ForgeBase services, providing comprehensive database operations,
|
|
3
|
+
A powerful, type-safe TypeScript SDK for interacting with ForgeBase services, providing comprehensive database operations, advanced query capabilities, and type safety.
|
|
4
4
|
|
|
5
5
|
## Core Features
|
|
6
6
|
|
|
7
7
|
- **Type-Safe Query Builder**:
|
|
8
8
|
- Fluent API design
|
|
9
|
-
- Advanced filtering
|
|
9
|
+
- Advanced filtering (`where`, `whereIn`, `whereExists`, etc.)
|
|
10
10
|
- Complex joins and relations
|
|
11
|
-
- Aggregations
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
-
|
|
11
|
+
- Aggregations (`count`, `sum`, `avg`, `min`, `max`)
|
|
12
|
+
- Window functions (`rowNumber`, `rank`, `lag`, `lead`)
|
|
13
|
+
- Recursive CTEs
|
|
14
|
+
- Result transformations (`pivot`, `compute`)
|
|
15
15
|
|
|
16
16
|
- **Database Operations**:
|
|
17
|
-
- CRUD operations
|
|
17
|
+
- CRUD operations (`create`, `update`, `delete`)
|
|
18
18
|
- Batch operations
|
|
19
|
-
- Pagination
|
|
20
|
-
- Sorting
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
-
|
|
24
|
-
|
|
25
|
-
- **Security Features**:
|
|
26
|
-
|
|
27
|
-
<!-- - JWKS support
|
|
28
|
-
- Token validation
|
|
29
|
-
- Request signing -->
|
|
30
|
-
- Input sanitization
|
|
31
|
-
- Type validation
|
|
32
|
-
- Error boundaries
|
|
33
|
-
<!-- - Rate limiting -->
|
|
34
|
-
|
|
35
|
-
- **Advanced Querying**:
|
|
36
|
-
- Window functions
|
|
37
|
-
- Common Table Expressions (CTEs)
|
|
38
|
-
- Recursive queries
|
|
39
|
-
- Complex filtering
|
|
40
|
-
- Advanced joins
|
|
41
|
-
- Subqueries
|
|
42
|
-
- Aggregations
|
|
43
|
-
|
|
44
|
-
<!-- - **Real-time Features**:
|
|
45
|
-
|
|
46
|
-
- Live queries
|
|
47
|
-
- Change notifications
|
|
48
|
-
- WebSocket integration
|
|
49
|
-
- Presence tracking
|
|
50
|
-
- Subscription management
|
|
51
|
-
- Connection handling
|
|
52
|
-
- Event buffering -->
|
|
53
|
-
|
|
54
|
-
<!-- - **Performance Features**:
|
|
55
|
-
- Query caching
|
|
56
|
-
- Connection pooling
|
|
57
|
-
- Batch operations
|
|
58
|
-
- Lazy loading
|
|
59
|
-
- Query optimization
|
|
60
|
-
- Result transformation
|
|
61
|
-
- Memory management -->
|
|
19
|
+
- Pagination (`limit`, `offset`)
|
|
20
|
+
- Sorting (`orderBy`)
|
|
21
|
+
|
|
22
|
+
- **Security & Validation**:
|
|
23
|
+
- Input validation
|
|
24
|
+
- Type inference from your interfaces
|
|
62
25
|
|
|
63
26
|
## Installation
|
|
64
27
|
|
|
@@ -72,35 +35,59 @@ pnpm add @forgebase/sdk
|
|
|
72
35
|
|
|
73
36
|
## Basic Usage
|
|
74
37
|
|
|
75
|
-
###
|
|
38
|
+
### Initialization
|
|
39
|
+
|
|
40
|
+
First, define your database schema and initialize the SDK. This provides automatic type safety across your entire application.
|
|
76
41
|
|
|
77
42
|
```typescript
|
|
78
43
|
import { DatabaseSDK } from '@forgebase/sdk/client';
|
|
79
44
|
|
|
80
|
-
//
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
45
|
+
// 1. Define your entity types
|
|
46
|
+
interface User {
|
|
47
|
+
id: number;
|
|
48
|
+
name: string;
|
|
49
|
+
email: string;
|
|
50
|
+
role: 'admin' | 'user';
|
|
51
|
+
status: 'active' | 'inactive';
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
interface Order {
|
|
55
|
+
id: number;
|
|
56
|
+
user_id: number;
|
|
57
|
+
amount: number;
|
|
58
|
+
status: 'pending' | 'completed';
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// 2. Define your Database Schema
|
|
62
|
+
interface Schema {
|
|
63
|
+
users: User;
|
|
64
|
+
orders: Order;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// 3. Initialize the SDK with your Schema
|
|
68
|
+
const db = new DatabaseSDK<Schema>({
|
|
69
|
+
baseUrl: 'http://localhost:3000',
|
|
70
|
+
axiosConfig: {
|
|
71
|
+
withCredentials: true,
|
|
72
|
+
headers: { 'Content-Type': 'application/json' },
|
|
85
73
|
},
|
|
86
74
|
});
|
|
75
|
+
```
|
|
87
76
|
|
|
88
|
-
|
|
89
|
-
const users = await db
|
|
90
|
-
.table('users')
|
|
91
|
-
.select('id', 'name', 'email')
|
|
92
|
-
.where('status', 'active')
|
|
93
|
-
.execute({
|
|
94
|
-
headers: {
|
|
95
|
-
'some-stuff': 'true',
|
|
96
|
-
},
|
|
97
|
-
});
|
|
77
|
+
### Database Operations
|
|
98
78
|
|
|
99
|
-
|
|
79
|
+
The SDK automatically infers types based on your Schema.
|
|
80
|
+
|
|
81
|
+
```typescript
|
|
82
|
+
// Query users (Type is inferred as User[])
|
|
83
|
+
const users = await db.table('users').select('id', 'name', 'email').where('status', 'active').query();
|
|
84
|
+
|
|
85
|
+
// Create a new record (Type checking ensures payload matches User)
|
|
100
86
|
const newUser = await db.table('users').create({
|
|
101
87
|
name: 'John Doe',
|
|
102
88
|
email: 'john@example.com',
|
|
103
89
|
role: 'user',
|
|
90
|
+
status: 'active',
|
|
104
91
|
});
|
|
105
92
|
|
|
106
93
|
// Update a record
|
|
@@ -115,74 +102,33 @@ await db.table('users').delete(1);
|
|
|
115
102
|
### Advanced Queries
|
|
116
103
|
|
|
117
104
|
```typescript
|
|
118
|
-
// Complex filtering
|
|
119
|
-
interface User {
|
|
120
|
-
id: number;
|
|
121
|
-
name: string;
|
|
122
|
-
email: string;
|
|
123
|
-
role: string;
|
|
124
|
-
department: string;
|
|
125
|
-
salary: number;
|
|
126
|
-
}
|
|
127
|
-
|
|
105
|
+
// Complex filtering
|
|
128
106
|
const results = await db
|
|
129
|
-
.table
|
|
107
|
+
.table('users') // Type inferred automatically
|
|
130
108
|
.where('status', 'active')
|
|
131
109
|
.andWhere((query) => {
|
|
132
|
-
query.where('role', '
|
|
110
|
+
query.where('role', 'admin').orWhere('email', 'like', '%@company.com');
|
|
133
111
|
})
|
|
134
112
|
.orderBy('name', 'asc')
|
|
135
113
|
.limit(10)
|
|
136
|
-
.
|
|
114
|
+
.query();
|
|
137
115
|
|
|
138
116
|
// Aggregations
|
|
139
|
-
const stats = await db.table
|
|
117
|
+
const stats = await db.table('orders').groupBy('status').sum('amount', 'total_amount').count('id', 'order_count').having('total_amount', '>', 5000).query();
|
|
118
|
+
|
|
119
|
+
// Result type is narrowed:
|
|
120
|
+
// stats.data -> { status: string, total_amount: number, order_count: number }[]
|
|
140
121
|
|
|
141
122
|
// Window Functions
|
|
142
123
|
const rankedUsers = await db
|
|
143
|
-
.table
|
|
124
|
+
.table('users')
|
|
144
125
|
.select('name', 'department', 'salary')
|
|
145
|
-
.
|
|
146
|
-
|
|
147
|
-
orderBy: [{ field: 'salary', direction: 'desc' }],
|
|
148
|
-
})
|
|
149
|
-
.execute();
|
|
150
|
-
|
|
151
|
-
// Advanced Window Functions
|
|
152
|
-
const analysis = await db
|
|
153
|
-
.table<User>('users')
|
|
154
|
-
.windowAdvanced('sum', 'running_total', {
|
|
155
|
-
field: 'salary',
|
|
156
|
-
over: {
|
|
157
|
-
partitionBy: ['department'],
|
|
158
|
-
orderBy: [{ field: 'hire_date', direction: 'asc' }],
|
|
159
|
-
frame: {
|
|
160
|
-
type: 'ROWS',
|
|
161
|
-
start: 'UNBOUNDED PRECEDING',
|
|
162
|
-
end: 'CURRENT ROW',
|
|
163
|
-
},
|
|
164
|
-
},
|
|
165
|
-
})
|
|
166
|
-
.execute();
|
|
167
|
-
```
|
|
168
|
-
|
|
169
|
-
### CTEs and Recursive Queries
|
|
170
|
-
|
|
171
|
-
```typescript
|
|
172
|
-
// Simple CTE
|
|
173
|
-
const highPaidUsers = db.table<User>('users').where('salary', '>', 100000);
|
|
174
|
-
|
|
175
|
-
const result = await db.table<User>('users').with('high_paid', highPaidUsers).execute();
|
|
176
|
-
|
|
177
|
-
// Recursive CTE
|
|
178
|
-
interface Category {
|
|
179
|
-
id: number;
|
|
180
|
-
parent_id: number | null;
|
|
181
|
-
name: string;
|
|
182
|
-
}
|
|
126
|
+
.rank('salary_rank', ['department'], [{ field: 'salary', direction: 'desc' }])
|
|
127
|
+
.query();
|
|
183
128
|
|
|
129
|
+
// Recursive CTEs (e.g., for hierarchical data)
|
|
184
130
|
const categories = await db
|
|
185
|
-
.table
|
|
131
|
+
.table('categories')
|
|
186
132
|
.withRecursive(
|
|
187
133
|
'category_tree',
|
|
188
134
|
// Initial query
|
|
@@ -191,199 +137,42 @@ const categories = await db
|
|
|
191
137
|
db.table('categories').join('category_tree', 'parent_id', 'id'),
|
|
192
138
|
{ unionAll: true },
|
|
193
139
|
)
|
|
194
|
-
.
|
|
140
|
+
.query();
|
|
195
141
|
```
|
|
196
142
|
|
|
197
|
-
|
|
143
|
+
### Transformations
|
|
198
144
|
|
|
199
|
-
|
|
200
|
-
// Subscribe to changes
|
|
201
|
-
const unsubscribe = await db
|
|
202
|
-
.table<User>('users')
|
|
203
|
-
.where('department', 'IT')
|
|
204
|
-
.subscribe({
|
|
205
|
-
onAdd: (user) => console.log('New user:', user),
|
|
206
|
-
onChange: (user) => console.log('User updated:', user),
|
|
207
|
-
onDelete: (id) => console.log('User deleted:', id),
|
|
208
|
-
});
|
|
209
|
-
|
|
210
|
-
// Later: cleanup subscription
|
|
211
|
-
unsubscribe();
|
|
212
|
-
``` -->
|
|
213
|
-
|
|
214
|
-
<!-- ### Security Features
|
|
145
|
+
You can transform the result set on the client side using `pivot` or `compute`.
|
|
215
146
|
|
|
216
147
|
```typescript
|
|
217
|
-
//
|
|
218
|
-
const
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
signRequests: true,
|
|
230
|
-
privateKey: 'your-private-key',
|
|
231
|
-
keyId: 'your-key-id',
|
|
232
|
-
},
|
|
233
|
-
});
|
|
234
|
-
|
|
235
|
-
// Rate Limiting
|
|
236
|
-
const db = new DatabaseSDK('http://localhost:3000', {
|
|
237
|
-
rateLimit: {
|
|
238
|
-
maxRequests: 100,
|
|
239
|
-
windowMs: 60000, // 1 minute
|
|
240
|
-
},
|
|
241
|
-
});
|
|
242
|
-
``` -->
|
|
148
|
+
// Pivot data
|
|
149
|
+
const pivoted = await db.table('sales').pivot('month', ['Jan', 'Feb', 'Mar'], { type: 'sum', field: 'amount' }).query();
|
|
150
|
+
|
|
151
|
+
// Compute new fields
|
|
152
|
+
const computed = await db
|
|
153
|
+
.table('employees')
|
|
154
|
+
.compute({
|
|
155
|
+
fullName: (row) => `${row.firstName} ${row.lastName}`,
|
|
156
|
+
tax: (row) => row.salary * 0.2,
|
|
157
|
+
})
|
|
158
|
+
.query();
|
|
159
|
+
```
|
|
243
160
|
|
|
244
161
|
## Error Handling
|
|
245
162
|
|
|
163
|
+
The SDK throws standard errors that you can catch and handle.
|
|
164
|
+
|
|
246
165
|
```typescript
|
|
247
166
|
try {
|
|
248
|
-
|
|
167
|
+
await db.table('users').create(data);
|
|
249
168
|
} catch (error) {
|
|
250
|
-
|
|
251
|
-
// Handle query-related errors
|
|
252
|
-
console.error('Query Error:', error.message);
|
|
253
|
-
} else if (error instanceof ValidationError) {
|
|
254
|
-
// Handle validation errors
|
|
255
|
-
console.error('Validation Error:', error.details);
|
|
256
|
-
} else if (error instanceof AuthorizationError) {
|
|
257
|
-
// Handle authorization errors
|
|
258
|
-
console.error('Authorization Error:', error.message);
|
|
259
|
-
} else {
|
|
260
|
-
// Handle other errors
|
|
261
|
-
console.error('Unknown Error:', error);
|
|
262
|
-
}
|
|
169
|
+
console.error('Failed to create user:', error.message);
|
|
263
170
|
}
|
|
264
171
|
```
|
|
265
172
|
|
|
266
|
-
|
|
267
|
-
## Advanced Configuration
|
|
268
|
-
|
|
269
|
-
```typescript
|
|
270
|
-
const db = new DatabaseSDK('http://localhost:3000', {
|
|
271
|
-
// Authentication
|
|
272
|
-
credentials: 'include',
|
|
273
|
-
headers: {
|
|
274
|
-
Authorization: 'Bearer your-token',
|
|
275
|
-
},
|
|
276
|
-
|
|
277
|
-
// Query Options
|
|
278
|
-
queryConfig: {
|
|
279
|
-
maxLimit: 1000,
|
|
280
|
-
defaultLimit: 50,
|
|
281
|
-
maxComplexity: 10,
|
|
282
|
-
},
|
|
283
|
-
|
|
284
|
-
// Cache Configuration
|
|
285
|
-
cache: {
|
|
286
|
-
enabled: true,
|
|
287
|
-
ttl: 300, // 5 minutes
|
|
288
|
-
maxSize: 100, // Maximum number of cached queries
|
|
289
|
-
},
|
|
290
|
-
|
|
291
|
-
// Real-time Configuration
|
|
292
|
-
realtime: {
|
|
293
|
-
enabled: true,
|
|
294
|
-
reconnectDelay: 1000,
|
|
295
|
-
maxRetries: 5,
|
|
296
|
-
},
|
|
297
|
-
|
|
298
|
-
// Performance Tuning
|
|
299
|
-
performance: {
|
|
300
|
-
batchSize: 1000,
|
|
301
|
-
poolSize: 10,
|
|
302
|
-
timeout: 5000,
|
|
303
|
-
},
|
|
304
|
-
});
|
|
305
|
-
``` -->
|
|
306
|
-
|
|
307
|
-
## Type Safety
|
|
308
|
-
|
|
309
|
-
The SDK provides full TypeScript support with generic types:
|
|
173
|
+
## Real-time Updates
|
|
310
174
|
|
|
311
|
-
|
|
312
|
-
interface User {
|
|
313
|
-
id: number;
|
|
314
|
-
name: string;
|
|
315
|
-
email: string;
|
|
316
|
-
role: string;
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
interface Order {
|
|
320
|
-
id: number;
|
|
321
|
-
userId: number;
|
|
322
|
-
total: number;
|
|
323
|
-
status: string;
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
// Type-safe queries
|
|
327
|
-
const users = await db.table<User>('users').select('id', 'name', 'email').where('role', 'admin').execute();
|
|
328
|
-
|
|
329
|
-
// Type-safe joins
|
|
330
|
-
const orders = await db.table<Order>('orders').join<User>('users', 'userId', 'id').select('orders.id', 'users.name', 'orders.total').execute();
|
|
331
|
-
```
|
|
332
|
-
|
|
333
|
-
## Performance Optimization
|
|
334
|
-
|
|
335
|
-
### Query Optimization
|
|
336
|
-
|
|
337
|
-
```typescript
|
|
338
|
-
// Use select to limit returned fields
|
|
339
|
-
const users = await db.table('users').select('id', 'name').where('active', true).execute();
|
|
340
|
-
|
|
341
|
-
// Use indexes effectively
|
|
342
|
-
const result = await db
|
|
343
|
-
.table('users')
|
|
344
|
-
.where('email', 'user@example.com') // Assuming email is indexed
|
|
345
|
-
.first()
|
|
346
|
-
.execute();
|
|
347
|
-
|
|
348
|
-
// Batch operations (WIP*)
|
|
349
|
-
await db.table('users').createMany([
|
|
350
|
-
{ name: 'User 1', email: 'user1@example.com' },
|
|
351
|
-
{ name: 'User 2', email: 'user2@example.com' },
|
|
352
|
-
]);
|
|
353
|
-
```
|
|
354
|
-
|
|
355
|
-
<!-- ### Caching
|
|
356
|
-
|
|
357
|
-
```typescript
|
|
358
|
-
// Enable caching for specific queries
|
|
359
|
-
const users = await db
|
|
360
|
-
.table('users')
|
|
361
|
-
.cache({
|
|
362
|
-
ttl: 300, // 5 minutes
|
|
363
|
-
tags: ['users'],
|
|
364
|
-
})
|
|
365
|
-
.execute();
|
|
366
|
-
|
|
367
|
-
// Invalidate cache
|
|
368
|
-
await db.invalidateCache('users');
|
|
369
|
-
``` -->
|
|
370
|
-
|
|
371
|
-
## Building
|
|
372
|
-
|
|
373
|
-
Run `nx build sdk` to build the library.
|
|
374
|
-
|
|
375
|
-
## Running Tests
|
|
376
|
-
|
|
377
|
-
```bash
|
|
378
|
-
# Run unit tests
|
|
379
|
-
nx test sdk
|
|
380
|
-
|
|
381
|
-
# Run integration tests
|
|
382
|
-
nx test sdk --config=integration
|
|
383
|
-
|
|
384
|
-
# Run tests with coverage
|
|
385
|
-
nx test sdk --coverage
|
|
386
|
-
```
|
|
175
|
+
> ⚠️ **Note**: Real-time features (WebSockets/SSE) are currently experimental and under active development. They are not yet fully documented or recommended for production use.
|
|
387
176
|
|
|
388
177
|
## License
|
|
389
178
|
|
|
@@ -153,7 +153,7 @@ export interface AuthInterceptors {
|
|
|
153
153
|
onRejected: (error: any) => Promise<any> | any;
|
|
154
154
|
};
|
|
155
155
|
}
|
|
156
|
-
export declare class DatabaseSDK {
|
|
156
|
+
export declare class DatabaseSDK<Schema extends Record<string, any> = any> {
|
|
157
157
|
private baseUrl;
|
|
158
158
|
private axiosInstance;
|
|
159
159
|
/**
|
|
@@ -251,6 +251,7 @@ export declare class DatabaseSDK {
|
|
|
251
251
|
* Helper method to create a query builder for fluent API usage
|
|
252
252
|
* @param tableName The name of the table to query
|
|
253
253
|
*/
|
|
254
|
+
table<K extends keyof Schema>(tableName: K): QueryBuilder<Schema[K]>;
|
|
254
255
|
table<T extends Record<string, any>>(tableName: string): QueryBuilder<T>;
|
|
255
256
|
/**
|
|
256
257
|
* Validates data object
|
|
@@ -260,7 +261,10 @@ export declare class DatabaseSDK {
|
|
|
260
261
|
/**
|
|
261
262
|
* Query builder class for more fluent API usage
|
|
262
263
|
*/
|
|
263
|
-
|
|
264
|
+
/**
|
|
265
|
+
* Query builder class for more fluent API usage
|
|
266
|
+
*/
|
|
267
|
+
declare class QueryBuilder<T extends Record<string, any>, Result extends Record<string, any> | undefined = undefined> {
|
|
264
268
|
private sdk;
|
|
265
269
|
private tableName;
|
|
266
270
|
private params;
|
|
@@ -270,7 +274,7 @@ declare class QueryBuilder<T extends Record<string, any>> {
|
|
|
270
274
|
/**
|
|
271
275
|
* Add a recursive CTE
|
|
272
276
|
*/
|
|
273
|
-
withRecursive(name: string, initialQuery: QueryBuilder<T>, recursiveQuery: QueryBuilder<T>, options?: {
|
|
277
|
+
withRecursive(name: string, initialQuery: QueryBuilder<T, any>, recursiveQuery: QueryBuilder<T, any>, options?: {
|
|
274
278
|
unionAll?: boolean;
|
|
275
279
|
columns?: string[];
|
|
276
280
|
}): this;
|
|
@@ -285,14 +289,14 @@ declare class QueryBuilder<T extends Record<string, any>> {
|
|
|
285
289
|
/**
|
|
286
290
|
* Add common window functions
|
|
287
291
|
*/
|
|
288
|
-
rowNumber(alias: string, partitionBy?:
|
|
289
|
-
rank(alias: string, partitionBy?:
|
|
290
|
-
lag(field:
|
|
291
|
-
lead(field:
|
|
292
|
+
rowNumber(alias: string, partitionBy?: FieldKeys<T>[], orderBy?: OrderByClause<T>[]): this;
|
|
293
|
+
rank(alias: string, partitionBy?: FieldKeys<T>[], orderBy?: OrderByClause<T>[]): this;
|
|
294
|
+
lag(field: FieldKeys<T>, alias: string, partitionBy?: FieldKeys<T>[], orderBy?: OrderByClause<T>[]): this;
|
|
295
|
+
lead(field: FieldKeys<T>, alias: string, partitionBy?: FieldKeys<T>[], orderBy?: OrderByClause<T>[]): this;
|
|
292
296
|
/**
|
|
293
297
|
* Add a CTE (WITH clause)
|
|
294
298
|
*/
|
|
295
|
-
with(name: string, queryOrCallback: QueryBuilder<T> | ((query: QueryBuilder<T>) => void), columns?: FieldKeys<T>[]): this;
|
|
299
|
+
with(name: string, queryOrCallback: QueryBuilder<T, any> | ((query: QueryBuilder<T, T>) => void), columns?: FieldKeys<T>[]): this;
|
|
296
300
|
/**
|
|
297
301
|
* Transform the result set
|
|
298
302
|
*/
|
|
@@ -311,18 +315,6 @@ declare class QueryBuilder<T extends Record<string, any>> {
|
|
|
311
315
|
* @param operator The comparison operator
|
|
312
316
|
* @param value The value to compare against
|
|
313
317
|
* @returns The query builder instance
|
|
314
|
-
* @example
|
|
315
|
-
* db.table<User>("users").where("status", "active").execute();
|
|
316
|
-
* db.table<User>("users").where("age", ">", 18).execute();
|
|
317
|
-
* db.table<User>("users").where("role", "in", ["admin", "manager"]).execute();
|
|
318
|
-
* db.table<User>("users").where("created_at", "is not null").execute();
|
|
319
|
-
* db.table<User>("users").where("name", "like", "%doe%").execute();
|
|
320
|
-
* db.table<User>("users").where("id", 1).execute();
|
|
321
|
-
* db.table<User>("users").where({ status: "active", role: "admin" }).execute();
|
|
322
|
-
* db.table<User>("users").where("age", ">=", 18).where("role", "manager").execute();
|
|
323
|
-
* db.table<User>("users").where("age", ">=", 18).orWhere((query) => {
|
|
324
|
-
* query.where("role", "manager").where("department", "IT");
|
|
325
|
-
* }).execute();
|
|
326
318
|
*/
|
|
327
319
|
where(field: FieldKeys<T>, operator: WhereOperator, value: any): this;
|
|
328
320
|
where(field: FieldKeys<T>, value: any): this;
|
|
@@ -339,85 +331,88 @@ declare class QueryBuilder<T extends Record<string, any>> {
|
|
|
339
331
|
/**
|
|
340
332
|
* Start an OR where group
|
|
341
333
|
*/
|
|
342
|
-
orWhere(callback: (query: QueryBuilder<T>) => void): this;
|
|
334
|
+
orWhere(callback: (query: QueryBuilder<T, Result>) => void): this;
|
|
343
335
|
/**
|
|
344
336
|
* Start an AND where group
|
|
345
337
|
*/
|
|
346
|
-
andWhere(callback: (query: QueryBuilder<T>) => void): this;
|
|
338
|
+
andWhere(callback: (query: QueryBuilder<T, Result>) => void): this;
|
|
347
339
|
/**
|
|
348
340
|
* Create a where group with the specified operator
|
|
349
341
|
*/
|
|
350
342
|
private whereGroup;
|
|
351
343
|
/**
|
|
352
344
|
* Add a where exists clause using a subquery
|
|
353
|
-
* @param subqueryBuilder A function that returns a configured query builder for the subquery
|
|
354
|
-
* @returns The query builder instance
|
|
355
|
-
* @example
|
|
356
|
-
* db.table<User>("users")
|
|
357
|
-
* .whereExists((subquery) =>
|
|
358
|
-
* subquery.table("orders")
|
|
359
|
-
* .where("orders.user_id", "=", "users.id")
|
|
360
|
-
* .where("total", ">", 1000)
|
|
361
|
-
* )
|
|
362
|
-
* .execute();
|
|
363
345
|
*/
|
|
364
|
-
whereExists(subqueryBuilder: (qb: DatabaseSDK) => QueryBuilder<any>): this;
|
|
346
|
+
whereExists(subqueryBuilder: (qb: DatabaseSDK) => QueryBuilder<any, any>): this;
|
|
365
347
|
/**
|
|
366
348
|
* Add a where exists clause with join conditions
|
|
367
|
-
* @param tableName The table to check for existence
|
|
368
|
-
* @param leftField The field from the main table
|
|
369
|
-
* @param rightField The field from the subquery table
|
|
370
|
-
* @param additionalConditions Additional conditions for the subquery
|
|
371
|
-
* @returns The query builder instance
|
|
372
|
-
* @example
|
|
373
|
-
* db.table<User>("users")
|
|
374
|
-
* .whereExistsJoin("orders", "id", "user_id", (qb) =>
|
|
375
|
-
* qb.where("total", ">", 1000)
|
|
376
|
-
* )
|
|
377
|
-
* .execute();
|
|
378
349
|
*/
|
|
379
|
-
whereExistsJoin(tableName: string, leftField: FieldKeys<T>, rightField: string, additionalConditions?: (qb: QueryBuilder<any>) => void): this;
|
|
350
|
+
whereExistsJoin(tableName: string, leftField: FieldKeys<T>, rightField: string, additionalConditions?: (qb: QueryBuilder<any, any>) => void): this;
|
|
380
351
|
getTableName(): string;
|
|
381
352
|
getParams(): QueryParams<T>;
|
|
382
353
|
/**
|
|
383
354
|
* Group by clause
|
|
384
355
|
*/
|
|
385
|
-
groupBy(...fields:
|
|
356
|
+
groupBy<K extends keyof T>(...fields: K[]): QueryBuilder<T, Result extends undefined ? Pick<T, K> : Result & Pick<T, K>>;
|
|
386
357
|
/**
|
|
387
358
|
* Having clause for grouped queries
|
|
388
359
|
*/
|
|
389
|
-
having(field: string, operator: WhereOperator, value: any): this;
|
|
360
|
+
having(field: FieldKeys<T> | string, operator: WhereOperator, value: any): this;
|
|
390
361
|
/**
|
|
391
362
|
* Add an aggregate function
|
|
392
363
|
*/
|
|
393
|
-
aggregate(type: AggregateOptions<T>['type'], field: FieldKeys<T>, alias?:
|
|
364
|
+
aggregate<Alias extends string>(type: AggregateOptions<T>['type'], field: FieldKeys<T>, alias?: Alias): QueryBuilder<T, Result extends undefined ? {
|
|
365
|
+
[P in Alias]: number;
|
|
366
|
+
} : Result & {
|
|
367
|
+
[P in Alias]: number;
|
|
368
|
+
}>;
|
|
394
369
|
/**
|
|
395
370
|
* Shorthand for count aggregate
|
|
396
371
|
*/
|
|
397
|
-
count(field?: FieldKeys<T>, alias?:
|
|
372
|
+
count<Alias extends string = 'count'>(field?: FieldKeys<T>, alias?: Alias): QueryBuilder<T, Result extends undefined ? {
|
|
373
|
+
[P in Alias]: number;
|
|
374
|
+
} : Result & {
|
|
375
|
+
[P in Alias]: number;
|
|
376
|
+
}>;
|
|
398
377
|
/**
|
|
399
378
|
* Shorthand for sum aggregate
|
|
400
379
|
*/
|
|
401
|
-
sum(field: FieldKeys<T>, alias
|
|
380
|
+
sum<Alias extends string>(field: FieldKeys<T>, alias: Alias): QueryBuilder<T, Result extends undefined ? {
|
|
381
|
+
[P in Alias]: number;
|
|
382
|
+
} : Result & {
|
|
383
|
+
[P in Alias]: number;
|
|
384
|
+
}>;
|
|
402
385
|
/**
|
|
403
386
|
* Shorthand for average aggregate
|
|
404
387
|
*/
|
|
405
|
-
avg(field: FieldKeys<T>, alias
|
|
388
|
+
avg<Alias extends string>(field: FieldKeys<T>, alias: Alias): QueryBuilder<T, Result extends undefined ? {
|
|
389
|
+
[P in Alias]: number;
|
|
390
|
+
} : Result & {
|
|
391
|
+
[P in Alias]: number;
|
|
392
|
+
}>;
|
|
406
393
|
/**
|
|
407
394
|
* Shorthand for minimum aggregate
|
|
408
395
|
*/
|
|
409
|
-
min(field: FieldKeys<T>, alias
|
|
396
|
+
min<Alias extends string>(field: FieldKeys<T>, alias: Alias): QueryBuilder<T, Result extends undefined ? {
|
|
397
|
+
[P in Alias]: number;
|
|
398
|
+
} : Result & {
|
|
399
|
+
[P in Alias]: number;
|
|
400
|
+
}>;
|
|
410
401
|
/**
|
|
411
402
|
* Shorthand for maximum aggregate
|
|
412
403
|
*/
|
|
413
|
-
max(field: FieldKeys<T>, alias
|
|
404
|
+
max<Alias extends string>(field: FieldKeys<T>, alias: Alias): QueryBuilder<T, Result extends undefined ? {
|
|
405
|
+
[P in Alias]: number;
|
|
406
|
+
} : Result & {
|
|
407
|
+
[P in Alias]: number;
|
|
408
|
+
}>;
|
|
414
409
|
toParams(): Promise<QueryParams<T>>;
|
|
415
410
|
/**
|
|
416
411
|
* Execute with transformations
|
|
417
412
|
* @param axiosConfig Optional axios config to be used for this request
|
|
418
413
|
* @returns Promise with the query results
|
|
419
414
|
*/
|
|
420
|
-
query(axiosConfig?: AxiosRequestConfig): Promise<ApiResponse<T>>;
|
|
415
|
+
query(axiosConfig?: AxiosRequestConfig): Promise<ApiResponse<Result extends undefined ? T : Result>>;
|
|
421
416
|
/**
|
|
422
417
|
* Create a record in the table
|
|
423
418
|
* @param data The data to create
|
|
@@ -464,7 +459,7 @@ declare class QueryBuilder<T extends Record<string, any>> {
|
|
|
464
459
|
* .select("id", "name", "email")
|
|
465
460
|
* .execute();
|
|
466
461
|
*/
|
|
467
|
-
select(...fields:
|
|
462
|
+
select<K extends keyof T>(...fields: K[]): QueryBuilder<T, Result extends undefined ? Pick<T, K> : Result & Pick<T, K>>;
|
|
468
463
|
}
|
|
469
464
|
export {};
|
|
470
465
|
//# sourceMappingURL=client.d.ts.map
|