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