@boltic/sdk 0.0.4 → 0.0.6
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/databases/index.d.ts +72 -0
- package/dist/databases/index.js +1 -1
- package/dist/databases/index.js.map +1 -1
- package/dist/databases/index.mjs +5 -5
- package/dist/databases/index.mjs.map +1 -1
- package/dist/databases/test-client-DfOmma3t.js +2 -0
- package/dist/databases/test-client-DfOmma3t.js.map +1 -0
- package/dist/databases/{test-client-BffJwqJq.mjs → test-client-rQ1AmTo6.mjs} +229 -4
- package/dist/databases/test-client-rQ1AmTo6.mjs.map +1 -0
- package/dist/databases/testing.d.ts +68 -0
- package/dist/databases/testing.js +1 -1
- package/dist/databases/testing.mjs +1 -1
- package/dist/sdk.js +299 -6
- package/dist/sdk.js.map +1 -1
- package/dist/sdk.mjs +299 -6
- package/dist/sdk.mjs.map +1 -1
- package/dist/types/index.d.ts +68 -0
- package/package.json +1 -1
- package/dist/databases/test-client-BI3VkYA6.js +0 -2
- package/dist/databases/test-client-BI3VkYA6.js.map +0 -1
- package/dist/databases/test-client-BffJwqJq.mjs.map +0 -1
package/dist/sdk.mjs
CHANGED
|
@@ -257,6 +257,39 @@ class AxiosAdapter {
|
|
|
257
257
|
// Don't throw on non-2xx status codes
|
|
258
258
|
};
|
|
259
259
|
const response = await this.axios(axiosConfig);
|
|
260
|
+
if (response.status < 200 || response.status >= 300) {
|
|
261
|
+
const isHtmlError = typeof response.data === "string" && response.data.trim().startsWith("<!DOCTYPE") || typeof response.data === "string" && response.data.includes("<html");
|
|
262
|
+
if (isHtmlError) {
|
|
263
|
+
const htmlContent = response.data;
|
|
264
|
+
const preMatch = htmlContent.match(/<pre>(.*?)<\/pre>/s);
|
|
265
|
+
const errorMessage = preMatch ? preMatch[1].trim() : `HTTP ${response.status}: ${response.statusText}`;
|
|
266
|
+
throw createErrorWithContext(errorMessage, {
|
|
267
|
+
url: config.url,
|
|
268
|
+
method: config.method,
|
|
269
|
+
status: response.status,
|
|
270
|
+
statusText: response.statusText,
|
|
271
|
+
isHtmlError: true
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
if (response.data && typeof response.data === "object" && "error" in response.data) {
|
|
275
|
+
return {
|
|
276
|
+
data: response.data,
|
|
277
|
+
status: response.status,
|
|
278
|
+
statusText: response.statusText,
|
|
279
|
+
headers: response.headers || {}
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
throw createErrorWithContext(
|
|
283
|
+
`HTTP ${response.status}: ${response.statusText}`,
|
|
284
|
+
{
|
|
285
|
+
url: config.url,
|
|
286
|
+
method: config.method,
|
|
287
|
+
status: response.status,
|
|
288
|
+
statusText: response.statusText,
|
|
289
|
+
responseData: response.data
|
|
290
|
+
}
|
|
291
|
+
);
|
|
292
|
+
}
|
|
260
293
|
return {
|
|
261
294
|
data: response.data,
|
|
262
295
|
status: response.status,
|
|
@@ -355,6 +388,39 @@ class FetchAdapter {
|
|
|
355
388
|
response.headers.forEach((value, key) => {
|
|
356
389
|
headers[key] = value;
|
|
357
390
|
});
|
|
391
|
+
if (response.status < 200 || response.status >= 300) {
|
|
392
|
+
const isHtmlError = typeof data === "string" && (data.trim().startsWith("<!DOCTYPE") || data.includes("<html"));
|
|
393
|
+
if (isHtmlError) {
|
|
394
|
+
const htmlContent = data;
|
|
395
|
+
const preMatch = htmlContent.match(/<pre>(.*?)<\/pre>/s);
|
|
396
|
+
const errorMessage = preMatch ? preMatch[1].trim() : `HTTP ${response.status}: ${response.statusText}`;
|
|
397
|
+
throw createErrorWithContext(errorMessage, {
|
|
398
|
+
url: config.url,
|
|
399
|
+
method: config.method,
|
|
400
|
+
status: response.status,
|
|
401
|
+
statusText: response.statusText,
|
|
402
|
+
isHtmlError: true
|
|
403
|
+
});
|
|
404
|
+
}
|
|
405
|
+
if (data && typeof data === "object" && "error" in data) {
|
|
406
|
+
return {
|
|
407
|
+
data,
|
|
408
|
+
status: response.status,
|
|
409
|
+
statusText: response.statusText,
|
|
410
|
+
headers
|
|
411
|
+
};
|
|
412
|
+
}
|
|
413
|
+
throw createErrorWithContext(
|
|
414
|
+
`HTTP ${response.status}: ${response.statusText}`,
|
|
415
|
+
{
|
|
416
|
+
url: config.url,
|
|
417
|
+
method: config.method,
|
|
418
|
+
status: response.status,
|
|
419
|
+
statusText: response.statusText,
|
|
420
|
+
responseData: data
|
|
421
|
+
}
|
|
422
|
+
);
|
|
423
|
+
}
|
|
358
424
|
const httpResponse = {
|
|
359
425
|
data,
|
|
360
426
|
status: response.status,
|
|
@@ -2296,6 +2362,209 @@ class ColumnResource extends BaseResource {
|
|
|
2296
2362
|
return tableInfo?.id || null;
|
|
2297
2363
|
}
|
|
2298
2364
|
}
|
|
2365
|
+
const INDEX_ENDPOINTS = {
|
|
2366
|
+
create: {
|
|
2367
|
+
path: "/tables/indexes/{table_id}",
|
|
2368
|
+
method: "POST",
|
|
2369
|
+
authenticated: true
|
|
2370
|
+
},
|
|
2371
|
+
list: {
|
|
2372
|
+
path: "/tables/indexes/{table_id}/list",
|
|
2373
|
+
method: "POST",
|
|
2374
|
+
authenticated: true
|
|
2375
|
+
},
|
|
2376
|
+
delete: {
|
|
2377
|
+
path: "/tables/indexes/{table_id}",
|
|
2378
|
+
method: "DELETE",
|
|
2379
|
+
authenticated: true
|
|
2380
|
+
}
|
|
2381
|
+
};
|
|
2382
|
+
const buildIndexEndpointPath = (endpoint, params = {}) => {
|
|
2383
|
+
let path = endpoint.path;
|
|
2384
|
+
Object.entries(params).forEach(([key, value]) => {
|
|
2385
|
+
path = path.replace(`{${key}}`, encodeURIComponent(value));
|
|
2386
|
+
});
|
|
2387
|
+
const unreplacedParams = path.match(/\{([^}]+)\}/g);
|
|
2388
|
+
if (unreplacedParams) {
|
|
2389
|
+
throw new Error(`Missing path parameters: ${unreplacedParams.join(", ")}`);
|
|
2390
|
+
}
|
|
2391
|
+
return path;
|
|
2392
|
+
};
|
|
2393
|
+
class IndexesApiClient {
|
|
2394
|
+
constructor(apiKey, config = {}) {
|
|
2395
|
+
this.config = { apiKey, ...config };
|
|
2396
|
+
this.httpAdapter = createHttpAdapter();
|
|
2397
|
+
const environment = config.environment || "prod";
|
|
2398
|
+
const region = config.region || "asia-south1";
|
|
2399
|
+
this.baseURL = this.getBaseURL(environment, region);
|
|
2400
|
+
}
|
|
2401
|
+
getBaseURL(environment, region) {
|
|
2402
|
+
const regionConfig = REGION_CONFIGS[region];
|
|
2403
|
+
if (!regionConfig) {
|
|
2404
|
+
throw new Error(`Unsupported region: ${region}`);
|
|
2405
|
+
}
|
|
2406
|
+
const envConfig = regionConfig[environment];
|
|
2407
|
+
if (!envConfig) {
|
|
2408
|
+
throw new Error(
|
|
2409
|
+
`Unsupported environment: ${environment} for region: ${region}`
|
|
2410
|
+
);
|
|
2411
|
+
}
|
|
2412
|
+
return `${envConfig.baseURL}/v1`;
|
|
2413
|
+
}
|
|
2414
|
+
async addIndex(tableId, request) {
|
|
2415
|
+
try {
|
|
2416
|
+
const endpoint = INDEX_ENDPOINTS.create;
|
|
2417
|
+
const url = `${this.baseURL}${buildIndexEndpointPath(endpoint, { table_id: tableId })}`;
|
|
2418
|
+
const response = await this.httpAdapter.request({
|
|
2419
|
+
url,
|
|
2420
|
+
method: endpoint.method,
|
|
2421
|
+
headers: this.buildHeaders(),
|
|
2422
|
+
data: request,
|
|
2423
|
+
timeout: this.config.timeout
|
|
2424
|
+
});
|
|
2425
|
+
return response.data;
|
|
2426
|
+
} catch (error) {
|
|
2427
|
+
return this.formatErrorResponse(error);
|
|
2428
|
+
}
|
|
2429
|
+
}
|
|
2430
|
+
async listIndexes(tableId, query) {
|
|
2431
|
+
try {
|
|
2432
|
+
const endpoint = INDEX_ENDPOINTS.list;
|
|
2433
|
+
const url = `${this.baseURL}${buildIndexEndpointPath(endpoint, { table_id: tableId })}`;
|
|
2434
|
+
const response = await this.httpAdapter.request({
|
|
2435
|
+
url,
|
|
2436
|
+
method: endpoint.method,
|
|
2437
|
+
headers: this.buildHeaders(),
|
|
2438
|
+
data: query,
|
|
2439
|
+
timeout: this.config.timeout
|
|
2440
|
+
});
|
|
2441
|
+
return response.data;
|
|
2442
|
+
} catch (error) {
|
|
2443
|
+
return this.formatErrorResponse(error);
|
|
2444
|
+
}
|
|
2445
|
+
}
|
|
2446
|
+
async deleteIndex(tableId, request) {
|
|
2447
|
+
try {
|
|
2448
|
+
const endpoint = INDEX_ENDPOINTS.delete;
|
|
2449
|
+
const url = `${this.baseURL}${buildIndexEndpointPath(endpoint, { table_id: tableId })}`;
|
|
2450
|
+
const response = await this.httpAdapter.request({
|
|
2451
|
+
url,
|
|
2452
|
+
method: endpoint.method,
|
|
2453
|
+
headers: this.buildHeaders(),
|
|
2454
|
+
data: request,
|
|
2455
|
+
timeout: this.config.timeout
|
|
2456
|
+
});
|
|
2457
|
+
return response.data;
|
|
2458
|
+
} catch (error) {
|
|
2459
|
+
return this.formatErrorResponse(error);
|
|
2460
|
+
}
|
|
2461
|
+
}
|
|
2462
|
+
buildHeaders() {
|
|
2463
|
+
return {
|
|
2464
|
+
"Content-Type": "application/json",
|
|
2465
|
+
Accept: "application/json",
|
|
2466
|
+
"x-boltic-token": this.config.apiKey
|
|
2467
|
+
};
|
|
2468
|
+
}
|
|
2469
|
+
formatErrorResponse(error) {
|
|
2470
|
+
if (this.config.debug) {
|
|
2471
|
+
console.error("Indexes API Error:", error);
|
|
2472
|
+
}
|
|
2473
|
+
if (error && typeof error === "object" && "response" in error) {
|
|
2474
|
+
const apiError = error;
|
|
2475
|
+
if (apiError.response?.data?.error) {
|
|
2476
|
+
return apiError.response.data;
|
|
2477
|
+
}
|
|
2478
|
+
return {
|
|
2479
|
+
error: {
|
|
2480
|
+
code: "API_ERROR",
|
|
2481
|
+
message: error.message || "Unknown API error",
|
|
2482
|
+
meta: [`Status: ${apiError.response?.status || "unknown"}`]
|
|
2483
|
+
}
|
|
2484
|
+
};
|
|
2485
|
+
}
|
|
2486
|
+
if (error && typeof error === "object" && "message" in error) {
|
|
2487
|
+
return {
|
|
2488
|
+
error: {
|
|
2489
|
+
code: "CLIENT_ERROR",
|
|
2490
|
+
message: error.message,
|
|
2491
|
+
meta: ["Client-side error occurred"]
|
|
2492
|
+
}
|
|
2493
|
+
};
|
|
2494
|
+
}
|
|
2495
|
+
return {
|
|
2496
|
+
error: {
|
|
2497
|
+
code: "UNKNOWN_ERROR",
|
|
2498
|
+
message: "An unexpected error occurred",
|
|
2499
|
+
meta: ["Unknown error type"]
|
|
2500
|
+
}
|
|
2501
|
+
};
|
|
2502
|
+
}
|
|
2503
|
+
}
|
|
2504
|
+
class IndexResource {
|
|
2505
|
+
constructor(client) {
|
|
2506
|
+
this.client = client;
|
|
2507
|
+
const config = client.getConfig();
|
|
2508
|
+
this.apiClient = new IndexesApiClient(config.apiKey, {
|
|
2509
|
+
environment: config.environment,
|
|
2510
|
+
region: config.region,
|
|
2511
|
+
timeout: config.timeout,
|
|
2512
|
+
debug: config.debug,
|
|
2513
|
+
retryAttempts: config.retryAttempts,
|
|
2514
|
+
retryDelay: config.retryDelay,
|
|
2515
|
+
headers: config.headers
|
|
2516
|
+
});
|
|
2517
|
+
this.tableResource = new TableResource(client);
|
|
2518
|
+
}
|
|
2519
|
+
async resolveTableId(tableName) {
|
|
2520
|
+
const tableResult = await this.tableResource.findByName(tableName);
|
|
2521
|
+
if (!tableResult.data) throw new Error(`Table not found: ${tableName}`);
|
|
2522
|
+
return tableResult.data.id;
|
|
2523
|
+
}
|
|
2524
|
+
async addIndex(tableName, request) {
|
|
2525
|
+
try {
|
|
2526
|
+
const tableId = await this.resolveTableId(tableName);
|
|
2527
|
+
return await this.apiClient.addIndex(tableId, request);
|
|
2528
|
+
} catch (error) {
|
|
2529
|
+
return {
|
|
2530
|
+
error: {
|
|
2531
|
+
code: "CLIENT_ERROR",
|
|
2532
|
+
message: error?.message || "Failed to add index",
|
|
2533
|
+
meta: ["IndexResource.addIndex"]
|
|
2534
|
+
}
|
|
2535
|
+
};
|
|
2536
|
+
}
|
|
2537
|
+
}
|
|
2538
|
+
async listIndexes(tableName, query) {
|
|
2539
|
+
try {
|
|
2540
|
+
const tableId = await this.resolveTableId(tableName);
|
|
2541
|
+
return await this.apiClient.listIndexes(tableId, query);
|
|
2542
|
+
} catch (error) {
|
|
2543
|
+
return {
|
|
2544
|
+
error: {
|
|
2545
|
+
code: "CLIENT_ERROR",
|
|
2546
|
+
message: error?.message || "Failed to list indexes",
|
|
2547
|
+
meta: ["IndexResource.listIndexes"]
|
|
2548
|
+
}
|
|
2549
|
+
};
|
|
2550
|
+
}
|
|
2551
|
+
}
|
|
2552
|
+
async deleteIndex(tableName, indexName) {
|
|
2553
|
+
try {
|
|
2554
|
+
const tableId = await this.resolveTableId(tableName);
|
|
2555
|
+
const request = { index_name: indexName };
|
|
2556
|
+
return await this.apiClient.deleteIndex(tableId, request);
|
|
2557
|
+
} catch (error) {
|
|
2558
|
+
return {
|
|
2559
|
+
error: {
|
|
2560
|
+
code: "CLIENT_ERROR",
|
|
2561
|
+
message: error?.message || "Failed to delete index",
|
|
2562
|
+
meta: ["IndexResource.deleteIndex"]
|
|
2563
|
+
}
|
|
2564
|
+
};
|
|
2565
|
+
}
|
|
2566
|
+
}
|
|
2567
|
+
}
|
|
2299
2568
|
const RECORD_ENDPOINTS = {
|
|
2300
2569
|
insert: {
|
|
2301
2570
|
path: "/tables/{table_id}/records",
|
|
@@ -2320,8 +2589,8 @@ const RECORD_ENDPOINTS = {
|
|
|
2320
2589
|
rateLimit: { requests: 200, window: 6e4 }
|
|
2321
2590
|
},
|
|
2322
2591
|
update: {
|
|
2323
|
-
path: "/tables/{table_id}/records",
|
|
2324
|
-
method: "
|
|
2592
|
+
path: "/tables/{table_id}/records/bulk-update",
|
|
2593
|
+
method: "PUT",
|
|
2325
2594
|
authenticated: true
|
|
2326
2595
|
},
|
|
2327
2596
|
updateById: {
|
|
@@ -2526,26 +2795,34 @@ class RecordsApiClient {
|
|
|
2526
2795
|
*/
|
|
2527
2796
|
async updateRecords(request) {
|
|
2528
2797
|
try {
|
|
2529
|
-
const { table_id, ...
|
|
2798
|
+
const { table_id, set, filters, fields, ...rest } = request;
|
|
2530
2799
|
if (!table_id) {
|
|
2531
2800
|
return this.formatErrorResponse(
|
|
2532
2801
|
new Error("table_id is required for update operation")
|
|
2533
2802
|
);
|
|
2534
2803
|
}
|
|
2804
|
+
const apiPayload = {
|
|
2805
|
+
updates: set,
|
|
2806
|
+
filters,
|
|
2807
|
+
...rest
|
|
2808
|
+
};
|
|
2809
|
+
if (fields) {
|
|
2810
|
+
apiPayload.fields = fields;
|
|
2811
|
+
}
|
|
2535
2812
|
const endpoint = RECORD_ENDPOINTS.update;
|
|
2536
2813
|
const url = `${this.baseURL}${buildRecordEndpointPath(endpoint, { table_id })}`;
|
|
2537
2814
|
const response = await this.httpAdapter.request({
|
|
2538
2815
|
url,
|
|
2539
2816
|
method: endpoint.method,
|
|
2540
2817
|
headers: this.buildHeaders(),
|
|
2541
|
-
data:
|
|
2818
|
+
data: apiPayload,
|
|
2542
2819
|
timeout: this.config.timeout
|
|
2543
2820
|
});
|
|
2544
2821
|
const responseData = response.data;
|
|
2545
|
-
if (
|
|
2822
|
+
if (fields && responseData.data) {
|
|
2546
2823
|
responseData.data = filterArrayFields(
|
|
2547
2824
|
responseData.data,
|
|
2548
|
-
|
|
2825
|
+
fields
|
|
2549
2826
|
);
|
|
2550
2827
|
}
|
|
2551
2828
|
return responseData;
|
|
@@ -3762,6 +4039,7 @@ class BolticClient {
|
|
|
3762
4039
|
this.columnResource = new ColumnResource(this.baseClient);
|
|
3763
4040
|
this.recordResource = new RecordResource(this.baseClient);
|
|
3764
4041
|
this.sqlResource = new SqlResource(this.baseClient);
|
|
4042
|
+
this.indexResource = new IndexResource(this.baseClient);
|
|
3765
4043
|
this.currentDatabase = {
|
|
3766
4044
|
databaseName: "Default"
|
|
3767
4045
|
};
|
|
@@ -3795,6 +4073,14 @@ class BolticClient {
|
|
|
3795
4073
|
delete: (tableName, columnName) => this.columnResource.delete(tableName, columnName)
|
|
3796
4074
|
};
|
|
3797
4075
|
}
|
|
4076
|
+
// Direct index operations
|
|
4077
|
+
get indexes() {
|
|
4078
|
+
return {
|
|
4079
|
+
addIndex: (tableName, payload) => this.indexResource.addIndex(tableName, payload),
|
|
4080
|
+
listIndexes: (tableName, query) => this.indexResource.listIndexes(tableName, query),
|
|
4081
|
+
deleteIndex: (tableName, indexName) => this.indexResource.deleteIndex(tableName, indexName)
|
|
4082
|
+
};
|
|
4083
|
+
}
|
|
3798
4084
|
// Fluent table operations
|
|
3799
4085
|
table(name) {
|
|
3800
4086
|
const tableBuilder = createTableBuilder({ name });
|
|
@@ -3827,6 +4113,12 @@ class BolticClient {
|
|
|
3827
4113
|
record: () => createRecordBuilder({
|
|
3828
4114
|
tableName,
|
|
3829
4115
|
recordResource: this.recordResource
|
|
4116
|
+
}),
|
|
4117
|
+
// Indexes - Method 2: Function chaining under from(tableName)
|
|
4118
|
+
indexes: () => ({
|
|
4119
|
+
addIndex: (payload) => this.indexResource.addIndex(tableName, payload),
|
|
4120
|
+
listIndexes: (query) => this.indexResource.listIndexes(tableName, query),
|
|
4121
|
+
deleteIndex: (indexName) => this.indexResource.deleteIndex(tableName, indexName)
|
|
3830
4122
|
})
|
|
3831
4123
|
};
|
|
3832
4124
|
}
|
|
@@ -3937,6 +4229,7 @@ class BolticClient {
|
|
|
3937
4229
|
this.columnResource = new ColumnResource(this.baseClient);
|
|
3938
4230
|
this.recordResource = new RecordResource(this.baseClient);
|
|
3939
4231
|
this.sqlResource = new SqlResource(this.baseClient);
|
|
4232
|
+
this.indexResource = new IndexResource(this.baseClient);
|
|
3940
4233
|
}
|
|
3941
4234
|
// Security methods to prevent API key exposure
|
|
3942
4235
|
toString() {
|