@xata.io/client 0.20.1 → 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 CHANGED
@@ -1,5 +1,41 @@
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
+
29
+ ## 0.20.2
30
+
31
+ ### Patch Changes
32
+
33
+ - [#756](https://github.com/xataio/client-ts/pull/756) [`27b73745`](https://github.com/xataio/client-ts/commit/27b737451227cf12774115ccb70649f6bbf76180) Thanks [@SferaDev](https://github.com/SferaDev)! - Fix update method with id in payload
34
+
35
+ - [#726](https://github.com/xataio/client-ts/pull/726) [`47a1f878`](https://github.com/xataio/client-ts/commit/47a1f87850a7178dad656a16d2584eee6ce68f29) Thanks [@SferaDev](https://github.com/SferaDev)! - Use transactions API internally for bulk operations
36
+
37
+ - [#726](https://github.com/xataio/client-ts/pull/726) [`adde9b10`](https://github.com/xataio/client-ts/commit/adde9b10708182295dee07c203c7bf737806e49e) Thanks [@SferaDev](https://github.com/SferaDev)! - Allow sending bulk operations of more than the limit
38
+
3
39
  ## 0.20.1
4
40
 
5
41
  ### Patch Changes
package/dist/index.cjs CHANGED
@@ -1,27 +1,8 @@
1
1
  'use strict';
2
2
 
3
- Object.defineProperty(exports, '__esModule', { value: true });
4
-
5
- function _interopNamespace(e) {
6
- if (e && e.__esModule) return e;
7
- var n = Object.create(null);
8
- if (e) {
9
- Object.keys(e).forEach(function (k) {
10
- if (k !== 'default') {
11
- var d = Object.getOwnPropertyDescriptor(e, k);
12
- Object.defineProperty(n, k, d.get ? d : {
13
- enumerable: true,
14
- get: function () { return e[k]; }
15
- });
16
- }
17
- });
18
- }
19
- n["default"] = e;
20
- return Object.freeze(n);
21
- }
22
-
23
- const defaultTrace = async (_name, fn, _options) => {
3
+ const defaultTrace = async (name, fn, _options) => {
24
4
  return await fn({
5
+ name,
25
6
  setAttributes: () => {
26
7
  return;
27
8
  }
@@ -63,6 +44,18 @@ function isStringArray(value) {
63
44
  function isNumber(value) {
64
45
  return isDefined(value) && typeof value === "number";
65
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
+ }
66
59
  function toBase64(value) {
67
60
  try {
68
61
  return btoa(value);
@@ -82,10 +75,20 @@ function deepMerge(a, b) {
82
75
  }
83
76
  return result;
84
77
  }
78
+ function chunk(array, chunkSize) {
79
+ const result = [];
80
+ for (let i = 0; i < array.length; i += chunkSize) {
81
+ result.push(array.slice(i, i + chunkSize));
82
+ }
83
+ return result;
84
+ }
85
+ async function timeout(ms) {
86
+ return new Promise((resolve) => setTimeout(resolve, ms));
87
+ }
85
88
 
86
89
  function getEnvironment() {
87
90
  try {
88
- if (isObject(process) && isObject(process.env)) {
91
+ if (isDefined(process) && isDefined(process.env)) {
89
92
  return {
90
93
  apiKey: process.env.XATA_API_KEY ?? getGlobalApiKey(),
91
94
  databaseURL: process.env.XATA_DATABASE_URL ?? getGlobalDatabaseURL(),
@@ -172,7 +175,7 @@ async function getGitBranch() {
172
175
  if (typeof require === "function") {
173
176
  return require(nodeModule).execSync(fullCmd, execOptions).trim();
174
177
  }
175
- const { execSync } = await (function (t) { return Promise.resolve().then(function () { return /*#__PURE__*/_interopNamespace(require(t)); }); })(nodeModule);
178
+ const { execSync } = await import(nodeModule);
176
179
  return execSync(fullCmd, execOptions).toString().trim();
177
180
  } catch (err) {
178
181
  }
@@ -194,6 +197,29 @@ function getAPIKey() {
194
197
  }
195
198
  }
196
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;
197
223
  function getFetchImplementation(userFetch) {
198
224
  const globalFetch = typeof fetch !== "undefined" ? fetch : void 0;
199
225
  const fetchImpl = userFetch ?? globalFetch;
@@ -204,8 +230,74 @@ function getFetchImplementation(userFetch) {
204
230
  }
205
231
  return fetchImpl;
206
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
+ };
207
299
 
208
- const VERSION = "0.20.1";
300
+ const VERSION = "0.21.0";
209
301
 
210
302
  class ErrorWithCause extends Error {
211
303
  constructor(message, options) {
@@ -248,6 +340,7 @@ function getMessage(data) {
248
340
  }
249
341
  }
250
342
 
343
+ const pool = new ApiRequestPool();
251
344
  const resolveUrl = (url, queryParams = {}, pathParams = {}) => {
252
345
  const cleanQueryParams = Object.entries(queryParams).reduce((acc, [key, value]) => {
253
346
  if (value === void 0 || value === null)
@@ -296,11 +389,13 @@ async function fetch$1({
296
389
  signal,
297
390
  clientID,
298
391
  sessionID,
392
+ clientName,
299
393
  fetchOptions = {}
300
394
  }) {
301
- return trace(
395
+ pool.setFetch(fetchImpl);
396
+ return await trace(
302
397
  `${method.toUpperCase()} ${path}`,
303
- async ({ setAttributes }) => {
398
+ async ({ name, setAttributes }) => {
304
399
  const baseUrl = buildBaseUrl({ endpoint, path, workspacesApiUrl, pathParams, apiUrl });
305
400
  const fullUrl = resolveUrl(baseUrl, queryParams, pathParams);
306
401
  const url = fullUrl.includes("localhost") ? fullUrl.replace(/^[^.]+\./, "http://") : fullUrl;
@@ -308,24 +403,26 @@ async function fetch$1({
308
403
  [TraceAttributes.HTTP_URL]: url,
309
404
  [TraceAttributes.HTTP_TARGET]: resolveUrl(path, queryParams, pathParams)
310
405
  });
311
- const response = await fetchImpl(url, {
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, {
312
412
  ...fetchOptions,
313
413
  method: method.toUpperCase(),
314
414
  body: body ? JSON.stringify(body) : void 0,
315
415
  headers: {
316
416
  "Content-Type": "application/json",
317
- "User-Agent": `Xata client-ts/${VERSION}`,
318
417
  "X-Xata-Client-ID": clientID ?? "",
319
418
  "X-Xata-Session-ID": sessionID ?? "",
419
+ "X-Xata-Agent": xataAgent,
320
420
  ...headers,
321
421
  ...hostHeader(fullUrl),
322
422
  Authorization: `Bearer ${apiKey}`
323
423
  },
324
424
  signal
325
425
  });
326
- if (response.status === 204) {
327
- return {};
328
- }
329
426
  const { host, protocol } = parseUrl(response.url);
330
427
  const requestId = response.headers?.get("x-request-id") ?? void 0;
331
428
  setAttributes({
@@ -335,6 +432,12 @@ async function fetch$1({
335
432
  [TraceAttributes.HTTP_HOST]: host,
336
433
  [TraceAttributes.HTTP_SCHEME]: protocol?.replace(":", "")
337
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
+ }
338
441
  try {
339
442
  const jsonResponse = await response.json();
340
443
  if (response.ok) {
@@ -786,7 +889,8 @@ class XataApiClient {
786
889
  workspacesApiUrl: getHostUrl(provider, "workspaces"),
787
890
  fetchImpl: getFetchImplementation(options.fetch),
788
891
  apiKey,
789
- trace
892
+ trace,
893
+ clientName: options.clientName
790
894
  });
791
895
  }
792
896
  get user() {
@@ -1388,6 +1492,19 @@ class RecordsApi {
1388
1492
  ...this.extraProps
1389
1493
  });
1390
1494
  }
1495
+ branchTransaction({
1496
+ workspace,
1497
+ region,
1498
+ database,
1499
+ branch,
1500
+ operations
1501
+ }) {
1502
+ return operationsByTag.records.branchTransaction({
1503
+ pathParams: { workspace, region, dbBranchName: `${database}:${branch}` },
1504
+ body: { operations },
1505
+ ...this.extraProps
1506
+ });
1507
+ }
1391
1508
  }
1392
1509
  class SearchAndFilterApi {
1393
1510
  constructor(extraProps) {
@@ -2153,7 +2270,8 @@ var __privateMethod$2 = (obj, member, method) => {
2153
2270
  __accessCheck$4(obj, member, "access private method");
2154
2271
  return method;
2155
2272
  };
2156
- var _table, _getFetchProps, _db, _cache, _schemaTables$2, _trace, _insertRecordWithoutId, insertRecordWithoutId_fn, _insertRecordWithId, insertRecordWithId_fn, _bulkInsertTableRecords, bulkInsertTableRecords_fn, _updateRecordWithID, updateRecordWithID_fn, _upsertRecordWithID, upsertRecordWithID_fn, _deleteRecord, deleteRecord_fn, _setCacheQuery, setCacheQuery_fn, _getCacheQuery, getCacheQuery_fn, _getSchemaTables$1, getSchemaTables_fn$1;
2273
+ var _table, _getFetchProps, _db, _cache, _schemaTables$2, _trace, _insertRecordWithoutId, insertRecordWithoutId_fn, _insertRecordWithId, insertRecordWithId_fn, _insertRecords, insertRecords_fn, _updateRecordWithID, updateRecordWithID_fn, _updateRecords, updateRecords_fn, _upsertRecordWithID, upsertRecordWithID_fn, _deleteRecord, deleteRecord_fn, _deleteRecords, deleteRecords_fn, _setCacheQuery, setCacheQuery_fn, _getCacheQuery, getCacheQuery_fn, _getSchemaTables$1, getSchemaTables_fn$1;
2274
+ const BULK_OPERATION_MAX_SIZE = 1e3;
2157
2275
  class Repository extends Query {
2158
2276
  }
2159
2277
  class RestRepository extends Query {
@@ -2165,10 +2283,12 @@ class RestRepository extends Query {
2165
2283
  );
2166
2284
  __privateAdd$4(this, _insertRecordWithoutId);
2167
2285
  __privateAdd$4(this, _insertRecordWithId);
2168
- __privateAdd$4(this, _bulkInsertTableRecords);
2286
+ __privateAdd$4(this, _insertRecords);
2169
2287
  __privateAdd$4(this, _updateRecordWithID);
2288
+ __privateAdd$4(this, _updateRecords);
2170
2289
  __privateAdd$4(this, _upsertRecordWithID);
2171
2290
  __privateAdd$4(this, _deleteRecord);
2291
+ __privateAdd$4(this, _deleteRecords);
2172
2292
  __privateAdd$4(this, _setCacheQuery);
2173
2293
  __privateAdd$4(this, _getCacheQuery);
2174
2294
  __privateAdd$4(this, _getSchemaTables$1);
@@ -2202,20 +2322,22 @@ class RestRepository extends Query {
2202
2322
  if (Array.isArray(a)) {
2203
2323
  if (a.length === 0)
2204
2324
  return [];
2205
- const columns = isStringArray(b) ? b : void 0;
2206
- return __privateMethod$2(this, _bulkInsertTableRecords, bulkInsertTableRecords_fn).call(this, a, columns);
2325
+ const ids = await __privateMethod$2(this, _insertRecords, insertRecords_fn).call(this, a, { ifVersion, createOnly: true });
2326
+ const columns = isStringArray(b) ? b : ["*"];
2327
+ const result = await this.read(ids, columns);
2328
+ return result;
2207
2329
  }
2208
2330
  if (isString(a) && isObject(b)) {
2209
2331
  if (a === "")
2210
2332
  throw new Error("The id can't be empty");
2211
2333
  const columns = isStringArray(c) ? c : void 0;
2212
- return __privateMethod$2(this, _insertRecordWithId, insertRecordWithId_fn).call(this, a, b, columns, { createOnly: true, ifVersion });
2334
+ return await __privateMethod$2(this, _insertRecordWithId, insertRecordWithId_fn).call(this, a, b, columns, { createOnly: true, ifVersion });
2213
2335
  }
2214
2336
  if (isObject(a) && isString(a.id)) {
2215
2337
  if (a.id === "")
2216
2338
  throw new Error("The id can't be empty");
2217
2339
  const columns = isStringArray(b) ? b : void 0;
2218
- return __privateMethod$2(this, _insertRecordWithId, insertRecordWithId_fn).call(this, a.id, { ...a, id: void 0 }, columns, { createOnly: true, ifVersion });
2340
+ return await __privateMethod$2(this, _insertRecordWithId, insertRecordWithId_fn).call(this, a.id, { ...a, id: void 0 }, columns, { createOnly: true, ifVersion });
2219
2341
  }
2220
2342
  if (isObject(a)) {
2221
2343
  const columns = isStringArray(b) ? b : void 0;
@@ -2290,11 +2412,15 @@ class RestRepository extends Query {
2290
2412
  if (Array.isArray(a)) {
2291
2413
  if (a.length === 0)
2292
2414
  return [];
2293
- if (a.length > 100) {
2294
- console.warn("Bulk update operation is not optimized in the Xata API yet, this request might be slow");
2295
- }
2415
+ const existing = await this.read(a, ["id"]);
2416
+ const updates = a.filter((_item, index) => existing[index] !== null);
2417
+ await __privateMethod$2(this, _updateRecords, updateRecords_fn).call(this, updates, {
2418
+ ifVersion,
2419
+ upsert: false
2420
+ });
2296
2421
  const columns = isStringArray(b) ? b : ["*"];
2297
- return Promise.all(a.map((object) => this.update(object, columns)));
2422
+ const result = await this.read(a, columns);
2423
+ return result;
2298
2424
  }
2299
2425
  if (isString(a) && isObject(b)) {
2300
2426
  const columns = isStringArray(c) ? c : void 0;
@@ -2332,11 +2458,13 @@ class RestRepository extends Query {
2332
2458
  if (Array.isArray(a)) {
2333
2459
  if (a.length === 0)
2334
2460
  return [];
2335
- if (a.length > 100) {
2336
- console.warn("Bulk update operation is not optimized in the Xata API yet, this request might be slow");
2337
- }
2461
+ await __privateMethod$2(this, _updateRecords, updateRecords_fn).call(this, a, {
2462
+ ifVersion,
2463
+ upsert: true
2464
+ });
2338
2465
  const columns = isStringArray(b) ? b : ["*"];
2339
- return Promise.all(a.map((object) => this.createOrUpdate(object, columns)));
2466
+ const result = await this.read(a, columns);
2467
+ return result;
2340
2468
  }
2341
2469
  if (isString(a) && isObject(b)) {
2342
2470
  const columns = isStringArray(c) ? c : void 0;
@@ -2355,8 +2483,10 @@ class RestRepository extends Query {
2355
2483
  if (Array.isArray(a)) {
2356
2484
  if (a.length === 0)
2357
2485
  return [];
2486
+ const ids = await __privateMethod$2(this, _insertRecords, insertRecords_fn).call(this, a, { ifVersion, createOnly: false });
2358
2487
  const columns = isStringArray(b) ? b : ["*"];
2359
- return __privateMethod$2(this, _bulkInsertTableRecords, bulkInsertTableRecords_fn).call(this, a, columns);
2488
+ const result = await this.read(ids, columns);
2489
+ return result;
2360
2490
  }
2361
2491
  if (isString(a) && isObject(b)) {
2362
2492
  const columns = isStringArray(c) ? c : void 0;
@@ -2374,10 +2504,17 @@ class RestRepository extends Query {
2374
2504
  if (Array.isArray(a)) {
2375
2505
  if (a.length === 0)
2376
2506
  return [];
2377
- if (a.length > 100) {
2378
- console.warn("Bulk delete operation is not optimized in the Xata API yet, this request might be slow");
2379
- }
2380
- return Promise.all(a.map((id) => this.delete(id, b)));
2507
+ const ids = a.map((o) => {
2508
+ if (isString(o))
2509
+ return o;
2510
+ if (isString(o.id))
2511
+ return o.id;
2512
+ throw new Error("Invalid arguments for delete method");
2513
+ });
2514
+ const columns = isStringArray(b) ? b : ["*"];
2515
+ const result = await this.read(a, columns);
2516
+ await __privateMethod$2(this, _deleteRecords, deleteRecords_fn).call(this, ids);
2517
+ return result;
2381
2518
  }
2382
2519
  if (isString(a)) {
2383
2520
  return __privateMethod$2(this, _deleteRecord, deleteRecord_fn).call(this, a, b);
@@ -2422,7 +2559,9 @@ class RestRepository extends Query {
2422
2559
  prefix: options.prefix,
2423
2560
  highlight: options.highlight,
2424
2561
  filter: options.filter,
2425
- boosters: options.boosters
2562
+ boosters: options.boosters,
2563
+ page: options.page,
2564
+ target: options.target
2426
2565
  },
2427
2566
  ...fetchProps
2428
2567
  });
@@ -2545,31 +2684,40 @@ insertRecordWithId_fn = async function(recordId, object, columns = ["*"], { crea
2545
2684
  const schemaTables = await __privateMethod$2(this, _getSchemaTables$1, getSchemaTables_fn$1).call(this);
2546
2685
  return initObject(__privateGet$4(this, _db), schemaTables, __privateGet$4(this, _table), response, columns);
2547
2686
  };
2548
- _bulkInsertTableRecords = new WeakSet();
2549
- bulkInsertTableRecords_fn = async function(objects, columns = ["*"]) {
2687
+ _insertRecords = new WeakSet();
2688
+ insertRecords_fn = async function(objects, { createOnly, ifVersion }) {
2550
2689
  const fetchProps = await __privateGet$4(this, _getFetchProps).call(this);
2551
- const records = objects.map((object) => transformObjectLinks(object));
2552
- const response = await bulkInsertTableRecords({
2553
- pathParams: {
2554
- workspace: "{workspaceId}",
2555
- dbBranchName: "{dbBranch}",
2556
- region: "{region}",
2557
- tableName: __privateGet$4(this, _table)
2558
- },
2559
- queryParams: { columns },
2560
- body: { records },
2561
- ...fetchProps
2562
- });
2563
- if (!isResponseWithRecords(response)) {
2564
- throw new Error("Request included columns but server didn't include them");
2690
+ const chunkedOperations = chunk(
2691
+ objects.map((object) => ({
2692
+ insert: { table: __privateGet$4(this, _table), record: transformObjectLinks(object), createOnly, ifVersion }
2693
+ })),
2694
+ BULK_OPERATION_MAX_SIZE
2695
+ );
2696
+ const ids = [];
2697
+ for (const operations of chunkedOperations) {
2698
+ const { results } = await branchTransaction({
2699
+ pathParams: {
2700
+ workspace: "{workspaceId}",
2701
+ dbBranchName: "{dbBranch}",
2702
+ region: "{region}"
2703
+ },
2704
+ body: { operations },
2705
+ ...fetchProps
2706
+ });
2707
+ for (const result of results) {
2708
+ if (result.operation === "insert") {
2709
+ ids.push(result.id);
2710
+ } else {
2711
+ ids.push(null);
2712
+ }
2713
+ }
2565
2714
  }
2566
- const schemaTables = await __privateMethod$2(this, _getSchemaTables$1, getSchemaTables_fn$1).call(this);
2567
- return response.records?.map((item) => initObject(__privateGet$4(this, _db), schemaTables, __privateGet$4(this, _table), item, columns));
2715
+ return ids;
2568
2716
  };
2569
2717
  _updateRecordWithID = new WeakSet();
2570
2718
  updateRecordWithID_fn = async function(recordId, object, columns = ["*"], { ifVersion }) {
2571
2719
  const fetchProps = await __privateGet$4(this, _getFetchProps).call(this);
2572
- const record = transformObjectLinks(object);
2720
+ const { id: _id, ...record } = transformObjectLinks(object);
2573
2721
  try {
2574
2722
  const response = await updateRecordWithID({
2575
2723
  pathParams: {
@@ -2592,6 +2740,36 @@ updateRecordWithID_fn = async function(recordId, object, columns = ["*"], { ifVe
2592
2740
  throw e;
2593
2741
  }
2594
2742
  };
2743
+ _updateRecords = new WeakSet();
2744
+ updateRecords_fn = async function(objects, { ifVersion, upsert }) {
2745
+ const fetchProps = await __privateGet$4(this, _getFetchProps).call(this);
2746
+ const chunkedOperations = chunk(
2747
+ objects.map(({ id, ...object }) => ({
2748
+ update: { table: __privateGet$4(this, _table), id, ifVersion, upsert, fields: transformObjectLinks(object) }
2749
+ })),
2750
+ BULK_OPERATION_MAX_SIZE
2751
+ );
2752
+ const ids = [];
2753
+ for (const operations of chunkedOperations) {
2754
+ const { results } = await branchTransaction({
2755
+ pathParams: {
2756
+ workspace: "{workspaceId}",
2757
+ dbBranchName: "{dbBranch}",
2758
+ region: "{region}"
2759
+ },
2760
+ body: { operations },
2761
+ ...fetchProps
2762
+ });
2763
+ for (const result of results) {
2764
+ if (result.operation === "update") {
2765
+ ids.push(result.id);
2766
+ } else {
2767
+ ids.push(null);
2768
+ }
2769
+ }
2770
+ }
2771
+ return ids;
2772
+ };
2595
2773
  _upsertRecordWithID = new WeakSet();
2596
2774
  upsertRecordWithID_fn = async function(recordId, object, columns = ["*"], { ifVersion }) {
2597
2775
  const fetchProps = await __privateGet$4(this, _getFetchProps).call(this);
@@ -2634,6 +2812,25 @@ deleteRecord_fn = async function(recordId, columns = ["*"]) {
2634
2812
  throw e;
2635
2813
  }
2636
2814
  };
2815
+ _deleteRecords = new WeakSet();
2816
+ deleteRecords_fn = async function(recordIds) {
2817
+ const fetchProps = await __privateGet$4(this, _getFetchProps).call(this);
2818
+ const chunkedOperations = chunk(
2819
+ recordIds.map((id) => ({ delete: { table: __privateGet$4(this, _table), id } })),
2820
+ BULK_OPERATION_MAX_SIZE
2821
+ );
2822
+ for (const operations of chunkedOperations) {
2823
+ await branchTransaction({
2824
+ pathParams: {
2825
+ workspace: "{workspaceId}",
2826
+ dbBranchName: "{dbBranch}",
2827
+ region: "{region}"
2828
+ },
2829
+ body: { operations },
2830
+ ...fetchProps
2831
+ });
2832
+ }
2833
+ };
2637
2834
  _setCacheQuery = new WeakSet();
2638
2835
  setCacheQuery_fn = async function(query, meta, records) {
2639
2836
  await __privateGet$4(this, _cache).set(`query_${__privateGet$4(this, _table)}:${query.key()}`, { date: new Date(), meta, records });
@@ -2682,10 +2879,10 @@ const initObject = (db, schemaTables, table, object, selectedColumns) => {
2682
2879
  const value = result[column.name];
2683
2880
  switch (column.type) {
2684
2881
  case "datetime": {
2685
- const date = value !== void 0 ? new Date(value) : void 0;
2686
- if (date && isNaN(date.getTime())) {
2882
+ const date = value !== void 0 ? new Date(value) : null;
2883
+ if (date !== null && isNaN(date.getTime())) {
2687
2884
  console.error(`Failed to parse date ${value} for field ${column.name}`);
2688
- } else if (date) {
2885
+ } else {
2689
2886
  result[column.name] = date;
2690
2887
  }
2691
2888
  break;
@@ -2744,9 +2941,6 @@ const initObject = (db, schemaTables, table, object, selectedColumns) => {
2744
2941
  Object.freeze(result);
2745
2942
  return result;
2746
2943
  };
2747
- function isResponseWithRecords(value) {
2748
- return isObject(value) && Array.isArray(value.records);
2749
- }
2750
2944
  function extractId(value) {
2751
2945
  if (isString(value))
2752
2946
  return value;
@@ -2956,10 +3150,10 @@ _schemaTables = new WeakMap();
2956
3150
  _search = new WeakSet();
2957
3151
  search_fn = async function(query, options, getFetchProps) {
2958
3152
  const fetchProps = await getFetchProps();
2959
- const { tables, fuzziness, highlight, prefix } = options ?? {};
3153
+ const { tables, fuzziness, highlight, prefix, page } = options ?? {};
2960
3154
  const { records } = await searchBranch({
2961
3155
  pathParams: { workspace: "{workspaceId}", dbBranchName: "{dbBranch}", region: "{region}" },
2962
- body: { tables, query, fuzziness, prefix, highlight },
3156
+ body: { tables, query, fuzziness, prefix, highlight, page },
2963
3157
  ...fetchProps
2964
3158
  });
2965
3159
  return records;
@@ -2977,6 +3171,22 @@ getSchemaTables_fn = async function(getFetchProps) {
2977
3171
  return schema.tables;
2978
3172
  };
2979
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
+
2980
3190
  const isBranchStrategyBuilder = (strategy) => {
2981
3191
  return typeof strategy === "function";
2982
3192
  };
@@ -3104,8 +3314,10 @@ const buildClient = (plugins) => {
3104
3314
  };
3105
3315
  const db = new SchemaPlugin(schemaTables).build(pluginOptions);
3106
3316
  const search = new SearchPlugin(db, schemaTables).build(pluginOptions);
3317
+ const transactions = new TransactionPlugin().build(pluginOptions);
3107
3318
  this.db = db;
3108
3319
  this.search = search;
3320
+ this.transactions = transactions;
3109
3321
  for (const [key, namespace] of Object.entries(plugins ?? {})) {
3110
3322
  if (namespace === void 0)
3111
3323
  continue;
@@ -3137,6 +3349,7 @@ const buildClient = (plugins) => {
3137
3349
  const apiKey = options?.apiKey || getAPIKey();
3138
3350
  const cache = options?.cache ?? new SimpleCache({ defaultQueryTTL: 0 });
3139
3351
  const trace = options?.trace ?? defaultTrace;
3352
+ const clientName = options?.clientName;
3140
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 });
3141
3354
  if (!apiKey) {
3142
3355
  throw new Error("Option apiKey is required");
@@ -3144,8 +3357,16 @@ const buildClient = (plugins) => {
3144
3357
  if (!databaseURL) {
3145
3358
  throw new Error("Option databaseURL is required");
3146
3359
  }
3147
- return { fetch, databaseURL, apiKey, branch, cache, trace, clientID: generateUUID(), enableBrowser };
3148
- }, _getFetchProps = new WeakSet(), getFetchProps_fn = async function({ fetch, apiKey, databaseURL, branch, trace, clientID }) {
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
+ }) {
3149
3370
  const branchValue = await __privateMethod(this, _evaluateBranch, evaluateBranch_fn).call(this, branch);
3150
3371
  if (!branchValue)
3151
3372
  throw new Error("Unable to resolve branch value");
@@ -3159,7 +3380,8 @@ const buildClient = (plugins) => {
3159
3380
  return databaseURL + newPath;
3160
3381
  },
3161
3382
  trace,
3162
- clientID
3383
+ clientID,
3384
+ clientName
3163
3385
  };
3164
3386
  }, _evaluateBranch = new WeakSet(), evaluateBranch_fn = async function(param) {
3165
3387
  if (__privateGet(this, _branch))