@xata.io/client 0.12.0 → 0.13.2

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
@@ -21,7 +21,8 @@ function toBase64(value) {
21
21
  try {
22
22
  return btoa(value);
23
23
  } catch (err) {
24
- return Buffer.from(value).toString("base64");
24
+ const buf = Buffer;
25
+ return buf.from(value).toString("base64");
25
26
  }
26
27
  }
27
28
 
@@ -77,21 +78,28 @@ function getFetchImplementation(userFetch) {
77
78
  return fetchImpl;
78
79
  }
79
80
 
81
+ const VERSION = "0.13.2";
82
+
80
83
  class ErrorWithCause extends Error {
81
84
  constructor(message, options) {
82
85
  super(message, options);
83
86
  }
84
87
  }
85
88
  class FetcherError extends ErrorWithCause {
86
- constructor(status, data) {
89
+ constructor(status, data, requestId) {
87
90
  super(getMessage(data));
88
91
  this.status = status;
89
92
  this.errors = isBulkError(data) ? data.errors : void 0;
93
+ this.requestId = requestId;
90
94
  if (data instanceof Error) {
91
95
  this.stack = data.stack;
92
96
  this.cause = data.cause;
93
97
  }
94
98
  }
99
+ toString() {
100
+ const error = super.toString();
101
+ return `[${this.status}] (${this.requestId ?? "Unknown"}): ${error}`;
102
+ }
95
103
  }
96
104
  function isBulkError(error) {
97
105
  return isObject(error) && Array.isArray(error.errors);
@@ -114,7 +122,12 @@ function getMessage(data) {
114
122
  }
115
123
 
116
124
  const resolveUrl = (url, queryParams = {}, pathParams = {}) => {
117
- const query = new URLSearchParams(queryParams).toString();
125
+ const cleanQueryParams = Object.entries(queryParams).reduce((acc, [key, value]) => {
126
+ if (value === void 0 || value === null)
127
+ return acc;
128
+ return { ...acc, [key]: value };
129
+ }, {});
130
+ const query = new URLSearchParams(cleanQueryParams).toString();
118
131
  const queryString = query.length > 0 ? `?${query}` : "";
119
132
  return url.replace(/\{\w*\}/g, (key) => pathParams[key.slice(1, -1)]) + queryString;
120
133
  };
@@ -154,6 +167,7 @@ async function fetch$1({
154
167
  body: body ? JSON.stringify(body) : void 0,
155
168
  headers: {
156
169
  "Content-Type": "application/json",
170
+ "User-Agent": `Xata client-ts/${VERSION}`,
157
171
  ...headers,
158
172
  ...hostHeader(fullUrl),
159
173
  Authorization: `Bearer ${apiKey}`
@@ -162,14 +176,15 @@ async function fetch$1({
162
176
  if (response.status === 204) {
163
177
  return {};
164
178
  }
179
+ const requestId = response.headers?.get("x-request-id") ?? void 0;
165
180
  try {
166
181
  const jsonResponse = await response.json();
167
182
  if (response.ok) {
168
183
  return jsonResponse;
169
184
  }
170
- throw new FetcherError(response.status, jsonResponse);
185
+ throw new FetcherError(response.status, jsonResponse, requestId);
171
186
  } catch (error) {
172
- throw new FetcherError(response.status, error);
187
+ throw new FetcherError(response.status, error, requestId);
173
188
  }
174
189
  }
175
190
 
@@ -693,10 +708,10 @@ class DatabaseApi {
693
708
  ...this.extraProps
694
709
  });
695
710
  }
696
- resolveBranch(workspace, dbName, gitBranch) {
711
+ resolveBranch(workspace, dbName, gitBranch, fallbackBranch) {
697
712
  return operationsByTag.database.resolveBranch({
698
713
  pathParams: { workspace, dbName },
699
- queryParams: { gitBranch },
714
+ queryParams: { gitBranch, fallbackBranch },
700
715
  ...this.extraProps
701
716
  });
702
717
  }
@@ -946,13 +961,13 @@ var __privateSet$5 = (obj, member, value, setter) => {
946
961
  setter ? setter.call(obj, value) : member.set(obj, value);
947
962
  return value;
948
963
  };
949
- var _query;
964
+ var _query, _page;
950
965
  class Page {
951
966
  constructor(query, meta, records = []) {
952
967
  __privateAdd$6(this, _query, void 0);
953
968
  __privateSet$5(this, _query, query);
954
969
  this.meta = meta;
955
- this.records = records;
970
+ this.records = new RecordArray(this, records);
956
971
  }
957
972
  async nextPage(size, offset) {
958
973
  return __privateGet$6(this, _query).getPaginated({ pagination: { size, offset, after: this.meta.page.cursor } });
@@ -972,12 +987,40 @@ class Page {
972
987
  }
973
988
  _query = new WeakMap();
974
989
  const PAGINATION_MAX_SIZE = 200;
975
- const PAGINATION_DEFAULT_SIZE = 200;
990
+ const PAGINATION_DEFAULT_SIZE = 20;
976
991
  const PAGINATION_MAX_OFFSET = 800;
977
992
  const PAGINATION_DEFAULT_OFFSET = 0;
978
993
  function isCursorPaginationOptions(options) {
979
994
  return isDefined(options) && (isDefined(options.first) || isDefined(options.last) || isDefined(options.after) || isDefined(options.before));
980
995
  }
996
+ const _RecordArray = class extends Array {
997
+ constructor(page, overrideRecords) {
998
+ super(...overrideRecords ?? page.records);
999
+ __privateAdd$6(this, _page, void 0);
1000
+ __privateSet$5(this, _page, page);
1001
+ }
1002
+ async nextPage(size, offset) {
1003
+ const newPage = await __privateGet$6(this, _page).nextPage(size, offset);
1004
+ return new _RecordArray(newPage);
1005
+ }
1006
+ async previousPage(size, offset) {
1007
+ const newPage = await __privateGet$6(this, _page).previousPage(size, offset);
1008
+ return new _RecordArray(newPage);
1009
+ }
1010
+ async firstPage(size, offset) {
1011
+ const newPage = await __privateGet$6(this, _page).firstPage(size, offset);
1012
+ return new _RecordArray(newPage);
1013
+ }
1014
+ async lastPage(size, offset) {
1015
+ const newPage = await __privateGet$6(this, _page).lastPage(size, offset);
1016
+ return new _RecordArray(newPage);
1017
+ }
1018
+ hasNextPage() {
1019
+ return __privateGet$6(this, _page).meta.page.more;
1020
+ }
1021
+ };
1022
+ let RecordArray = _RecordArray;
1023
+ _page = new WeakMap();
981
1024
 
982
1025
  var __accessCheck$5 = (obj, member, msg) => {
983
1026
  if (!member.has(obj))
@@ -1004,7 +1047,7 @@ const _Query = class {
1004
1047
  __privateAdd$5(this, _repository, void 0);
1005
1048
  __privateAdd$5(this, _data, { filter: {} });
1006
1049
  this.meta = { page: { cursor: "start", more: true } };
1007
- this.records = [];
1050
+ this.records = new RecordArray(this, []);
1008
1051
  __privateSet$4(this, _table$1, table);
1009
1052
  if (repository) {
1010
1053
  __privateSet$4(this, _repository, repository);
@@ -1093,8 +1136,11 @@ const _Query = class {
1093
1136
  }
1094
1137
  }
1095
1138
  async getMany(options = {}) {
1096
- const { records } = await this.getPaginated(options);
1097
- return records;
1139
+ const page = await this.getPaginated(options);
1140
+ if (page.hasNextPage() && options.pagination?.size === void 0) {
1141
+ console.trace("Calling getMany does not return all results. Paginate to get all results or call getAll.");
1142
+ }
1143
+ return page.records;
1098
1144
  }
1099
1145
  async getAll(options = {}) {
1100
1146
  const { batchSize = PAGINATION_MAX_SIZE, ...rest } = options;
@@ -1223,9 +1269,29 @@ class RestRepository extends Query {
1223
1269
  if (Array.isArray(a)) {
1224
1270
  if (a.length === 0)
1225
1271
  return [];
1226
- const records = await __privateMethod$2(this, _bulkInsertTableRecords, bulkInsertTableRecords_fn).call(this, a);
1227
- await Promise.all(records.map((record) => __privateMethod$2(this, _setCacheRecord, setCacheRecord_fn).call(this, record)));
1228
- return records;
1272
+ const [itemsWithoutIds, itemsWithIds, order] = a.reduce(([accWithoutIds, accWithIds, accOrder], item) => {
1273
+ const condition = isString(item.id);
1274
+ accOrder.push(condition);
1275
+ if (condition) {
1276
+ accWithIds.push(item);
1277
+ } else {
1278
+ accWithoutIds.push(item);
1279
+ }
1280
+ return [accWithoutIds, accWithIds, accOrder];
1281
+ }, [[], [], []]);
1282
+ const recordsWithoutId = await __privateMethod$2(this, _bulkInsertTableRecords, bulkInsertTableRecords_fn).call(this, itemsWithoutIds);
1283
+ await Promise.all(recordsWithoutId.map((record) => __privateMethod$2(this, _setCacheRecord, setCacheRecord_fn).call(this, record)));
1284
+ if (itemsWithIds.length > 100) {
1285
+ console.warn("Bulk create operation with id is not optimized in the Xata API yet, this request might be slow");
1286
+ }
1287
+ const recordsWithId = await Promise.all(itemsWithIds.map((object) => this.create(object)));
1288
+ return order.map((condition) => {
1289
+ if (condition) {
1290
+ return recordsWithId.shift();
1291
+ } else {
1292
+ return recordsWithoutId.shift();
1293
+ }
1294
+ }).filter((record) => !!record);
1229
1295
  }
1230
1296
  if (isString(a) && isObject(b)) {
1231
1297
  if (a === "")
@@ -1252,16 +1318,18 @@ class RestRepository extends Query {
1252
1318
  if (Array.isArray(a)) {
1253
1319
  if (a.length === 0)
1254
1320
  return [];
1255
- return this.getAll({ filter: { id: { $any: a } } });
1321
+ const ids = a.map((item) => isString(item) ? item : item.id).filter((id2) => isString(id2));
1322
+ return this.getAll({ filter: { id: { $any: ids } } });
1256
1323
  }
1257
- if (isString(a)) {
1258
- const cacheRecord = await __privateMethod$2(this, _getCacheRecord, getCacheRecord_fn).call(this, a);
1324
+ const id = isString(a) ? a : a.id;
1325
+ if (isString(id)) {
1326
+ const cacheRecord = await __privateMethod$2(this, _getCacheRecord, getCacheRecord_fn).call(this, id);
1259
1327
  if (cacheRecord)
1260
1328
  return cacheRecord;
1261
1329
  const fetchProps = await __privateGet$4(this, _getFetchProps).call(this);
1262
1330
  try {
1263
1331
  const response = await getRecord({
1264
- pathParams: { workspace: "{workspaceId}", dbBranchName: "{dbBranch}", tableName: __privateGet$4(this, _table), recordId: a },
1332
+ pathParams: { workspace: "{workspaceId}", dbBranchName: "{dbBranch}", tableName: __privateGet$4(this, _table), recordId: id },
1265
1333
  ...fetchProps
1266
1334
  });
1267
1335
  const schema = await __privateMethod$2(this, _getSchema$1, getSchema_fn$1).call(this);
@@ -1433,7 +1501,7 @@ bulkInsertTableRecords_fn = async function(objects) {
1433
1501
  body: { records },
1434
1502
  ...fetchProps
1435
1503
  });
1436
- const finalObjects = await this.any(...response.recordIDs.map((id) => this.filter("id", id))).getAll();
1504
+ const finalObjects = await this.read(response.recordIDs);
1437
1505
  if (finalObjects.length !== objects.length) {
1438
1506
  throw new Error("The server failed to save some records");
1439
1507
  }
@@ -1837,10 +1905,7 @@ async function getDatabaseBranch(branch, options) {
1837
1905
  apiUrl: databaseURL,
1838
1906
  fetchImpl: getFetchImplementation(options?.fetchImpl),
1839
1907
  workspacesApiUrl: `${protocol}//${host}`,
1840
- pathParams: {
1841
- dbBranchName,
1842
- workspace
1843
- }
1908
+ pathParams: { dbBranchName, workspace }
1844
1909
  });
1845
1910
  } catch (err) {
1846
1911
  if (isObject(err) && err.status === 404)
@@ -1985,6 +2050,7 @@ exports.PAGINATION_MAX_OFFSET = PAGINATION_MAX_OFFSET;
1985
2050
  exports.PAGINATION_MAX_SIZE = PAGINATION_MAX_SIZE;
1986
2051
  exports.Page = Page;
1987
2052
  exports.Query = Query;
2053
+ exports.RecordArray = RecordArray;
1988
2054
  exports.Repository = Repository;
1989
2055
  exports.RestRepository = RestRepository;
1990
2056
  exports.SchemaPlugin = SchemaPlugin;