@boltic/sdk 0.0.6 → 0.0.8

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.
@@ -1,3 +1,9 @@
1
+ function isErrorResponse(response) {
2
+ return "error" in response && response.error !== void 0;
3
+ }
4
+ function isListResponse(response) {
5
+ return "pagination" in response;
6
+ }
1
7
  class ValidationError extends Error {
2
8
  constructor(message, failures = []) {
3
9
  super(message);
@@ -150,6 +156,39 @@ class AxiosAdapter {
150
156
  // Don't throw on non-2xx status codes
151
157
  };
152
158
  const response = await this.axios(axiosConfig);
159
+ if (response.status < 200 || response.status >= 300) {
160
+ const isHtmlError = typeof response.data === "string" && response.data.trim().startsWith("<!DOCTYPE") || typeof response.data === "string" && response.data.includes("<html");
161
+ if (isHtmlError) {
162
+ const htmlContent = response.data;
163
+ const preMatch = htmlContent.match(/<pre>(.*?)<\/pre>/s);
164
+ const errorMessage = preMatch ? preMatch[1].trim() : `HTTP ${response.status}: ${response.statusText}`;
165
+ throw createErrorWithContext(errorMessage, {
166
+ url: config.url,
167
+ method: config.method,
168
+ status: response.status,
169
+ statusText: response.statusText,
170
+ isHtmlError: true
171
+ });
172
+ }
173
+ if (response.data && typeof response.data === "object" && "error" in response.data) {
174
+ return {
175
+ data: response.data,
176
+ status: response.status,
177
+ statusText: response.statusText,
178
+ headers: response.headers || {}
179
+ };
180
+ }
181
+ throw createErrorWithContext(
182
+ `HTTP ${response.status}: ${response.statusText}`,
183
+ {
184
+ url: config.url,
185
+ method: config.method,
186
+ status: response.status,
187
+ statusText: response.statusText,
188
+ responseData: response.data
189
+ }
190
+ );
191
+ }
153
192
  return {
154
193
  data: response.data,
155
194
  status: response.status,
@@ -248,6 +287,39 @@ class FetchAdapter {
248
287
  response.headers.forEach((value, key) => {
249
288
  headers[key] = value;
250
289
  });
290
+ if (response.status < 200 || response.status >= 300) {
291
+ const isHtmlError = typeof data === "string" && (data.trim().startsWith("<!DOCTYPE") || data.includes("<html"));
292
+ if (isHtmlError) {
293
+ const htmlContent = data;
294
+ const preMatch = htmlContent.match(/<pre>(.*?)<\/pre>/s);
295
+ const errorMessage = preMatch ? preMatch[1].trim() : `HTTP ${response.status}: ${response.statusText}`;
296
+ throw createErrorWithContext(errorMessage, {
297
+ url: config.url,
298
+ method: config.method,
299
+ status: response.status,
300
+ statusText: response.statusText,
301
+ isHtmlError: true
302
+ });
303
+ }
304
+ if (data && typeof data === "object" && "error" in data) {
305
+ return {
306
+ data,
307
+ status: response.status,
308
+ statusText: response.statusText,
309
+ headers
310
+ };
311
+ }
312
+ throw createErrorWithContext(
313
+ `HTTP ${response.status}: ${response.statusText}`,
314
+ {
315
+ url: config.url,
316
+ method: config.method,
317
+ status: response.status,
318
+ statusText: response.statusText,
319
+ responseData: data
320
+ }
321
+ );
322
+ }
251
323
  const httpResponse = {
252
324
  data,
253
325
  status: response.status,
@@ -579,6 +651,13 @@ function filterArrayFields(arr, fields) {
579
651
  }
580
652
  return arr.map((obj) => filterObjectFields(obj, fields));
581
653
  }
654
+ function addDbIdToUrl(url, dbId) {
655
+ if (!dbId || dbId === "") {
656
+ return url;
657
+ }
658
+ const separator = url.includes("?") ? "&" : "?";
659
+ return `${url}${separator}db_id=${encodeURIComponent(dbId)}`;
660
+ }
582
661
  const COLUMN_ENDPOINTS = {
583
662
  list: {
584
663
  path: "/tables/{table_id}/fields/list",
@@ -812,7 +891,8 @@ class ColumnsApiClient {
812
891
  async listColumns(tableId, options = {}) {
813
892
  try {
814
893
  const endpoint = COLUMN_ENDPOINTS.list;
815
- const url = `${this.baseURL}${buildEndpointPath$1(endpoint, { table_id: tableId })}?no_cache=true`;
894
+ let url = `${this.baseURL}${buildEndpointPath$1(endpoint, { table_id: tableId })}?no_cache=true`;
895
+ url = addDbIdToUrl(url, options.db_id);
816
896
  const response = await this.httpAdapter.request({
817
897
  url,
818
898
  method: endpoint.method,
@@ -1442,7 +1522,8 @@ class TablesApiClient {
1442
1522
  async createTable(request, options = {}) {
1443
1523
  try {
1444
1524
  const endpoint = TABLE_ENDPOINTS.create;
1445
- const url = `${this.baseURL}${endpoint.path}`;
1525
+ let url = `${this.baseURL}${endpoint.path}`;
1526
+ url = addDbIdToUrl(url, options.db_id);
1446
1527
  const transformedRequest = transformTableCreateRequest(request, options);
1447
1528
  const response = await this.httpAdapter.request({
1448
1529
  url,
@@ -1462,7 +1543,8 @@ class TablesApiClient {
1462
1543
  async listTables(options = {}) {
1463
1544
  try {
1464
1545
  const endpoint = TABLE_ENDPOINTS.list;
1465
- const url = `${this.baseURL}${endpoint.path}`;
1546
+ let url = `${this.baseURL}${endpoint.path}`;
1547
+ url = addDbIdToUrl(url, options.db_id);
1466
1548
  const response = await this.httpAdapter.request({
1467
1549
  url,
1468
1550
  method: endpoint.method,
@@ -1488,7 +1570,8 @@ class TablesApiClient {
1488
1570
  async getTable(tableId, options = {}) {
1489
1571
  try {
1490
1572
  const endpoint = TABLE_ENDPOINTS.get;
1491
- const url = `${this.baseURL}${buildEndpointPath(endpoint, { table_id: tableId })}`;
1573
+ let url = `${this.baseURL}${buildEndpointPath(endpoint, { table_id: tableId })}`;
1574
+ url = addDbIdToUrl(url, options.db_id);
1492
1575
  const response = await this.httpAdapter.request({
1493
1576
  url,
1494
1577
  method: endpoint.method,
@@ -1512,9 +1595,10 @@ class TablesApiClient {
1512
1595
  */
1513
1596
  async updateTable(tableId, updates) {
1514
1597
  try {
1515
- const { fields, ...updateData } = updates;
1598
+ const { fields, db_id, ...updateData } = updates;
1516
1599
  const endpoint = TABLE_ENDPOINTS.update;
1517
- const url = `${this.baseURL}${buildEndpointPath(endpoint, { table_id: tableId })}`;
1600
+ let url = `${this.baseURL}${buildEndpointPath(endpoint, { table_id: tableId })}`;
1601
+ url = addDbIdToUrl(url, db_id);
1518
1602
  const response = await this.httpAdapter.request({
1519
1603
  url,
1520
1604
  method: endpoint.method,
@@ -1537,10 +1621,11 @@ class TablesApiClient {
1537
1621
  /**
1538
1622
  * Delete a table
1539
1623
  */
1540
- async deleteTable(tableId) {
1624
+ async deleteTable(tableId, options = {}) {
1541
1625
  try {
1542
1626
  const endpoint = TABLE_ENDPOINTS.delete;
1543
- const url = `${this.baseURL}${buildEndpointPath(endpoint, { table_id: tableId })}`;
1627
+ let url = `${this.baseURL}${buildEndpointPath(endpoint, { table_id: tableId })}`;
1628
+ url = addDbIdToUrl(url, options.db_id);
1544
1629
  const response = await this.httpAdapter.request({
1545
1630
  url,
1546
1631
  method: endpoint.method,
@@ -1596,12 +1681,6 @@ class TablesApiClient {
1596
1681
  };
1597
1682
  }
1598
1683
  }
1599
- function isErrorResponse(response) {
1600
- return "error" in response && response.error !== void 0;
1601
- }
1602
- function isListResponse(response) {
1603
- return "pagination" in response;
1604
- }
1605
1684
  class BaseResource {
1606
1685
  constructor(client, basePath) {
1607
1686
  this.client = client;
@@ -1703,13 +1782,16 @@ class TableResource extends BaseResource {
1703
1782
  /**
1704
1783
  * Create a new table
1705
1784
  */
1706
- async create(data) {
1785
+ async create(data, dbId) {
1707
1786
  try {
1708
1787
  const processedData = { ...data };
1709
1788
  if (data.fields && data.fields.length > 0) {
1710
1789
  processedData.fields = await this.processFieldsDefaults(data.fields);
1711
1790
  }
1712
- const result = await this.tablesApiClient.createTable(processedData);
1791
+ const result = await this.tablesApiClient.createTable(
1792
+ processedData,
1793
+ dbId ? { db_id: dbId } : {}
1794
+ );
1713
1795
  if (isErrorResponse(result)) {
1714
1796
  throw new ApiError(
1715
1797
  result.error.message || "Create table failed",
@@ -1792,12 +1874,14 @@ class TableResource extends BaseResource {
1792
1874
  /**
1793
1875
  * Find all tables with optional filtering
1794
1876
  */
1795
- async findAll(options = {}) {
1877
+ async findAll(options = {}, dbId) {
1796
1878
  try {
1797
1879
  const apiRequest = this.transformTableQueryToApiRequest(options);
1798
- const result = await this.tablesApiClient.listTables(
1799
- apiRequest
1800
- );
1880
+ const listOptions = {
1881
+ ...apiRequest,
1882
+ ...dbId && { db_id: dbId }
1883
+ };
1884
+ const result = await this.tablesApiClient.listTables(listOptions);
1801
1885
  if (isErrorResponse(result)) {
1802
1886
  throw new ApiError(
1803
1887
  result.error.message || "List tables failed",
@@ -1813,7 +1897,7 @@ class TableResource extends BaseResource {
1813
1897
  /**
1814
1898
  * Find a single table by ID or name
1815
1899
  */
1816
- async findOne(options) {
1900
+ async findOne(options, dbId) {
1817
1901
  var _a, _b, _c;
1818
1902
  try {
1819
1903
  if (!((_a = options.where) == null ? void 0 : _a.id) && !((_b = options.where) == null ? void 0 : _b.name)) {
@@ -1823,7 +1907,8 @@ class TableResource extends BaseResource {
1823
1907
  }
1824
1908
  if ((_c = options.where) == null ? void 0 : _c.id) {
1825
1909
  const result = await this.tablesApiClient.getTable(
1826
- options.where.id
1910
+ options.where.id,
1911
+ dbId ? { db_id: dbId } : {}
1827
1912
  );
1828
1913
  if (isErrorResponse(result)) {
1829
1914
  if (result.error.code === "TABLE_NOT_FOUND") {
@@ -1851,9 +1936,11 @@ class TableResource extends BaseResource {
1851
1936
  ],
1852
1937
  sort: []
1853
1938
  };
1854
- const listResult = await this.tablesApiClient.listTables(
1855
- apiRequest
1856
- );
1939
+ const listOptions = {
1940
+ ...apiRequest,
1941
+ ...dbId && { db_id: dbId }
1942
+ };
1943
+ const listResult = await this.tablesApiClient.listTables(listOptions);
1857
1944
  if (isErrorResponse(listResult)) {
1858
1945
  throw new ApiError(
1859
1946
  listResult.error.message || "Find table by name failed",
@@ -1874,21 +1961,21 @@ class TableResource extends BaseResource {
1874
1961
  /**
1875
1962
  * Find a single table by name
1876
1963
  */
1877
- async findByName(name) {
1878
- return this.findOne({ where: { name } });
1964
+ async findByName(name, dbId) {
1965
+ return this.findOne({ where: { name } }, dbId);
1879
1966
  }
1880
1967
  /**
1881
1968
  * Find a single table by ID
1882
1969
  */
1883
- async findById(id) {
1884
- return this.findOne({ where: { id } });
1970
+ async findById(id, dbId) {
1971
+ return this.findOne({ where: { id } }, dbId);
1885
1972
  }
1886
1973
  /**
1887
1974
  * Update a table by name
1888
1975
  */
1889
- async update(name, data) {
1976
+ async update(name, data, dbId) {
1890
1977
  try {
1891
- const tableResult = await this.findByName(name);
1978
+ const tableResult = await this.findByName(name, dbId);
1892
1979
  if (!tableResult.data) {
1893
1980
  throw new ApiError(`Table '${name}' not found`, 404);
1894
1981
  }
@@ -1900,7 +1987,7 @@ class TableResource extends BaseResource {
1900
1987
  }
1901
1988
  const result = await this.tablesApiClient.updateTable(
1902
1989
  tableResult.data.id,
1903
- data
1990
+ dbId ? { ...data, db_id: dbId } : data
1904
1991
  );
1905
1992
  if (isErrorResponse(result)) {
1906
1993
  throw new ApiError(
@@ -1917,9 +2004,9 @@ class TableResource extends BaseResource {
1917
2004
  /**
1918
2005
  * Delete a table by name
1919
2006
  */
1920
- async delete(name) {
2007
+ async delete(name, dbId) {
1921
2008
  try {
1922
- const tableResult = await this.findByName(name);
2009
+ const tableResult = await this.findByName(name, dbId);
1923
2010
  if (!tableResult.data) {
1924
2011
  throw new ApiError(`Table '${name}' not found`, 404);
1925
2012
  }
@@ -1930,7 +2017,8 @@ class TableResource extends BaseResource {
1930
2017
  );
1931
2018
  }
1932
2019
  const result = await this.tablesApiClient.deleteTable(
1933
- tableResult.data.id
2020
+ tableResult.data.id,
2021
+ dbId ? { db_id: dbId } : {}
1934
2022
  );
1935
2023
  if (isErrorResponse(result)) {
1936
2024
  throw new ApiError(
@@ -1947,11 +2035,15 @@ class TableResource extends BaseResource {
1947
2035
  /**
1948
2036
  * Rename a table
1949
2037
  */
1950
- async rename(oldName, newName) {
2038
+ async rename(oldName, newName, dbId) {
1951
2039
  try {
1952
- const result = await this.update(oldName, {
1953
- name: newName
1954
- });
2040
+ const result = await this.update(
2041
+ oldName,
2042
+ {
2043
+ name: newName
2044
+ },
2045
+ dbId
2046
+ );
1955
2047
  return result;
1956
2048
  } catch (error) {
1957
2049
  throw error instanceof ApiError ? error : new ApiError(this.formatError(error), 500);
@@ -1960,11 +2052,15 @@ class TableResource extends BaseResource {
1960
2052
  /**
1961
2053
  * Set table access permissions
1962
2054
  */
1963
- async setAccess(request) {
2055
+ async setAccess(request, dbId) {
1964
2056
  try {
1965
- const result = await this.update(request.table_name, {
1966
- is_shared: request.is_shared
1967
- });
2057
+ const result = await this.update(
2058
+ request.table_name,
2059
+ {
2060
+ is_shared: request.is_shared
2061
+ },
2062
+ dbId
2063
+ );
1968
2064
  return result;
1969
2065
  } catch (error) {
1970
2066
  throw error instanceof ApiError ? error : new ApiError(this.formatError(error), 500);
@@ -2355,6 +2451,652 @@ class ColumnResource extends BaseResource {
2355
2451
  return (tableInfo == null ? void 0 : tableInfo.id) || null;
2356
2452
  }
2357
2453
  }
2454
+ const DATABASE_ENDPOINTS = {
2455
+ create: {
2456
+ path: "/tables/databases",
2457
+ method: "POST",
2458
+ authenticated: true
2459
+ },
2460
+ list: {
2461
+ path: "/tables/databases/list",
2462
+ method: "POST",
2463
+ authenticated: true
2464
+ },
2465
+ update: {
2466
+ path: "/tables/databases/{db_id}",
2467
+ method: "PATCH",
2468
+ authenticated: true
2469
+ },
2470
+ delete: {
2471
+ path: "/tables/databases/{db_id}",
2472
+ method: "DELETE",
2473
+ authenticated: true
2474
+ },
2475
+ listJobs: {
2476
+ path: "/tables/databases/jobs/list",
2477
+ method: "POST",
2478
+ authenticated: true
2479
+ },
2480
+ pollDeleteStatus: {
2481
+ path: "/tables/databases/delete-status/{job_id}",
2482
+ method: "GET",
2483
+ authenticated: true
2484
+ }
2485
+ };
2486
+ const buildDatabaseEndpointPath = (endpoint, params = {}) => {
2487
+ let path = endpoint.path;
2488
+ Object.entries(params).forEach(([key, value]) => {
2489
+ path = path.replace(`{${key}}`, value);
2490
+ });
2491
+ return path;
2492
+ };
2493
+ class DatabasesApiClient {
2494
+ constructor(apiKey, config = {}) {
2495
+ this.config = { apiKey, ...config };
2496
+ this.httpAdapter = createHttpAdapter();
2497
+ const environment = config.environment || "prod";
2498
+ const region = config.region || "asia-south1";
2499
+ this.baseURL = this.getBaseURL(environment, region);
2500
+ }
2501
+ getBaseURL(environment, region) {
2502
+ const regionConfig = REGION_CONFIGS[region];
2503
+ if (!regionConfig) {
2504
+ throw new Error(`Unsupported region: ${region}`);
2505
+ }
2506
+ const envConfig = regionConfig[environment];
2507
+ if (!envConfig) {
2508
+ throw new Error(
2509
+ `Unsupported environment: ${environment} for region: ${region}`
2510
+ );
2511
+ }
2512
+ return `${envConfig.baseURL}/v1`;
2513
+ }
2514
+ /**
2515
+ * Create a new database
2516
+ */
2517
+ async createDatabase(request) {
2518
+ try {
2519
+ const endpoint = DATABASE_ENDPOINTS.create;
2520
+ const url = `${this.baseURL}${endpoint.path}`;
2521
+ const response = await this.httpAdapter.request({
2522
+ url,
2523
+ method: endpoint.method,
2524
+ headers: {
2525
+ "Content-Type": "application/json",
2526
+ "x-boltic-token": this.config.apiKey
2527
+ },
2528
+ data: request,
2529
+ timeout: this.config.timeout
2530
+ });
2531
+ return response.data;
2532
+ } catch (error) {
2533
+ return this.handleError(error);
2534
+ }
2535
+ }
2536
+ /**
2537
+ * List databases with pagination, sorting, and filtering
2538
+ */
2539
+ async listDatabases(request = {}, queryParams, options) {
2540
+ try {
2541
+ const endpoint = DATABASE_ENDPOINTS.list;
2542
+ let url = `${this.baseURL}${endpoint.path}`;
2543
+ const params = new URLSearchParams();
2544
+ if (queryParams == null ? void 0 : queryParams.connector_id) {
2545
+ params.append("connector_id", queryParams.connector_id);
2546
+ }
2547
+ if (queryParams == null ? void 0 : queryParams.add_default_if_missing) {
2548
+ params.append(
2549
+ "add_default_if_missing",
2550
+ queryParams.add_default_if_missing
2551
+ );
2552
+ }
2553
+ if (params.toString()) {
2554
+ url += `?${params.toString()}`;
2555
+ }
2556
+ const response = await this.httpAdapter.request({
2557
+ url,
2558
+ method: endpoint.method,
2559
+ headers: {
2560
+ "Content-Type": "application/json",
2561
+ "x-boltic-token": this.config.apiKey
2562
+ },
2563
+ data: request,
2564
+ timeout: this.config.timeout
2565
+ });
2566
+ const result = response.data;
2567
+ if ((options == null ? void 0 : options.fields) && !("error" in result)) {
2568
+ return {
2569
+ ...result,
2570
+ data: filterArrayFields(
2571
+ result.data,
2572
+ options.fields
2573
+ )
2574
+ };
2575
+ }
2576
+ return result;
2577
+ } catch (error) {
2578
+ return this.handleError(error);
2579
+ }
2580
+ }
2581
+ /**
2582
+ * Update a database
2583
+ */
2584
+ async updateDatabase(dbId, request) {
2585
+ try {
2586
+ const endpoint = DATABASE_ENDPOINTS.update;
2587
+ const path = buildDatabaseEndpointPath(endpoint, { db_id: dbId });
2588
+ const url = `${this.baseURL}${path}`;
2589
+ const response = await this.httpAdapter.request({
2590
+ url,
2591
+ method: endpoint.method,
2592
+ headers: {
2593
+ "Content-Type": "application/json",
2594
+ "x-boltic-token": this.config.apiKey
2595
+ },
2596
+ data: request,
2597
+ timeout: this.config.timeout
2598
+ });
2599
+ return response.data;
2600
+ } catch (error) {
2601
+ return this.handleError(error);
2602
+ }
2603
+ }
2604
+ /**
2605
+ * Delete a database (initiates deletion job)
2606
+ */
2607
+ async deleteDatabase(dbId) {
2608
+ try {
2609
+ const endpoint = DATABASE_ENDPOINTS.delete;
2610
+ const path = buildDatabaseEndpointPath(endpoint, { db_id: dbId });
2611
+ const url = `${this.baseURL}${path}`;
2612
+ const response = await this.httpAdapter.request({
2613
+ url,
2614
+ method: endpoint.method,
2615
+ headers: {
2616
+ "Content-Type": "application/json",
2617
+ "x-boltic-token": this.config.apiKey
2618
+ },
2619
+ timeout: this.config.timeout
2620
+ });
2621
+ return response.data;
2622
+ } catch (error) {
2623
+ return this.handleError(error);
2624
+ }
2625
+ }
2626
+ /**
2627
+ * List database jobs
2628
+ */
2629
+ async listDatabaseJobs(request = {}, options) {
2630
+ try {
2631
+ const endpoint = DATABASE_ENDPOINTS.listJobs;
2632
+ const url = `${this.baseURL}${endpoint.path}`;
2633
+ const response = await this.httpAdapter.request({
2634
+ url,
2635
+ method: endpoint.method,
2636
+ headers: {
2637
+ "Content-Type": "application/json",
2638
+ "x-boltic-token": this.config.apiKey
2639
+ },
2640
+ data: request,
2641
+ timeout: this.config.timeout
2642
+ });
2643
+ const result = response.data;
2644
+ if ((options == null ? void 0 : options.fields) && !("error" in result)) {
2645
+ return {
2646
+ ...result,
2647
+ data: filterArrayFields(
2648
+ result.data,
2649
+ options.fields
2650
+ )
2651
+ };
2652
+ }
2653
+ return result;
2654
+ } catch (error) {
2655
+ return this.handleError(error);
2656
+ }
2657
+ }
2658
+ /**
2659
+ * Poll deletion status for a database job
2660
+ */
2661
+ async pollDeleteStatus(jobId) {
2662
+ try {
2663
+ const endpoint = DATABASE_ENDPOINTS.pollDeleteStatus;
2664
+ const path = buildDatabaseEndpointPath(endpoint, { job_id: jobId });
2665
+ const url = `${this.baseURL}${path}`;
2666
+ const response = await this.httpAdapter.request({
2667
+ url,
2668
+ method: endpoint.method,
2669
+ headers: {
2670
+ "Content-Type": "application/json",
2671
+ "x-boltic-token": this.config.apiKey
2672
+ },
2673
+ timeout: this.config.timeout
2674
+ });
2675
+ return response.data;
2676
+ } catch (error) {
2677
+ return this.handleError(error);
2678
+ }
2679
+ }
2680
+ /**
2681
+ * Handle API errors and convert to standard error format
2682
+ */
2683
+ handleError(error) {
2684
+ if (this.config.debug) {
2685
+ console.error("[DatabasesApiClient] Error:", error);
2686
+ }
2687
+ const hasErrorProperty = (err) => {
2688
+ return typeof err === "object" && err !== null && "error" in err && typeof err.error === "object" && err.error !== null;
2689
+ };
2690
+ const hasResponseError = (err) => {
2691
+ return typeof err === "object" && err !== null && "response" in err && typeof err.response === "object" && err.response !== null && "data" in err.response && typeof err.response.data === "object" && err.response.data !== null && "error" in err.response.data;
2692
+ };
2693
+ const isStandardError = (err) => {
2694
+ return err instanceof Error;
2695
+ };
2696
+ if (hasErrorProperty(error)) {
2697
+ return {
2698
+ error: {
2699
+ code: typeof error.error.code === "number" ? String(error.error.code) : error.error.code || "UNKNOWN_ERROR",
2700
+ message: error.error.message || "An error occurred",
2701
+ meta: error.error.meta || []
2702
+ }
2703
+ };
2704
+ }
2705
+ if (hasResponseError(error)) {
2706
+ return {
2707
+ error: {
2708
+ code: typeof error.response.data.error.code === "number" ? String(error.response.data.error.code) : error.response.data.error.code || "UNKNOWN_ERROR",
2709
+ message: error.response.data.error.message || "An error occurred",
2710
+ meta: error.response.data.error.meta || []
2711
+ }
2712
+ };
2713
+ }
2714
+ if (isStandardError(error)) {
2715
+ return {
2716
+ error: {
2717
+ code: error.code || "UNKNOWN_ERROR",
2718
+ message: error.message || "An unexpected error occurred",
2719
+ meta: []
2720
+ }
2721
+ };
2722
+ }
2723
+ return {
2724
+ error: {
2725
+ code: "UNKNOWN_ERROR",
2726
+ message: "An unexpected error occurred",
2727
+ meta: []
2728
+ }
2729
+ };
2730
+ }
2731
+ }
2732
+ class DatabaseResource extends BaseResource {
2733
+ constructor(client) {
2734
+ super(client, "/v1/tables/databases");
2735
+ this.apiClient = new DatabasesApiClient(client.getConfig().apiKey, {
2736
+ environment: client.getConfig().environment,
2737
+ region: client.getConfig().region,
2738
+ timeout: client.getConfig().timeout,
2739
+ debug: client.getConfig().debug
2740
+ });
2741
+ }
2742
+ /**
2743
+ * Create a new database
2744
+ *
2745
+ * @param request - Database creation request
2746
+ * @returns Promise with created database or error
2747
+ *
2748
+ * @example
2749
+ * ```typescript
2750
+ * const result = await client.databases.create({
2751
+ * db_name: 'My Database',
2752
+ * db_internal_name: 'my-database',
2753
+ * resource_id: 'boltic'
2754
+ * });
2755
+ * ```
2756
+ */
2757
+ async create(request) {
2758
+ const result = await this.apiClient.createDatabase(request);
2759
+ if ("error" in result) {
2760
+ return {
2761
+ error: {
2762
+ code: typeof result.error.code === "number" ? String(result.error.code) : result.error.code,
2763
+ message: result.error.message,
2764
+ meta: result.error.meta
2765
+ }
2766
+ };
2767
+ }
2768
+ return result;
2769
+ }
2770
+ /**
2771
+ * List all databases with optional filtering and pagination
2772
+ * By default, only shows active databases
2773
+ *
2774
+ * @param options - Query options for listing databases
2775
+ * @returns Promise with list of databases or error
2776
+ *
2777
+ * @example
2778
+ * ```typescript
2779
+ * // List all active databases (default)
2780
+ * const result = await client.databases.findAll();
2781
+ *
2782
+ * // List with pagination
2783
+ * const result = await client.databases.findAll({
2784
+ * page: { page_no: 1, page_size: 10 }
2785
+ * });
2786
+ *
2787
+ * // List with sorting
2788
+ * const result = await client.databases.findAll({
2789
+ * sort: [{ field: 'db_name', direction: 'asc' }]
2790
+ * });
2791
+ * ```
2792
+ */
2793
+ async findAll(options) {
2794
+ const request = {};
2795
+ if (options == null ? void 0 : options.page) {
2796
+ request.page = options.page;
2797
+ }
2798
+ if (options == null ? void 0 : options.sort) {
2799
+ request.sort = options.sort;
2800
+ }
2801
+ if (options == null ? void 0 : options.filters) {
2802
+ const filtersWithoutStatus = options.filters.filter(
2803
+ (f) => f.field !== "status"
2804
+ );
2805
+ request.filters = [
2806
+ ...filtersWithoutStatus,
2807
+ { field: "status", operator: "=", values: ["ACTIVE"] }
2808
+ ];
2809
+ } else {
2810
+ request.filters = [
2811
+ { field: "status", operator: "=", values: ["ACTIVE"] }
2812
+ ];
2813
+ }
2814
+ const queryParams = {};
2815
+ if (options == null ? void 0 : options.connector_id) {
2816
+ queryParams.connector_id = options.connector_id;
2817
+ }
2818
+ if ((options == null ? void 0 : options.add_default_if_missing) !== void 0) {
2819
+ queryParams.add_default_if_missing = options.add_default_if_missing ? "true" : "false";
2820
+ }
2821
+ const result = await this.apiClient.listDatabases(
2822
+ request,
2823
+ queryParams,
2824
+ options
2825
+ );
2826
+ if ("error" in result) {
2827
+ return {
2828
+ error: {
2829
+ code: typeof result.error.code === "number" ? String(result.error.code) : result.error.code,
2830
+ message: result.error.message,
2831
+ meta: result.error.meta
2832
+ }
2833
+ };
2834
+ }
2835
+ if ("pagination" in result && result.pagination) {
2836
+ const pagination = result.pagination;
2837
+ return {
2838
+ ...result,
2839
+ pagination: {
2840
+ total_count: pagination.total_count,
2841
+ total_pages: pagination.total_pages ?? Math.ceil(pagination.total_count / pagination.per_page),
2842
+ current_page: pagination.current_page,
2843
+ per_page: pagination.per_page,
2844
+ type: "page"
2845
+ }
2846
+ };
2847
+ }
2848
+ return result;
2849
+ }
2850
+ /**
2851
+ * Get a specific database by internal name (slug)
2852
+ *
2853
+ * @param dbInternalName - Database internal name (slug)
2854
+ * @param options - Query options (e.g., fields to return)
2855
+ * @returns Promise with database or error
2856
+ *
2857
+ * @example
2858
+ * ```typescript
2859
+ * const result = await client.databases.findOne('my_database_slug');
2860
+ * ```
2861
+ */
2862
+ async findOne(dbInternalName, options) {
2863
+ const result = await this.findAll({
2864
+ filters: [
2865
+ {
2866
+ field: "db_internal_name",
2867
+ operator: "=",
2868
+ values: [dbInternalName]
2869
+ }
2870
+ ],
2871
+ fields: options == null ? void 0 : options.fields,
2872
+ page: { page_no: 1, page_size: 1 }
2873
+ });
2874
+ if (isErrorResponse(result)) {
2875
+ return result;
2876
+ }
2877
+ if (result.data.length === 0) {
2878
+ return {
2879
+ error: {
2880
+ code: "NOT_FOUND",
2881
+ message: `Database with internal name '${dbInternalName}' not found`,
2882
+ meta: []
2883
+ }
2884
+ };
2885
+ }
2886
+ return {
2887
+ data: result.data[0],
2888
+ message: "Database found"
2889
+ };
2890
+ }
2891
+ /**
2892
+ * Get the default database
2893
+ *
2894
+ * @returns Promise with default database or error
2895
+ *
2896
+ * @example
2897
+ * ```typescript
2898
+ * const result = await client.databases.getDefault();
2899
+ * ```
2900
+ */
2901
+ async getDefault() {
2902
+ const result = await this.findAll({
2903
+ filters: [{ field: "is_default", operator: "=", values: [true] }],
2904
+ page: { page_no: 1, page_size: 1 }
2905
+ });
2906
+ if (isErrorResponse(result)) {
2907
+ return result;
2908
+ }
2909
+ if (result.data.length === 0) {
2910
+ return {
2911
+ error: {
2912
+ code: "NOT_FOUND",
2913
+ message: "Default database not found",
2914
+ meta: []
2915
+ }
2916
+ };
2917
+ }
2918
+ return {
2919
+ data: result.data[0],
2920
+ message: "Default database found"
2921
+ };
2922
+ }
2923
+ /**
2924
+ * Update a database
2925
+ * Only allows updating the display name (db_name)
2926
+ *
2927
+ * @param dbInternalName - Database internal name (slug)
2928
+ * @param request - Update request (only db_name is allowed)
2929
+ * @returns Promise with updated database or error
2930
+ *
2931
+ * @example
2932
+ * ```typescript
2933
+ * const result = await client.databases.update('my_database_slug', {
2934
+ * db_name: 'Updated Database Name'
2935
+ * });
2936
+ * ```
2937
+ */
2938
+ async update(dbInternalName, request) {
2939
+ const dbInfo = await this.findOne(dbInternalName);
2940
+ if (isErrorResponse(dbInfo)) {
2941
+ return {
2942
+ error: {
2943
+ code: "DATABASE_NOT_FOUND",
2944
+ message: `Database with internal name '${dbInternalName}' not found`,
2945
+ meta: []
2946
+ }
2947
+ };
2948
+ }
2949
+ const dbId = dbInfo.data.id;
2950
+ const updateRequest = {
2951
+ db_name: request.db_name
2952
+ };
2953
+ const result = await this.apiClient.updateDatabase(dbId, updateRequest);
2954
+ if ("error" in result) {
2955
+ return {
2956
+ error: {
2957
+ code: typeof result.error.code === "number" ? String(result.error.code) : result.error.code,
2958
+ message: result.error.message,
2959
+ meta: result.error.meta
2960
+ }
2961
+ };
2962
+ }
2963
+ return result;
2964
+ }
2965
+ /**
2966
+ * Delete a database (initiates async deletion job)
2967
+ *
2968
+ * @param dbInternalName - Database internal name (slug)
2969
+ * @returns Promise with job details or error
2970
+ *
2971
+ * @example
2972
+ * ```typescript
2973
+ * const result = await client.databases.delete('my_database_slug');
2974
+ * if (!result.error) {
2975
+ * console.log('Deletion job started:', result.data.job_id);
2976
+ * // Poll for status
2977
+ * const status = await client.databases.pollDeleteStatus(result.data.job_id);
2978
+ * }
2979
+ * ```
2980
+ */
2981
+ async delete(dbInternalName) {
2982
+ const dbInfo = await this.findOne(dbInternalName);
2983
+ if (isErrorResponse(dbInfo)) {
2984
+ return {
2985
+ error: {
2986
+ code: "DATABASE_NOT_FOUND",
2987
+ message: `Database with internal name '${dbInternalName}' not found`,
2988
+ meta: []
2989
+ }
2990
+ };
2991
+ }
2992
+ if (dbInfo.data.is_default) {
2993
+ return {
2994
+ error: {
2995
+ code: "CANNOT_DELETE_DEFAULT",
2996
+ message: "Cannot delete the default database",
2997
+ meta: []
2998
+ }
2999
+ };
3000
+ }
3001
+ const dbId = dbInfo.data.id;
3002
+ const result = await this.apiClient.deleteDatabase(dbId);
3003
+ if ("error" in result) {
3004
+ return {
3005
+ error: {
3006
+ code: typeof result.error.code === "number" ? String(result.error.code) : result.error.code,
3007
+ message: result.error.message,
3008
+ meta: result.error.meta
3009
+ }
3010
+ };
3011
+ }
3012
+ return result;
3013
+ }
3014
+ /**
3015
+ * List database jobs (e.g., deletion jobs)
3016
+ *
3017
+ * @param options - Query options for listing jobs
3018
+ * @returns Promise with list of jobs or error
3019
+ *
3020
+ * @example
3021
+ * ```typescript
3022
+ * // List all jobs
3023
+ * const result = await client.databases.listJobs();
3024
+ *
3025
+ * // List jobs deleted by current user
3026
+ * const result = await client.databases.listJobs({
3027
+ * deleted_by_me: true
3028
+ * });
3029
+ * ```
3030
+ */
3031
+ async listJobs(options) {
3032
+ const request = {};
3033
+ if ((options == null ? void 0 : options.deleted_by_me) !== void 0) {
3034
+ request.deleted_by_me = options.deleted_by_me;
3035
+ }
3036
+ if (options == null ? void 0 : options.page) {
3037
+ request.page = options.page;
3038
+ }
3039
+ if (options == null ? void 0 : options.sort) {
3040
+ request.sort = options.sort;
3041
+ }
3042
+ if (options == null ? void 0 : options.filters) {
3043
+ request.filters = options.filters;
3044
+ }
3045
+ const result = await this.apiClient.listDatabaseJobs(request, options);
3046
+ if ("error" in result) {
3047
+ return {
3048
+ error: {
3049
+ code: typeof result.error.code === "number" ? String(result.error.code) : result.error.code,
3050
+ message: result.error.message,
3051
+ meta: result.error.meta
3052
+ }
3053
+ };
3054
+ }
3055
+ if ("pagination" in result && result.pagination) {
3056
+ const pagination = result.pagination;
3057
+ const normalizedResult = {
3058
+ ...result,
3059
+ pagination: {
3060
+ total_count: pagination.total_count,
3061
+ total_pages: pagination.total_pages ?? Math.ceil(pagination.total_count / pagination.per_page),
3062
+ current_page: pagination.current_page,
3063
+ per_page: pagination.per_page,
3064
+ type: "page"
3065
+ }
3066
+ };
3067
+ return normalizedResult;
3068
+ }
3069
+ return result;
3070
+ }
3071
+ /**
3072
+ * Poll the status of a database deletion job
3073
+ *
3074
+ * @param jobId - Job ID
3075
+ * @returns Promise with job status or error
3076
+ *
3077
+ * @example
3078
+ * ```typescript
3079
+ * const status = await client.databases.pollDeleteStatus('job-uuid');
3080
+ * if (!status.error) {
3081
+ * console.log('Job status:', status.data.status);
3082
+ * console.log('Message:', status.data.message);
3083
+ * }
3084
+ * ```
3085
+ */
3086
+ async pollDeleteStatus(jobId) {
3087
+ const result = await this.apiClient.pollDeleteStatus(jobId);
3088
+ if ("error" in result) {
3089
+ return {
3090
+ error: {
3091
+ code: typeof result.error.code === "number" ? String(result.error.code) : result.error.code,
3092
+ message: result.error.message,
3093
+ meta: result.error.meta
3094
+ }
3095
+ };
3096
+ }
3097
+ return result;
3098
+ }
3099
+ }
2358
3100
  const INDEX_ENDPOINTS = {
2359
3101
  create: {
2360
3102
  path: "/tables/indexes/{table_id}",
@@ -2404,10 +3146,11 @@ class IndexesApiClient {
2404
3146
  }
2405
3147
  return `${envConfig.baseURL}/v1`;
2406
3148
  }
2407
- async addIndex(tableId, request) {
3149
+ async addIndex(tableId, request, dbId) {
2408
3150
  try {
2409
3151
  const endpoint = INDEX_ENDPOINTS.create;
2410
- const url = `${this.baseURL}${buildIndexEndpointPath(endpoint, { table_id: tableId })}`;
3152
+ let url = `${this.baseURL}${buildIndexEndpointPath(endpoint, { table_id: tableId })}`;
3153
+ url = addDbIdToUrl(url, dbId);
2411
3154
  const response = await this.httpAdapter.request({
2412
3155
  url,
2413
3156
  method: endpoint.method,
@@ -2420,10 +3163,11 @@ class IndexesApiClient {
2420
3163
  return this.formatErrorResponse(error);
2421
3164
  }
2422
3165
  }
2423
- async listIndexes(tableId, query) {
3166
+ async listIndexes(tableId, query, dbId) {
2424
3167
  try {
2425
3168
  const endpoint = INDEX_ENDPOINTS.list;
2426
- const url = `${this.baseURL}${buildIndexEndpointPath(endpoint, { table_id: tableId })}`;
3169
+ let url = `${this.baseURL}${buildIndexEndpointPath(endpoint, { table_id: tableId })}`;
3170
+ url = addDbIdToUrl(url, dbId);
2427
3171
  const response = await this.httpAdapter.request({
2428
3172
  url,
2429
3173
  method: endpoint.method,
@@ -2436,10 +3180,11 @@ class IndexesApiClient {
2436
3180
  return this.formatErrorResponse(error);
2437
3181
  }
2438
3182
  }
2439
- async deleteIndex(tableId, request) {
3183
+ async deleteIndex(tableId, request, dbId) {
2440
3184
  try {
2441
3185
  const endpoint = INDEX_ENDPOINTS.delete;
2442
- const url = `${this.baseURL}${buildIndexEndpointPath(endpoint, { table_id: tableId })}`;
3186
+ let url = `${this.baseURL}${buildIndexEndpointPath(endpoint, { table_id: tableId })}`;
3187
+ url = addDbIdToUrl(url, dbId);
2443
3188
  const response = await this.httpAdapter.request({
2444
3189
  url,
2445
3190
  method: endpoint.method,
@@ -2510,15 +3255,15 @@ class IndexResource {
2510
3255
  });
2511
3256
  this.tableResource = new TableResource(client);
2512
3257
  }
2513
- async resolveTableId(tableName) {
2514
- const tableResult = await this.tableResource.findByName(tableName);
3258
+ async resolveTableId(tableName, dbId) {
3259
+ const tableResult = await this.tableResource.findByName(tableName, dbId);
2515
3260
  if (!tableResult.data) throw new Error(`Table not found: ${tableName}`);
2516
3261
  return tableResult.data.id;
2517
3262
  }
2518
- async addIndex(tableName, request) {
3263
+ async addIndex(tableName, request, dbId) {
2519
3264
  try {
2520
- const tableId = await this.resolveTableId(tableName);
2521
- return await this.apiClient.addIndex(tableId, request);
3265
+ const tableId = await this.resolveTableId(tableName, dbId);
3266
+ return await this.apiClient.addIndex(tableId, request, dbId);
2522
3267
  } catch (error) {
2523
3268
  return {
2524
3269
  error: {
@@ -2529,10 +3274,10 @@ class IndexResource {
2529
3274
  };
2530
3275
  }
2531
3276
  }
2532
- async listIndexes(tableName, query) {
3277
+ async listIndexes(tableName, query, dbId) {
2533
3278
  try {
2534
- const tableId = await this.resolveTableId(tableName);
2535
- return await this.apiClient.listIndexes(tableId, query);
3279
+ const tableId = await this.resolveTableId(tableName, dbId);
3280
+ return await this.apiClient.listIndexes(tableId, query, dbId);
2536
3281
  } catch (error) {
2537
3282
  return {
2538
3283
  error: {
@@ -2543,11 +3288,11 @@ class IndexResource {
2543
3288
  };
2544
3289
  }
2545
3290
  }
2546
- async deleteIndex(tableName, indexName) {
3291
+ async deleteIndex(tableName, indexName, dbId) {
2547
3292
  try {
2548
- const tableId = await this.resolveTableId(tableName);
3293
+ const tableId = await this.resolveTableId(tableName, dbId);
2549
3294
  const request = { index_name: indexName };
2550
- return await this.apiClient.deleteIndex(tableId, request);
3295
+ return await this.apiClient.deleteIndex(tableId, request, dbId);
2551
3296
  } catch (error) {
2552
3297
  return {
2553
3298
  error: {
@@ -2583,8 +3328,8 @@ const RECORD_ENDPOINTS = {
2583
3328
  rateLimit: { requests: 200, window: 6e4 }
2584
3329
  },
2585
3330
  update: {
2586
- path: "/tables/{table_id}/records",
2587
- method: "PATCH",
3331
+ path: "/tables/{table_id}/records/bulk-update",
3332
+ method: "PUT",
2588
3333
  authenticated: true
2589
3334
  },
2590
3335
  updateById: {
@@ -2654,7 +3399,7 @@ class RecordsApiClient {
2654
3399
  /**
2655
3400
  * Insert a single record
2656
3401
  */
2657
- async insertRecord(request) {
3402
+ async insertRecord(request, dbId) {
2658
3403
  try {
2659
3404
  const { table_id, fields, ...recordData } = request;
2660
3405
  if (!table_id) {
@@ -2663,7 +3408,8 @@ class RecordsApiClient {
2663
3408
  );
2664
3409
  }
2665
3410
  const endpoint = RECORD_ENDPOINTS.insert;
2666
- const url = `${this.baseURL}${buildRecordEndpointPath(endpoint, { table_id })}`;
3411
+ let url = `${this.baseURL}${buildRecordEndpointPath(endpoint, { table_id })}`;
3412
+ url = addDbIdToUrl(url, dbId);
2667
3413
  const response = await this.httpAdapter.request({
2668
3414
  url,
2669
3415
  method: endpoint.method,
@@ -2686,7 +3432,7 @@ class RecordsApiClient {
2686
3432
  /**
2687
3433
  * Insert multiple records in bulk
2688
3434
  */
2689
- async insertManyRecords(records, tableId, options = { validation: true }) {
3435
+ async insertManyRecords(records, tableId, options = { validation: true }, dbId) {
2690
3436
  try {
2691
3437
  if (!tableId) {
2692
3438
  return this.formatErrorResponse(
@@ -2707,6 +3453,7 @@ class RecordsApiClient {
2707
3453
  if (queryParams.toString()) {
2708
3454
  url += `?${queryParams.toString()}`;
2709
3455
  }
3456
+ url = addDbIdToUrl(url, dbId);
2710
3457
  const response = await this.httpAdapter.request({
2711
3458
  url,
2712
3459
  method: endpoint.method,
@@ -2722,7 +3469,7 @@ class RecordsApiClient {
2722
3469
  /**
2723
3470
  * Get a single record by ID
2724
3471
  */
2725
- async getRecord(recordId, tableId, options = {}) {
3472
+ async getRecord(recordId, tableId, options = {}, dbId) {
2726
3473
  try {
2727
3474
  if (!tableId) {
2728
3475
  return this.formatErrorResponse(
@@ -2730,10 +3477,11 @@ class RecordsApiClient {
2730
3477
  );
2731
3478
  }
2732
3479
  const endpoint = RECORD_ENDPOINTS.get;
2733
- const url = `${this.baseURL}${buildRecordEndpointPath(endpoint, {
3480
+ let url = `${this.baseURL}${buildRecordEndpointPath(endpoint, {
2734
3481
  table_id: tableId,
2735
3482
  record_id: recordId
2736
3483
  })}`;
3484
+ url = addDbIdToUrl(url, dbId);
2737
3485
  const response = await this.httpAdapter.request({
2738
3486
  url,
2739
3487
  method: endpoint.method,
@@ -2755,7 +3503,7 @@ class RecordsApiClient {
2755
3503
  /**
2756
3504
  * List records with filtering and pagination
2757
3505
  */
2758
- async listRecords(options = {}) {
3506
+ async listRecords(options = {}, dbId) {
2759
3507
  try {
2760
3508
  const { table_id, ...queryOptions } = options;
2761
3509
  if (!table_id) {
@@ -2764,7 +3512,8 @@ class RecordsApiClient {
2764
3512
  );
2765
3513
  }
2766
3514
  const endpoint = RECORD_ENDPOINTS.list;
2767
- const url = `${this.baseURL}${buildRecordEndpointPath(endpoint, { table_id })}`;
3515
+ let url = `${this.baseURL}${buildRecordEndpointPath(endpoint, { table_id })}`;
3516
+ url = addDbIdToUrl(url, dbId);
2768
3517
  const response = await this.httpAdapter.request({
2769
3518
  url,
2770
3519
  method: endpoint.method,
@@ -2787,28 +3536,37 @@ class RecordsApiClient {
2787
3536
  /**
2788
3537
  * Update records by filters
2789
3538
  */
2790
- async updateRecords(request) {
3539
+ async updateRecords(request, dbId) {
2791
3540
  try {
2792
- const { table_id, ...updateOptions } = request;
3541
+ const { table_id, set, filters, fields, ...rest } = request;
2793
3542
  if (!table_id) {
2794
3543
  return this.formatErrorResponse(
2795
3544
  new Error("table_id is required for update operation")
2796
3545
  );
2797
3546
  }
3547
+ const apiPayload = {
3548
+ updates: set,
3549
+ filters,
3550
+ ...rest
3551
+ };
3552
+ if (fields) {
3553
+ apiPayload.fields = fields;
3554
+ }
2798
3555
  const endpoint = RECORD_ENDPOINTS.update;
2799
- const url = `${this.baseURL}${buildRecordEndpointPath(endpoint, { table_id })}`;
3556
+ let url = `${this.baseURL}${buildRecordEndpointPath(endpoint, { table_id })}`;
3557
+ url = addDbIdToUrl(url, dbId);
2800
3558
  const response = await this.httpAdapter.request({
2801
3559
  url,
2802
3560
  method: endpoint.method,
2803
3561
  headers: this.buildHeaders(),
2804
- data: updateOptions,
3562
+ data: apiPayload,
2805
3563
  timeout: this.config.timeout
2806
3564
  });
2807
3565
  const responseData = response.data;
2808
- if (updateOptions.fields && responseData.data) {
3566
+ if (fields && responseData.data) {
2809
3567
  responseData.data = filterArrayFields(
2810
3568
  responseData.data,
2811
- updateOptions.fields
3569
+ fields
2812
3570
  );
2813
3571
  }
2814
3572
  return responseData;
@@ -2819,7 +3577,7 @@ class RecordsApiClient {
2819
3577
  /**
2820
3578
  * Update a single record by ID
2821
3579
  */
2822
- async updateRecordById(recordId, request) {
3580
+ async updateRecordById(recordId, request, dbId) {
2823
3581
  try {
2824
3582
  const { table_id, ...updateOptions } = request;
2825
3583
  if (!table_id) {
@@ -2828,10 +3586,11 @@ class RecordsApiClient {
2828
3586
  );
2829
3587
  }
2830
3588
  const endpoint = RECORD_ENDPOINTS.updateById;
2831
- const url = `${this.baseURL}${buildRecordEndpointPath(endpoint, {
3589
+ let url = `${this.baseURL}${buildRecordEndpointPath(endpoint, {
2832
3590
  record_id: recordId,
2833
3591
  table_id
2834
3592
  })}`;
3593
+ url = addDbIdToUrl(url, dbId);
2835
3594
  const response = await this.httpAdapter.request({
2836
3595
  url,
2837
3596
  method: endpoint.method,
@@ -2854,7 +3613,7 @@ class RecordsApiClient {
2854
3613
  /**
2855
3614
  * Unified delete records method that supports both record_ids and filters
2856
3615
  */
2857
- async deleteRecords(request) {
3616
+ async deleteRecords(request, dbId) {
2858
3617
  try {
2859
3618
  const { table_id } = request;
2860
3619
  if (!table_id) {
@@ -2864,7 +3623,8 @@ class RecordsApiClient {
2864
3623
  }
2865
3624
  const transformedRequest = transformDeleteRequest(request);
2866
3625
  const endpoint = RECORD_ENDPOINTS.delete;
2867
- const url = `${this.baseURL}${buildRecordEndpointPath(endpoint, { table_id })}`;
3626
+ let url = `${this.baseURL}${buildRecordEndpointPath(endpoint, { table_id })}`;
3627
+ url = addDbIdToUrl(url, dbId);
2868
3628
  const response = await this.httpAdapter.request({
2869
3629
  url,
2870
3630
  method: endpoint.method,
@@ -2880,11 +3640,14 @@ class RecordsApiClient {
2880
3640
  /**
2881
3641
  * Delete a single record by ID
2882
3642
  */
2883
- async deleteRecordById(recordId, request) {
2884
- return this.deleteRecords({
2885
- record_ids: [recordId],
2886
- table_id: request.table_id
2887
- });
3643
+ async deleteRecordById(recordId, request, dbId) {
3644
+ return this.deleteRecords(
3645
+ {
3646
+ record_ids: [recordId],
3647
+ table_id: request.table_id
3648
+ },
3649
+ dbId
3650
+ );
2888
3651
  }
2889
3652
  buildHeaders() {
2890
3653
  return {
@@ -2948,9 +3711,9 @@ class RecordResource {
2948
3711
  /**
2949
3712
  * Insert a single record
2950
3713
  */
2951
- async insert(tableName, data) {
3714
+ async insert(tableName, data, dbId) {
2952
3715
  try {
2953
- const tableInfo = await this.getTableInfo(tableName);
3716
+ const tableInfo = await this.getTableInfo(tableName, dbId);
2954
3717
  if (!tableInfo) {
2955
3718
  return {
2956
3719
  error: {
@@ -2970,7 +3733,7 @@ class RecordResource {
2970
3733
  ...completeDataResult,
2971
3734
  table_id: tableInfo.id
2972
3735
  };
2973
- const result = await this.apiClient.insertRecord(requestData);
3736
+ const result = await this.apiClient.insertRecord(requestData, dbId);
2974
3737
  if (isErrorResponse(result)) {
2975
3738
  return result;
2976
3739
  }
@@ -2987,7 +3750,7 @@ class RecordResource {
2987
3750
  /**
2988
3751
  * Insert multiple records in bulk
2989
3752
  */
2990
- async insertMany(tableName, records, options = { validation: true }) {
3753
+ async insertMany(tableName, records, options = { validation: true }, dbId) {
2991
3754
  try {
2992
3755
  if (!records || !Array.isArray(records) || records.length === 0) {
2993
3756
  return {
@@ -2997,7 +3760,7 @@ class RecordResource {
2997
3760
  }
2998
3761
  };
2999
3762
  }
3000
- const tableInfo = await this.getTableInfo(tableName);
3763
+ const tableInfo = await this.getTableInfo(tableName, dbId);
3001
3764
  if (!tableInfo) {
3002
3765
  return {
3003
3766
  error: {
@@ -3009,7 +3772,8 @@ class RecordResource {
3009
3772
  const result = await this.apiClient.insertManyRecords(
3010
3773
  records,
3011
3774
  tableInfo.id,
3012
- options
3775
+ options,
3776
+ dbId
3013
3777
  );
3014
3778
  if (isErrorResponse(result)) {
3015
3779
  return result;
@@ -3027,9 +3791,9 @@ class RecordResource {
3027
3791
  /**
3028
3792
  * Get a single record by ID
3029
3793
  */
3030
- async get(tableName, recordId) {
3794
+ async get(tableName, recordId, dbId) {
3031
3795
  try {
3032
- const tableInfo = await this.getTableInfo(tableName);
3796
+ const tableInfo = await this.getTableInfo(tableName, dbId);
3033
3797
  if (!tableInfo) {
3034
3798
  return {
3035
3799
  error: {
@@ -3038,7 +3802,12 @@ class RecordResource {
3038
3802
  }
3039
3803
  };
3040
3804
  }
3041
- const result = await this.apiClient.getRecord(recordId, tableInfo.id);
3805
+ const result = await this.apiClient.getRecord(
3806
+ recordId,
3807
+ tableInfo.id,
3808
+ {},
3809
+ dbId
3810
+ );
3042
3811
  if (isErrorResponse(result)) {
3043
3812
  return result;
3044
3813
  }
@@ -3055,9 +3824,9 @@ class RecordResource {
3055
3824
  /**
3056
3825
  * List records with filtering and pagination
3057
3826
  */
3058
- async list(tableName, options = {}) {
3827
+ async list(tableName, options = {}, dbId) {
3059
3828
  try {
3060
- const tableInfo = await this.getTableInfo(tableName);
3829
+ const tableInfo = await this.getTableInfo(tableName, dbId);
3061
3830
  if (!tableInfo) {
3062
3831
  return {
3063
3832
  error: {
@@ -3067,7 +3836,7 @@ class RecordResource {
3067
3836
  };
3068
3837
  }
3069
3838
  const requestOptions = { ...options, table_id: tableInfo.id };
3070
- const result = await this.apiClient.listRecords(requestOptions);
3839
+ const result = await this.apiClient.listRecords(requestOptions, dbId);
3071
3840
  if (isErrorResponse(result)) {
3072
3841
  return result;
3073
3842
  }
@@ -3084,9 +3853,9 @@ class RecordResource {
3084
3853
  /**
3085
3854
  * Update records by filters
3086
3855
  */
3087
- async update(tableName, options) {
3856
+ async update(tableName, options, dbId) {
3088
3857
  try {
3089
- const tableInfo = await this.getTableInfo(tableName);
3858
+ const tableInfo = await this.getTableInfo(tableName, dbId);
3090
3859
  if (!tableInfo) {
3091
3860
  return {
3092
3861
  error: {
@@ -3096,7 +3865,7 @@ class RecordResource {
3096
3865
  };
3097
3866
  }
3098
3867
  const requestOptions = { ...options, table_id: tableInfo.id };
3099
- const result = await this.apiClient.updateRecords(requestOptions);
3868
+ const result = await this.apiClient.updateRecords(requestOptions, dbId);
3100
3869
  if (isErrorResponse(result)) {
3101
3870
  return result;
3102
3871
  }
@@ -3113,9 +3882,9 @@ class RecordResource {
3113
3882
  /**
3114
3883
  * Update a single record by ID
3115
3884
  */
3116
- async updateById(tableName, recordId, data) {
3885
+ async updateById(tableName, recordId, data, dbId) {
3117
3886
  try {
3118
- const tableInfo = await this.getTableInfo(tableName);
3887
+ const tableInfo = await this.getTableInfo(tableName, dbId);
3119
3888
  if (!tableInfo) {
3120
3889
  return {
3121
3890
  error: {
@@ -3131,7 +3900,8 @@ class RecordResource {
3131
3900
  };
3132
3901
  const result = await this.apiClient.updateRecordById(
3133
3902
  recordId,
3134
- requestOptions
3903
+ requestOptions,
3904
+ dbId
3135
3905
  );
3136
3906
  if (isErrorResponse(result)) {
3137
3907
  return result;
@@ -3149,9 +3919,9 @@ class RecordResource {
3149
3919
  /**
3150
3920
  * Unified delete method that supports both record IDs and filters
3151
3921
  */
3152
- async delete(tableName, options) {
3922
+ async delete(tableName, options, dbId) {
3153
3923
  try {
3154
- const tableInfo = await this.getTableInfo(tableName);
3924
+ const tableInfo = await this.getTableInfo(tableName, dbId);
3155
3925
  if (!tableInfo) {
3156
3926
  return {
3157
3927
  error: {
@@ -3161,7 +3931,7 @@ class RecordResource {
3161
3931
  };
3162
3932
  }
3163
3933
  const requestOptions = { ...options, table_id: tableInfo.id };
3164
- const result = await this.apiClient.deleteRecords(requestOptions);
3934
+ const result = await this.apiClient.deleteRecords(requestOptions, dbId);
3165
3935
  if (isErrorResponse(result)) {
3166
3936
  return result;
3167
3937
  }
@@ -3178,9 +3948,9 @@ class RecordResource {
3178
3948
  /**
3179
3949
  * Delete a single record by ID
3180
3950
  */
3181
- async deleteById(tableName, recordId) {
3951
+ async deleteById(tableName, recordId, dbId) {
3182
3952
  try {
3183
- const tableInfo = await this.getTableInfo(tableName);
3953
+ const tableInfo = await this.getTableInfo(tableName, dbId);
3184
3954
  if (!tableInfo) {
3185
3955
  return {
3186
3956
  error: {
@@ -3189,9 +3959,13 @@ class RecordResource {
3189
3959
  }
3190
3960
  };
3191
3961
  }
3192
- const result = await this.apiClient.deleteRecordById(recordId, {
3193
- table_id: tableInfo.id
3194
- });
3962
+ const result = await this.apiClient.deleteRecordById(
3963
+ recordId,
3964
+ {
3965
+ table_id: tableInfo.id
3966
+ },
3967
+ dbId
3968
+ );
3195
3969
  if (isErrorResponse(result)) {
3196
3970
  return result;
3197
3971
  }
@@ -3208,10 +3982,10 @@ class RecordResource {
3208
3982
  /**
3209
3983
  * Helper method to get table information by name
3210
3984
  */
3211
- async getTableInfo(tableName) {
3985
+ async getTableInfo(tableName, dbId) {
3212
3986
  try {
3213
3987
  const tableResource = new TableResource(this.client);
3214
- const tableResult = await tableResource.findByName(tableName);
3988
+ const tableResult = await tableResource.findByName(tableName, dbId);
3215
3989
  if (tableResult.data) {
3216
3990
  return {
3217
3991
  id: tableResult.data.id,
@@ -3575,10 +4349,13 @@ class SqlApiClient extends BaseApiClient {
3575
4349
  /**
3576
4350
  * Convert natural language to SQL query (streaming)
3577
4351
  */
3578
- async textToSQL(request) {
4352
+ async textToSQL(request, dbId) {
3579
4353
  try {
3580
4354
  const endpoint = SQL_ENDPOINTS.textToSQL;
3581
- const url = `${this.baseURL}${buildSqlEndpointPath(endpoint)}`;
4355
+ let url = `${this.baseURL}${buildSqlEndpointPath(endpoint)}`;
4356
+ if (dbId) {
4357
+ url += `?db_id=${encodeURIComponent(dbId)}`;
4358
+ }
3582
4359
  const response = await this.httpAdapter.request({
3583
4360
  url,
3584
4361
  method: endpoint.method,
@@ -3603,10 +4380,13 @@ class SqlApiClient extends BaseApiClient {
3603
4380
  /**
3604
4381
  * Execute SQL query
3605
4382
  */
3606
- async executeSQL(request) {
4383
+ async executeSQL(request, dbId) {
3607
4384
  try {
3608
4385
  const endpoint = SQL_ENDPOINTS.executeSQL;
3609
- const url = `${this.baseURL}${buildSqlEndpointPath(endpoint)}`;
4386
+ let url = `${this.baseURL}${buildSqlEndpointPath(endpoint)}`;
4387
+ if (dbId) {
4388
+ url += `?db_id=${encodeURIComponent(dbId)}`;
4389
+ }
3610
4390
  const response = await this.httpAdapter.request({
3611
4391
  url,
3612
4392
  method: endpoint.method,
@@ -3663,9 +4443,9 @@ class SqlResource {
3663
4443
  * @returns AsyncIterable<string> for streaming SQL generation
3664
4444
  *
3665
4445
  */
3666
- async textToSQL(prompt, options = {}) {
4446
+ async textToSQL(prompt, options = {}, dbId) {
3667
4447
  const request = transformTextToSQLRequest(prompt, options);
3668
- const response = await this.sqlApiClient.textToSQL(request);
4448
+ const response = await this.sqlApiClient.textToSQL(request, dbId);
3669
4449
  if ("error" in response && response.error !== void 0) {
3670
4450
  throw response;
3671
4451
  }
@@ -3678,8 +4458,8 @@ class SqlResource {
3678
4458
  * @returns Promise<ExecuteSQLApiResponse> with raw API response following Boltic API Response Structure
3679
4459
  *
3680
4460
  */
3681
- async executeSQL(query) {
3682
- const response = await this.sqlApiClient.executeSQL({ query });
4461
+ async executeSQL(query, dbId) {
4462
+ const response = await this.sqlApiClient.executeSQL({ query }, dbId);
3683
4463
  if (isErrorResponse(response)) {
3684
4464
  return response;
3685
4465
  }
@@ -4028,25 +4808,76 @@ class BolticClient {
4028
4808
  this.recordResource = new RecordResource(this.baseClient);
4029
4809
  this.sqlResource = new SqlResource(this.baseClient);
4030
4810
  this.indexResource = new IndexResource(this.baseClient);
4031
- this.currentDatabase = {
4032
- databaseName: "Default"
4033
- };
4811
+ this.databaseResource = new DatabaseResource(this.baseClient);
4812
+ this.currentDatabase = null;
4034
4813
  }
4814
+ /**
4815
+ * Get current database context
4816
+ */
4035
4817
  getCurrentDatabase() {
4036
4818
  return this.currentDatabase;
4037
4819
  }
4820
+ /**
4821
+ * Switch to a different database using its internal name (slug).
4822
+ * All subsequent operations will use this database.
4823
+ *
4824
+ * If no internal name is provided, the SDK will switch back to the default database.
4825
+ *
4826
+ * @param dbInternalName - Database internal name/slug to switch to. If omitted or empty, default DB is used.
4827
+ *
4828
+ * @example
4829
+ * ```typescript
4830
+ * // Switch to a specific database by slug
4831
+ * await client.useDatabase('my_database_slug');
4832
+ *
4833
+ * // Switch back to default database
4834
+ * await client.useDatabase();
4835
+ * ```
4836
+ */
4837
+ async useDatabase(dbInternalName) {
4838
+ if (!dbInternalName || dbInternalName === "") {
4839
+ this.currentDatabase = null;
4840
+ return;
4841
+ }
4842
+ const result = await this.databaseResource.findOne(dbInternalName);
4843
+ if (isErrorResponse(result)) {
4844
+ throw new Error(
4845
+ result.error.message || `Failed to switch database to internal name '${dbInternalName}'`
4846
+ );
4847
+ }
4848
+ const db = result.data;
4849
+ this.currentDatabase = {
4850
+ databaseId: db.id,
4851
+ dbInternalName: db.db_internal_name || dbInternalName
4852
+ };
4853
+ }
4854
+ // Direct database operations
4855
+ get databases() {
4856
+ return {
4857
+ create: (data) => this.databaseResource.create(data),
4858
+ findAll: (options) => this.databaseResource.findAll(options),
4859
+ findOne: (dbInternalName, options) => this.databaseResource.findOne(dbInternalName, options),
4860
+ getDefault: () => this.databaseResource.getDefault(),
4861
+ update: (dbInternalName, data) => this.databaseResource.update(dbInternalName, data),
4862
+ delete: (dbInternalName) => this.databaseResource.delete(dbInternalName),
4863
+ listJobs: (options) => this.databaseResource.listJobs(options),
4864
+ pollDeleteStatus: (jobId) => this.databaseResource.pollDeleteStatus(jobId)
4865
+ };
4866
+ }
4038
4867
  // Direct table operations
4039
4868
  get tables() {
4869
+ var _a;
4870
+ const dbId = (_a = this.currentDatabase) == null ? void 0 : _a.databaseId;
4040
4871
  return {
4041
- create: (data) => this.tableResource.create(data),
4042
- findAll: (options) => this.tableResource.findAll(options),
4043
- findById: (id) => this.tableResource.findById(id),
4044
- findByName: (name) => this.tableResource.findByName(name),
4045
- findOne: (options) => this.tableResource.findOne(options),
4046
- update: (name, data) => this.tableResource.update(name, data),
4047
- delete: (name) => this.tableResource.delete(name),
4048
- rename: (oldName, newName) => this.tableResource.rename(oldName, newName),
4049
- setAccess: (request) => this.tableResource.setAccess(request)
4872
+ create: (data) => this.tableResource.create(data, dbId),
4873
+ findAll: (options) => this.tableResource.findAll(options, dbId),
4874
+ findById: (id) => this.tableResource.findById(id, dbId),
4875
+ findByName: (name) => this.tableResource.findByName(name, dbId),
4876
+ findOne: (options) => this.tableResource.findOne(options, dbId),
4877
+ update: (name, data) => this.tableResource.update(name, data, dbId),
4878
+ delete: (name) => this.tableResource.delete(name, dbId),
4879
+ rename: (oldName, newName) => this.tableResource.rename(oldName, newName, dbId),
4880
+ setAccess: (request) => this.tableResource.setAccess(request, dbId)
4050
4881
  };
4051
4882
  }
4052
4883
  // Direct column operations
@@ -4074,53 +4905,42 @@ class BolticClient {
4074
4905
  const tableBuilder = createTableBuilder({ name });
4075
4906
  return tableBuilder;
4076
4907
  }
4077
- // Method 3: Table-scoped operations
4908
+ // Table-scoped operations for method chaining
4078
4909
  from(tableName) {
4910
+ var _a;
4911
+ const dbId = (_a = this.currentDatabase) == null ? void 0 : _a.databaseId;
4079
4912
  return {
4080
- // Column operations for this table
4081
- columns: () => ({
4082
- create: (column) => this.columnResource.create(tableName, column),
4083
- findAll: (options) => this.columnResource.findAll(tableName, options),
4084
- get: (columnName) => this.columnResource.get(tableName, columnName),
4085
- update: (columnName, updates) => this.columnResource.update(tableName, columnName, updates),
4086
- delete: (columnName) => this.columnResource.delete(tableName, columnName)
4913
+ // Index operations for this table
4914
+ indexes: () => ({
4915
+ addIndex: (payload) => this.indexResource.addIndex(tableName, payload, dbId),
4916
+ listIndexes: (query) => this.indexResource.listIndexes(tableName, query, dbId),
4917
+ deleteIndex: (indexName) => this.indexResource.deleteIndex(tableName, indexName, dbId)
4087
4918
  }),
4088
4919
  // Record operations for this table
4089
4920
  records: () => ({
4090
- insert: (data) => this.recordResource.insert(tableName, data),
4091
- insertMany: (records, options) => this.recordResource.insertMany(tableName, records, options),
4092
- findOne: (recordId) => this.recordResource.get(tableName, recordId),
4093
- update: (options) => this.recordResource.update(tableName, options),
4094
- updateById: (recordId, data) => this.recordResource.updateById(tableName, recordId, data),
4095
- // Unified delete method
4096
- delete: (options) => this.recordResource.delete(tableName, options),
4097
- // Single record delete method
4098
- deleteById: (recordId) => this.recordResource.deleteById(tableName, recordId)
4099
- }),
4100
- // Fluent record builder for this table
4101
- record: () => createRecordBuilder({
4102
- tableName,
4103
- recordResource: this.recordResource
4104
- }),
4105
- // Indexes - Method 2: Function chaining under from(tableName)
4106
- indexes: () => ({
4107
- addIndex: (payload) => this.indexResource.addIndex(tableName, payload),
4108
- listIndexes: (query) => this.indexResource.listIndexes(tableName, query),
4109
- deleteIndex: (indexName) => this.indexResource.deleteIndex(tableName, indexName)
4921
+ insert: (data) => this.recordResource.insert(tableName, data, dbId),
4922
+ insertMany: (records, options) => this.recordResource.insertMany(tableName, records, options, dbId),
4923
+ findOne: (recordId) => this.recordResource.get(tableName, recordId, dbId),
4924
+ update: (options) => this.recordResource.update(tableName, options, dbId),
4925
+ updateById: (recordId, data) => this.recordResource.updateById(tableName, recordId, data, dbId),
4926
+ delete: (options) => this.recordResource.delete(tableName, options, dbId),
4927
+ deleteById: (recordId) => this.recordResource.deleteById(tableName, recordId, dbId)
4110
4928
  })
4111
4929
  };
4112
4930
  }
4113
4931
  // Direct record operations
4114
4932
  get records() {
4933
+ var _a;
4934
+ const dbId = (_a = this.currentDatabase) == null ? void 0 : _a.databaseId;
4115
4935
  return {
4116
- insert: (tableName, data) => this.recordResource.insert(tableName, data),
4117
- insertMany: (tableName, records, options) => this.recordResource.insertMany(tableName, records, options),
4118
- findAll: (tableName, options) => this.recordResource.list(tableName, options),
4119
- findOne: (tableName, recordId) => this.recordResource.get(tableName, recordId),
4120
- update: (tableName, options) => this.recordResource.update(tableName, options),
4121
- updateById: (tableName, recordId, data) => this.recordResource.updateById(tableName, recordId, data),
4122
- delete: (tableName, options) => this.recordResource.delete(tableName, options),
4123
- deleteById: (tableName, recordId) => this.recordResource.deleteById(tableName, recordId)
4936
+ insert: (tableName, data) => this.recordResource.insert(tableName, data, dbId),
4937
+ insertMany: (tableName, records, options) => this.recordResource.insertMany(tableName, records, options, dbId),
4938
+ findAll: (tableName, options) => this.recordResource.list(tableName, options, dbId),
4939
+ findOne: (tableName, recordId) => this.recordResource.get(tableName, recordId, dbId),
4940
+ update: (tableName, options) => this.recordResource.update(tableName, options, dbId),
4941
+ updateById: (tableName, recordId, data) => this.recordResource.updateById(tableName, recordId, data, dbId),
4942
+ delete: (tableName, options) => this.recordResource.delete(tableName, options, dbId),
4943
+ deleteById: (tableName, recordId) => this.recordResource.deleteById(tableName, recordId, dbId)
4124
4944
  };
4125
4945
  }
4126
4946
  // Method 4: Create fluent record builder
@@ -4132,9 +4952,11 @@ class BolticClient {
4132
4952
  }
4133
4953
  // Direct SQL operations
4134
4954
  get sql() {
4955
+ var _a;
4956
+ const dbId = (_a = this.currentDatabase) == null ? void 0 : _a.databaseId;
4135
4957
  return {
4136
- textToSQL: (prompt, options) => this.sqlResource.textToSQL(prompt, options),
4137
- executeSQL: (query) => this.sqlResource.executeSQL(query)
4958
+ textToSQL: (prompt, options) => this.sqlResource.textToSQL(prompt, options, dbId),
4959
+ executeSQL: (query) => this.sqlResource.executeSQL(query, dbId)
4138
4960
  };
4139
4961
  }
4140
4962
  // SQL resource access for testing
@@ -4218,6 +5040,7 @@ class BolticClient {
4218
5040
  this.recordResource = new RecordResource(this.baseClient);
4219
5041
  this.sqlResource = new SqlResource(this.baseClient);
4220
5042
  this.indexResource = new IndexResource(this.baseClient);
5043
+ this.databaseResource = new DatabaseResource(this.baseClient);
4221
5044
  }
4222
5045
  // Security methods to prevent API key exposure
4223
5046
  toString() {
@@ -4286,4 +5109,4 @@ export {
4286
5109
  createMockResponse as p,
4287
5110
  createTestClient as q
4288
5111
  };
4289
- //# sourceMappingURL=test-client-rQ1AmTo6.mjs.map
5112
+ //# sourceMappingURL=test-client-D8i2zDgI.mjs.map