@upstash/vector 0.1.0-alpha
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 +15 -0
- package/dist/index.d.mts +358 -0
- package/dist/index.d.ts +358 -0
- package/dist/index.js +5 -0
- package/dist/index.mjs +3 -0
- package/package.json +34 -0
package/README.md
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# vector-sdk
|
|
2
|
+
|
|
3
|
+
To install dependencies:
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
bun install
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
To run:
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
bun run index.ts
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
This project was created using `bun init` in bun v1.0.4. [Bun](https://bun.sh) is a fast all-in-one JavaScript runtime.
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,358 @@
|
|
|
1
|
+
type CacheSetting = "default" | "force-cache" | "no-cache" | "no-store" | "only-if-cached" | "reload";
|
|
2
|
+
type UpstashRequest = {
|
|
3
|
+
path?: string[];
|
|
4
|
+
/**
|
|
5
|
+
* Request body will be serialized to json
|
|
6
|
+
*/
|
|
7
|
+
body?: unknown;
|
|
8
|
+
};
|
|
9
|
+
type UpstashResponse<TResult> = {
|
|
10
|
+
result?: TResult;
|
|
11
|
+
error?: string;
|
|
12
|
+
};
|
|
13
|
+
interface Requester {
|
|
14
|
+
request: <TResult = unknown>(req: UpstashRequest) => Promise<UpstashResponse<TResult>>;
|
|
15
|
+
}
|
|
16
|
+
type RetryConfig = false | {
|
|
17
|
+
/**
|
|
18
|
+
* The number of retries to attempt before giving up.
|
|
19
|
+
*
|
|
20
|
+
* @default 5
|
|
21
|
+
*/
|
|
22
|
+
retries?: number;
|
|
23
|
+
/**
|
|
24
|
+
* A backoff function receives the current retry cound and returns a number in milliseconds to wait before retrying.
|
|
25
|
+
*
|
|
26
|
+
* @default
|
|
27
|
+
* ```ts
|
|
28
|
+
* Math.exp(retryCount) * 50
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
backoff?: (retryCount: number) => number;
|
|
32
|
+
};
|
|
33
|
+
type RequesterConfig = {
|
|
34
|
+
/**
|
|
35
|
+
* Configure the retry behaviour in case of network errors
|
|
36
|
+
*/
|
|
37
|
+
retry?: RetryConfig;
|
|
38
|
+
/**
|
|
39
|
+
* Configure the cache behaviour
|
|
40
|
+
* @default "no-store"
|
|
41
|
+
*/
|
|
42
|
+
cache?: CacheSetting;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
type Vector<TMetadata> = {
|
|
46
|
+
id: string;
|
|
47
|
+
vector: number[];
|
|
48
|
+
metadata?: TMetadata;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
declare const ENDPOINTS: readonly ["upsert", "query", "delete", "fetch", "reset", "range"];
|
|
52
|
+
type EndpointVariants = (typeof ENDPOINTS)[number];
|
|
53
|
+
/**
|
|
54
|
+
* TResult is the raw data returned from upstash, which may need to be transformed or parsed.
|
|
55
|
+
*/
|
|
56
|
+
declare class Command<TResult> {
|
|
57
|
+
readonly payload: Record<string, unknown> | unknown[];
|
|
58
|
+
readonly endpoint: EndpointVariants;
|
|
59
|
+
constructor(command: Record<string, unknown> | unknown[], endpoint: EndpointVariants);
|
|
60
|
+
/**
|
|
61
|
+
* Execute the command using a client.
|
|
62
|
+
*/
|
|
63
|
+
exec(client: Requester): Promise<TResult>;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Payload Type Definition for DeleteCommand
|
|
68
|
+
*
|
|
69
|
+
* This type defines the structure of the payload specifically used in the DeleteCommand.
|
|
70
|
+
*
|
|
71
|
+
* Properties:
|
|
72
|
+
* - ids: An array of numbers or strings representing the unique identifiers of the records to be deleted. These could be database IDs, unique keys, or any identifier used to uniquely refer to records in a specific context.
|
|
73
|
+
*
|
|
74
|
+
* Usage:
|
|
75
|
+
* This type is typically used in scenarios where a batch deletion of records is required. The `ids` array allows specifying multiple records for deletion in a single command, thereby facilitating efficient bulk operations.
|
|
76
|
+
*/
|
|
77
|
+
type Payload$4 = {
|
|
78
|
+
ids: number[] | string[];
|
|
79
|
+
};
|
|
80
|
+
/**
|
|
81
|
+
* DeleteCommand Class
|
|
82
|
+
*
|
|
83
|
+
* This class extends the generic Command class to implement the deletion functionality.
|
|
84
|
+
*
|
|
85
|
+
* Example:
|
|
86
|
+
* ```
|
|
87
|
+
* const deletionIds = [123, 456, 789];
|
|
88
|
+
* const deleteCommand = new DeleteCommand({ ids: deletionIds });
|
|
89
|
+
* // Use deleteCommand to execute the deletion operation
|
|
90
|
+
* ```
|
|
91
|
+
*/
|
|
92
|
+
declare class DeleteCommand extends Command<string> {
|
|
93
|
+
constructor(payload: Payload$4);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Payload Type Definition
|
|
98
|
+
*
|
|
99
|
+
* This type defines the structure of the payload used in a specific function or API call.
|
|
100
|
+
*
|
|
101
|
+
* Properties:
|
|
102
|
+
* - vector: An array of numbers representing a specific vector. This could be coordinates, data points, or any numerical representation depending on the context of the function or API.
|
|
103
|
+
*
|
|
104
|
+
* - topK: A number indicating the 'top K' elements to be considered or returned. In many contexts, this refers to the top 'K' results, items, or entities based on certain criteria like highest score, most relevance, etc.
|
|
105
|
+
*
|
|
106
|
+
* - includeVectors: A boolean value indicating whether to include the vector data in the response or output. Setting this to 'true' includes the vector data.
|
|
107
|
+
*
|
|
108
|
+
* Usage:
|
|
109
|
+
* This type is typically used when sending or receiving data where a combination of a numerical vector, a limit on the number of elements to consider, and an option to include or exclude detailed vector data is required.
|
|
110
|
+
*/
|
|
111
|
+
type Payload$3 = {
|
|
112
|
+
vector: number[];
|
|
113
|
+
topK: number;
|
|
114
|
+
includeVectors: boolean;
|
|
115
|
+
};
|
|
116
|
+
type QueryReturnResponse<TMetadata> = {
|
|
117
|
+
id: number | string;
|
|
118
|
+
score: number;
|
|
119
|
+
vector: number[];
|
|
120
|
+
metadata?: TMetadata;
|
|
121
|
+
};
|
|
122
|
+
/**
|
|
123
|
+
* QueryCommand Class
|
|
124
|
+
* Example:
|
|
125
|
+
* ```
|
|
126
|
+
* const payload = { vector: [1, 2, 3], topK: 5, includeVectors: true };
|
|
127
|
+
* const queryCommand = new QueryCommand(payload);
|
|
128
|
+
* // Use queryCommand for further operations
|
|
129
|
+
* ```
|
|
130
|
+
*/
|
|
131
|
+
declare class QueryCommand<TResult> extends Command<QueryReturnResponse<TResult>[]> {
|
|
132
|
+
constructor(payload: Payload$3);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Payload Type Definition for UpsertCommand
|
|
137
|
+
*
|
|
138
|
+
* This type defines the structure of the payload used in the UpsertCommand.
|
|
139
|
+
*
|
|
140
|
+
* Properties:
|
|
141
|
+
* - id: A number or string representing the unique identifier of the record to be upserted (inserted or updated).
|
|
142
|
+
* - vector: An array of numbers representing a specific vector. This could be coordinates, data points, or any numerical representation depending on the context.
|
|
143
|
+
* - metadata (optional): An object with key-value pairs, where the keys are strings and the values are of unknown type. This allows for flexible and additional data to be associated with the record being upserted.
|
|
144
|
+
*
|
|
145
|
+
* Usage:
|
|
146
|
+
* This type is primarily used in scenarios where a record needs to be inserted into a database if it does not already exist, or updated if it does. The flexibility of the metadata field allows for various additional information to be passed along with the primary data.
|
|
147
|
+
*/
|
|
148
|
+
type Payload$2 = {
|
|
149
|
+
id: number | string;
|
|
150
|
+
vector: number[];
|
|
151
|
+
metadata?: Record<string, unknown>;
|
|
152
|
+
};
|
|
153
|
+
/**
|
|
154
|
+
* UpsertCommand Class
|
|
155
|
+
*
|
|
156
|
+
* Extends the generic Command class to implement an upsert (insert or update) operation.
|
|
157
|
+
*
|
|
158
|
+
* Example:
|
|
159
|
+
* ```
|
|
160
|
+
* const upsertPayload = { id: 123, vector: [1.1, 2.2, 3.3], metadata: { key: "value" } };
|
|
161
|
+
* const upsertCommand = new UpsertCommand(upsertPayload);
|
|
162
|
+
* // Use upsertCommand to execute the upsert operation
|
|
163
|
+
* ```
|
|
164
|
+
*
|
|
165
|
+
* The UpsertCommand takes a payload containing the necessary data for the upsert operation. It supports handling both insertion and update of records based on the provided identifier.
|
|
166
|
+
*/
|
|
167
|
+
declare class UpsertCommand extends Command<string> {
|
|
168
|
+
constructor(payload: Payload$2);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Type definition for FetchCommand payload
|
|
173
|
+
*
|
|
174
|
+
* Properties:
|
|
175
|
+
* - ids: An array of numbers or strings, representing the unique identifiers of the records to be fetched.
|
|
176
|
+
* - includeMetadata (optional): A boolean flag indicating whether to include metadata in the response.
|
|
177
|
+
* - includeVectors (optional): A boolean flag indicating whether to include vector data in the response.
|
|
178
|
+
*
|
|
179
|
+
* The Payload type is used in the FetchCommand to specify the data required to fetch specific records.
|
|
180
|
+
* The optional flags allow for more detailed responses depending on the requirements.
|
|
181
|
+
*/
|
|
182
|
+
type Payload$1 = {
|
|
183
|
+
ids: number[] | string[];
|
|
184
|
+
includeMetadata?: boolean;
|
|
185
|
+
includeVectors?: boolean;
|
|
186
|
+
};
|
|
187
|
+
/**
|
|
188
|
+
* Generic response type for FetchCommand
|
|
189
|
+
*
|
|
190
|
+
* This type represents the possible return type of a FetchCommand. It can be either a Vector
|
|
191
|
+
* containing metadata or null, depending on whether the fetch operation was successful or not.
|
|
192
|
+
*/
|
|
193
|
+
type FetchReturnResponse<TMetadata> = Vector<TMetadata> | null;
|
|
194
|
+
/**
|
|
195
|
+
* FetchCommand Class
|
|
196
|
+
*
|
|
197
|
+
* Extends the generic Command class to implement a fetch operation.
|
|
198
|
+
*
|
|
199
|
+
* Example:
|
|
200
|
+
* ```
|
|
201
|
+
* const fetchPayload = { ids: [1, 2, 3], includeMetadata: true };
|
|
202
|
+
* const fetchCommand = new FetchCommand(fetchPayload);
|
|
203
|
+
* // Use fetchCommand to execute the fetch operation
|
|
204
|
+
* ```
|
|
205
|
+
*/
|
|
206
|
+
declare class FetchCommand<TMetadata> extends Command<FetchReturnResponse<TMetadata>[]> {
|
|
207
|
+
constructor(payload: Payload$1);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Type definition for RangeCommand payload
|
|
212
|
+
*
|
|
213
|
+
* This type specifies the structure of the payload used in the RangeCommand.
|
|
214
|
+
*
|
|
215
|
+
* Properties:
|
|
216
|
+
* - cursor: A number indicating the starting point for the range query.
|
|
217
|
+
* - limit: A number specifying the maximum number of records to be returned.
|
|
218
|
+
* - includeVectors (optional): A boolean flag indicating whether to include vector data in the response.
|
|
219
|
+
* - includeMetadata (optional): A boolean flag indicating whether to include metadata in the response.
|
|
220
|
+
*
|
|
221
|
+
* This payload type is used for range queries, where a set of records is retrieved based on the specified cursor
|
|
222
|
+
* and limit. The optional inclusion of vectors and metadata allows for flexible and detailed data retrieval.
|
|
223
|
+
*/
|
|
224
|
+
type Payload = {
|
|
225
|
+
cursor: number;
|
|
226
|
+
limit: number;
|
|
227
|
+
includeVectors?: boolean;
|
|
228
|
+
includeMetadata?: boolean;
|
|
229
|
+
};
|
|
230
|
+
/**
|
|
231
|
+
* Type definition for the response returned by RangeCommand
|
|
232
|
+
*
|
|
233
|
+
* This type outlines the structure of the response from a RangeCommand.
|
|
234
|
+
*
|
|
235
|
+
* Properties:
|
|
236
|
+
* - nextCursor: A string that indicates the cursor to be used for the next range query, facilitating pagination.
|
|
237
|
+
* - vectors: An array of Vector objects, each containing TMetadata, representing the data retrieved in the range query.
|
|
238
|
+
*
|
|
239
|
+
* The RangeReturnResponse type is crucial for operations that involve retrieving a range of records,
|
|
240
|
+
* providing both the data (in the form of vectors) and the means to continue fetching subsequent ranges (via nextCursor).
|
|
241
|
+
*/
|
|
242
|
+
type RangeReturnResponse<TMetadata> = {
|
|
243
|
+
nextCursor: string;
|
|
244
|
+
vectors: Vector<TMetadata>[];
|
|
245
|
+
};
|
|
246
|
+
/**
|
|
247
|
+
* RangeCommand Class
|
|
248
|
+
* Example:
|
|
249
|
+
* ```
|
|
250
|
+
* const rangePayload = { cursor: 0, limit: 10, includeVectors: true };
|
|
251
|
+
* const rangeCommand = new RangeCommand(rangePayload);
|
|
252
|
+
* // Use rangeCommand to execute the range query and retrieve data
|
|
253
|
+
* ```
|
|
254
|
+
*/
|
|
255
|
+
declare class RangeCommand<TResult> extends Command<RangeReturnResponse<TResult>> {
|
|
256
|
+
constructor(payload: Payload);
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
type CommandArgs<TCommand extends new (_args: any) => any> = ConstructorParameters<TCommand>[0];
|
|
260
|
+
/**
|
|
261
|
+
* Serverless vector client for upstash vector db.
|
|
262
|
+
*/
|
|
263
|
+
declare class Index$1 {
|
|
264
|
+
protected client: Requester;
|
|
265
|
+
/**
|
|
266
|
+
* Create a new vector db client
|
|
267
|
+
*
|
|
268
|
+
* @example
|
|
269
|
+
* ```typescript
|
|
270
|
+
* const index = new Index({
|
|
271
|
+
* url: "<UPSTASH_VECTOR_REST_URL>",
|
|
272
|
+
* token: "<UPSTASH_VECTOR_REST_TOKEN>",
|
|
273
|
+
* });
|
|
274
|
+
* ```
|
|
275
|
+
*/
|
|
276
|
+
constructor(client: Requester);
|
|
277
|
+
delete: (args: CommandArgs<typeof DeleteCommand>) => Promise<string>;
|
|
278
|
+
query: (args: CommandArgs<typeof QueryCommand>) => Promise<{
|
|
279
|
+
id: string | number;
|
|
280
|
+
score: number;
|
|
281
|
+
vector: number[];
|
|
282
|
+
metadata?: unknown;
|
|
283
|
+
}[]>;
|
|
284
|
+
upsert: (args: CommandArgs<typeof UpsertCommand>) => Promise<string>;
|
|
285
|
+
fetch: (args: CommandArgs<typeof FetchCommand>) => Promise<(Vector<unknown> | null)[]>;
|
|
286
|
+
reset: () => Promise<string>;
|
|
287
|
+
range: (args: CommandArgs<typeof RangeCommand>) => Promise<{
|
|
288
|
+
nextCursor: string;
|
|
289
|
+
vectors: Vector<unknown>[];
|
|
290
|
+
}>;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
/**
|
|
294
|
+
* Connection credentials for upstash vector.
|
|
295
|
+
* Get them from https://console.upstash.com/vector/<uuid>
|
|
296
|
+
*/
|
|
297
|
+
type VectorConfig = {
|
|
298
|
+
/**
|
|
299
|
+
* UPSTASH_VECTOR_REST_URL
|
|
300
|
+
*/
|
|
301
|
+
url: string;
|
|
302
|
+
/**
|
|
303
|
+
* UPSTASH_VECTOR_REST_TOKEN
|
|
304
|
+
*/
|
|
305
|
+
token: string;
|
|
306
|
+
/**
|
|
307
|
+
* The signal will allow aborting requests on the fly.
|
|
308
|
+
* For more check: https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal
|
|
309
|
+
*/
|
|
310
|
+
signal?: AbortSignal;
|
|
311
|
+
} & RequesterConfig;
|
|
312
|
+
/**
|
|
313
|
+
* Serverless vector client for upstash.
|
|
314
|
+
*/
|
|
315
|
+
declare class Index extends Index$1 {
|
|
316
|
+
/**
|
|
317
|
+
* Create a new vector client by providing the url and token
|
|
318
|
+
*
|
|
319
|
+
* @example
|
|
320
|
+
* ```typescript
|
|
321
|
+
* const vector = new Vector({
|
|
322
|
+
* url: "<UPSTASH_VECTOR_REST_URL>",
|
|
323
|
+
* token: "<UPSTASH_VECTOR_REST_TOKEN>",
|
|
324
|
+
* });
|
|
325
|
+
* ```
|
|
326
|
+
*/
|
|
327
|
+
constructor(config: VectorConfig);
|
|
328
|
+
/**
|
|
329
|
+
* Create a new vector client by providing a custom `Requester` implementation
|
|
330
|
+
*
|
|
331
|
+
* @example
|
|
332
|
+
* ```ts
|
|
333
|
+
*
|
|
334
|
+
* import { UpstashRequest, Requester, UpstashResponse, vector } from "@upstash/vector"
|
|
335
|
+
*
|
|
336
|
+
* const requester: Requester = {
|
|
337
|
+
* request: <TResult>(req: UpstashRequest): Promise<UpstashResponse<TResult>> => {
|
|
338
|
+
* // ...
|
|
339
|
+
* }
|
|
340
|
+
* }
|
|
341
|
+
*
|
|
342
|
+
* const vector = new vector(requester)
|
|
343
|
+
* ```
|
|
344
|
+
*/
|
|
345
|
+
constructor(requesters: Requester);
|
|
346
|
+
/**
|
|
347
|
+
* Create a new Upstash Vector instance from environment variables.
|
|
348
|
+
*
|
|
349
|
+
* Use this to automatically load connection secrets from your environment
|
|
350
|
+
* variables. For instance when using the Vercel integration.
|
|
351
|
+
*
|
|
352
|
+
* This tries to load `UPSTASH_VECTOR_REST_URL` and `UPSTASH_VECTOR_REST_TOKEN` from
|
|
353
|
+
* your environment using `process.env`.
|
|
354
|
+
*/
|
|
355
|
+
static fromEnv(config?: Omit<VectorConfig, "url" | "token">): Index;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
export { Index, type Requester, type UpstashRequest, type UpstashResponse, type VectorConfig };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,358 @@
|
|
|
1
|
+
type CacheSetting = "default" | "force-cache" | "no-cache" | "no-store" | "only-if-cached" | "reload";
|
|
2
|
+
type UpstashRequest = {
|
|
3
|
+
path?: string[];
|
|
4
|
+
/**
|
|
5
|
+
* Request body will be serialized to json
|
|
6
|
+
*/
|
|
7
|
+
body?: unknown;
|
|
8
|
+
};
|
|
9
|
+
type UpstashResponse<TResult> = {
|
|
10
|
+
result?: TResult;
|
|
11
|
+
error?: string;
|
|
12
|
+
};
|
|
13
|
+
interface Requester {
|
|
14
|
+
request: <TResult = unknown>(req: UpstashRequest) => Promise<UpstashResponse<TResult>>;
|
|
15
|
+
}
|
|
16
|
+
type RetryConfig = false | {
|
|
17
|
+
/**
|
|
18
|
+
* The number of retries to attempt before giving up.
|
|
19
|
+
*
|
|
20
|
+
* @default 5
|
|
21
|
+
*/
|
|
22
|
+
retries?: number;
|
|
23
|
+
/**
|
|
24
|
+
* A backoff function receives the current retry cound and returns a number in milliseconds to wait before retrying.
|
|
25
|
+
*
|
|
26
|
+
* @default
|
|
27
|
+
* ```ts
|
|
28
|
+
* Math.exp(retryCount) * 50
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
backoff?: (retryCount: number) => number;
|
|
32
|
+
};
|
|
33
|
+
type RequesterConfig = {
|
|
34
|
+
/**
|
|
35
|
+
* Configure the retry behaviour in case of network errors
|
|
36
|
+
*/
|
|
37
|
+
retry?: RetryConfig;
|
|
38
|
+
/**
|
|
39
|
+
* Configure the cache behaviour
|
|
40
|
+
* @default "no-store"
|
|
41
|
+
*/
|
|
42
|
+
cache?: CacheSetting;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
type Vector<TMetadata> = {
|
|
46
|
+
id: string;
|
|
47
|
+
vector: number[];
|
|
48
|
+
metadata?: TMetadata;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
declare const ENDPOINTS: readonly ["upsert", "query", "delete", "fetch", "reset", "range"];
|
|
52
|
+
type EndpointVariants = (typeof ENDPOINTS)[number];
|
|
53
|
+
/**
|
|
54
|
+
* TResult is the raw data returned from upstash, which may need to be transformed or parsed.
|
|
55
|
+
*/
|
|
56
|
+
declare class Command<TResult> {
|
|
57
|
+
readonly payload: Record<string, unknown> | unknown[];
|
|
58
|
+
readonly endpoint: EndpointVariants;
|
|
59
|
+
constructor(command: Record<string, unknown> | unknown[], endpoint: EndpointVariants);
|
|
60
|
+
/**
|
|
61
|
+
* Execute the command using a client.
|
|
62
|
+
*/
|
|
63
|
+
exec(client: Requester): Promise<TResult>;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Payload Type Definition for DeleteCommand
|
|
68
|
+
*
|
|
69
|
+
* This type defines the structure of the payload specifically used in the DeleteCommand.
|
|
70
|
+
*
|
|
71
|
+
* Properties:
|
|
72
|
+
* - ids: An array of numbers or strings representing the unique identifiers of the records to be deleted. These could be database IDs, unique keys, or any identifier used to uniquely refer to records in a specific context.
|
|
73
|
+
*
|
|
74
|
+
* Usage:
|
|
75
|
+
* This type is typically used in scenarios where a batch deletion of records is required. The `ids` array allows specifying multiple records for deletion in a single command, thereby facilitating efficient bulk operations.
|
|
76
|
+
*/
|
|
77
|
+
type Payload$4 = {
|
|
78
|
+
ids: number[] | string[];
|
|
79
|
+
};
|
|
80
|
+
/**
|
|
81
|
+
* DeleteCommand Class
|
|
82
|
+
*
|
|
83
|
+
* This class extends the generic Command class to implement the deletion functionality.
|
|
84
|
+
*
|
|
85
|
+
* Example:
|
|
86
|
+
* ```
|
|
87
|
+
* const deletionIds = [123, 456, 789];
|
|
88
|
+
* const deleteCommand = new DeleteCommand({ ids: deletionIds });
|
|
89
|
+
* // Use deleteCommand to execute the deletion operation
|
|
90
|
+
* ```
|
|
91
|
+
*/
|
|
92
|
+
declare class DeleteCommand extends Command<string> {
|
|
93
|
+
constructor(payload: Payload$4);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Payload Type Definition
|
|
98
|
+
*
|
|
99
|
+
* This type defines the structure of the payload used in a specific function or API call.
|
|
100
|
+
*
|
|
101
|
+
* Properties:
|
|
102
|
+
* - vector: An array of numbers representing a specific vector. This could be coordinates, data points, or any numerical representation depending on the context of the function or API.
|
|
103
|
+
*
|
|
104
|
+
* - topK: A number indicating the 'top K' elements to be considered or returned. In many contexts, this refers to the top 'K' results, items, or entities based on certain criteria like highest score, most relevance, etc.
|
|
105
|
+
*
|
|
106
|
+
* - includeVectors: A boolean value indicating whether to include the vector data in the response or output. Setting this to 'true' includes the vector data.
|
|
107
|
+
*
|
|
108
|
+
* Usage:
|
|
109
|
+
* This type is typically used when sending or receiving data where a combination of a numerical vector, a limit on the number of elements to consider, and an option to include or exclude detailed vector data is required.
|
|
110
|
+
*/
|
|
111
|
+
type Payload$3 = {
|
|
112
|
+
vector: number[];
|
|
113
|
+
topK: number;
|
|
114
|
+
includeVectors: boolean;
|
|
115
|
+
};
|
|
116
|
+
type QueryReturnResponse<TMetadata> = {
|
|
117
|
+
id: number | string;
|
|
118
|
+
score: number;
|
|
119
|
+
vector: number[];
|
|
120
|
+
metadata?: TMetadata;
|
|
121
|
+
};
|
|
122
|
+
/**
|
|
123
|
+
* QueryCommand Class
|
|
124
|
+
* Example:
|
|
125
|
+
* ```
|
|
126
|
+
* const payload = { vector: [1, 2, 3], topK: 5, includeVectors: true };
|
|
127
|
+
* const queryCommand = new QueryCommand(payload);
|
|
128
|
+
* // Use queryCommand for further operations
|
|
129
|
+
* ```
|
|
130
|
+
*/
|
|
131
|
+
declare class QueryCommand<TResult> extends Command<QueryReturnResponse<TResult>[]> {
|
|
132
|
+
constructor(payload: Payload$3);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Payload Type Definition for UpsertCommand
|
|
137
|
+
*
|
|
138
|
+
* This type defines the structure of the payload used in the UpsertCommand.
|
|
139
|
+
*
|
|
140
|
+
* Properties:
|
|
141
|
+
* - id: A number or string representing the unique identifier of the record to be upserted (inserted or updated).
|
|
142
|
+
* - vector: An array of numbers representing a specific vector. This could be coordinates, data points, or any numerical representation depending on the context.
|
|
143
|
+
* - metadata (optional): An object with key-value pairs, where the keys are strings and the values are of unknown type. This allows for flexible and additional data to be associated with the record being upserted.
|
|
144
|
+
*
|
|
145
|
+
* Usage:
|
|
146
|
+
* This type is primarily used in scenarios where a record needs to be inserted into a database if it does not already exist, or updated if it does. The flexibility of the metadata field allows for various additional information to be passed along with the primary data.
|
|
147
|
+
*/
|
|
148
|
+
type Payload$2 = {
|
|
149
|
+
id: number | string;
|
|
150
|
+
vector: number[];
|
|
151
|
+
metadata?: Record<string, unknown>;
|
|
152
|
+
};
|
|
153
|
+
/**
|
|
154
|
+
* UpsertCommand Class
|
|
155
|
+
*
|
|
156
|
+
* Extends the generic Command class to implement an upsert (insert or update) operation.
|
|
157
|
+
*
|
|
158
|
+
* Example:
|
|
159
|
+
* ```
|
|
160
|
+
* const upsertPayload = { id: 123, vector: [1.1, 2.2, 3.3], metadata: { key: "value" } };
|
|
161
|
+
* const upsertCommand = new UpsertCommand(upsertPayload);
|
|
162
|
+
* // Use upsertCommand to execute the upsert operation
|
|
163
|
+
* ```
|
|
164
|
+
*
|
|
165
|
+
* The UpsertCommand takes a payload containing the necessary data for the upsert operation. It supports handling both insertion and update of records based on the provided identifier.
|
|
166
|
+
*/
|
|
167
|
+
declare class UpsertCommand extends Command<string> {
|
|
168
|
+
constructor(payload: Payload$2);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Type definition for FetchCommand payload
|
|
173
|
+
*
|
|
174
|
+
* Properties:
|
|
175
|
+
* - ids: An array of numbers or strings, representing the unique identifiers of the records to be fetched.
|
|
176
|
+
* - includeMetadata (optional): A boolean flag indicating whether to include metadata in the response.
|
|
177
|
+
* - includeVectors (optional): A boolean flag indicating whether to include vector data in the response.
|
|
178
|
+
*
|
|
179
|
+
* The Payload type is used in the FetchCommand to specify the data required to fetch specific records.
|
|
180
|
+
* The optional flags allow for more detailed responses depending on the requirements.
|
|
181
|
+
*/
|
|
182
|
+
type Payload$1 = {
|
|
183
|
+
ids: number[] | string[];
|
|
184
|
+
includeMetadata?: boolean;
|
|
185
|
+
includeVectors?: boolean;
|
|
186
|
+
};
|
|
187
|
+
/**
|
|
188
|
+
* Generic response type for FetchCommand
|
|
189
|
+
*
|
|
190
|
+
* This type represents the possible return type of a FetchCommand. It can be either a Vector
|
|
191
|
+
* containing metadata or null, depending on whether the fetch operation was successful or not.
|
|
192
|
+
*/
|
|
193
|
+
type FetchReturnResponse<TMetadata> = Vector<TMetadata> | null;
|
|
194
|
+
/**
|
|
195
|
+
* FetchCommand Class
|
|
196
|
+
*
|
|
197
|
+
* Extends the generic Command class to implement a fetch operation.
|
|
198
|
+
*
|
|
199
|
+
* Example:
|
|
200
|
+
* ```
|
|
201
|
+
* const fetchPayload = { ids: [1, 2, 3], includeMetadata: true };
|
|
202
|
+
* const fetchCommand = new FetchCommand(fetchPayload);
|
|
203
|
+
* // Use fetchCommand to execute the fetch operation
|
|
204
|
+
* ```
|
|
205
|
+
*/
|
|
206
|
+
declare class FetchCommand<TMetadata> extends Command<FetchReturnResponse<TMetadata>[]> {
|
|
207
|
+
constructor(payload: Payload$1);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Type definition for RangeCommand payload
|
|
212
|
+
*
|
|
213
|
+
* This type specifies the structure of the payload used in the RangeCommand.
|
|
214
|
+
*
|
|
215
|
+
* Properties:
|
|
216
|
+
* - cursor: A number indicating the starting point for the range query.
|
|
217
|
+
* - limit: A number specifying the maximum number of records to be returned.
|
|
218
|
+
* - includeVectors (optional): A boolean flag indicating whether to include vector data in the response.
|
|
219
|
+
* - includeMetadata (optional): A boolean flag indicating whether to include metadata in the response.
|
|
220
|
+
*
|
|
221
|
+
* This payload type is used for range queries, where a set of records is retrieved based on the specified cursor
|
|
222
|
+
* and limit. The optional inclusion of vectors and metadata allows for flexible and detailed data retrieval.
|
|
223
|
+
*/
|
|
224
|
+
type Payload = {
|
|
225
|
+
cursor: number;
|
|
226
|
+
limit: number;
|
|
227
|
+
includeVectors?: boolean;
|
|
228
|
+
includeMetadata?: boolean;
|
|
229
|
+
};
|
|
230
|
+
/**
|
|
231
|
+
* Type definition for the response returned by RangeCommand
|
|
232
|
+
*
|
|
233
|
+
* This type outlines the structure of the response from a RangeCommand.
|
|
234
|
+
*
|
|
235
|
+
* Properties:
|
|
236
|
+
* - nextCursor: A string that indicates the cursor to be used for the next range query, facilitating pagination.
|
|
237
|
+
* - vectors: An array of Vector objects, each containing TMetadata, representing the data retrieved in the range query.
|
|
238
|
+
*
|
|
239
|
+
* The RangeReturnResponse type is crucial for operations that involve retrieving a range of records,
|
|
240
|
+
* providing both the data (in the form of vectors) and the means to continue fetching subsequent ranges (via nextCursor).
|
|
241
|
+
*/
|
|
242
|
+
type RangeReturnResponse<TMetadata> = {
|
|
243
|
+
nextCursor: string;
|
|
244
|
+
vectors: Vector<TMetadata>[];
|
|
245
|
+
};
|
|
246
|
+
/**
|
|
247
|
+
* RangeCommand Class
|
|
248
|
+
* Example:
|
|
249
|
+
* ```
|
|
250
|
+
* const rangePayload = { cursor: 0, limit: 10, includeVectors: true };
|
|
251
|
+
* const rangeCommand = new RangeCommand(rangePayload);
|
|
252
|
+
* // Use rangeCommand to execute the range query and retrieve data
|
|
253
|
+
* ```
|
|
254
|
+
*/
|
|
255
|
+
declare class RangeCommand<TResult> extends Command<RangeReturnResponse<TResult>> {
|
|
256
|
+
constructor(payload: Payload);
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
type CommandArgs<TCommand extends new (_args: any) => any> = ConstructorParameters<TCommand>[0];
|
|
260
|
+
/**
|
|
261
|
+
* Serverless vector client for upstash vector db.
|
|
262
|
+
*/
|
|
263
|
+
declare class Index$1 {
|
|
264
|
+
protected client: Requester;
|
|
265
|
+
/**
|
|
266
|
+
* Create a new vector db client
|
|
267
|
+
*
|
|
268
|
+
* @example
|
|
269
|
+
* ```typescript
|
|
270
|
+
* const index = new Index({
|
|
271
|
+
* url: "<UPSTASH_VECTOR_REST_URL>",
|
|
272
|
+
* token: "<UPSTASH_VECTOR_REST_TOKEN>",
|
|
273
|
+
* });
|
|
274
|
+
* ```
|
|
275
|
+
*/
|
|
276
|
+
constructor(client: Requester);
|
|
277
|
+
delete: (args: CommandArgs<typeof DeleteCommand>) => Promise<string>;
|
|
278
|
+
query: (args: CommandArgs<typeof QueryCommand>) => Promise<{
|
|
279
|
+
id: string | number;
|
|
280
|
+
score: number;
|
|
281
|
+
vector: number[];
|
|
282
|
+
metadata?: unknown;
|
|
283
|
+
}[]>;
|
|
284
|
+
upsert: (args: CommandArgs<typeof UpsertCommand>) => Promise<string>;
|
|
285
|
+
fetch: (args: CommandArgs<typeof FetchCommand>) => Promise<(Vector<unknown> | null)[]>;
|
|
286
|
+
reset: () => Promise<string>;
|
|
287
|
+
range: (args: CommandArgs<typeof RangeCommand>) => Promise<{
|
|
288
|
+
nextCursor: string;
|
|
289
|
+
vectors: Vector<unknown>[];
|
|
290
|
+
}>;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
/**
|
|
294
|
+
* Connection credentials for upstash vector.
|
|
295
|
+
* Get them from https://console.upstash.com/vector/<uuid>
|
|
296
|
+
*/
|
|
297
|
+
type VectorConfig = {
|
|
298
|
+
/**
|
|
299
|
+
* UPSTASH_VECTOR_REST_URL
|
|
300
|
+
*/
|
|
301
|
+
url: string;
|
|
302
|
+
/**
|
|
303
|
+
* UPSTASH_VECTOR_REST_TOKEN
|
|
304
|
+
*/
|
|
305
|
+
token: string;
|
|
306
|
+
/**
|
|
307
|
+
* The signal will allow aborting requests on the fly.
|
|
308
|
+
* For more check: https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal
|
|
309
|
+
*/
|
|
310
|
+
signal?: AbortSignal;
|
|
311
|
+
} & RequesterConfig;
|
|
312
|
+
/**
|
|
313
|
+
* Serverless vector client for upstash.
|
|
314
|
+
*/
|
|
315
|
+
declare class Index extends Index$1 {
|
|
316
|
+
/**
|
|
317
|
+
* Create a new vector client by providing the url and token
|
|
318
|
+
*
|
|
319
|
+
* @example
|
|
320
|
+
* ```typescript
|
|
321
|
+
* const vector = new Vector({
|
|
322
|
+
* url: "<UPSTASH_VECTOR_REST_URL>",
|
|
323
|
+
* token: "<UPSTASH_VECTOR_REST_TOKEN>",
|
|
324
|
+
* });
|
|
325
|
+
* ```
|
|
326
|
+
*/
|
|
327
|
+
constructor(config: VectorConfig);
|
|
328
|
+
/**
|
|
329
|
+
* Create a new vector client by providing a custom `Requester` implementation
|
|
330
|
+
*
|
|
331
|
+
* @example
|
|
332
|
+
* ```ts
|
|
333
|
+
*
|
|
334
|
+
* import { UpstashRequest, Requester, UpstashResponse, vector } from "@upstash/vector"
|
|
335
|
+
*
|
|
336
|
+
* const requester: Requester = {
|
|
337
|
+
* request: <TResult>(req: UpstashRequest): Promise<UpstashResponse<TResult>> => {
|
|
338
|
+
* // ...
|
|
339
|
+
* }
|
|
340
|
+
* }
|
|
341
|
+
*
|
|
342
|
+
* const vector = new vector(requester)
|
|
343
|
+
* ```
|
|
344
|
+
*/
|
|
345
|
+
constructor(requesters: Requester);
|
|
346
|
+
/**
|
|
347
|
+
* Create a new Upstash Vector instance from environment variables.
|
|
348
|
+
*
|
|
349
|
+
* Use this to automatically load connection secrets from your environment
|
|
350
|
+
* variables. For instance when using the Vercel integration.
|
|
351
|
+
*
|
|
352
|
+
* This tries to load `UPSTASH_VECTOR_REST_URL` and `UPSTASH_VECTOR_REST_TOKEN` from
|
|
353
|
+
* your environment using `process.env`.
|
|
354
|
+
*/
|
|
355
|
+
static fromEnv(config?: Omit<VectorConfig, "url" | "token">): Index;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
export { Index, type Requester, type UpstashRequest, type UpstashResponse, type VectorConfig };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var n=class extends Error{constructor(e){super(e),this.name="UpstashError";}};var i=class{baseUrl;headers;options;retry;constructor(e){this.options={cache:e.cache,signal:e.signal},this.baseUrl=e.baseUrl.replace(/\/$/,""),this.headers={"Content-Type":"application/json",...e.headers},typeof e?.retry=="boolean"&&e?.retry===!1?this.retry={attempts:1,backoff:()=>0}:this.retry={attempts:e?.retry?.retries??5,backoff:e?.retry?.backoff??(s=>Math.exp(s)*50)};}async request(e){let s={cache:this.options.cache,method:"POST",headers:this.headers,body:JSON.stringify(e.body),keepalive:!0,signal:this.options.signal},o=null,f=null;for(let y=0;y<=this.retry.attempts;y++)try{o=await fetch([this.baseUrl,...e.path??[]].join("/"),s);break}catch(g){if(this.options.signal?.aborted){let R=new Blob([JSON.stringify({result:this.options.signal.reason??"Aborted"})]),T={status:200,statusText:this.options.signal.reason??"Aborted"};o=new Response(R,T);break}f=g,await new Promise(R=>setTimeout(R,this.retry.backoff(y)));}if(!o)throw f??new Error("Exhausted all retries");let a=await o.json();if(x(a)){if(!o.ok)throw new n(`${a.error}, command was: ${JSON.stringify(e.body)}`);return a}return {result:a}}};function x(t){return t&&typeof t=="object"&&("result"in t||"error"in t)}var r=class{payload;endpoint;constructor(e,s){this.payload=e,this.endpoint=s;}async exec(e){let{result:s,error:o}=await e.request({body:this.payload,path:[this.endpoint]});if(o)throw new n(o);if(typeof s>"u")throw new Error("Request did not return a result");return s}};var p=class extends r{constructor(e){super(e.ids,"delete");}};var l=class extends r{constructor(e){super({...e},"query");}};var u=class extends r{constructor(e){super({...e},"upsert");}};var c=class extends r{constructor(e){super({...e},"fetch");}};var m=class extends r{constructor(e){super(e,"range");}};var d=class extends r{constructor(){super([],"reset");}};var h=class{client;constructor(e){this.client=e;}delete=e=>new p(e).exec(this.client);query=e=>new l(e).exec(this.client);upsert=e=>new u(e).exec(this.client);fetch=e=>new c(e).exec(this.client);reset=()=>new d().exec(this.client);range=e=>new m(e).exec(this.client)};var b=class t extends h{constructor(e){if("request"in e){super(e);return}(e.url.startsWith(" ")||e.url.endsWith(" ")||/\r|\n/.test(e.url))&&console.warn("The vector url contains whitespace or newline, which can cause errors!"),(e.token.startsWith(" ")||e.token.endsWith(" ")||/\r|\n/.test(e.token))&&console.warn("The vector token contains whitespace or newline, which can cause errors!");let s=new i({baseUrl:e.url,retry:e.retry,headers:{authorization:`Bearer ${e.token}`},cache:e.cache||"no-store",signal:e.signal});super(s);}static fromEnv(e){let s=process?.env.UPSTASH_VECTOR_REST_URL;if(!s)throw new Error("Unable to find environment variable: `UPSTASH_VECTOR_REST_URL`");let o=process?.env.UPSTASH_VECTOR_REST_TOKEN;if(!o)throw new Error("Unable to find environment variable: `UPSTASH_VECTOR_REST_TOKEN`");return new t({...e,url:s,token:o})}};
|
|
4
|
+
|
|
5
|
+
exports.Index = b;
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
var n=class extends Error{constructor(e){super(e),this.name="UpstashError";}};var i=class{baseUrl;headers;options;retry;constructor(e){this.options={cache:e.cache,signal:e.signal},this.baseUrl=e.baseUrl.replace(/\/$/,""),this.headers={"Content-Type":"application/json",...e.headers},typeof e?.retry=="boolean"&&e?.retry===!1?this.retry={attempts:1,backoff:()=>0}:this.retry={attempts:e?.retry?.retries??5,backoff:e?.retry?.backoff??(s=>Math.exp(s)*50)};}async request(e){let s={cache:this.options.cache,method:"POST",headers:this.headers,body:JSON.stringify(e.body),keepalive:!0,signal:this.options.signal},o=null,f=null;for(let y=0;y<=this.retry.attempts;y++)try{o=await fetch([this.baseUrl,...e.path??[]].join("/"),s);break}catch(g){if(this.options.signal?.aborted){let R=new Blob([JSON.stringify({result:this.options.signal.reason??"Aborted"})]),T={status:200,statusText:this.options.signal.reason??"Aborted"};o=new Response(R,T);break}f=g,await new Promise(R=>setTimeout(R,this.retry.backoff(y)));}if(!o)throw f??new Error("Exhausted all retries");let a=await o.json();if(x(a)){if(!o.ok)throw new n(`${a.error}, command was: ${JSON.stringify(e.body)}`);return a}return {result:a}}};function x(t){return t&&typeof t=="object"&&("result"in t||"error"in t)}var r=class{payload;endpoint;constructor(e,s){this.payload=e,this.endpoint=s;}async exec(e){let{result:s,error:o}=await e.request({body:this.payload,path:[this.endpoint]});if(o)throw new n(o);if(typeof s>"u")throw new Error("Request did not return a result");return s}};var p=class extends r{constructor(e){super(e.ids,"delete");}};var l=class extends r{constructor(e){super({...e},"query");}};var u=class extends r{constructor(e){super({...e},"upsert");}};var c=class extends r{constructor(e){super({...e},"fetch");}};var m=class extends r{constructor(e){super(e,"range");}};var d=class extends r{constructor(){super([],"reset");}};var h=class{client;constructor(e){this.client=e;}delete=e=>new p(e).exec(this.client);query=e=>new l(e).exec(this.client);upsert=e=>new u(e).exec(this.client);fetch=e=>new c(e).exec(this.client);reset=()=>new d().exec(this.client);range=e=>new m(e).exec(this.client)};var b=class t extends h{constructor(e){if("request"in e){super(e);return}(e.url.startsWith(" ")||e.url.endsWith(" ")||/\r|\n/.test(e.url))&&console.warn("The vector url contains whitespace or newline, which can cause errors!"),(e.token.startsWith(" ")||e.token.endsWith(" ")||/\r|\n/.test(e.token))&&console.warn("The vector token contains whitespace or newline, which can cause errors!");let s=new i({baseUrl:e.url,retry:e.retry,headers:{authorization:`Bearer ${e.token}`},cache:e.cache||"no-store",signal:e.signal});super(s);}static fromEnv(e){let s=process?.env.UPSTASH_VECTOR_REST_URL;if(!s)throw new Error("Unable to find environment variable: `UPSTASH_VECTOR_REST_URL`");let o=process?.env.UPSTASH_VECTOR_REST_TOKEN;if(!o)throw new Error("Unable to find environment variable: `UPSTASH_VECTOR_REST_TOKEN`");return new t({...e,url:s,token:o})}};
|
|
2
|
+
|
|
3
|
+
export { b as Index };
|
package/package.json
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@upstash/vector",
|
|
3
|
+
"description": "An HTTP/REST based Vector DB client built on top of Upstash REST API.",
|
|
4
|
+
"module": "./dist/index.mjs",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"types": "./dist/index.d.ts",
|
|
7
|
+
"version": "v0.1.0-alpha",
|
|
8
|
+
"keywords": [
|
|
9
|
+
"vector",
|
|
10
|
+
"upstash",
|
|
11
|
+
"db"
|
|
12
|
+
],
|
|
13
|
+
"author": "Oguzhan Olguncu <oguzhan@upstash.com>",
|
|
14
|
+
"license": "MIT",
|
|
15
|
+
"files": [
|
|
16
|
+
"dist"
|
|
17
|
+
],
|
|
18
|
+
"bugs": {
|
|
19
|
+
"url": "https://github.com/upstash/vector/issues"
|
|
20
|
+
},
|
|
21
|
+
"scripts": {
|
|
22
|
+
"test": "bun test src --coverage --bail --coverageSkipTestFiles=[test-utils.ts]",
|
|
23
|
+
"fmt": "bunx biome check --apply ./src",
|
|
24
|
+
"build": "tsup",
|
|
25
|
+
"prepare": "husky install"
|
|
26
|
+
},
|
|
27
|
+
"devDependencies": {
|
|
28
|
+
"typescript": "^5.0.0",
|
|
29
|
+
"@biomejs/biome": "^1.4.1",
|
|
30
|
+
"bun-types": "latest",
|
|
31
|
+
"husky": "^8.0.3",
|
|
32
|
+
"tsup": "latest"
|
|
33
|
+
}
|
|
34
|
+
}
|