@boltic/sdk 0.1.3 → 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
@@ -549,7 +549,8 @@ class AuthManager2 {
549
549
  const SERVICE_PATHS = {
550
550
  DATABASES: "/service/sdk/boltic-tables/v1",
551
551
  WORKFLOW_TEMPORAL: "/service/panel/temporal/v1.0",
552
- INTEGRATION: "/service/panel/integration/v1"
552
+ INTEGRATION: "/service/panel/integration/v1",
553
+ SERVERLESS: "/service/panel/serverless/v1.0"
553
554
  };
554
555
  class BaseApiClient {
555
556
  constructor(apiKey, config = {}, servicePath = SERVICE_PATHS.DATABASES) {
@@ -4786,7 +4787,7 @@ function buildExecuteActivityBody(params) {
4786
4787
  result: params.result ?? buildDefaultResultPayload()
4787
4788
  };
4788
4789
  }
4789
- function sleep(ms) {
4790
+ function sleep$1(ms) {
4790
4791
  return new Promise((resolve) => setTimeout(resolve, ms));
4791
4792
  }
4792
4793
  class WorkflowResource extends BaseResource {
@@ -4984,7 +4985,7 @@ class WorkflowResource extends BaseResource {
4984
4985
  }
4985
4986
  return result;
4986
4987
  }
4987
- await sleep(POLLING_INTERVAL_MS);
4988
+ await sleep$1(POLLING_INTERVAL_MS);
4988
4989
  }
4989
4990
  return {
4990
4991
  error: {
@@ -4998,6 +4999,485 @@ class WorkflowResource extends BaseResource {
4998
4999
  };
4999
5000
  }
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
+ }
5001
5481
  class BolticClient {
5002
5482
  constructor(apiKey, options = {}) {
5003
5483
  this.currentDatabase = null;
@@ -5021,6 +5501,7 @@ class BolticClient {
5021
5501
  this.indexResource = new IndexResource(this.baseClient);
5022
5502
  this.databaseResource = new DatabaseResource(this.baseClient);
5023
5503
  this.workflowResource = new WorkflowResource(this.baseClient);
5504
+ this.serverlessResource = new ServerlessResource(this.baseClient);
5024
5505
  this.currentDatabase = null;
5025
5506
  }
5026
5507
  /**
@@ -5202,6 +5683,47 @@ class BolticClient {
5202
5683
  getIntegrationForm: (params) => this.workflowResource.getIntegrationForm(params)
5203
5684
  };
5204
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
+ }
5205
5727
  // SQL resource access for testing
5206
5728
  getSqlResource() {
5207
5729
  return this.sqlResource;
@@ -5285,6 +5807,7 @@ class BolticClient {
5285
5807
  this.indexResource = new IndexResource(this.baseClient);
5286
5808
  this.databaseResource = new DatabaseResource(this.baseClient);
5287
5809
  this.workflowResource = new WorkflowResource(this.baseClient);
5810
+ this.serverlessResource = new ServerlessResource(this.baseClient);
5288
5811
  }
5289
5812
  // Security methods to prevent API key exposure
5290
5813
  toString() {
@@ -5312,7 +5835,14 @@ function createClient(apiKey, options = {}) {
5312
5835
  const VERSION = "1.0.0";
5313
5836
  exports.AuthManager = AuthManager$1;
5314
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;
5315
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;
5316
5846
  exports.VERSION = VERSION;
5317
5847
  exports.WorkflowResource = WorkflowResource;
5318
5848
  exports.createClient = createClient;