@synapcores/sdk 0.1.0
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 +1011 -0
- package/dist/index.d.mts +2473 -0
- package/dist/index.d.ts +2473 -0
- package/dist/index.js +3109 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +3055 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +78 -0
package/README.md
ADDED
|
@@ -0,0 +1,1011 @@
|
|
|
1
|
+
# SynapCores Node.js/TypeScript SDK
|
|
2
|
+
|
|
3
|
+
Official Node.js/TypeScript SDK for SynapCores AI-Native Database Management System - A SQL 2026-compliant database with native tenant isolation, AI/ML functions, and multimedia support.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- 🚀 **Full TypeScript Support**: Complete type definitions for excellent IDE experience
|
|
8
|
+
- 🔐 **Dual Authentication**: Support for both JWT tokens and API keys
|
|
9
|
+
- 👤 **User Management**: Registration, login, and token refresh
|
|
10
|
+
- 🔑 **API Key Management**: Create, list, monitor, and revoke API keys
|
|
11
|
+
- 🤖 **AI-Native Operations**: Built-in embeddings, vector search, and semantic analysis
|
|
12
|
+
- 📊 **SQL 2026 Compliance**: Enhanced SQL syntax with AI operations
|
|
13
|
+
- 📁 **Multimedia Support**: Upload and manage images, videos, audio, and documents
|
|
14
|
+
- 🔄 **Real-time Subscriptions**: WebSocket support for live data updates
|
|
15
|
+
- 🧠 **AutoML Integration**: Train and deploy ML models automatically
|
|
16
|
+
- 🏢 **Multi-tenant**: Automatic tenant isolation for SaaS applications
|
|
17
|
+
- ⚡ **High Performance**: Async/await support with connection pooling
|
|
18
|
+
|
|
19
|
+
## Installation
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npm install @synapcores/sdk
|
|
23
|
+
# or
|
|
24
|
+
yarn add @synapcores/sdk
|
|
25
|
+
# or
|
|
26
|
+
pnpm add @synapcores/sdk
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Quick Start
|
|
30
|
+
|
|
31
|
+
### Using API Key Authentication
|
|
32
|
+
|
|
33
|
+
```typescript
|
|
34
|
+
import { SynapCores } from '@synapcores/sdk';
|
|
35
|
+
|
|
36
|
+
// Initialize client with API key authentication
|
|
37
|
+
// API keys can be created from your AIDB dashboard or programmatically
|
|
38
|
+
const client = new SynapCores({
|
|
39
|
+
host: 'localhost',
|
|
40
|
+
port: 8080,
|
|
41
|
+
apiKey: 'ak_prod_your_api_key_here', // API keys start with 'ak_' or 'aidb_'
|
|
42
|
+
useHttps: false, // Set to true in production
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
// Execute a query
|
|
46
|
+
const result = await client.executeQuery({
|
|
47
|
+
sql: 'SELECT * FROM products WHERE category = $1 LIMIT 10',
|
|
48
|
+
parameters: ['electronics'],
|
|
49
|
+
max_rows: 1000,
|
|
50
|
+
timeout_secs: 300,
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
console.log('Columns:', result.columns);
|
|
54
|
+
console.log('Rows:', result.rows);
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### Using JWT Token Authentication
|
|
58
|
+
|
|
59
|
+
```typescript
|
|
60
|
+
import { SynapCores } from '@synapcores/sdk';
|
|
61
|
+
|
|
62
|
+
// Step 1: Register a new user (or login if already registered)
|
|
63
|
+
const client = new SynapCores({
|
|
64
|
+
host: 'localhost',
|
|
65
|
+
port: 8080,
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
// Register new user
|
|
69
|
+
const user = await client.registerUser({
|
|
70
|
+
username: 'my_username',
|
|
71
|
+
email: 'user@example.com',
|
|
72
|
+
password: 'SecurePass123!',
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
console.log('Registered user:', user.id);
|
|
76
|
+
console.log('Active:', user.is_active);
|
|
77
|
+
|
|
78
|
+
// Step 2: Login to get JWT token
|
|
79
|
+
const loginResponse = await client.login({
|
|
80
|
+
username: 'my_username',
|
|
81
|
+
password: 'SecurePass123!',
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
// Token is automatically stored in client
|
|
85
|
+
// Or manually set it:
|
|
86
|
+
client.setJWTToken(loginResponse.access_token);
|
|
87
|
+
|
|
88
|
+
// Now authenticated - all subsequent requests use JWT
|
|
89
|
+
const collections = await client.listCollectionsDetailed();
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## Authentication
|
|
93
|
+
|
|
94
|
+
### API Key Authentication
|
|
95
|
+
|
|
96
|
+
API keys are suitable for server-to-server integrations and programmatic access.
|
|
97
|
+
|
|
98
|
+
```typescript
|
|
99
|
+
const client = new SynapCores({
|
|
100
|
+
host: 'localhost',
|
|
101
|
+
port: 8080,
|
|
102
|
+
apiKey: 'ak_prod_xyz789abc123...', // Use X-API-Key header
|
|
103
|
+
});
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
**API Key Formats:**
|
|
107
|
+
- Production keys: `ak_prod_...`
|
|
108
|
+
- Development keys: `ak_dev_...`
|
|
109
|
+
- Legacy format: `aidb_...` (also supported)
|
|
110
|
+
|
|
111
|
+
### JWT Token Authentication
|
|
112
|
+
|
|
113
|
+
JWT tokens are suitable for user sessions in web applications.
|
|
114
|
+
|
|
115
|
+
```typescript
|
|
116
|
+
// Initialize without auth
|
|
117
|
+
const client = new SynapCores({
|
|
118
|
+
host: 'localhost',
|
|
119
|
+
port: 8080,
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
// Login to get token
|
|
123
|
+
const { access_token } = await client.login({
|
|
124
|
+
username: 'username',
|
|
125
|
+
password: 'password',
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
// Token is automatically set, or manually:
|
|
129
|
+
client.setJWTToken(access_token);
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
**Refresh Token:**
|
|
133
|
+
```typescript
|
|
134
|
+
// Refresh before expiration
|
|
135
|
+
const refreshResponse = await client.refreshToken();
|
|
136
|
+
console.log('New token expires in:', refreshResponse.expires_in, 'seconds');
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
**Logout:**
|
|
140
|
+
```typescript
|
|
141
|
+
client.logout(); // Clears authentication
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
## User Registration & Management
|
|
145
|
+
|
|
146
|
+
### Register New User
|
|
147
|
+
|
|
148
|
+
```typescript
|
|
149
|
+
const user = await client.registerUser({
|
|
150
|
+
username: 'acme_admin',
|
|
151
|
+
email: 'admin@acme.com',
|
|
152
|
+
password: 'SecurePass123!',
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
// Check if user is active or waitlisted
|
|
156
|
+
if (!user.is_active) {
|
|
157
|
+
console.log('User added to waitlist');
|
|
158
|
+
} else {
|
|
159
|
+
console.log('User created and active:', user.id);
|
|
160
|
+
}
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
**Validation Rules:**
|
|
164
|
+
- `username`: 3-64 characters, alphanumeric + underscores/hyphens
|
|
165
|
+
- `email`: Valid email format
|
|
166
|
+
- `password`: Min 8 chars, must contain uppercase, lowercase, and number
|
|
167
|
+
|
|
168
|
+
## API Key Management
|
|
169
|
+
|
|
170
|
+
### Create API Key
|
|
171
|
+
|
|
172
|
+
```typescript
|
|
173
|
+
const result = await client.createAPIKey({
|
|
174
|
+
name: 'Production API',
|
|
175
|
+
permission: 'ReadOnly', // or 'FullAccess'
|
|
176
|
+
expires_in_days: 90, // Optional, omit for no expiration
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
console.log('⚠️ SAVE THIS KEY - shown only once:', result.raw_key);
|
|
180
|
+
console.log('Key ID:', result.api_key.id);
|
|
181
|
+
console.log('Key Preview:', result.api_key.key_preview);
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
**⚠️ Important:** The `raw_key` is shown **only once**. Store it securely immediately!
|
|
185
|
+
|
|
186
|
+
### List API Keys
|
|
187
|
+
|
|
188
|
+
```typescript
|
|
189
|
+
const { keys, total } = await client.listAPIKeys();
|
|
190
|
+
|
|
191
|
+
keys.forEach(key => {
|
|
192
|
+
console.log(`${key.name}: ${key.key_preview}`);
|
|
193
|
+
console.log(` Permission: ${key.permission}`);
|
|
194
|
+
console.log(` Usage: ${key.usage_count} requests`);
|
|
195
|
+
console.log(` Last used: ${key.last_used || 'Never'}`);
|
|
196
|
+
});
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
### Get API Key Statistics
|
|
200
|
+
|
|
201
|
+
```typescript
|
|
202
|
+
const stats = await client.getAPIKeyStats('key_xyz789');
|
|
203
|
+
|
|
204
|
+
console.log(`Total requests: ${stats.total_requests}`);
|
|
205
|
+
console.log(`Last 24h: ${stats.requests_last_24h}`);
|
|
206
|
+
console.log(`Last 7 days: ${stats.requests_last_7d}`);
|
|
207
|
+
|
|
208
|
+
stats.most_used_endpoints.forEach(endpoint => {
|
|
209
|
+
console.log(`${endpoint.endpoint} (${endpoint.method}): ${endpoint.count} (${endpoint.percentage}%)`);
|
|
210
|
+
});
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
### Revoke API Key
|
|
214
|
+
|
|
215
|
+
```typescript
|
|
216
|
+
await client.revokeAPIKey('key_xyz789');
|
|
217
|
+
console.log('API key revoked');
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
## SQL Query Execution
|
|
221
|
+
|
|
222
|
+
### Execute Query
|
|
223
|
+
|
|
224
|
+
Execute SQL queries with full SQL 2026 compliance and AI/ML extensions.
|
|
225
|
+
|
|
226
|
+
```typescript
|
|
227
|
+
const result = await client.executeQuery({
|
|
228
|
+
sql: 'SELECT * FROM products WHERE category = $1 LIMIT 10',
|
|
229
|
+
parameters: ['electronics'],
|
|
230
|
+
max_rows: 1000,
|
|
231
|
+
timeout_secs: 300,
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
// Access results
|
|
235
|
+
result.columns.forEach(col => {
|
|
236
|
+
console.log(`${col.name}: ${col.data_type} (nullable: ${col.nullable})`);
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
result.rows.forEach(row => {
|
|
240
|
+
// row is an array matching column order
|
|
241
|
+
console.log('Product:', row[0], 'Price:', row[1]);
|
|
242
|
+
});
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
**Query Result Format:**
|
|
246
|
+
```typescript
|
|
247
|
+
interface QueryResult {
|
|
248
|
+
columns: Array<{
|
|
249
|
+
name: string;
|
|
250
|
+
data_type: string;
|
|
251
|
+
nullable: boolean;
|
|
252
|
+
}>;
|
|
253
|
+
rows: any[][]; // Array of arrays (not objects)
|
|
254
|
+
rows_affected?: number;
|
|
255
|
+
execution_time_ms: number;
|
|
256
|
+
queryPlan?: Record<string, any>;
|
|
257
|
+
}
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
### Parameterized Queries
|
|
261
|
+
|
|
262
|
+
Always use parameters to prevent SQL injection:
|
|
263
|
+
|
|
264
|
+
```typescript
|
|
265
|
+
// ✅ SAFE - using parameters
|
|
266
|
+
const result = await client.executeQuery({
|
|
267
|
+
sql: 'SELECT * FROM users WHERE email = $1',
|
|
268
|
+
parameters: [userEmail],
|
|
269
|
+
});
|
|
270
|
+
|
|
271
|
+
// ❌ UNSAFE - vulnerable to SQL injection
|
|
272
|
+
const result = await client.executeQuery({
|
|
273
|
+
sql: `SELECT * FROM users WHERE email = '${userEmail}'`,
|
|
274
|
+
parameters: [],
|
|
275
|
+
});
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
### Batch Query Execution
|
|
279
|
+
|
|
280
|
+
Execute multiple queries in a single request:
|
|
281
|
+
|
|
282
|
+
```typescript
|
|
283
|
+
const batchResult = await client.executeBatchQueries({
|
|
284
|
+
queries: [
|
|
285
|
+
{
|
|
286
|
+
sql: 'SELECT COUNT(*) FROM products',
|
|
287
|
+
parameters: [],
|
|
288
|
+
},
|
|
289
|
+
{
|
|
290
|
+
sql: 'SELECT AVG(price) FROM products WHERE category = $1',
|
|
291
|
+
parameters: ['electronics'],
|
|
292
|
+
},
|
|
293
|
+
{
|
|
294
|
+
sql: 'INSERT INTO audit_log (action, timestamp) VALUES ($1, $2)',
|
|
295
|
+
parameters: ['batch_query', new Date().toISOString()],
|
|
296
|
+
},
|
|
297
|
+
],
|
|
298
|
+
transactional: false, // Set to true for transaction
|
|
299
|
+
});
|
|
300
|
+
|
|
301
|
+
batchResult.results.forEach((result, idx) => {
|
|
302
|
+
if (result.type === 'success') {
|
|
303
|
+
console.log(`Query ${idx + 1} succeeded:`, result.data?.rows);
|
|
304
|
+
} else {
|
|
305
|
+
console.error(`Query ${idx + 1} failed:`, result.error?.message);
|
|
306
|
+
}
|
|
307
|
+
});
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
### AI/ML Query Functions
|
|
311
|
+
|
|
312
|
+
Use built-in AI functions in SQL queries:
|
|
313
|
+
|
|
314
|
+
```typescript
|
|
315
|
+
// Generate embeddings
|
|
316
|
+
const embedResult = await client.executeQuery({
|
|
317
|
+
sql: "SELECT EMBED('search query text', 'minilm') as embedding",
|
|
318
|
+
parameters: [],
|
|
319
|
+
});
|
|
320
|
+
|
|
321
|
+
// Semantic similarity search
|
|
322
|
+
const searchResult = await client.executeQuery({
|
|
323
|
+
sql: `
|
|
324
|
+
SELECT
|
|
325
|
+
id,
|
|
326
|
+
title,
|
|
327
|
+
COSINE_SIMILARITY(
|
|
328
|
+
embedding,
|
|
329
|
+
EMBED($1, 'minilm')
|
|
330
|
+
) as similarity
|
|
331
|
+
FROM documents
|
|
332
|
+
ORDER BY similarity DESC
|
|
333
|
+
LIMIT 10
|
|
334
|
+
`,
|
|
335
|
+
parameters: ['artificial intelligence'],
|
|
336
|
+
});
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
**Available AI Functions:**
|
|
340
|
+
- `EMBED(text, model)` - Generate embedding vector
|
|
341
|
+
- `COSINE_SIMILARITY(vec1, vec2)` - Cosine similarity
|
|
342
|
+
- `EXTRACT_TEXT(multimedia_id)` - Extract text from images/PDFs
|
|
343
|
+
- `EXTRACT_FRAMES(multimedia_id, count)` - Extract video frames
|
|
344
|
+
- `DURATION(multimedia_id)` - Get media duration
|
|
345
|
+
- `VECTOR_ADD(vec1, vec2)` - Vector addition
|
|
346
|
+
- `VECTOR_DOT(vec1, vec2)` - Dot product
|
|
347
|
+
- `VECTOR_NORMALIZE(vec)` - Normalize vector
|
|
348
|
+
|
|
349
|
+
### Legacy SQL Method
|
|
350
|
+
|
|
351
|
+
The `sql()` method is still available for backward compatibility:
|
|
352
|
+
|
|
353
|
+
```typescript
|
|
354
|
+
// Legacy method (deprecated - use executeQuery instead)
|
|
355
|
+
const result = await client.sql('SELECT * FROM products LIMIT 10');
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
## Collection Management
|
|
359
|
+
|
|
360
|
+
### Create Collection with Schema
|
|
361
|
+
|
|
362
|
+
Create collections with structured schemas matching the database integration guide:
|
|
363
|
+
|
|
364
|
+
```typescript
|
|
365
|
+
const collection = await client.createCollectionWithSchema({
|
|
366
|
+
name: 'customer_profiles',
|
|
367
|
+
description: 'Customer data with structured schema',
|
|
368
|
+
schema: {
|
|
369
|
+
fields: [
|
|
370
|
+
{
|
|
371
|
+
name: 'id',
|
|
372
|
+
type: 'string',
|
|
373
|
+
required: true,
|
|
374
|
+
description: 'Unique customer ID',
|
|
375
|
+
},
|
|
376
|
+
{
|
|
377
|
+
name: 'name',
|
|
378
|
+
type: 'string',
|
|
379
|
+
required: true,
|
|
380
|
+
},
|
|
381
|
+
{
|
|
382
|
+
name: 'email',
|
|
383
|
+
type: 'string',
|
|
384
|
+
required: true,
|
|
385
|
+
},
|
|
386
|
+
{
|
|
387
|
+
name: 'age',
|
|
388
|
+
type: 'number',
|
|
389
|
+
required: false,
|
|
390
|
+
},
|
|
391
|
+
{
|
|
392
|
+
name: 'profile_image',
|
|
393
|
+
type: 'image',
|
|
394
|
+
required: false,
|
|
395
|
+
},
|
|
396
|
+
{
|
|
397
|
+
name: 'preferences',
|
|
398
|
+
type: 'object',
|
|
399
|
+
required: false,
|
|
400
|
+
},
|
|
401
|
+
{
|
|
402
|
+
name: 'tags',
|
|
403
|
+
type: 'array',
|
|
404
|
+
required: false,
|
|
405
|
+
},
|
|
406
|
+
{
|
|
407
|
+
name: 'embedding',
|
|
408
|
+
type: 'vector',
|
|
409
|
+
required: false,
|
|
410
|
+
},
|
|
411
|
+
{
|
|
412
|
+
name: 'created_at',
|
|
413
|
+
type: 'date',
|
|
414
|
+
required: true,
|
|
415
|
+
},
|
|
416
|
+
],
|
|
417
|
+
indexes: [
|
|
418
|
+
{
|
|
419
|
+
name: 'email_idx',
|
|
420
|
+
fields: ['email'],
|
|
421
|
+
type: 'btree',
|
|
422
|
+
unique: true,
|
|
423
|
+
},
|
|
424
|
+
{
|
|
425
|
+
name: 'vector_idx',
|
|
426
|
+
fields: ['embedding'],
|
|
427
|
+
type: 'vector',
|
|
428
|
+
},
|
|
429
|
+
],
|
|
430
|
+
},
|
|
431
|
+
});
|
|
432
|
+
```
|
|
433
|
+
|
|
434
|
+
**Supported Field Types:**
|
|
435
|
+
- `string` - Text data
|
|
436
|
+
- `number` - Integer or decimal
|
|
437
|
+
- `boolean` - True/false
|
|
438
|
+
- `date` - Date and time
|
|
439
|
+
- `object` - Nested objects
|
|
440
|
+
- `array` - Lists
|
|
441
|
+
- `vector` - AI embeddings
|
|
442
|
+
- `image` - Image file reference
|
|
443
|
+
- `audio` - Audio file reference
|
|
444
|
+
- `video` - Video file reference
|
|
445
|
+
|
|
446
|
+
**Index Types:**
|
|
447
|
+
- `btree` - Range queries, sorting (general purpose)
|
|
448
|
+
- `hash` - Exact matches (fast equality)
|
|
449
|
+
- `vector` - Similarity search (AI/ML queries)
|
|
450
|
+
- `text` - Full-text search
|
|
451
|
+
|
|
452
|
+
### List Collections
|
|
453
|
+
|
|
454
|
+
```typescript
|
|
455
|
+
// Simple list (backward compatible)
|
|
456
|
+
const collectionNames = await client.listCollections();
|
|
457
|
+
|
|
458
|
+
// Detailed list with pagination and filtering
|
|
459
|
+
const result = await client.listCollectionsDetailed({
|
|
460
|
+
page: 1,
|
|
461
|
+
pageSize: 20,
|
|
462
|
+
search: 'customer', // Optional search filter
|
|
463
|
+
sortBy: 'name',
|
|
464
|
+
sortOrder: 'asc',
|
|
465
|
+
});
|
|
466
|
+
|
|
467
|
+
result.collections.forEach(collection => {
|
|
468
|
+
console.log(`${collection.name}: ${collection.documentCount} documents`);
|
|
469
|
+
});
|
|
470
|
+
```
|
|
471
|
+
|
|
472
|
+
### Get Collection
|
|
473
|
+
|
|
474
|
+
```typescript
|
|
475
|
+
const collection = await client.getCollection('products');
|
|
476
|
+
console.log('Schema:', collection.schema);
|
|
477
|
+
```
|
|
478
|
+
|
|
479
|
+
### Delete Collection
|
|
480
|
+
|
|
481
|
+
```typescript
|
|
482
|
+
// ⚠️ Warning: Deletes all documents and multimedia in the collection!
|
|
483
|
+
await client.deleteCollection('products');
|
|
484
|
+
```
|
|
485
|
+
|
|
486
|
+
## Multimedia File Uploads
|
|
487
|
+
|
|
488
|
+
Upload and manage images, videos, audio, and documents with automatic processing.
|
|
489
|
+
|
|
490
|
+
### Upload Multimedia
|
|
491
|
+
|
|
492
|
+
```typescript
|
|
493
|
+
import * as fs from 'fs';
|
|
494
|
+
|
|
495
|
+
// Upload file to a document
|
|
496
|
+
const fileBuffer = fs.readFileSync('path/to/image.jpg');
|
|
497
|
+
|
|
498
|
+
const multimedia = await client.uploadMultimedia(
|
|
499
|
+
'products', // collection name
|
|
500
|
+
'prod_123', // document ID
|
|
501
|
+
fileBuffer, // File, Blob, or Buffer
|
|
502
|
+
{
|
|
503
|
+
description: 'Product photo',
|
|
504
|
+
tags: ['product', 'catalog'],
|
|
505
|
+
custom_field: 'value',
|
|
506
|
+
}
|
|
507
|
+
);
|
|
508
|
+
|
|
509
|
+
console.log('Uploaded:', multimedia.id);
|
|
510
|
+
console.log('File:', multimedia.file_name);
|
|
511
|
+
console.log('Size:', multimedia.file_size, 'bytes');
|
|
512
|
+
console.log('Thumbnail:', client.getMultimediaThumbnailUrl(
|
|
513
|
+
'products',
|
|
514
|
+
'prod_123',
|
|
515
|
+
multimedia.id
|
|
516
|
+
));
|
|
517
|
+
```
|
|
518
|
+
|
|
519
|
+
**Supported File Types:**
|
|
520
|
+
- **Images**: JPEG, PNG, GIF, WebP, SVG
|
|
521
|
+
- **Videos**: MP4, WebM, AVI, MOV
|
|
522
|
+
- **Audio**: MP3, WAV, OGG, M4A
|
|
523
|
+
- **Documents**: PDF
|
|
524
|
+
|
|
525
|
+
**File Size Limit:** 100MB per file (default, configurable)
|
|
526
|
+
|
|
527
|
+
### List Multimedia
|
|
528
|
+
|
|
529
|
+
```typescript
|
|
530
|
+
const result = await client.listMultimedia(
|
|
531
|
+
'products',
|
|
532
|
+
'prod_123',
|
|
533
|
+
50, // limit
|
|
534
|
+
0 // offset
|
|
535
|
+
);
|
|
536
|
+
|
|
537
|
+
result.items.forEach(item => {
|
|
538
|
+
console.log(`${item.file_name} (${item.file_size} bytes)`);
|
|
539
|
+
});
|
|
540
|
+
```
|
|
541
|
+
|
|
542
|
+
### Get Multimedia Information
|
|
543
|
+
|
|
544
|
+
```typescript
|
|
545
|
+
const multimedia = await client.getMultimedia(
|
|
546
|
+
'products',
|
|
547
|
+
'prod_123',
|
|
548
|
+
'media_xyz789'
|
|
549
|
+
);
|
|
550
|
+
|
|
551
|
+
console.log('File:', multimedia.file_name);
|
|
552
|
+
console.log('Type:', multimedia.content_type);
|
|
553
|
+
console.log('Extracted text:', multimedia.extracted_text);
|
|
554
|
+
```
|
|
555
|
+
|
|
556
|
+
### Get Multimedia URLs
|
|
557
|
+
|
|
558
|
+
```typescript
|
|
559
|
+
// View URL (for display in browser)
|
|
560
|
+
const viewUrl = client.getMultimediaUrl(
|
|
561
|
+
'products',
|
|
562
|
+
'prod_123',
|
|
563
|
+
'media_xyz789'
|
|
564
|
+
);
|
|
565
|
+
|
|
566
|
+
// Download URL (forces download)
|
|
567
|
+
const downloadUrl = client.getMultimediaUrl(
|
|
568
|
+
'products',
|
|
569
|
+
'prod_123',
|
|
570
|
+
'media_xyz789',
|
|
571
|
+
true // download flag
|
|
572
|
+
);
|
|
573
|
+
|
|
574
|
+
// Thumbnail URL (for images/videos)
|
|
575
|
+
const thumbnailUrl = client.getMultimediaThumbnailUrl(
|
|
576
|
+
'products',
|
|
577
|
+
'prod_123',
|
|
578
|
+
'media_xyz789'
|
|
579
|
+
);
|
|
580
|
+
```
|
|
581
|
+
|
|
582
|
+
### Delete Multimedia
|
|
583
|
+
|
|
584
|
+
```typescript
|
|
585
|
+
await client.deleteMultimedia(
|
|
586
|
+
'products',
|
|
587
|
+
'prod_123',
|
|
588
|
+
'media_xyz789'
|
|
589
|
+
);
|
|
590
|
+
```
|
|
591
|
+
|
|
592
|
+
## Advanced Features
|
|
593
|
+
|
|
594
|
+
### Vector Operations
|
|
595
|
+
|
|
596
|
+
```typescript
|
|
597
|
+
// Generate embeddings
|
|
598
|
+
const embedding = await client.embed('High-quality mechanical keyboard');
|
|
599
|
+
// or batch
|
|
600
|
+
const embeddings = await client.embed([
|
|
601
|
+
'Laptop computer',
|
|
602
|
+
'Wireless mouse',
|
|
603
|
+
'Mechanical keyboard',
|
|
604
|
+
]);
|
|
605
|
+
|
|
606
|
+
// Vector similarity
|
|
607
|
+
const similarity = await client.cosineSimilarity(
|
|
608
|
+
embedding1,
|
|
609
|
+
embedding2
|
|
610
|
+
);
|
|
611
|
+
|
|
612
|
+
// Vector arithmetic
|
|
613
|
+
const sum = await client.vectorAdd(vec1, vec2);
|
|
614
|
+
const normalized = await client.normalizeVector(vec);
|
|
615
|
+
```
|
|
616
|
+
|
|
617
|
+
### Vector Search
|
|
618
|
+
|
|
619
|
+
```typescript
|
|
620
|
+
// K-nearest neighbors search
|
|
621
|
+
const knnResults = await client.knnSearch({
|
|
622
|
+
queryVector: embedding,
|
|
623
|
+
k: 10,
|
|
624
|
+
tableName: 'products',
|
|
625
|
+
vectorColumn: 'embedding',
|
|
626
|
+
metadataColumns: ['name', 'price'],
|
|
627
|
+
filter: { category: 'electronics' },
|
|
628
|
+
});
|
|
629
|
+
|
|
630
|
+
// Range search
|
|
631
|
+
const rangeResults = await client.rangeSearch({
|
|
632
|
+
queryVector: embedding,
|
|
633
|
+
threshold: 0.8,
|
|
634
|
+
tableName: 'products',
|
|
635
|
+
vectorColumn: 'embedding',
|
|
636
|
+
maxResults: 100,
|
|
637
|
+
});
|
|
638
|
+
```
|
|
639
|
+
|
|
640
|
+
### Collection Operations
|
|
641
|
+
|
|
642
|
+
```typescript
|
|
643
|
+
// Get collection reference
|
|
644
|
+
const products = await client.getCollection('products');
|
|
645
|
+
|
|
646
|
+
// Insert documents
|
|
647
|
+
await products.insert({
|
|
648
|
+
name: 'Laptop',
|
|
649
|
+
price: 1299.99,
|
|
650
|
+
category: 'Electronics',
|
|
651
|
+
});
|
|
652
|
+
|
|
653
|
+
// Search
|
|
654
|
+
const results = await products.search({
|
|
655
|
+
filter: { category: 'Electronics' },
|
|
656
|
+
topK: 10,
|
|
657
|
+
offset: 0,
|
|
658
|
+
});
|
|
659
|
+
|
|
660
|
+
// Vector search
|
|
661
|
+
const vectorResults = await products.vectorSearch({
|
|
662
|
+
vector: embedding,
|
|
663
|
+
topK: 5,
|
|
664
|
+
filter: { price: { $lt: 500 } },
|
|
665
|
+
});
|
|
666
|
+
```
|
|
667
|
+
|
|
668
|
+
### AutoML
|
|
669
|
+
|
|
670
|
+
```typescript
|
|
671
|
+
// Train a model
|
|
672
|
+
const model = await client.automl.train({
|
|
673
|
+
collection: 'sales_data',
|
|
674
|
+
target: 'revenue',
|
|
675
|
+
features: ['product_category', 'season', 'price'],
|
|
676
|
+
task: 'regression',
|
|
677
|
+
});
|
|
678
|
+
|
|
679
|
+
// Make predictions
|
|
680
|
+
const predictions = await model.predict({
|
|
681
|
+
product_category: 'electronics',
|
|
682
|
+
season: 'holiday',
|
|
683
|
+
price: 299.99,
|
|
684
|
+
});
|
|
685
|
+
```
|
|
686
|
+
|
|
687
|
+
### NLP Analysis
|
|
688
|
+
|
|
689
|
+
```typescript
|
|
690
|
+
// Analyze text
|
|
691
|
+
const analysis = await client.nlp.analyze({
|
|
692
|
+
text: 'This product exceeded my expectations. Highly recommend!',
|
|
693
|
+
tasks: ['sentiment', 'entities', 'summary'],
|
|
694
|
+
});
|
|
695
|
+
|
|
696
|
+
console.log(`Sentiment: ${analysis.sentiment.label}`);
|
|
697
|
+
console.log(`Entities:`, analysis.entities);
|
|
698
|
+
```
|
|
699
|
+
|
|
700
|
+
### Real-time Subscriptions
|
|
701
|
+
|
|
702
|
+
```typescript
|
|
703
|
+
// Subscribe to collection changes
|
|
704
|
+
const subscription = await products.subscribe({
|
|
705
|
+
filter: { price: { $lt: 100 } },
|
|
706
|
+
onChange: (event) => {
|
|
707
|
+
console.log(`${event.operation}: ${event.document.name}`);
|
|
708
|
+
},
|
|
709
|
+
});
|
|
710
|
+
|
|
711
|
+
// Unsubscribe
|
|
712
|
+
await subscription.close();
|
|
713
|
+
```
|
|
714
|
+
|
|
715
|
+
## Error Handling
|
|
716
|
+
|
|
717
|
+
The SDK provides comprehensive error handling with specific error types:
|
|
718
|
+
|
|
719
|
+
```typescript
|
|
720
|
+
import {
|
|
721
|
+
SynapCoresError,
|
|
722
|
+
ConnectionError,
|
|
723
|
+
AuthenticationError,
|
|
724
|
+
ValidationError,
|
|
725
|
+
NotFoundError,
|
|
726
|
+
ServerError,
|
|
727
|
+
RateLimitError,
|
|
728
|
+
SQLError,
|
|
729
|
+
VectorError,
|
|
730
|
+
} from '@synapcores/sdk';
|
|
731
|
+
|
|
732
|
+
try {
|
|
733
|
+
const result = await client.executeQuery({
|
|
734
|
+
sql: 'SELECT * FROM products',
|
|
735
|
+
parameters: [],
|
|
736
|
+
});
|
|
737
|
+
} catch (error) {
|
|
738
|
+
if (error instanceof AuthenticationError) {
|
|
739
|
+
console.error('Authentication failed:', error.message);
|
|
740
|
+
// Try refreshing token or re-login
|
|
741
|
+
await client.refreshToken();
|
|
742
|
+
} else if (error instanceof ValidationError) {
|
|
743
|
+
console.error('Validation error:', error.message);
|
|
744
|
+
console.error('Details:', error.details);
|
|
745
|
+
} else if (error instanceof NotFoundError) {
|
|
746
|
+
console.error('Resource not found:', error.message);
|
|
747
|
+
} else if (error instanceof RateLimitError) {
|
|
748
|
+
console.error('Rate limited. Retry after:', error.retryAfter, 'seconds');
|
|
749
|
+
} else if (error instanceof ConnectionError) {
|
|
750
|
+
console.error('Connection failed:', error.message);
|
|
751
|
+
} else if (error instanceof ServerError) {
|
|
752
|
+
console.error('Server error:', error.message);
|
|
753
|
+
} else if (error instanceof SynapCoresError) {
|
|
754
|
+
console.error('SynapCores error:', error.message);
|
|
755
|
+
console.error('Code:', error.code);
|
|
756
|
+
}
|
|
757
|
+
}
|
|
758
|
+
```
|
|
759
|
+
|
|
760
|
+
**Error Format (matching database integration guide):**
|
|
761
|
+
```typescript
|
|
762
|
+
{
|
|
763
|
+
error: {
|
|
764
|
+
code: "VALIDATION_ERROR",
|
|
765
|
+
message: "Invalid email format",
|
|
766
|
+
details: {
|
|
767
|
+
field: "email",
|
|
768
|
+
received: "invalid-email"
|
|
769
|
+
},
|
|
770
|
+
timestamp: "2025-10-31T10:00:00Z",
|
|
771
|
+
requestId: "req_xyz789"
|
|
772
|
+
}
|
|
773
|
+
}
|
|
774
|
+
```
|
|
775
|
+
|
|
776
|
+
## Configuration
|
|
777
|
+
|
|
778
|
+
### Full Configuration Options
|
|
779
|
+
|
|
780
|
+
```typescript
|
|
781
|
+
const client = new SynapCores({
|
|
782
|
+
host: 'localhost', // Server host (default: 'localhost')
|
|
783
|
+
port: 8080, // Server port (default: 8080)
|
|
784
|
+
apiKey: 'ak_prod_...', // API key (optional, use with X-API-Key header)
|
|
785
|
+
jwtToken: 'eyJhbGc...', // JWT token (optional, use with Bearer header)
|
|
786
|
+
useHttps: false, // Use HTTPS (default: false)
|
|
787
|
+
timeout: 30000, // Request timeout in ms (default: 30000)
|
|
788
|
+
maxRetries: 3, // Max retry attempts (default: 3)
|
|
789
|
+
rejectUnauthorized: true, // Reject unauthorized SSL certs (default: true)
|
|
790
|
+
});
|
|
791
|
+
```
|
|
792
|
+
|
|
793
|
+
## Complete Example: Document Management SaaS
|
|
794
|
+
|
|
795
|
+
Here's a complete example demonstrating a document management workflow:
|
|
796
|
+
|
|
797
|
+
```typescript
|
|
798
|
+
import { SynapCores } from '@synapcores/sdk';
|
|
799
|
+
import * as fs from 'fs';
|
|
800
|
+
|
|
801
|
+
async function documentManagementExample() {
|
|
802
|
+
// 1. Initialize client
|
|
803
|
+
const client = new SynapCores({
|
|
804
|
+
host: 'localhost',
|
|
805
|
+
port: 8080,
|
|
806
|
+
});
|
|
807
|
+
|
|
808
|
+
// 2. Register and login
|
|
809
|
+
const user = await client.registerUser({
|
|
810
|
+
username: 'acme_admin',
|
|
811
|
+
email: 'admin@acme.com',
|
|
812
|
+
password: 'SecurePass123!',
|
|
813
|
+
});
|
|
814
|
+
|
|
815
|
+
if (user.is_active) {
|
|
816
|
+
await client.login({
|
|
817
|
+
username: 'acme_admin',
|
|
818
|
+
password: 'SecurePass123!',
|
|
819
|
+
});
|
|
820
|
+
}
|
|
821
|
+
|
|
822
|
+
// 3. Create API key for programmatic access
|
|
823
|
+
const apiKeyResult = await client.createAPIKey({
|
|
824
|
+
name: 'Production Integration',
|
|
825
|
+
permission: 'FullAccess',
|
|
826
|
+
expires_in_days: 90,
|
|
827
|
+
});
|
|
828
|
+
console.log('⚠️ Save API key:', apiKeyResult.raw_key);
|
|
829
|
+
|
|
830
|
+
// 4. Create document collection
|
|
831
|
+
const collection = await client.createCollectionWithSchema({
|
|
832
|
+
name: 'customer_documents',
|
|
833
|
+
description: 'Customer documents with AI-powered search',
|
|
834
|
+
schema: {
|
|
835
|
+
fields: [
|
|
836
|
+
{ name: 'customer_id', type: 'string', required: true },
|
|
837
|
+
{ name: 'document_name', type: 'string', required: true },
|
|
838
|
+
{ name: 'document_type', type: 'string', required: true },
|
|
839
|
+
{ name: 'content_text', type: 'string', required: false },
|
|
840
|
+
{ name: 'embedding', type: 'vector', required: false },
|
|
841
|
+
{ name: 'uploaded_at', type: 'date', required: true },
|
|
842
|
+
{ name: 'processed', type: 'boolean', required: true },
|
|
843
|
+
],
|
|
844
|
+
indexes: [
|
|
845
|
+
{ name: 'customer_idx', fields: ['customer_id'], type: 'btree' },
|
|
846
|
+
{ name: 'vector_idx', fields: ['embedding'], type: 'vector' },
|
|
847
|
+
],
|
|
848
|
+
},
|
|
849
|
+
});
|
|
850
|
+
|
|
851
|
+
// 5. Create document record
|
|
852
|
+
const docResult = await client.executeQuery({
|
|
853
|
+
sql: `
|
|
854
|
+
INSERT INTO customer_documents
|
|
855
|
+
(customer_id, document_name, document_type, uploaded_at, processed)
|
|
856
|
+
VALUES ($1, $2, $3, $4, $5)
|
|
857
|
+
RETURNING id
|
|
858
|
+
`,
|
|
859
|
+
parameters: [
|
|
860
|
+
'cust_123',
|
|
861
|
+
'contract.pdf',
|
|
862
|
+
'pdf',
|
|
863
|
+
new Date().toISOString(),
|
|
864
|
+
false,
|
|
865
|
+
],
|
|
866
|
+
});
|
|
867
|
+
const documentId = docResult.rows[0][0];
|
|
868
|
+
|
|
869
|
+
// 6. Upload PDF file
|
|
870
|
+
const pdfBuffer = fs.readFileSync('contract.pdf');
|
|
871
|
+
const multimedia = await client.uploadMultimedia(
|
|
872
|
+
'customer_documents',
|
|
873
|
+
documentId,
|
|
874
|
+
pdfBuffer,
|
|
875
|
+
{
|
|
876
|
+
customer_id: 'cust_123',
|
|
877
|
+
uploaded_by: 'admin',
|
|
878
|
+
document_type: 'pdf',
|
|
879
|
+
}
|
|
880
|
+
);
|
|
881
|
+
|
|
882
|
+
// 7. Extract text and generate embedding
|
|
883
|
+
await client.executeQuery({
|
|
884
|
+
sql: `
|
|
885
|
+
UPDATE customer_documents
|
|
886
|
+
SET
|
|
887
|
+
content_text = EXTRACT_TEXT($1),
|
|
888
|
+
embedding = EMBED(EXTRACT_TEXT($1), 'minilm'),
|
|
889
|
+
processed = true
|
|
890
|
+
WHERE id = $2
|
|
891
|
+
`,
|
|
892
|
+
parameters: [multimedia.id, documentId],
|
|
893
|
+
});
|
|
894
|
+
|
|
895
|
+
// 8. Semantic search
|
|
896
|
+
const searchResult = await client.executeQuery({
|
|
897
|
+
sql: `
|
|
898
|
+
SELECT
|
|
899
|
+
id,
|
|
900
|
+
customer_id,
|
|
901
|
+
document_name,
|
|
902
|
+
content_text,
|
|
903
|
+
COSINE_SIMILARITY(
|
|
904
|
+
embedding,
|
|
905
|
+
EMBED($1, 'minilm')
|
|
906
|
+
) as relevance
|
|
907
|
+
FROM customer_documents
|
|
908
|
+
WHERE embedding IS NOT NULL
|
|
909
|
+
AND processed = true
|
|
910
|
+
ORDER BY relevance DESC
|
|
911
|
+
LIMIT 10
|
|
912
|
+
`,
|
|
913
|
+
parameters: ['contract payment terms'],
|
|
914
|
+
});
|
|
915
|
+
|
|
916
|
+
console.log('Search results:', searchResult.rows);
|
|
917
|
+
}
|
|
918
|
+
|
|
919
|
+
documentManagementExample().catch(console.error);
|
|
920
|
+
```
|
|
921
|
+
|
|
922
|
+
## TypeScript Support
|
|
923
|
+
|
|
924
|
+
This SDK is written in TypeScript and provides complete type definitions:
|
|
925
|
+
|
|
926
|
+
```typescript
|
|
927
|
+
import {
|
|
928
|
+
SynapCores,
|
|
929
|
+
Collection,
|
|
930
|
+
Document,
|
|
931
|
+
SearchResult,
|
|
932
|
+
QueryResult,
|
|
933
|
+
RegisterRequest,
|
|
934
|
+
LoginRequest,
|
|
935
|
+
CreateAPIKeyRequest,
|
|
936
|
+
CreateCollectionRequest,
|
|
937
|
+
MultimediaInfo,
|
|
938
|
+
} from '@synapcores/sdk';
|
|
939
|
+
|
|
940
|
+
// All methods are fully typed
|
|
941
|
+
const createUser = async (
|
|
942
|
+
client: SynapCores,
|
|
943
|
+
request: RegisterRequest
|
|
944
|
+
): Promise<void> => {
|
|
945
|
+
const user = await client.registerUser(request);
|
|
946
|
+
console.log('User created:', user.id);
|
|
947
|
+
};
|
|
948
|
+
```
|
|
949
|
+
|
|
950
|
+
## Best Practices
|
|
951
|
+
|
|
952
|
+
### Security
|
|
953
|
+
|
|
954
|
+
1. **Never expose API keys** in client-side code or public repositories
|
|
955
|
+
2. **Use HTTPS** in production (never HTTP)
|
|
956
|
+
3. **Store tokens in sessionStorage** (not localStorage) for web apps
|
|
957
|
+
4. **Set API key expiration** for time-limited access
|
|
958
|
+
5. **Use ReadOnly permission** unless write access is required
|
|
959
|
+
6. **Monitor API key usage** regularly
|
|
960
|
+
7. **Revoke compromised keys** immediately
|
|
961
|
+
|
|
962
|
+
### Performance
|
|
963
|
+
|
|
964
|
+
1. **Use batch queries** for multiple operations
|
|
965
|
+
2. **Limit result sets** with `max_rows` parameter
|
|
966
|
+
3. **Create indexes** on frequently queried fields
|
|
967
|
+
4. **Use vector indexes** for similarity search
|
|
968
|
+
5. **Compress large files** before upload
|
|
969
|
+
6. **Implement pagination** for large datasets
|
|
970
|
+
|
|
971
|
+
### Error Handling
|
|
972
|
+
|
|
973
|
+
1. **Always handle errors** with try-catch
|
|
974
|
+
2. **Implement retry logic** for transient failures
|
|
975
|
+
3. **Use exponential backoff** for rate limits
|
|
976
|
+
4. **Handle network errors** gracefully
|
|
977
|
+
5. **Display loading states** during async operations
|
|
978
|
+
|
|
979
|
+
## Migration Guide
|
|
980
|
+
|
|
981
|
+
### From Legacy Methods to New Methods
|
|
982
|
+
|
|
983
|
+
```typescript
|
|
984
|
+
// OLD (still works but deprecated)
|
|
985
|
+
const result = await client.sql('SELECT * FROM products');
|
|
986
|
+
|
|
987
|
+
// NEW (recommended)
|
|
988
|
+
const result = await client.executeQuery({
|
|
989
|
+
sql: 'SELECT * FROM products',
|
|
990
|
+
parameters: [],
|
|
991
|
+
});
|
|
992
|
+
```
|
|
993
|
+
|
|
994
|
+
```typescript
|
|
995
|
+
// OLD
|
|
996
|
+
const collections = await client.listCollections(); // Returns string[]
|
|
997
|
+
|
|
998
|
+
// NEW
|
|
999
|
+
const result = await client.listCollectionsDetailed(); // Returns detailed info
|
|
1000
|
+
```
|
|
1001
|
+
|
|
1002
|
+
## Documentation
|
|
1003
|
+
|
|
1004
|
+
For detailed API documentation and the complete integration guide, visit:
|
|
1005
|
+
- **Database Integration Guide**: See `databaseintegrationguide.md`
|
|
1006
|
+
- **API Documentation**: [https://docs.synapcores.ai](https://docs.synapcores.ai)
|
|
1007
|
+
|
|
1008
|
+
## License
|
|
1009
|
+
|
|
1010
|
+
MIT License - see LICENSE file for details.
|
|
1011
|
+
|