endee 1.0.0-beta.1 → 1.0.0-dev.2

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 CHANGED
@@ -1,16 +1,22 @@
1
1
  # Endee - TypeScript Vector Database Client
2
2
 
3
- Endee is a TypeScript client for a vector database designed for maximum speed and efficiency. This package provides full type safety, modern ES module support, and optimized code for rapid Approximate Nearest Neighbor (ANN) searches on vector data.
3
+ Endee is a TypeScript client for a local vector database designed for maximum speed and efficiency. This package provides full type safety, modern ES module support, and optimized code for rapid Approximate Nearest Neighbor (ANN) searches on vector data.
4
4
 
5
5
  ## Key Features
6
6
 
7
7
  - **TypeScript First**: Full type safety and IntelliSense support
8
8
  - **Fast ANN Searches**: Efficient similarity searches on vector data
9
9
  - **Multiple Distance Metrics**: Support for cosine, L2, and inner product distance metrics
10
+ - **Hybrid Indexes**: Support for dense vectors, sparse vectors, and hybrid (dense + sparse) searches
10
11
  - **Metadata Support**: Attach and search with metadata and filters
11
12
  - **High Performance**: Optimized for speed and efficiency
12
13
  - **Modern ES Modules**: Native ES module support with proper tree-shaking
13
14
 
15
+ ## Requirements
16
+
17
+ - Node.js >= 18.0.0
18
+ - Endee Local server running (see [Quick Start](https://docs.endee.io/quick-start))
19
+
14
20
  ## Installation
15
21
 
16
22
  ```bash
@@ -19,120 +25,357 @@ npm install endee
19
25
 
20
26
  ## Quick Start
21
27
 
28
+ ### Initialize the Client
29
+
30
+ The Endee client connects to your local server (defaults to `http://127.0.0.1:8080/api/v1`):
31
+
32
+ ```typescript
33
+ import { Endee, Precision } from 'endee';
34
+
35
+ // Connect to local Endee server (defaults to localhost:8080)
36
+ const client = new Endee();
37
+ ```
38
+
39
+ **Using Authentication?** If your server has `NDD_AUTH_TOKEN` set, pass the same token when initializing:
40
+
22
41
  ```typescript
23
- import { Endee } from "endee";
42
+ const client = new Endee('your-auth-token');
43
+ ```
24
44
 
25
- // Initialize client with your API token
26
- const endee = new Endee("user_id:api_token:region");
45
+ ### Setting a Custom Base URL
27
46
 
28
- // Create a new index
29
- await endee.createIndex({
30
- name: "my_vectors",
31
- dimension: 1536, // Your vector dimension
32
- spaceType: "cosine" // Distance metric (cosine, l2, ip)
47
+ If your server runs on a different port, use `setBaseUrl()`:
48
+
49
+ ```typescript
50
+ const client = new Endee();
51
+
52
+ // Set custom base URL for non-default port
53
+ client.setBaseUrl('http://0.0.0.0:8081/api/v1');
54
+ ```
55
+
56
+ ### Create a Dense Index
57
+
58
+ ```typescript
59
+ import { Precision } from 'endee';
60
+
61
+ await client.createIndex({
62
+ name: 'my_vectors',
63
+ dimension: 384,
64
+ spaceType: 'cosine',
65
+ precision: Precision.INT8D,
33
66
  });
67
+ ```
68
+
69
+ **Dense Index Parameters:**
70
+
71
+ | Parameter | Description |
72
+ |-----------|-------------|
73
+ | `name` | Unique name for your index |
74
+ | `dimension` | Vector dimensionality (must match your embedding model's output) |
75
+ | `spaceType` | Distance metric - `"cosine"`, `"l2"`, or `"ip"` (inner product) |
76
+ | `M` | Graph connectivity - higher values increase recall but use more memory (default: 16) |
77
+ | `efCon` | Construction-time parameter - higher values improve index quality (default: 128) |
78
+ | `precision` | Quantization precision (default: `Precision.INT8D`) |
79
+
80
+ ### Create a Hybrid Index
81
+
82
+ Hybrid indexes combine dense vector search with sparse vector search. Add the `sparseDimension` parameter:
83
+
84
+ ```typescript
85
+ await client.createIndex({
86
+ name: 'hybrid_index',
87
+ dimension: 384, // Dense vector dimension
88
+ sparseDimension: 30000, // Sparse vector dimension (vocabulary size)
89
+ spaceType: 'cosine',
90
+ precision: Precision.INT8D,
91
+ });
92
+ ```
93
+
94
+ ### List and Access Indexes
34
95
 
35
- // Get index reference
36
- const index = await endee.getIndex("my_vectors");
96
+ ```typescript
97
+ // List all indexes
98
+ const indexes = await client.listIndexes();
99
+
100
+ // Get reference to an existing index
101
+ const index = await client.getIndex('my_vectors');
102
+
103
+ // Delete an index
104
+ await client.deleteIndex('my_vectors');
105
+ ```
106
+
107
+ ## Upserting Vectors
108
+
109
+ The `index.upsert()` method adds or updates vectors in an existing index.
110
+
111
+ ```typescript
112
+ const index = await client.getIndex('my_index');
37
113
 
38
- // Insert vectors
39
114
  await index.upsert([
40
115
  {
41
- id: "doc1",
42
- vector: [0.1, 0.2, 0.3 /* ... */], // Your vector data
43
- meta: { text: "Example document", category: "reference" },
116
+ id: 'vec1',
117
+ vector: [0.1, 0.2, 0.3 /* ... */],
118
+ meta: { title: 'First document' },
119
+ filter: { category: 'tech' },
120
+ },
121
+ {
122
+ id: 'vec2',
123
+ vector: [0.3, 0.4, 0.5 /* ... */],
124
+ meta: { title: 'Second document' },
125
+ filter: { category: 'science' },
44
126
  },
45
127
  ]);
128
+ ```
129
+
130
+ **Vector Object Fields:**
131
+
132
+ | Field | Required | Description |
133
+ |-------|----------|-------------|
134
+ | `id` | Yes | Unique identifier for the vector |
135
+ | `vector` | Yes | Array of floats representing the embedding |
136
+ | `meta` | No | Arbitrary metadata object |
137
+ | `filter` | No | Key-value pairs for filtering during queries |
138
+
139
+ ## Querying the Index
46
140
 
47
- // Query similar vectors
141
+ The `index.query()` method performs a similarity search.
142
+
143
+ ```typescript
48
144
  const results = await index.query({
49
- vector: [0.2, 0.3, 0.4 /* ... */], // Query vector
50
- topK: 10,
51
- filter: { category: { eq: "reference" } }, // Optional filter
145
+ vector: [0.15, 0.25 /* ... */],
146
+ topK: 5,
147
+ ef: 128,
148
+ includeVectors: true,
52
149
  });
53
150
 
54
- // Process results
55
151
  for (const item of results) {
56
152
  console.log(`ID: ${item.id}, Similarity: ${item.similarity}`);
57
- console.log(`Metadata:`, item.meta);
58
153
  }
59
154
  ```
60
155
 
61
- ## Basic Usage
156
+ **Query Parameters:**
62
157
 
63
- ### Initializing the Client
158
+ | Parameter | Description |
159
+ |-----------|-------------|
160
+ | `vector` | Query vector (must match index dimension) |
161
+ | `topK` | Number of results to return (default: 10, max: 512) |
162
+ | `ef` | Search quality parameter (default: 128, max: 1024) |
163
+ | `includeVectors` | Include vector data in results (default: false) |
64
164
 
65
- ```typescript
66
- import { Endee } from "endee";
165
+ ## Filtered Querying
67
166
 
68
- // Production with specific region
69
- const endee = new Endee("user_id:api_token:region");
167
+ Use the `filter` parameter to restrict results. All filters are combined with **logical AND**.
70
168
 
71
- // Local development (defaults to http://127.0.0.1:8080/api/v1)
72
- const endee = new Endee();
169
+ ```typescript
170
+ const results = await index.query({
171
+ vector: [0.15, 0.25 /* ... */],
172
+ topK: 5,
173
+ filter: [
174
+ { category: { $eq: 'tech' } },
175
+ { score: { $range: [80, 100] } },
176
+ ],
177
+ });
73
178
  ```
74
179
 
75
- ### Managing Indexes
180
+ ### Filtering Operators
181
+
182
+ | Operator | Description | Example |
183
+ |----------|-------------|---------|
184
+ | `$eq` | Exact match | `{ status: { $eq: 'published' } }` |
185
+ | `$in` | Match any in list | `{ tags: { $in: ['ai', 'ml'] } }` |
186
+ | `$range` | Numeric range (inclusive) | `{ score: { $range: [70, 95] } }` |
187
+
188
+ > **Note:** The `$range` operator supports values within **[0 - 999]**. Normalize larger values before upserting.
189
+
190
+ ## Hybrid Search
191
+
192
+ ### Upserting Hybrid Vectors
193
+
194
+ Provide both dense vectors and sparse representations:
76
195
 
77
196
  ```typescript
78
- // List all indexes
79
- const indexes = await endee.listIndexes();
197
+ const index = await client.getIndex('hybrid_index');
80
198
 
81
- // Create an index with custom parameters
82
- await endee.createIndex({
83
- name: "my_custom_index",
84
- dimension: 384,
85
- spaceType: "l2", // space type
86
- M: 32, // M: Graph connectivity parameter
87
- efCon: 200, // efCon: Construction-time parameter
88
- useFp16: true // useFp16: Use half-precision for storage optimization
199
+ await index.upsert([
200
+ {
201
+ id: 'doc1',
202
+ vector: [0.1, 0.2 /* ... */], // Dense vector
203
+ sparseIndices: [10, 50, 200], // Non-zero term positions
204
+ sparseValues: [0.8, 0.5, 0.3], // Weights for each position
205
+ meta: { title: 'Document 1' },
206
+ },
207
+ {
208
+ id: 'doc2',
209
+ vector: [0.3, 0.4 /* ... */],
210
+ sparseIndices: [15, 100, 500],
211
+ sparseValues: [0.9, 0.4, 0.6],
212
+ meta: { title: 'Document 2' },
213
+ },
214
+ ]);
215
+ ```
216
+
217
+ **Hybrid Vector Fields:**
218
+
219
+ | Field | Required | Description |
220
+ |-------|----------|-------------|
221
+ | `id` | Yes | Unique identifier |
222
+ | `vector` | Yes | Dense embedding vector |
223
+ | `sparseIndices` | Yes (hybrid) | Non-zero term positions in sparse vector |
224
+ | `sparseValues` | Yes (hybrid) | Weights for each sparse index |
225
+ | `meta` | No | Metadata dictionary |
226
+ | `filter` | No | Filter fields |
227
+
228
+ > **Important:** `sparseIndices` and `sparseValues` must have the same length. Values in `sparseIndices` must be within `[0, sparseDimension)`.
229
+
230
+ ### Querying Hybrid Index
231
+
232
+ Provide both dense and sparse query vectors:
233
+
234
+ ```typescript
235
+ const results = await index.query({
236
+ vector: [0.15, 0.25 /* ... */], // Dense query
237
+ sparseIndices: [10, 100, 300], // Sparse query positions
238
+ sparseValues: [0.7, 0.5, 0.4], // Sparse query weights
239
+ topK: 5,
89
240
  });
90
241
 
91
- // Delete an index
92
- await endee.deleteIndex("my_index");
242
+ for (const item of results) {
243
+ console.log(`ID: ${item.id}, Similarity: ${item.similarity}`);
244
+ }
245
+ ```
246
+
247
+ You can also query with:
248
+ - **Dense only**: Provide only `vector`
249
+ - **Sparse only**: Provide only `sparseIndices` and `sparseValues`
250
+ - **Hybrid**: Provide all three for combined results
251
+
252
+ ## Deletion Methods
253
+
254
+ ### Delete by ID
255
+ Delete vector with a specifc vector id.
256
+ ```typescript
257
+ await index.deleteVector('vec1');
258
+ ```
259
+ ### Delete by Filter
260
+ Delete all vectors matching specific filters.
261
+ ```typescript
262
+ await index.deleteWithFilter([{'category': {'$eq' : 'tech'}}]);
263
+ ```
264
+
265
+ ### Delete Index
266
+ Delete an entire Index.
267
+ ```typescript
268
+ await client.deleteIndex('my_index');
269
+ ```
270
+
271
+ > **Warning:** Deletion operations are **irreversible**.
272
+
273
+ ## Additional Operations
274
+
275
+ ### Get Vector by ID
276
+
277
+ ```typescript
278
+ const vector = await index.getVector('vec1');
279
+ ```
280
+
281
+ ### Describe Index
282
+
283
+ ```typescript
284
+ const info = index.describe();
285
+ console.log(info);
286
+ // { name, spaceType, dimension, sparseDimension, isHybrid, count, precision, M }
287
+ ```
288
+
289
+ ## Precision Options
290
+
291
+ Endee supports different quantization precision levels:
292
+
293
+ ```typescript
294
+ import { Precision } from 'endee';
295
+
296
+ Precision.BINARY; // Binary quantization (1-bit) - smallest storage, fastest search
297
+ Precision.INT8D; // 8-bit integer quantization (default) - balanced performance
298
+ Precision.INT16D; // 16-bit integer quantization - higher precision
299
+ Precision.FLOAT16; // 16-bit floating point - good balance
300
+ Precision.FLOAT32; // 32-bit floating point - highest precision
93
301
  ```
94
302
 
95
- ### Working with Vectors
303
+ **Choosing Precision:**
304
+
305
+ - `BINARY`: Best for very large datasets where speed and storage are critical
306
+ - `INT8D` (default): Recommended for most use cases - good balance of accuracy and performance
307
+ - `INT16D`: When you need better accuracy than INT8D but less storage than FLOAT32
308
+ - `FLOAT16`: Good compromise between precision and storage for embeddings
309
+ - `FLOAT32`: When you need maximum precision and storage is not a concern
310
+
311
+ ## Complete Example
96
312
 
97
313
  ```typescript
98
- // Get index reference
99
- const index = await endee.getIndex("my_index");
314
+ import { Endee, Precision } from 'endee';
100
315
 
101
- // Insert multiple vectors in a batch
316
+ // Initialize client
317
+ const client = new Endee();
318
+
319
+ // Create a dense index
320
+ await client.createIndex({
321
+ name: 'documents',
322
+ dimension: 384,
323
+ spaceType: 'cosine',
324
+ precision: Precision.INT8D,
325
+ });
326
+
327
+ // Get the index
328
+ const index = await client.getIndex('documents');
329
+
330
+ // Add vectors
102
331
  await index.upsert([
103
332
  {
104
- id: "vec1",
105
- vector: [/* ... */], // Your vector
106
- meta: { title: "First document" },
107
- filter: { tags: "important" },
333
+ id: 'doc1',
334
+ vector: [0.1, 0.2 /* ... 384 dimensions */],
335
+ meta: { title: 'First Document' },
336
+ filter: { category: 'tech' },
108
337
  },
109
338
  {
110
- id: "vec2",
111
- vector: [/* ... */], // Another vector
112
- filter: { visibility: "public" }, // Optional filter values
339
+ id: 'doc2',
340
+ vector: [0.3, 0.4 /* ... 384 dimensions */],
341
+ meta: { title: 'Second Document' },
342
+ filter: { category: 'science' },
113
343
  },
114
344
  ]);
115
345
 
116
- // Query with custom parameters
346
+ // Query the index
117
347
  const results = await index.query({
118
- vector: [/* ... */], // Query vector
119
- topK: 5, // Number of results to return
120
- filter: { tags: "important" }, // Filter for matching
121
- ef: 128, // Runtime parameter for search quality
122
- includeVectors: true, // Include vector data in results
348
+ vector: [0.15, 0.25 /* ... */],
349
+ topK: 5,
123
350
  });
124
351
 
125
- // Delete vectors
126
- await index.deleteVector("vec1");
127
- await index.deleteWithFilter({ visibility: "public" });
352
+ for (const item of results) {
353
+ console.log(`ID: ${item.id}, Similarity: ${item.similarity}`);
354
+ }
355
+ ```
128
356
 
129
- // Get a specific vector
130
- const vector = await index.getVector("vec1");
357
+ ## API Reference
131
358
 
132
- // Get index description
133
- const description = await index.describe();
134
- console.log(description);
135
- ```
359
+ ### Endee Class
360
+
361
+ | Method | Description |
362
+ |--------|-------------|
363
+ | `createIndex(options)` | Create a new index (add `sparseDimension` for hybrid) |
364
+ | `listIndexes()` | List all indexes |
365
+ | `deleteIndex(name)` | Delete an index |
366
+ | `getIndex(name)` | Get reference to an index |
367
+ | `setBaseUrl(url)` | Set a custom base URL |
368
+
369
+ ### Index Class
370
+
371
+ | Method | Description |
372
+ |--------|-------------|
373
+ | `upsert(vectors)` | Insert or update vectors |
374
+ | `query(options)` | Search for similar vectors |
375
+ | `deleteVector(id)` | Delete a vector by ID |
376
+ | `deleteWithFilter(filter)` | Delete vectors by Filter |
377
+ | `getVector(id)` | Get a vector by ID |
378
+ | `describe()` | Get index info |
136
379
 
137
380
  ## TypeScript Types
138
381
 
@@ -145,15 +388,11 @@ import type {
145
388
  QueryResult,
146
389
  CreateIndexOptions,
147
390
  IndexDescription,
148
- SpaceType
149
- } from "endee";
391
+ SpaceType,
392
+ Precision,
393
+ } from 'endee';
150
394
  ```
151
395
 
152
- ## Requirements
153
-
154
- - Node.js >= 18.0.0
155
- - TypeScript >= 5.0.0 (for development)
156
-
157
396
  ## License
158
397
 
159
398
  MIT
package/dist/crypto.d.ts CHANGED
@@ -1,6 +1,23 @@
1
1
  /**
2
2
  * Cryptographic utilities for Endee-DB
3
3
  */
4
- export declare function jsonZip(obj: Record<string, unknown> | null | undefined): Buffer;
5
- export declare function jsonUnzip(compressed: Buffer | Uint8Array | string | Record<string, unknown> | null | undefined): Record<string, unknown>;
4
+ export declare function getChecksum(key: string | null): number;
5
+ export declare function jsonZip(obj: Record<string, unknown> | null | undefined, key?: string | null): Buffer;
6
+ export declare function jsonUnzip(compressed: Buffer | Uint8Array | string | Record<string, unknown> | null | undefined, key?: string | null): Record<string, unknown>;
7
+ /**
8
+ * Encrypt data using AES-256 in CBC mode.
9
+ *
10
+ * @param data - The data to encrypt
11
+ * @param keyHex - A 256-bit hex key (64 hex characters)
12
+ * @returns IV + ciphertext (IV is prepended to the ciphertext)
13
+ */
14
+ export declare function aesEncrypt(data: Buffer, keyHex: string): Buffer;
15
+ /**
16
+ * Decrypt data using AES-256 in CBC mode.
17
+ *
18
+ * @param data - The encrypted data (IV + ciphertext)
19
+ * @param keyHex - A 256-bit hex key (64 hex characters)
20
+ * @returns The decrypted data
21
+ */
22
+ export declare function aesDecrypt(data: Buffer, keyHex: string): Buffer;
6
23
  //# sourceMappingURL=crypto.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"crypto.d.ts","sourceRoot":"","sources":["../src/crypto.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAI/E;AAED,wBAAgB,SAAS,CAAC,UAAU,EAAE,MAAM,GAAG,UAAU,GAAG,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAuBxI"}
1
+ {"version":3,"file":"crypto.d.ts","sourceRoot":"","sources":["../src/crypto.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAItD;AAED,wBAAgB,OAAO,CACrB,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GAAG,SAAS,EAC/C,GAAG,GAAE,MAAM,GAAG,IAAW,GACxB,MAAM,CAWR;AAED,wBAAgB,SAAS,CACvB,UAAU,EAAE,MAAM,GAAG,UAAU,GAAG,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GAAG,SAAS,EACrF,GAAG,GAAE,MAAM,GAAG,IAAW,GACxB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAgCzB;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAuB/D;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAsB/D"}
package/dist/crypto.js CHANGED
@@ -2,19 +2,33 @@
2
2
  * Cryptographic utilities for Endee-DB
3
3
  */
4
4
  import * as zlib from 'zlib';
5
- export function jsonZip(obj) {
5
+ import crypto from 'crypto';
6
+ export function getChecksum(key) {
7
+ // Convert last two characters of key to integer (hex)
8
+ if (key === null)
9
+ return -1;
10
+ return parseInt(key.slice(-2), 16);
11
+ }
12
+ export function jsonZip(obj, key = null) {
6
13
  if (!obj || Object.keys(obj).length === 0)
7
14
  return Buffer.alloc(0);
8
15
  const jsonStr = JSON.stringify(obj);
9
- return zlib.deflateSync(Buffer.from(jsonStr, 'utf-8'));
16
+ const compressed = zlib.deflateSync(Buffer.from(jsonStr, 'utf-8'));
17
+ // If key is provided, encrypt the compressed data
18
+ if (key) {
19
+ return aesEncrypt(compressed, key);
20
+ }
21
+ return compressed;
10
22
  }
11
- export function jsonUnzip(compressed) {
23
+ export function jsonUnzip(compressed, key = null) {
12
24
  if (!compressed || (compressed instanceof Buffer && compressed.length === 0))
13
25
  return {};
14
- if (typeof compressed === "object" && !Buffer.isBuffer(compressed) && !(compressed instanceof Uint8Array)) {
26
+ if (typeof compressed === 'object' &&
27
+ !Buffer.isBuffer(compressed) &&
28
+ !(compressed instanceof Uint8Array)) {
15
29
  return compressed;
16
30
  }
17
- if (typeof compressed === "string") {
31
+ if (typeof compressed === 'string') {
18
32
  try {
19
33
  return JSON.parse(compressed);
20
34
  }
@@ -23,13 +37,81 @@ export function jsonUnzip(compressed) {
23
37
  }
24
38
  }
25
39
  try {
26
- const buffer = Buffer.isBuffer(compressed) ? compressed : Buffer.from(compressed);
40
+ let buffer = Buffer.isBuffer(compressed) ? compressed : Buffer.from(compressed);
41
+ // If key is provided, decrypt the compressed data first
42
+ if (key) {
43
+ buffer = aesDecrypt(buffer, key);
44
+ }
27
45
  const decompressed = zlib.inflateSync(buffer);
28
46
  return JSON.parse(decompressed.toString('utf-8'));
29
47
  }
30
- catch (err) {
31
- const error = err;
32
- throw new Error(`Failed to decompress data: ${error.message}`);
48
+ catch {
49
+ return {};
50
+ }
51
+ }
52
+ /**
53
+ * Encrypt data using AES-256 in CBC mode.
54
+ *
55
+ * @param data - The data to encrypt
56
+ * @param keyHex - A 256-bit hex key (64 hex characters)
57
+ * @returns IV + ciphertext (IV is prepended to the ciphertext)
58
+ */
59
+ export function aesEncrypt(data, keyHex) {
60
+ // Convert hex key to bytes
61
+ const key = Buffer.from(keyHex, 'hex');
62
+ if (key.length !== 32) {
63
+ // 256 bits = 32 bytes
64
+ throw new Error('Key must be 256 bits (64 hex characters)');
65
+ }
66
+ // Generate a random 16-byte IV
67
+ const iv = crypto.randomBytes(16);
68
+ // Create cipher
69
+ const cipher = crypto.createCipheriv('aes-256-cbc', key, iv);
70
+ // Pad data to 16-byte boundary (PKCS7 padding)
71
+ const paddedData = pkcs7Pad(data);
72
+ // Encrypt
73
+ const ciphertext = Buffer.concat([cipher.update(paddedData), cipher.final()]);
74
+ // Return IV + ciphertext
75
+ return Buffer.concat([iv, ciphertext]);
76
+ }
77
+ /**
78
+ * Decrypt data using AES-256 in CBC mode.
79
+ *
80
+ * @param data - The encrypted data (IV + ciphertext)
81
+ * @param keyHex - A 256-bit hex key (64 hex characters)
82
+ * @returns The decrypted data
83
+ */
84
+ export function aesDecrypt(data, keyHex) {
85
+ // Convert hex key to bytes
86
+ const key = Buffer.from(keyHex, 'hex');
87
+ if (key.length !== 32) {
88
+ // 256 bits = 32 bytes
89
+ throw new Error('Key must be 256 bits (64 hex characters)');
33
90
  }
91
+ // Extract IV and ciphertext
92
+ const iv = data.subarray(0, 16);
93
+ const ciphertext = data.subarray(16);
94
+ // Create decipher
95
+ const decipher = crypto.createDecipheriv('aes-256-cbc', key, iv);
96
+ decipher.setAutoPadding(false); // We handle padding manually
97
+ // Decrypt
98
+ const paddedData = Buffer.concat([decipher.update(ciphertext), decipher.final()]);
99
+ // Remove PKCS7 padding
100
+ return pkcs7Unpad(paddedData);
101
+ }
102
+ /**
103
+ * Add PKCS7 padding to data.
104
+ */
105
+ function pkcs7Pad(data, blockSize = 16) {
106
+ const paddingLength = blockSize - (data.length % blockSize);
107
+ const padding = Buffer.alloc(paddingLength, paddingLength);
108
+ return Buffer.concat([data, padding]);
109
+ }
110
+ /**
111
+ * Remove PKCS7 padding from data.
112
+ */
113
+ function pkcs7Unpad(data) {
114
+ const paddingLength = data[data.length - 1];
115
+ return data.subarray(0, data.length - paddingLength);
34
116
  }
35
117
  //# sourceMappingURL=crypto.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"crypto.js","sourceRoot":"","sources":["../src/crypto.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAE7B,MAAM,UAAU,OAAO,CAAC,GAA+C;IACrE,IAAI,CAAC,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAClE,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;IACpC,OAAO,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;AACzD,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,UAAqF;IAC7G,IAAI,CAAC,UAAU,IAAI,CAAC,UAAU,YAAY,MAAM,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,CAAC;QAAE,OAAO,EAAE,CAAC;IAExF,IAAI,OAAO,UAAU,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,UAAU,YAAY,UAAU,CAAC,EAAE,CAAC;QAC1G,OAAO,UAAqC,CAAC;IAC/C,CAAC;IAED,IAAI,OAAO,UAAU,KAAK,QAAQ,EAAE,CAAC;QACnC,IAAI,CAAC;YACH,OAAO,IAAI,CAAC,KAAK,CAAC,UAAU,CAA4B,CAAC;QAC3D,CAAC;QAAC,MAAM,CAAC;YACP,iCAAiC;QACnC,CAAC;IACH,CAAC;IAED,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAClF,MAAM,YAAY,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QAC9C,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,QAAQ,CAAC,OAAO,CAAC,CAA4B,CAAC;IAC/E,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,KAAK,GAAG,GAAY,CAAC;QAC3B,MAAM,IAAI,KAAK,CAAC,8BAA8B,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;IACjE,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"crypto.js","sourceRoot":"","sources":["../src/crypto.ts"],"names":[],"mappings":"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"}
@@ -1,16 +1,14 @@
1
- /**
2
- * Main Endee client for Endee-DB
3
- */
4
- import { Index } from './indexClient.js';
5
- import type { CreateIndexOptions } from './types/index.js';
1
+ import { Index } from './index.class.js';
2
+ import { type CreateIndexOptions } from './types/index.js';
6
3
  export declare class Endee {
7
4
  private token;
8
5
  private baseUrl;
9
6
  private version;
10
7
  constructor(token?: string | null);
8
+ setBaseUrl(url: string): string;
11
9
  createIndex(options: CreateIndexOptions): Promise<string>;
12
10
  listIndexes(): Promise<unknown>;
13
11
  deleteIndex(name: string): Promise<string>;
14
12
  getIndex(name: string): Promise<Index>;
15
13
  }
16
- //# sourceMappingURL=endee.d.ts.map
14
+ //# sourceMappingURL=endee.class.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"endee.class.d.ts","sourceRoot":"","sources":["../src/endee.class.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAEzC,OAAO,EAAa,KAAK,kBAAkB,EAAkB,MAAM,kBAAkB,CAAC;AAEtF,qBAAa,KAAK;IAChB,OAAO,CAAC,KAAK,CAAgB;IAC7B,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,OAAO,CAAS;gBAEZ,KAAK,GAAE,MAAM,GAAG,IAAW;IAavC,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM;IAKzB,WAAW,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,MAAM,CAAC;IAkEzD,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IAgB/B,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAuB1C,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC;CAiC7C"}