@boltic/sdk 0.1.2 → 0.1.4

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,73 @@ let AuthManager$1 = class AuthManager {
111
111
  }
112
112
  }
113
113
  };
114
+ const REGION_CONFIGS = {
115
+ "asia-south1": {
116
+ local: {
117
+ baseURL: "http://localhost:8000",
118
+ timeout: 3e4,
119
+ debug: true
120
+ },
121
+ sit: {
122
+ baseURL: "https://asia-south1.api.fcz0.de/service/sdk/boltic-tables",
123
+ timeout: 15e3
124
+ },
125
+ uat: {
126
+ baseURL: "https://asia-south1.api.uat.fcz0.de/service/sdk/boltic-tables",
127
+ timeout: 15e3
128
+ },
129
+ prod: {
130
+ baseURL: "https://asia-south1.api.boltic.io/service/sdk/boltic-tables",
131
+ timeout: 1e4
132
+ }
133
+ },
134
+ "us-central1": {
135
+ local: {
136
+ baseURL: "http://localhost:8000",
137
+ timeout: 3e4,
138
+ debug: true
139
+ },
140
+ sit: {
141
+ baseURL: "https://us-central1.api.fcz0.de/service/sdk/boltic-tables",
142
+ timeout: 15e3
143
+ },
144
+ uat: {
145
+ baseURL: "https://us-central1.api.uat.fcz0.de/service/sdk/boltic-tables",
146
+ timeout: 15e3
147
+ },
148
+ prod: {
149
+ baseURL: "https://us-central1.api.boltic.io/service/sdk/boltic-tables",
150
+ timeout: 1e4
151
+ }
152
+ }
153
+ };
154
+ const REGION_BASE_HOSTS = {
155
+ "asia-south1": {
156
+ local: { host: "http://localhost:8000", timeout: 3e4, debug: true },
157
+ sit: { host: "https://asia-south1.api.fcz0.de", timeout: 15e3 },
158
+ uat: { host: "https://asia-south1.api.uat.fcz0.de", timeout: 15e3 },
159
+ prod: { host: "https://asia-south1.api.boltic.io", timeout: 1e4 }
160
+ },
161
+ "us-central1": {
162
+ local: { host: "http://localhost:8000", timeout: 3e4, debug: true },
163
+ sit: { host: "https://us-central1.api.fcz0.de", timeout: 15e3 },
164
+ uat: { host: "https://us-central1.api.uat.fcz0.de", timeout: 15e3 },
165
+ prod: { host: "https://us-central1.api.boltic.io", timeout: 1e4 }
166
+ }
167
+ };
168
+ function resolveServiceURL(region, environment, servicePath) {
169
+ const regionConfig = REGION_BASE_HOSTS[region];
170
+ if (!regionConfig) {
171
+ throw new Error(`Unsupported region: ${region}`);
172
+ }
173
+ const envConfig = regionConfig[environment];
174
+ if (!envConfig) {
175
+ throw new Error(
176
+ `Unsupported environment: ${environment} for region: ${region}`
177
+ );
178
+ }
179
+ return `${envConfig.host}${servicePath}`;
180
+ }
114
181
  function isErrorResponse(response) {
115
182
  return "error" in response && response.error !== void 0;
116
183
  }
@@ -169,77 +236,6 @@ Context: ${JSON.stringify(context, null, 2)}`;
169
236
  }
170
237
  return String(error);
171
238
  }
172
- class AuthManager2 {
173
- constructor(config) {
174
- this.tokenInfo = null;
175
- this.config = {
176
- maxRetries: 3,
177
- ...config
178
- };
179
- this.validateApiKey(config.apiKey);
180
- }
181
- validateApiKey(apiKey) {
182
- if (!apiKey || typeof apiKey !== "string" || apiKey.trim().length === 0) {
183
- throw createErrorWithContext(
184
- "API key is required and must be a non-empty string",
185
- {
186
- name: "AuthenticationError",
187
- code: "INVALID_API_KEY"
188
- }
189
- );
190
- }
191
- if (apiKey.length < 10) {
192
- throw createErrorWithContext(
193
- "API key appears to be invalid (too short)",
194
- {
195
- name: "AuthenticationError",
196
- code: "INVALID_API_KEY_FORMAT"
197
- }
198
- );
199
- }
200
- }
201
- getAuthHeaders() {
202
- return {
203
- "x-boltic-token": this.config.apiKey
204
- };
205
- }
206
- updateApiKey(newApiKey) {
207
- this.validateApiKey(newApiKey);
208
- this.config.apiKey = newApiKey;
209
- this.tokenInfo = null;
210
- }
211
- isAuthenticated() {
212
- return !!this.config.apiKey;
213
- }
214
- async validateApiKeyAsync() {
215
- try {
216
- this.validateApiKey(this.config.apiKey);
217
- return true;
218
- } catch {
219
- return false;
220
- }
221
- }
222
- getTokenInfo() {
223
- return this.tokenInfo ? { ...this.tokenInfo } : null;
224
- }
225
- getMaxRetries() {
226
- return this.config.maxRetries || 3;
227
- }
228
- // Security methods to prevent API key exposure
229
- toString() {
230
- return `AuthManager { authenticated: ${this.isAuthenticated()}, maxRetries: ${this.getMaxRetries()} }`;
231
- }
232
- toJSON() {
233
- return {
234
- authenticated: this.isAuthenticated(),
235
- maxRetries: this.getMaxRetries()
236
- };
237
- }
238
- // Custom inspect method for Node.js console logging
239
- [/* @__PURE__ */ Symbol.for("nodejs.util.inspect.custom")]() {
240
- return this.toString();
241
- }
242
- }
243
239
  class AxiosAdapter {
244
240
  constructor() {
245
241
  try {
@@ -262,7 +258,6 @@ class AxiosAdapter {
262
258
  timeout: config.timeout,
263
259
  signal: config.signal,
264
260
  validateStatus: () => true
265
- // Don't throw on non-2xx status codes
266
261
  };
267
262
  const response = await this.axios(axiosConfig);
268
263
  if (response.status < 200 || response.status >= 300) {
@@ -482,6 +477,157 @@ function createHttpAdapter() {
482
477
  );
483
478
  }
484
479
  }
480
+ class AuthManager2 {
481
+ constructor(config) {
482
+ this.tokenInfo = null;
483
+ this.config = {
484
+ maxRetries: 3,
485
+ ...config
486
+ };
487
+ this.validateApiKey(config.apiKey);
488
+ }
489
+ validateApiKey(apiKey) {
490
+ if (!apiKey || typeof apiKey !== "string" || apiKey.trim().length === 0) {
491
+ throw createErrorWithContext(
492
+ "API key is required and must be a non-empty string",
493
+ {
494
+ name: "AuthenticationError",
495
+ code: "INVALID_API_KEY"
496
+ }
497
+ );
498
+ }
499
+ if (apiKey.length < 10) {
500
+ throw createErrorWithContext(
501
+ "API key appears to be invalid (too short)",
502
+ {
503
+ name: "AuthenticationError",
504
+ code: "INVALID_API_KEY_FORMAT"
505
+ }
506
+ );
507
+ }
508
+ }
509
+ getAuthHeaders() {
510
+ return {
511
+ "x-boltic-token": this.config.apiKey
512
+ };
513
+ }
514
+ updateApiKey(newApiKey) {
515
+ this.validateApiKey(newApiKey);
516
+ this.config.apiKey = newApiKey;
517
+ this.tokenInfo = null;
518
+ }
519
+ isAuthenticated() {
520
+ return !!this.config.apiKey;
521
+ }
522
+ async validateApiKeyAsync() {
523
+ try {
524
+ this.validateApiKey(this.config.apiKey);
525
+ return true;
526
+ } catch {
527
+ return false;
528
+ }
529
+ }
530
+ getTokenInfo() {
531
+ return this.tokenInfo ? { ...this.tokenInfo } : null;
532
+ }
533
+ getMaxRetries() {
534
+ return this.config.maxRetries || 3;
535
+ }
536
+ toString() {
537
+ return `AuthManager { authenticated: ${this.isAuthenticated()}, maxRetries: ${this.getMaxRetries()} }`;
538
+ }
539
+ toJSON() {
540
+ return {
541
+ authenticated: this.isAuthenticated(),
542
+ maxRetries: this.getMaxRetries()
543
+ };
544
+ }
545
+ [/* @__PURE__ */ Symbol.for("nodejs.util.inspect.custom")]() {
546
+ return this.toString();
547
+ }
548
+ }
549
+ const SERVICE_PATHS = {
550
+ DATABASES: "/service/sdk/boltic-tables/v1",
551
+ WORKFLOW_TEMPORAL: "/service/panel/temporal/v1.0",
552
+ INTEGRATION: "/service/panel/integration/v1",
553
+ SERVERLESS: "/service/panel/serverless/v1.0"
554
+ };
555
+ class BaseApiClient {
556
+ constructor(apiKey, config = {}, servicePath = SERVICE_PATHS.DATABASES) {
557
+ this.config = { apiKey, ...config };
558
+ this.httpAdapter = createHttpAdapter();
559
+ this.environment = config.environment || "prod";
560
+ this.region = config.region || "asia-south1";
561
+ this.baseURL = resolveServiceURL(
562
+ this.region,
563
+ this.environment,
564
+ servicePath
565
+ );
566
+ }
567
+ /**
568
+ * Resolve a secondary service URL using the same region/environment
569
+ * but a different service path.
570
+ */
571
+ resolveAdditionalServiceURL(servicePath) {
572
+ return resolveServiceURL(this.region, this.environment, servicePath);
573
+ }
574
+ buildHeaders() {
575
+ return {
576
+ "Content-Type": "application/json",
577
+ Accept: "application/json",
578
+ "x-boltic-token": this.config.apiKey,
579
+ ...this.config.headers
580
+ };
581
+ }
582
+ formatErrorResponse(error, prefix = "API") {
583
+ if (this.config.debug) {
584
+ console.error(`[${this.constructor.name}] ${prefix} Error:`, error);
585
+ }
586
+ if (error && typeof error === "object" && "response" in error) {
587
+ const apiError = error;
588
+ if (apiError.response?.data?.error) {
589
+ return apiError.response.data;
590
+ }
591
+ return {
592
+ error: {
593
+ code: `${prefix}_ERROR`,
594
+ message: error instanceof Error ? error.message : `Unknown ${prefix} error`,
595
+ meta: [`Status: ${apiError.response?.status || "unknown"}`]
596
+ }
597
+ };
598
+ }
599
+ if (error instanceof Error) {
600
+ return {
601
+ error: {
602
+ code: `${prefix}_CLIENT_ERROR`,
603
+ message: error.message,
604
+ meta: []
605
+ }
606
+ };
607
+ }
608
+ return {
609
+ error: {
610
+ code: `${prefix}_UNKNOWN_ERROR`,
611
+ message: `An unexpected ${prefix} error occurred`,
612
+ meta: []
613
+ }
614
+ };
615
+ }
616
+ toString() {
617
+ return `${this.constructor.name} { environment: "${this.config.environment || "prod"}", debug: ${this.config.debug || false} }`;
618
+ }
619
+ toJSON() {
620
+ const safeConfig = { ...this.config };
621
+ delete safeConfig.apiKey;
622
+ return {
623
+ client: this.constructor.name,
624
+ config: safeConfig
625
+ };
626
+ }
627
+ [/* @__PURE__ */ Symbol.for("nodejs.util.inspect.custom")]() {
628
+ return this.toString();
629
+ }
630
+ }
485
631
  class InterceptorManagerImpl {
486
632
  constructor() {
487
633
  this.requestInterceptors = /* @__PURE__ */ new Map();
@@ -666,46 +812,88 @@ class BaseClient {
666
812
  return { ...this.config };
667
813
  }
668
814
  }
669
- const REGION_CONFIGS = {
670
- "asia-south1": {
671
- local: {
672
- baseURL: "http://localhost:8000",
673
- timeout: 3e4,
674
- debug: true
675
- },
676
- sit: {
677
- baseURL: "https://asia-south1.api.fcz0.de/service/sdk/boltic-tables",
678
- timeout: 15e3
679
- },
680
- uat: {
681
- baseURL: "https://asia-south1.api.uat.fcz0.de/service/sdk/boltic-tables",
682
- timeout: 15e3
683
- },
684
- prod: {
685
- baseURL: "https://asia-south1.api.boltic.io/service/sdk/boltic-tables",
686
- timeout: 1e4
815
+ class BaseResource {
816
+ constructor(client, basePath) {
817
+ this.client = client;
818
+ this.basePath = basePath;
819
+ }
820
+ getBasePath() {
821
+ return this.basePath;
822
+ }
823
+ async makeRequest(method, path, data, options) {
824
+ const url = `${this.basePath}${path}`;
825
+ try {
826
+ let response;
827
+ switch (method) {
828
+ case "GET":
829
+ response = await this.client.get(url, {
830
+ params: options?.params
831
+ });
832
+ break;
833
+ case "POST":
834
+ response = await this.client.post(url, data, {
835
+ params: options?.params
836
+ });
837
+ break;
838
+ case "PUT":
839
+ response = await this.client.put(url, data, {
840
+ params: options?.params
841
+ });
842
+ break;
843
+ case "PATCH":
844
+ response = await this.client.patch(url, data, {
845
+ params: options?.params
846
+ });
847
+ break;
848
+ case "DELETE":
849
+ response = await this.client.delete(url, {
850
+ params: options?.params
851
+ });
852
+ break;
853
+ }
854
+ return response.data;
855
+ } catch (error) {
856
+ return {
857
+ error: {
858
+ code: "CLIENT_ERROR",
859
+ message: formatError(error),
860
+ meta: ["Request failed"]
861
+ }
862
+ };
687
863
  }
688
- },
689
- "us-central1": {
690
- local: {
691
- baseURL: "http://localhost:8000",
692
- timeout: 3e4,
693
- debug: true
694
- },
695
- sit: {
696
- baseURL: "https://us-central1.api.fcz0.de/service/sdk/boltic-tables",
697
- timeout: 15e3
698
- },
699
- uat: {
700
- baseURL: "https://us-central1.api.uat.fcz0.de/service/sdk/boltic-tables",
701
- timeout: 15e3
702
- },
703
- prod: {
704
- baseURL: "https://us-central1.api.boltic.io/service/sdk/boltic-tables",
705
- timeout: 1e4
864
+ }
865
+ buildQueryParams(options = {}) {
866
+ const params = {};
867
+ if (options.fields?.length) {
868
+ params.fields = options.fields.join(",");
869
+ }
870
+ if (options.sort?.length) {
871
+ params.sort = options.sort.map((s) => `${s.field}:${s.order}`).join(",");
872
+ }
873
+ if (options.limit !== void 0) {
874
+ params.limit = options.limit;
875
+ }
876
+ if (options.offset !== void 0) {
877
+ params.offset = options.offset;
878
+ }
879
+ if (options.where) {
880
+ Object.entries(options.where).forEach(([key, value]) => {
881
+ if (value !== void 0 && value !== null) {
882
+ params[`where[${key}]`] = typeof value === "object" ? JSON.stringify(value) : value;
883
+ }
884
+ });
706
885
  }
886
+ return params;
707
887
  }
708
- };
888
+ handleResponse(response) {
889
+ if ("error" in response) {
890
+ if (this.client.getConfig().debug) {
891
+ console.error("API Error:", response.error);
892
+ }
893
+ }
894
+ return response;
895
+ }
896
+ }
709
897
  class ConfigManager {
710
898
  constructor(apiKey, environment = "prod", region = "asia-south1", overrides) {
711
899
  const envConfig = REGION_CONFIGS[region][environment];
@@ -728,7 +916,6 @@ class ConfigManager {
728
916
  updateConfig(updates) {
729
917
  this.config = { ...this.config, ...updates };
730
918
  }
731
- // Security methods to prevent API key exposure
732
919
  toString() {
733
920
  return `ConfigManager { environment: "${this.config.environment}", region: "${this.config.region}", debug: ${this.config.debug} }`;
734
921
  }
@@ -737,7 +924,6 @@ class ConfigManager {
737
924
  delete safeConfig.apiKey;
738
925
  return safeConfig;
739
926
  }
740
- // Custom inspect method for Node.js console logging
741
927
  [/* @__PURE__ */ Symbol.for("nodejs.util.inspect.custom")]() {
742
928
  return this.toString();
743
929
  }
@@ -924,26 +1110,9 @@ function transformDateFormat(dateFormat) {
924
1110
  function transformTimeFormat(timeFormat) {
925
1111
  return TimeFormatEnum[timeFormat] || timeFormat;
926
1112
  }
927
- class ColumnsApiClient {
1113
+ class ColumnsApiClient extends BaseApiClient {
928
1114
  constructor(apiKey, config = {}) {
929
- this.config = { apiKey, ...config };
930
- this.httpAdapter = createHttpAdapter();
931
- const environment = config.environment || "prod";
932
- const region = config.region || "asia-south1";
933
- this.baseURL = this.getBaseURL(environment, region);
934
- }
935
- getBaseURL(environment, region) {
936
- const regionConfig = REGION_CONFIGS[region];
937
- if (!regionConfig) {
938
- throw new Error(`Unsupported region: ${region}`);
939
- }
940
- const envConfig = regionConfig[environment];
941
- if (!envConfig) {
942
- throw new Error(
943
- `Unsupported environment: ${environment} for region: ${region}`
944
- );
945
- }
946
- return `${envConfig.baseURL}/v1`;
1115
+ super(apiKey, config);
947
1116
  }
948
1117
  /**
949
1118
  * Create a single column in a table
@@ -980,7 +1149,7 @@ class ColumnsApiClient {
980
1149
  const createdColumns = [];
981
1150
  for (const column of columns) {
982
1151
  const result = await this.createColumn(tableId, column);
983
- if ("error" in result) {
1152
+ if (isErrorResponse(result)) {
984
1153
  return result;
985
1154
  }
986
1155
  createdColumns.push(result.data);
@@ -1132,7 +1301,7 @@ class ColumnsApiClient {
1132
1301
  tableId,
1133
1302
  apiRequest
1134
1303
  );
1135
- if ("error" in listResult) {
1304
+ if (isErrorResponse(listResult)) {
1136
1305
  return listResult;
1137
1306
  }
1138
1307
  const column = listResult.data[0] || null;
@@ -1179,7 +1348,7 @@ class ColumnsApiClient {
1179
1348
  async updateColumnByName(tableId, columnName, updates) {
1180
1349
  try {
1181
1350
  const findResult = await this.findColumnByName(tableId, columnName);
1182
- if ("error" in findResult) {
1351
+ if (isErrorResponse(findResult)) {
1183
1352
  return findResult;
1184
1353
  }
1185
1354
  if (!findResult.data) {
@@ -1213,7 +1382,7 @@ class ColumnsApiClient {
1213
1382
  async deleteColumnByName(tableId, columnName) {
1214
1383
  try {
1215
1384
  const findResult = await this.findColumnByName(tableId, columnName);
1216
- if ("error" in findResult) {
1385
+ if (isErrorResponse(findResult)) {
1217
1386
  return findResult;
1218
1387
  }
1219
1388
  if (!findResult.data) {
@@ -1230,47 +1399,6 @@ class ColumnsApiClient {
1230
1399
  return this.formatErrorResponse(error);
1231
1400
  }
1232
1401
  }
1233
- buildHeaders() {
1234
- return {
1235
- "Content-Type": "application/json",
1236
- Accept: "application/json",
1237
- "x-boltic-token": this.config.apiKey
1238
- };
1239
- }
1240
- formatErrorResponse(error) {
1241
- if (this.config.debug) {
1242
- console.error("Columns API Error:", error);
1243
- }
1244
- if (error && typeof error === "object" && "response" in error) {
1245
- const apiError = error;
1246
- if (apiError.response?.data?.error) {
1247
- return apiError.response.data;
1248
- }
1249
- return {
1250
- error: {
1251
- code: "API_ERROR",
1252
- message: error.message || "Unknown API error",
1253
- meta: [`Status: ${apiError.response?.status || "unknown"}`]
1254
- }
1255
- };
1256
- }
1257
- if (error && typeof error === "object" && "message" in error) {
1258
- return {
1259
- error: {
1260
- code: "CLIENT_ERROR",
1261
- message: error.message,
1262
- meta: ["Client-side error occurred"]
1263
- }
1264
- };
1265
- }
1266
- return {
1267
- error: {
1268
- code: "UNKNOWN_ERROR",
1269
- message: "An unexpected error occurred",
1270
- meta: ["Unknown error type"]
1271
- }
1272
- };
1273
- }
1274
1402
  }
1275
1403
  const TABLE_ENDPOINTS = {
1276
1404
  list: {
@@ -1449,26 +1577,9 @@ function transformFieldDefinition(field) {
1449
1577
  default_value: field.default_value
1450
1578
  };
1451
1579
  }
1452
- class TablesApiClient {
1580
+ class TablesApiClient extends BaseApiClient {
1453
1581
  constructor(apiKey, config = {}) {
1454
- this.config = { apiKey, ...config };
1455
- this.httpAdapter = createHttpAdapter();
1456
- const environment = config.environment || "prod";
1457
- const region = config.region || "asia-south1";
1458
- this.baseURL = this.getBaseURL(environment, region);
1459
- }
1460
- getBaseURL(environment, region) {
1461
- const regionConfig = REGION_CONFIGS[region];
1462
- if (!regionConfig) {
1463
- throw new Error(`Unsupported region: ${region}`);
1464
- }
1465
- const envConfig = regionConfig[environment];
1466
- if (!envConfig) {
1467
- throw new Error(
1468
- `Unsupported environment: ${environment} for region: ${region}`
1469
- );
1470
- }
1471
- return `${envConfig.baseURL}/v1`;
1582
+ super(apiKey, config);
1472
1583
  }
1473
1584
  /**
1474
1585
  * Create a new table
@@ -1591,200 +1702,75 @@ class TablesApiClient {
1591
1702
  return this.formatErrorResponse(error);
1592
1703
  }
1593
1704
  }
1594
- // Private helper methods
1595
- buildHeaders() {
1596
- return {
1597
- "Content-Type": "application/json",
1598
- Accept: "application/json",
1599
- "x-boltic-token": this.config.apiKey
1600
- };
1705
+ }
1706
+ class TableResource extends BaseResource {
1707
+ constructor(client) {
1708
+ super(client, "/v1/tables");
1709
+ const config = client.getConfig();
1710
+ this.tablesApiClient = new TablesApiClient(config.apiKey, {
1711
+ environment: config.environment,
1712
+ region: config.region,
1713
+ timeout: config.timeout,
1714
+ debug: config.debug,
1715
+ retryAttempts: config.retryAttempts,
1716
+ retryDelay: config.retryDelay,
1717
+ headers: config.headers
1718
+ });
1601
1719
  }
1602
- formatErrorResponse(error) {
1603
- if (this.config.debug) {
1604
- console.error("Tables API Error:", error);
1720
+ /**
1721
+ * Create a new table
1722
+ */
1723
+ async create(data, dbId) {
1724
+ try {
1725
+ const processedData = { ...data };
1726
+ if (data.fields && data.fields.length > 0) {
1727
+ processedData.fields = await this.processFieldsDefaults(data.fields);
1728
+ }
1729
+ const result = await this.tablesApiClient.createTable(
1730
+ processedData,
1731
+ dbId ? { db_id: dbId } : {}
1732
+ );
1733
+ if (isErrorResponse(result)) {
1734
+ throw new ApiError(
1735
+ result.error.message || "Create table failed",
1736
+ 400,
1737
+ result.error
1738
+ );
1739
+ }
1740
+ return result;
1741
+ } catch (error) {
1742
+ throw error instanceof ApiError ? error : new ApiError(this.formatError(error), 500);
1605
1743
  }
1606
- if (error && typeof error === "object" && "response" in error) {
1607
- const apiError = error;
1608
- if (apiError.response?.data?.error) {
1609
- return apiError.response.data;
1744
+ }
1745
+ /**
1746
+ * Process fields with defaults for table creation
1747
+ */
1748
+ async processFieldsDefaults(fields) {
1749
+ const processedFields = [];
1750
+ for (let i = 0; i < fields.length; i++) {
1751
+ const field = fields[i];
1752
+ const processedField = { ...field };
1753
+ if (processedField.is_primary_key === void 0) {
1754
+ processedField.is_primary_key = false;
1610
1755
  }
1611
- return {
1612
- error: {
1613
- code: "API_ERROR",
1614
- message: error.message || "Unknown API error",
1615
- meta: [`Status: ${apiError.response?.status || "unknown"}`]
1756
+ if (processedField.is_unique === void 0) {
1757
+ processedField.is_unique = false;
1758
+ }
1759
+ if (processedField.is_nullable === void 0) {
1760
+ processedField.is_nullable = true;
1761
+ }
1762
+ if (processedField.is_indexed === void 0) {
1763
+ processedField.is_indexed = false;
1764
+ }
1765
+ if (processedField.type === "encrypted") {
1766
+ if (processedField.show_decrypted === void 0) {
1767
+ processedField.show_decrypted = false;
1616
1768
  }
1617
- };
1618
- }
1619
- if (error && typeof error === "object" && "message" in error) {
1620
- return {
1621
- error: {
1622
- code: "CLIENT_ERROR",
1623
- message: error.message,
1624
- meta: ["Client-side error occurred"]
1625
- }
1626
- };
1627
- }
1628
- return {
1629
- error: {
1630
- code: "UNKNOWN_ERROR",
1631
- message: "An unexpected error occurred",
1632
- meta: ["Unknown error type"]
1633
- }
1634
- };
1635
- }
1636
- }
1637
- class BaseResource {
1638
- constructor(client, basePath) {
1639
- this.client = client;
1640
- this.basePath = basePath;
1641
- }
1642
- // Public getter for basePath
1643
- getBasePath() {
1644
- return this.basePath;
1645
- }
1646
- async makeRequest(method, path, data, options) {
1647
- const url = `${this.basePath}${path}`;
1648
- try {
1649
- let response;
1650
- switch (method) {
1651
- case "GET":
1652
- response = await this.client.get(url, {
1653
- params: options?.params
1654
- });
1655
- break;
1656
- case "POST":
1657
- response = await this.client.post(url, data, {
1658
- params: options?.params
1659
- });
1660
- break;
1661
- case "PUT":
1662
- response = await this.client.put(url, data, {
1663
- params: options?.params
1664
- });
1665
- break;
1666
- case "PATCH":
1667
- response = await this.client.patch(url, data, {
1668
- params: options?.params
1669
- });
1670
- break;
1671
- case "DELETE":
1672
- response = await this.client.delete(url, {
1673
- params: options?.params
1674
- });
1675
- break;
1676
- }
1677
- return response.data;
1678
- } catch (error) {
1679
- return {
1680
- error: {
1681
- code: "CLIENT_ERROR",
1682
- message: formatError(error),
1683
- meta: ["Request failed"]
1684
- }
1685
- };
1686
- }
1687
- }
1688
- buildQueryParams(options = {}) {
1689
- const params = {};
1690
- if (options.fields?.length) {
1691
- params.fields = options.fields.join(",");
1692
- }
1693
- if (options.sort?.length) {
1694
- params.sort = options.sort.map((s) => `${s.field}:${s.order}`).join(",");
1695
- }
1696
- if (options.limit !== void 0) {
1697
- params.limit = options.limit;
1698
- }
1699
- if (options.offset !== void 0) {
1700
- params.offset = options.offset;
1701
- }
1702
- if (options.where) {
1703
- Object.entries(options.where).forEach(([key, value]) => {
1704
- if (value !== void 0 && value !== null) {
1705
- params[`where[${key}]`] = typeof value === "object" ? JSON.stringify(value) : value;
1706
- }
1707
- });
1708
- }
1709
- return params;
1710
- }
1711
- handleResponse(response) {
1712
- if ("error" in response) {
1713
- if (this.client.getConfig().debug) {
1714
- console.error("API Error:", response.error);
1715
- }
1716
- }
1717
- return response;
1718
- }
1719
- }
1720
- class TableResource extends BaseResource {
1721
- constructor(client) {
1722
- super(client, "/v1/tables");
1723
- const config = client.getConfig();
1724
- this.tablesApiClient = new TablesApiClient(config.apiKey, {
1725
- environment: config.environment,
1726
- region: config.region,
1727
- timeout: config.timeout,
1728
- debug: config.debug,
1729
- retryAttempts: config.retryAttempts,
1730
- retryDelay: config.retryDelay,
1731
- headers: config.headers
1732
- });
1733
- }
1734
- /**
1735
- * Create a new table
1736
- */
1737
- async create(data, dbId) {
1738
- try {
1739
- const processedData = { ...data };
1740
- if (data.fields && data.fields.length > 0) {
1741
- processedData.fields = await this.processFieldsDefaults(data.fields);
1742
- }
1743
- const result = await this.tablesApiClient.createTable(
1744
- processedData,
1745
- dbId ? { db_id: dbId } : {}
1746
- );
1747
- if (isErrorResponse(result)) {
1748
- throw new ApiError(
1749
- result.error.message || "Create table failed",
1750
- 400,
1751
- result.error
1752
- );
1753
- }
1754
- return result;
1755
- } catch (error) {
1756
- throw error instanceof ApiError ? error : new ApiError(this.formatError(error), 500);
1757
- }
1758
- }
1759
- /**
1760
- * Process fields with defaults for table creation
1761
- */
1762
- async processFieldsDefaults(fields) {
1763
- const processedFields = [];
1764
- for (let i = 0; i < fields.length; i++) {
1765
- const field = fields[i];
1766
- const processedField = { ...field };
1767
- if (processedField.is_primary_key === void 0) {
1768
- processedField.is_primary_key = false;
1769
- }
1770
- if (processedField.is_unique === void 0) {
1771
- processedField.is_unique = false;
1772
- }
1773
- if (processedField.is_nullable === void 0) {
1774
- processedField.is_nullable = true;
1775
- }
1776
- if (processedField.is_indexed === void 0) {
1777
- processedField.is_indexed = false;
1778
- }
1779
- if (processedField.type === "encrypted") {
1780
- if (processedField.show_decrypted === void 0) {
1781
- processedField.show_decrypted = false;
1782
- }
1783
- if (processedField.is_deterministic === void 0) {
1784
- processedField.is_deterministic = false;
1785
- }
1786
- if (processedField.default_value !== void 0 && processedField.default_value !== null) {
1787
- throw new Error("Encrypted columns do not accept a default value");
1769
+ if (processedField.is_deterministic === void 0) {
1770
+ processedField.is_deterministic = false;
1771
+ }
1772
+ if (processedField.default_value !== void 0 && processedField.default_value !== null) {
1773
+ throw new Error("Encrypted columns do not accept a default value");
1788
1774
  }
1789
1775
  }
1790
1776
  if (processedField.field_order === void 0) {
@@ -2466,26 +2452,9 @@ const buildDatabaseEndpointPath = (endpoint, params = {}) => {
2466
2452
  });
2467
2453
  return path;
2468
2454
  };
2469
- class DatabasesApiClient {
2455
+ class DatabasesApiClient extends BaseApiClient {
2470
2456
  constructor(apiKey, config = {}) {
2471
- this.config = { apiKey, ...config };
2472
- this.httpAdapter = createHttpAdapter();
2473
- const environment = config.environment || "prod";
2474
- const region = config.region || "asia-south1";
2475
- this.baseURL = this.getBaseURL(environment, region);
2476
- }
2477
- getBaseURL(environment, region) {
2478
- const regionConfig = REGION_CONFIGS[region];
2479
- if (!regionConfig) {
2480
- throw new Error(`Unsupported region: ${region}`);
2481
- }
2482
- const envConfig = regionConfig[environment];
2483
- if (!envConfig) {
2484
- throw new Error(
2485
- `Unsupported environment: ${environment} for region: ${region}`
2486
- );
2487
- }
2488
- return `${envConfig.baseURL}/v1`;
2457
+ super(apiKey, config);
2489
2458
  }
2490
2459
  /**
2491
2460
  * Create a new database
@@ -2497,16 +2466,13 @@ class DatabasesApiClient {
2497
2466
  const response = await this.httpAdapter.request({
2498
2467
  url,
2499
2468
  method: endpoint.method,
2500
- headers: {
2501
- "Content-Type": "application/json",
2502
- "x-boltic-token": this.config.apiKey
2503
- },
2469
+ headers: this.buildHeaders(),
2504
2470
  data: request,
2505
2471
  timeout: this.config.timeout
2506
2472
  });
2507
2473
  return response.data;
2508
2474
  } catch (error) {
2509
- return this.handleError(error);
2475
+ return this.formatErrorResponse(error);
2510
2476
  }
2511
2477
  }
2512
2478
  /**
@@ -2532,10 +2498,7 @@ class DatabasesApiClient {
2532
2498
  const response = await this.httpAdapter.request({
2533
2499
  url,
2534
2500
  method: endpoint.method,
2535
- headers: {
2536
- "Content-Type": "application/json",
2537
- "x-boltic-token": this.config.apiKey
2538
- },
2501
+ headers: this.buildHeaders(),
2539
2502
  data: request,
2540
2503
  timeout: this.config.timeout
2541
2504
  });
@@ -2551,7 +2514,7 @@ class DatabasesApiClient {
2551
2514
  }
2552
2515
  return result;
2553
2516
  } catch (error) {
2554
- return this.handleError(error);
2517
+ return this.formatErrorResponse(error);
2555
2518
  }
2556
2519
  }
2557
2520
  /**
@@ -2565,16 +2528,13 @@ class DatabasesApiClient {
2565
2528
  const response = await this.httpAdapter.request({
2566
2529
  url,
2567
2530
  method: endpoint.method,
2568
- headers: {
2569
- "Content-Type": "application/json",
2570
- "x-boltic-token": this.config.apiKey
2571
- },
2531
+ headers: this.buildHeaders(),
2572
2532
  data: request,
2573
2533
  timeout: this.config.timeout
2574
2534
  });
2575
2535
  return response.data;
2576
2536
  } catch (error) {
2577
- return this.handleError(error);
2537
+ return this.formatErrorResponse(error);
2578
2538
  }
2579
2539
  }
2580
2540
  /**
@@ -2588,15 +2548,12 @@ class DatabasesApiClient {
2588
2548
  const response = await this.httpAdapter.request({
2589
2549
  url,
2590
2550
  method: endpoint.method,
2591
- headers: {
2592
- "Content-Type": "application/json",
2593
- "x-boltic-token": this.config.apiKey
2594
- },
2551
+ headers: this.buildHeaders(),
2595
2552
  timeout: this.config.timeout
2596
2553
  });
2597
2554
  return response.data;
2598
2555
  } catch (error) {
2599
- return this.handleError(error);
2556
+ return this.formatErrorResponse(error);
2600
2557
  }
2601
2558
  }
2602
2559
  /**
@@ -2609,10 +2566,7 @@ class DatabasesApiClient {
2609
2566
  const response = await this.httpAdapter.request({
2610
2567
  url,
2611
2568
  method: endpoint.method,
2612
- headers: {
2613
- "Content-Type": "application/json",
2614
- "x-boltic-token": this.config.apiKey
2615
- },
2569
+ headers: this.buildHeaders(),
2616
2570
  data: request,
2617
2571
  timeout: this.config.timeout
2618
2572
  });
@@ -2628,7 +2582,7 @@ class DatabasesApiClient {
2628
2582
  }
2629
2583
  return result;
2630
2584
  } catch (error) {
2631
- return this.handleError(error);
2585
+ return this.formatErrorResponse(error);
2632
2586
  }
2633
2587
  }
2634
2588
  /**
@@ -2642,70 +2596,13 @@ class DatabasesApiClient {
2642
2596
  const response = await this.httpAdapter.request({
2643
2597
  url,
2644
2598
  method: endpoint.method,
2645
- headers: {
2646
- "Content-Type": "application/json",
2647
- "x-boltic-token": this.config.apiKey
2648
- },
2599
+ headers: this.buildHeaders(),
2649
2600
  timeout: this.config.timeout
2650
2601
  });
2651
2602
  return response.data;
2652
2603
  } catch (error) {
2653
- return this.handleError(error);
2654
- }
2655
- }
2656
- /**
2657
- * Handle API errors and convert to standard error format
2658
- */
2659
- handleError(error) {
2660
- if (this.config.debug) {
2661
- console.error("[DatabasesApiClient] Error:", error);
2662
- }
2663
- const hasErrorProperty = (err) => {
2664
- return typeof err === "object" && err !== null && "error" in err && typeof err.error === "object" && err.error !== null;
2665
- };
2666
- const hasResponseError = (err) => {
2667
- 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;
2668
- };
2669
- const isStandardError = (err) => {
2670
- return err instanceof Error;
2671
- };
2672
- if (hasErrorProperty(error)) {
2673
- const errorWithError = error;
2674
- return {
2675
- error: {
2676
- code: typeof errorWithError.error.code === "number" ? String(errorWithError.error.code) : errorWithError.error.code || "UNKNOWN_ERROR",
2677
- message: errorWithError.error.message || "An error occurred",
2678
- meta: errorWithError.error.meta || []
2679
- }
2680
- };
2681
- }
2682
- if (hasResponseError(error)) {
2683
- const errorWithResponse = error;
2684
- return {
2685
- error: {
2686
- code: typeof errorWithResponse.response.data.error.code === "number" ? String(errorWithResponse.response.data.error.code) : errorWithResponse.response.data.error.code || "UNKNOWN_ERROR",
2687
- message: errorWithResponse.response.data.error.message || "An error occurred",
2688
- meta: errorWithResponse.response.data.error.meta || []
2689
- }
2690
- };
2691
- }
2692
- if (isStandardError(error)) {
2693
- const standardError = error;
2694
- return {
2695
- error: {
2696
- code: standardError.code || "UNKNOWN_ERROR",
2697
- message: standardError.message || "An unexpected error occurred",
2698
- meta: []
2699
- }
2700
- };
2604
+ return this.formatErrorResponse(error);
2701
2605
  }
2702
- return {
2703
- error: {
2704
- code: "UNKNOWN_ERROR",
2705
- message: "An unexpected error occurred",
2706
- meta: []
2707
- }
2708
- };
2709
2606
  }
2710
2607
  }
2711
2608
  class DatabaseResource extends BaseResource {
@@ -2735,7 +2632,7 @@ class DatabaseResource extends BaseResource {
2735
2632
  */
2736
2633
  async create(request) {
2737
2634
  const result = await this.apiClient.createDatabase(request);
2738
- if ("error" in result) {
2635
+ if (isErrorResponse(result)) {
2739
2636
  return {
2740
2637
  error: {
2741
2638
  code: typeof result.error.code === "number" ? String(result.error.code) : result.error.code,
@@ -2802,7 +2699,7 @@ class DatabaseResource extends BaseResource {
2802
2699
  queryParams,
2803
2700
  options
2804
2701
  );
2805
- if ("error" in result) {
2702
+ if (isErrorResponse(result)) {
2806
2703
  return {
2807
2704
  error: {
2808
2705
  code: typeof result.error.code === "number" ? String(result.error.code) : result.error.code,
@@ -2930,7 +2827,7 @@ class DatabaseResource extends BaseResource {
2930
2827
  db_name: request.db_name
2931
2828
  };
2932
2829
  const result = await this.apiClient.updateDatabase(dbId, updateRequest);
2933
- if ("error" in result) {
2830
+ if (isErrorResponse(result)) {
2934
2831
  return {
2935
2832
  error: {
2936
2833
  code: typeof result.error.code === "number" ? String(result.error.code) : result.error.code,
@@ -2979,7 +2876,7 @@ class DatabaseResource extends BaseResource {
2979
2876
  }
2980
2877
  const dbId = dbInfo.data.id;
2981
2878
  const result = await this.apiClient.deleteDatabase(dbId);
2982
- if ("error" in result) {
2879
+ if (isErrorResponse(result)) {
2983
2880
  return {
2984
2881
  error: {
2985
2882
  code: typeof result.error.code === "number" ? String(result.error.code) : result.error.code,
@@ -3022,7 +2919,7 @@ class DatabaseResource extends BaseResource {
3022
2919
  request.filters = options.filters;
3023
2920
  }
3024
2921
  const result = await this.apiClient.listDatabaseJobs(request, options);
3025
- if ("error" in result) {
2922
+ if (isErrorResponse(result)) {
3026
2923
  return {
3027
2924
  error: {
3028
2925
  code: typeof result.error.code === "number" ? String(result.error.code) : result.error.code,
@@ -3067,7 +2964,7 @@ class DatabaseResource extends BaseResource {
3067
2964
  */
3068
2965
  async pollDeleteStatus(jobId) {
3069
2966
  const result = await this.apiClient.pollDeleteStatus(jobId);
3070
- if ("error" in result) {
2967
+ if (isErrorResponse(result)) {
3071
2968
  return {
3072
2969
  error: {
3073
2970
  code: typeof result.error.code === "number" ? String(result.error.code) : result.error.code,
@@ -3107,26 +3004,9 @@ const buildIndexEndpointPath = (endpoint, params = {}) => {
3107
3004
  }
3108
3005
  return path;
3109
3006
  };
3110
- class IndexesApiClient {
3007
+ class IndexesApiClient extends BaseApiClient {
3111
3008
  constructor(apiKey, config = {}) {
3112
- this.config = { apiKey, ...config };
3113
- this.httpAdapter = createHttpAdapter();
3114
- const environment = config.environment || "prod";
3115
- const region = config.region || "asia-south1";
3116
- this.baseURL = this.getBaseURL(environment, region);
3117
- }
3118
- getBaseURL(environment, region) {
3119
- const regionConfig = REGION_CONFIGS[region];
3120
- if (!regionConfig) {
3121
- throw new Error(`Unsupported region: ${region}`);
3122
- }
3123
- const envConfig = regionConfig[environment];
3124
- if (!envConfig) {
3125
- throw new Error(
3126
- `Unsupported environment: ${environment} for region: ${region}`
3127
- );
3128
- }
3129
- return `${envConfig.baseURL}/v1`;
3009
+ super(apiKey, config);
3130
3010
  }
3131
3011
  async addIndex(tableId, request, dbId) {
3132
3012
  try {
@@ -3179,62 +3059,21 @@ class IndexesApiClient {
3179
3059
  return this.formatErrorResponse(error);
3180
3060
  }
3181
3061
  }
3182
- buildHeaders() {
3183
- return {
3184
- "Content-Type": "application/json",
3185
- Accept: "application/json",
3186
- "x-boltic-token": this.config.apiKey
3187
- };
3188
- }
3189
- formatErrorResponse(error) {
3190
- if (this.config.debug) {
3191
- console.error("Indexes API Error:", error);
3192
- }
3193
- if (error && typeof error === "object" && "response" in error) {
3194
- const apiError = error;
3195
- if (apiError.response?.data?.error) {
3196
- return apiError.response.data;
3197
- }
3198
- return {
3199
- error: {
3200
- code: "API_ERROR",
3201
- message: error.message || "Unknown API error",
3202
- meta: [`Status: ${apiError.response?.status || "unknown"}`]
3203
- }
3204
- };
3205
- }
3206
- if (error && typeof error === "object" && "message" in error) {
3207
- return {
3208
- error: {
3209
- code: "CLIENT_ERROR",
3210
- message: error.message,
3211
- meta: ["Client-side error occurred"]
3212
- }
3213
- };
3214
- }
3215
- return {
3216
- error: {
3217
- code: "UNKNOWN_ERROR",
3218
- message: "An unexpected error occurred",
3219
- meta: ["Unknown error type"]
3220
- }
3221
- };
3222
- }
3223
- }
3224
- class IndexResource {
3225
- constructor(client) {
3226
- this.client = client;
3227
- const config = client.getConfig();
3228
- this.apiClient = new IndexesApiClient(config.apiKey, {
3229
- environment: config.environment,
3230
- region: config.region,
3231
- timeout: config.timeout,
3232
- debug: config.debug,
3233
- retryAttempts: config.retryAttempts,
3234
- retryDelay: config.retryDelay,
3235
- headers: config.headers
3236
- });
3237
- this.tableResource = new TableResource(client);
3062
+ }
3063
+ class IndexResource {
3064
+ constructor(client) {
3065
+ this.client = client;
3066
+ const config = client.getConfig();
3067
+ this.apiClient = new IndexesApiClient(config.apiKey, {
3068
+ environment: config.environment,
3069
+ region: config.region,
3070
+ timeout: config.timeout,
3071
+ debug: config.debug,
3072
+ retryAttempts: config.retryAttempts,
3073
+ retryDelay: config.retryDelay,
3074
+ headers: config.headers
3075
+ });
3076
+ this.tableResource = new TableResource(client);
3238
3077
  }
3239
3078
  async resolveTableId(tableName, dbId) {
3240
3079
  const tableResult = await this.tableResource.findByName(tableName, dbId);
@@ -3356,26 +3195,9 @@ function transformDeleteRequest(sdkRequest) {
3356
3195
  }
3357
3196
  return result;
3358
3197
  }
3359
- class RecordsApiClient {
3198
+ class RecordsApiClient extends BaseApiClient {
3360
3199
  constructor(apiKey, config = {}) {
3361
- this.config = { apiKey, ...config };
3362
- this.httpAdapter = createHttpAdapter();
3363
- const environment = config.environment || "prod";
3364
- const region = config.region || "asia-south1";
3365
- this.baseURL = this.getBaseURL(environment, region);
3366
- }
3367
- getBaseURL(environment, region) {
3368
- const regionConfig = REGION_CONFIGS[region];
3369
- if (!regionConfig) {
3370
- throw new Error(`Unsupported region: ${region}`);
3371
- }
3372
- const envConfig = regionConfig[environment];
3373
- if (!envConfig) {
3374
- throw new Error(
3375
- `Unsupported environment: ${environment} for region: ${region}`
3376
- );
3377
- }
3378
- return `${envConfig.baseURL}/v1`;
3200
+ super(apiKey, config);
3379
3201
  }
3380
3202
  /**
3381
3203
  * Insert a single record
@@ -3651,47 +3473,6 @@ class RecordsApiClient {
3651
3473
  dbId
3652
3474
  );
3653
3475
  }
3654
- buildHeaders() {
3655
- return {
3656
- "Content-Type": "application/json",
3657
- Accept: "application/json",
3658
- "x-boltic-token": this.config.apiKey
3659
- };
3660
- }
3661
- formatErrorResponse(error) {
3662
- if (this.config.debug) {
3663
- console.error("Records API Error:", error);
3664
- }
3665
- if (error && typeof error === "object" && "response" in error) {
3666
- const apiError = error;
3667
- if (apiError.response?.data?.error) {
3668
- return apiError.response.data;
3669
- }
3670
- return {
3671
- error: {
3672
- code: "API_ERROR",
3673
- message: error.message || "Unknown API error",
3674
- meta: [`Status: ${apiError.response?.status || "unknown"}`]
3675
- }
3676
- };
3677
- }
3678
- if (error && typeof error === "object" && "message" in error) {
3679
- return {
3680
- error: {
3681
- code: "CLIENT_ERROR",
3682
- message: error.message,
3683
- meta: ["Client-side error occurred"]
3684
- }
3685
- };
3686
- }
3687
- return {
3688
- error: {
3689
- code: "UNKNOWN_ERROR",
3690
- message: "An unexpected error occurred",
3691
- meta: ["Unknown error type"]
3692
- }
3693
- };
3694
- }
3695
3476
  }
3696
3477
  class RecordResource {
3697
3478
  constructor(client) {
@@ -4279,86 +4060,6 @@ const buildSqlEndpointPath = (endpoint, params = {}) => {
4279
4060
  });
4280
4061
  return path;
4281
4062
  };
4282
- class BaseApiClient {
4283
- constructor(apiKey, config = {}) {
4284
- this.config = { apiKey, ...config };
4285
- this.httpAdapter = createHttpAdapter();
4286
- const environment = config.environment || "prod";
4287
- const region = config.region || "asia-south1";
4288
- this.baseURL = this.getBaseURL(environment, region);
4289
- }
4290
- getBaseURL(environment, region) {
4291
- const regionConfig = REGION_CONFIGS[region];
4292
- if (!regionConfig) {
4293
- throw new Error(`Unsupported region: ${region}`);
4294
- }
4295
- const envConfig = regionConfig[environment];
4296
- if (!envConfig) {
4297
- throw new Error(
4298
- `Unsupported environment: ${environment} for region: ${region}`
4299
- );
4300
- }
4301
- return `${envConfig.baseURL}/v1`;
4302
- }
4303
- buildHeaders() {
4304
- return {
4305
- "Content-Type": "application/json",
4306
- Accept: "application/json",
4307
- "x-boltic-token": this.config.apiKey,
4308
- ...this.config.headers
4309
- };
4310
- }
4311
- formatErrorResponse(error, prefix = "API") {
4312
- if (this.config.debug) {
4313
- console.error(`${prefix} Error:`, error);
4314
- }
4315
- if (error && typeof error === "object" && "response" in error) {
4316
- const apiError = error;
4317
- if (apiError.response?.data?.error) {
4318
- return apiError.response.data;
4319
- }
4320
- return {
4321
- error: {
4322
- code: `${prefix}_ERROR`,
4323
- message: error.message || `Unknown ${prefix} error`,
4324
- meta: [`Status: ${apiError.response?.status || "unknown"}`]
4325
- }
4326
- };
4327
- }
4328
- if (error && typeof error === "object" && "message" in error) {
4329
- return {
4330
- error: {
4331
- code: `${prefix}_CLIENT_ERROR`,
4332
- message: error.message,
4333
- meta: [`${prefix} client-side error occurred`]
4334
- }
4335
- };
4336
- }
4337
- return {
4338
- error: {
4339
- code: `${prefix}_UNKNOWN_ERROR`,
4340
- message: `An unexpected ${prefix} error occurred`,
4341
- meta: [`Unknown ${prefix} error type`]
4342
- }
4343
- };
4344
- }
4345
- // Security methods to prevent API key exposure
4346
- toString() {
4347
- return `${this.constructor.name} { environment: "${this.config.environment || "prod"}", debug: ${this.config.debug || false} }`;
4348
- }
4349
- toJSON() {
4350
- const safeConfig = { ...this.config };
4351
- delete safeConfig.apiKey;
4352
- return {
4353
- client: this.constructor.name,
4354
- config: safeConfig
4355
- };
4356
- }
4357
- // Custom inspect method for Node.js console logging
4358
- [/* @__PURE__ */ Symbol.for("nodejs.util.inspect.custom")]() {
4359
- return this.toString();
4360
- }
4361
- }
4362
4063
  class SqlApiClient extends BaseApiClient {
4363
4064
  constructor(apiKey, config = {}) {
4364
4065
  super(apiKey, config);
@@ -4796,74 +4497,1057 @@ class TableBuilder {
4796
4497
  function createTableBuilder(options, tablesApiClient) {
4797
4498
  return new TableBuilder(options, tablesApiClient);
4798
4499
  }
4799
- class BolticClient {
4800
- constructor(apiKey, options = {}) {
4801
- this.currentDatabase = null;
4802
- this.clientOptions = options;
4803
- this.configManager = new ConfigManager(
4804
- apiKey,
4805
- options.environment || "prod",
4806
- options.region || "asia-south1",
4807
- options
4500
+ const POLLING_INTERVAL_MS = 1e3;
4501
+ const MAX_POLLING_ATTEMPTS = 30;
4502
+ const SCHEMA_TYPE_MAPPING = {
4503
+ string: { type: "string", fallback_value: "" },
4504
+ number: { type: "number", fallback_value: "" },
4505
+ boolean: { type: "boolean", secondary_type: "string", fallback_value: "" },
4506
+ int: { type: "number", fallback_value: "" },
4507
+ integer: { type: "number", fallback_value: "" },
4508
+ "date-time": { type: "date-time", secondary_type: "string", fallback_value: "" },
4509
+ date: { type: "date", secondary_type: "string", fallback_value: "" },
4510
+ json: { type: "object", fallback_value: {} },
4511
+ text: { type: "string", fallback_value: "" },
4512
+ email: { type: "string", fallback_value: "" },
4513
+ password: { type: "string", fallback_value: "" },
4514
+ url: { type: "string", fallback_value: "" },
4515
+ textarea: { type: "string", fallback_value: "" },
4516
+ select: { type: "string", fallback_value: "" },
4517
+ multiselect: { type: "string", fallback_value: "" },
4518
+ autocomplete: { type: "array", fallback_value: [] },
4519
+ radio: { type: "string", fallback_value: "" },
4520
+ radiobuttons: { type: "string", fallback_value: "" },
4521
+ checkbox: { type: "array", fallback_value: [] },
4522
+ toggle: { type: "boolean", fallback_value: "" },
4523
+ hidden: { type: "string", fallback_value: "" },
4524
+ slider: { type: "number", fallback_value: "" },
4525
+ datepicker: { type: "string", fallback_value: "" },
4526
+ phoneinput: { type: "string", fallback_value: "" },
4527
+ time: { type: "string", fallback_value: "" },
4528
+ datetime: { type: "string", fallback_value: "" },
4529
+ code: { type: "string", fallback_value: "" },
4530
+ multitext: { type: "array", fallback_value: [] },
4531
+ array: { type: "array", fallback_value: [] },
4532
+ keyvalue: { type: "object", fallback_value: {} },
4533
+ object: { type: "object", fallback_value: {} },
4534
+ phone: { type: "string", fallback_value: "" },
4535
+ "number[]": { type: "string", fallback_value: "" },
4536
+ "number []": { type: "string", fallback_value: "" },
4537
+ "object | any": { type: "string", fallback_value: "" }
4538
+ };
4539
+ const WORKFLOW_ENDPOINTS = {
4540
+ executeActivity: {
4541
+ path: "/workflows/execute/activity",
4542
+ method: "POST",
4543
+ authenticated: true
4544
+ },
4545
+ getExecutionById: {
4546
+ path: "/workflows/run/{run_id}",
4547
+ method: "GET",
4548
+ authenticated: true
4549
+ },
4550
+ getIntegrations: {
4551
+ path: "/integrations",
4552
+ method: "GET",
4553
+ authenticated: true
4554
+ },
4555
+ getCredentials: {
4556
+ path: "/integrations/entity/{entity}",
4557
+ method: "GET",
4558
+ authenticated: true
4559
+ },
4560
+ getIntegrationResource: {
4561
+ path: "/integrations/{integration_slug}/schema",
4562
+ method: "GET",
4563
+ authenticated: true
4564
+ },
4565
+ getIntegrationForm: {
4566
+ path: "/integrations/{integration_slug}/fields",
4567
+ method: "GET",
4568
+ authenticated: true
4569
+ }
4570
+ };
4571
+ function buildWorkflowEndpointPath(endpoint, params = {}) {
4572
+ let path = endpoint.path;
4573
+ for (const [key, value] of Object.entries(params)) {
4574
+ path = path.replace(`{${key}}`, value);
4575
+ }
4576
+ return path;
4577
+ }
4578
+ class WorkflowApiClient extends BaseApiClient {
4579
+ constructor(apiKey, config = {}) {
4580
+ super(apiKey, config, SERVICE_PATHS.WORKFLOW_TEMPORAL);
4581
+ this.integrationBaseURL = this.resolveAdditionalServiceURL(
4582
+ SERVICE_PATHS.INTEGRATION
4808
4583
  );
4809
- const config = this.configManager.getConfig();
4810
- this.authManager = new AuthManager2({
4811
- apiKey: config.apiKey,
4812
- maxRetries: config.maxRetries
4813
- });
4814
- this.baseClient = new BaseClient(config, this.authManager);
4815
- this.tableResource = new TableResource(this.baseClient);
4816
- this.columnResource = new ColumnResource(this.baseClient);
4817
- this.recordResource = new RecordResource(this.baseClient);
4818
- this.sqlResource = new SqlResource(this.baseClient);
4819
- this.indexResource = new IndexResource(this.baseClient);
4820
- this.databaseResource = new DatabaseResource(this.baseClient);
4821
- this.currentDatabase = null;
4822
4584
  }
4823
4585
  /**
4824
- * Get current database context
4586
+ * Execute a workflow activity.
4587
+ *
4588
+ * @param body - The execute-activity request body
4825
4589
  */
4826
- getCurrentDatabase() {
4827
- return this.currentDatabase;
4590
+ async executeActivity(body) {
4591
+ try {
4592
+ const endpoint = WORKFLOW_ENDPOINTS.executeActivity;
4593
+ const url = `${this.baseURL}${endpoint.path}`;
4594
+ const response = await this.httpAdapter.request({
4595
+ url,
4596
+ method: endpoint.method,
4597
+ headers: this.buildHeaders(),
4598
+ data: body,
4599
+ timeout: this.config.timeout
4600
+ });
4601
+ return response.data;
4602
+ } catch (error) {
4603
+ return this.formatErrorResponse(error, "WORKFLOW");
4604
+ }
4828
4605
  }
4829
4606
  /**
4830
- * Switch to a different database using its internal name (slug).
4831
- * All subsequent operations will use this database.
4832
- *
4833
- * If no internal name is provided, the SDK will switch back to the default database.
4834
- *
4835
- * @param dbInternalName - Database internal name/slug to switch to. If omitted or empty, default DB is used.
4836
- *
4837
- * @example
4838
- * ```typescript
4839
- * // Switch to a specific database by slug
4840
- * await client.useDatabase('my_database_slug');
4607
+ * Fetch the result of a workflow execution by its run ID.
4841
4608
  *
4842
- * // Switch back to default database
4843
- * await client.useDatabase();
4844
- * ```
4609
+ * @param runId - The execution run ID returned by `executeActivity`
4845
4610
  */
4846
- async useDatabase(dbInternalName) {
4847
- console.log(`Database internal name:${dbInternalName}`);
4848
- if (!dbInternalName || dbInternalName === "") {
4849
- this.currentDatabase = null;
4850
- return;
4611
+ async getExecutionById(runId) {
4612
+ try {
4613
+ const endpoint = WORKFLOW_ENDPOINTS.getExecutionById;
4614
+ const path = buildWorkflowEndpointPath(endpoint, { run_id: runId });
4615
+ const url = `${this.baseURL}${path}`;
4616
+ const response = await this.httpAdapter.request({
4617
+ url,
4618
+ method: endpoint.method,
4619
+ headers: this.buildHeaders(),
4620
+ timeout: this.config.timeout
4621
+ });
4622
+ return response.data;
4623
+ } catch (error) {
4624
+ return this.formatErrorResponse(error, "WORKFLOW");
4851
4625
  }
4852
- const result = await this.databaseResource.findOne(dbInternalName);
4853
- console.log(`Result:${JSON.stringify(result, null, 2)}`);
4854
- if (isErrorResponse(result)) {
4855
- console.log(`Error:${result.error.message}`);
4856
- throw new Error(
4857
- result.error.message || `Failed to switch database to internal name '${dbInternalName}'`
4858
- );
4626
+ }
4627
+ /**
4628
+ * Fetch the list of available integrations.
4629
+ *
4630
+ * @param params - Optional pagination parameters
4631
+ */
4632
+ async getIntegrations(params = {}) {
4633
+ try {
4634
+ const endpoint = WORKFLOW_ENDPOINTS.getIntegrations;
4635
+ const query = new URLSearchParams({
4636
+ page: String(params.page ?? 1),
4637
+ per_page: String(params.per_page ?? 999)
4638
+ });
4639
+ const url = `${this.baseURL}${endpoint.path}?${query.toString()}`;
4640
+ const response = await this.httpAdapter.request({
4641
+ url,
4642
+ method: endpoint.method,
4643
+ headers: this.buildHeaders(),
4644
+ timeout: this.config.timeout
4645
+ });
4646
+ return response.data;
4647
+ } catch (error) {
4648
+ return this.formatErrorResponse(error, "WORKFLOW");
4859
4649
  }
4860
- const db = result.data;
4861
- this.currentDatabase = {
4862
- databaseId: db.id,
4863
- dbInternalName: db.db_internal_name || dbInternalName
4864
- };
4865
4650
  }
4866
- // Direct database operations
4651
+ /**
4652
+ * Fetch credentials for a given integration entity.
4653
+ *
4654
+ * @param params - Entity name (required) and optional pagination
4655
+ */
4656
+ async getCredentials(params) {
4657
+ try {
4658
+ const endpoint = WORKFLOW_ENDPOINTS.getCredentials;
4659
+ const path = buildWorkflowEndpointPath(endpoint, {
4660
+ entity: params.entity.toUpperCase()
4661
+ });
4662
+ const query = new URLSearchParams({
4663
+ current_page: String(params.current_page ?? 1),
4664
+ page_size: String(params.page_size ?? 999)
4665
+ });
4666
+ const url = `${this.integrationBaseURL}${path}?${query.toString()}`;
4667
+ const response = await this.httpAdapter.request({
4668
+ url,
4669
+ method: endpoint.method,
4670
+ headers: this.buildHeaders(),
4671
+ timeout: this.config.timeout
4672
+ });
4673
+ return response.data;
4674
+ } catch (error) {
4675
+ return this.formatErrorResponse(error, "INTEGRATION");
4676
+ }
4677
+ }
4678
+ /**
4679
+ * Fetch the resource/operation schema for an integration.
4680
+ *
4681
+ * @param params - Integration slug identifier
4682
+ */
4683
+ async getIntegrationResource(params) {
4684
+ try {
4685
+ const endpoint = WORKFLOW_ENDPOINTS.getIntegrationResource;
4686
+ const path = buildWorkflowEndpointPath(endpoint, {
4687
+ integration_slug: params.integration_slug
4688
+ });
4689
+ const url = `${this.baseURL}${path}`;
4690
+ const response = await this.httpAdapter.request({
4691
+ url,
4692
+ method: endpoint.method,
4693
+ headers: this.buildHeaders(),
4694
+ timeout: this.config.timeout
4695
+ });
4696
+ return response.data;
4697
+ } catch (error) {
4698
+ return this.formatErrorResponse(error, "WORKFLOW");
4699
+ }
4700
+ }
4701
+ /**
4702
+ * Fetch the form schema (fields) for a specific integration resource + operation.
4703
+ *
4704
+ * @param params - Integration slug, resource, operation, and credential secret
4705
+ */
4706
+ async getIntegrationForm(params) {
4707
+ try {
4708
+ const endpoint = WORKFLOW_ENDPOINTS.getIntegrationForm;
4709
+ const path = buildWorkflowEndpointPath(endpoint, {
4710
+ integration_slug: params.integration_slug
4711
+ });
4712
+ const query = new URLSearchParams({
4713
+ resource: params.resource,
4714
+ operation: params.operation,
4715
+ // getFormOnly: String(params.getFormOnly ?? true),
4716
+ secret: params.secret
4717
+ });
4718
+ const url = `${this.baseURL}${path}?${query.toString()}`;
4719
+ const response = await this.httpAdapter.request({
4720
+ url,
4721
+ method: endpoint.method,
4722
+ headers: this.buildHeaders(),
4723
+ timeout: this.config.timeout
4724
+ });
4725
+ return response.data;
4726
+ } catch (error) {
4727
+ return this.formatErrorResponse(error, "WORKFLOW");
4728
+ }
4729
+ }
4730
+ }
4731
+ const FORM_META_FIELDS = /* @__PURE__ */ new Set(["resource", "operation"]);
4732
+ function getSchemaMapping(displayType) {
4733
+ return SCHEMA_TYPE_MAPPING[displayType] ?? {
4734
+ type: "string",
4735
+ fallback_value: ""
4736
+ };
4737
+ }
4738
+ function transformFormToDefaults(fields, skipFields = FORM_META_FIELDS) {
4739
+ const result = {};
4740
+ for (const field of fields) {
4741
+ if (skipFields.has(field.name)) continue;
4742
+ const displayType = field.meta?.displayType || "text";
4743
+ const mapping = getSchemaMapping(displayType);
4744
+ result[field.name] = field.meta?.value !== void 0 ? field.meta.value : mapping.fallback_value;
4745
+ }
4746
+ return result;
4747
+ }
4748
+ function transformFormToJsonSchema(fields, skipFields = FORM_META_FIELDS) {
4749
+ const properties = {};
4750
+ for (const field of fields) {
4751
+ if (skipFields.has(field.name)) continue;
4752
+ const displayType = field.meta?.displayType || "text";
4753
+ const mapping = getSchemaMapping(displayType);
4754
+ const isRequired = field.meta?.validation?.required ?? false;
4755
+ const defaultValue = field.meta?.value !== void 0 ? field.meta.value : mapping.fallback_value;
4756
+ const prop = {
4757
+ type: mapping.type,
4758
+ required: isRequired,
4759
+ default: defaultValue
4760
+ };
4761
+ if (field.meta?.description) {
4762
+ prop.description = field.meta.description;
4763
+ }
4764
+ if (field.meta?.options && Array.isArray(field.meta.options) && field.meta.options.length > 0) {
4765
+ prop.enum = field.meta.options.map((opt) => opt.value);
4766
+ }
4767
+ properties[field.name] = prop;
4768
+ }
4769
+ return { type: "object", properties };
4770
+ }
4771
+ function buildDefaultResultPayload() {
4772
+ return {
4773
+ payload: {},
4774
+ global_variables: {}
4775
+ };
4776
+ }
4777
+ function buildExecuteActivityBody(params) {
4778
+ const node = {
4779
+ data: {
4780
+ type: params.data.type,
4781
+ name: params.data.name,
4782
+ properties: params.data.properties
4783
+ }
4784
+ };
4785
+ return {
4786
+ nodes: [node],
4787
+ result: params.result ?? buildDefaultResultPayload()
4788
+ };
4789
+ }
4790
+ function sleep$1(ms) {
4791
+ return new Promise((resolve) => setTimeout(resolve, ms));
4792
+ }
4793
+ class WorkflowResource extends BaseResource {
4794
+ constructor(client) {
4795
+ super(client, "/workflows");
4796
+ const config = client.getConfig();
4797
+ this.apiClient = new WorkflowApiClient(config.apiKey, {
4798
+ environment: config.environment,
4799
+ region: config.region,
4800
+ timeout: config.timeout,
4801
+ debug: config.debug
4802
+ });
4803
+ }
4804
+ /**
4805
+ * Execute a workflow integration activity.
4806
+ *
4807
+ * When `executeOnly` is `true`, returns the immediate API response.
4808
+ * When `executeOnly` is `false` (default), polls until a terminal state
4809
+ * is reached and returns the final execution result.
4810
+ *
4811
+ * @param params - Execution parameters
4812
+ * @returns The execute response or the final polled result
4813
+ *
4814
+ * @example
4815
+ * ```typescript
4816
+ * const result = await client.workflow.executeIntegration({
4817
+ * data: { type: 'apiActivity', name: 'api1', properties: { method: 'get', endpoint: '...' } },
4818
+ * });
4819
+ *
4820
+ * const fire = await client.workflow.executeIntegration({
4821
+ * data: { type: 'apiActivity', name: 'api1', properties: { method: 'get', endpoint: '...' } },
4822
+ * executeOnly: true,
4823
+ * });
4824
+ * ```
4825
+ */
4826
+ async executeIntegration(params) {
4827
+ const body = buildExecuteActivityBody(params);
4828
+ const executeResult = await this.apiClient.executeActivity(body);
4829
+ if (isErrorResponse(executeResult)) {
4830
+ return executeResult;
4831
+ }
4832
+ if (params.executeOnly) {
4833
+ return executeResult;
4834
+ }
4835
+ const executionId = executeResult.data?.execution_id;
4836
+ if (!executionId) {
4837
+ return {
4838
+ error: {
4839
+ code: "MISSING_EXECUTION_ID",
4840
+ message: "Execute API response did not contain an execution_id",
4841
+ meta: []
4842
+ }
4843
+ };
4844
+ }
4845
+ return this.pollExecution(executionId);
4846
+ }
4847
+ /**
4848
+ * Retrieve the result of a workflow execution by its run/execution ID.
4849
+ *
4850
+ * @param executionId - The execution run ID
4851
+ * @returns The execution data or an error response
4852
+ *
4853
+ * @example
4854
+ * ```typescript
4855
+ * const result = await client.workflow.getIntegrationExecuteById('run-uuid');
4856
+ * ```
4857
+ */
4858
+ async getIntegrationExecuteById(executionId) {
4859
+ return this.apiClient.getExecutionById(executionId);
4860
+ }
4861
+ /**
4862
+ * Fetch the list of available integrations.
4863
+ *
4864
+ * @param params - Optional pagination parameters (`page`, `per_page`)
4865
+ * @returns The integrations list or an error response
4866
+ *
4867
+ * @example
4868
+ * ```typescript
4869
+ * const list = await client.workflow.getIntegrations();
4870
+ * ```
4871
+ */
4872
+ async getIntegrations(params = {}) {
4873
+ return this.apiClient.getIntegrations(params);
4874
+ }
4875
+ /**
4876
+ * Fetch credentials for a given integration entity.
4877
+ *
4878
+ * @param params - Entity name (required), optional `current_page` and `page_size`
4879
+ * @returns The credentials list or an error response
4880
+ *
4881
+ * @example
4882
+ * ```typescript
4883
+ * const creds = await client.workflow.getCredentials({ entity: 'freshsales' });
4884
+ * ```
4885
+ */
4886
+ async getCredentials(params) {
4887
+ return this.apiClient.getCredentials(params);
4888
+ }
4889
+ /**
4890
+ * Fetch the resource/operation schema for an integration.
4891
+ *
4892
+ * Returns the available resources and operations supported by the
4893
+ * specified integration (e.g. which resources like "task", "project"
4894
+ * are available and what operations can be performed on them).
4895
+ *
4896
+ * @param params - Integration slug identifier
4897
+ * @returns The integration resource schema or an error response
4898
+ *
4899
+ * @example
4900
+ * ```typescript
4901
+ * const schema = await client.workflow.getIntegrationResource({
4902
+ * integration_slug: 'blt-int.asana',
4903
+ * });
4904
+ * ```
4905
+ */
4906
+ async getIntegrationResource(params) {
4907
+ return this.apiClient.getIntegrationResource(params);
4908
+ }
4909
+ /**
4910
+ * Fetch the form schema (fields) for a specific integration resource + operation.
4911
+ *
4912
+ * By default, returns a flat JSON object with default/fallback values
4913
+ * for each input field. Set `asJsonSchema: true` to get a JSON Schema
4914
+ * object describing the expected input shape instead.
4915
+ *
4916
+ * Fields like `resource` and `operation` are automatically excluded
4917
+ * since they are already handled by the SDK parameters. The `secret`
4918
+ * field is included and populated with the value from `params.secret`.
4919
+ *
4920
+ * @param params - Integration slug, resource, operation, credential secret, and format flag
4921
+ * @returns Transformed form data or an error response
4922
+ *
4923
+ * @example
4924
+ * ```typescript
4925
+ * // Get flat defaults: { name: '', workspace: [], team: '', ... }
4926
+ * const defaults = await client.workflow.getIntegrationForm({
4927
+ * integration_slug: 'blt-int.asana',
4928
+ * resource: 'project',
4929
+ * operation: 'create',
4930
+ * secret: 'credential-secret-here',
4931
+ * });
4932
+ *
4933
+ * // Get JSON Schema: { type: 'object', properties: { name: { type: 'string', ... } } }
4934
+ * const schema = await client.workflow.getIntegrationForm({
4935
+ * integration_slug: 'blt-int.asana',
4936
+ * resource: 'project',
4937
+ * operation: 'create',
4938
+ * secret: 'credential-secret-here',
4939
+ * asJsonSchema: true,
4940
+ * });
4941
+ * ```
4942
+ */
4943
+ async getIntegrationForm(params) {
4944
+ const rawResult = await this.apiClient.getIntegrationForm(params);
4945
+ console.log("rawResult", JSON.stringify(rawResult, null, 2));
4946
+ if (isErrorResponse(rawResult)) {
4947
+ return rawResult;
4948
+ }
4949
+ const configuration = rawResult.data?.parameters || rawResult.data;
4950
+ const fields = configuration ?? [];
4951
+ const transformed = params.asJsonSchema ? transformFormToJsonSchema(fields) : transformFormToDefaults(fields);
4952
+ if (params.asJsonSchema) {
4953
+ const schema = transformed;
4954
+ if (schema.properties.secret) {
4955
+ schema.properties.secret.default = params.secret;
4956
+ }
4957
+ } else {
4958
+ const defaults = transformed;
4959
+ if ("secret" in defaults) {
4960
+ defaults.secret = params.secret;
4961
+ }
4962
+ }
4963
+ return {
4964
+ data: transformed,
4965
+ message: rawResult.message
4966
+ };
4967
+ }
4968
+ /**
4969
+ * Internal polling loop.
4970
+ * Repeatedly calls `getExecutionById` until the response `data` object is
4971
+ * non-empty (execution finished) or max attempts are exhausted.
4972
+ */
4973
+ async pollExecution(executionId) {
4974
+ const debug = this.client.getConfig().debug;
4975
+ for (let attempt = 0; attempt < MAX_POLLING_ATTEMPTS; attempt++) {
4976
+ const result = await this.apiClient.getExecutionById(executionId);
4977
+ if (isErrorResponse(result)) {
4978
+ return result;
4979
+ }
4980
+ if (result.data && Object.keys(result.data).length > 0) {
4981
+ if (debug) {
4982
+ console.log(
4983
+ `[WorkflowResource] Execution ${executionId} completed after ${attempt + 1} poll(s)`
4984
+ );
4985
+ }
4986
+ return result;
4987
+ }
4988
+ await sleep$1(POLLING_INTERVAL_MS);
4989
+ }
4990
+ return {
4991
+ error: {
4992
+ code: "EXECUTION_TIMEOUT",
4993
+ message: `Execution ${executionId} did not complete within ${MAX_POLLING_ATTEMPTS} polling attempts`,
4994
+ meta: [
4995
+ `execution_id: ${executionId}`,
4996
+ `max_attempts: ${MAX_POLLING_ATTEMPTS}`
4997
+ ]
4998
+ }
4999
+ };
5000
+ }
5001
+ }
5002
+ const STATUS_POLLING_INTERVAL_MS = 5e3;
5003
+ const MAX_STATUS_POLLING_ATTEMPTS = 60;
5004
+ const TERMINAL_STATUSES = [
5005
+ "running",
5006
+ "failed",
5007
+ "degraded",
5008
+ "suspended"
5009
+ ];
5010
+ const DEFAULT_RESOURCES = {
5011
+ CPU: 0.1,
5012
+ MemoryMB: 128,
5013
+ MemoryMaxMB: 128
5014
+ };
5015
+ const DEFAULT_SCALING = {
5016
+ AutoStop: false,
5017
+ Min: 1,
5018
+ Max: 1,
5019
+ MaxIdleTime: 0
5020
+ };
5021
+ const SERVERLESS_ENDPOINTS = {
5022
+ list: {
5023
+ path: "/apps",
5024
+ method: "GET",
5025
+ authenticated: true
5026
+ },
5027
+ get: {
5028
+ path: "/apps/{app_id}",
5029
+ method: "GET",
5030
+ authenticated: true
5031
+ },
5032
+ create: {
5033
+ path: "/apps",
5034
+ method: "POST",
5035
+ authenticated: true
5036
+ },
5037
+ update: {
5038
+ path: "/apps/{app_id}",
5039
+ method: "PUT",
5040
+ authenticated: true
5041
+ },
5042
+ getBuilds: {
5043
+ path: "/apps/{app_id}/builds",
5044
+ method: "GET",
5045
+ authenticated: true
5046
+ },
5047
+ getLogs: {
5048
+ path: "/apps/{app_id}/logs",
5049
+ method: "GET",
5050
+ authenticated: true
5051
+ },
5052
+ getBuildLogs: {
5053
+ path: "/apps/{app_id}/builds/{build_id}/logs",
5054
+ method: "GET",
5055
+ authenticated: true
5056
+ }
5057
+ };
5058
+ function buildServerlessEndpointPath(endpoint, params = {}) {
5059
+ let path = endpoint.path;
5060
+ for (const [key, value] of Object.entries(params)) {
5061
+ path = path.replace(`{${key}}`, value);
5062
+ }
5063
+ return path;
5064
+ }
5065
+ class ServerlessApiClient extends BaseApiClient {
5066
+ constructor(apiKey, config = {}) {
5067
+ super(apiKey, config, SERVICE_PATHS.SERVERLESS);
5068
+ }
5069
+ /**
5070
+ * List all serverless functions with optional pagination and search.
5071
+ */
5072
+ async list(params = {}) {
5073
+ try {
5074
+ const endpoint = SERVERLESS_ENDPOINTS.list;
5075
+ const query = new URLSearchParams({
5076
+ page: String(params.page ?? 1),
5077
+ limit: String(params.limit ?? 20),
5078
+ sortBy: params.sortBy ?? "CreatedAt",
5079
+ sortOrder: params.sortOrder ?? "desc"
5080
+ });
5081
+ if (params.query) {
5082
+ query.set("q", params.query);
5083
+ }
5084
+ const url = `${this.baseURL}${endpoint.path}?${query.toString()}`;
5085
+ const response = await this.httpAdapter.request({
5086
+ url,
5087
+ method: endpoint.method,
5088
+ headers: this.buildHeaders(),
5089
+ timeout: this.config.timeout
5090
+ });
5091
+ return response.data;
5092
+ } catch (error) {
5093
+ return this.formatErrorResponse(error, "SERVERLESS");
5094
+ }
5095
+ }
5096
+ /**
5097
+ * Get a serverless function by its ID.
5098
+ */
5099
+ async get(appId) {
5100
+ try {
5101
+ const endpoint = SERVERLESS_ENDPOINTS.get;
5102
+ const path = buildServerlessEndpointPath(endpoint, { app_id: appId });
5103
+ const url = `${this.baseURL}${path}`;
5104
+ console.log("url", url);
5105
+ const response = await this.httpAdapter.request({
5106
+ url,
5107
+ method: endpoint.method,
5108
+ headers: this.buildHeaders(),
5109
+ timeout: this.config.timeout
5110
+ });
5111
+ console.log("response", response.data);
5112
+ return response.data;
5113
+ } catch (error) {
5114
+ return this.formatErrorResponse(error, "SERVERLESS");
5115
+ }
5116
+ }
5117
+ /**
5118
+ * Create a new serverless function.
5119
+ */
5120
+ async create(payload) {
5121
+ try {
5122
+ const endpoint = SERVERLESS_ENDPOINTS.create;
5123
+ const url = `${this.baseURL}${endpoint.path}`;
5124
+ const response = await this.httpAdapter.request({
5125
+ url,
5126
+ method: endpoint.method,
5127
+ headers: this.buildHeaders(),
5128
+ data: payload,
5129
+ timeout: this.config.timeout
5130
+ });
5131
+ return response.data;
5132
+ } catch (error) {
5133
+ return this.formatErrorResponse(error, "SERVERLESS");
5134
+ }
5135
+ }
5136
+ /**
5137
+ * Update an existing serverless function.
5138
+ */
5139
+ async update(params) {
5140
+ try {
5141
+ const endpoint = SERVERLESS_ENDPOINTS.update;
5142
+ const path = buildServerlessEndpointPath(endpoint, {
5143
+ app_id: params.appId
5144
+ });
5145
+ const url = `${this.baseURL}${path}`;
5146
+ const response = await this.httpAdapter.request({
5147
+ url,
5148
+ method: endpoint.method,
5149
+ headers: this.buildHeaders(),
5150
+ data: params.payload,
5151
+ timeout: this.config.timeout
5152
+ });
5153
+ return response.data;
5154
+ } catch (error) {
5155
+ return this.formatErrorResponse(error, "SERVERLESS");
5156
+ }
5157
+ }
5158
+ /**
5159
+ * List builds for a serverless function.
5160
+ */
5161
+ async getBuilds(params) {
5162
+ try {
5163
+ const endpoint = SERVERLESS_ENDPOINTS.getBuilds;
5164
+ const path = buildServerlessEndpointPath(endpoint, {
5165
+ app_id: params.appId
5166
+ });
5167
+ const query = new URLSearchParams({
5168
+ page: String(params.page ?? 1),
5169
+ limit: String(params.limit ?? 20),
5170
+ sortBy: "CreatedAt",
5171
+ sortOrder: "desc"
5172
+ });
5173
+ const url = `${this.baseURL}${path}?${query.toString()}`;
5174
+ const response = await this.httpAdapter.request({
5175
+ url,
5176
+ method: endpoint.method,
5177
+ headers: this.buildHeaders(),
5178
+ timeout: this.config.timeout
5179
+ });
5180
+ return response.data;
5181
+ } catch (error) {
5182
+ return this.formatErrorResponse(error, "SERVERLESS");
5183
+ }
5184
+ }
5185
+ /**
5186
+ * Get runtime logs for a serverless function.
5187
+ */
5188
+ async getLogs(params) {
5189
+ try {
5190
+ const endpoint = SERVERLESS_ENDPOINTS.getLogs;
5191
+ const path = buildServerlessEndpointPath(endpoint, {
5192
+ app_id: params.appId
5193
+ });
5194
+ const now = Math.floor(Date.now() / 1e3);
5195
+ const defaultStart = now - 24 * 60 * 60;
5196
+ const query = new URLSearchParams({
5197
+ page: String(params.page ?? 1),
5198
+ limit: String(params.limit ?? 50),
5199
+ sortBy: "Timestamp",
5200
+ sortOrder: params.sortOrder ?? "DESC",
5201
+ timestampStart: String(params.timestampStart ?? defaultStart),
5202
+ timestampEnd: String(params.timestampEnd ?? now),
5203
+ metric_interval: "60"
5204
+ });
5205
+ const url = `${this.baseURL}${path}?${query.toString()}`;
5206
+ const response = await this.httpAdapter.request({
5207
+ url,
5208
+ method: endpoint.method,
5209
+ headers: this.buildHeaders(),
5210
+ timeout: this.config.timeout
5211
+ });
5212
+ return response.data;
5213
+ } catch (error) {
5214
+ return this.formatErrorResponse(error, "SERVERLESS");
5215
+ }
5216
+ }
5217
+ /**
5218
+ * Get build logs for a specific build of a serverless function.
5219
+ */
5220
+ async getBuildLogs(params) {
5221
+ try {
5222
+ const endpoint = SERVERLESS_ENDPOINTS.getBuildLogs;
5223
+ const path = buildServerlessEndpointPath(endpoint, {
5224
+ app_id: params.appId,
5225
+ build_id: params.buildId
5226
+ });
5227
+ const query = new URLSearchParams({
5228
+ limit: "-1",
5229
+ tail: "false",
5230
+ sortOrder: "asc",
5231
+ sortBy: "Timestamp"
5232
+ });
5233
+ const url = `${this.baseURL}${path}?${query.toString()}`;
5234
+ const response = await this.httpAdapter.request({
5235
+ url,
5236
+ method: endpoint.method,
5237
+ headers: this.buildHeaders(),
5238
+ timeout: this.config.timeout
5239
+ });
5240
+ return response.data;
5241
+ } catch (error) {
5242
+ return this.formatErrorResponse(error, "SERVERLESS");
5243
+ }
5244
+ }
5245
+ }
5246
+ function sleep(ms) {
5247
+ return new Promise((resolve) => setTimeout(resolve, ms));
5248
+ }
5249
+ class ServerlessResource extends BaseResource {
5250
+ constructor(client) {
5251
+ super(client, "/serverless");
5252
+ const config = client.getConfig();
5253
+ this.apiClient = new ServerlessApiClient(config.apiKey, {
5254
+ environment: config.environment,
5255
+ region: config.region,
5256
+ timeout: config.timeout,
5257
+ debug: config.debug
5258
+ });
5259
+ }
5260
+ /**
5261
+ * List all serverless functions with optional pagination and search.
5262
+ *
5263
+ * @param params - Optional pagination and filter parameters
5264
+ * @returns Paginated list of serverless functions
5265
+ *
5266
+ * @example
5267
+ * ```typescript
5268
+ * const list = await client.serverless.list();
5269
+ * const filtered = await client.serverless.list({ query: 'my-func', limit: 10 });
5270
+ * ```
5271
+ */
5272
+ async list(params = {}) {
5273
+ return this.apiClient.list(params);
5274
+ }
5275
+ /**
5276
+ * Get a serverless function by its ID.
5277
+ *
5278
+ * @param appId - The serverless function ID
5279
+ * @returns The serverless function details
5280
+ *
5281
+ * @example
5282
+ * ```typescript
5283
+ * const fn = await client.serverless.get('serverless-id');
5284
+ * ```
5285
+ */
5286
+ async get(appId) {
5287
+ return this.apiClient.get(appId);
5288
+ }
5289
+ /**
5290
+ * Create a new serverless function.
5291
+ *
5292
+ * Supports three runtime types:
5293
+ * - `code` — deploy code directly (blueprint)
5294
+ * - `git` — deploy from a Git repository
5295
+ * - `container` — deploy a Docker container
5296
+ *
5297
+ * @param params - The serverless creation payload
5298
+ * @returns The created serverless function
5299
+ *
5300
+ * @example
5301
+ * ```typescript
5302
+ * const fn = await client.serverless.create({
5303
+ * Name: 'my-api',
5304
+ * Runtime: 'code',
5305
+ * Resources: { CPU: 0.1, MemoryMB: 128, MemoryMaxMB: 128 },
5306
+ * Scaling: { AutoStop: false, Min: 1, Max: 1, MaxIdleTime: 0 },
5307
+ * CodeOpts: { Language: 'nodejs/20', Code: 'module.exports.handler = ...' },
5308
+ * });
5309
+ * ```
5310
+ */
5311
+ async create(params) {
5312
+ return this.apiClient.create(params);
5313
+ }
5314
+ /**
5315
+ * Create a serverless function and poll until it reaches a terminal state.
5316
+ *
5317
+ * Combines `create()` + `pollStatus()` for a simpler workflow.
5318
+ *
5319
+ * @param params - The serverless creation payload
5320
+ * @returns The final serverless state after reaching a terminal status
5321
+ *
5322
+ * @example
5323
+ * ```typescript
5324
+ * const fn = await client.serverless.createAndWait({
5325
+ * Name: 'my-api',
5326
+ * Runtime: 'code',
5327
+ * CodeOpts: { Language: 'nodejs/20', Code: '...' },
5328
+ * Resources: { CPU: 0.1, MemoryMB: 128, MemoryMaxMB: 128 },
5329
+ * Scaling: { AutoStop: false, Min: 1, Max: 1, MaxIdleTime: 0 },
5330
+ * });
5331
+ * ```
5332
+ */
5333
+ async createAndWait(params) {
5334
+ const createResult = await this.apiClient.create(params);
5335
+ if (isErrorResponse(createResult)) {
5336
+ return createResult;
5337
+ }
5338
+ const appId = createResult.data?.ID;
5339
+ if (!appId) {
5340
+ return {
5341
+ error: {
5342
+ code: "SERVERLESS_MISSING_ID",
5343
+ message: "Create API response did not contain an ID",
5344
+ meta: []
5345
+ }
5346
+ };
5347
+ }
5348
+ return this.pollStatus(appId);
5349
+ }
5350
+ /**
5351
+ * Update an existing serverless function.
5352
+ *
5353
+ * @param params - The update parameters (appId + partial payload)
5354
+ * @returns The updated serverless function
5355
+ *
5356
+ * @example
5357
+ * ```typescript
5358
+ * const updated = await client.serverless.update({
5359
+ * appId: 'serverless-id',
5360
+ * payload: { Scaling: { AutoStop: true, Min: 0, Max: 3, MaxIdleTime: 300 } },
5361
+ * });
5362
+ * ```
5363
+ */
5364
+ async update(params) {
5365
+ return this.apiClient.update(params);
5366
+ }
5367
+ /**
5368
+ * Update a serverless function and poll until it reaches a terminal state.
5369
+ *
5370
+ * @param params - The update parameters (appId + partial payload)
5371
+ * @returns The final serverless state after reaching a terminal status
5372
+ */
5373
+ async updateAndWait(params) {
5374
+ const updateResult = await this.apiClient.update(params);
5375
+ if (isErrorResponse(updateResult)) {
5376
+ return updateResult;
5377
+ }
5378
+ return this.pollStatus(params.appId);
5379
+ }
5380
+ /**
5381
+ * List builds for a serverless function.
5382
+ *
5383
+ * @param params - The app ID and optional pagination
5384
+ * @returns List of builds
5385
+ *
5386
+ * @example
5387
+ * ```typescript
5388
+ * const builds = await client.serverless.getBuilds({ appId: 'serverless-id' });
5389
+ * ```
5390
+ */
5391
+ async getBuilds(params) {
5392
+ return this.apiClient.getBuilds(params);
5393
+ }
5394
+ /**
5395
+ * Get runtime logs for a serverless function.
5396
+ *
5397
+ * @param params - The app ID and optional time range / pagination
5398
+ * @returns Log entries
5399
+ *
5400
+ * @example
5401
+ * ```typescript
5402
+ * const logs = await client.serverless.getLogs({ appId: 'serverless-id' });
5403
+ * const recentLogs = await client.serverless.getLogs({
5404
+ * appId: 'serverless-id',
5405
+ * limit: 100,
5406
+ * sortOrder: 'DESC',
5407
+ * });
5408
+ * ```
5409
+ */
5410
+ async getLogs(params) {
5411
+ return this.apiClient.getLogs(params);
5412
+ }
5413
+ /**
5414
+ * Get build logs for a specific build.
5415
+ *
5416
+ * @param params - The app ID and build ID
5417
+ * @returns Build log entries
5418
+ *
5419
+ * @example
5420
+ * ```typescript
5421
+ * const logs = await client.serverless.getBuildLogs({
5422
+ * appId: 'serverless-id',
5423
+ * buildId: 'build-id',
5424
+ * });
5425
+ * ```
5426
+ */
5427
+ async getBuildLogs(params) {
5428
+ return this.apiClient.getBuildLogs(params);
5429
+ }
5430
+ /**
5431
+ * Poll a serverless function until it reaches a terminal status
5432
+ * (running, failed, degraded, or suspended).
5433
+ *
5434
+ * @param appId - The serverless function ID to poll
5435
+ * @param options - Optional polling configuration overrides
5436
+ * @returns The final serverless state or a timeout error
5437
+ *
5438
+ * @example
5439
+ * ```typescript
5440
+ * const result = await client.serverless.pollStatus('serverless-id');
5441
+ * ```
5442
+ */
5443
+ async pollStatus(appId, options = {}) {
5444
+ const interval = options.intervalMs ?? STATUS_POLLING_INTERVAL_MS;
5445
+ const maxAttempts = options.maxAttempts ?? MAX_STATUS_POLLING_ATTEMPTS;
5446
+ const debug = this.client.getConfig().debug;
5447
+ for (let attempt = 0; attempt < maxAttempts; attempt++) {
5448
+ const result = await this.apiClient.get(appId);
5449
+ if (isErrorResponse(result)) {
5450
+ return result;
5451
+ }
5452
+ const status = result.data?.Status;
5453
+ if (debug) {
5454
+ console.log(
5455
+ `[ServerlessResource] Poll #${attempt + 1}: status=${status}`
5456
+ );
5457
+ }
5458
+ if (status && TERMINAL_STATUSES.includes(status)) {
5459
+ if (debug) {
5460
+ console.log(
5461
+ `[ServerlessResource] Reached terminal state: ${status} after ${attempt + 1} poll(s)`
5462
+ );
5463
+ }
5464
+ return result;
5465
+ }
5466
+ await sleep(interval);
5467
+ }
5468
+ return {
5469
+ error: {
5470
+ code: "SERVERLESS_STATUS_TIMEOUT",
5471
+ message: `Serverless ${appId} did not reach a terminal state within ${maxAttempts} polling attempts`,
5472
+ meta: [
5473
+ `app_id: ${appId}`,
5474
+ `max_attempts: ${maxAttempts}`,
5475
+ `interval_ms: ${interval}`
5476
+ ]
5477
+ }
5478
+ };
5479
+ }
5480
+ }
5481
+ class BolticClient {
5482
+ constructor(apiKey, options = {}) {
5483
+ this.currentDatabase = null;
5484
+ this.clientOptions = options;
5485
+ this.configManager = new ConfigManager(
5486
+ apiKey,
5487
+ options.environment || "prod",
5488
+ options.region || "asia-south1",
5489
+ options
5490
+ );
5491
+ const config = this.configManager.getConfig();
5492
+ this.authManager = new AuthManager2({
5493
+ apiKey: config.apiKey,
5494
+ maxRetries: config.maxRetries
5495
+ });
5496
+ this.baseClient = new BaseClient(config, this.authManager);
5497
+ this.tableResource = new TableResource(this.baseClient);
5498
+ this.columnResource = new ColumnResource(this.baseClient);
5499
+ this.recordResource = new RecordResource(this.baseClient);
5500
+ this.sqlResource = new SqlResource(this.baseClient);
5501
+ this.indexResource = new IndexResource(this.baseClient);
5502
+ this.databaseResource = new DatabaseResource(this.baseClient);
5503
+ this.workflowResource = new WorkflowResource(this.baseClient);
5504
+ this.serverlessResource = new ServerlessResource(this.baseClient);
5505
+ this.currentDatabase = null;
5506
+ }
5507
+ /**
5508
+ * Get current database context
5509
+ */
5510
+ getCurrentDatabase() {
5511
+ return this.currentDatabase;
5512
+ }
5513
+ /**
5514
+ * Switch to a different database using its internal name (slug).
5515
+ * All subsequent operations will use this database.
5516
+ *
5517
+ * If no internal name is provided, the SDK will switch back to the default database.
5518
+ *
5519
+ * @param dbInternalName - Database internal name/slug to switch to. If omitted or empty, default DB is used.
5520
+ *
5521
+ * @example
5522
+ * ```typescript
5523
+ * // Switch to a specific database by slug
5524
+ * await client.useDatabase('my_database_slug');
5525
+ *
5526
+ * // Switch back to default database
5527
+ * await client.useDatabase();
5528
+ * ```
5529
+ */
5530
+ async useDatabase(dbInternalName) {
5531
+ console.log(`Database internal name:${dbInternalName}`);
5532
+ if (!dbInternalName || dbInternalName === "") {
5533
+ this.currentDatabase = null;
5534
+ return;
5535
+ }
5536
+ const result = await this.databaseResource.findOne(dbInternalName);
5537
+ console.log(`Result:${JSON.stringify(result, null, 2)}`);
5538
+ if (isErrorResponse(result)) {
5539
+ console.log(`Error:${result.error.message}`);
5540
+ throw new Error(
5541
+ result.error.message || `Failed to switch database to internal name '${dbInternalName}'`
5542
+ );
5543
+ }
5544
+ const db = result.data;
5545
+ this.currentDatabase = {
5546
+ databaseId: db.id,
5547
+ dbInternalName: db.db_internal_name || dbInternalName
5548
+ };
5549
+ }
5550
+ // Direct database operations
4867
5551
  get databases() {
4868
5552
  return {
4869
5553
  create: (data) => this.databaseResource.create(data),
@@ -4972,6 +5656,74 @@ class BolticClient {
4972
5656
  executeSQL: (query) => this.sqlResource.executeSQL(query, dbId)
4973
5657
  };
4974
5658
  }
5659
+ /**
5660
+ * Workflow integration operations.
5661
+ *
5662
+ * @example
5663
+ * ```typescript
5664
+ * // Execute and poll for result
5665
+ * const result = await client.workflow.executeIntegration({
5666
+ * nodes: [{ id: 'api1', data: { ... }, activity_data: { ... } }],
5667
+ * });
5668
+ *
5669
+ * // Get execution result by ID
5670
+ * const exec = await client.workflow.getIntegrationExecuteById('run-uuid');
5671
+ *
5672
+ * // List integrations
5673
+ * const integrations = await client.workflow.getIntegrations();
5674
+ * ```
5675
+ */
5676
+ get workflow() {
5677
+ return {
5678
+ executeIntegration: (params) => this.workflowResource.executeIntegration(params),
5679
+ getIntegrationExecuteById: (executionId) => this.workflowResource.getIntegrationExecuteById(executionId),
5680
+ getIntegrations: (params) => this.workflowResource.getIntegrations(params),
5681
+ getCredentials: (params) => this.workflowResource.getCredentials(params),
5682
+ getIntegrationResource: (params) => this.workflowResource.getIntegrationResource(params),
5683
+ getIntegrationForm: (params) => this.workflowResource.getIntegrationForm(params)
5684
+ };
5685
+ }
5686
+ /**
5687
+ * Serverless function operations.
5688
+ *
5689
+ * @example
5690
+ * ```typescript
5691
+ * // List all serverless functions
5692
+ * const list = await client.serverless.list();
5693
+ *
5694
+ * // Create a new serverless function
5695
+ * const fn = await client.serverless.create({
5696
+ * Name: 'my-api',
5697
+ * Runtime: 'code',
5698
+ * CodeOpts: { Language: 'nodejs/20', Code: '...' },
5699
+ * Resources: { CPU: 0.1, MemoryMB: 128, MemoryMaxMB: 128 },
5700
+ * Scaling: { AutoStop: false, Min: 1, Max: 1, MaxIdleTime: 0 },
5701
+ * });
5702
+ *
5703
+ * // Get a serverless function by ID
5704
+ * const details = await client.serverless.get('serverless-id');
5705
+ *
5706
+ * // Get builds
5707
+ * const builds = await client.serverless.getBuilds({ appId: 'id' });
5708
+ *
5709
+ * // Get runtime logs
5710
+ * const logs = await client.serverless.getLogs({ appId: 'id' });
5711
+ * ```
5712
+ */
5713
+ get serverless() {
5714
+ return {
5715
+ list: (params) => this.serverlessResource.list(params),
5716
+ get: (appId) => this.serverlessResource.get(appId),
5717
+ create: (params) => this.serverlessResource.create(params),
5718
+ createAndWait: (params) => this.serverlessResource.createAndWait(params),
5719
+ update: (params) => this.serverlessResource.update(params),
5720
+ updateAndWait: (params) => this.serverlessResource.updateAndWait(params),
5721
+ getBuilds: (params) => this.serverlessResource.getBuilds(params),
5722
+ getLogs: (params) => this.serverlessResource.getLogs(params),
5723
+ getBuildLogs: (params) => this.serverlessResource.getBuildLogs(params),
5724
+ pollStatus: (appId, options) => this.serverlessResource.pollStatus(appId, options)
5725
+ };
5726
+ }
4975
5727
  // SQL resource access for testing
4976
5728
  getSqlResource() {
4977
5729
  return this.sqlResource;
@@ -5054,6 +5806,8 @@ class BolticClient {
5054
5806
  this.sqlResource = new SqlResource(this.baseClient);
5055
5807
  this.indexResource = new IndexResource(this.baseClient);
5056
5808
  this.databaseResource = new DatabaseResource(this.baseClient);
5809
+ this.workflowResource = new WorkflowResource(this.baseClient);
5810
+ this.serverlessResource = new ServerlessResource(this.baseClient);
5057
5811
  }
5058
5812
  // Security methods to prevent API key exposure
5059
5813
  toString() {
@@ -5081,7 +5835,16 @@ function createClient(apiKey, options = {}) {
5081
5835
  const VERSION = "1.0.0";
5082
5836
  exports.AuthManager = AuthManager$1;
5083
5837
  exports.BolticClient = BolticClient;
5838
+ exports.DEFAULT_RESOURCES = DEFAULT_RESOURCES;
5839
+ exports.DEFAULT_SCALING = DEFAULT_SCALING;
5840
+ exports.MAX_STATUS_POLLING_ATTEMPTS = MAX_STATUS_POLLING_ATTEMPTS;
5841
+ exports.SERVICE_PATHS = SERVICE_PATHS;
5842
+ exports.STATUS_POLLING_INTERVAL_MS = STATUS_POLLING_INTERVAL_MS;
5843
+ exports.ServerlessApiClient = ServerlessApiClient;
5844
+ exports.ServerlessResource = ServerlessResource;
5845
+ exports.TERMINAL_STATUSES = TERMINAL_STATUSES;
5084
5846
  exports.VERSION = VERSION;
5847
+ exports.WorkflowResource = WorkflowResource;
5085
5848
  exports.createClient = createClient;
5086
5849
  exports.createErrorWithContext = createErrorWithContext$1;
5087
5850
  exports.formatError = formatError$1;
@@ -5089,4 +5852,7 @@ exports.getHttpStatusCode = getHttpStatusCode$1;
5089
5852
  exports.isErrorResponse = isErrorResponse;
5090
5853
  exports.isListResponse = isListResponse;
5091
5854
  exports.isNetworkError = isNetworkError;
5855
+ exports.resolveServiceURL = resolveServiceURL;
5856
+ exports.transformFormToDefaults = transformFormToDefaults;
5857
+ exports.transformFormToJsonSchema = transformFormToJsonSchema;
5092
5858
  //# sourceMappingURL=sdk.js.map