@boltic/sdk 0.0.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/LICENSE +21 -0
- package/README.md +1012 -0
- package/dist/databases/index.d.ts +1560 -0
- package/dist/databases/index.js +2 -0
- package/dist/databases/index.js.map +1 -0
- package/dist/databases/index.mjs +523 -0
- package/dist/databases/index.mjs.map +1 -0
- package/dist/databases/test-client-BM9X5DH9.mjs +4053 -0
- package/dist/databases/test-client-BM9X5DH9.mjs.map +1 -0
- package/dist/databases/test-client-D-SuKCUC.js +2 -0
- package/dist/databases/test-client-D-SuKCUC.js.map +1 -0
- package/dist/databases/testing.d.ts +1077 -0
- package/dist/databases/testing.js +2 -0
- package/dist/databases/testing.js.map +1 -0
- package/dist/databases/testing.mjs +139 -0
- package/dist/databases/testing.mjs.map +1 -0
- package/dist/package.json +15 -0
- package/dist/sdk.js +3972 -0
- package/dist/sdk.js.map +1 -0
- package/dist/sdk.mjs +3972 -0
- package/dist/sdk.mjs.map +1 -0
- package/dist/types/index.d.ts +1087 -0
- package/package.json +82 -0
package/README.md
ADDED
|
@@ -0,0 +1,1012 @@
|
|
|
1
|
+
# Boltic SDK
|
|
2
|
+
|
|
3
|
+
Boltic SDK is an open-source TypeScript library, developed by Fynd, designed to empower developers worldwide with integration to the Boltic platform. Effortlessly manage databases, tables, columns, records, and run SQL queries to build robust, modern applications with ease and confidence.
|
|
4
|
+
|
|
5
|
+
## Documentation
|
|
6
|
+
|
|
7
|
+
- **[Boltic SDK Documentation](https://docs.uat.fcz0.de/docs/category/sdk/)** - Complete SDK documentation
|
|
8
|
+
|
|
9
|
+
## Features
|
|
10
|
+
|
|
11
|
+
- 🔧 **Full TypeScript Support**: Comprehensive type definitions and IntelliSense
|
|
12
|
+
- 🚀 **Modern Architecture**: ES modules and CommonJS support
|
|
13
|
+
- 🔐 **Built-in Authentication**: Integrated API key management
|
|
14
|
+
- 📊 **Database Operations**: Complete table and column management
|
|
15
|
+
- 📝 **Record Operations**: Full CRUD operations with advanced querying
|
|
16
|
+
- 🌐 **Multi-Region Support**: Asia Pacific and US Central regions
|
|
17
|
+
- 🔍 **Advanced Filtering**: Comprehensive query operators
|
|
18
|
+
- 🛠️ **Helper Classes**: Schema and column creation utilities
|
|
19
|
+
- 🎯 **Vector Support**: AI/ML vector fields with multiple precisions
|
|
20
|
+
|
|
21
|
+
## Prerequisites
|
|
22
|
+
|
|
23
|
+
- **Node.js:** >=18.0.0
|
|
24
|
+
- **NPM:** >=8.0.0
|
|
25
|
+
|
|
26
|
+
## Installation
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
npm install @boltic/sdk
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Quick Start
|
|
33
|
+
|
|
34
|
+
```typescript
|
|
35
|
+
import { createClient } from '@boltic/sdk';
|
|
36
|
+
|
|
37
|
+
// Initialize the client
|
|
38
|
+
const client = createClient('your-api-key', {
|
|
39
|
+
region: 'asia-south1', // 'asia-south1' or 'us-central1'
|
|
40
|
+
debug: false,
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
// Use the client for database operations
|
|
44
|
+
const tables = client.tables;
|
|
45
|
+
const columns = client.columns;
|
|
46
|
+
const records = client.records;
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Authentication
|
|
50
|
+
|
|
51
|
+
### API Key Setup
|
|
52
|
+
|
|
53
|
+
You can get your API key from [boltic.io](https://boltic.io).
|
|
54
|
+
|
|
55
|
+
1. Log into your [Boltic](https://boltic.io) account
|
|
56
|
+
2. Go to Settings → PAT Tokens
|
|
57
|
+
3. Generate and copy your API key
|
|
58
|
+
|
|
59
|
+
```typescript
|
|
60
|
+
import { createClient } from '@boltic/sdk';
|
|
61
|
+
|
|
62
|
+
const client = createClient('your-api-key-here', {
|
|
63
|
+
region: 'asia-south1',
|
|
64
|
+
});
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Environment Variables
|
|
68
|
+
|
|
69
|
+
```typescript
|
|
70
|
+
import dotenv from 'dotenv';
|
|
71
|
+
import { createClient } from '@boltic/sdk';
|
|
72
|
+
|
|
73
|
+
dotenv.config();
|
|
74
|
+
|
|
75
|
+
const client = createClient(process.env.BOLTIC_API_KEY!, {
|
|
76
|
+
region: process.env.BOLTIC_REGION || 'asia-south1',
|
|
77
|
+
debug: process.env.DEBUG === 'true',
|
|
78
|
+
});
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## Configuration Options
|
|
82
|
+
|
|
83
|
+
```typescript
|
|
84
|
+
interface ClientOptions {
|
|
85
|
+
region?: 'asia-south1' | 'us-central1';
|
|
86
|
+
retryAttempts?: number;
|
|
87
|
+
retryDelay?: number;
|
|
88
|
+
maxRetries?: number;
|
|
89
|
+
timeout?: number;
|
|
90
|
+
debug?: boolean;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const client = createClient('your-api-key', {
|
|
94
|
+
region: 'asia-south1',
|
|
95
|
+
debug: true,
|
|
96
|
+
retryAttempts: 3,
|
|
97
|
+
retryDelay: 1000,
|
|
98
|
+
maxRetries: 3,
|
|
99
|
+
timeout: 30000,
|
|
100
|
+
});
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Run your file to create client:
|
|
104
|
+
|
|
105
|
+
```sh
|
|
106
|
+
npx tsx create-client.ts
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## Database Context
|
|
110
|
+
|
|
111
|
+
The client automatically uses a default database context for all operations:
|
|
112
|
+
|
|
113
|
+
```typescript
|
|
114
|
+
// Get current database context
|
|
115
|
+
const currentDb = client.getCurrentDatabase();
|
|
116
|
+
console.log('Current database:', currentDb);
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## Table Operations
|
|
120
|
+
|
|
121
|
+
### Reserved Columns
|
|
122
|
+
|
|
123
|
+
The following columns are automatically added to all tables and cannot be modified or deleted:
|
|
124
|
+
|
|
125
|
+
- **`id`**: Primary key field (uuid type, unique, not nullable)
|
|
126
|
+
- **`created_at`**: Timestamp when the record was created
|
|
127
|
+
- **`updated_at`**: Timestamp when the record was last updated
|
|
128
|
+
|
|
129
|
+
These columns are managed by the system and provide essential functionality for record identification and tracking.
|
|
130
|
+
|
|
131
|
+
### Creating Tables
|
|
132
|
+
|
|
133
|
+
```typescript
|
|
134
|
+
// Create a table with schema
|
|
135
|
+
const tableResult = await client.tables.create({
|
|
136
|
+
name: 'users',
|
|
137
|
+
description: 'User management table',
|
|
138
|
+
fields: [
|
|
139
|
+
{
|
|
140
|
+
name: 'name',
|
|
141
|
+
type: 'text',
|
|
142
|
+
is_nullable: false,
|
|
143
|
+
description: 'User name',
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
name: 'email',
|
|
147
|
+
type: 'email',
|
|
148
|
+
is_nullable: false,
|
|
149
|
+
is_unique: true,
|
|
150
|
+
description: 'User email',
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
name: 'age',
|
|
154
|
+
type: 'number',
|
|
155
|
+
decimals: '0.00',
|
|
156
|
+
description: 'User age',
|
|
157
|
+
},
|
|
158
|
+
{
|
|
159
|
+
name: 'salary',
|
|
160
|
+
type: 'currency',
|
|
161
|
+
currency_format: 'USD',
|
|
162
|
+
decimals: '0.00',
|
|
163
|
+
description: 'User salary',
|
|
164
|
+
},
|
|
165
|
+
{
|
|
166
|
+
name: 'is_active',
|
|
167
|
+
type: 'checkbox',
|
|
168
|
+
default_value: true,
|
|
169
|
+
description: 'User status',
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
name: 'role',
|
|
173
|
+
type: 'dropdown',
|
|
174
|
+
selectable_items: ['Admin', 'User', 'Guest'],
|
|
175
|
+
multiple_selections: false,
|
|
176
|
+
description: 'User role',
|
|
177
|
+
},
|
|
178
|
+
],
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
// Note: The following columns are automatically added to all tables:
|
|
182
|
+
// - 'id': Primary key (text, unique, not nullable)
|
|
183
|
+
// - 'created_at': Timestamp when record was created
|
|
184
|
+
// - 'updated_at': Timestamp when record was last updated
|
|
185
|
+
|
|
186
|
+
if (tableResult.error) {
|
|
187
|
+
console.error('Table creation failed:', tableResult.error);
|
|
188
|
+
} else {
|
|
189
|
+
console.log('Table created:', tableResult.data);
|
|
190
|
+
}
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
### Listing and Filtering Tables
|
|
194
|
+
|
|
195
|
+
```typescript
|
|
196
|
+
// List all tables
|
|
197
|
+
const allTables = await client.tables.findAll();
|
|
198
|
+
|
|
199
|
+
// Filter tables by name
|
|
200
|
+
const filteredTables = await client.tables.findAll({
|
|
201
|
+
where: { name: 'users' },
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
// Get a specific table
|
|
205
|
+
const table = await client.tables.findOne({
|
|
206
|
+
where: { name: 'users' },
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
// Get table by name
|
|
210
|
+
const tableByName = await client.tables.findByName('users');
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
### Updating Tables
|
|
214
|
+
|
|
215
|
+
```typescript
|
|
216
|
+
// Update table properties
|
|
217
|
+
const updateResult = await client.tables.update('users', {
|
|
218
|
+
name: 'updated_users',
|
|
219
|
+
is_shared: true,
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
// Rename table
|
|
223
|
+
const renameResult = await client.tables.rename('users', 'new_users');
|
|
224
|
+
|
|
225
|
+
// Set table access
|
|
226
|
+
const accessResult = await client.tables.setAccess({
|
|
227
|
+
table_name: 'new_users',
|
|
228
|
+
is_shared: true,
|
|
229
|
+
});
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
### Deleting Tables
|
|
233
|
+
|
|
234
|
+
```typescript
|
|
235
|
+
// Delete table by name
|
|
236
|
+
const deleteResult = await client.tables.delete('users');
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
## Column Operations
|
|
240
|
+
|
|
241
|
+
### Creating Columns
|
|
242
|
+
|
|
243
|
+
```typescript
|
|
244
|
+
// Create different types of columns
|
|
245
|
+
const columnTypes = [
|
|
246
|
+
{
|
|
247
|
+
name: 'description',
|
|
248
|
+
type: 'long-text',
|
|
249
|
+
description: 'User description',
|
|
250
|
+
},
|
|
251
|
+
{
|
|
252
|
+
name: 'age',
|
|
253
|
+
type: 'number',
|
|
254
|
+
decimals: '0.00',
|
|
255
|
+
description: 'User age',
|
|
256
|
+
},
|
|
257
|
+
{
|
|
258
|
+
name: 'salary',
|
|
259
|
+
type: 'currency',
|
|
260
|
+
currency_format: 'USD',
|
|
261
|
+
decimals: '0.00',
|
|
262
|
+
description: 'User salary',
|
|
263
|
+
},
|
|
264
|
+
{
|
|
265
|
+
name: 'is_active',
|
|
266
|
+
type: 'checkbox',
|
|
267
|
+
default_value: true,
|
|
268
|
+
description: 'User status',
|
|
269
|
+
},
|
|
270
|
+
{
|
|
271
|
+
name: 'role',
|
|
272
|
+
type: 'dropdown',
|
|
273
|
+
selectable_items: ['Admin', 'User', 'Guest'],
|
|
274
|
+
multiple_selections: false,
|
|
275
|
+
description: 'User role',
|
|
276
|
+
},
|
|
277
|
+
{
|
|
278
|
+
name: 'phone',
|
|
279
|
+
type: 'phone-number',
|
|
280
|
+
phone_format: '+91 123 456 7890',
|
|
281
|
+
description: 'Phone number',
|
|
282
|
+
},
|
|
283
|
+
{
|
|
284
|
+
name: 'embedding',
|
|
285
|
+
type: 'vector',
|
|
286
|
+
vector_dimension: 1536,
|
|
287
|
+
description: 'Text embedding vector',
|
|
288
|
+
},
|
|
289
|
+
];
|
|
290
|
+
|
|
291
|
+
for (const columnData of columnTypes) {
|
|
292
|
+
const result = await client.columns.create('users', columnData);
|
|
293
|
+
if (result.error) {
|
|
294
|
+
console.error(`Failed to create ${columnData.type} column:`, result.error);
|
|
295
|
+
} else {
|
|
296
|
+
console.log(`Created ${columnData.type} column:`, result.data);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
### Listing and Filtering Columns
|
|
302
|
+
|
|
303
|
+
```typescript
|
|
304
|
+
// List all columns in a table
|
|
305
|
+
const allColumns = await client.columns.findAll('users');
|
|
306
|
+
|
|
307
|
+
// Filter columns by type
|
|
308
|
+
const textColumns = await client.columns.findAll('users', {
|
|
309
|
+
where: { type: 'text' },
|
|
310
|
+
});
|
|
311
|
+
|
|
312
|
+
// Get a specific column
|
|
313
|
+
const column = await client.columns.findOne('users', {
|
|
314
|
+
where: { name: 'email' },
|
|
315
|
+
});
|
|
316
|
+
|
|
317
|
+
// Get column by UUID
|
|
318
|
+
const columnById = await client.columns.findById('users', 'column-id');
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
### Updating Columns
|
|
322
|
+
|
|
323
|
+
```typescript
|
|
324
|
+
// Update column properties
|
|
325
|
+
const updateResult = await client.columns.update('users', 'description', {
|
|
326
|
+
description: 'Updated user description',
|
|
327
|
+
});
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
### Deleting Columns
|
|
331
|
+
|
|
332
|
+
```typescript
|
|
333
|
+
// Delete a column
|
|
334
|
+
const deleteResult = await client.columns.delete('users', 'description');
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
## Record Operations
|
|
338
|
+
|
|
339
|
+
### Inserting Records
|
|
340
|
+
|
|
341
|
+
```typescript
|
|
342
|
+
// Insert a single record
|
|
343
|
+
const recordData = {
|
|
344
|
+
name: 'John Doe',
|
|
345
|
+
email: 'john.doe@example.com',
|
|
346
|
+
age: 30,
|
|
347
|
+
salary: 75000,
|
|
348
|
+
is_active: true,
|
|
349
|
+
role: 'Admin',
|
|
350
|
+
};
|
|
351
|
+
|
|
352
|
+
const insertResult = await client.records.insert('users', recordData);
|
|
353
|
+
|
|
354
|
+
if (insertResult.error) {
|
|
355
|
+
console.error('Record insertion failed:', insertResult.error);
|
|
356
|
+
} else {
|
|
357
|
+
console.log('Record inserted:', insertResult.data);
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
// Insert multiple records using insertMany() for better performance
|
|
361
|
+
const multipleRecords = [
|
|
362
|
+
{
|
|
363
|
+
name: 'Jane Smith',
|
|
364
|
+
email: 'jane@example.com',
|
|
365
|
+
age: 28,
|
|
366
|
+
salary: 65000,
|
|
367
|
+
is_active: true,
|
|
368
|
+
role: 'User',
|
|
369
|
+
},
|
|
370
|
+
{
|
|
371
|
+
name: 'Bob Johnson',
|
|
372
|
+
email: 'bob@example.com',
|
|
373
|
+
age: 35,
|
|
374
|
+
salary: 70000,
|
|
375
|
+
is_active: true,
|
|
376
|
+
role: 'Admin',
|
|
377
|
+
},
|
|
378
|
+
];
|
|
379
|
+
|
|
380
|
+
// Bulk insert with validation (default)
|
|
381
|
+
const bulkResult = await client.records.insertMany('users', multipleRecords);
|
|
382
|
+
|
|
383
|
+
if (bulkResult.error) {
|
|
384
|
+
console.error('Bulk insertion failed:', bulkResult.error);
|
|
385
|
+
} else {
|
|
386
|
+
console.log(`Successfully inserted ${bulkResult.data.insert_count} records`);
|
|
387
|
+
console.log('Inserted records:', bulkResult.data.records);
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
// Bulk insert without validation
|
|
391
|
+
const bulkNoValidationResult = await client.records.insertMany(
|
|
392
|
+
'users',
|
|
393
|
+
multipleRecords,
|
|
394
|
+
{ validation: false }
|
|
395
|
+
);
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
**Note:**
|
|
399
|
+
|
|
400
|
+
- Unlike single insert(), insertMany() requires complete records. All required fields must be provided in insertMany() call.
|
|
401
|
+
|
|
402
|
+
### Bulk Insert Operations
|
|
403
|
+
|
|
404
|
+
The SDK provides an efficient `insertMany()` method for inserting multiple records in a single API call:
|
|
405
|
+
|
|
406
|
+
```typescript
|
|
407
|
+
// Bulk insert with validation (default behavior)
|
|
408
|
+
const records = [
|
|
409
|
+
{ name: 'User 1', email: 'user1@example.com', age: 25 },
|
|
410
|
+
{ name: 'User 2', email: 'user2@example.com', age: 30 },
|
|
411
|
+
{ name: 'User 3', email: 'user3@example.com', age: 35 },
|
|
412
|
+
];
|
|
413
|
+
|
|
414
|
+
const result = await client.records.insertMany('users', records);
|
|
415
|
+
|
|
416
|
+
if (result.error) {
|
|
417
|
+
console.error('Bulk insertion failed:', result.error);
|
|
418
|
+
} else {
|
|
419
|
+
console.log(`Successfully inserted ${result.data.insert_count} records`);
|
|
420
|
+
console.log('Response:', result.data);
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
// Bulk insert without validation (faster, less safe)
|
|
424
|
+
const resultNoValidation = await client.records.insertMany('users', records, {
|
|
425
|
+
validation: false,
|
|
426
|
+
});
|
|
427
|
+
```
|
|
428
|
+
|
|
429
|
+
### Querying Records
|
|
430
|
+
|
|
431
|
+
```typescript
|
|
432
|
+
// Find all records
|
|
433
|
+
const allRecords = await client.records.findAll('users');
|
|
434
|
+
|
|
435
|
+
// Find records with pagination
|
|
436
|
+
const paginatedRecords = await client.records.findAll('users', {
|
|
437
|
+
page: {
|
|
438
|
+
page_no: 1,
|
|
439
|
+
page_size: 10,
|
|
440
|
+
},
|
|
441
|
+
});
|
|
442
|
+
|
|
443
|
+
// Find records with filters (API format)
|
|
444
|
+
const filteredRecords = await client.records.findAll('users', {
|
|
445
|
+
filters: [
|
|
446
|
+
{ field: 'age', operator: '>=', values: [25] },
|
|
447
|
+
{ field: 'is_active', operator: '=', values: [true] },
|
|
448
|
+
{ field: 'role', operator: 'IN', values: ['Admin', 'User'] },
|
|
449
|
+
],
|
|
450
|
+
});
|
|
451
|
+
|
|
452
|
+
// Find records with sorting
|
|
453
|
+
const sortedRecords = await client.records.findAll('users', {
|
|
454
|
+
sort: [
|
|
455
|
+
{ field: 'age', order: 'desc' },
|
|
456
|
+
{ field: 'name', order: 'asc' },
|
|
457
|
+
],
|
|
458
|
+
});
|
|
459
|
+
|
|
460
|
+
// Find a specific record
|
|
461
|
+
const specificRecord = await client.records.findOne('users', 'record-id');
|
|
462
|
+
|
|
463
|
+
// Find one record with filters
|
|
464
|
+
const filteredRecord = await client.records.findAll('users', {
|
|
465
|
+
filters: [
|
|
466
|
+
{ field: 'email', operator: '=', values: ['john.doe@example.com'] },
|
|
467
|
+
],
|
|
468
|
+
});
|
|
469
|
+
```
|
|
470
|
+
|
|
471
|
+
### Advanced Filtering
|
|
472
|
+
|
|
473
|
+
The SDK supports comprehensive filtering with various operators:
|
|
474
|
+
|
|
475
|
+
```typescript
|
|
476
|
+
// Text field filters
|
|
477
|
+
const textFilters = [
|
|
478
|
+
{ field: 'name', operator: '=', values: ['John'] }, // Equals
|
|
479
|
+
{ field: 'name', operator: '!=', values: ['Admin'] }, // Not equals
|
|
480
|
+
{ field: 'name', operator: 'LIKE', values: ['%John%'] }, // Contains (case sensitive)
|
|
481
|
+
{ field: 'name', operator: 'ILIKE', values: ['%john%'] }, // Contains (case insensitive)
|
|
482
|
+
{ field: 'name', operator: 'STARTS WITH', values: ['J'] }, // Starts with
|
|
483
|
+
{ field: 'name', operator: 'IN', values: ['John', 'Jane'] }, // Is one of
|
|
484
|
+
{ field: 'name', operator: 'IS EMPTY', values: [false] }, // Is not empty
|
|
485
|
+
];
|
|
486
|
+
|
|
487
|
+
// Number field filters
|
|
488
|
+
const numberFilters = [
|
|
489
|
+
{ field: 'age', operator: '>', values: [30] }, // Greater than
|
|
490
|
+
{ field: 'age', operator: '>=', values: [30] }, // Greater than or equal
|
|
491
|
+
{ field: 'age', operator: '<', values: [35] }, // Less than
|
|
492
|
+
{ field: 'age', operator: '<=', values: [35] }, // Less than or equal
|
|
493
|
+
{ field: 'age', operator: 'BETWEEN', values: [25, 35] }, // Between
|
|
494
|
+
{ field: 'age', operator: 'IN', values: [25, 30, 35] }, // Is one of
|
|
495
|
+
];
|
|
496
|
+
|
|
497
|
+
// Boolean field filters
|
|
498
|
+
const booleanFilters = [
|
|
499
|
+
{ field: 'is_active', operator: '=', values: [true] }, // Is true
|
|
500
|
+
{ field: 'is_active', operator: '=', values: [false] }, // Is false
|
|
501
|
+
];
|
|
502
|
+
|
|
503
|
+
// Date field filters
|
|
504
|
+
const dateFilters = [
|
|
505
|
+
{ field: 'created_at', operator: '>', values: ['2024-01-01T00:00:00Z'] },
|
|
506
|
+
{
|
|
507
|
+
field: 'created_at',
|
|
508
|
+
operator: 'BETWEEN',
|
|
509
|
+
values: ['2024-01-01T00:00:00Z', '2024-12-31T23:59:59Z'],
|
|
510
|
+
},
|
|
511
|
+
{ field: 'created_at', operator: 'WITHIN', values: ['last-30-days'] },
|
|
512
|
+
];
|
|
513
|
+
|
|
514
|
+
// Array/dropdown field filters
|
|
515
|
+
const arrayFilters = [
|
|
516
|
+
{ field: 'tags', operator: '@>', values: [['tag1']] }, // Array contains
|
|
517
|
+
{ field: 'tags', operator: 'ANY', values: ['tag1'] }, // Any element matches
|
|
518
|
+
{ field: 'category', operator: 'IS ONE OF', values: ['tech', 'business'] },
|
|
519
|
+
];
|
|
520
|
+
|
|
521
|
+
// Vector field filters
|
|
522
|
+
const vectorFilters = [
|
|
523
|
+
{ field: 'embedding', operator: '!=', values: [null] }, // Not null
|
|
524
|
+
{ field: 'embedding', operator: '<->', values: ['[0.1,0.2,0.3]'] }, // Euclidean distance
|
|
525
|
+
{ field: 'embedding', operator: '<=>', values: ['[0.1,0.2,0.3]'] }, // Cosine distance
|
|
526
|
+
];
|
|
527
|
+
|
|
528
|
+
// Multiple conditions (AND logic)
|
|
529
|
+
const multipleFilters = await client.records.findAll('users', {
|
|
530
|
+
filters: [
|
|
531
|
+
{ field: 'age', operator: '>=', values: [25] },
|
|
532
|
+
{ field: 'is_active', operator: '=', values: [true] },
|
|
533
|
+
{ field: 'salary', operator: '>', values: [50000] },
|
|
534
|
+
],
|
|
535
|
+
});
|
|
536
|
+
```
|
|
537
|
+
|
|
538
|
+
### Updating Records
|
|
539
|
+
|
|
540
|
+
```typescript
|
|
541
|
+
// Update records by filters
|
|
542
|
+
const updateResult = await client.records.update('users', {
|
|
543
|
+
set: { is_active: false },
|
|
544
|
+
filters: [{ field: 'role', operator: '=', values: ['Guest'] }],
|
|
545
|
+
});
|
|
546
|
+
|
|
547
|
+
// Update record by ID
|
|
548
|
+
const updateByIdResult = await client.records.updateById(
|
|
549
|
+
'users',
|
|
550
|
+
'record-id-here',
|
|
551
|
+
{
|
|
552
|
+
salary: 80000,
|
|
553
|
+
}
|
|
554
|
+
);
|
|
555
|
+
```
|
|
556
|
+
|
|
557
|
+
### Deleting Records
|
|
558
|
+
|
|
559
|
+
```typescript
|
|
560
|
+
// Delete records by filters
|
|
561
|
+
const deleteResult = await client.records.delete('users', {
|
|
562
|
+
filters: [{ field: 'is_active', operator: '=', values: [false] }],
|
|
563
|
+
});
|
|
564
|
+
|
|
565
|
+
// Delete records by IDs
|
|
566
|
+
const deleteByIdsResult = await client.records.delete('users', {
|
|
567
|
+
record_ids: ['id1', 'id2', 'id3'],
|
|
568
|
+
});
|
|
569
|
+
|
|
570
|
+
// Delete with multiple filter conditions
|
|
571
|
+
const deleteWithFilters = await client.records.delete('users', {
|
|
572
|
+
filters: [{ field: 'is_active', operator: '=', values: [false] }],
|
|
573
|
+
});
|
|
574
|
+
```
|
|
575
|
+
|
|
576
|
+
## SQL Operations
|
|
577
|
+
|
|
578
|
+
The Boltic SDK provides powerful SQL capabilities including natural language to SQL conversion and direct SQL query execution.
|
|
579
|
+
|
|
580
|
+
### Text-to-SQL Conversion
|
|
581
|
+
|
|
582
|
+
Convert natural language descriptions into SQL queries using AI:
|
|
583
|
+
|
|
584
|
+
```typescript
|
|
585
|
+
// Basic text-to-SQL conversion (streaming)
|
|
586
|
+
const sqlStream = await client.sql.textToSQL(
|
|
587
|
+
'Find all active users who registered this year'
|
|
588
|
+
);
|
|
589
|
+
|
|
590
|
+
// Collect the streaming response
|
|
591
|
+
let generatedSQL = '';
|
|
592
|
+
for await (const chunk of sqlStream) {
|
|
593
|
+
process.stdout.write(chunk); // Real-time output
|
|
594
|
+
generatedSQL += chunk;
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
console.log('\nGenerated SQL:', generatedSQL);
|
|
598
|
+
```
|
|
599
|
+
|
|
600
|
+
### SQL Query Refinement
|
|
601
|
+
|
|
602
|
+
Refine existing SQL queries with additional instructions:
|
|
603
|
+
|
|
604
|
+
```typescript
|
|
605
|
+
// Start with a base query
|
|
606
|
+
const baseQuery = `SELECT * FROM "users" WHERE "created_at" > '2024-01-01'`;
|
|
607
|
+
|
|
608
|
+
// Refine it with additional instructions
|
|
609
|
+
const refinedStream = await client.sql.textToSQL(
|
|
610
|
+
'Add sorting by registration date and limit to 10 results',
|
|
611
|
+
{
|
|
612
|
+
currentQuery: baseQuery,
|
|
613
|
+
}
|
|
614
|
+
);
|
|
615
|
+
|
|
616
|
+
// Process the refined query
|
|
617
|
+
let refinedSQL = '';
|
|
618
|
+
for await (const chunk of refinedStream) {
|
|
619
|
+
refinedSQL += chunk;
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
console.log('Refined SQL:', refinedSQL);
|
|
623
|
+
```
|
|
624
|
+
|
|
625
|
+
### SQL Query Execution
|
|
626
|
+
|
|
627
|
+
Execute SQL queries directly with built-in safety measures:
|
|
628
|
+
|
|
629
|
+
```typescript
|
|
630
|
+
// Execute a simple SQL query
|
|
631
|
+
const result = await client.sql.executeSQL(
|
|
632
|
+
`SELECT "name", "email" FROM "users" WHERE "is_active" = true`
|
|
633
|
+
);
|
|
634
|
+
|
|
635
|
+
if (result.error) {
|
|
636
|
+
console.error('SQL execution failed:', result.error);
|
|
637
|
+
} else {
|
|
638
|
+
// Extract data from Boltic API Response Structure
|
|
639
|
+
const [resultRows, metadata] = result.data;
|
|
640
|
+
|
|
641
|
+
console.log('Query results:', resultRows);
|
|
642
|
+
console.log('Metadata:', metadata);
|
|
643
|
+
|
|
644
|
+
if (result.pagination) {
|
|
645
|
+
console.log('Total records:', result.pagination.total_count);
|
|
646
|
+
console.log('Current page:', result.pagination.current_page);
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
// When joining or comparing id fields with other columns, cast to text using ::text
|
|
651
|
+
const joinQuery = await client.sql.executeSQL(`
|
|
652
|
+
SELECT u.name, p.title
|
|
653
|
+
FROM "users" u
|
|
654
|
+
JOIN "posts" p ON u.id::text = p.user_id
|
|
655
|
+
`);
|
|
656
|
+
```
|
|
657
|
+
|
|
658
|
+
**Note:** When joining or comparing an `id` field with a different-typed column, you need to cast using `::text` (e.g., `u.id::text = p.user_id`) since `id` fields are UUID type.
|
|
659
|
+
|
|
660
|
+
### Working with UUID ID Fields in SQL
|
|
661
|
+
|
|
662
|
+
**Important:** The `id` field in Boltic tables contains UUID values. When joining tables or comparing `id` fields with other column types, you must cast the `id` field to text using `::text`:
|
|
663
|
+
|
|
664
|
+
```typescript
|
|
665
|
+
const query = `
|
|
666
|
+
SELECT u.name, p.title
|
|
667
|
+
FROM "users" u
|
|
668
|
+
JOIN "posts" p ON u.id::text = p.user_id
|
|
669
|
+
`;
|
|
670
|
+
|
|
671
|
+
const result = await client.sql.executeSQL(query);
|
|
672
|
+
|
|
673
|
+
// More examples of UUID casting:
|
|
674
|
+
|
|
675
|
+
// Filtering by UUID id
|
|
676
|
+
const filterByIdQuery = `
|
|
677
|
+
SELECT * FROM "users"
|
|
678
|
+
WHERE id::text = 'some-uuid-string'
|
|
679
|
+
`;
|
|
680
|
+
|
|
681
|
+
// Joining multiple tables with UUID references
|
|
682
|
+
const complexJoinQuery = `
|
|
683
|
+
SELECT u.name, p.title, c.content
|
|
684
|
+
FROM "users" u
|
|
685
|
+
JOIN "posts" p ON u.id::text = p.user_id
|
|
686
|
+
JOIN "comments" c ON p.id::text = c.post_id
|
|
687
|
+
WHERE u.id::text IN ('uuid1', 'uuid2', 'uuid3')
|
|
688
|
+
`;
|
|
689
|
+
|
|
690
|
+
// Using UUID id in subqueries
|
|
691
|
+
const subqueryExample = `
|
|
692
|
+
SELECT * FROM "users" u
|
|
693
|
+
WHERE u.id::text IN (
|
|
694
|
+
SELECT DISTINCT user_id
|
|
695
|
+
FROM "posts"
|
|
696
|
+
WHERE created_at > '2024-01-01'
|
|
697
|
+
)
|
|
698
|
+
`;
|
|
699
|
+
```
|
|
700
|
+
|
|
701
|
+
**Why UUID Casting is Required:**
|
|
702
|
+
|
|
703
|
+
- The `id` field uses PostgreSQL's UUID type internally
|
|
704
|
+
- When comparing UUIDs with text columns (like foreign key references), PostgreSQL requires explicit type casting
|
|
705
|
+
- The `::text` operator converts the UUID to its string representation for comparison
|
|
706
|
+
- This applies to all system-generated `id` fields (`id`, and potentially foreign key references)
|
|
707
|
+
|
|
708
|
+
### SQL Error Handling
|
|
709
|
+
|
|
710
|
+
```typescript
|
|
711
|
+
try {
|
|
712
|
+
const result = await client.sql.executeSQL(
|
|
713
|
+
'SELECT * FROM "non_existent_table"'
|
|
714
|
+
);
|
|
715
|
+
|
|
716
|
+
if (result.error) {
|
|
717
|
+
console.error('SQL Error:', result.error);
|
|
718
|
+
|
|
719
|
+
// Access detailed error information
|
|
720
|
+
console.log('Error code:', result.error.code);
|
|
721
|
+
console.log('Error details:', result.error.details);
|
|
722
|
+
}
|
|
723
|
+
} catch (error) {
|
|
724
|
+
console.error('SQL execution exception:', error);
|
|
725
|
+
}
|
|
726
|
+
```
|
|
727
|
+
|
|
728
|
+
## Advanced Features
|
|
729
|
+
|
|
730
|
+
### Vector Columns for AI/ML
|
|
731
|
+
|
|
732
|
+
```typescript
|
|
733
|
+
// Create vector columns for AI/ML applications
|
|
734
|
+
const vectorColumns = [
|
|
735
|
+
{
|
|
736
|
+
name: 'embedding',
|
|
737
|
+
type: 'vector',
|
|
738
|
+
vector_dimension: 1536,
|
|
739
|
+
description: 'Text embedding vector',
|
|
740
|
+
},
|
|
741
|
+
{
|
|
742
|
+
name: 'half_embedding',
|
|
743
|
+
type: 'halfvec',
|
|
744
|
+
vector_dimension: 768,
|
|
745
|
+
description: 'Half precision vector',
|
|
746
|
+
},
|
|
747
|
+
{
|
|
748
|
+
name: 'sparse_features',
|
|
749
|
+
type: 'sparsevec',
|
|
750
|
+
vector_dimension: 5,
|
|
751
|
+
description: 'Sparse vector features (example: {1:1,3:2,5:3}/5)',
|
|
752
|
+
},
|
|
753
|
+
];
|
|
754
|
+
|
|
755
|
+
// Sparse Vector Format Example:
|
|
756
|
+
// {1:1,3:2,5:3}/5 represents a 5-dimensional vector where:
|
|
757
|
+
// - Position 1 has value 1
|
|
758
|
+
// - Position 3 has value 2
|
|
759
|
+
// - Position 5 has value 3
|
|
760
|
+
// - Positions 2 and 4 are implicitly 0
|
|
761
|
+
|
|
762
|
+
for (const vectorColumn of vectorColumns) {
|
|
763
|
+
await client.columns.create('vectors', vectorColumn);
|
|
764
|
+
}
|
|
765
|
+
```
|
|
766
|
+
|
|
767
|
+
### Configuration Management
|
|
768
|
+
|
|
769
|
+
```typescript
|
|
770
|
+
// Update API key
|
|
771
|
+
client.updateApiKey('new-api-key');
|
|
772
|
+
|
|
773
|
+
// Update configuration
|
|
774
|
+
client.updateConfig({
|
|
775
|
+
debug: true,
|
|
776
|
+
timeout: 45000,
|
|
777
|
+
});
|
|
778
|
+
|
|
779
|
+
// Get current configuration
|
|
780
|
+
const config = client.getConfig();
|
|
781
|
+
console.log('Current config:', config);
|
|
782
|
+
```
|
|
783
|
+
|
|
784
|
+
## Error Handling
|
|
785
|
+
|
|
786
|
+
The SDK provides comprehensive error handling with detailed error objects:
|
|
787
|
+
|
|
788
|
+
```typescript
|
|
789
|
+
try {
|
|
790
|
+
const result = await client.tables.create({
|
|
791
|
+
name: 'test-table',
|
|
792
|
+
fields: [{ name: 'id', type: 'text' }],
|
|
793
|
+
});
|
|
794
|
+
|
|
795
|
+
if (result.error) {
|
|
796
|
+
console.error('Operation failed:', result.error);
|
|
797
|
+
|
|
798
|
+
// Handle specific error cases
|
|
799
|
+
if (
|
|
800
|
+
result.error.message &&
|
|
801
|
+
result.error.message.includes('already exists')
|
|
802
|
+
) {
|
|
803
|
+
console.log('Table already exists, continuing...');
|
|
804
|
+
}
|
|
805
|
+
|
|
806
|
+
// Access error details
|
|
807
|
+
console.log('Error code:', result.error.code);
|
|
808
|
+
console.log('Error details:', result.error.details);
|
|
809
|
+
console.log('Error message:', result.error.message);
|
|
810
|
+
} else {
|
|
811
|
+
console.log('Success:', result.data);
|
|
812
|
+
}
|
|
813
|
+
} catch (error) {
|
|
814
|
+
console.error('API Error:', error.message);
|
|
815
|
+
}
|
|
816
|
+
```
|
|
817
|
+
|
|
818
|
+
### Error Object Structure
|
|
819
|
+
|
|
820
|
+
```typescript
|
|
821
|
+
interface ErrorResponse {
|
|
822
|
+
error: {
|
|
823
|
+
message: string; // Human-readable error message
|
|
824
|
+
code?: string; // Specific error code
|
|
825
|
+
details?: string[]; // Additional details
|
|
826
|
+
};
|
|
827
|
+
data?: null;
|
|
828
|
+
}
|
|
829
|
+
```
|
|
830
|
+
|
|
831
|
+
## Regions
|
|
832
|
+
|
|
833
|
+
The SDK supports multiple regions for global deployment:
|
|
834
|
+
|
|
835
|
+
- **`asia-south1`** (default): Asia Pacific (Mumbai) region
|
|
836
|
+
- **`us-central1`**: US Central (Iowa) region
|
|
837
|
+
|
|
838
|
+
Each region has its own API endpoints and environment configurations.
|
|
839
|
+
|
|
840
|
+
## Module Formats
|
|
841
|
+
|
|
842
|
+
The SDK supports both ES modules and CommonJS:
|
|
843
|
+
|
|
844
|
+
### ES Modules (Recommended)
|
|
845
|
+
|
|
846
|
+
```typescript
|
|
847
|
+
import { createClient } from '@boltic/sdk';
|
|
848
|
+
```
|
|
849
|
+
|
|
850
|
+
### CommonJS
|
|
851
|
+
|
|
852
|
+
```javascript
|
|
853
|
+
const { createClient } = require('@boltic/sdk');
|
|
854
|
+
```
|
|
855
|
+
|
|
856
|
+
### TypeScript
|
|
857
|
+
|
|
858
|
+
```typescript
|
|
859
|
+
import { createClient, ClientOptions, BolticClient } from '@boltic/sdk';
|
|
860
|
+
|
|
861
|
+
const options: ClientOptions = {
|
|
862
|
+
region: 'asia-south1',
|
|
863
|
+
debug: true,
|
|
864
|
+
timeout: 30000,
|
|
865
|
+
maxRetries: 3,
|
|
866
|
+
};
|
|
867
|
+
|
|
868
|
+
const client: BolticClient = createClient('your-api-key', options);
|
|
869
|
+
```
|
|
870
|
+
|
|
871
|
+
## File Format Examples
|
|
872
|
+
|
|
873
|
+
### JavaScript (.js)
|
|
874
|
+
|
|
875
|
+
```javascript
|
|
876
|
+
const { createClient } = require('@boltic/sdk');
|
|
877
|
+
|
|
878
|
+
const client = createClient('your-api-key');
|
|
879
|
+
|
|
880
|
+
async function main() {
|
|
881
|
+
const tables = await client.tables.findAll();
|
|
882
|
+
console.log('Tables:', tables);
|
|
883
|
+
}
|
|
884
|
+
|
|
885
|
+
main().catch(console.error);
|
|
886
|
+
```
|
|
887
|
+
|
|
888
|
+
### TypeScript (.ts)
|
|
889
|
+
|
|
890
|
+
```typescript
|
|
891
|
+
import { createClient, ClientOptions } from '@boltic/sdk';
|
|
892
|
+
|
|
893
|
+
const options: ClientOptions = {
|
|
894
|
+
region: 'asia-south1',
|
|
895
|
+
debug: true,
|
|
896
|
+
};
|
|
897
|
+
|
|
898
|
+
const client = createClient('your-api-key', options);
|
|
899
|
+
|
|
900
|
+
async function main(): Promise<void> {
|
|
901
|
+
const tables = await client.tables.findAll();
|
|
902
|
+
console.log('Tables:', tables);
|
|
903
|
+
}
|
|
904
|
+
|
|
905
|
+
main().catch(console.error);
|
|
906
|
+
```
|
|
907
|
+
|
|
908
|
+
### ES Modules (.mjs)
|
|
909
|
+
|
|
910
|
+
```javascript
|
|
911
|
+
import { createClient } from '@boltic/sdk';
|
|
912
|
+
|
|
913
|
+
const client = createClient('your-api-key');
|
|
914
|
+
|
|
915
|
+
async function main() {
|
|
916
|
+
const tables = await client.tables.findAll();
|
|
917
|
+
console.log('Tables:', tables);
|
|
918
|
+
}
|
|
919
|
+
|
|
920
|
+
main().catch(console.error);
|
|
921
|
+
```
|
|
922
|
+
|
|
923
|
+
## API Reference
|
|
924
|
+
|
|
925
|
+
### Core Client
|
|
926
|
+
|
|
927
|
+
- **`createClient(apiKey: string, options?: ClientOptions)`**: Initialize the Boltic client
|
|
928
|
+
|
|
929
|
+
### Tables
|
|
930
|
+
|
|
931
|
+
- **`client.tables.create(data)`**: Create a new table
|
|
932
|
+
- **`client.tables.findAll(options?)`**: List tables with optional filtering
|
|
933
|
+
- **`client.tables.findOne(options)`**: Get a specific table
|
|
934
|
+
- **`client.tables.findByName(name)`**: Get table by name
|
|
935
|
+
- **`client.tables.update(identifier, data)`**: Update table properties
|
|
936
|
+
- **`client.tables.rename(oldName, newName)`**: Rename a table
|
|
937
|
+
- **`client.tables.setAccess(data)`**: Update table access settings
|
|
938
|
+
- **`client.tables.delete(name)`**: Delete a table by name
|
|
939
|
+
|
|
940
|
+
### Columns
|
|
941
|
+
|
|
942
|
+
- **`client.columns.create(tableName, data)`**: Create a new column
|
|
943
|
+
- **`client.columns.findAll(tableName, options?)`**: List columns with optional filtering
|
|
944
|
+
- **`client.columns.findOne(tableName, options)`**: Get a specific column
|
|
945
|
+
- **`client.columns.findById(tableName, columnId)`**: Get column by ID
|
|
946
|
+
- **`client.columns.update(tableName, columnName, data)`**: Update column properties
|
|
947
|
+
- **`client.columns.delete(tableName, columnName)`**: Delete a column
|
|
948
|
+
|
|
949
|
+
### Records
|
|
950
|
+
|
|
951
|
+
- **`client.records.insert(tableName, data)`**: Insert a new record
|
|
952
|
+
- **`client.records.insertMany(tableName, records, options?)`**: Insert multiple records in bulk
|
|
953
|
+
- **`client.records.findAll(tableName, options?)`**: List records with optional filtering
|
|
954
|
+
- **`client.records.findOne(tableName, idOrOptions)`**: Get a specific record
|
|
955
|
+
- **`client.records.update(tableName, options)`**: Update records by filters
|
|
956
|
+
- **`client.records.updateById(tableName, options)`**: Update record by ID
|
|
957
|
+
- **`client.records.delete(tableName, options)`**: Delete records by filters or IDs
|
|
958
|
+
|
|
959
|
+
### SQL Operations
|
|
960
|
+
|
|
961
|
+
- **`client.sql.textToSQL(prompt, options?)`**: Convert natural language to SQL query (streaming)
|
|
962
|
+
- **`client.sql.executeSQL(query)`**: Execute SQL query with safety measures
|
|
963
|
+
|
|
964
|
+
## Examples and Demos
|
|
965
|
+
|
|
966
|
+
Check out the comprehensive demo files for complete usage examples:
|
|
967
|
+
|
|
968
|
+
- **[Comprehensive Database Operations Demo](./src/services/databases/examples/basic/comprehensive-database-operations-demo.ts)** - Complete SDK functionality demo
|
|
969
|
+
- **[SQL Operations Demo](./src/services/databases/examples/basic/comprehensive-sql-operations-demo.ts)** - SQL operations and text-to-SQL demo
|
|
970
|
+
|
|
971
|
+
These demos cover:
|
|
972
|
+
|
|
973
|
+
- All column types and their properties
|
|
974
|
+
- Advanced filtering and querying
|
|
975
|
+
- Error handling patterns
|
|
976
|
+
- Vector operations
|
|
977
|
+
- SQL operations and text-to-SQL conversion
|
|
978
|
+
|
|
979
|
+
## Development
|
|
980
|
+
|
|
981
|
+
```bash
|
|
982
|
+
# Install dependencies
|
|
983
|
+
npm install
|
|
984
|
+
|
|
985
|
+
# Build the package
|
|
986
|
+
npm run build
|
|
987
|
+
|
|
988
|
+
# Run tests
|
|
989
|
+
npm test
|
|
990
|
+
|
|
991
|
+
# Type checking
|
|
992
|
+
npm run type-check
|
|
993
|
+
|
|
994
|
+
# Linting
|
|
995
|
+
npm run lint
|
|
996
|
+
```
|
|
997
|
+
|
|
998
|
+
## Contributing
|
|
999
|
+
|
|
1000
|
+
1. Fork the repository
|
|
1001
|
+
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
|
|
1002
|
+
3. Commit your changes (`git commit -m 'Add some amazing feature'`)
|
|
1003
|
+
4. Push to the branch (`git push origin feature/amazing-feature`)
|
|
1004
|
+
5. Open a Pull Request
|
|
1005
|
+
|
|
1006
|
+
## Support
|
|
1007
|
+
|
|
1008
|
+
For support, email support@boltic.io or create an issue on [GitHub](https://github.com/bolticio/boltic-sdk).
|
|
1009
|
+
|
|
1010
|
+
## License
|
|
1011
|
+
|
|
1012
|
+
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|