@xata.io/client 0.11.0 → 0.13.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/dist/index.cjs CHANGED
@@ -77,6 +77,8 @@ function getFetchImplementation(userFetch) {
77
77
  return fetchImpl;
78
78
  }
79
79
 
80
+ const VERSION = "0.13.1";
81
+
80
82
  class ErrorWithCause extends Error {
81
83
  constructor(message, options) {
82
84
  super(message, options);
@@ -114,7 +116,12 @@ function getMessage(data) {
114
116
  }
115
117
 
116
118
  const resolveUrl = (url, queryParams = {}, pathParams = {}) => {
117
- const query = new URLSearchParams(queryParams).toString();
119
+ const cleanQueryParams = Object.entries(queryParams).reduce((acc, [key, value]) => {
120
+ if (value === void 0 || value === null)
121
+ return acc;
122
+ return { ...acc, [key]: value };
123
+ }, {});
124
+ const query = new URLSearchParams(cleanQueryParams).toString();
118
125
  const queryString = query.length > 0 ? `?${query}` : "";
119
126
  return url.replace(/\{\w*\}/g, (key) => pathParams[key.slice(1, -1)]) + queryString;
120
127
  };
@@ -154,6 +161,7 @@ async function fetch$1({
154
161
  body: body ? JSON.stringify(body) : void 0,
155
162
  headers: {
156
163
  "Content-Type": "application/json",
164
+ "User-Agent": `Xata client-ts/${VERSION}`,
157
165
  ...headers,
158
166
  ...hostHeader(fullUrl),
159
167
  Authorization: `Bearer ${apiKey}`
@@ -693,10 +701,10 @@ class DatabaseApi {
693
701
  ...this.extraProps
694
702
  });
695
703
  }
696
- resolveBranch(workspace, dbName, gitBranch) {
704
+ resolveBranch(workspace, dbName, gitBranch, fallbackBranch) {
697
705
  return operationsByTag.database.resolveBranch({
698
706
  pathParams: { workspace, dbName },
699
- queryParams: { gitBranch },
707
+ queryParams: { gitBranch, fallbackBranch },
700
708
  ...this.extraProps
701
709
  });
702
710
  }
@@ -946,13 +954,13 @@ var __privateSet$5 = (obj, member, value, setter) => {
946
954
  setter ? setter.call(obj, value) : member.set(obj, value);
947
955
  return value;
948
956
  };
949
- var _query;
957
+ var _query, _page;
950
958
  class Page {
951
959
  constructor(query, meta, records = []) {
952
960
  __privateAdd$6(this, _query, void 0);
953
961
  __privateSet$5(this, _query, query);
954
962
  this.meta = meta;
955
- this.records = records;
963
+ this.records = new RecordArray(this, records);
956
964
  }
957
965
  async nextPage(size, offset) {
958
966
  return __privateGet$6(this, _query).getPaginated({ pagination: { size, offset, after: this.meta.page.cursor } });
@@ -972,12 +980,40 @@ class Page {
972
980
  }
973
981
  _query = new WeakMap();
974
982
  const PAGINATION_MAX_SIZE = 200;
975
- const PAGINATION_DEFAULT_SIZE = 200;
983
+ const PAGINATION_DEFAULT_SIZE = 20;
976
984
  const PAGINATION_MAX_OFFSET = 800;
977
985
  const PAGINATION_DEFAULT_OFFSET = 0;
978
986
  function isCursorPaginationOptions(options) {
979
987
  return isDefined(options) && (isDefined(options.first) || isDefined(options.last) || isDefined(options.after) || isDefined(options.before));
980
988
  }
989
+ const _RecordArray = class extends Array {
990
+ constructor(page, overrideRecords) {
991
+ super(...overrideRecords ?? page.records);
992
+ __privateAdd$6(this, _page, void 0);
993
+ __privateSet$5(this, _page, page);
994
+ }
995
+ async nextPage(size, offset) {
996
+ const newPage = await __privateGet$6(this, _page).nextPage(size, offset);
997
+ return new _RecordArray(newPage);
998
+ }
999
+ async previousPage(size, offset) {
1000
+ const newPage = await __privateGet$6(this, _page).previousPage(size, offset);
1001
+ return new _RecordArray(newPage);
1002
+ }
1003
+ async firstPage(size, offset) {
1004
+ const newPage = await __privateGet$6(this, _page).firstPage(size, offset);
1005
+ return new _RecordArray(newPage);
1006
+ }
1007
+ async lastPage(size, offset) {
1008
+ const newPage = await __privateGet$6(this, _page).lastPage(size, offset);
1009
+ return new _RecordArray(newPage);
1010
+ }
1011
+ hasNextPage() {
1012
+ return __privateGet$6(this, _page).meta.page.more;
1013
+ }
1014
+ };
1015
+ let RecordArray = _RecordArray;
1016
+ _page = new WeakMap();
981
1017
 
982
1018
  var __accessCheck$5 = (obj, member, msg) => {
983
1019
  if (!member.has(obj))
@@ -1004,7 +1040,7 @@ const _Query = class {
1004
1040
  __privateAdd$5(this, _repository, void 0);
1005
1041
  __privateAdd$5(this, _data, { filter: {} });
1006
1042
  this.meta = { page: { cursor: "start", more: true } };
1007
- this.records = [];
1043
+ this.records = new RecordArray(this, []);
1008
1044
  __privateSet$4(this, _table$1, table);
1009
1045
  if (repository) {
1010
1046
  __privateSet$4(this, _repository, repository);
@@ -1093,8 +1129,11 @@ const _Query = class {
1093
1129
  }
1094
1130
  }
1095
1131
  async getMany(options = {}) {
1096
- const { records } = await this.getPaginated(options);
1097
- return records;
1132
+ const page = await this.getPaginated(options);
1133
+ if (page.hasNextPage() && options.pagination?.size === void 0) {
1134
+ console.trace("Calling getMany does not return all results. Paginate to get all results or call getAll.");
1135
+ }
1136
+ return page.records;
1098
1137
  }
1099
1138
  async getAll(options = {}) {
1100
1139
  const { batchSize = PAGINATION_MAX_SIZE, ...rest } = options;
@@ -1142,7 +1181,9 @@ function isIdentifiable(x) {
1142
1181
  return isObject(x) && isString(x?.id);
1143
1182
  }
1144
1183
  function isXataRecord(x) {
1145
- return isIdentifiable(x) && typeof x?.xata === "object" && typeof x?.xata?.version === "number";
1184
+ const record = x;
1185
+ const metadata = record?.getMetadata();
1186
+ return isIdentifiable(x) && isObject(metadata) && typeof metadata.version === "number";
1146
1187
  }
1147
1188
 
1148
1189
  function isSortFilterString(value) {
@@ -1221,9 +1262,29 @@ class RestRepository extends Query {
1221
1262
  if (Array.isArray(a)) {
1222
1263
  if (a.length === 0)
1223
1264
  return [];
1224
- const records = await __privateMethod$2(this, _bulkInsertTableRecords, bulkInsertTableRecords_fn).call(this, a);
1225
- await Promise.all(records.map((record) => __privateMethod$2(this, _setCacheRecord, setCacheRecord_fn).call(this, record)));
1226
- return records;
1265
+ const [itemsWithoutIds, itemsWithIds, order] = a.reduce(([accWithoutIds, accWithIds, accOrder], item) => {
1266
+ const condition = isString(item.id);
1267
+ accOrder.push(condition);
1268
+ if (condition) {
1269
+ accWithIds.push(item);
1270
+ } else {
1271
+ accWithoutIds.push(item);
1272
+ }
1273
+ return [accWithoutIds, accWithIds, accOrder];
1274
+ }, [[], [], []]);
1275
+ const recordsWithoutId = await __privateMethod$2(this, _bulkInsertTableRecords, bulkInsertTableRecords_fn).call(this, itemsWithoutIds);
1276
+ await Promise.all(recordsWithoutId.map((record) => __privateMethod$2(this, _setCacheRecord, setCacheRecord_fn).call(this, record)));
1277
+ if (itemsWithIds.length > 100) {
1278
+ console.warn("Bulk create operation with id is not optimized in the Xata API yet, this request might be slow");
1279
+ }
1280
+ const recordsWithId = await Promise.all(itemsWithIds.map((object) => this.create(object)));
1281
+ return order.map((condition) => {
1282
+ if (condition) {
1283
+ return recordsWithId.shift();
1284
+ } else {
1285
+ return recordsWithoutId.shift();
1286
+ }
1287
+ }).filter((record) => !!record);
1227
1288
  }
1228
1289
  if (isString(a) && isObject(b)) {
1229
1290
  if (a === "")
@@ -1250,16 +1311,18 @@ class RestRepository extends Query {
1250
1311
  if (Array.isArray(a)) {
1251
1312
  if (a.length === 0)
1252
1313
  return [];
1253
- return this.getAll({ filter: { id: { $any: a } } });
1314
+ const ids = a.map((item) => isString(item) ? item : item.id).filter((id2) => isString(id2));
1315
+ return this.getAll({ filter: { id: { $any: ids } } });
1254
1316
  }
1255
- if (isString(a)) {
1256
- const cacheRecord = await __privateMethod$2(this, _getCacheRecord, getCacheRecord_fn).call(this, a);
1317
+ const id = isString(a) ? a : a.id;
1318
+ if (isString(id)) {
1319
+ const cacheRecord = await __privateMethod$2(this, _getCacheRecord, getCacheRecord_fn).call(this, id);
1257
1320
  if (cacheRecord)
1258
1321
  return cacheRecord;
1259
1322
  const fetchProps = await __privateGet$4(this, _getFetchProps).call(this);
1260
1323
  try {
1261
1324
  const response = await getRecord({
1262
- pathParams: { workspace: "{workspaceId}", dbBranchName: "{dbBranch}", tableName: __privateGet$4(this, _table), recordId: a },
1325
+ pathParams: { workspace: "{workspaceId}", dbBranchName: "{dbBranch}", tableName: __privateGet$4(this, _table), recordId: id },
1263
1326
  ...fetchProps
1264
1327
  });
1265
1328
  const schema = await __privateMethod$2(this, _getSchema$1, getSchema_fn$1).call(this);
@@ -1431,7 +1494,7 @@ bulkInsertTableRecords_fn = async function(objects) {
1431
1494
  body: { records },
1432
1495
  ...fetchProps
1433
1496
  });
1434
- const finalObjects = await this.any(...response.recordIDs.map((id) => this.filter("id", id))).getAll();
1497
+ const finalObjects = await this.read(response.recordIDs);
1435
1498
  if (finalObjects.length !== objects.length) {
1436
1499
  throw new Error("The server failed to save some records");
1437
1500
  }
@@ -1532,7 +1595,8 @@ const transformObjectLinks = (object) => {
1532
1595
  };
1533
1596
  const initObject = (db, schema, table, object) => {
1534
1597
  const result = {};
1535
- Object.assign(result, object);
1598
+ const { xata, ...rest } = object ?? {};
1599
+ Object.assign(result, rest);
1536
1600
  const { columns } = schema.tables.find(({ name }) => name === table) ?? {};
1537
1601
  if (!columns)
1538
1602
  console.error(`Table ${table} not found in schema`);
@@ -1540,10 +1604,10 @@ const initObject = (db, schema, table, object) => {
1540
1604
  const value = result[column.name];
1541
1605
  switch (column.type) {
1542
1606
  case "datetime": {
1543
- const date = new Date(value);
1544
- if (isNaN(date.getTime())) {
1607
+ const date = value !== void 0 ? new Date(value) : void 0;
1608
+ if (date && isNaN(date.getTime())) {
1545
1609
  console.error(`Failed to parse date ${value} for field ${column.name}`);
1546
- } else {
1610
+ } else if (date) {
1547
1611
  result[column.name] = date;
1548
1612
  }
1549
1613
  break;
@@ -1568,7 +1632,10 @@ const initObject = (db, schema, table, object) => {
1568
1632
  result.delete = function() {
1569
1633
  return db[table].delete(result["id"]);
1570
1634
  };
1571
- for (const prop of ["read", "update", "delete"]) {
1635
+ result.getMetadata = function() {
1636
+ return xata;
1637
+ };
1638
+ for (const prop of ["read", "update", "delete", "getMetadata"]) {
1572
1639
  Object.defineProperty(result, prop, { enumerable: false });
1573
1640
  }
1574
1641
  Object.freeze(result);
@@ -1831,10 +1898,7 @@ async function getDatabaseBranch(branch, options) {
1831
1898
  apiUrl: databaseURL,
1832
1899
  fetchImpl: getFetchImplementation(options?.fetchImpl),
1833
1900
  workspacesApiUrl: `${protocol}//${host}`,
1834
- pathParams: {
1835
- dbBranchName,
1836
- workspace
1837
- }
1901
+ pathParams: { dbBranchName, workspace }
1838
1902
  });
1839
1903
  } catch (err) {
1840
1904
  if (isObject(err) && err.status === 404)
@@ -1979,6 +2043,7 @@ exports.PAGINATION_MAX_OFFSET = PAGINATION_MAX_OFFSET;
1979
2043
  exports.PAGINATION_MAX_SIZE = PAGINATION_MAX_SIZE;
1980
2044
  exports.Page = Page;
1981
2045
  exports.Query = Query;
2046
+ exports.RecordArray = RecordArray;
1982
2047
  exports.Repository = Repository;
1983
2048
  exports.RestRepository = RestRepository;
1984
2049
  exports.SchemaPlugin = SchemaPlugin;