@xata.io/client 0.20.2 → 0.21.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +32 -0
- package/dist/index.cjs +181 -27
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +840 -582
- package/dist/index.mjs +181 -27
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
@@ -1,5 +1,6 @@
|
|
1
|
-
const defaultTrace = async (
|
1
|
+
const defaultTrace = async (name, fn, _options) => {
|
2
2
|
return await fn({
|
3
|
+
name,
|
3
4
|
setAttributes: () => {
|
4
5
|
return;
|
5
6
|
}
|
@@ -41,6 +42,18 @@ function isStringArray(value) {
|
|
41
42
|
function isNumber(value) {
|
42
43
|
return isDefined(value) && typeof value === "number";
|
43
44
|
}
|
45
|
+
function parseNumber(value) {
|
46
|
+
if (isNumber(value)) {
|
47
|
+
return value;
|
48
|
+
}
|
49
|
+
if (isString(value)) {
|
50
|
+
const parsed = Number(value);
|
51
|
+
if (!Number.isNaN(parsed)) {
|
52
|
+
return parsed;
|
53
|
+
}
|
54
|
+
}
|
55
|
+
return void 0;
|
56
|
+
}
|
44
57
|
function toBase64(value) {
|
45
58
|
try {
|
46
59
|
return btoa(value);
|
@@ -67,10 +80,13 @@ function chunk(array, chunkSize) {
|
|
67
80
|
}
|
68
81
|
return result;
|
69
82
|
}
|
83
|
+
async function timeout(ms) {
|
84
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
85
|
+
}
|
70
86
|
|
71
87
|
function getEnvironment() {
|
72
88
|
try {
|
73
|
-
if (
|
89
|
+
if (isDefined(process) && isDefined(process.env)) {
|
74
90
|
return {
|
75
91
|
apiKey: process.env.XATA_API_KEY ?? getGlobalApiKey(),
|
76
92
|
databaseURL: process.env.XATA_DATABASE_URL ?? getGlobalDatabaseURL(),
|
@@ -179,6 +195,29 @@ function getAPIKey() {
|
|
179
195
|
}
|
180
196
|
}
|
181
197
|
|
198
|
+
var __accessCheck$8 = (obj, member, msg) => {
|
199
|
+
if (!member.has(obj))
|
200
|
+
throw TypeError("Cannot " + msg);
|
201
|
+
};
|
202
|
+
var __privateGet$8 = (obj, member, getter) => {
|
203
|
+
__accessCheck$8(obj, member, "read from private field");
|
204
|
+
return getter ? getter.call(obj) : member.get(obj);
|
205
|
+
};
|
206
|
+
var __privateAdd$8 = (obj, member, value) => {
|
207
|
+
if (member.has(obj))
|
208
|
+
throw TypeError("Cannot add the same private member more than once");
|
209
|
+
member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
210
|
+
};
|
211
|
+
var __privateSet$8 = (obj, member, value, setter) => {
|
212
|
+
__accessCheck$8(obj, member, "write to private field");
|
213
|
+
setter ? setter.call(obj, value) : member.set(obj, value);
|
214
|
+
return value;
|
215
|
+
};
|
216
|
+
var __privateMethod$4 = (obj, member, method) => {
|
217
|
+
__accessCheck$8(obj, member, "access private method");
|
218
|
+
return method;
|
219
|
+
};
|
220
|
+
var _fetch, _queue, _concurrency, _enqueue, enqueue_fn;
|
182
221
|
function getFetchImplementation(userFetch) {
|
183
222
|
const globalFetch = typeof fetch !== "undefined" ? fetch : void 0;
|
184
223
|
const fetchImpl = userFetch ?? globalFetch;
|
@@ -189,8 +228,74 @@ function getFetchImplementation(userFetch) {
|
|
189
228
|
}
|
190
229
|
return fetchImpl;
|
191
230
|
}
|
231
|
+
class ApiRequestPool {
|
232
|
+
constructor(concurrency = 10) {
|
233
|
+
__privateAdd$8(this, _enqueue);
|
234
|
+
__privateAdd$8(this, _fetch, void 0);
|
235
|
+
__privateAdd$8(this, _queue, void 0);
|
236
|
+
__privateAdd$8(this, _concurrency, void 0);
|
237
|
+
__privateSet$8(this, _queue, []);
|
238
|
+
__privateSet$8(this, _concurrency, concurrency);
|
239
|
+
this.running = 0;
|
240
|
+
this.started = 0;
|
241
|
+
}
|
242
|
+
setFetch(fetch2) {
|
243
|
+
__privateSet$8(this, _fetch, fetch2);
|
244
|
+
}
|
245
|
+
getFetch() {
|
246
|
+
if (!__privateGet$8(this, _fetch)) {
|
247
|
+
throw new Error("Fetch not set");
|
248
|
+
}
|
249
|
+
return __privateGet$8(this, _fetch);
|
250
|
+
}
|
251
|
+
request(url, options) {
|
252
|
+
const start = new Date();
|
253
|
+
const fetch2 = this.getFetch();
|
254
|
+
const runRequest = async (stalled = false) => {
|
255
|
+
const response = await fetch2(url, options);
|
256
|
+
if (response.status === 429) {
|
257
|
+
const rateLimitReset = parseNumber(response.headers?.get("x-ratelimit-reset")) ?? 1;
|
258
|
+
await timeout(rateLimitReset * 1e3);
|
259
|
+
return await runRequest(true);
|
260
|
+
}
|
261
|
+
if (stalled) {
|
262
|
+
const stalledTime = new Date().getTime() - start.getTime();
|
263
|
+
console.warn(`A request to Xata hit your workspace limits, was retried and stalled for ${stalledTime}ms`);
|
264
|
+
}
|
265
|
+
return response;
|
266
|
+
};
|
267
|
+
return __privateMethod$4(this, _enqueue, enqueue_fn).call(this, async () => {
|
268
|
+
return await runRequest();
|
269
|
+
});
|
270
|
+
}
|
271
|
+
}
|
272
|
+
_fetch = new WeakMap();
|
273
|
+
_queue = new WeakMap();
|
274
|
+
_concurrency = new WeakMap();
|
275
|
+
_enqueue = new WeakSet();
|
276
|
+
enqueue_fn = function(task) {
|
277
|
+
const promise = new Promise((resolve) => __privateGet$8(this, _queue).push(resolve)).finally(() => {
|
278
|
+
this.started--;
|
279
|
+
this.running++;
|
280
|
+
}).then(() => task()).finally(() => {
|
281
|
+
this.running--;
|
282
|
+
const next = __privateGet$8(this, _queue).shift();
|
283
|
+
if (next !== void 0) {
|
284
|
+
this.started++;
|
285
|
+
next();
|
286
|
+
}
|
287
|
+
});
|
288
|
+
if (this.running + this.started < __privateGet$8(this, _concurrency)) {
|
289
|
+
const next = __privateGet$8(this, _queue).shift();
|
290
|
+
if (next !== void 0) {
|
291
|
+
this.started++;
|
292
|
+
next();
|
293
|
+
}
|
294
|
+
}
|
295
|
+
return promise;
|
296
|
+
};
|
192
297
|
|
193
|
-
const VERSION = "0.
|
298
|
+
const VERSION = "0.21.1";
|
194
299
|
|
195
300
|
class ErrorWithCause extends Error {
|
196
301
|
constructor(message, options) {
|
@@ -233,6 +338,7 @@ function getMessage(data) {
|
|
233
338
|
}
|
234
339
|
}
|
235
340
|
|
341
|
+
const pool = new ApiRequestPool();
|
236
342
|
const resolveUrl = (url, queryParams = {}, pathParams = {}) => {
|
237
343
|
const cleanQueryParams = Object.entries(queryParams).reduce((acc, [key, value]) => {
|
238
344
|
if (value === void 0 || value === null)
|
@@ -281,11 +387,13 @@ async function fetch$1({
|
|
281
387
|
signal,
|
282
388
|
clientID,
|
283
389
|
sessionID,
|
390
|
+
clientName,
|
284
391
|
fetchOptions = {}
|
285
392
|
}) {
|
286
|
-
|
393
|
+
pool.setFetch(fetchImpl);
|
394
|
+
return await trace(
|
287
395
|
`${method.toUpperCase()} ${path}`,
|
288
|
-
async ({ setAttributes }) => {
|
396
|
+
async ({ name, setAttributes }) => {
|
289
397
|
const baseUrl = buildBaseUrl({ endpoint, path, workspacesApiUrl, pathParams, apiUrl });
|
290
398
|
const fullUrl = resolveUrl(baseUrl, queryParams, pathParams);
|
291
399
|
const url = fullUrl.includes("localhost") ? fullUrl.replace(/^[^.]+\./, "http://") : fullUrl;
|
@@ -293,24 +401,27 @@ async function fetch$1({
|
|
293
401
|
[TraceAttributes.HTTP_URL]: url,
|
294
402
|
[TraceAttributes.HTTP_TARGET]: resolveUrl(path, queryParams, pathParams)
|
295
403
|
});
|
296
|
-
const
|
404
|
+
const xataAgent = compact([
|
405
|
+
["client", "TS_SDK"],
|
406
|
+
["version", VERSION],
|
407
|
+
isDefined(clientName) ? ["service", clientName] : void 0
|
408
|
+
]).map(([key, value]) => `${key}=${value}`).join("; ");
|
409
|
+
const response = await pool.request(url, {
|
297
410
|
...fetchOptions,
|
298
411
|
method: method.toUpperCase(),
|
299
412
|
body: body ? JSON.stringify(body) : void 0,
|
300
413
|
headers: {
|
414
|
+
"Accept-Encoding": "identity",
|
301
415
|
"Content-Type": "application/json",
|
302
|
-
"User-Agent": `Xata client-ts/${VERSION}`,
|
303
416
|
"X-Xata-Client-ID": clientID ?? "",
|
304
417
|
"X-Xata-Session-ID": sessionID ?? "",
|
418
|
+
"X-Xata-Agent": xataAgent,
|
305
419
|
...headers,
|
306
420
|
...hostHeader(fullUrl),
|
307
421
|
Authorization: `Bearer ${apiKey}`
|
308
422
|
},
|
309
423
|
signal
|
310
424
|
});
|
311
|
-
if (response.status === 204) {
|
312
|
-
return {};
|
313
|
-
}
|
314
425
|
const { host, protocol } = parseUrl(response.url);
|
315
426
|
const requestId = response.headers?.get("x-request-id") ?? void 0;
|
316
427
|
setAttributes({
|
@@ -320,6 +431,12 @@ async function fetch$1({
|
|
320
431
|
[TraceAttributes.HTTP_HOST]: host,
|
321
432
|
[TraceAttributes.HTTP_SCHEME]: protocol?.replace(":", "")
|
322
433
|
});
|
434
|
+
if (response.status === 204) {
|
435
|
+
return {};
|
436
|
+
}
|
437
|
+
if (response.status === 429) {
|
438
|
+
throw new FetcherError(response.status, "Rate limit exceeded", requestId);
|
439
|
+
}
|
323
440
|
try {
|
324
441
|
const jsonResponse = await response.json();
|
325
442
|
if (response.ok) {
|
@@ -771,7 +888,8 @@ class XataApiClient {
|
|
771
888
|
workspacesApiUrl: getHostUrl(provider, "workspaces"),
|
772
889
|
fetchImpl: getFetchImplementation(options.fetch),
|
773
890
|
apiKey,
|
774
|
-
trace
|
891
|
+
trace,
|
892
|
+
clientName: options.clientName
|
775
893
|
});
|
776
894
|
}
|
777
895
|
get user() {
|
@@ -2303,13 +2421,19 @@ class RestRepository extends Query {
|
|
2303
2421
|
const result = await this.read(a, columns);
|
2304
2422
|
return result;
|
2305
2423
|
}
|
2306
|
-
|
2307
|
-
|
2308
|
-
|
2309
|
-
|
2310
|
-
|
2311
|
-
|
2312
|
-
|
2424
|
+
try {
|
2425
|
+
if (isString(a) && isObject(b)) {
|
2426
|
+
const columns = isStringArray(c) ? c : void 0;
|
2427
|
+
return await __privateMethod$2(this, _updateRecordWithID, updateRecordWithID_fn).call(this, a, b, columns, { ifVersion });
|
2428
|
+
}
|
2429
|
+
if (isObject(a) && isString(a.id)) {
|
2430
|
+
const columns = isStringArray(b) ? b : void 0;
|
2431
|
+
return await __privateMethod$2(this, _updateRecordWithID, updateRecordWithID_fn).call(this, a.id, { ...a, id: void 0 }, columns, { ifVersion });
|
2432
|
+
}
|
2433
|
+
} catch (error) {
|
2434
|
+
if (error.status === 422)
|
2435
|
+
return null;
|
2436
|
+
throw error;
|
2313
2437
|
}
|
2314
2438
|
throw new Error("Invalid arguments for update method");
|
2315
2439
|
});
|
@@ -2440,7 +2564,9 @@ class RestRepository extends Query {
|
|
2440
2564
|
prefix: options.prefix,
|
2441
2565
|
highlight: options.highlight,
|
2442
2566
|
filter: options.filter,
|
2443
|
-
boosters: options.boosters
|
2567
|
+
boosters: options.boosters,
|
2568
|
+
page: options.page,
|
2569
|
+
target: options.target
|
2444
2570
|
},
|
2445
2571
|
...fetchProps
|
2446
2572
|
});
|
@@ -2758,10 +2884,10 @@ const initObject = (db, schemaTables, table, object, selectedColumns) => {
|
|
2758
2884
|
const value = result[column.name];
|
2759
2885
|
switch (column.type) {
|
2760
2886
|
case "datetime": {
|
2761
|
-
const date = value !== void 0 ? new Date(value) :
|
2762
|
-
if (date && isNaN(date.getTime())) {
|
2887
|
+
const date = value !== void 0 ? new Date(value) : null;
|
2888
|
+
if (date !== null && isNaN(date.getTime())) {
|
2763
2889
|
console.error(`Failed to parse date ${value} for field ${column.name}`);
|
2764
|
-
} else
|
2890
|
+
} else {
|
2765
2891
|
result[column.name] = date;
|
2766
2892
|
}
|
2767
2893
|
break;
|
@@ -3029,10 +3155,10 @@ _schemaTables = new WeakMap();
|
|
3029
3155
|
_search = new WeakSet();
|
3030
3156
|
search_fn = async function(query, options, getFetchProps) {
|
3031
3157
|
const fetchProps = await getFetchProps();
|
3032
|
-
const { tables, fuzziness, highlight, prefix } = options ?? {};
|
3158
|
+
const { tables, fuzziness, highlight, prefix, page } = options ?? {};
|
3033
3159
|
const { records } = await searchBranch({
|
3034
3160
|
pathParams: { workspace: "{workspaceId}", dbBranchName: "{dbBranch}", region: "{region}" },
|
3035
|
-
body: { tables, query, fuzziness, prefix, highlight },
|
3161
|
+
body: { tables, query, fuzziness, prefix, highlight, page },
|
3036
3162
|
...fetchProps
|
3037
3163
|
});
|
3038
3164
|
return records;
|
@@ -3050,6 +3176,22 @@ getSchemaTables_fn = async function(getFetchProps) {
|
|
3050
3176
|
return schema.tables;
|
3051
3177
|
};
|
3052
3178
|
|
3179
|
+
class TransactionPlugin extends XataPlugin {
|
3180
|
+
build({ getFetchProps }) {
|
3181
|
+
return {
|
3182
|
+
run: async (operations) => {
|
3183
|
+
const fetchProps = await getFetchProps();
|
3184
|
+
const response = await branchTransaction({
|
3185
|
+
pathParams: { workspace: "{workspaceId}", dbBranchName: "{dbBranch}", region: "{region}" },
|
3186
|
+
body: { operations },
|
3187
|
+
...fetchProps
|
3188
|
+
});
|
3189
|
+
return response;
|
3190
|
+
}
|
3191
|
+
};
|
3192
|
+
}
|
3193
|
+
}
|
3194
|
+
|
3053
3195
|
const isBranchStrategyBuilder = (strategy) => {
|
3054
3196
|
return typeof strategy === "function";
|
3055
3197
|
};
|
@@ -3177,8 +3319,10 @@ const buildClient = (plugins) => {
|
|
3177
3319
|
};
|
3178
3320
|
const db = new SchemaPlugin(schemaTables).build(pluginOptions);
|
3179
3321
|
const search = new SearchPlugin(db, schemaTables).build(pluginOptions);
|
3322
|
+
const transactions = new TransactionPlugin().build(pluginOptions);
|
3180
3323
|
this.db = db;
|
3181
3324
|
this.search = search;
|
3325
|
+
this.transactions = transactions;
|
3182
3326
|
for (const [key, namespace] of Object.entries(plugins ?? {})) {
|
3183
3327
|
if (namespace === void 0)
|
3184
3328
|
continue;
|
@@ -3210,6 +3354,7 @@ const buildClient = (plugins) => {
|
|
3210
3354
|
const apiKey = options?.apiKey || getAPIKey();
|
3211
3355
|
const cache = options?.cache ?? new SimpleCache({ defaultQueryTTL: 0 });
|
3212
3356
|
const trace = options?.trace ?? defaultTrace;
|
3357
|
+
const clientName = options?.clientName;
|
3213
3358
|
const branch = async () => options?.branch !== void 0 ? await __privateMethod(this, _evaluateBranch, evaluateBranch_fn).call(this, options.branch) : await getCurrentBranchName({ apiKey, databaseURL, fetchImpl: options?.fetch });
|
3214
3359
|
if (!apiKey) {
|
3215
3360
|
throw new Error("Option apiKey is required");
|
@@ -3217,8 +3362,16 @@ const buildClient = (plugins) => {
|
|
3217
3362
|
if (!databaseURL) {
|
3218
3363
|
throw new Error("Option databaseURL is required");
|
3219
3364
|
}
|
3220
|
-
return { fetch, databaseURL, apiKey, branch, cache, trace, clientID: generateUUID(), enableBrowser };
|
3221
|
-
}, _getFetchProps = new WeakSet(), getFetchProps_fn = async function({
|
3365
|
+
return { fetch, databaseURL, apiKey, branch, cache, trace, clientID: generateUUID(), enableBrowser, clientName };
|
3366
|
+
}, _getFetchProps = new WeakSet(), getFetchProps_fn = async function({
|
3367
|
+
fetch,
|
3368
|
+
apiKey,
|
3369
|
+
databaseURL,
|
3370
|
+
branch,
|
3371
|
+
trace,
|
3372
|
+
clientID,
|
3373
|
+
clientName
|
3374
|
+
}) {
|
3222
3375
|
const branchValue = await __privateMethod(this, _evaluateBranch, evaluateBranch_fn).call(this, branch);
|
3223
3376
|
if (!branchValue)
|
3224
3377
|
throw new Error("Unable to resolve branch value");
|
@@ -3232,7 +3385,8 @@ const buildClient = (plugins) => {
|
|
3232
3385
|
return databaseURL + newPath;
|
3233
3386
|
},
|
3234
3387
|
trace,
|
3235
|
-
clientID
|
3388
|
+
clientID,
|
3389
|
+
clientName
|
3236
3390
|
};
|
3237
3391
|
}, _evaluateBranch = new WeakSet(), evaluateBranch_fn = async function(param) {
|
3238
3392
|
if (__privateGet(this, _branch))
|