@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.
package/dist/sdk.mjs CHANGED
@@ -109,6 +109,12 @@ let AuthManager$1 = class AuthManager {
109
109
  }
110
110
  }
111
111
  };
112
+ function isErrorResponse(response) {
113
+ return "error" in response && response.error !== void 0;
114
+ }
115
+ function isListResponse(response) {
116
+ return "pagination" in response;
117
+ }
112
118
  class ValidationError extends Error {
113
119
  constructor(message, failures = []) {
114
120
  super(message);
@@ -228,7 +234,7 @@ class AuthManager2 {
228
234
  };
229
235
  }
230
236
  // Custom inspect method for Node.js console logging
231
- [Symbol.for("nodejs.util.inspect.custom")]() {
237
+ [/* @__PURE__ */ Symbol.for("nodejs.util.inspect.custom")]() {
232
238
  return this.toString();
233
239
  }
234
240
  }
@@ -505,14 +511,16 @@ class InterceptorManagerImpl {
505
511
  }
506
512
  async executeRequestInterceptors(config) {
507
513
  let result = config;
508
- for (const interceptor of this.requestInterceptors.values()) {
514
+ for (const interceptor of Array.from(this.requestInterceptors.values())) {
509
515
  result = await interceptor(result);
510
516
  }
511
517
  return result;
512
518
  }
513
519
  async executeResponseInterceptors(response) {
514
520
  let result = response;
515
- for (const { fulfilled } of this.responseInterceptors.values()) {
521
+ for (const { fulfilled } of Array.from(
522
+ this.responseInterceptors.values()
523
+ )) {
516
524
  if (fulfilled) {
517
525
  result = await fulfilled(result);
518
526
  }
@@ -521,7 +529,7 @@ class InterceptorManagerImpl {
521
529
  }
522
530
  async executeErrorInterceptors(error) {
523
531
  let result = error;
524
- for (const { rejected } of this.responseInterceptors.values()) {
532
+ for (const { rejected } of Array.from(this.responseInterceptors.values())) {
525
533
  if (rejected) {
526
534
  result = await rejected(result);
527
535
  }
@@ -728,7 +736,7 @@ class ConfigManager {
728
736
  return safeConfig;
729
737
  }
730
738
  // Custom inspect method for Node.js console logging
731
- [Symbol.for("nodejs.util.inspect.custom")]() {
739
+ [/* @__PURE__ */ Symbol.for("nodejs.util.inspect.custom")]() {
732
740
  return this.toString();
733
741
  }
734
742
  }
@@ -750,6 +758,13 @@ function filterArrayFields(arr, fields) {
750
758
  }
751
759
  return arr.map((obj) => filterObjectFields(obj, fields));
752
760
  }
761
+ function addDbIdToUrl(url, dbId) {
762
+ if (!dbId || dbId === "") {
763
+ return url;
764
+ }
765
+ const separator = url.includes("?") ? "&" : "?";
766
+ return `${url}${separator}db_id=${encodeURIComponent(dbId)}`;
767
+ }
753
768
  const COLUMN_ENDPOINTS = {
754
769
  list: {
755
770
  path: "/tables/{table_id}/fields/list",
@@ -983,7 +998,8 @@ class ColumnsApiClient {
983
998
  async listColumns(tableId, options = {}) {
984
999
  try {
985
1000
  const endpoint = COLUMN_ENDPOINTS.list;
986
- const url = `${this.baseURL}${buildEndpointPath$1(endpoint, { table_id: tableId })}?no_cache=true`;
1001
+ let url = `${this.baseURL}${buildEndpointPath$1(endpoint, { table_id: tableId })}?no_cache=true`;
1002
+ url = addDbIdToUrl(url, options.db_id);
987
1003
  const response = await this.httpAdapter.request({
988
1004
  url,
989
1005
  method: endpoint.method,
@@ -1452,7 +1468,8 @@ class TablesApiClient {
1452
1468
  async createTable(request, options = {}) {
1453
1469
  try {
1454
1470
  const endpoint = TABLE_ENDPOINTS.create;
1455
- const url = `${this.baseURL}${endpoint.path}`;
1471
+ let url = `${this.baseURL}${endpoint.path}`;
1472
+ url = addDbIdToUrl(url, options.db_id);
1456
1473
  const transformedRequest = transformTableCreateRequest(request, options);
1457
1474
  const response = await this.httpAdapter.request({
1458
1475
  url,
@@ -1472,7 +1489,8 @@ class TablesApiClient {
1472
1489
  async listTables(options = {}) {
1473
1490
  try {
1474
1491
  const endpoint = TABLE_ENDPOINTS.list;
1475
- const url = `${this.baseURL}${endpoint.path}`;
1492
+ let url = `${this.baseURL}${endpoint.path}`;
1493
+ url = addDbIdToUrl(url, options.db_id);
1476
1494
  const response = await this.httpAdapter.request({
1477
1495
  url,
1478
1496
  method: endpoint.method,
@@ -1498,7 +1516,8 @@ class TablesApiClient {
1498
1516
  async getTable(tableId, options = {}) {
1499
1517
  try {
1500
1518
  const endpoint = TABLE_ENDPOINTS.get;
1501
- const url = `${this.baseURL}${buildEndpointPath(endpoint, { table_id: tableId })}`;
1519
+ let url = `${this.baseURL}${buildEndpointPath(endpoint, { table_id: tableId })}`;
1520
+ url = addDbIdToUrl(url, options.db_id);
1502
1521
  const response = await this.httpAdapter.request({
1503
1522
  url,
1504
1523
  method: endpoint.method,
@@ -1522,9 +1541,10 @@ class TablesApiClient {
1522
1541
  */
1523
1542
  async updateTable(tableId, updates) {
1524
1543
  try {
1525
- const { fields, ...updateData } = updates;
1544
+ const { fields, db_id, ...updateData } = updates;
1526
1545
  const endpoint = TABLE_ENDPOINTS.update;
1527
- const url = `${this.baseURL}${buildEndpointPath(endpoint, { table_id: tableId })}`;
1546
+ let url = `${this.baseURL}${buildEndpointPath(endpoint, { table_id: tableId })}`;
1547
+ url = addDbIdToUrl(url, db_id);
1528
1548
  const response = await this.httpAdapter.request({
1529
1549
  url,
1530
1550
  method: endpoint.method,
@@ -1547,10 +1567,11 @@ class TablesApiClient {
1547
1567
  /**
1548
1568
  * Delete a table
1549
1569
  */
1550
- async deleteTable(tableId) {
1570
+ async deleteTable(tableId, options = {}) {
1551
1571
  try {
1552
1572
  const endpoint = TABLE_ENDPOINTS.delete;
1553
- 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);
1554
1575
  const response = await this.httpAdapter.request({
1555
1576
  url,
1556
1577
  method: endpoint.method,
@@ -1605,12 +1626,6 @@ class TablesApiClient {
1605
1626
  };
1606
1627
  }
1607
1628
  }
1608
- function isErrorResponse(response) {
1609
- return "error" in response && response.error !== void 0;
1610
- }
1611
- function isListResponse(response) {
1612
- return "pagination" in response;
1613
- }
1614
1629
  class BaseResource {
1615
1630
  constructor(client, basePath) {
1616
1631
  this.client = client;
@@ -1711,13 +1726,16 @@ class TableResource extends BaseResource {
1711
1726
  /**
1712
1727
  * Create a new table
1713
1728
  */
1714
- async create(data) {
1729
+ async create(data, dbId) {
1715
1730
  try {
1716
1731
  const processedData = { ...data };
1717
1732
  if (data.fields && data.fields.length > 0) {
1718
1733
  processedData.fields = await this.processFieldsDefaults(data.fields);
1719
1734
  }
1720
- const result = await this.tablesApiClient.createTable(processedData);
1735
+ const result = await this.tablesApiClient.createTable(
1736
+ processedData,
1737
+ dbId ? { db_id: dbId } : {}
1738
+ );
1721
1739
  if (isErrorResponse(result)) {
1722
1740
  throw new ApiError(
1723
1741
  result.error.message || "Create table failed",
@@ -1800,12 +1818,17 @@ class TableResource extends BaseResource {
1800
1818
  /**
1801
1819
  * Find all tables with optional filtering
1802
1820
  */
1803
- async findAll(options = {}) {
1821
+ async findAll(options = {}, dbId) {
1804
1822
  try {
1805
1823
  const apiRequest = this.transformTableQueryToApiRequest(options);
1806
- const result = await this.tablesApiClient.listTables(
1807
- apiRequest
1808
- );
1824
+ const requestPayload = {
1825
+ page: apiRequest.page,
1826
+ filters: apiRequest.filters,
1827
+ sort: apiRequest.sort,
1828
+ ...dbId && { db_id: dbId },
1829
+ ...options.fields && { fields: options.fields }
1830
+ };
1831
+ const result = await this.tablesApiClient.listTables(requestPayload);
1809
1832
  if (isErrorResponse(result)) {
1810
1833
  throw new ApiError(
1811
1834
  result.error.message || "List tables failed",
@@ -1821,7 +1844,7 @@ class TableResource extends BaseResource {
1821
1844
  /**
1822
1845
  * Find a single table by ID or name
1823
1846
  */
1824
- async findOne(options) {
1847
+ async findOne(options, dbId) {
1825
1848
  try {
1826
1849
  if (!options.where?.id && !options.where?.name) {
1827
1850
  throw new ValidationError(
@@ -1830,7 +1853,8 @@ class TableResource extends BaseResource {
1830
1853
  }
1831
1854
  if (options.where?.id) {
1832
1855
  const result = await this.tablesApiClient.getTable(
1833
- options.where.id
1856
+ options.where.id,
1857
+ dbId ? { db_id: dbId } : {}
1834
1858
  );
1835
1859
  if (isErrorResponse(result)) {
1836
1860
  if (result.error.code === "TABLE_NOT_FOUND") {
@@ -1858,9 +1882,13 @@ class TableResource extends BaseResource {
1858
1882
  ],
1859
1883
  sort: []
1860
1884
  };
1861
- const listResult = await this.tablesApiClient.listTables(
1862
- apiRequest
1863
- );
1885
+ const requestPayload = {
1886
+ page: apiRequest.page,
1887
+ filters: apiRequest.filters,
1888
+ sort: apiRequest.sort,
1889
+ ...dbId && { db_id: dbId }
1890
+ };
1891
+ const listResult = await this.tablesApiClient.listTables(requestPayload);
1864
1892
  if (isErrorResponse(listResult)) {
1865
1893
  throw new ApiError(
1866
1894
  listResult.error.message || "Find table by name failed",
@@ -1881,21 +1909,21 @@ class TableResource extends BaseResource {
1881
1909
  /**
1882
1910
  * Find a single table by name
1883
1911
  */
1884
- async findByName(name) {
1885
- return this.findOne({ where: { name } });
1912
+ async findByName(name, dbId) {
1913
+ return this.findOne({ where: { name } }, dbId);
1886
1914
  }
1887
1915
  /**
1888
1916
  * Find a single table by ID
1889
1917
  */
1890
- async findById(id) {
1891
- return this.findOne({ where: { id } });
1918
+ async findById(id, dbId) {
1919
+ return this.findOne({ where: { id } }, dbId);
1892
1920
  }
1893
1921
  /**
1894
1922
  * Update a table by name
1895
1923
  */
1896
- async update(name, data) {
1924
+ async update(name, data, dbId) {
1897
1925
  try {
1898
- const tableResult = await this.findByName(name);
1926
+ const tableResult = await this.findByName(name, dbId);
1899
1927
  if (!tableResult.data) {
1900
1928
  throw new ApiError(`Table '${name}' not found`, 404);
1901
1929
  }
@@ -1907,7 +1935,7 @@ class TableResource extends BaseResource {
1907
1935
  }
1908
1936
  const result = await this.tablesApiClient.updateTable(
1909
1937
  tableResult.data.id,
1910
- data
1938
+ dbId ? { ...data, db_id: dbId } : data
1911
1939
  );
1912
1940
  if (isErrorResponse(result)) {
1913
1941
  throw new ApiError(
@@ -1924,9 +1952,9 @@ class TableResource extends BaseResource {
1924
1952
  /**
1925
1953
  * Delete a table by name
1926
1954
  */
1927
- async delete(name) {
1955
+ async delete(name, dbId) {
1928
1956
  try {
1929
- const tableResult = await this.findByName(name);
1957
+ const tableResult = await this.findByName(name, dbId);
1930
1958
  if (!tableResult.data) {
1931
1959
  throw new ApiError(`Table '${name}' not found`, 404);
1932
1960
  }
@@ -1937,7 +1965,8 @@ class TableResource extends BaseResource {
1937
1965
  );
1938
1966
  }
1939
1967
  const result = await this.tablesApiClient.deleteTable(
1940
- tableResult.data.id
1968
+ tableResult.data.id,
1969
+ dbId ? { db_id: dbId } : {}
1941
1970
  );
1942
1971
  if (isErrorResponse(result)) {
1943
1972
  throw new ApiError(
@@ -1954,11 +1983,15 @@ class TableResource extends BaseResource {
1954
1983
  /**
1955
1984
  * Rename a table
1956
1985
  */
1957
- async rename(oldName, newName) {
1986
+ async rename(oldName, newName, dbId) {
1958
1987
  try {
1959
- const result = await this.update(oldName, {
1960
- name: newName
1961
- });
1988
+ const result = await this.update(
1989
+ oldName,
1990
+ {
1991
+ name: newName
1992
+ },
1993
+ dbId
1994
+ );
1962
1995
  return result;
1963
1996
  } catch (error) {
1964
1997
  throw error instanceof ApiError ? error : new ApiError(this.formatError(error), 500);
@@ -1967,11 +2000,15 @@ class TableResource extends BaseResource {
1967
2000
  /**
1968
2001
  * Set table access permissions
1969
2002
  */
1970
- async setAccess(request) {
2003
+ async setAccess(request, dbId) {
1971
2004
  try {
1972
- const result = await this.update(request.table_name, {
1973
- is_shared: request.is_shared
1974
- });
2005
+ const result = await this.update(
2006
+ request.table_name,
2007
+ {
2008
+ is_shared: request.is_shared
2009
+ },
2010
+ dbId
2011
+ );
1975
2012
  return result;
1976
2013
  } catch (error) {
1977
2014
  throw error instanceof ApiError ? error : new ApiError(this.formatError(error), 500);
@@ -2362,6 +2399,658 @@ class ColumnResource extends BaseResource {
2362
2399
  return tableInfo?.id || null;
2363
2400
  }
2364
2401
  }
2402
+ const DATABASE_ENDPOINTS = {
2403
+ create: {
2404
+ path: "/tables/databases",
2405
+ method: "POST",
2406
+ authenticated: true
2407
+ },
2408
+ list: {
2409
+ path: "/tables/databases/list",
2410
+ method: "POST",
2411
+ authenticated: true
2412
+ },
2413
+ update: {
2414
+ path: "/tables/databases/{db_id}",
2415
+ method: "PATCH",
2416
+ authenticated: true
2417
+ },
2418
+ delete: {
2419
+ path: "/tables/databases/{db_id}",
2420
+ method: "DELETE",
2421
+ authenticated: true
2422
+ },
2423
+ listJobs: {
2424
+ path: "/tables/databases/jobs/list",
2425
+ method: "POST",
2426
+ authenticated: true
2427
+ },
2428
+ pollDeleteStatus: {
2429
+ path: "/tables/databases/delete-status/{job_id}",
2430
+ method: "GET",
2431
+ authenticated: true
2432
+ }
2433
+ };
2434
+ const buildDatabaseEndpointPath = (endpoint, params = {}) => {
2435
+ let path = endpoint.path;
2436
+ Object.entries(params).forEach(([key, value]) => {
2437
+ path = path.replace(`{${key}}`, value);
2438
+ });
2439
+ return path;
2440
+ };
2441
+ class DatabasesApiClient {
2442
+ constructor(apiKey, config = {}) {
2443
+ this.config = { apiKey, ...config };
2444
+ this.httpAdapter = createHttpAdapter();
2445
+ const environment = config.environment || "prod";
2446
+ const region = config.region || "asia-south1";
2447
+ this.baseURL = this.getBaseURL(environment, region);
2448
+ }
2449
+ getBaseURL(environment, region) {
2450
+ const regionConfig = REGION_CONFIGS[region];
2451
+ if (!regionConfig) {
2452
+ throw new Error(`Unsupported region: ${region}`);
2453
+ }
2454
+ const envConfig = regionConfig[environment];
2455
+ if (!envConfig) {
2456
+ throw new Error(
2457
+ `Unsupported environment: ${environment} for region: ${region}`
2458
+ );
2459
+ }
2460
+ return `${envConfig.baseURL}/v1`;
2461
+ }
2462
+ /**
2463
+ * Create a new database
2464
+ */
2465
+ async createDatabase(request) {
2466
+ try {
2467
+ const endpoint = DATABASE_ENDPOINTS.create;
2468
+ const url = `${this.baseURL}${endpoint.path}`;
2469
+ const response = await this.httpAdapter.request({
2470
+ url,
2471
+ method: endpoint.method,
2472
+ headers: {
2473
+ "Content-Type": "application/json",
2474
+ "x-boltic-token": this.config.apiKey
2475
+ },
2476
+ data: request,
2477
+ timeout: this.config.timeout
2478
+ });
2479
+ return response.data;
2480
+ } catch (error) {
2481
+ return this.handleError(error);
2482
+ }
2483
+ }
2484
+ /**
2485
+ * List databases with pagination, sorting, and filtering
2486
+ */
2487
+ async listDatabases(request = {}, queryParams, options) {
2488
+ try {
2489
+ const endpoint = DATABASE_ENDPOINTS.list;
2490
+ let url = `${this.baseURL}${endpoint.path}`;
2491
+ const params = new URLSearchParams();
2492
+ if (queryParams?.connector_id) {
2493
+ params.append("connector_id", queryParams.connector_id);
2494
+ }
2495
+ if (queryParams?.add_default_if_missing) {
2496
+ params.append(
2497
+ "add_default_if_missing",
2498
+ queryParams.add_default_if_missing
2499
+ );
2500
+ }
2501
+ if (params.toString()) {
2502
+ url += `?${params.toString()}`;
2503
+ }
2504
+ const response = await this.httpAdapter.request({
2505
+ url,
2506
+ method: endpoint.method,
2507
+ headers: {
2508
+ "Content-Type": "application/json",
2509
+ "x-boltic-token": this.config.apiKey
2510
+ },
2511
+ data: request,
2512
+ timeout: this.config.timeout
2513
+ });
2514
+ const result = response.data;
2515
+ if (options?.fields && !("error" in result)) {
2516
+ return {
2517
+ ...result,
2518
+ data: filterArrayFields(
2519
+ result.data,
2520
+ options.fields
2521
+ )
2522
+ };
2523
+ }
2524
+ return result;
2525
+ } catch (error) {
2526
+ return this.handleError(error);
2527
+ }
2528
+ }
2529
+ /**
2530
+ * Update a database
2531
+ */
2532
+ async updateDatabase(dbId, request) {
2533
+ try {
2534
+ const endpoint = DATABASE_ENDPOINTS.update;
2535
+ const path = buildDatabaseEndpointPath(endpoint, { db_id: dbId });
2536
+ const url = `${this.baseURL}${path}`;
2537
+ const response = await this.httpAdapter.request({
2538
+ url,
2539
+ method: endpoint.method,
2540
+ headers: {
2541
+ "Content-Type": "application/json",
2542
+ "x-boltic-token": this.config.apiKey
2543
+ },
2544
+ data: request,
2545
+ timeout: this.config.timeout
2546
+ });
2547
+ return response.data;
2548
+ } catch (error) {
2549
+ return this.handleError(error);
2550
+ }
2551
+ }
2552
+ /**
2553
+ * Delete a database (initiates deletion job)
2554
+ */
2555
+ async deleteDatabase(dbId) {
2556
+ try {
2557
+ const endpoint = DATABASE_ENDPOINTS.delete;
2558
+ const path = buildDatabaseEndpointPath(endpoint, { db_id: dbId });
2559
+ const url = `${this.baseURL}${path}`;
2560
+ const response = await this.httpAdapter.request({
2561
+ url,
2562
+ method: endpoint.method,
2563
+ headers: {
2564
+ "Content-Type": "application/json",
2565
+ "x-boltic-token": this.config.apiKey
2566
+ },
2567
+ timeout: this.config.timeout
2568
+ });
2569
+ return response.data;
2570
+ } catch (error) {
2571
+ return this.handleError(error);
2572
+ }
2573
+ }
2574
+ /**
2575
+ * List database jobs
2576
+ */
2577
+ async listDatabaseJobs(request = {}, options) {
2578
+ try {
2579
+ const endpoint = DATABASE_ENDPOINTS.listJobs;
2580
+ const url = `${this.baseURL}${endpoint.path}`;
2581
+ const response = await this.httpAdapter.request({
2582
+ url,
2583
+ method: endpoint.method,
2584
+ headers: {
2585
+ "Content-Type": "application/json",
2586
+ "x-boltic-token": this.config.apiKey
2587
+ },
2588
+ data: request,
2589
+ timeout: this.config.timeout
2590
+ });
2591
+ const result = response.data;
2592
+ if (options?.fields && !("error" in result)) {
2593
+ return {
2594
+ ...result,
2595
+ data: filterArrayFields(
2596
+ result.data,
2597
+ options.fields
2598
+ )
2599
+ };
2600
+ }
2601
+ return result;
2602
+ } catch (error) {
2603
+ return this.handleError(error);
2604
+ }
2605
+ }
2606
+ /**
2607
+ * Poll deletion status for a database job
2608
+ */
2609
+ async pollDeleteStatus(jobId) {
2610
+ try {
2611
+ const endpoint = DATABASE_ENDPOINTS.pollDeleteStatus;
2612
+ const path = buildDatabaseEndpointPath(endpoint, { job_id: jobId });
2613
+ const url = `${this.baseURL}${path}`;
2614
+ const response = await this.httpAdapter.request({
2615
+ url,
2616
+ method: endpoint.method,
2617
+ headers: {
2618
+ "Content-Type": "application/json",
2619
+ "x-boltic-token": this.config.apiKey
2620
+ },
2621
+ timeout: this.config.timeout
2622
+ });
2623
+ return response.data;
2624
+ } catch (error) {
2625
+ return this.handleError(error);
2626
+ }
2627
+ }
2628
+ /**
2629
+ * Handle API errors and convert to standard error format
2630
+ */
2631
+ handleError(error) {
2632
+ if (this.config.debug) {
2633
+ console.error("[DatabasesApiClient] Error:", error);
2634
+ }
2635
+ const hasErrorProperty = (err) => {
2636
+ return typeof err === "object" && err !== null && "error" in err && typeof err.error === "object" && err.error !== null;
2637
+ };
2638
+ const hasResponseError = (err) => {
2639
+ 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;
2640
+ };
2641
+ const isStandardError = (err) => {
2642
+ return err instanceof Error;
2643
+ };
2644
+ if (hasErrorProperty(error)) {
2645
+ const errorWithError = error;
2646
+ return {
2647
+ error: {
2648
+ code: typeof errorWithError.error.code === "number" ? String(errorWithError.error.code) : errorWithError.error.code || "UNKNOWN_ERROR",
2649
+ message: errorWithError.error.message || "An error occurred",
2650
+ meta: errorWithError.error.meta || []
2651
+ }
2652
+ };
2653
+ }
2654
+ if (hasResponseError(error)) {
2655
+ const errorWithResponse = error;
2656
+ return {
2657
+ error: {
2658
+ code: typeof errorWithResponse.response.data.error.code === "number" ? String(errorWithResponse.response.data.error.code) : errorWithResponse.response.data.error.code || "UNKNOWN_ERROR",
2659
+ message: errorWithResponse.response.data.error.message || "An error occurred",
2660
+ meta: errorWithResponse.response.data.error.meta || []
2661
+ }
2662
+ };
2663
+ }
2664
+ if (isStandardError(error)) {
2665
+ const standardError = error;
2666
+ return {
2667
+ error: {
2668
+ code: standardError.code || "UNKNOWN_ERROR",
2669
+ message: standardError.message || "An unexpected error occurred",
2670
+ meta: []
2671
+ }
2672
+ };
2673
+ }
2674
+ return {
2675
+ error: {
2676
+ code: "UNKNOWN_ERROR",
2677
+ message: "An unexpected error occurred",
2678
+ meta: []
2679
+ }
2680
+ };
2681
+ }
2682
+ }
2683
+ class DatabaseResource extends BaseResource {
2684
+ constructor(client) {
2685
+ super(client, "/v1/tables/databases");
2686
+ this.apiClient = new DatabasesApiClient(client.getConfig().apiKey, {
2687
+ environment: client.getConfig().environment,
2688
+ region: client.getConfig().region,
2689
+ timeout: client.getConfig().timeout,
2690
+ debug: client.getConfig().debug
2691
+ });
2692
+ }
2693
+ /**
2694
+ * Create a new database
2695
+ *
2696
+ * @param request - Database creation request
2697
+ * @returns Promise with created database or error
2698
+ *
2699
+ * @example
2700
+ * ```typescript
2701
+ * const result = await client.databases.create({
2702
+ * db_name: 'My Database',
2703
+ * db_internal_name: 'my-database',
2704
+ * resource_id: 'boltic'
2705
+ * });
2706
+ * ```
2707
+ */
2708
+ async create(request) {
2709
+ const result = await this.apiClient.createDatabase(request);
2710
+ if ("error" in result) {
2711
+ return {
2712
+ error: {
2713
+ code: typeof result.error.code === "number" ? String(result.error.code) : result.error.code,
2714
+ message: result.error.message,
2715
+ meta: result.error.meta
2716
+ }
2717
+ };
2718
+ }
2719
+ return result;
2720
+ }
2721
+ /**
2722
+ * List all databases with optional filtering and pagination
2723
+ * By default, only shows active databases
2724
+ *
2725
+ * @param options - Query options for listing databases
2726
+ * @returns Promise with list of databases or error
2727
+ *
2728
+ * @example
2729
+ * ```typescript
2730
+ * // List all active databases (default)
2731
+ * const result = await client.databases.findAll();
2732
+ *
2733
+ * // List with pagination
2734
+ * const result = await client.databases.findAll({
2735
+ * page: { page_no: 1, page_size: 10 }
2736
+ * });
2737
+ *
2738
+ * // List with sorting
2739
+ * const result = await client.databases.findAll({
2740
+ * sort: [{ field: 'db_name', direction: 'asc' }]
2741
+ * });
2742
+ * ```
2743
+ */
2744
+ async findAll(options) {
2745
+ const request = {};
2746
+ if (options?.page) {
2747
+ request.page = options.page;
2748
+ }
2749
+ if (options?.sort) {
2750
+ request.sort = options.sort;
2751
+ }
2752
+ if (options?.filters) {
2753
+ const filtersWithoutStatus = options.filters.filter(
2754
+ (f) => f.field !== "status"
2755
+ );
2756
+ request.filters = [
2757
+ ...filtersWithoutStatus,
2758
+ { field: "status", operator: "=", values: ["ACTIVE"] }
2759
+ ];
2760
+ } else {
2761
+ request.filters = [
2762
+ { field: "status", operator: "=", values: ["ACTIVE"] }
2763
+ ];
2764
+ }
2765
+ const queryParams = {};
2766
+ if (options?.connector_id) {
2767
+ queryParams.connector_id = options.connector_id;
2768
+ }
2769
+ if (options?.add_default_if_missing !== void 0) {
2770
+ queryParams.add_default_if_missing = options.add_default_if_missing ? "true" : "false";
2771
+ }
2772
+ const result = await this.apiClient.listDatabases(
2773
+ request,
2774
+ queryParams,
2775
+ options
2776
+ );
2777
+ if ("error" in result) {
2778
+ return {
2779
+ error: {
2780
+ code: typeof result.error.code === "number" ? String(result.error.code) : result.error.code,
2781
+ message: result.error.message,
2782
+ meta: result.error.meta
2783
+ }
2784
+ };
2785
+ }
2786
+ if ("pagination" in result && result.pagination) {
2787
+ const pagination = result.pagination;
2788
+ return {
2789
+ ...result,
2790
+ pagination: {
2791
+ total_count: pagination.total_count,
2792
+ total_pages: pagination.total_pages ?? Math.ceil(pagination.total_count / pagination.per_page),
2793
+ current_page: pagination.current_page,
2794
+ per_page: pagination.per_page,
2795
+ type: "page"
2796
+ }
2797
+ };
2798
+ }
2799
+ return result;
2800
+ }
2801
+ /**
2802
+ * Get a specific database by internal name (slug)
2803
+ *
2804
+ * @param dbInternalName - Database internal name (slug)
2805
+ * @param options - Query options (e.g., fields to return)
2806
+ * @returns Promise with database or error
2807
+ *
2808
+ * @example
2809
+ * ```typescript
2810
+ * const result = await client.databases.findOne('my_database_slug');
2811
+ * ```
2812
+ */
2813
+ async findOne(dbInternalName, options) {
2814
+ const result = await this.findAll({
2815
+ filters: [
2816
+ {
2817
+ field: "db_internal_name",
2818
+ operator: "=",
2819
+ values: [dbInternalName]
2820
+ }
2821
+ ],
2822
+ fields: options?.fields,
2823
+ page: { page_no: 1, page_size: 1 }
2824
+ });
2825
+ if (isErrorResponse(result)) {
2826
+ return result;
2827
+ }
2828
+ if (result.data.length === 0) {
2829
+ return {
2830
+ error: {
2831
+ code: "NOT_FOUND",
2832
+ message: `Database with internal name '${dbInternalName}' not found`,
2833
+ meta: []
2834
+ }
2835
+ };
2836
+ }
2837
+ return {
2838
+ data: result.data[0],
2839
+ message: "Database found"
2840
+ };
2841
+ }
2842
+ /**
2843
+ * Get the default database
2844
+ *
2845
+ * @returns Promise with default database or error
2846
+ *
2847
+ * @example
2848
+ * ```typescript
2849
+ * const result = await client.databases.getDefault();
2850
+ * ```
2851
+ */
2852
+ async getDefault() {
2853
+ const result = await this.findAll({
2854
+ filters: [{ field: "is_default", operator: "=", values: [true] }],
2855
+ page: { page_no: 1, page_size: 1 }
2856
+ });
2857
+ if (isErrorResponse(result)) {
2858
+ return result;
2859
+ }
2860
+ if (result.data.length === 0) {
2861
+ return {
2862
+ error: {
2863
+ code: "NOT_FOUND",
2864
+ message: "Default database not found",
2865
+ meta: []
2866
+ }
2867
+ };
2868
+ }
2869
+ return {
2870
+ data: result.data[0],
2871
+ message: "Default database found"
2872
+ };
2873
+ }
2874
+ /**
2875
+ * Update a database
2876
+ * Only allows updating the display name (db_name)
2877
+ *
2878
+ * @param dbInternalName - Database internal name (slug)
2879
+ * @param request - Update request (only db_name is allowed)
2880
+ * @returns Promise with updated database or error
2881
+ *
2882
+ * @example
2883
+ * ```typescript
2884
+ * const result = await client.databases.update('my_database_slug', {
2885
+ * db_name: 'Updated Database Name'
2886
+ * });
2887
+ * ```
2888
+ */
2889
+ async update(dbInternalName, request) {
2890
+ const dbInfo = await this.findOne(dbInternalName);
2891
+ if (isErrorResponse(dbInfo)) {
2892
+ return {
2893
+ error: {
2894
+ code: "DATABASE_NOT_FOUND",
2895
+ message: `Database with internal name '${dbInternalName}' not found`,
2896
+ meta: []
2897
+ }
2898
+ };
2899
+ }
2900
+ const dbId = dbInfo.data.id;
2901
+ const updateRequest = {
2902
+ db_name: request.db_name
2903
+ };
2904
+ const result = await this.apiClient.updateDatabase(dbId, updateRequest);
2905
+ if ("error" in result) {
2906
+ return {
2907
+ error: {
2908
+ code: typeof result.error.code === "number" ? String(result.error.code) : result.error.code,
2909
+ message: result.error.message,
2910
+ meta: result.error.meta
2911
+ }
2912
+ };
2913
+ }
2914
+ return result;
2915
+ }
2916
+ /**
2917
+ * Delete a database (initiates async deletion job)
2918
+ *
2919
+ * @param dbInternalName - Database internal name (slug)
2920
+ * @returns Promise with job details or error
2921
+ *
2922
+ * @example
2923
+ * ```typescript
2924
+ * const result = await client.databases.delete('my_database_slug');
2925
+ * if (!result.error) {
2926
+ * console.log('Deletion job started:', result.data.job_id);
2927
+ * // Poll for status
2928
+ * const status = await client.databases.pollDeleteStatus(result.data.job_id);
2929
+ * }
2930
+ * ```
2931
+ */
2932
+ async delete(dbInternalName) {
2933
+ const dbInfo = await this.findOne(dbInternalName);
2934
+ if (isErrorResponse(dbInfo)) {
2935
+ return {
2936
+ error: {
2937
+ code: "DATABASE_NOT_FOUND",
2938
+ message: `Database with internal name '${dbInternalName}' not found`,
2939
+ meta: []
2940
+ }
2941
+ };
2942
+ }
2943
+ if (dbInfo.data.is_default) {
2944
+ return {
2945
+ error: {
2946
+ code: "CANNOT_DELETE_DEFAULT",
2947
+ message: "Cannot delete the default database",
2948
+ meta: []
2949
+ }
2950
+ };
2951
+ }
2952
+ const dbId = dbInfo.data.id;
2953
+ const result = await this.apiClient.deleteDatabase(dbId);
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
+ * List database jobs (e.g., deletion jobs)
2967
+ *
2968
+ * @param options - Query options for listing jobs
2969
+ * @returns Promise with list of jobs or error
2970
+ *
2971
+ * @example
2972
+ * ```typescript
2973
+ * // List all jobs
2974
+ * const result = await client.databases.listJobs();
2975
+ *
2976
+ * // List jobs deleted by current user
2977
+ * const result = await client.databases.listJobs({
2978
+ * deleted_by_me: true
2979
+ * });
2980
+ * ```
2981
+ */
2982
+ async listJobs(options) {
2983
+ const request = {};
2984
+ if (options?.deleted_by_me !== void 0) {
2985
+ request.deleted_by_me = options.deleted_by_me;
2986
+ }
2987
+ if (options?.page) {
2988
+ request.page = options.page;
2989
+ }
2990
+ if (options?.sort) {
2991
+ request.sort = options.sort;
2992
+ }
2993
+ if (options?.filters) {
2994
+ request.filters = options.filters;
2995
+ }
2996
+ const result = await this.apiClient.listDatabaseJobs(request, options);
2997
+ if ("error" in result) {
2998
+ return {
2999
+ error: {
3000
+ code: typeof result.error.code === "number" ? String(result.error.code) : result.error.code,
3001
+ message: result.error.message,
3002
+ meta: result.error.meta
3003
+ }
3004
+ };
3005
+ }
3006
+ if ("pagination" in result && result.pagination) {
3007
+ const pagination = result.pagination;
3008
+ const normalizedResult = {
3009
+ ...result,
3010
+ pagination: {
3011
+ total_count: pagination.total_count,
3012
+ total_pages: pagination.total_pages ?? Math.ceil(pagination.total_count / pagination.per_page),
3013
+ current_page: pagination.current_page,
3014
+ per_page: pagination.per_page,
3015
+ type: "page"
3016
+ }
3017
+ };
3018
+ return normalizedResult;
3019
+ }
3020
+ return {
3021
+ ...result,
3022
+ data: result.data || []
3023
+ };
3024
+ }
3025
+ /**
3026
+ * Poll the status of a database deletion job
3027
+ *
3028
+ * @param jobId - Job ID
3029
+ * @returns Promise with job status or error
3030
+ *
3031
+ * @example
3032
+ * ```typescript
3033
+ * const status = await client.databases.pollDeleteStatus('job-uuid');
3034
+ * if (!status.error) {
3035
+ * console.log('Job status:', status.data.status);
3036
+ * console.log('Message:', status.data.message);
3037
+ * }
3038
+ * ```
3039
+ */
3040
+ async pollDeleteStatus(jobId) {
3041
+ const result = await this.apiClient.pollDeleteStatus(jobId);
3042
+ if ("error" in result) {
3043
+ return {
3044
+ error: {
3045
+ code: typeof result.error.code === "number" ? String(result.error.code) : result.error.code,
3046
+ message: result.error.message,
3047
+ meta: result.error.meta
3048
+ }
3049
+ };
3050
+ }
3051
+ return result;
3052
+ }
3053
+ }
2365
3054
  const INDEX_ENDPOINTS = {
2366
3055
  create: {
2367
3056
  path: "/tables/indexes/{table_id}",
@@ -2411,10 +3100,11 @@ class IndexesApiClient {
2411
3100
  }
2412
3101
  return `${envConfig.baseURL}/v1`;
2413
3102
  }
2414
- async addIndex(tableId, request) {
3103
+ async addIndex(tableId, request, dbId) {
2415
3104
  try {
2416
3105
  const endpoint = INDEX_ENDPOINTS.create;
2417
- const url = `${this.baseURL}${buildIndexEndpointPath(endpoint, { table_id: tableId })}`;
3106
+ let url = `${this.baseURL}${buildIndexEndpointPath(endpoint, { table_id: tableId })}`;
3107
+ url = addDbIdToUrl(url, dbId);
2418
3108
  const response = await this.httpAdapter.request({
2419
3109
  url,
2420
3110
  method: endpoint.method,
@@ -2427,10 +3117,11 @@ class IndexesApiClient {
2427
3117
  return this.formatErrorResponse(error);
2428
3118
  }
2429
3119
  }
2430
- async listIndexes(tableId, query) {
3120
+ async listIndexes(tableId, query, dbId) {
2431
3121
  try {
2432
3122
  const endpoint = INDEX_ENDPOINTS.list;
2433
- const url = `${this.baseURL}${buildIndexEndpointPath(endpoint, { table_id: tableId })}`;
3123
+ let url = `${this.baseURL}${buildIndexEndpointPath(endpoint, { table_id: tableId })}`;
3124
+ url = addDbIdToUrl(url, dbId);
2434
3125
  const response = await this.httpAdapter.request({
2435
3126
  url,
2436
3127
  method: endpoint.method,
@@ -2443,10 +3134,11 @@ class IndexesApiClient {
2443
3134
  return this.formatErrorResponse(error);
2444
3135
  }
2445
3136
  }
2446
- async deleteIndex(tableId, request) {
3137
+ async deleteIndex(tableId, request, dbId) {
2447
3138
  try {
2448
3139
  const endpoint = INDEX_ENDPOINTS.delete;
2449
- const url = `${this.baseURL}${buildIndexEndpointPath(endpoint, { table_id: tableId })}`;
3140
+ let url = `${this.baseURL}${buildIndexEndpointPath(endpoint, { table_id: tableId })}`;
3141
+ url = addDbIdToUrl(url, dbId);
2450
3142
  const response = await this.httpAdapter.request({
2451
3143
  url,
2452
3144
  method: endpoint.method,
@@ -2516,15 +3208,15 @@ class IndexResource {
2516
3208
  });
2517
3209
  this.tableResource = new TableResource(client);
2518
3210
  }
2519
- async resolveTableId(tableName) {
2520
- const tableResult = await this.tableResource.findByName(tableName);
3211
+ async resolveTableId(tableName, dbId) {
3212
+ const tableResult = await this.tableResource.findByName(tableName, dbId);
2521
3213
  if (!tableResult.data) throw new Error(`Table not found: ${tableName}`);
2522
3214
  return tableResult.data.id;
2523
3215
  }
2524
- async addIndex(tableName, request) {
3216
+ async addIndex(tableName, request, dbId) {
2525
3217
  try {
2526
- const tableId = await this.resolveTableId(tableName);
2527
- return await this.apiClient.addIndex(tableId, request);
3218
+ const tableId = await this.resolveTableId(tableName, dbId);
3219
+ return await this.apiClient.addIndex(tableId, request, dbId);
2528
3220
  } catch (error) {
2529
3221
  return {
2530
3222
  error: {
@@ -2535,10 +3227,10 @@ class IndexResource {
2535
3227
  };
2536
3228
  }
2537
3229
  }
2538
- async listIndexes(tableName, query) {
3230
+ async listIndexes(tableName, query, dbId) {
2539
3231
  try {
2540
- const tableId = await this.resolveTableId(tableName);
2541
- return await this.apiClient.listIndexes(tableId, query);
3232
+ const tableId = await this.resolveTableId(tableName, dbId);
3233
+ return await this.apiClient.listIndexes(tableId, query, dbId);
2542
3234
  } catch (error) {
2543
3235
  return {
2544
3236
  error: {
@@ -2549,11 +3241,11 @@ class IndexResource {
2549
3241
  };
2550
3242
  }
2551
3243
  }
2552
- async deleteIndex(tableName, indexName) {
3244
+ async deleteIndex(tableName, indexName, dbId) {
2553
3245
  try {
2554
- const tableId = await this.resolveTableId(tableName);
3246
+ const tableId = await this.resolveTableId(tableName, dbId);
2555
3247
  const request = { index_name: indexName };
2556
- return await this.apiClient.deleteIndex(tableId, request);
3248
+ return await this.apiClient.deleteIndex(tableId, request, dbId);
2557
3249
  } catch (error) {
2558
3250
  return {
2559
3251
  error: {
@@ -2660,7 +3352,7 @@ class RecordsApiClient {
2660
3352
  /**
2661
3353
  * Insert a single record
2662
3354
  */
2663
- async insertRecord(request) {
3355
+ async insertRecord(request, dbId) {
2664
3356
  try {
2665
3357
  const { table_id, fields, ...recordData } = request;
2666
3358
  if (!table_id) {
@@ -2669,7 +3361,8 @@ class RecordsApiClient {
2669
3361
  );
2670
3362
  }
2671
3363
  const endpoint = RECORD_ENDPOINTS.insert;
2672
- const url = `${this.baseURL}${buildRecordEndpointPath(endpoint, { table_id })}`;
3364
+ let url = `${this.baseURL}${buildRecordEndpointPath(endpoint, { table_id })}`;
3365
+ url = addDbIdToUrl(url, dbId);
2673
3366
  const response = await this.httpAdapter.request({
2674
3367
  url,
2675
3368
  method: endpoint.method,
@@ -2692,7 +3385,7 @@ class RecordsApiClient {
2692
3385
  /**
2693
3386
  * Insert multiple records in bulk
2694
3387
  */
2695
- async insertManyRecords(records, tableId, options = { validation: true }) {
3388
+ async insertManyRecords(records, tableId, options = { validation: true }, dbId) {
2696
3389
  try {
2697
3390
  if (!tableId) {
2698
3391
  return this.formatErrorResponse(
@@ -2713,6 +3406,7 @@ class RecordsApiClient {
2713
3406
  if (queryParams.toString()) {
2714
3407
  url += `?${queryParams.toString()}`;
2715
3408
  }
3409
+ url = addDbIdToUrl(url, dbId);
2716
3410
  const response = await this.httpAdapter.request({
2717
3411
  url,
2718
3412
  method: endpoint.method,
@@ -2728,7 +3422,7 @@ class RecordsApiClient {
2728
3422
  /**
2729
3423
  * Get a single record by ID
2730
3424
  */
2731
- async getRecord(recordId, tableId, options = {}) {
3425
+ async getRecord(recordId, tableId, options = {}, dbId) {
2732
3426
  try {
2733
3427
  if (!tableId) {
2734
3428
  return this.formatErrorResponse(
@@ -2736,10 +3430,11 @@ class RecordsApiClient {
2736
3430
  );
2737
3431
  }
2738
3432
  const endpoint = RECORD_ENDPOINTS.get;
2739
- const url = `${this.baseURL}${buildRecordEndpointPath(endpoint, {
3433
+ let url = `${this.baseURL}${buildRecordEndpointPath(endpoint, {
2740
3434
  table_id: tableId,
2741
3435
  record_id: recordId
2742
3436
  })}`;
3437
+ url = addDbIdToUrl(url, dbId);
2743
3438
  const response = await this.httpAdapter.request({
2744
3439
  url,
2745
3440
  method: endpoint.method,
@@ -2761,7 +3456,7 @@ class RecordsApiClient {
2761
3456
  /**
2762
3457
  * List records with filtering and pagination
2763
3458
  */
2764
- async listRecords(options = {}) {
3459
+ async listRecords(options = {}, dbId) {
2765
3460
  try {
2766
3461
  const { table_id, ...queryOptions } = options;
2767
3462
  if (!table_id) {
@@ -2770,7 +3465,8 @@ class RecordsApiClient {
2770
3465
  );
2771
3466
  }
2772
3467
  const endpoint = RECORD_ENDPOINTS.list;
2773
- const url = `${this.baseURL}${buildRecordEndpointPath(endpoint, { table_id })}`;
3468
+ let url = `${this.baseURL}${buildRecordEndpointPath(endpoint, { table_id })}`;
3469
+ url = addDbIdToUrl(url, dbId);
2774
3470
  const response = await this.httpAdapter.request({
2775
3471
  url,
2776
3472
  method: endpoint.method,
@@ -2793,7 +3489,7 @@ class RecordsApiClient {
2793
3489
  /**
2794
3490
  * Update records by filters
2795
3491
  */
2796
- async updateRecords(request) {
3492
+ async updateRecords(request, dbId) {
2797
3493
  try {
2798
3494
  const { table_id, set, filters, fields, ...rest } = request;
2799
3495
  if (!table_id) {
@@ -2810,7 +3506,8 @@ class RecordsApiClient {
2810
3506
  apiPayload.fields = fields;
2811
3507
  }
2812
3508
  const endpoint = RECORD_ENDPOINTS.update;
2813
- const url = `${this.baseURL}${buildRecordEndpointPath(endpoint, { table_id })}`;
3509
+ let url = `${this.baseURL}${buildRecordEndpointPath(endpoint, { table_id })}`;
3510
+ url = addDbIdToUrl(url, dbId);
2814
3511
  const response = await this.httpAdapter.request({
2815
3512
  url,
2816
3513
  method: endpoint.method,
@@ -2833,7 +3530,7 @@ class RecordsApiClient {
2833
3530
  /**
2834
3531
  * Update a single record by ID
2835
3532
  */
2836
- async updateRecordById(recordId, request) {
3533
+ async updateRecordById(recordId, request, dbId) {
2837
3534
  try {
2838
3535
  const { table_id, ...updateOptions } = request;
2839
3536
  if (!table_id) {
@@ -2842,10 +3539,11 @@ class RecordsApiClient {
2842
3539
  );
2843
3540
  }
2844
3541
  const endpoint = RECORD_ENDPOINTS.updateById;
2845
- const url = `${this.baseURL}${buildRecordEndpointPath(endpoint, {
3542
+ let url = `${this.baseURL}${buildRecordEndpointPath(endpoint, {
2846
3543
  record_id: recordId,
2847
3544
  table_id
2848
3545
  })}`;
3546
+ url = addDbIdToUrl(url, dbId);
2849
3547
  const response = await this.httpAdapter.request({
2850
3548
  url,
2851
3549
  method: endpoint.method,
@@ -2868,7 +3566,7 @@ class RecordsApiClient {
2868
3566
  /**
2869
3567
  * Unified delete records method that supports both record_ids and filters
2870
3568
  */
2871
- async deleteRecords(request) {
3569
+ async deleteRecords(request, dbId) {
2872
3570
  try {
2873
3571
  const { table_id } = request;
2874
3572
  if (!table_id) {
@@ -2878,7 +3576,8 @@ class RecordsApiClient {
2878
3576
  }
2879
3577
  const transformedRequest = transformDeleteRequest(request);
2880
3578
  const endpoint = RECORD_ENDPOINTS.delete;
2881
- const url = `${this.baseURL}${buildRecordEndpointPath(endpoint, { table_id })}`;
3579
+ let url = `${this.baseURL}${buildRecordEndpointPath(endpoint, { table_id })}`;
3580
+ url = addDbIdToUrl(url, dbId);
2882
3581
  const response = await this.httpAdapter.request({
2883
3582
  url,
2884
3583
  method: endpoint.method,
@@ -2894,11 +3593,14 @@ class RecordsApiClient {
2894
3593
  /**
2895
3594
  * Delete a single record by ID
2896
3595
  */
2897
- async deleteRecordById(recordId, request) {
2898
- return this.deleteRecords({
2899
- record_ids: [recordId],
2900
- table_id: request.table_id
2901
- });
3596
+ async deleteRecordById(recordId, request, dbId) {
3597
+ return this.deleteRecords(
3598
+ {
3599
+ record_ids: [recordId],
3600
+ table_id: request.table_id
3601
+ },
3602
+ dbId
3603
+ );
2902
3604
  }
2903
3605
  buildHeaders() {
2904
3606
  return {
@@ -2961,9 +3663,9 @@ class RecordResource {
2961
3663
  /**
2962
3664
  * Insert a single record
2963
3665
  */
2964
- async insert(tableName, data) {
3666
+ async insert(tableName, data, dbId) {
2965
3667
  try {
2966
- const tableInfo = await this.getTableInfo(tableName);
3668
+ const tableInfo = await this.getTableInfo(tableName, dbId);
2967
3669
  if (!tableInfo) {
2968
3670
  return {
2969
3671
  error: {
@@ -2983,7 +3685,7 @@ class RecordResource {
2983
3685
  ...completeDataResult,
2984
3686
  table_id: tableInfo.id
2985
3687
  };
2986
- const result = await this.apiClient.insertRecord(requestData);
3688
+ const result = await this.apiClient.insertRecord(requestData, dbId);
2987
3689
  if (isErrorResponse(result)) {
2988
3690
  return result;
2989
3691
  }
@@ -3000,7 +3702,7 @@ class RecordResource {
3000
3702
  /**
3001
3703
  * Insert multiple records in bulk
3002
3704
  */
3003
- async insertMany(tableName, records, options = { validation: true }) {
3705
+ async insertMany(tableName, records, options = { validation: true }, dbId) {
3004
3706
  try {
3005
3707
  if (!records || !Array.isArray(records) || records.length === 0) {
3006
3708
  return {
@@ -3010,7 +3712,7 @@ class RecordResource {
3010
3712
  }
3011
3713
  };
3012
3714
  }
3013
- const tableInfo = await this.getTableInfo(tableName);
3715
+ const tableInfo = await this.getTableInfo(tableName, dbId);
3014
3716
  if (!tableInfo) {
3015
3717
  return {
3016
3718
  error: {
@@ -3022,7 +3724,8 @@ class RecordResource {
3022
3724
  const result = await this.apiClient.insertManyRecords(
3023
3725
  records,
3024
3726
  tableInfo.id,
3025
- options
3727
+ options,
3728
+ dbId
3026
3729
  );
3027
3730
  if (isErrorResponse(result)) {
3028
3731
  return result;
@@ -3040,9 +3743,9 @@ class RecordResource {
3040
3743
  /**
3041
3744
  * Get a single record by ID
3042
3745
  */
3043
- async get(tableName, recordId) {
3746
+ async get(tableName, recordId, dbId) {
3044
3747
  try {
3045
- const tableInfo = await this.getTableInfo(tableName);
3748
+ const tableInfo = await this.getTableInfo(tableName, dbId);
3046
3749
  if (!tableInfo) {
3047
3750
  return {
3048
3751
  error: {
@@ -3051,7 +3754,12 @@ class RecordResource {
3051
3754
  }
3052
3755
  };
3053
3756
  }
3054
- const result = await this.apiClient.getRecord(recordId, tableInfo.id);
3757
+ const result = await this.apiClient.getRecord(
3758
+ recordId,
3759
+ tableInfo.id,
3760
+ { fields: void 0 },
3761
+ dbId
3762
+ );
3055
3763
  if (isErrorResponse(result)) {
3056
3764
  return result;
3057
3765
  }
@@ -3068,9 +3776,9 @@ class RecordResource {
3068
3776
  /**
3069
3777
  * List records with filtering and pagination
3070
3778
  */
3071
- async list(tableName, options = {}) {
3779
+ async list(tableName, options = {}, dbId) {
3072
3780
  try {
3073
- const tableInfo = await this.getTableInfo(tableName);
3781
+ const tableInfo = await this.getTableInfo(tableName, dbId);
3074
3782
  if (!tableInfo) {
3075
3783
  return {
3076
3784
  error: {
@@ -3080,7 +3788,7 @@ class RecordResource {
3080
3788
  };
3081
3789
  }
3082
3790
  const requestOptions = { ...options, table_id: tableInfo.id };
3083
- const result = await this.apiClient.listRecords(requestOptions);
3791
+ const result = await this.apiClient.listRecords(requestOptions, dbId);
3084
3792
  if (isErrorResponse(result)) {
3085
3793
  return result;
3086
3794
  }
@@ -3097,9 +3805,9 @@ class RecordResource {
3097
3805
  /**
3098
3806
  * Update records by filters
3099
3807
  */
3100
- async update(tableName, options) {
3808
+ async update(tableName, options, dbId) {
3101
3809
  try {
3102
- const tableInfo = await this.getTableInfo(tableName);
3810
+ const tableInfo = await this.getTableInfo(tableName, dbId);
3103
3811
  if (!tableInfo) {
3104
3812
  return {
3105
3813
  error: {
@@ -3109,7 +3817,7 @@ class RecordResource {
3109
3817
  };
3110
3818
  }
3111
3819
  const requestOptions = { ...options, table_id: tableInfo.id };
3112
- const result = await this.apiClient.updateRecords(requestOptions);
3820
+ const result = await this.apiClient.updateRecords(requestOptions, dbId);
3113
3821
  if (isErrorResponse(result)) {
3114
3822
  return result;
3115
3823
  }
@@ -3126,9 +3834,9 @@ class RecordResource {
3126
3834
  /**
3127
3835
  * Update a single record by ID
3128
3836
  */
3129
- async updateById(tableName, recordId, data) {
3837
+ async updateById(tableName, recordId, data, dbId) {
3130
3838
  try {
3131
- const tableInfo = await this.getTableInfo(tableName);
3839
+ const tableInfo = await this.getTableInfo(tableName, dbId);
3132
3840
  if (!tableInfo) {
3133
3841
  return {
3134
3842
  error: {
@@ -3144,7 +3852,8 @@ class RecordResource {
3144
3852
  };
3145
3853
  const result = await this.apiClient.updateRecordById(
3146
3854
  recordId,
3147
- requestOptions
3855
+ requestOptions,
3856
+ dbId
3148
3857
  );
3149
3858
  if (isErrorResponse(result)) {
3150
3859
  return result;
@@ -3162,9 +3871,9 @@ class RecordResource {
3162
3871
  /**
3163
3872
  * Unified delete method that supports both record IDs and filters
3164
3873
  */
3165
- async delete(tableName, options) {
3874
+ async delete(tableName, options, dbId) {
3166
3875
  try {
3167
- const tableInfo = await this.getTableInfo(tableName);
3876
+ const tableInfo = await this.getTableInfo(tableName, dbId);
3168
3877
  if (!tableInfo) {
3169
3878
  return {
3170
3879
  error: {
@@ -3174,7 +3883,7 @@ class RecordResource {
3174
3883
  };
3175
3884
  }
3176
3885
  const requestOptions = { ...options, table_id: tableInfo.id };
3177
- const result = await this.apiClient.deleteRecords(requestOptions);
3886
+ const result = await this.apiClient.deleteRecords(requestOptions, dbId);
3178
3887
  if (isErrorResponse(result)) {
3179
3888
  return result;
3180
3889
  }
@@ -3191,9 +3900,9 @@ class RecordResource {
3191
3900
  /**
3192
3901
  * Delete a single record by ID
3193
3902
  */
3194
- async deleteById(tableName, recordId) {
3903
+ async deleteById(tableName, recordId, dbId) {
3195
3904
  try {
3196
- const tableInfo = await this.getTableInfo(tableName);
3905
+ const tableInfo = await this.getTableInfo(tableName, dbId);
3197
3906
  if (!tableInfo) {
3198
3907
  return {
3199
3908
  error: {
@@ -3202,9 +3911,13 @@ class RecordResource {
3202
3911
  }
3203
3912
  };
3204
3913
  }
3205
- const result = await this.apiClient.deleteRecordById(recordId, {
3206
- table_id: tableInfo.id
3207
- });
3914
+ const result = await this.apiClient.deleteRecordById(
3915
+ recordId,
3916
+ {
3917
+ table_id: tableInfo.id
3918
+ },
3919
+ dbId
3920
+ );
3208
3921
  if (isErrorResponse(result)) {
3209
3922
  return result;
3210
3923
  }
@@ -3221,10 +3934,10 @@ class RecordResource {
3221
3934
  /**
3222
3935
  * Helper method to get table information by name
3223
3936
  */
3224
- async getTableInfo(tableName) {
3937
+ async getTableInfo(tableName, dbId) {
3225
3938
  try {
3226
3939
  const tableResource = new TableResource(this.client);
3227
- const tableResult = await tableResource.findByName(tableName);
3940
+ const tableResult = await tableResource.findByName(tableName, dbId);
3228
3941
  if (tableResult.data) {
3229
3942
  return {
3230
3943
  id: tableResult.data.id,
@@ -3576,7 +4289,7 @@ class BaseApiClient {
3576
4289
  };
3577
4290
  }
3578
4291
  // Custom inspect method for Node.js console logging
3579
- [Symbol.for("nodejs.util.inspect.custom")]() {
4292
+ [/* @__PURE__ */ Symbol.for("nodejs.util.inspect.custom")]() {
3580
4293
  return this.toString();
3581
4294
  }
3582
4295
  }
@@ -3587,10 +4300,13 @@ class SqlApiClient extends BaseApiClient {
3587
4300
  /**
3588
4301
  * Convert natural language to SQL query (streaming)
3589
4302
  */
3590
- async textToSQL(request) {
4303
+ async textToSQL(request, dbId) {
3591
4304
  try {
3592
4305
  const endpoint = SQL_ENDPOINTS.textToSQL;
3593
- const url = `${this.baseURL}${buildSqlEndpointPath(endpoint)}`;
4306
+ let url = `${this.baseURL}${buildSqlEndpointPath(endpoint)}`;
4307
+ if (dbId) {
4308
+ url += `?db_id=${encodeURIComponent(dbId)}`;
4309
+ }
3594
4310
  const response = await this.httpAdapter.request({
3595
4311
  url,
3596
4312
  method: endpoint.method,
@@ -3615,10 +4331,13 @@ class SqlApiClient extends BaseApiClient {
3615
4331
  /**
3616
4332
  * Execute SQL query
3617
4333
  */
3618
- async executeSQL(request) {
4334
+ async executeSQL(request, dbId) {
3619
4335
  try {
3620
4336
  const endpoint = SQL_ENDPOINTS.executeSQL;
3621
- const url = `${this.baseURL}${buildSqlEndpointPath(endpoint)}`;
4337
+ let url = `${this.baseURL}${buildSqlEndpointPath(endpoint)}`;
4338
+ if (dbId) {
4339
+ url += `?db_id=${encodeURIComponent(dbId)}`;
4340
+ }
3622
4341
  const response = await this.httpAdapter.request({
3623
4342
  url,
3624
4343
  method: endpoint.method,
@@ -3675,9 +4394,9 @@ class SqlResource {
3675
4394
  * @returns AsyncIterable<string> for streaming SQL generation
3676
4395
  *
3677
4396
  */
3678
- async textToSQL(prompt, options = {}) {
4397
+ async textToSQL(prompt, options = {}, dbId) {
3679
4398
  const request = transformTextToSQLRequest(prompt, options);
3680
- const response = await this.sqlApiClient.textToSQL(request);
4399
+ const response = await this.sqlApiClient.textToSQL(request, dbId);
3681
4400
  if ("error" in response && response.error !== void 0) {
3682
4401
  throw response;
3683
4402
  }
@@ -3690,8 +4409,8 @@ class SqlResource {
3690
4409
  * @returns Promise<ExecuteSQLApiResponse> with raw API response following Boltic API Response Structure
3691
4410
  *
3692
4411
  */
3693
- async executeSQL(query) {
3694
- const response = await this.sqlApiClient.executeSQL({ query });
4412
+ async executeSQL(query, dbId) {
4413
+ const response = await this.sqlApiClient.executeSQL({ query }, dbId);
3695
4414
  if (isErrorResponse(response)) {
3696
4415
  return response;
3697
4416
  }
@@ -4040,25 +4759,75 @@ class BolticClient {
4040
4759
  this.recordResource = new RecordResource(this.baseClient);
4041
4760
  this.sqlResource = new SqlResource(this.baseClient);
4042
4761
  this.indexResource = new IndexResource(this.baseClient);
4043
- this.currentDatabase = {
4044
- databaseName: "Default"
4045
- };
4762
+ this.databaseResource = new DatabaseResource(this.baseClient);
4763
+ this.currentDatabase = null;
4046
4764
  }
4765
+ /**
4766
+ * Get current database context
4767
+ */
4047
4768
  getCurrentDatabase() {
4048
4769
  return this.currentDatabase;
4049
4770
  }
4771
+ /**
4772
+ * Switch to a different database using its internal name (slug).
4773
+ * All subsequent operations will use this database.
4774
+ *
4775
+ * If no internal name is provided, the SDK will switch back to the default database.
4776
+ *
4777
+ * @param dbInternalName - Database internal name/slug to switch to. If omitted or empty, default DB is used.
4778
+ *
4779
+ * @example
4780
+ * ```typescript
4781
+ * // Switch to a specific database by slug
4782
+ * await client.useDatabase('my_database_slug');
4783
+ *
4784
+ * // Switch back to default database
4785
+ * await client.useDatabase();
4786
+ * ```
4787
+ */
4788
+ async useDatabase(dbInternalName) {
4789
+ if (!dbInternalName || dbInternalName === "") {
4790
+ this.currentDatabase = null;
4791
+ return;
4792
+ }
4793
+ const result = await this.databaseResource.findOne(dbInternalName);
4794
+ if (isErrorResponse(result)) {
4795
+ throw new Error(
4796
+ result.error.message || `Failed to switch database to internal name '${dbInternalName}'`
4797
+ );
4798
+ }
4799
+ const db = result.data;
4800
+ this.currentDatabase = {
4801
+ databaseId: db.id,
4802
+ dbInternalName: db.db_internal_name || dbInternalName
4803
+ };
4804
+ }
4805
+ // Direct database operations
4806
+ get databases() {
4807
+ return {
4808
+ create: (data) => this.databaseResource.create(data),
4809
+ findAll: (options) => this.databaseResource.findAll(options),
4810
+ findOne: (dbInternalName, options) => this.databaseResource.findOne(dbInternalName, options),
4811
+ getDefault: () => this.databaseResource.getDefault(),
4812
+ update: (dbInternalName, data) => this.databaseResource.update(dbInternalName, data),
4813
+ delete: (dbInternalName) => this.databaseResource.delete(dbInternalName),
4814
+ listJobs: (options) => this.databaseResource.listJobs(options),
4815
+ pollDeleteStatus: (jobId) => this.databaseResource.pollDeleteStatus(jobId)
4816
+ };
4817
+ }
4050
4818
  // Direct table operations
4051
4819
  get tables() {
4820
+ const dbId = this.currentDatabase?.databaseId;
4052
4821
  return {
4053
- create: (data) => this.tableResource.create(data),
4054
- findAll: (options) => this.tableResource.findAll(options),
4055
- findById: (id) => this.tableResource.findById(id),
4056
- findByName: (name) => this.tableResource.findByName(name),
4057
- findOne: (options) => this.tableResource.findOne(options),
4058
- update: (name, data) => this.tableResource.update(name, data),
4059
- delete: (name) => this.tableResource.delete(name),
4060
- rename: (oldName, newName) => this.tableResource.rename(oldName, newName),
4061
- setAccess: (request) => this.tableResource.setAccess(request)
4822
+ create: (data) => this.tableResource.create(data, dbId),
4823
+ findAll: (options) => this.tableResource.findAll(options, dbId),
4824
+ findById: (id) => this.tableResource.findById(id, dbId),
4825
+ findByName: (name) => this.tableResource.findByName(name, dbId),
4826
+ findOne: (options) => this.tableResource.findOne(options, dbId),
4827
+ update: (name, data) => this.tableResource.update(name, data, dbId),
4828
+ delete: (name) => this.tableResource.delete(name, dbId),
4829
+ rename: (oldName, newName) => this.tableResource.rename(oldName, newName, dbId),
4830
+ setAccess: (request) => this.tableResource.setAccess(request, dbId)
4062
4831
  };
4063
4832
  }
4064
4833
  // Direct column operations
@@ -4086,53 +4855,40 @@ class BolticClient {
4086
4855
  const tableBuilder = createTableBuilder({ name });
4087
4856
  return tableBuilder;
4088
4857
  }
4089
- // Method 3: Table-scoped operations
4858
+ // Table-scoped operations for method chaining
4090
4859
  from(tableName) {
4860
+ const dbId = this.currentDatabase?.databaseId;
4091
4861
  return {
4092
- // Column operations for this table
4093
- columns: () => ({
4094
- create: (column) => this.columnResource.create(tableName, column),
4095
- findAll: (options) => this.columnResource.findAll(tableName, options),
4096
- get: (columnName) => this.columnResource.get(tableName, columnName),
4097
- update: (columnName, updates) => this.columnResource.update(tableName, columnName, updates),
4098
- delete: (columnName) => this.columnResource.delete(tableName, columnName)
4862
+ // Index operations for this table
4863
+ indexes: () => ({
4864
+ addIndex: (payload) => this.indexResource.addIndex(tableName, payload, dbId),
4865
+ listIndexes: (query) => this.indexResource.listIndexes(tableName, query, dbId),
4866
+ deleteIndex: (indexName) => this.indexResource.deleteIndex(tableName, indexName, dbId)
4099
4867
  }),
4100
4868
  // Record operations for this table
4101
4869
  records: () => ({
4102
- insert: (data) => this.recordResource.insert(tableName, data),
4103
- insertMany: (records, options) => this.recordResource.insertMany(tableName, records, options),
4104
- findOne: (recordId) => this.recordResource.get(tableName, recordId),
4105
- update: (options) => this.recordResource.update(tableName, options),
4106
- updateById: (recordId, data) => this.recordResource.updateById(tableName, recordId, data),
4107
- // Unified delete method
4108
- delete: (options) => this.recordResource.delete(tableName, options),
4109
- // Single record delete method
4110
- deleteById: (recordId) => this.recordResource.deleteById(tableName, recordId)
4111
- }),
4112
- // Fluent record builder for this table
4113
- record: () => createRecordBuilder({
4114
- tableName,
4115
- recordResource: this.recordResource
4116
- }),
4117
- // Indexes - Method 2: Function chaining under from(tableName)
4118
- indexes: () => ({
4119
- addIndex: (payload) => this.indexResource.addIndex(tableName, payload),
4120
- listIndexes: (query) => this.indexResource.listIndexes(tableName, query),
4121
- deleteIndex: (indexName) => this.indexResource.deleteIndex(tableName, indexName)
4870
+ insert: (data) => this.recordResource.insert(tableName, data, dbId),
4871
+ insertMany: (records, options) => this.recordResource.insertMany(tableName, records, options, dbId),
4872
+ findOne: (recordId) => this.recordResource.get(tableName, recordId, dbId),
4873
+ update: (options) => this.recordResource.update(tableName, options, dbId),
4874
+ updateById: (recordId, data) => this.recordResource.updateById(tableName, recordId, data, dbId),
4875
+ delete: (options) => this.recordResource.delete(tableName, options, dbId),
4876
+ deleteById: (recordId) => this.recordResource.deleteById(tableName, recordId, dbId)
4122
4877
  })
4123
4878
  };
4124
4879
  }
4125
4880
  // Direct record operations
4126
4881
  get records() {
4882
+ const dbId = this.currentDatabase?.databaseId;
4127
4883
  return {
4128
- insert: (tableName, data) => this.recordResource.insert(tableName, data),
4129
- insertMany: (tableName, records, options) => this.recordResource.insertMany(tableName, records, options),
4130
- findAll: (tableName, options) => this.recordResource.list(tableName, options),
4131
- findOne: (tableName, recordId) => this.recordResource.get(tableName, recordId),
4132
- update: (tableName, options) => this.recordResource.update(tableName, options),
4133
- updateById: (tableName, recordId, data) => this.recordResource.updateById(tableName, recordId, data),
4134
- delete: (tableName, options) => this.recordResource.delete(tableName, options),
4135
- deleteById: (tableName, recordId) => this.recordResource.deleteById(tableName, recordId)
4884
+ insert: (tableName, data) => this.recordResource.insert(tableName, data, dbId),
4885
+ insertMany: (tableName, records, options) => this.recordResource.insertMany(tableName, records, options, dbId),
4886
+ findAll: (tableName, options) => this.recordResource.list(tableName, options, dbId),
4887
+ findOne: (tableName, recordId) => this.recordResource.get(tableName, recordId, dbId),
4888
+ update: (tableName, options) => this.recordResource.update(tableName, options, dbId),
4889
+ updateById: (tableName, recordId, data) => this.recordResource.updateById(tableName, recordId, data, dbId),
4890
+ delete: (tableName, options) => this.recordResource.delete(tableName, options, dbId),
4891
+ deleteById: (tableName, recordId) => this.recordResource.deleteById(tableName, recordId, dbId)
4136
4892
  };
4137
4893
  }
4138
4894
  // Method 4: Create fluent record builder
@@ -4144,9 +4900,10 @@ class BolticClient {
4144
4900
  }
4145
4901
  // Direct SQL operations
4146
4902
  get sql() {
4903
+ const dbId = this.currentDatabase?.databaseId;
4147
4904
  return {
4148
- textToSQL: (prompt, options) => this.sqlResource.textToSQL(prompt, options),
4149
- executeSQL: (query) => this.sqlResource.executeSQL(query)
4905
+ textToSQL: (prompt, options) => this.sqlResource.textToSQL(prompt, options, dbId),
4906
+ executeSQL: (query) => this.sqlResource.executeSQL(query, dbId)
4150
4907
  };
4151
4908
  }
4152
4909
  // SQL resource access for testing
@@ -4230,6 +4987,7 @@ class BolticClient {
4230
4987
  this.recordResource = new RecordResource(this.baseClient);
4231
4988
  this.sqlResource = new SqlResource(this.baseClient);
4232
4989
  this.indexResource = new IndexResource(this.baseClient);
4990
+ this.databaseResource = new DatabaseResource(this.baseClient);
4233
4991
  }
4234
4992
  // Security methods to prevent API key exposure
4235
4993
  toString() {
@@ -4247,7 +5005,7 @@ class BolticClient {
4247
5005
  };
4248
5006
  }
4249
5007
  // Custom inspect method for Node.js console logging
4250
- [Symbol.for("nodejs.util.inspect.custom")]() {
5008
+ [/* @__PURE__ */ Symbol.for("nodejs.util.inspect.custom")]() {
4251
5009
  return this.toString();
4252
5010
  }
4253
5011
  }