@xata.io/client 0.17.1 → 0.18.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 CHANGED
@@ -1,5 +1,33 @@
1
1
  # @xata.io/client
2
2
 
3
+ ## 0.18.1
4
+
5
+ ### Patch Changes
6
+
7
+ - [#627](https://github.com/xataio/client-ts/pull/627) [`ad0a5b4`](https://github.com/xataio/client-ts/commit/ad0a5b4bc87b82fdc10008a8ea324a8ca783e678) Thanks [@SferaDev](https://github.com/SferaDev)! - Fix some cases where filters on link and multiple column types are not working
8
+
9
+ ## 0.18.0
10
+
11
+ ### Minor Changes
12
+
13
+ - [#562](https://github.com/xataio/client-ts/pull/562) [`699beb4`](https://github.com/xataio/client-ts/commit/699beb4bbf21cffa001d3f88a03246980e30250b) Thanks [@SferaDev](https://github.com/SferaDev)! - Return null on nullable columns
14
+
15
+ ### Patch Changes
16
+
17
+ - [#583](https://github.com/xataio/client-ts/pull/583) [`330b076`](https://github.com/xataio/client-ts/commit/330b076a0781e3576c82afab76e3fb2a64f2e041) Thanks [@SferaDev](https://github.com/SferaDev)! - Add support for unique columns
18
+
19
+ - [#598](https://github.com/xataio/client-ts/pull/598) [`c3dfb4b`](https://github.com/xataio/client-ts/commit/c3dfb4babc990634b9e9747616ed93223178a2e7) Thanks [@SferaDev](https://github.com/SferaDev)! - API: Add patch database metadata endpoint
20
+
21
+ - [#602](https://github.com/xataio/client-ts/pull/602) [`74b17aa`](https://github.com/xataio/client-ts/commit/74b17aaedc0dbdd79bfdcb182b2e70b61f98f5a5) Thanks [@gimenete](https://github.com/gimenete)! - API: Make workspace slug optional on create
22
+
23
+ - [#615](https://github.com/xataio/client-ts/pull/615) [`83f20cd`](https://github.com/xataio/client-ts/commit/83f20cdbe53706c16016c4db3f318e679b24ec86) Thanks [@SferaDev](https://github.com/SferaDev)! - Make `getMany` return more items than max pagination size
24
+
25
+ - [#562](https://github.com/xataio/client-ts/pull/562) [`addfcc6`](https://github.com/xataio/client-ts/commit/addfcc67fca663defdd340111ea09c9188bad3ab) Thanks [@SferaDev](https://github.com/SferaDev)! - Add `orThrows` methods that instead of returning null, throw an exception.
26
+
27
+ - [#583](https://github.com/xataio/client-ts/pull/583) [`eb7ba59`](https://github.com/xataio/client-ts/commit/eb7ba594be2a1f0ab90956836bbeb912e188a46d) Thanks [@SferaDev](https://github.com/SferaDev)! - Add support for non nullable columns
28
+
29
+ - [#612](https://github.com/xataio/client-ts/pull/612) [`f1a0742`](https://github.com/xataio/client-ts/commit/f1a0742a04e1aefab14f46371a04a41069faec01) Thanks [@xata-bot](https://github.com/xata-bot)! - API: Add summarize table endpoint
30
+
3
31
  ## 0.17.1
4
32
 
5
33
  ### Patch Changes
package/README.md CHANGED
@@ -246,7 +246,7 @@ const api = new XataApiClient({ apiKey: process.env.XATA_API_KEY });
246
246
  Once you have initialized the API client, the operations are organized following the same hiearchy as in the [official documentation](https://docs.xata.io). You have different namespaces for each entity (ie. `workspaces`, `databases`, `tables`, `branches`, `users`, `records`...).
247
247
 
248
248
  ```ts
249
- const { id: workspace } = await api.workspaces.createWorkspace({ name: 'example', slug: 'example' });
249
+ const { id: workspace } = await api.workspaces.createWorkspace({ name: 'example' });
250
250
  const { databaseName } = await api.databases.createDatabase(workspace, 'database');
251
251
 
252
252
  await api.branches.createBranch(workspace, databaseName, 'branch');
package/Usage.md CHANGED
@@ -41,6 +41,8 @@ To get a collection of records, you can use the `Query` object. It provides the
41
41
  - `getAll()`: returns all the records in the query results by making multiple requests to iterate over all the pages which exist. If the query is not filtered and the table is a large dataset, this operation can affect the performance.
42
42
  - `getMany()`: returns an array with a subset of the first results in the query. The default [pagination](#page) size (20) is used and can be customised by passing a different `{ pagination: { size: number } }` in its options. To learn more about default values, see [helper variables](#helper-variables).
43
43
 
44
+ Both the `getAll()` and `getMany()` will produce multiple requests to the server if the query should return more than the maximum page size. We perform the minimum number of requests to get the desired number of records.
45
+
44
46
  All these methods allow customising its filters, column selection, column ordering, pagination or cache TTL. For example:
45
47
 
46
48
  ```ts
package/dist/index.cjs CHANGED
@@ -172,7 +172,7 @@ function getFetchImplementation(userFetch) {
172
172
  return fetchImpl;
173
173
  }
174
174
 
175
- const VERSION = "0.17.1";
175
+ const VERSION = "0.18.1";
176
176
 
177
177
  class ErrorWithCause extends Error {
178
178
  constructor(message, options) {
@@ -408,6 +408,7 @@ const getDatabaseMetadata = (variables) => fetch$1({
408
408
  method: "get",
409
409
  ...variables
410
410
  });
411
+ const updateDatabaseMetadata = (variables) => fetch$1({ url: "/dbs/{dbName}/metadata", method: "patch", ...variables });
411
412
  const getGitBranchesMapping = (variables) => fetch$1({ url: "/dbs/{dbName}/gitBranches", method: "get", ...variables });
412
413
  const addGitBranchesEntry = (variables) => fetch$1({ url: "/dbs/{dbName}/gitBranches", method: "post", ...variables });
413
414
  const removeGitBranchesEntry = (variables) => fetch$1({ url: "/dbs/{dbName}/gitBranches", method: "delete", ...variables });
@@ -551,6 +552,11 @@ const searchBranch = (variables) => fetch$1({
551
552
  method: "post",
552
553
  ...variables
553
554
  });
555
+ const summarizeTable = (variables) => fetch$1({
556
+ url: "/db/{dbBranchName}/tables/{tableName}/summarize",
557
+ method: "post",
558
+ ...variables
559
+ });
554
560
  const operationsByTag = {
555
561
  users: { getUser, updateUser, deleteUser, getUserAPIKeys, createUserAPIKey, deleteUserAPIKey },
556
562
  workspaces: {
@@ -573,6 +579,7 @@ const operationsByTag = {
573
579
  createDatabase,
574
580
  deleteDatabase,
575
581
  getDatabaseMetadata,
582
+ updateDatabaseMetadata,
576
583
  getGitBranchesMapping,
577
584
  addGitBranchesEntry,
578
585
  removeGitBranchesEntry,
@@ -630,7 +637,8 @@ const operationsByTag = {
630
637
  bulkInsertTableRecords,
631
638
  queryTable,
632
639
  searchTable,
633
- searchBranch
640
+ searchBranch,
641
+ summarizeTable
634
642
  }
635
643
  };
636
644
 
@@ -881,6 +889,13 @@ class DatabaseApi {
881
889
  ...this.extraProps
882
890
  });
883
891
  }
892
+ updateDatabaseMetadata(workspace, dbName, options = {}) {
893
+ return operationsByTag.database.updateDatabaseMetadata({
894
+ pathParams: { workspace, dbName },
895
+ body: options,
896
+ ...this.extraProps
897
+ });
898
+ }
884
899
  getGitBranchesMapping(workspace, dbName) {
885
900
  return operationsByTag.database.getGitBranchesMapping({
886
901
  pathParams: { workspace, dbName },
@@ -1107,6 +1122,13 @@ class RecordsApi {
1107
1122
  ...this.extraProps
1108
1123
  });
1109
1124
  }
1125
+ summarizeTable(workspace, database, branch, tableName, query) {
1126
+ return operationsByTag.records.summarizeTable({
1127
+ pathParams: { workspace, dbBranchName: `${database}:${branch}`, tableName },
1128
+ body: query,
1129
+ ...this.extraProps
1130
+ });
1131
+ }
1110
1132
  }
1111
1133
  class MigrationRequestsApi {
1112
1134
  constructor(extraProps) {
@@ -1357,9 +1379,14 @@ var __privateSet$5 = (obj, member, value, setter) => {
1357
1379
  setter ? setter.call(obj, value) : member.set(obj, value);
1358
1380
  return value;
1359
1381
  };
1360
- var _table$1, _repository, _data;
1382
+ var __privateMethod$3 = (obj, member, method) => {
1383
+ __accessCheck$5(obj, member, "access private method");
1384
+ return method;
1385
+ };
1386
+ var _table$1, _repository, _data, _cleanFilterConstraint, cleanFilterConstraint_fn;
1361
1387
  const _Query = class {
1362
1388
  constructor(repository, table, data, rawParent) {
1389
+ __privateAdd$5(this, _cleanFilterConstraint);
1363
1390
  __privateAdd$5(this, _table$1, void 0);
1364
1391
  __privateAdd$5(this, _repository, void 0);
1365
1392
  __privateAdd$5(this, _data, { filter: {} });
@@ -1416,22 +1443,17 @@ const _Query = class {
1416
1443
  }
1417
1444
  filter(a, b) {
1418
1445
  if (arguments.length === 1) {
1419
- const constraints = Object.entries(a ?? {}).map(([column, constraint]) => ({ [column]: constraint }));
1446
+ const constraints = Object.entries(a ?? {}).map(([column, constraint]) => ({
1447
+ [column]: __privateMethod$3(this, _cleanFilterConstraint, cleanFilterConstraint_fn).call(this, column, constraint)
1448
+ }));
1420
1449
  const $all = compact([__privateGet$5(this, _data).filter?.$all].flat().concat(constraints));
1421
1450
  return new _Query(__privateGet$5(this, _repository), __privateGet$5(this, _table$1), { filter: { $all } }, __privateGet$5(this, _data));
1422
1451
  } else {
1423
- const constraints = isDefined(a) && isDefined(b) ? [{ [a]: this.defaultFilter(a, b) }] : void 0;
1452
+ const constraints = isDefined(a) && isDefined(b) ? [{ [a]: __privateMethod$3(this, _cleanFilterConstraint, cleanFilterConstraint_fn).call(this, a, b) }] : void 0;
1424
1453
  const $all = compact([__privateGet$5(this, _data).filter?.$all].flat().concat(constraints));
1425
1454
  return new _Query(__privateGet$5(this, _repository), __privateGet$5(this, _table$1), { filter: { $all } }, __privateGet$5(this, _data));
1426
1455
  }
1427
1456
  }
1428
- defaultFilter(column, value) {
1429
- const columnType = __privateGet$5(this, _table$1).schema?.columns.find(({ name }) => name === column)?.type;
1430
- if (columnType === "multiple" && (isString(value) || isStringArray(value))) {
1431
- return { $includes: value };
1432
- }
1433
- return value;
1434
- }
1435
1457
  sort(column, direction = "asc") {
1436
1458
  const originalSort = [__privateGet$5(this, _data).sort ?? []].flat();
1437
1459
  const sort = [...originalSort, { column, direction }];
@@ -1466,11 +1488,20 @@ const _Query = class {
1466
1488
  }
1467
1489
  }
1468
1490
  async getMany(options = {}) {
1469
- const page = await this.getPaginated(options);
1491
+ const { pagination = {}, ...rest } = options;
1492
+ const { size = PAGINATION_DEFAULT_SIZE, offset } = pagination;
1493
+ const batchSize = size <= PAGINATION_MAX_SIZE ? size : PAGINATION_MAX_SIZE;
1494
+ let page = await this.getPaginated({ ...rest, pagination: { size: batchSize, offset } });
1495
+ const results = [...page.records];
1496
+ while (page.hasNextPage() && results.length < size) {
1497
+ page = await page.nextPage();
1498
+ results.push(...page.records);
1499
+ }
1470
1500
  if (page.hasNextPage() && options.pagination?.size === void 0) {
1471
1501
  console.trace("Calling getMany does not return all results. Paginate to get all results or call getAll.");
1472
1502
  }
1473
- return page.records;
1503
+ const array = new RecordArray(page, results.slice(0, size));
1504
+ return array;
1474
1505
  }
1475
1506
  async getAll(options = {}) {
1476
1507
  const { batchSize = PAGINATION_MAX_SIZE, ...rest } = options;
@@ -1484,6 +1515,12 @@ const _Query = class {
1484
1515
  const records = await this.getMany({ ...options, pagination: { size: 1 } });
1485
1516
  return records[0] ?? null;
1486
1517
  }
1518
+ async getFirstOrThrow(options = {}) {
1519
+ const records = await this.getMany({ ...options, pagination: { size: 1 } });
1520
+ if (records[0] === void 0)
1521
+ throw new Error("No results found.");
1522
+ return records[0];
1523
+ }
1487
1524
  cache(ttl) {
1488
1525
  return new _Query(__privateGet$5(this, _repository), __privateGet$5(this, _table$1), { cache: ttl }, __privateGet$5(this, _data));
1489
1526
  }
@@ -1507,6 +1544,17 @@ let Query = _Query;
1507
1544
  _table$1 = new WeakMap();
1508
1545
  _repository = new WeakMap();
1509
1546
  _data = new WeakMap();
1547
+ _cleanFilterConstraint = new WeakSet();
1548
+ cleanFilterConstraint_fn = function(column, value) {
1549
+ const columnType = __privateGet$5(this, _table$1).schema?.columns.find(({ name }) => name === column)?.type;
1550
+ if (columnType === "multiple" && (isString(value) || isStringArray(value))) {
1551
+ return { $includes: value };
1552
+ }
1553
+ if (columnType === "link" && isObject(value) && isString(value.id)) {
1554
+ return value.id;
1555
+ }
1556
+ return value;
1557
+ };
1510
1558
  function cleanParent(data, parent) {
1511
1559
  if (isCursorPaginationOptions(data.pagination)) {
1512
1560
  return { ...parent, sorting: void 0, filter: void 0 };
@@ -1675,6 +1723,25 @@ class RestRepository extends Query {
1675
1723
  return null;
1676
1724
  });
1677
1725
  }
1726
+ async readOrThrow(a, b) {
1727
+ return __privateGet$4(this, _trace).call(this, "readOrThrow", async () => {
1728
+ const result = await this.read(a, b);
1729
+ if (Array.isArray(result)) {
1730
+ const missingIds = compact(
1731
+ a.filter((_item, index) => result[index] === null).map((item) => extractId(item))
1732
+ );
1733
+ if (missingIds.length > 0) {
1734
+ throw new Error(`Could not find records with ids: ${missingIds.join(", ")}`);
1735
+ }
1736
+ return result;
1737
+ }
1738
+ if (result === null) {
1739
+ const id = extractId(a) ?? "unknown";
1740
+ throw new Error(`Record with id ${id} not found`);
1741
+ }
1742
+ return result;
1743
+ });
1744
+ }
1678
1745
  async update(a, b, c) {
1679
1746
  return __privateGet$4(this, _trace).call(this, "update", async () => {
1680
1747
  if (Array.isArray(a)) {
@@ -1697,6 +1764,25 @@ class RestRepository extends Query {
1697
1764
  throw new Error("Invalid arguments for update method");
1698
1765
  });
1699
1766
  }
1767
+ async updateOrThrow(a, b, c) {
1768
+ return __privateGet$4(this, _trace).call(this, "updateOrThrow", async () => {
1769
+ const result = await this.update(a, b, c);
1770
+ if (Array.isArray(result)) {
1771
+ const missingIds = compact(
1772
+ a.filter((_item, index) => result[index] === null).map((item) => extractId(item))
1773
+ );
1774
+ if (missingIds.length > 0) {
1775
+ throw new Error(`Could not find records with ids: ${missingIds.join(", ")}`);
1776
+ }
1777
+ return result;
1778
+ }
1779
+ if (result === null) {
1780
+ const id = extractId(a) ?? "unknown";
1781
+ throw new Error(`Record with id ${id} not found`);
1782
+ }
1783
+ return result;
1784
+ });
1785
+ }
1700
1786
  async createOrUpdate(a, b, c) {
1701
1787
  return __privateGet$4(this, _trace).call(this, "createOrUpdate", async () => {
1702
1788
  if (Array.isArray(a)) {
@@ -1738,6 +1824,24 @@ class RestRepository extends Query {
1738
1824
  throw new Error("Invalid arguments for delete method");
1739
1825
  });
1740
1826
  }
1827
+ async deleteOrThrow(a, b) {
1828
+ return __privateGet$4(this, _trace).call(this, "deleteOrThrow", async () => {
1829
+ const result = await this.delete(a, b);
1830
+ if (Array.isArray(result)) {
1831
+ const missingIds = compact(
1832
+ a.filter((_item, index) => result[index] === null).map((item) => extractId(item))
1833
+ );
1834
+ if (missingIds.length > 0) {
1835
+ throw new Error(`Could not find records with ids: ${missingIds.join(", ")}`);
1836
+ }
1837
+ return result;
1838
+ } else if (result === null) {
1839
+ const id = extractId(a) ?? "unknown";
1840
+ throw new Error(`Record with id ${id} not found`);
1841
+ }
1842
+ return result;
1843
+ });
1844
+ }
1741
1845
  async search(query, options = {}) {
1742
1846
  return __privateGet$4(this, _trace).call(this, "search", async () => {
1743
1847
  const fetchProps = await __privateGet$4(this, _getFetchProps).call(this);
@@ -1949,9 +2053,17 @@ const initObject = (db, schemaTables, table, object) => {
1949
2053
  console.error(`Failed to parse link for field ${column.name}`);
1950
2054
  } else if (isObject(value)) {
1951
2055
  result[column.name] = initObject(db, schemaTables, linkTable, value);
2056
+ } else {
2057
+ result[column.name] = null;
1952
2058
  }
1953
2059
  break;
1954
2060
  }
2061
+ default:
2062
+ result[column.name] = value ?? null;
2063
+ if (column.notNull === true && value === null) {
2064
+ console.error(`Parse error, column ${column.name} is non nullable and value resolves null`);
2065
+ }
2066
+ break;
1955
2067
  }
1956
2068
  }
1957
2069
  result.read = function(columns2) {
@@ -2591,9 +2703,11 @@ exports.searchTable = searchTable;
2591
2703
  exports.serialize = serialize;
2592
2704
  exports.setTableSchema = setTableSchema;
2593
2705
  exports.startsWith = startsWith;
2706
+ exports.summarizeTable = summarizeTable;
2594
2707
  exports.updateBranchMetadata = updateBranchMetadata;
2595
2708
  exports.updateBranchSchema = updateBranchSchema;
2596
2709
  exports.updateColumn = updateColumn;
2710
+ exports.updateDatabaseMetadata = updateDatabaseMetadata;
2597
2711
  exports.updateMigrationRequest = updateMigrationRequest;
2598
2712
  exports.updateRecordWithID = updateRecordWithID;
2599
2713
  exports.updateTable = updateTable;