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 +314 -75
- package/dist/crypto.d.ts +19 -2
- package/dist/crypto.d.ts.map +1 -1
- package/dist/crypto.js +91 -9
- package/dist/crypto.js.map +1 -1
- package/dist/{endee.d.ts → endee.class.d.ts} +4 -6
- package/dist/endee.class.d.ts.map +1 -0
- package/dist/{endee.js → endee.class.js} +38 -14
- package/dist/endee.class.js.map +1 -0
- package/dist/exceptions.js +15 -15
- package/dist/{indexClient.d.ts → index.class.d.ts} +7 -11
- package/dist/index.class.d.ts.map +1 -0
- package/dist/{indexClient.js → index.class.js} +98 -45
- package/dist/index.class.js.map +1 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/types/index.d.ts +33 -11
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +8 -1
- package/dist/types/index.js.map +1 -1
- package/dist/userClient.d.ts.map +1 -1
- package/dist/userClient.js +35 -35
- package/dist/userClient.js.map +1 -1
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +14 -4
- package/dist/utils.js.map +1 -1
- package/package.json +28 -7
- package/dist/endee.d.ts.map +0 -1
- package/dist/endee.js.map +0 -1
- package/dist/indexClient.d.ts.map +0 -1
- package/dist/indexClient.js.map +0 -1
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
|
-
|
|
42
|
+
const client = new Endee('your-auth-token');
|
|
43
|
+
```
|
|
24
44
|
|
|
25
|
-
|
|
26
|
-
const endee = new Endee("user_id:api_token:region");
|
|
45
|
+
### Setting a Custom Base URL
|
|
27
46
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
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
|
-
|
|
36
|
-
|
|
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:
|
|
42
|
-
vector: [0.1, 0.2, 0.3 /* ... */],
|
|
43
|
-
meta: {
|
|
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
|
-
|
|
141
|
+
The `index.query()` method performs a similarity search.
|
|
142
|
+
|
|
143
|
+
```typescript
|
|
48
144
|
const results = await index.query({
|
|
49
|
-
vector: [0.
|
|
50
|
-
topK:
|
|
51
|
-
|
|
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
|
-
|
|
156
|
+
**Query Parameters:**
|
|
62
157
|
|
|
63
|
-
|
|
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
|
-
|
|
66
|
-
import { Endee } from "endee";
|
|
165
|
+
## Filtered Querying
|
|
67
166
|
|
|
68
|
-
|
|
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
|
-
|
|
72
|
-
const
|
|
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
|
-
###
|
|
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
|
-
|
|
79
|
-
const indexes = await endee.listIndexes();
|
|
197
|
+
const index = await client.getIndex('hybrid_index');
|
|
80
198
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
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
|
-
|
|
92
|
-
|
|
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
|
-
|
|
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
|
-
|
|
99
|
-
const index = await endee.getIndex("my_index");
|
|
314
|
+
import { Endee, Precision } from 'endee';
|
|
100
315
|
|
|
101
|
-
//
|
|
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:
|
|
105
|
-
vector: [/* ... */],
|
|
106
|
-
meta: { title:
|
|
107
|
-
filter: {
|
|
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:
|
|
111
|
-
vector: [/* ... */],
|
|
112
|
-
|
|
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
|
|
346
|
+
// Query the index
|
|
117
347
|
const results = await index.query({
|
|
118
|
-
vector: [/* ... */],
|
|
119
|
-
topK: 5,
|
|
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
|
-
|
|
126
|
-
|
|
127
|
-
|
|
352
|
+
for (const item of results) {
|
|
353
|
+
console.log(`ID: ${item.id}, Similarity: ${item.similarity}`);
|
|
354
|
+
}
|
|
355
|
+
```
|
|
128
356
|
|
|
129
|
-
|
|
130
|
-
const vector = await index.getVector("vec1");
|
|
357
|
+
## API Reference
|
|
131
358
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
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
|
-
|
|
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
|
|
5
|
-
export declare function
|
|
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
|
package/dist/crypto.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"crypto.d.ts","sourceRoot":"","sources":["../src/crypto.ts"],"names":[],"mappings":"AAAA;;GAEG;
|
|
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
|
-
|
|
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
|
-
|
|
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 ===
|
|
26
|
+
if (typeof compressed === 'object' &&
|
|
27
|
+
!Buffer.isBuffer(compressed) &&
|
|
28
|
+
!(compressed instanceof Uint8Array)) {
|
|
15
29
|
return compressed;
|
|
16
30
|
}
|
|
17
|
-
if (typeof compressed ===
|
|
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
|
-
|
|
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
|
|
31
|
-
|
|
32
|
-
|
|
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
|
package/dist/crypto.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"crypto.js","sourceRoot":"","sources":["../src/crypto.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"crypto.js","sourceRoot":"","sources":["../src/crypto.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,16 +1,14 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
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"}
|