@xata.io/client 0.20.2 → 0.21.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +26 -0
- package/dist/index.cjs +167 -20
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +257 -36
- package/dist/index.mjs +167 -20
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
@@ -1,5 +1,31 @@
|
|
1
1
|
# @xata.io/client
|
2
2
|
|
3
|
+
## 0.21.0
|
4
|
+
|
5
|
+
### Minor Changes
|
6
|
+
|
7
|
+
- [#757](https://github.com/xataio/client-ts/pull/757) [`7da604d2`](https://github.com/xataio/client-ts/commit/7da604d27990e20ecadba6122434fca563e6a8c9) Thanks [@SferaDev](https://github.com/SferaDev)! - Add promise pool for retries
|
8
|
+
|
9
|
+
### Patch Changes
|
10
|
+
|
11
|
+
- [#764](https://github.com/xataio/client-ts/pull/764) [`b131040a`](https://github.com/xataio/client-ts/commit/b131040a2d142c4e71a2e586fbf05cd9295af9a1) Thanks [@SferaDev](https://github.com/SferaDev)! - Fix bun
|
12
|
+
|
13
|
+
- [#759](https://github.com/xataio/client-ts/pull/759) [`7ea810dc`](https://github.com/xataio/client-ts/commit/7ea810dc083ec284447e3bd27bd0465f887481e6) Thanks [@SferaDev](https://github.com/SferaDev)! - Expose new transaction API
|
14
|
+
|
15
|
+
- [#767](https://github.com/xataio/client-ts/pull/767) [`d124cbfb`](https://github.com/xataio/client-ts/commit/d124cbfb93d3d591e79bbe9e94c4b6304d825e71) Thanks [@SferaDev](https://github.com/SferaDev)! - Remove formatVersion from schema
|
16
|
+
|
17
|
+
- [#767](https://github.com/xataio/client-ts/pull/767) [`d124cbfb`](https://github.com/xataio/client-ts/commit/d124cbfb93d3d591e79bbe9e94c4b6304d825e71) Thanks [@SferaDev](https://github.com/SferaDev)! - Fix null value returning on date columns
|
18
|
+
|
19
|
+
- [#775](https://github.com/xataio/client-ts/pull/775) [`fb5ccdf9`](https://github.com/xataio/client-ts/commit/fb5ccdf9fa95c37d54fbc5d9c0bb45872c831609) Thanks [@SferaDev](https://github.com/SferaDev)! - Add missing target field to search
|
20
|
+
|
21
|
+
- [#760](https://github.com/xataio/client-ts/pull/760) [`4ae00036`](https://github.com/xataio/client-ts/commit/4ae00036b53c6c89e02a1fcfdd992f1a3c22892c) Thanks [@SferaDev](https://github.com/SferaDev)! - Add support for filters in boosters
|
22
|
+
|
23
|
+
- [#766](https://github.com/xataio/client-ts/pull/766) [`bdae6668`](https://github.com/xataio/client-ts/commit/bdae6668fb571d29f1b1068a54f6866a80d9b174) Thanks [@SferaDev](https://github.com/SferaDev)! - Remove beta for Workers
|
24
|
+
|
25
|
+
- [#771](https://github.com/xataio/client-ts/pull/771) [`9486bdcc`](https://github.com/xataio/client-ts/commit/9486bdccc0af567bc5f2e8f91592b0143c539c45) Thanks [@SferaDev](https://github.com/SferaDev)! - Add modifier for numeric booster
|
26
|
+
|
27
|
+
- [#771](https://github.com/xataio/client-ts/pull/771) [`9486bdcc`](https://github.com/xataio/client-ts/commit/9486bdccc0af567bc5f2e8f91592b0143c539c45) Thanks [@SferaDev](https://github.com/SferaDev)! - Add pagination to search
|
28
|
+
|
3
29
|
## 0.20.2
|
4
30
|
|
5
31
|
### Patch Changes
|
package/dist/index.cjs
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
'use strict';
|
2
2
|
|
3
|
-
const defaultTrace = async (
|
3
|
+
const defaultTrace = async (name, fn, _options) => {
|
4
4
|
return await fn({
|
5
|
+
name,
|
5
6
|
setAttributes: () => {
|
6
7
|
return;
|
7
8
|
}
|
@@ -43,6 +44,18 @@ function isStringArray(value) {
|
|
43
44
|
function isNumber(value) {
|
44
45
|
return isDefined(value) && typeof value === "number";
|
45
46
|
}
|
47
|
+
function parseNumber(value) {
|
48
|
+
if (isNumber(value)) {
|
49
|
+
return value;
|
50
|
+
}
|
51
|
+
if (isString(value)) {
|
52
|
+
const parsed = Number(value);
|
53
|
+
if (!Number.isNaN(parsed)) {
|
54
|
+
return parsed;
|
55
|
+
}
|
56
|
+
}
|
57
|
+
return void 0;
|
58
|
+
}
|
46
59
|
function toBase64(value) {
|
47
60
|
try {
|
48
61
|
return btoa(value);
|
@@ -69,10 +82,13 @@ function chunk(array, chunkSize) {
|
|
69
82
|
}
|
70
83
|
return result;
|
71
84
|
}
|
85
|
+
async function timeout(ms) {
|
86
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
87
|
+
}
|
72
88
|
|
73
89
|
function getEnvironment() {
|
74
90
|
try {
|
75
|
-
if (
|
91
|
+
if (isDefined(process) && isDefined(process.env)) {
|
76
92
|
return {
|
77
93
|
apiKey: process.env.XATA_API_KEY ?? getGlobalApiKey(),
|
78
94
|
databaseURL: process.env.XATA_DATABASE_URL ?? getGlobalDatabaseURL(),
|
@@ -181,6 +197,29 @@ function getAPIKey() {
|
|
181
197
|
}
|
182
198
|
}
|
183
199
|
|
200
|
+
var __accessCheck$8 = (obj, member, msg) => {
|
201
|
+
if (!member.has(obj))
|
202
|
+
throw TypeError("Cannot " + msg);
|
203
|
+
};
|
204
|
+
var __privateGet$8 = (obj, member, getter) => {
|
205
|
+
__accessCheck$8(obj, member, "read from private field");
|
206
|
+
return getter ? getter.call(obj) : member.get(obj);
|
207
|
+
};
|
208
|
+
var __privateAdd$8 = (obj, member, value) => {
|
209
|
+
if (member.has(obj))
|
210
|
+
throw TypeError("Cannot add the same private member more than once");
|
211
|
+
member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
212
|
+
};
|
213
|
+
var __privateSet$8 = (obj, member, value, setter) => {
|
214
|
+
__accessCheck$8(obj, member, "write to private field");
|
215
|
+
setter ? setter.call(obj, value) : member.set(obj, value);
|
216
|
+
return value;
|
217
|
+
};
|
218
|
+
var __privateMethod$4 = (obj, member, method) => {
|
219
|
+
__accessCheck$8(obj, member, "access private method");
|
220
|
+
return method;
|
221
|
+
};
|
222
|
+
var _fetch, _queue, _concurrency, _enqueue, enqueue_fn;
|
184
223
|
function getFetchImplementation(userFetch) {
|
185
224
|
const globalFetch = typeof fetch !== "undefined" ? fetch : void 0;
|
186
225
|
const fetchImpl = userFetch ?? globalFetch;
|
@@ -191,8 +230,74 @@ function getFetchImplementation(userFetch) {
|
|
191
230
|
}
|
192
231
|
return fetchImpl;
|
193
232
|
}
|
233
|
+
class ApiRequestPool {
|
234
|
+
constructor(concurrency = 10) {
|
235
|
+
__privateAdd$8(this, _enqueue);
|
236
|
+
__privateAdd$8(this, _fetch, void 0);
|
237
|
+
__privateAdd$8(this, _queue, void 0);
|
238
|
+
__privateAdd$8(this, _concurrency, void 0);
|
239
|
+
__privateSet$8(this, _queue, []);
|
240
|
+
__privateSet$8(this, _concurrency, concurrency);
|
241
|
+
this.running = 0;
|
242
|
+
this.started = 0;
|
243
|
+
}
|
244
|
+
setFetch(fetch2) {
|
245
|
+
__privateSet$8(this, _fetch, fetch2);
|
246
|
+
}
|
247
|
+
getFetch() {
|
248
|
+
if (!__privateGet$8(this, _fetch)) {
|
249
|
+
throw new Error("Fetch not set");
|
250
|
+
}
|
251
|
+
return __privateGet$8(this, _fetch);
|
252
|
+
}
|
253
|
+
request(url, options) {
|
254
|
+
const start = new Date();
|
255
|
+
const fetch2 = this.getFetch();
|
256
|
+
const runRequest = async (stalled = false) => {
|
257
|
+
const response = await fetch2(url, options);
|
258
|
+
if (response.status === 429) {
|
259
|
+
const rateLimitReset = parseNumber(response.headers?.get("x-ratelimit-reset")) ?? 1;
|
260
|
+
await timeout(rateLimitReset * 1e3);
|
261
|
+
return await runRequest(true);
|
262
|
+
}
|
263
|
+
if (stalled) {
|
264
|
+
const stalledTime = new Date().getTime() - start.getTime();
|
265
|
+
console.warn(`A request to Xata hit your workspace limits, was retried and stalled for ${stalledTime}ms`);
|
266
|
+
}
|
267
|
+
return response;
|
268
|
+
};
|
269
|
+
return __privateMethod$4(this, _enqueue, enqueue_fn).call(this, async () => {
|
270
|
+
return await runRequest();
|
271
|
+
});
|
272
|
+
}
|
273
|
+
}
|
274
|
+
_fetch = new WeakMap();
|
275
|
+
_queue = new WeakMap();
|
276
|
+
_concurrency = new WeakMap();
|
277
|
+
_enqueue = new WeakSet();
|
278
|
+
enqueue_fn = function(task) {
|
279
|
+
const promise = new Promise((resolve) => __privateGet$8(this, _queue).push(resolve)).finally(() => {
|
280
|
+
this.started--;
|
281
|
+
this.running++;
|
282
|
+
}).then(() => task()).finally(() => {
|
283
|
+
this.running--;
|
284
|
+
const next = __privateGet$8(this, _queue).shift();
|
285
|
+
if (next !== void 0) {
|
286
|
+
this.started++;
|
287
|
+
next();
|
288
|
+
}
|
289
|
+
});
|
290
|
+
if (this.running + this.started < __privateGet$8(this, _concurrency)) {
|
291
|
+
const next = __privateGet$8(this, _queue).shift();
|
292
|
+
if (next !== void 0) {
|
293
|
+
this.started++;
|
294
|
+
next();
|
295
|
+
}
|
296
|
+
}
|
297
|
+
return promise;
|
298
|
+
};
|
194
299
|
|
195
|
-
const VERSION = "0.
|
300
|
+
const VERSION = "0.21.0";
|
196
301
|
|
197
302
|
class ErrorWithCause extends Error {
|
198
303
|
constructor(message, options) {
|
@@ -235,6 +340,7 @@ function getMessage(data) {
|
|
235
340
|
}
|
236
341
|
}
|
237
342
|
|
343
|
+
const pool = new ApiRequestPool();
|
238
344
|
const resolveUrl = (url, queryParams = {}, pathParams = {}) => {
|
239
345
|
const cleanQueryParams = Object.entries(queryParams).reduce((acc, [key, value]) => {
|
240
346
|
if (value === void 0 || value === null)
|
@@ -283,11 +389,13 @@ async function fetch$1({
|
|
283
389
|
signal,
|
284
390
|
clientID,
|
285
391
|
sessionID,
|
392
|
+
clientName,
|
286
393
|
fetchOptions = {}
|
287
394
|
}) {
|
288
|
-
|
395
|
+
pool.setFetch(fetchImpl);
|
396
|
+
return await trace(
|
289
397
|
`${method.toUpperCase()} ${path}`,
|
290
|
-
async ({ setAttributes }) => {
|
398
|
+
async ({ name, setAttributes }) => {
|
291
399
|
const baseUrl = buildBaseUrl({ endpoint, path, workspacesApiUrl, pathParams, apiUrl });
|
292
400
|
const fullUrl = resolveUrl(baseUrl, queryParams, pathParams);
|
293
401
|
const url = fullUrl.includes("localhost") ? fullUrl.replace(/^[^.]+\./, "http://") : fullUrl;
|
@@ -295,24 +403,26 @@ async function fetch$1({
|
|
295
403
|
[TraceAttributes.HTTP_URL]: url,
|
296
404
|
[TraceAttributes.HTTP_TARGET]: resolveUrl(path, queryParams, pathParams)
|
297
405
|
});
|
298
|
-
const
|
406
|
+
const xataAgent = compact([
|
407
|
+
["client", "TS_SDK"],
|
408
|
+
["version", VERSION],
|
409
|
+
isDefined(clientName) ? ["service", clientName] : void 0
|
410
|
+
]).map(([key, value]) => `${key}=${value}`).join("; ");
|
411
|
+
const response = await pool.request(url, {
|
299
412
|
...fetchOptions,
|
300
413
|
method: method.toUpperCase(),
|
301
414
|
body: body ? JSON.stringify(body) : void 0,
|
302
415
|
headers: {
|
303
416
|
"Content-Type": "application/json",
|
304
|
-
"User-Agent": `Xata client-ts/${VERSION}`,
|
305
417
|
"X-Xata-Client-ID": clientID ?? "",
|
306
418
|
"X-Xata-Session-ID": sessionID ?? "",
|
419
|
+
"X-Xata-Agent": xataAgent,
|
307
420
|
...headers,
|
308
421
|
...hostHeader(fullUrl),
|
309
422
|
Authorization: `Bearer ${apiKey}`
|
310
423
|
},
|
311
424
|
signal
|
312
425
|
});
|
313
|
-
if (response.status === 204) {
|
314
|
-
return {};
|
315
|
-
}
|
316
426
|
const { host, protocol } = parseUrl(response.url);
|
317
427
|
const requestId = response.headers?.get("x-request-id") ?? void 0;
|
318
428
|
setAttributes({
|
@@ -322,6 +432,12 @@ async function fetch$1({
|
|
322
432
|
[TraceAttributes.HTTP_HOST]: host,
|
323
433
|
[TraceAttributes.HTTP_SCHEME]: protocol?.replace(":", "")
|
324
434
|
});
|
435
|
+
if (response.status === 204) {
|
436
|
+
return {};
|
437
|
+
}
|
438
|
+
if (response.status === 429) {
|
439
|
+
throw new FetcherError(response.status, "Rate limit exceeded", requestId);
|
440
|
+
}
|
325
441
|
try {
|
326
442
|
const jsonResponse = await response.json();
|
327
443
|
if (response.ok) {
|
@@ -773,7 +889,8 @@ class XataApiClient {
|
|
773
889
|
workspacesApiUrl: getHostUrl(provider, "workspaces"),
|
774
890
|
fetchImpl: getFetchImplementation(options.fetch),
|
775
891
|
apiKey,
|
776
|
-
trace
|
892
|
+
trace,
|
893
|
+
clientName: options.clientName
|
777
894
|
});
|
778
895
|
}
|
779
896
|
get user() {
|
@@ -2442,7 +2559,9 @@ class RestRepository extends Query {
|
|
2442
2559
|
prefix: options.prefix,
|
2443
2560
|
highlight: options.highlight,
|
2444
2561
|
filter: options.filter,
|
2445
|
-
boosters: options.boosters
|
2562
|
+
boosters: options.boosters,
|
2563
|
+
page: options.page,
|
2564
|
+
target: options.target
|
2446
2565
|
},
|
2447
2566
|
...fetchProps
|
2448
2567
|
});
|
@@ -2760,10 +2879,10 @@ const initObject = (db, schemaTables, table, object, selectedColumns) => {
|
|
2760
2879
|
const value = result[column.name];
|
2761
2880
|
switch (column.type) {
|
2762
2881
|
case "datetime": {
|
2763
|
-
const date = value !== void 0 ? new Date(value) :
|
2764
|
-
if (date && isNaN(date.getTime())) {
|
2882
|
+
const date = value !== void 0 ? new Date(value) : null;
|
2883
|
+
if (date !== null && isNaN(date.getTime())) {
|
2765
2884
|
console.error(`Failed to parse date ${value} for field ${column.name}`);
|
2766
|
-
} else
|
2885
|
+
} else {
|
2767
2886
|
result[column.name] = date;
|
2768
2887
|
}
|
2769
2888
|
break;
|
@@ -3031,10 +3150,10 @@ _schemaTables = new WeakMap();
|
|
3031
3150
|
_search = new WeakSet();
|
3032
3151
|
search_fn = async function(query, options, getFetchProps) {
|
3033
3152
|
const fetchProps = await getFetchProps();
|
3034
|
-
const { tables, fuzziness, highlight, prefix } = options ?? {};
|
3153
|
+
const { tables, fuzziness, highlight, prefix, page } = options ?? {};
|
3035
3154
|
const { records } = await searchBranch({
|
3036
3155
|
pathParams: { workspace: "{workspaceId}", dbBranchName: "{dbBranch}", region: "{region}" },
|
3037
|
-
body: { tables, query, fuzziness, prefix, highlight },
|
3156
|
+
body: { tables, query, fuzziness, prefix, highlight, page },
|
3038
3157
|
...fetchProps
|
3039
3158
|
});
|
3040
3159
|
return records;
|
@@ -3052,6 +3171,22 @@ getSchemaTables_fn = async function(getFetchProps) {
|
|
3052
3171
|
return schema.tables;
|
3053
3172
|
};
|
3054
3173
|
|
3174
|
+
class TransactionPlugin extends XataPlugin {
|
3175
|
+
build({ getFetchProps }) {
|
3176
|
+
return {
|
3177
|
+
run: async (operations) => {
|
3178
|
+
const fetchProps = await getFetchProps();
|
3179
|
+
const response = await branchTransaction({
|
3180
|
+
pathParams: { workspace: "{workspaceId}", dbBranchName: "{dbBranch}", region: "{region}" },
|
3181
|
+
body: { operations },
|
3182
|
+
...fetchProps
|
3183
|
+
});
|
3184
|
+
return response;
|
3185
|
+
}
|
3186
|
+
};
|
3187
|
+
}
|
3188
|
+
}
|
3189
|
+
|
3055
3190
|
const isBranchStrategyBuilder = (strategy) => {
|
3056
3191
|
return typeof strategy === "function";
|
3057
3192
|
};
|
@@ -3179,8 +3314,10 @@ const buildClient = (plugins) => {
|
|
3179
3314
|
};
|
3180
3315
|
const db = new SchemaPlugin(schemaTables).build(pluginOptions);
|
3181
3316
|
const search = new SearchPlugin(db, schemaTables).build(pluginOptions);
|
3317
|
+
const transactions = new TransactionPlugin().build(pluginOptions);
|
3182
3318
|
this.db = db;
|
3183
3319
|
this.search = search;
|
3320
|
+
this.transactions = transactions;
|
3184
3321
|
for (const [key, namespace] of Object.entries(plugins ?? {})) {
|
3185
3322
|
if (namespace === void 0)
|
3186
3323
|
continue;
|
@@ -3212,6 +3349,7 @@ const buildClient = (plugins) => {
|
|
3212
3349
|
const apiKey = options?.apiKey || getAPIKey();
|
3213
3350
|
const cache = options?.cache ?? new SimpleCache({ defaultQueryTTL: 0 });
|
3214
3351
|
const trace = options?.trace ?? defaultTrace;
|
3352
|
+
const clientName = options?.clientName;
|
3215
3353
|
const branch = async () => options?.branch !== void 0 ? await __privateMethod(this, _evaluateBranch, evaluateBranch_fn).call(this, options.branch) : await getCurrentBranchName({ apiKey, databaseURL, fetchImpl: options?.fetch });
|
3216
3354
|
if (!apiKey) {
|
3217
3355
|
throw new Error("Option apiKey is required");
|
@@ -3219,8 +3357,16 @@ const buildClient = (plugins) => {
|
|
3219
3357
|
if (!databaseURL) {
|
3220
3358
|
throw new Error("Option databaseURL is required");
|
3221
3359
|
}
|
3222
|
-
return { fetch, databaseURL, apiKey, branch, cache, trace, clientID: generateUUID(), enableBrowser };
|
3223
|
-
}, _getFetchProps = new WeakSet(), getFetchProps_fn = async function({
|
3360
|
+
return { fetch, databaseURL, apiKey, branch, cache, trace, clientID: generateUUID(), enableBrowser, clientName };
|
3361
|
+
}, _getFetchProps = new WeakSet(), getFetchProps_fn = async function({
|
3362
|
+
fetch,
|
3363
|
+
apiKey,
|
3364
|
+
databaseURL,
|
3365
|
+
branch,
|
3366
|
+
trace,
|
3367
|
+
clientID,
|
3368
|
+
clientName
|
3369
|
+
}) {
|
3224
3370
|
const branchValue = await __privateMethod(this, _evaluateBranch, evaluateBranch_fn).call(this, branch);
|
3225
3371
|
if (!branchValue)
|
3226
3372
|
throw new Error("Unable to resolve branch value");
|
@@ -3234,7 +3380,8 @@ const buildClient = (plugins) => {
|
|
3234
3380
|
return databaseURL + newPath;
|
3235
3381
|
},
|
3236
3382
|
trace,
|
3237
|
-
clientID
|
3383
|
+
clientID,
|
3384
|
+
clientName
|
3238
3385
|
};
|
3239
3386
|
}, _evaluateBranch = new WeakSet(), evaluateBranch_fn = async function(param) {
|
3240
3387
|
if (__privateGet(this, _branch))
|