@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/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.