@boltic/sdk 0.1.3 → 0.1.5

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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-client-DzMli6cH.js","sources":["../../common/types/environment.ts","../../common/types/responses.ts","../../common/errors/utils.ts","../../common/http/binary-response-body.ts","../../common/http/axios-adapter.ts","../../common/http/fetch-adapter.ts","../../common/http/client-factory.ts","../../common/client/auth-manager.ts","../../common/client/base-api-client.ts","../../common/client/interceptors.ts","../../common/client/base-client.ts","../../common/client/base-resource.ts","../../common/client/config.ts","../src/utils/common/index.ts","../src/utils/database/db-context.ts","../src/api/endpoints/columns.ts","../src/types/api/column.ts","../src/api/transformers/columns.ts","../src/api/clients/columns-api-client.ts","../src/api/endpoints/tables.ts","../src/utils/filters/filter-mapper.ts","../src/api/transformers/tables.ts","../src/api/clients/tables-api-client.ts","../src/client/resources/table.ts","../src/client/resources/column.ts","../src/api/endpoints/databases.ts","../src/api/clients/databases-api-client.ts","../src/client/resources/database.ts","../src/api/endpoints/indexes.ts","../src/api/clients/indexes-api-client.ts","../src/client/resources/indexes.ts","../src/api/endpoints/records.ts","../src/api/clients/records-api-client.ts","../src/api/transformers/records.ts","../src/client/resources/record.ts","../src/client/resources/record-builder.ts","../src/api/endpoints/sql.ts","../src/api/clients/sql-api-client.ts","../src/client/resources/sql.ts","../src/api/transformers/sql.ts","../src/client/resources/table-builder.ts","../../workflows/src/constants.ts","../../workflows/src/api/endpoints/workflows.ts","../../workflows/src/api/clients/workflow-api-client.ts","../../workflows/src/utils/form-transformer.ts","../../workflows/src/client/resources/workflow.ts","../../serverless/src/constants.ts","../../serverless/src/api/endpoints/serverless.ts","../../serverless/src/api/clients/serverless-api-client.ts","../../serverless/src/client/resources/serverless.ts","../../storage/src/constants.ts","../../storage/src/api/endpoints/storage.ts","../../storage/src/api/clients/storage-api-client.ts","../../storage/src/client/resources/storage.ts","../src/client/boltic-client.ts","../src/testing/test-client.ts"],"sourcesContent":["export type Region = 'asia-south1' | 'us-central1';\nexport type Environment = 'local' | 'sit' | 'uat' | 'prod';\n\nexport interface EnvironmentConfig {\n baseURL: string;\n timeout: number;\n retryAttempts?: number;\n debug?: boolean;\n}\n\nexport const REGION_CONFIGS: Record<\n Region,\n Record<Environment, EnvironmentConfig>\n> = {\n 'asia-south1': {\n local: {\n baseURL: 'http://localhost:8000',\n timeout: 30000,\n debug: true,\n },\n sit: {\n baseURL: 'https://asia-south1.api.fcz0.de/service/sdk/boltic-tables',\n timeout: 15000,\n },\n uat: {\n baseURL: 'https://asia-south1.api.uat.fcz0.de/service/sdk/boltic-tables',\n timeout: 15000,\n },\n prod: {\n baseURL: 'https://asia-south1.api.boltic.io/service/sdk/boltic-tables',\n timeout: 10000,\n },\n },\n 'us-central1': {\n local: {\n baseURL: 'http://localhost:8000',\n timeout: 30000,\n debug: true,\n },\n sit: {\n baseURL: 'https://us-central1.api.fcz0.de/service/sdk/boltic-tables',\n timeout: 15000,\n },\n uat: {\n baseURL: 'https://us-central1.api.uat.fcz0.de/service/sdk/boltic-tables',\n timeout: 15000,\n },\n prod: {\n baseURL: 'https://us-central1.api.boltic.io/service/sdk/boltic-tables',\n timeout: 10000,\n },\n },\n};\n\nexport const ENV_CONFIGS: Record<Environment, EnvironmentConfig> =\n REGION_CONFIGS['asia-south1'];\n\nexport interface RegionHostConfig {\n host: string;\n timeout: number;\n debug?: boolean;\n}\n\nexport const REGION_BASE_HOSTS: Record<\n Region,\n Record<Environment, RegionHostConfig>\n> = {\n 'asia-south1': {\n local: { host: 'http://localhost:8000', timeout: 30000, debug: true },\n sit: { host: 'https://asia-south1.api.fcz0.de', timeout: 15000 },\n uat: { host: 'https://asia-south1.api.uat.fcz0.de', timeout: 15000 },\n prod: { host: 'https://asia-south1.api.boltic.io', timeout: 10000 },\n },\n 'us-central1': {\n local: { host: 'http://localhost:8000', timeout: 30000, debug: true },\n sit: { host: 'https://us-central1.api.fcz0.de', timeout: 15000 },\n uat: { host: 'https://us-central1.api.uat.fcz0.de', timeout: 15000 },\n prod: { host: 'https://us-central1.api.boltic.io', timeout: 10000 },\n },\n};\n\n/**\n * Resolve a full service URL from region, environment, and service path.\n */\nexport function resolveServiceURL(\n region: Region,\n environment: Environment,\n servicePath: string\n): string {\n const regionConfig = REGION_BASE_HOSTS[region];\n if (!regionConfig) {\n throw new Error(`Unsupported region: ${region}`);\n }\n\n const envConfig = regionConfig[environment];\n if (!envConfig) {\n throw new Error(\n `Unsupported environment: ${environment} for region: ${region}`\n );\n }\n\n return `${envConfig.host}${servicePath}`;\n}\n","import { PaginationInfo } from './operations';\n\nexport interface BolticSuccessResponse<T> {\n data: T;\n message?: string;\n error?: {\n code?: string;\n message?: string;\n meta?: string[];\n };\n}\n\nexport interface BolticListResponse<T> {\n data: T[];\n pagination?: {\n total_count: number;\n total_pages: number;\n current_page: number;\n per_page: number;\n type: string;\n };\n message?: string;\n error?: {\n code?: string;\n message?: string;\n meta?: string[];\n };\n}\n\nexport interface BolticErrorResponse {\n data?: never;\n message?: string;\n error: {\n code?: string;\n message?: string;\n meta?: string[];\n };\n}\n\nexport type ApiResponse<T> =\n | BolticSuccessResponse<T>\n | BolticListResponse<T>\n | BolticErrorResponse;\n\nexport function isErrorResponse<T>(\n response: ApiResponse<T>\n): response is BolticErrorResponse {\n return 'error' in response && response.error !== undefined;\n}\n\nexport function isListResponse<T>(\n response: ApiResponse<T>\n): response is BolticListResponse<T> {\n return 'pagination' in response;\n}\n\n// Legacy interfaces for backwards compatibility\nexport interface SuccessResponse<T> {\n data: T;\n error?: never;\n pagination?: PaginationInfo;\n}\n\nexport interface ErrorResponse {\n data?: never;\n error: string;\n details?: unknown;\n code?: string;\n}\n\nexport interface BulkResponse<T> {\n success: T[];\n failed: Array<{\n item: unknown;\n error: string;\n }>;\n summary: {\n total: number;\n successful: number;\n failed: number;\n };\n}\n\nexport interface QueryOptions {\n fields?: string[];\n sort?: Array<{ field: string; order: 'asc' | 'desc' }>;\n limit?: number;\n offset?: number;\n where?: Record<string, unknown>;\n}\n","export interface ValidationFailure {\n field: string;\n message: string;\n}\n\nexport class ValidationError extends Error {\n public readonly failures: ValidationFailure[];\n\n constructor(message: string, failures: ValidationFailure[] = []) {\n super(message);\n this.name = 'ValidationError';\n this.failures = failures;\n }\n}\n\nexport class ApiError extends Error {\n public readonly statusCode: number;\n public readonly response?: unknown;\n\n constructor(message: string, statusCode: number, response?: unknown) {\n super(message);\n this.name = 'ApiError';\n this.statusCode = statusCode;\n this.response = response;\n }\n}\n\nexport function createErrorWithContext(\n message: string,\n context?: Record<string, unknown>\n): Error {\n const error = new Error(message);\n if (context) {\n (error as Error & { context: Record<string, unknown> }).context = context;\n }\n return error;\n}\n\nexport function isNetworkError(error: unknown): error is Error {\n return (\n error instanceof Error &&\n (error.message.includes('network') ||\n error.message.includes('fetch') ||\n error.message.includes('timeout') ||\n error.name === 'AbortError')\n );\n}\n\nexport function getHttpStatusCode(error: unknown): number | null {\n if (error && typeof error === 'object') {\n if (\n 'response' in error &&\n error.response &&\n typeof error.response === 'object'\n ) {\n const response = error.response as { status?: unknown };\n if ('status' in response && typeof response.status === 'number') {\n return response.status;\n }\n }\n if (\n 'status' in error &&\n typeof (error as { status: unknown }).status === 'number'\n ) {\n return (error as { status: number }).status;\n }\n }\n return null;\n}\n\nexport function formatError(error: unknown): string {\n if (error instanceof Error) {\n const context = (error as Error & { context?: Record<string, unknown> })\n .context;\n const statusCode = getHttpStatusCode(error);\n\n let formatted = `${error.name}: ${error.message}`;\n\n if (statusCode) {\n formatted += ` (HTTP ${statusCode})`;\n }\n\n if (context) {\n formatted += `\\nContext: ${JSON.stringify(context, null, 2)}`;\n }\n\n return formatted;\n }\n\n return String(error);\n}\n","/**\n * Helpers for `HttpRequestConfig.responseType === 'arraybuffer'` only.\n * Other SDK services use the default JSON/text parsing — they never set `responseType`.\n */\n\n/** Decode an error response body that was read as ArrayBuffer (try JSON, else UTF-8 text). */\nexport function decodeArrayBufferErrorBody(buffer: ArrayBuffer): unknown {\n const txt = new TextDecoder().decode(buffer);\n try {\n return JSON.parse(txt) as unknown;\n } catch {\n return txt;\n }\n}\n","import { createErrorWithContext } from '../errors';\nimport { HttpAdapter, HttpRequestConfig, HttpResponse } from './adapter';\nimport { decodeArrayBufferErrorBody } from './binary-response-body';\n\ninterface AxiosInstance {\n (config: unknown): Promise<{\n data: unknown;\n status: number;\n statusText: string;\n headers: Record<string, string>;\n }>;\n}\n\n/**\n * When `responseType === 'arraybuffer'` and the server returns an error, axios gives\n * an ArrayBuffer body that may actually be JSON — decode for the same error handling\n * as other services. Success binary responses are left as ArrayBuffer.\n */\nfunction normalizeAxiosDataAfterResponse(\n config: HttpRequestConfig,\n status: number,\n data: unknown\n): unknown {\n if (\n config.responseType !== 'arraybuffer' ||\n !(data instanceof ArrayBuffer) ||\n status < 400\n ) {\n return data;\n }\n return decodeArrayBufferErrorBody(data);\n}\n\nexport class AxiosAdapter implements HttpAdapter {\n private axios: AxiosInstance;\n\n constructor() {\n try {\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n this.axios = require('axios');\n } catch (error) {\n throw createErrorWithContext(\n 'Axios is required for Node.js < 18. Please install axios: npm install axios',\n { error }\n );\n }\n }\n\n async request<T = unknown>(\n config: HttpRequestConfig\n ): Promise<HttpResponse<T>> {\n try {\n const isFormData =\n typeof FormData !== 'undefined' && config.data instanceof FormData;\n let headers = config.headers;\n if (isFormData && headers) {\n headers = { ...headers };\n delete headers['Content-Type'];\n delete headers['content-type'];\n }\n\n const axiosConfig: Record<string, unknown> = {\n url: config.url,\n method: config.method.toLowerCase(),\n headers,\n params: config.params,\n data: config.data,\n timeout: config.timeout,\n signal: config.signal,\n validateStatus: () => true,\n };\n if (config.responseType === 'arraybuffer') {\n axiosConfig.responseType = 'arraybuffer';\n }\n\n const response = await this.axios(axiosConfig);\n\n const responseData = normalizeAxiosDataAfterResponse(\n config,\n response.status,\n response.data\n );\n\n if (response.status < 200 || response.status >= 300) {\n const isHtmlError =\n (typeof responseData === 'string' &&\n responseData.trim().startsWith('<!DOCTYPE')) ||\n (typeof responseData === 'string' && responseData.includes('<html'));\n\n if (isHtmlError) {\n const htmlContent = responseData as string;\n const preMatch = htmlContent.match(/<pre>(.*?)<\\/pre>/s);\n const errorMessage = preMatch\n ? preMatch[1].trim()\n : `HTTP ${response.status}: ${response.statusText}`;\n\n throw createErrorWithContext(errorMessage, {\n url: config.url,\n method: config.method,\n status: response.status,\n statusText: response.statusText,\n isHtmlError: true,\n });\n }\n\n if (\n responseData &&\n typeof responseData === 'object' &&\n 'error' in (responseData as object)\n ) {\n return {\n data: responseData as T,\n status: response.status,\n statusText: response.statusText,\n headers: response.headers || {},\n };\n }\n\n throw createErrorWithContext(\n `HTTP ${response.status}: ${response.statusText}`,\n {\n url: config.url,\n method: config.method,\n status: response.status,\n statusText: response.statusText,\n responseData,\n }\n );\n }\n\n return {\n data: responseData as T,\n status: response.status,\n statusText: response.statusText,\n headers: response.headers || {},\n };\n } catch (error: unknown) {\n const axiosError = error as {\n code?: string;\n message?: string;\n name?: string;\n };\n\n if (\n axiosError.code === 'ECONNABORTED' ||\n axiosError.message?.includes('timeout')\n ) {\n throw createErrorWithContext('Request timeout', {\n url: config.url,\n method: config.method,\n timeout: config.timeout,\n });\n }\n\n if (\n axiosError.code === 'ERR_NETWORK' ||\n axiosError.code === 'ENOTFOUND' ||\n axiosError.code === 'ECONNREFUSED' ||\n axiosError.code === 'EHOSTUNREACH' ||\n axiosError.code === 'ETIMEDOUT' ||\n axiosError.code === 'ERR_INTERNET_DISCONNECTED' ||\n axiosError.message?.includes('network') ||\n axiosError.message?.includes('internet') ||\n axiosError.message?.includes('connection') ||\n axiosError.message?.includes('resolve')\n ) {\n throw createErrorWithContext(\n 'Network connection failed. Please check your internet connection or VPN settings.',\n {\n url: config.url,\n method: config.method,\n networkError: true,\n errorCode: axiosError.code,\n originalMessage: axiosError.message,\n }\n );\n }\n\n if (\n axiosError.name === 'AbortError' ||\n axiosError.code === 'ERR_CANCELED'\n ) {\n throw createErrorWithContext('Request was aborted', {\n url: config.url,\n method: config.method,\n });\n }\n\n throw createErrorWithContext(\n `HTTP request failed: ${axiosError.message || 'Unknown error'}`,\n {\n url: config.url,\n method: config.method,\n originalError: error,\n }\n );\n }\n }\n}\n","import { createErrorWithContext } from '../errors';\nimport { HttpAdapter, HttpRequestConfig, HttpResponse } from './adapter';\nimport { decodeArrayBufferErrorBody } from './binary-response-body';\n\n/**\n * Default response parsing for JSON APIs (all services except opt-in binary downloads).\n */\nasync function parseFetchBodyDefault(response: Response): Promise<unknown> {\n const contentType = response.headers.get('content-type');\n if (contentType?.includes('application/json')) {\n return response.json();\n }\n return response.text();\n}\n\n/**\n * ArrayBuffer path — only when `config.responseType === 'arraybuffer'` (e.g. storage download).\n */\nasync function parseFetchBodyArrayBuffer(response: Response): Promise<unknown> {\n const buf = await response.arrayBuffer();\n if (response.status >= 400) {\n return decodeArrayBufferErrorBody(buf);\n }\n return buf;\n}\n\nasync function parseFetchResponseData(\n response: Response,\n config: HttpRequestConfig\n): Promise<unknown> {\n if (config.responseType === 'arraybuffer') {\n return parseFetchBodyArrayBuffer(response);\n }\n return parseFetchBodyDefault(response);\n}\n\nexport class FetchAdapter implements HttpAdapter {\n async request<T = unknown>(\n config: HttpRequestConfig\n ): Promise<HttpResponse<T>> {\n const url = new URL(config.url);\n\n if (config.params) {\n Object.entries(config.params).forEach(([key, value]) => {\n if (value !== undefined && value !== null) {\n url.searchParams.append(key, String(value));\n }\n });\n }\n\n const isFormData =\n typeof FormData !== 'undefined' && config.data instanceof FormData;\n\n const headerMap: Record<string, string> = { ...(config.headers || {}) };\n if (!isFormData) {\n headerMap['Content-Type'] =\n headerMap['Content-Type'] ??\n headerMap['content-type'] ??\n 'application/json';\n } else {\n delete headerMap['Content-Type'];\n delete headerMap['content-type'];\n }\n\n const init: RequestInit = {\n method: config.method,\n headers: headerMap,\n signal: config.signal,\n };\n\n if (\n config.data &&\n ['POST', 'PUT', 'PATCH', 'DELETE'].includes(config.method)\n ) {\n init.body = isFormData\n ? (config.data as FormData)\n : JSON.stringify(config.data);\n }\n\n try {\n const controller = new AbortController();\n let timeoutId: ReturnType<typeof setTimeout> | undefined;\n\n if (config.timeout) {\n timeoutId = setTimeout(() => controller.abort(), config.timeout);\n init.signal = config.signal\n ? (() => {\n const combinedController = new AbortController();\n config.signal.addEventListener('abort', () =>\n combinedController.abort()\n );\n controller.signal.addEventListener('abort', () =>\n combinedController.abort()\n );\n return combinedController.signal;\n })()\n : controller.signal;\n }\n\n const response = await fetch(url.toString(), init);\n\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n\n const data = (await parseFetchResponseData(\n response,\n config\n )) as T;\n\n const headers: Record<string, string> = {};\n response.headers.forEach((value, key) => {\n headers[key] = value;\n });\n\n if (response.status < 200 || response.status >= 300) {\n const isHtmlError =\n typeof data === 'string' &&\n (data.trim().startsWith('<!DOCTYPE') || data.includes('<html'));\n\n if (isHtmlError) {\n const htmlContent = data as string;\n const preMatch = htmlContent.match(/<pre>(.*?)<\\/pre>/s);\n const errorMessage = preMatch\n ? preMatch[1].trim()\n : `HTTP ${response.status}: ${response.statusText}`;\n\n throw createErrorWithContext(errorMessage, {\n url: config.url,\n method: config.method,\n status: response.status,\n statusText: response.statusText,\n isHtmlError: true,\n });\n }\n\n if (data && typeof data === 'object' && 'error' in data) {\n return {\n data,\n status: response.status,\n statusText: response.statusText,\n headers,\n };\n }\n\n throw createErrorWithContext(\n `HTTP ${response.status}: ${response.statusText}`,\n {\n url: config.url,\n method: config.method,\n status: response.status,\n statusText: response.statusText,\n responseData: data,\n }\n );\n }\n\n const httpResponse: HttpResponse<T> = {\n data,\n status: response.status,\n statusText: response.statusText,\n headers,\n };\n\n return httpResponse;\n } catch (error) {\n if (error instanceof Error && error.name === 'AbortError') {\n throw createErrorWithContext('Request was aborted', {\n type: 'AbortError',\n url: config.url,\n method: config.method,\n });\n }\n\n if (error instanceof Error) {\n const errorMessage = error.message.toLowerCase();\n if (\n error.name === 'TypeError' &&\n (errorMessage.includes('network') ||\n errorMessage.includes('fetch') ||\n errorMessage.includes('failed to fetch') ||\n errorMessage.includes('internet') ||\n errorMessage.includes('connection') ||\n errorMessage.includes('resolve') ||\n errorMessage.includes('unreachable'))\n ) {\n throw createErrorWithContext(\n 'Network connection failed. Please check your internet connection or VPN settings.',\n {\n url: config.url,\n method: config.method,\n networkError: true,\n originalMessage: error.message,\n }\n );\n }\n }\n\n throw createErrorWithContext(\n `HTTP request failed: ${error instanceof Error ? error.message : 'Unknown error'}`,\n {\n url: config.url,\n method: config.method,\n originalError: error,\n }\n );\n }\n }\n}\n","import { createErrorWithContext } from '../errors';\nimport { HttpAdapter } from './adapter';\nimport { AxiosAdapter } from './axios-adapter';\nimport { FetchAdapter } from './fetch-adapter';\n\nexport function createHttpAdapter(): HttpAdapter {\n if (typeof fetch !== 'undefined') {\n return new FetchAdapter();\n }\n\n try {\n return new AxiosAdapter();\n } catch (error) {\n throw createErrorWithContext(\n 'No suitable HTTP adapter found. Please use Node.js >= 18 or install axios: npm install axios',\n { error }\n );\n }\n}\n","import { createErrorWithContext } from '../errors';\nimport { AuthConfig, AuthHeaders, TokenInfo } from '../types/auth';\n\nexport class AuthManager {\n private config: AuthConfig;\n private tokenInfo: TokenInfo | null = null;\n\n constructor(config: AuthConfig) {\n this.config = {\n maxRetries: 3,\n ...config,\n };\n this.validateApiKey(config.apiKey);\n }\n\n private validateApiKey(apiKey: string): void {\n if (!apiKey || typeof apiKey !== 'string' || apiKey.trim().length === 0) {\n throw createErrorWithContext(\n 'API key is required and must be a non-empty string',\n {\n name: 'AuthenticationError',\n code: 'INVALID_API_KEY',\n }\n );\n }\n\n if (apiKey.length < 10) {\n throw createErrorWithContext(\n 'API key appears to be invalid (too short)',\n {\n name: 'AuthenticationError',\n code: 'INVALID_API_KEY_FORMAT',\n }\n );\n }\n }\n\n getAuthHeaders(): AuthHeaders {\n return {\n 'x-boltic-token': this.config.apiKey,\n };\n }\n\n updateApiKey(newApiKey: string): void {\n this.validateApiKey(newApiKey);\n this.config.apiKey = newApiKey;\n this.tokenInfo = null;\n }\n\n isAuthenticated(): boolean {\n return !!this.config.apiKey;\n }\n\n async validateApiKeyAsync(): Promise<boolean> {\n try {\n this.validateApiKey(this.config.apiKey);\n return true;\n } catch {\n return false;\n }\n }\n\n getTokenInfo(): TokenInfo | null {\n return this.tokenInfo ? { ...this.tokenInfo } : null;\n }\n\n getMaxRetries(): number {\n return this.config.maxRetries || 3;\n }\n\n toString(): string {\n return `AuthManager { authenticated: ${this.isAuthenticated()}, maxRetries: ${this.getMaxRetries()} }`;\n }\n\n toJSON(): object {\n return {\n authenticated: this.isAuthenticated(),\n maxRetries: this.getMaxRetries(),\n };\n }\n\n [Symbol.for('nodejs.util.inspect.custom')](): string {\n return this.toString();\n }\n}\n","import { BolticErrorResponse } from '../types/responses';\nimport type { Environment, Region } from '../types/environment';\nimport { resolveServiceURL } from '../types/environment';\nimport { HttpAdapter, createHttpAdapter } from '../http';\n\n/** Well-known service paths used across the SDK */\nexport const SERVICE_PATHS = {\n DATABASES: '/service/sdk/boltic-tables/v1',\n WORKFLOW_TEMPORAL: '/service/panel/temporal/v1.0',\n INTEGRATION: '/service/panel/integration/v1',\n SERVERLESS: '/service/panel/serverless/v1.0',\n STORAGE: '/service/panel/storage/v1.0',\n} as const;\n\nexport interface BaseApiClientConfig {\n apiKey: string;\n environment?: Environment;\n region?: Region;\n timeout?: number;\n debug?: boolean;\n retryAttempts?: number;\n retryDelay?: number;\n headers?: Record<string, string>;\n}\n\n/**\n * Base API Client — provides common functionality for all API clients.\n *\n * Subclasses pass a `servicePath` to target different backend services\n * while sharing auth, headers, error handling, and HTTP infrastructure.\n */\nexport abstract class BaseApiClient {\n protected httpAdapter: HttpAdapter;\n protected config: BaseApiClientConfig;\n protected baseURL: string;\n protected environment: Environment;\n protected region: Region;\n\n constructor(\n apiKey: string,\n config: Omit<BaseApiClientConfig, 'apiKey'> = {},\n servicePath: string = SERVICE_PATHS.DATABASES\n ) {\n this.config = { apiKey, ...config };\n this.httpAdapter = createHttpAdapter();\n\n this.environment = config.environment || 'prod';\n this.region = config.region || 'asia-south1';\n this.baseURL = resolveServiceURL(\n this.region,\n this.environment,\n servicePath\n );\n }\n\n /**\n * Resolve a secondary service URL using the same region/environment\n * but a different service path.\n */\n protected resolveAdditionalServiceURL(servicePath: string): string {\n return resolveServiceURL(this.region, this.environment, servicePath);\n }\n\n protected buildHeaders(): Record<string, string> {\n return {\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n 'x-boltic-token': this.config.apiKey,\n ...this.config.headers,\n };\n }\n\n protected formatErrorResponse(\n error: unknown,\n prefix = 'API'\n ): BolticErrorResponse {\n if (this.config.debug) {\n // eslint-disable-next-line no-console\n console.error(`[${this.constructor.name}] ${prefix} Error:`, error);\n }\n\n if (error && typeof error === 'object' && 'response' in error) {\n const apiError = error as {\n response?: {\n data?: BolticErrorResponse;\n status?: number;\n };\n };\n\n if (apiError.response?.data?.error) {\n return apiError.response.data;\n }\n\n return {\n error: {\n code: `${prefix}_ERROR`,\n message:\n error instanceof Error ? error.message : `Unknown ${prefix} error`,\n meta: [`Status: ${apiError.response?.status || 'unknown'}`],\n },\n };\n }\n\n if (error instanceof Error) {\n return {\n error: {\n code: `${prefix}_CLIENT_ERROR`,\n message: error.message,\n meta: [],\n },\n };\n }\n\n return {\n error: {\n code: `${prefix}_UNKNOWN_ERROR`,\n message: `An unexpected ${prefix} error occurred`,\n meta: [],\n },\n };\n }\n\n toString(): string {\n return `${this.constructor.name} { environment: \"${this.config.environment || 'prod'}\", debug: ${this.config.debug || false} }`;\n }\n\n toJSON(): object {\n const safeConfig = { ...this.config };\n delete (safeConfig as Record<string, unknown>).apiKey;\n return {\n client: this.constructor.name,\n config: safeConfig,\n };\n }\n\n [Symbol.for('nodejs.util.inspect.custom')](): string {\n return this.toString();\n }\n}\n","import { HttpRequestConfig, HttpResponse } from '../http/adapter';\n\nexport type RequestInterceptor = (\n config: HttpRequestConfig\n) => HttpRequestConfig | Promise<HttpRequestConfig>;\n\nexport type ResponseInterceptor = (\n response: HttpResponse\n) => HttpResponse | Promise<HttpResponse>;\n\nexport type ErrorInterceptor = (error: unknown) => unknown | Promise<unknown>;\n\nexport interface InterceptorManager {\n request: {\n use(interceptor: RequestInterceptor): number;\n eject(id: number): void;\n };\n response: {\n use(\n onFulfilled?: ResponseInterceptor,\n onRejected?: ErrorInterceptor\n ): number;\n eject(id: number): void;\n };\n}\n\nexport class InterceptorManagerImpl implements InterceptorManager {\n private requestInterceptors: Map<number, RequestInterceptor> = new Map();\n private responseInterceptors: Map<\n number,\n { fulfilled?: ResponseInterceptor; rejected?: ErrorInterceptor }\n > = new Map();\n private nextId = 0;\n\n request = {\n use: (interceptor: RequestInterceptor): number => {\n const id = this.nextId++;\n this.requestInterceptors.set(id, interceptor);\n return id;\n },\n eject: (id: number): void => {\n this.requestInterceptors.delete(id);\n },\n };\n\n response = {\n use: (\n onFulfilled?: ResponseInterceptor,\n onRejected?: ErrorInterceptor\n ): number => {\n const id = this.nextId++;\n this.responseInterceptors.set(id, {\n fulfilled: onFulfilled,\n rejected: onRejected,\n });\n return id;\n },\n eject: (id: number): void => {\n this.responseInterceptors.delete(id);\n },\n };\n\n async executeRequestInterceptors(\n config: HttpRequestConfig\n ): Promise<HttpRequestConfig> {\n let result = config;\n for (const interceptor of Array.from(this.requestInterceptors.values())) {\n result = await interceptor(result);\n }\n return result;\n }\n\n async executeResponseInterceptors(\n response: HttpResponse\n ): Promise<HttpResponse> {\n let result = response;\n for (const { fulfilled } of Array.from(\n this.responseInterceptors.values()\n )) {\n if (fulfilled) {\n result = await fulfilled(result);\n }\n }\n return result;\n }\n\n async executeErrorInterceptors(error: unknown): Promise<unknown> {\n let result = error;\n for (const { rejected } of Array.from(this.responseInterceptors.values())) {\n if (rejected) {\n result = await rejected(result);\n }\n }\n return result;\n }\n}\n","import { createErrorWithContext, getHttpStatusCode } from '../errors';\nimport {\n HttpAdapter,\n HttpRequestConfig,\n HttpResponse,\n createHttpAdapter,\n} from '../http';\nimport { AuthManager } from './auth-manager';\nimport { ClientConfig } from './config';\nimport { InterceptorManagerImpl } from './interceptors';\n\nexport class BaseClient {\n private httpAdapter: HttpAdapter;\n private authManager: AuthManager;\n private interceptors: InterceptorManagerImpl;\n private config: ClientConfig;\n\n constructor(config: ClientConfig, authManager: AuthManager) {\n this.config = config;\n this.authManager = authManager;\n this.httpAdapter = createHttpAdapter();\n this.interceptors = new InterceptorManagerImpl();\n\n this.setupDefaultInterceptors();\n }\n\n private setupDefaultInterceptors(): void {\n this.interceptors.request.use((config) => {\n const authHeaders = this.authManager.getAuthHeaders();\n config.headers = {\n ...config.headers,\n ...authHeaders,\n ...this.config.headers,\n };\n return config;\n });\n\n this.interceptors.response.use(\n (response) => {\n if (this.config.debug) {\n // eslint-disable-next-line no-console\n console.log('HTTP Response:', response);\n }\n return response;\n },\n (error) => {\n return this.handleError(error);\n }\n );\n }\n\n private handleError(error: unknown): never {\n if (this.config.debug) {\n // eslint-disable-next-line no-console\n console.error('HTTP Error:', error);\n }\n\n if (\n error instanceof Error &&\n (error as Error & { context?: unknown }).context\n ) {\n throw error;\n }\n\n const statusCode = getHttpStatusCode(error);\n\n if (!statusCode) {\n throw createErrorWithContext('Network request failed', {\n name: 'NetworkError',\n originalError: error,\n });\n }\n\n const errorData =\n (error as { response?: { data?: unknown }; data?: unknown }).response\n ?.data || (error as { data?: unknown }).data;\n const message =\n (errorData as { message?: string; error?: string })?.message ||\n (errorData as { message?: string; error?: string })?.error ||\n `HTTP ${statusCode} error`;\n\n throw createErrorWithContext(message, {\n name: 'ApiError',\n statusCode,\n response: errorData,\n isClientError: statusCode >= 400 && statusCode < 500,\n isServerError: statusCode >= 500,\n isAuthError: statusCode === 401 || statusCode === 403,\n isNotFoundError: statusCode === 404,\n isRateLimitError: statusCode === 429,\n });\n }\n\n async request<T = unknown>(\n config: HttpRequestConfig\n ): Promise<HttpResponse<T>> {\n let lastError: unknown;\n const maxRetries = this.config.maxRetries;\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n try {\n if (!config.url.startsWith('http')) {\n config.url = `${this.config.baseURL}${config.url}`;\n }\n\n if (!config.timeout) {\n config.timeout = this.config.timeout;\n }\n\n const requestConfig =\n await this.interceptors.executeRequestInterceptors(config);\n\n const response = await this.httpAdapter.request<T>(requestConfig);\n\n if (response.status >= 400) {\n const error = createErrorWithContext(\n `HTTP ${response.status} error`,\n {\n name: 'ApiError',\n statusCode: response.status,\n response: response.data,\n statusText: response.statusText,\n }\n );\n throw await this.interceptors.executeErrorInterceptors(error);\n }\n\n return (await this.interceptors.executeResponseInterceptors(\n response\n )) as HttpResponse<T>;\n } catch (error) {\n lastError = error;\n\n if (attempt === maxRetries) {\n break;\n }\n\n const statusCode = getHttpStatusCode(error);\n if (statusCode && statusCode >= 400 && statusCode < 500) {\n break;\n }\n\n if (attempt < maxRetries) {\n const delay = this.config.retryDelay * Math.pow(2, attempt);\n await new Promise((resolve) => setTimeout(resolve, delay));\n }\n }\n }\n\n throw await this.interceptors.executeErrorInterceptors(lastError);\n }\n\n get<T = unknown>(\n url: string,\n config?: Partial<HttpRequestConfig>\n ): Promise<HttpResponse<T>> {\n return this.request<T>({ ...config, method: 'GET', url });\n }\n\n post<T = unknown>(\n url: string,\n data?: unknown,\n config?: Partial<HttpRequestConfig>\n ): Promise<HttpResponse<T>> {\n return this.request<T>({ ...config, method: 'POST', url, data });\n }\n\n put<T = unknown>(\n url: string,\n data?: unknown,\n config?: Partial<HttpRequestConfig>\n ): Promise<HttpResponse<T>> {\n return this.request<T>({ ...config, method: 'PUT', url, data });\n }\n\n patch<T = unknown>(\n url: string,\n data?: unknown,\n config?: Partial<HttpRequestConfig>\n ): Promise<HttpResponse<T>> {\n return this.request<T>({ ...config, method: 'PATCH', url, data });\n }\n\n delete<T = unknown>(\n url: string,\n config?: Partial<HttpRequestConfig>\n ): Promise<HttpResponse<T>> {\n return this.request<T>({ ...config, method: 'DELETE', url });\n }\n\n getInterceptors(): InterceptorManagerImpl {\n return this.interceptors;\n }\n\n updateConfig(updates: Partial<ClientConfig>): void {\n this.config = { ...this.config, ...updates };\n }\n\n getConfig(): ClientConfig {\n return { ...this.config };\n }\n}\n","import { formatError } from '../errors';\nimport { ApiResponse, QueryOptions } from '../types/responses';\nimport { HttpResponse } from '../http/adapter';\nimport { BaseClient } from './base-client';\n\nexport abstract class BaseResource {\n protected client: BaseClient;\n protected basePath: string;\n\n constructor(client: BaseClient, basePath: string) {\n this.client = client;\n this.basePath = basePath;\n }\n\n getBasePath(): string {\n return this.basePath;\n }\n\n protected async makeRequest<T>(\n method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE',\n path: string,\n data?: unknown,\n options?: { params?: Record<string, unknown> }\n ): Promise<ApiResponse<T>> {\n const url = `${this.basePath}${path}`;\n\n try {\n let response: HttpResponse<ApiResponse<T>>;\n\n switch (method) {\n case 'GET':\n response = await this.client.get<ApiResponse<T>>(url, {\n params: options?.params,\n });\n break;\n case 'POST':\n response = await this.client.post<ApiResponse<T>>(url, data, {\n params: options?.params,\n });\n break;\n case 'PUT':\n response = await this.client.put<ApiResponse<T>>(url, data, {\n params: options?.params,\n });\n break;\n case 'PATCH':\n response = await this.client.patch<ApiResponse<T>>(url, data, {\n params: options?.params,\n });\n break;\n case 'DELETE':\n response = await this.client.delete<ApiResponse<T>>(url, {\n params: options?.params,\n });\n break;\n }\n\n return response.data;\n } catch (error) {\n return {\n error: {\n code: 'CLIENT_ERROR',\n message: formatError(error),\n meta: ['Request failed'],\n },\n };\n }\n }\n\n protected buildQueryParams(\n options: QueryOptions = {}\n ): Record<string, unknown> {\n const params: Record<string, unknown> = {};\n\n if (options.fields?.length) {\n params.fields = options.fields.join(',');\n }\n\n if (options.sort?.length) {\n params.sort = options.sort.map((s) => `${s.field}:${s.order}`).join(',');\n }\n\n if (options.limit !== undefined) {\n params.limit = options.limit;\n }\n\n if (options.offset !== undefined) {\n params.offset = options.offset;\n }\n\n if (options.where) {\n Object.entries(options.where).forEach(([key, value]) => {\n if (value !== undefined && value !== null) {\n params[`where[${key}]`] =\n typeof value === 'object' ? JSON.stringify(value) : value;\n }\n });\n }\n\n return params;\n }\n\n protected handleResponse<T>(response: ApiResponse<T>): ApiResponse<T> {\n if ('error' in response) {\n if (this.client.getConfig().debug) {\n // eslint-disable-next-line no-console\n console.error('API Error:', response.error);\n }\n }\n return response;\n }\n}\n","import {\n Environment,\n EnvironmentConfig,\n Region,\n REGION_CONFIGS,\n} from '../types/environment';\n\nexport interface ClientConfig extends EnvironmentConfig {\n apiKey: string;\n environment: Environment;\n region: Region;\n headers?: Record<string, string>;\n retryAttempts: number;\n retryDelay: number;\n maxRetries: number;\n}\n\nexport class ConfigManager {\n private config: ClientConfig;\n\n constructor(\n apiKey: string,\n environment: Environment = 'prod',\n region: Region = 'asia-south1',\n overrides?: Partial<\n EnvironmentConfig & {\n retryAttempts?: number;\n retryDelay?: number;\n maxRetries?: number;\n headers?: Record<string, string>;\n }\n >\n ) {\n const envConfig = REGION_CONFIGS[region][environment];\n this.config = {\n apiKey,\n environment,\n region,\n retryAttempts: 3,\n retryDelay: 1000,\n maxRetries: 3,\n debug: false,\n headers: {},\n ...envConfig,\n ...overrides,\n };\n }\n\n getConfig(): ClientConfig {\n return { ...this.config };\n }\n\n updateConfig(updates: Partial<ClientConfig>): void {\n this.config = { ...this.config, ...updates };\n }\n\n toString(): string {\n return `ConfigManager { environment: \"${this.config.environment}\", region: \"${this.config.region}\", debug: ${this.config.debug} }`;\n }\n\n toJSON(): object {\n const safeConfig = { ...this.config };\n delete (safeConfig as Record<string, unknown>).apiKey;\n return safeConfig;\n }\n\n [Symbol.for('nodejs.util.inspect.custom')](): string {\n return this.toString();\n }\n}\n","/**\n * Common utility functions for the Boltic SDK\n */\n\n/**\n * Filters an object to only include specified fields\n * @param obj - The object to filter\n * @param fields - Array of field names to include. If empty or undefined, returns the original object\n * @returns Filtered object with only the specified fields\n */\nexport function filterObjectFields<T extends Record<string, unknown>>(\n obj: T,\n fields?: string[]\n): Partial<T> {\n // If no fields specified or empty array, return original object\n if (!fields || fields.length === 0) {\n return obj;\n }\n\n // Filter the object to only include specified fields\n const filtered: Partial<T> = {};\n for (const field of fields) {\n if (field in obj) {\n (filtered as Record<string, unknown>)[field] = obj[field];\n }\n }\n\n return filtered;\n}\n\n/**\n * Filters an array of objects to only include specified fields\n * @param arr - Array of objects to filter\n * @param fields - Array of field names to include. If empty or undefined, returns the original array\n * @returns Array of filtered objects with only the specified fields\n */\nexport function filterArrayFields<T extends Record<string, unknown>>(\n arr: T[],\n fields?: string[]\n): Partial<T>[] {\n // If no fields specified or empty array, return original array\n if (!fields || fields.length === 0) {\n return arr;\n }\n\n // Filter each object in the array\n return arr.map((obj) => filterObjectFields(obj, fields));\n}\n","/**\n * Database context utilities\n * Helps manage database selection across API calls\n */\n\n/**\n * Adds db_id query parameter to a URL if provided\n * If db_id is undefined or empty string, the default database will be used by the API\n *\n * @param url - Base URL\n * @param dbId - Database ID (optional)\n * @returns URL with db_id query parameter if applicable\n */\nexport function addDbIdToUrl(url: string, dbId?: string): string {\n // If dbId is not provided or is empty string, return original URL (API will use default DB)\n if (!dbId || dbId === '') {\n return url;\n }\n\n // Check if URL already has query parameters\n const separator = url.includes('?') ? '&' : '?';\n\n return `${url}${separator}db_id=${encodeURIComponent(dbId)}`;\n}\n\n/**\n * Extracts db_id from options and returns both the db_id and remaining options\n * This is a helper to cleanly extract db_id from method options\n *\n * @param options - Options object that may contain db_id\n * @returns Tuple of [db_id, remaining options]\n */\nexport function extractDbId<T extends { db_id?: string }>(\n options?: T\n): [string | undefined, Omit<T, 'db_id'>] {\n if (!options) {\n return [undefined, {} as Omit<T, 'db_id'>];\n }\n\n const { db_id, ...rest } = options;\n return [db_id, rest as Omit<T, 'db_id'>];\n}\n","export interface ApiEndpoint {\n path: string;\n method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';\n authenticated: boolean;\n rateLimit?: {\n requests: number;\n window: number; // in milliseconds\n };\n}\n\nexport interface ColumnEndpoints {\n list: ApiEndpoint;\n create: ApiEndpoint;\n get: ApiEndpoint;\n update: ApiEndpoint;\n delete: ApiEndpoint;\n}\n\nexport const COLUMN_ENDPOINTS: ColumnEndpoints = {\n list: {\n path: '/tables/{table_id}/fields/list',\n method: 'POST',\n authenticated: true,\n rateLimit: { requests: 200, window: 60000 },\n },\n create: {\n path: '/tables/{table_id}/fields',\n method: 'POST',\n authenticated: true,\n },\n get: {\n path: '/tables/{table_id}/fields/{field_id}',\n method: 'GET',\n authenticated: true,\n rateLimit: { requests: 300, window: 60000 },\n },\n update: {\n path: '/tables/{table_id}/fields/{field_id}',\n method: 'PATCH',\n authenticated: true,\n },\n delete: {\n path: '/tables/{table_id}/fields/{field_id}',\n method: 'DELETE',\n authenticated: true,\n },\n};\n\nexport const buildEndpointPath = (\n endpoint: ApiEndpoint,\n params: Record<string, string> = {}\n): string => {\n let path = endpoint.path;\n\n // Replace path parameters\n Object.entries(params).forEach(([key, value]) => {\n path = path.replace(`{${key}}`, encodeURIComponent(value));\n });\n\n // Check for unreplaced parameters\n const unreplacedParams = path.match(/\\{([^}]+)\\}/g);\n if (unreplacedParams) {\n throw new Error(`Missing path parameters: ${unreplacedParams.join(', ')}`);\n }\n\n return path;\n};\n","import { FieldDefinition, FieldType } from './table';\n\n// Alignment types\nexport type AlignmentType = 'left' | 'center' | 'right';\n\n// Decimal types for number and currency fields\nexport type DecimalType =\n | '00'\n | '0.0'\n | '0.00'\n | '0.000'\n | '0.0000'\n | '0.00000'\n | '0.000000';\n\n// Phone format types\nexport type PhoneFormatType =\n | '+91 123 456 7890'\n | '(123) 456-7890'\n | '+1 (123) 456-7890'\n | '+91 12 3456 7890';\n\n// Date format enum for user-friendly values\nexport const DateFormatEnum = Object.freeze({\n MMDDYY: '%m/%d/%y',\n MMDDYYYY: '%m/%d/%Y',\n MM_DD_YYYY: '%m-%d-%Y',\n DD_MM_YYYY: '%d-%m-%Y',\n DDMMYYYY: '%d/%m/%Y',\n DDMMYY: '%d/%m/%y',\n YYYY_MM_DD: '%Y-%m-%d',\n MMMM__DD__YYYY: '%B %d %Y',\n MMM__DD__YYYY: '%b %d %Y',\n ddd__MMM__DD__YYYY: '%a %b %d %Y',\n});\n\n// Time format enum for user-friendly values\nexport const TimeFormatEnum = Object.freeze({\n HH_mm_ss: '%H:%M:%S',\n HH_mm_ssZ: '%H:%M:%SZ',\n HH_mm_ss_SSS: '%H:%M:%S.%f',\n HH_mm_ss__Z: '%H:%M:%S %Z',\n HH_mm__AMPM: '%I:%M %p', // 12-hour format with AM/PM\n HH_mm_ss__AMPM: '%I:%M:%S %p',\n});\n\n// Field type enum for validation\nexport enum FieldTypeEnum {\n TEXT = 'text',\n EMAIL = 'email',\n LONG_TEXT = 'long-text',\n DATE_TIME = 'date-time',\n NUMBER = 'number',\n CURRENCY = 'currency',\n CHECKBOX = 'checkbox',\n DROPDOWN = 'dropdown',\n PHONE_NUMBER = 'phone-number',\n LINK = 'link',\n JSON = 'json',\n VECTOR = 'vector',\n SPARSEVECTOR = 'sparsevec',\n HALFVECTOR = 'halfvec',\n ENCRYPTED = 'encrypted',\n}\n\n// Allowed field type conversions\nexport const ALLOWED_FIELD_TYPE_CONVERSIONS = {\n [FieldTypeEnum.TEXT]: [\n FieldTypeEnum.EMAIL,\n FieldTypeEnum.LONG_TEXT,\n FieldTypeEnum.DATE_TIME,\n FieldTypeEnum.NUMBER,\n FieldTypeEnum.CURRENCY,\n FieldTypeEnum.CHECKBOX,\n FieldTypeEnum.PHONE_NUMBER,\n FieldTypeEnum.LINK,\n FieldTypeEnum.JSON,\n FieldTypeEnum.VECTOR,\n FieldTypeEnum.SPARSEVECTOR,\n FieldTypeEnum.HALFVECTOR,\n FieldTypeEnum.ENCRYPTED,\n ],\n [FieldTypeEnum.EMAIL]: [\n FieldTypeEnum.TEXT,\n FieldTypeEnum.LONG_TEXT,\n FieldTypeEnum.DATE_TIME,\n FieldTypeEnum.NUMBER,\n FieldTypeEnum.CURRENCY,\n FieldTypeEnum.CHECKBOX,\n FieldTypeEnum.PHONE_NUMBER,\n FieldTypeEnum.LINK,\n FieldTypeEnum.JSON,\n FieldTypeEnum.VECTOR,\n FieldTypeEnum.SPARSEVECTOR,\n FieldTypeEnum.HALFVECTOR,\n ],\n [FieldTypeEnum.LONG_TEXT]: [\n FieldTypeEnum.TEXT,\n FieldTypeEnum.EMAIL,\n FieldTypeEnum.DATE_TIME,\n FieldTypeEnum.NUMBER,\n FieldTypeEnum.CURRENCY,\n FieldTypeEnum.CHECKBOX,\n FieldTypeEnum.PHONE_NUMBER,\n FieldTypeEnum.LINK,\n FieldTypeEnum.JSON,\n FieldTypeEnum.VECTOR,\n FieldTypeEnum.SPARSEVECTOR,\n FieldTypeEnum.HALFVECTOR,\n ],\n [FieldTypeEnum.DATE_TIME]: [\n FieldTypeEnum.TEXT,\n FieldTypeEnum.EMAIL,\n FieldTypeEnum.LONG_TEXT,\n FieldTypeEnum.PHONE_NUMBER,\n FieldTypeEnum.LINK,\n ],\n [FieldTypeEnum.NUMBER]: [\n FieldTypeEnum.TEXT,\n FieldTypeEnum.EMAIL,\n FieldTypeEnum.LONG_TEXT,\n FieldTypeEnum.CURRENCY,\n FieldTypeEnum.PHONE_NUMBER,\n FieldTypeEnum.LINK,\n ],\n [FieldTypeEnum.CURRENCY]: [\n FieldTypeEnum.TEXT,\n FieldTypeEnum.EMAIL,\n FieldTypeEnum.LONG_TEXT,\n FieldTypeEnum.NUMBER,\n FieldTypeEnum.PHONE_NUMBER,\n FieldTypeEnum.LINK,\n ],\n [FieldTypeEnum.CHECKBOX]: [\n FieldTypeEnum.TEXT,\n FieldTypeEnum.EMAIL,\n FieldTypeEnum.LONG_TEXT,\n FieldTypeEnum.PHONE_NUMBER,\n FieldTypeEnum.LINK,\n ],\n [FieldTypeEnum.DROPDOWN]: [],\n [FieldTypeEnum.PHONE_NUMBER]: [\n FieldTypeEnum.TEXT,\n FieldTypeEnum.EMAIL,\n FieldTypeEnum.LONG_TEXT,\n FieldTypeEnum.DATE_TIME,\n FieldTypeEnum.NUMBER,\n FieldTypeEnum.CURRENCY,\n FieldTypeEnum.CHECKBOX,\n FieldTypeEnum.LINK,\n FieldTypeEnum.JSON,\n FieldTypeEnum.VECTOR,\n FieldTypeEnum.SPARSEVECTOR,\n FieldTypeEnum.HALFVECTOR,\n ],\n [FieldTypeEnum.LINK]: [\n FieldTypeEnum.TEXT,\n FieldTypeEnum.EMAIL,\n FieldTypeEnum.LONG_TEXT,\n FieldTypeEnum.NUMBER,\n FieldTypeEnum.CURRENCY,\n FieldTypeEnum.CHECKBOX,\n FieldTypeEnum.PHONE_NUMBER,\n FieldTypeEnum.JSON,\n FieldTypeEnum.VECTOR,\n FieldTypeEnum.SPARSEVECTOR,\n FieldTypeEnum.HALFVECTOR,\n ],\n [FieldTypeEnum.JSON]: [\n FieldTypeEnum.TEXT,\n FieldTypeEnum.EMAIL,\n FieldTypeEnum.LONG_TEXT,\n FieldTypeEnum.PHONE_NUMBER,\n FieldTypeEnum.LINK,\n ],\n [FieldTypeEnum.VECTOR]: [\n FieldTypeEnum.TEXT,\n FieldTypeEnum.EMAIL,\n FieldTypeEnum.LONG_TEXT,\n FieldTypeEnum.PHONE_NUMBER,\n FieldTypeEnum.LINK,\n FieldTypeEnum.HALFVECTOR,\n FieldTypeEnum.SPARSEVECTOR,\n FieldTypeEnum.VECTOR,\n ],\n [FieldTypeEnum.SPARSEVECTOR]: [\n FieldTypeEnum.TEXT,\n FieldTypeEnum.EMAIL,\n FieldTypeEnum.LONG_TEXT,\n FieldTypeEnum.PHONE_NUMBER,\n FieldTypeEnum.LINK,\n FieldTypeEnum.VECTOR,\n FieldTypeEnum.HALFVECTOR,\n FieldTypeEnum.SPARSEVECTOR,\n ],\n [FieldTypeEnum.HALFVECTOR]: [\n FieldTypeEnum.TEXT,\n FieldTypeEnum.EMAIL,\n FieldTypeEnum.LONG_TEXT,\n FieldTypeEnum.PHONE_NUMBER,\n FieldTypeEnum.LINK,\n FieldTypeEnum.VECTOR,\n FieldTypeEnum.SPARSEVECTOR,\n FieldTypeEnum.HALFVECTOR,\n ],\n [FieldTypeEnum.ENCRYPTED]: [],\n};\n\n// Field-specific validation keys map\nexport const FIELD_SPECIFIC_KEYS_MAP = {\n [FieldTypeEnum.TEXT]: [],\n [FieldTypeEnum.EMAIL]: [],\n [FieldTypeEnum.LONG_TEXT]: [],\n [FieldTypeEnum.NUMBER]: ['decimals'],\n [FieldTypeEnum.CURRENCY]: ['decimals', 'currency_format'],\n [FieldTypeEnum.CHECKBOX]: [],\n [FieldTypeEnum.DROPDOWN]: [\n 'selection_source',\n 'selectable_items',\n 'multiple_selections',\n ],\n [FieldTypeEnum.DATE_TIME]: ['timezone', 'date_format', 'time_format'],\n [FieldTypeEnum.PHONE_NUMBER]: ['phone_format'],\n [FieldTypeEnum.LINK]: [],\n [FieldTypeEnum.JSON]: [],\n [FieldTypeEnum.VECTOR]: ['vector_dimension'],\n [FieldTypeEnum.SPARSEVECTOR]: ['vector_dimension'],\n [FieldTypeEnum.HALFVECTOR]: ['vector_dimension'],\n [FieldTypeEnum.ENCRYPTED]: ['show_decrypted', 'is_deterministic'],\n};\n\nexport interface ColumnCreateRequest {\n columns: FieldDefinition[];\n fields?: Array<keyof ColumnDetails>;\n}\n\nexport interface ColumnUpdateRequest {\n name?: string;\n type?: FieldType;\n description?: string;\n is_nullable?: boolean;\n is_unique?: boolean;\n is_indexed?: boolean;\n is_visible?: boolean;\n is_primary_key?: boolean;\n is_readonly?: boolean;\n default_value?: unknown;\n field_order?: number;\n fields?: Array<keyof ColumnDetails>;\n\n // Type-specific properties that can be updated\n alignment?: AlignmentType;\n decimals?: DecimalType;\n currency_format?: string; // Use Currency API for validation\n selection_source?: 'provide-static-list';\n selectable_items?: string[];\n multiple_selections?: boolean;\n phone_format?: PhoneFormatType;\n date_format?: keyof typeof DateFormatEnum;\n time_format?: keyof typeof TimeFormatEnum;\n timezone?: string;\n vector_dimension?: number;\n show_decrypted?: boolean;\n is_deterministic?: boolean; // Cannot be changed once set\n}\n\nexport interface ColumnRecord {\n id: string;\n}\n\n// Full column details interface for when complete column data is returned\nexport interface ColumnDetails {\n id: string;\n name: string;\n table_id: string;\n type: FieldType;\n description?: string;\n is_nullable: boolean;\n is_primary_key: boolean;\n is_unique: boolean;\n is_indexed: boolean;\n is_visible: boolean;\n is_readonly: boolean;\n field_order: number;\n default_value?: unknown;\n created_at: string;\n updated_at: string;\n\n // Type-specific properties\n alignment?: AlignmentType;\n timezone?: string;\n date_format?: string;\n time_format?: string;\n decimals?: number | string;\n currency_format?: string;\n selection_source?: string;\n selectable_items?: string[];\n multiple_selections?: boolean;\n phone_format?: string;\n vector_dimension?: number;\n show_decrypted?: boolean;\n is_deterministic?: boolean;\n}\n\nexport interface ColumnQueryOptions {\n where?: {\n id?: string;\n name?: string;\n table_id?: string;\n type?: FieldType;\n is_nullable?: boolean;\n is_unique?: boolean;\n is_indexed?: boolean;\n is_primary_key?: boolean;\n };\n fields?: Array<keyof ColumnDetails>;\n sort?: Array<{\n field: keyof ColumnDetails;\n order: 'asc' | 'desc';\n }>;\n limit?: number;\n offset?: number;\n}\n\nexport interface ColumnDeleteOptions {\n where: {\n id?: string;\n name?: string;\n };\n}\n\nexport interface ColumnListResponse {\n columns: ColumnDetails[];\n pagination: {\n total: number;\n page: number;\n limit: number;\n pages: number;\n };\n}\n\nexport interface ColumnUpdateOptions {\n set: ColumnUpdateRequest;\n where: {\n id?: string;\n name?: string;\n };\n}\n","import {\n ColumnDetails,\n ColumnQueryOptions,\n ColumnRecord,\n ColumnUpdateRequest,\n DateFormatEnum,\n TimeFormatEnum,\n} from '../../types/api/column';\nimport { FieldDefinition, FieldType } from '../../types/api/table';\nimport { ApiFilter } from '../../utils/filters/filter-mapper';\n\nexport interface ColumnCreateApiRequest {\n field: FieldDefinition;\n}\n\nexport interface ColumnListApiRequest {\n page?: {\n page_no: number;\n page_size: number;\n };\n sort?: Array<{\n field: string;\n direction: 'asc' | 'desc';\n }>;\n filters?: ApiFilter[];\n}\n\nexport interface ColumnUpdateApiRequest {\n id?: string;\n name?: string;\n type?: string;\n description?: string;\n is_nullable?: boolean;\n is_unique?: boolean;\n is_indexed?: boolean;\n is_primary_key?: boolean;\n is_visible?: boolean;\n is_readonly?: boolean;\n default_value?: unknown;\n field_order?: number;\n alignment?: 'left' | 'center' | 'right';\n decimals?: string;\n currency_format?: string;\n selection_source?: string;\n selectable_items?: string[];\n multiple_selections?: boolean;\n phone_format?: string;\n date_format?: string;\n time_format?: string;\n timezone?: string;\n vector_dimension?: number;\n show_decrypted?: boolean;\n is_deterministic?: boolean;\n}\n\nexport interface ColumnApiResponse {\n data: {\n id: string;\n name: string;\n original_name: string;\n table_id: string;\n table_name: string;\n type: string;\n description?: string;\n is_nullable: boolean;\n is_primary_key: boolean;\n is_unique: boolean;\n is_indexed: boolean;\n is_visible: boolean;\n is_readonly: boolean;\n field_order: number;\n default_value?: unknown;\n created_at: string;\n updated_at: string;\n alignment?: string;\n timezone?: string;\n date_format?: string;\n time_format?: string;\n decimals?: string;\n currency_format?: string;\n selection_source?: string;\n selectable_items?: string[];\n multiple_selections?: boolean;\n phone_format?: string;\n vector_dimension?: number;\n show_decrypted?: boolean;\n is_deterministic?: boolean;\n };\n}\n\nexport interface ColumnListApiResponse {\n data: ColumnDetails[];\n pagination: {\n total_count: number;\n total_pages: number;\n current_page: number;\n per_page: number;\n type: string;\n };\n}\n\n/**\n * Transform SDK column create request to API format\n */\nexport function transformColumnCreateRequest(\n request: FieldDefinition\n): FieldDefinition {\n // Validate the single column data\n if (!request || typeof request !== 'object') {\n throw new Error('Invalid request: single column data is required');\n }\n\n if (!request.name || !request.type) {\n throw new Error('Column name and type are required');\n }\n\n // Transform the single column\n return transformFieldDefinition(request);\n}\n\n/**\n * Transform field definition to API format\n */\nfunction transformFieldDefinition(field: FieldDefinition): FieldDefinition {\n return {\n name: field.name,\n type: field.type,\n is_nullable: field.is_nullable ?? true,\n is_primary_key: field.is_primary_key ?? false,\n is_unique: field.is_unique ?? false,\n is_visible: field.is_visible ?? true,\n is_readonly: field.is_readonly ?? false,\n is_indexed: field.is_indexed ?? false,\n field_order: field.field_order ?? 1,\n alignment: field.alignment ?? 'left',\n timezone: field.timezone ?? undefined,\n date_format: field.date_format\n ? transformDateFormat(field.date_format as keyof typeof DateFormatEnum)\n : undefined,\n time_format: field.time_format\n ? transformTimeFormat(field.time_format as keyof typeof TimeFormatEnum)\n : undefined,\n decimals: field.decimals ?? undefined,\n currency_format: field.currency_format ?? undefined,\n selection_source:\n field.type === 'dropdown' && !field.selection_source\n ? 'provide-static-list'\n : (field.selection_source ?? undefined),\n selectable_items: field.selectable_items ?? undefined,\n multiple_selections: field.multiple_selections ?? undefined,\n phone_format: field.phone_format ?? undefined,\n vector_dimension: field.vector_dimension ?? undefined,\n description: field.description ?? undefined,\n default_value: field.default_value ?? undefined,\n show_decrypted: field.show_decrypted ?? undefined,\n is_deterministic: field.is_deterministic ?? undefined,\n };\n}\n\n/**\n * Transform SDK column list request to API format\n */\nexport function transformColumnListRequest(\n options: ColumnQueryOptions & {\n page?: number;\n pageSize?: number;\n } = {}\n): ColumnListApiRequest {\n const request: ColumnListApiRequest = {};\n\n // Add pagination\n if (options.page !== undefined || options.pageSize !== undefined) {\n request.page = {\n page_no: options.page || 1,\n page_size: options.pageSize || 1000,\n };\n }\n\n // Add sorting\n if (options.sort?.length) {\n request.sort = options.sort.map((s) => ({\n field: s.field as string,\n direction: s.order,\n }));\n }\n\n // Add filters\n if (options.where) {\n const filters: ApiFilter[] = [];\n\n Object.entries(options.where).forEach(([key, value]) => {\n if (value !== undefined && value !== null) {\n filters.push({\n field: key,\n operator: '=',\n values: [value],\n });\n }\n });\n\n if (filters.length > 0) {\n request.filters = filters;\n }\n }\n\n return request;\n}\n\n/**\n * Transform SDK column update request to API format\n */\nexport function transformColumnUpdateRequest(\n updates: ColumnUpdateRequest\n): ColumnUpdateApiRequest {\n const apiRequest: ColumnUpdateApiRequest = {};\n\n if (updates.name !== undefined) apiRequest.name = updates.name;\n if (updates.type !== undefined) apiRequest.type = updates.type;\n if (updates.description !== undefined)\n apiRequest.description = updates.description;\n if (updates.is_nullable !== undefined)\n apiRequest.is_nullable = updates.is_nullable;\n if (updates.is_unique !== undefined) apiRequest.is_unique = updates.is_unique;\n if (updates.is_primary_key !== undefined)\n apiRequest.is_primary_key = updates.is_primary_key;\n if (updates.is_indexed !== undefined)\n apiRequest.is_indexed = updates.is_indexed;\n if (updates.is_visible !== undefined)\n apiRequest.is_visible = updates.is_visible;\n if (updates.is_readonly !== undefined)\n apiRequest.is_readonly = updates.is_readonly;\n if (updates.default_value !== undefined)\n apiRequest.default_value = updates.default_value;\n if (updates.field_order !== undefined)\n apiRequest.field_order = updates.field_order;\n if (updates.show_decrypted !== undefined)\n apiRequest.show_decrypted = updates.show_decrypted;\n if (updates.is_deterministic !== undefined)\n apiRequest.is_deterministic = updates.is_deterministic;\n\n // Type-specific fields\n if (updates.alignment !== undefined) apiRequest.alignment = updates.alignment;\n if (updates.decimals !== undefined) apiRequest.decimals = updates.decimals;\n if (updates.currency_format !== undefined)\n apiRequest.currency_format = updates.currency_format;\n\n // Handle selection_source for dropdown columns\n // Set to \"provide-static-list\" when:\n // 1. Changing type to dropdown\n // 2. Updating selectable_items (implies dropdown behavior)\n // 3. Explicitly setting selection_source\n if (updates.type === 'dropdown') {\n // When changing type to dropdown, always set selection_source\n apiRequest.selection_source = 'provide-static-list';\n } else if (updates.selectable_items !== undefined) {\n // When updating selectable_items, ensure selection_source is set\n apiRequest.selection_source = 'provide-static-list';\n } else if (updates.selection_source !== undefined) {\n // When explicitly setting selection_source, use the provided value\n apiRequest.selection_source = updates.selection_source;\n }\n // If none of the above, don't modify selection_source (preserve existing)\n\n if (updates.selectable_items !== undefined)\n apiRequest.selectable_items = updates.selectable_items;\n if (updates.multiple_selections !== undefined)\n apiRequest.multiple_selections = updates.multiple_selections;\n if (updates.phone_format !== undefined)\n apiRequest.phone_format = updates.phone_format;\n if (updates.timezone !== undefined) apiRequest.timezone = updates.timezone;\n if (updates.vector_dimension !== undefined)\n apiRequest.vector_dimension = updates.vector_dimension;\n\n // Transform date and time formats\n if (updates.date_format !== undefined) {\n apiRequest.date_format = transformDateFormat(updates.date_format);\n }\n if (updates.time_format !== undefined) {\n apiRequest.time_format = transformTimeFormat(updates.time_format);\n }\n\n return apiRequest;\n}\n\n/**\n * Transform API column response to SDK format\n */\nexport function transformColumnResponse(\n response: ColumnApiResponse\n): ColumnDetails {\n return {\n id: response.data.id,\n name: response.data.name,\n table_id: response.data.table_id,\n type: response.data.type as FieldType,\n description: response.data.description,\n is_nullable: response.data.is_nullable,\n is_primary_key: response.data.is_primary_key,\n is_unique: response.data.is_unique,\n is_indexed: response.data.is_indexed,\n is_visible: response.data.is_visible,\n is_readonly: response.data.is_readonly,\n field_order: response.data.field_order,\n default_value: response.data.default_value,\n created_at: response.data.created_at,\n updated_at: response.data.updated_at,\n alignment: response.data.alignment as 'left' | 'center' | 'right',\n timezone: response.data.timezone,\n date_format: response.data.date_format,\n time_format: response.data.time_format,\n decimals: response.data.decimals,\n currency_format: response.data.currency_format,\n selection_source: response.data.selection_source,\n selectable_items: response.data.selectable_items,\n multiple_selections: response.data.multiple_selections,\n phone_format: response.data.phone_format,\n vector_dimension: response.data.vector_dimension,\n show_decrypted: response.data.show_decrypted,\n is_deterministic: response.data.is_deterministic,\n };\n}\n\n/**\n * Transform API column create response to SDK format\n * For create operations, the API returns only the id\n */\nexport function transformColumnCreateResponse(response: {\n data: { id: string };\n message?: string;\n}): ColumnRecord {\n return {\n id: response.data.id,\n };\n}\n\n/**\n * Transform API column list response to SDK format\n */\nexport function transformColumnListResponse(response: ColumnListApiResponse): {\n columns: ColumnDetails[];\n pagination: {\n total_count: number;\n total_pages: number;\n current_page: number;\n per_page: number;\n type: string;\n };\n} {\n return {\n columns: response.data,\n pagination: {\n total_count: response.pagination?.total_count,\n total_pages: response.pagination?.total_pages,\n current_page: response.pagination?.current_page,\n per_page: response.pagination?.per_page,\n type: response.pagination?.type,\n },\n };\n}\n\n/**\n * Transform date format from user-friendly enum to API format\n */\nfunction transformDateFormat(dateFormat: keyof typeof DateFormatEnum): string {\n return DateFormatEnum[dateFormat] || dateFormat;\n}\n\n/**\n * Transform time format from user-friendly enum to API format\n */\nfunction transformTimeFormat(timeFormat: keyof typeof TimeFormatEnum): string {\n return TimeFormatEnum[timeFormat] || timeFormat;\n}\n","import {\n ColumnCreateRequest,\n ColumnDetails,\n ColumnQueryOptions,\n ColumnRecord,\n ColumnUpdateRequest,\n} from '../../types/api/column';\nimport { FieldDefinition } from '../../types/api/table';\nimport {\n BaseApiClient,\n type BaseApiClientConfig,\n type BolticSuccessResponse,\n type BolticListResponse,\n type BolticErrorResponse,\n isErrorResponse,\n} from '../../../../common';\nimport { filterArrayFields, filterObjectFields } from '../../utils/common';\nimport { addDbIdToUrl } from '../../utils/database/db-context';\nimport { buildEndpointPath, COLUMN_ENDPOINTS } from '../endpoints/columns';\nimport {\n transformColumnCreateRequest,\n transformColumnUpdateRequest,\n} from '../transformers/columns';\n\nexport type ColumnsApiClientConfig = BaseApiClientConfig;\n\nexport interface ColumnListOptions extends ColumnQueryOptions {\n page?: number;\n pageSize?: number;\n db_id?: string;\n}\n\nexport interface ApiFilter {\n field: string;\n operator: string;\n values: unknown[];\n}\n\nexport interface ApiSort {\n field: string;\n direction: 'asc' | 'desc';\n}\n\nexport interface ColumnApiListRequest {\n page: {\n page_no: number;\n page_size: number;\n };\n filters: ApiFilter[];\n sort: ApiSort[];\n}\n\nexport class ColumnsApiClient extends BaseApiClient {\n constructor(\n apiKey: string,\n config: Omit<BaseApiClientConfig, 'apiKey'> = {}\n ) {\n super(apiKey, config);\n }\n\n /**\n * Create a single column in a table\n */\n async createColumn(\n tableId: string,\n request: FieldDefinition\n ): Promise<BolticSuccessResponse<ColumnRecord> | BolticErrorResponse> {\n try {\n const endpoint = COLUMN_ENDPOINTS.create;\n const url = `${this.baseURL}${buildEndpointPath(endpoint, { table_id: tableId })}`;\n\n // Transform the request to ensure proper formatting (e.g., selection_source for dropdowns)\n const transformedRequest = transformColumnCreateRequest(request);\n\n const response = await this.httpAdapter.request({\n url,\n method: endpoint.method,\n headers: this.buildHeaders(),\n data: transformedRequest,\n timeout: this.config.timeout,\n });\n\n if (this.config.debug) {\n console.log(\n 'Column API Response:',\n JSON.stringify(response.data, null, 2)\n );\n }\n\n // Return raw response without transformation\n return response.data as BolticSuccessResponse<ColumnRecord>;\n } catch (error) {\n return this.formatErrorResponse(error);\n }\n }\n\n /**\n * Create multiple columns in a table (one by one)\n */\n async createColumns(\n tableId: string,\n request: ColumnCreateRequest\n ): Promise<BolticListResponse<ColumnRecord> | BolticErrorResponse> {\n try {\n const columns = request.columns;\n const createdColumns: ColumnRecord[] = [];\n\n for (const column of columns) {\n const result = await this.createColumn(tableId, column);\n\n if (isErrorResponse(result)) {\n return result;\n }\n\n createdColumns.push(result.data);\n }\n\n // Apply field filtering if fields are specified\n if (request.fields && createdColumns.length > 0) {\n const filteredColumns = filterArrayFields(\n createdColumns as unknown as Record<string, unknown>[],\n request.fields as string[]\n ) as unknown as ColumnRecord[];\n createdColumns.splice(0, createdColumns.length, ...filteredColumns);\n }\n\n // Return in Boltic list format\n return {\n data: createdColumns,\n message: 'Columns created successfully',\n };\n } catch (error) {\n return this.formatErrorResponse(error);\n }\n }\n\n /**\n * List columns in a table with filtering and pagination\n */\n async listColumns(\n tableId: string,\n options: ColumnListOptions = {}\n ): Promise<BolticListResponse<ColumnDetails> | BolticErrorResponse> {\n try {\n const endpoint = COLUMN_ENDPOINTS.list;\n let url = `${this.baseURL}${buildEndpointPath(endpoint, { table_id: tableId })}?no_cache=true`;\n\n // Add db_id query parameter if provided on options\n url = addDbIdToUrl(url, options.db_id);\n\n const response = await this.httpAdapter.request({\n url,\n method: endpoint.method,\n headers: this.buildHeaders(),\n data: options,\n timeout: this.config.timeout,\n });\n\n // Apply field filtering if fields are specified\n const responseData = response.data as BolticListResponse<ColumnDetails>;\n if (options.fields && responseData.data) {\n responseData.data = filterArrayFields(\n responseData.data as unknown as Record<string, unknown>[],\n options.fields as string[]\n ) as unknown as ColumnDetails[];\n }\n\n return responseData;\n } catch (error) {\n return this.formatErrorResponse(error);\n }\n }\n\n /**\n * Get a single column by ID\n */\n async getColumn(\n tableId: string,\n columnId: string,\n options: { fields?: Array<keyof ColumnDetails> } = {}\n ): Promise<BolticSuccessResponse<ColumnDetails> | BolticErrorResponse> {\n try {\n const endpoint = COLUMN_ENDPOINTS.get;\n const url = `${this.baseURL}${buildEndpointPath(endpoint, {\n table_id: tableId,\n field_id: columnId,\n })}`;\n\n const response = await this.httpAdapter.request({\n url,\n method: endpoint.method,\n headers: this.buildHeaders(),\n timeout: this.config.timeout,\n });\n\n if (this.config.debug) {\n console.log(\n 'Column API Response:',\n JSON.stringify(response.data, null, 2)\n );\n }\n\n // Apply field filtering if fields are specified\n const responseData =\n response.data as BolticSuccessResponse<ColumnDetails>;\n if (options.fields && responseData.data) {\n responseData.data = filterObjectFields(\n responseData.data as unknown as Record<string, unknown>,\n options.fields as string[]\n ) as unknown as ColumnDetails;\n }\n\n return responseData;\n } catch (error) {\n return this.formatErrorResponse(error);\n }\n }\n\n /**\n * Update a column\n */\n async updateColumn(\n tableId: string,\n columnId: string,\n updates: ColumnUpdateRequest\n ): Promise<BolticSuccessResponse<ColumnDetails> | BolticErrorResponse> {\n try {\n const endpoint = COLUMN_ENDPOINTS.update;\n const url = `${this.baseURL}${buildEndpointPath(endpoint, {\n table_id: tableId,\n field_id: columnId,\n })}`;\n\n // Transform the updates to API format\n const transformedUpdates = transformColumnUpdateRequest(updates);\n\n const response = await this.httpAdapter.request({\n url,\n method: endpoint.method,\n headers: this.buildHeaders(),\n data: transformedUpdates,\n timeout: this.config.timeout,\n });\n\n // Apply field filtering if fields are specified\n const responseData =\n response.data as BolticSuccessResponse<ColumnDetails>;\n if (updates.fields && responseData.data) {\n responseData.data = filterObjectFields(\n responseData.data as unknown as Record<string, unknown>,\n updates.fields as string[]\n ) as unknown as ColumnDetails;\n }\n\n return responseData;\n } catch (error) {\n return this.formatErrorResponse(error);\n }\n }\n\n /**\n * Delete a column\n */\n async deleteColumn(\n tableId: string,\n columnId: string\n ): Promise<BolticSuccessResponse<{ message: string }> | BolticErrorResponse> {\n try {\n const endpoint = COLUMN_ENDPOINTS.delete;\n const url = `${this.baseURL}${buildEndpointPath(endpoint, {\n table_id: tableId,\n field_id: columnId,\n })}`;\n\n const response = await this.httpAdapter.request({\n url,\n method: endpoint.method,\n headers: this.buildHeaders(),\n timeout: this.config.timeout,\n });\n\n // Return raw response without transformation\n return response.data as BolticSuccessResponse<{ message: string }>;\n } catch (error) {\n return this.formatErrorResponse(error);\n }\n }\n\n /**\n * Find column by name in a table\n */\n async findColumnByName(\n tableId: string,\n columnName: string\n ): Promise<\n BolticSuccessResponse<ColumnDetails | null> | BolticErrorResponse\n > {\n try {\n // Transform to API format\n const apiRequest = {\n page: { page_no: 1, page_size: 1 },\n filters: [\n {\n field: 'name',\n operator: '=',\n values: [columnName],\n },\n ],\n sort: [],\n };\n\n const listResult = await this.listColumns(\n tableId,\n apiRequest as unknown as ColumnListOptions\n );\n if (isErrorResponse(listResult)) {\n return listResult;\n }\n const column = listResult.data[0] || null;\n return {\n data: column,\n message: column ? 'Column found' : 'Column not found',\n };\n } catch (error) {\n return this.formatErrorResponse(error);\n }\n }\n\n /**\n * Helper function to convert ColumnDetails to ColumnUpdateRequest format\n */\n private convertColumnDetailsToUpdateRequest(\n columnDetails: ColumnDetails\n ): Record<string, unknown> {\n return {\n name: columnDetails.name,\n type: columnDetails.type,\n description: columnDetails.description,\n is_nullable: columnDetails.is_nullable,\n is_unique: columnDetails.is_unique,\n is_indexed: columnDetails.is_indexed,\n is_visible: columnDetails.is_visible,\n is_primary_key: columnDetails.is_primary_key,\n is_readonly: columnDetails.is_readonly,\n default_value: columnDetails.default_value,\n field_order: columnDetails.field_order,\n alignment: columnDetails.alignment,\n decimals: columnDetails.decimals,\n currency_format: columnDetails.currency_format,\n selection_source: columnDetails.selection_source,\n selectable_items: columnDetails.selectable_items,\n multiple_selections: columnDetails.multiple_selections,\n phone_format: columnDetails.phone_format,\n date_format: columnDetails.date_format,\n time_format: columnDetails.time_format,\n timezone: columnDetails.timezone,\n vector_dimension: columnDetails.vector_dimension,\n };\n }\n\n /**\n * Update a column by name\n */\n async updateColumnByName(\n tableId: string,\n columnName: string,\n updates: ColumnUpdateRequest\n ): Promise<BolticSuccessResponse<ColumnDetails> | BolticErrorResponse> {\n try {\n // First find the column to get its current data\n const findResult = await this.findColumnByName(tableId, columnName);\n\n if (isErrorResponse(findResult)) {\n return findResult;\n }\n\n if (!findResult.data) {\n return {\n error: {\n code: 'COLUMN_NOT_FOUND',\n message: `Column '${columnName}' not found in table`,\n meta: ['404'],\n },\n };\n }\n\n // Convert existing column details to update request format\n const existingColumnAsUpdate = this.convertColumnDetailsToUpdateRequest(\n findResult.data\n );\n\n // Merge existing data with updates (updates override existing values)\n const mergedUpdates: ColumnUpdateRequest = {\n ...existingColumnAsUpdate,\n ...updates,\n } as ColumnUpdateRequest;\n\n // Update using the column ID with merged data\n return await this.updateColumn(\n tableId,\n findResult.data.id,\n mergedUpdates\n );\n } catch (error) {\n return this.formatErrorResponse(error);\n }\n }\n\n /**\n * Delete column by name\n */\n async deleteColumnByName(\n tableId: string,\n columnName: string\n ): Promise<BolticSuccessResponse<{ message: string }> | BolticErrorResponse> {\n try {\n // First find the column to get its ID\n const findResult = await this.findColumnByName(tableId, columnName);\n\n if (isErrorResponse(findResult)) {\n return findResult;\n }\n\n if (!findResult.data) {\n return {\n error: {\n code: 'COLUMN_NOT_FOUND',\n message: `Column '${columnName}' not found in table`,\n meta: ['Column not found'],\n },\n };\n }\n\n // Delete using the column ID\n return await this.deleteColumn(tableId, findResult.data.id);\n } catch (error) {\n return this.formatErrorResponse(error);\n }\n }\n}\n","export interface ApiEndpoint {\n path: string;\n method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';\n authenticated: boolean;\n rateLimit?: {\n requests: number;\n window: number; // in milliseconds\n };\n}\n\nexport interface TableEndpoints {\n list: ApiEndpoint;\n create: ApiEndpoint;\n get: ApiEndpoint;\n update: ApiEndpoint;\n delete: ApiEndpoint;\n}\n\nexport const TABLE_ENDPOINTS: TableEndpoints = {\n list: {\n path: '/tables/list',\n method: 'POST',\n authenticated: true,\n rateLimit: { requests: 200, window: 60000 },\n },\n create: {\n path: '/tables',\n method: 'POST',\n authenticated: true,\n },\n get: {\n path: '/tables/{table_id}',\n method: 'GET',\n authenticated: true,\n rateLimit: { requests: 300, window: 60000 },\n },\n update: {\n path: '/tables/{table_id}',\n method: 'PATCH',\n authenticated: true,\n },\n delete: {\n path: '/tables/{table_id}',\n method: 'DELETE',\n authenticated: true,\n },\n};\n\nexport const buildEndpointPath = (\n endpoint: ApiEndpoint,\n params: Record<string, string> = {}\n): string => {\n let path = endpoint.path;\n\n // Replace path parameters\n Object.entries(params).forEach(([key, value]) => {\n path = path.replace(`{${key}}`, encodeURIComponent(value));\n });\n\n // Check for unreplaced parameters\n const unreplacedParams = path.match(/\\{([^}]+)\\}/g);\n if (unreplacedParams) {\n throw new Error(`Missing path parameters: ${unreplacedParams.join(', ')}`);\n }\n\n return path;\n};\n","/**\n * Filter structure according to Tables Module PRD and backend buildWhereClause function\n */\nexport interface ApiFilter {\n field: string;\n operator: string;\n values: unknown[];\n}\n\nexport interface WhereCondition {\n [field: string]: unknown;\n}\n\n/**\n * Comprehensive filter operators based on backend buildWhereClause function\n */\nexport const FILTER_OPERATORS = {\n // Relational operators\n EQUALS: '=',\n NOT_EQUALS: '!=',\n GREATER_THAN: '>',\n GREATER_THAN_EQUAL: '>=',\n LESS_THAN: '<',\n LESS_THAN_EQUAL: '<=',\n\n // String operators\n LIKE: 'LIKE', // contains (case-sensitive)\n ILIKE: 'ILIKE', // contains (case-insensitive)\n STARTS_WITH: 'STARTS WITH',\n\n // Array/Set operators\n IN: 'IN', // is one of\n NOT_IN: 'NOT IN', // is not one of\n\n // Special operators\n IS_EMPTY: 'IS EMPTY',\n IS_NULL: 'IS NULL',\n IS_NOT_NULL: 'IS NOT NULL',\n BETWEEN: 'BETWEEN',\n\n // Dropdown/Array specific operators\n ARRAY_CONTAINS: '@>', // is exactly for dropdown\n ARRAY_NOT_CONTAINS: 'NOT @>', // is different from for dropdown\n ANY: 'ANY', // contains (case-sensitive) for dropdown\n IS_ONE_OF_ARRAY: 'IS ONE OF', // is one of for dropdown\n DROPDOWN_ITEM_STARTS_WITH: 'DROPDOWN ITEM STARTS WITH',\n\n // Date operators\n WITHIN: 'WITHIN', // date range operator\n} as const;\n\n/**\n * Map SDK where clause operators to API filter operators\n */\nconst OPERATOR_MAPPING: Record<string, string> = {\n // Basic comparisons\n $eq: FILTER_OPERATORS.EQUALS,\n $ne: FILTER_OPERATORS.NOT_EQUALS,\n $gt: FILTER_OPERATORS.GREATER_THAN,\n $gte: FILTER_OPERATORS.GREATER_THAN_EQUAL,\n $lt: FILTER_OPERATORS.LESS_THAN,\n $lte: FILTER_OPERATORS.LESS_THAN_EQUAL,\n\n // String operations\n $like: FILTER_OPERATORS.LIKE,\n $ilike: FILTER_OPERATORS.ILIKE,\n $startsWith: FILTER_OPERATORS.STARTS_WITH,\n\n // Array operations\n $in: FILTER_OPERATORS.IN,\n $notIn: FILTER_OPERATORS.NOT_IN,\n\n // Special operations\n $between: FILTER_OPERATORS.BETWEEN,\n $isEmpty: FILTER_OPERATORS.IS_EMPTY,\n $isNull: FILTER_OPERATORS.IS_NULL,\n $isNotNull: FILTER_OPERATORS.IS_NOT_NULL,\n\n // Array/dropdown operations\n $arrayContains: FILTER_OPERATORS.ARRAY_CONTAINS,\n $arrayNotContains: FILTER_OPERATORS.ARRAY_NOT_CONTAINS,\n $any: FILTER_OPERATORS.ANY,\n $isOneOfArray: FILTER_OPERATORS.IS_ONE_OF_ARRAY,\n $dropdownItemStartsWith: FILTER_OPERATORS.DROPDOWN_ITEM_STARTS_WITH,\n\n // Date operations\n $within: FILTER_OPERATORS.WITHIN,\n};\n\n/**\n * Convert direct filter array format to SDK format\n * This handles the case where filters are passed directly as an array\n */\nexport function normalizeFilters(\n filters: ApiFilter[] | Record<string, unknown>[] | WhereCondition\n): ApiFilter[] {\n if (Array.isArray(filters)) {\n // Check if it's already ApiFilter format\n if (\n filters.length > 0 &&\n typeof filters[0] === 'object' &&\n 'field' in filters[0] &&\n 'operator' in filters[0] &&\n 'values' in filters[0]\n ) {\n return filters as ApiFilter[];\n }\n // Handle legacy Record<string, unknown>[] format\n // For now, treat it as an empty array since this format is deprecated\n console.warn(\n 'Legacy Record<string, unknown>[] filter format detected. Please migrate to the new filter format.'\n );\n return [];\n }\n return mapWhereToFilters(filters);\n}\n\n/**\n * Map SDK where clause to API filters format\n */\nexport function mapWhereToFilters(where: WhereCondition): ApiFilter[] {\n const filters: ApiFilter[] = [];\n\n Object.entries(where).forEach(([field, condition]) => {\n if (\n typeof condition !== 'object' ||\n Array.isArray(condition) ||\n condition === null\n ) {\n // Direct value comparison\n filters.push({\n field,\n operator: FILTER_OPERATORS.EQUALS,\n values: [condition],\n });\n return;\n }\n\n // Handle operator-based conditions\n Object.entries(condition).forEach(([operator, value]) => {\n const apiOperator = OPERATOR_MAPPING[operator];\n if (!apiOperator) {\n throw new Error(`Unsupported operator: ${operator}`);\n }\n\n let values: unknown[];\n\n // Handle different operator value formats\n if (\n apiOperator === FILTER_OPERATORS.BETWEEN &&\n Array.isArray(value) &&\n value.length === 2\n ) {\n values = value;\n } else if (\n (apiOperator === FILTER_OPERATORS.IN ||\n apiOperator === FILTER_OPERATORS.NOT_IN ||\n apiOperator === FILTER_OPERATORS.IS_ONE_OF_ARRAY) &&\n Array.isArray(value)\n ) {\n values = value;\n } else if (\n apiOperator === FILTER_OPERATORS.IS_NULL ||\n apiOperator === FILTER_OPERATORS.IS_NOT_NULL ||\n apiOperator === FILTER_OPERATORS.IS_EMPTY\n ) {\n values = [];\n } else {\n values = [value];\n }\n\n filters.push({\n field,\n operator: apiOperator,\n values,\n });\n });\n });\n\n return filters;\n}\n\n/**\n * Build API filters with validation based on backend buildWhereClause\n */\nexport function buildApiFilters(\n whereOrFilters: WhereCondition | ApiFilter[],\n whereOperator: 'AND' | 'OR' = 'AND'\n): { filters: ApiFilter[]; whereOperator: string } {\n const filters = normalizeFilters(whereOrFilters);\n\n // Validate filters\n filters.forEach((filter, index) => {\n if (!filter.field) {\n throw new Error(`Filter at index ${index} missing required field`);\n }\n if (!filter.operator) {\n throw new Error(`Filter at index ${index} missing required operator`);\n }\n if (!Array.isArray(filter.values)) {\n throw new Error(`Filter at index ${index} values must be an array`);\n }\n });\n\n return {\n filters,\n whereOperator,\n };\n}\n\n/**\n * Convert API filters back to SDK where clause\n */\nexport function mapFiltersToWhere(filters: ApiFilter[]): WhereCondition {\n const where: WhereCondition = {};\n\n filters.forEach((filter) => {\n const reverseMapping: Record<string, string> = {};\n Object.entries(OPERATOR_MAPPING).forEach(([sdkOp, apiOp]) => {\n reverseMapping[apiOp] = sdkOp;\n });\n\n const sdkOperator = reverseMapping[filter.operator];\n if (!sdkOperator) {\n throw new Error(`Unsupported API operator: ${filter.operator}`);\n }\n\n if (!where[filter.field]) {\n where[filter.field] = {};\n }\n\n const fieldCondition = where[filter.field] as Record<string, unknown>;\n\n if (sdkOperator === '$between' && filter.values.length === 2) {\n fieldCondition[sdkOperator] = filter.values;\n } else if (\n sdkOperator === '$in' ||\n sdkOperator === '$notIn' ||\n sdkOperator === '$isOneOfArray'\n ) {\n fieldCondition[sdkOperator] = filter.values;\n } else if (\n sdkOperator === '$isNull' ||\n sdkOperator === '$isNotNull' ||\n sdkOperator === '$isEmpty'\n ) {\n fieldCondition[sdkOperator] = true;\n } else {\n fieldCondition[sdkOperator] = filter.values[0];\n }\n });\n\n return where;\n}\n\n/**\n * Validate filter values based on operator\n */\nexport function validateFilterValues(\n operator: string,\n values: unknown[]\n): boolean {\n switch (operator) {\n case FILTER_OPERATORS.BETWEEN:\n return values.length === 2;\n case FILTER_OPERATORS.IS_NULL:\n case FILTER_OPERATORS.IS_NOT_NULL:\n case FILTER_OPERATORS.IS_EMPTY:\n return values.length === 0;\n case FILTER_OPERATORS.IN:\n case FILTER_OPERATORS.NOT_IN:\n case FILTER_OPERATORS.IS_ONE_OF_ARRAY:\n return values.length > 0;\n default:\n return values.length === 1;\n }\n}\n\n/**\n * Create filter helper for building complex filter conditions\n */\nexport class FilterBuilder {\n private filters: ApiFilter[] = [];\n\n equals(field: string, value: unknown): FilterBuilder {\n this.filters.push({\n field,\n operator: FILTER_OPERATORS.EQUALS,\n values: [value],\n });\n return this;\n }\n\n notEquals(field: string, value: unknown): FilterBuilder {\n this.filters.push({\n field,\n operator: FILTER_OPERATORS.NOT_EQUALS,\n values: [value],\n });\n return this;\n }\n\n greaterThan(field: string, value: unknown): FilterBuilder {\n this.filters.push({\n field,\n operator: FILTER_OPERATORS.GREATER_THAN,\n values: [value],\n });\n return this;\n }\n\n lessThan(field: string, value: unknown): FilterBuilder {\n this.filters.push({\n field,\n operator: FILTER_OPERATORS.LESS_THAN,\n values: [value],\n });\n return this;\n }\n\n between(field: string, start: unknown, end: unknown): FilterBuilder {\n this.filters.push({\n field,\n operator: FILTER_OPERATORS.BETWEEN,\n values: [start, end],\n });\n return this;\n }\n\n in(field: string, values: unknown[]): FilterBuilder {\n this.filters.push({\n field,\n operator: FILTER_OPERATORS.IN,\n values,\n });\n return this;\n }\n\n like(field: string, value: unknown): FilterBuilder {\n this.filters.push({\n field,\n operator: FILTER_OPERATORS.LIKE,\n values: [value],\n });\n return this;\n }\n\n startsWith(field: string, value: unknown): FilterBuilder {\n this.filters.push({\n field,\n operator: FILTER_OPERATORS.STARTS_WITH,\n values: [value],\n });\n return this;\n }\n\n isEmpty(field: string): FilterBuilder {\n this.filters.push({\n field,\n operator: FILTER_OPERATORS.IS_EMPTY,\n values: [],\n });\n return this;\n }\n\n isNull(field: string): FilterBuilder {\n this.filters.push({\n field,\n operator: FILTER_OPERATORS.IS_NULL,\n values: [],\n });\n return this;\n }\n\n arrayContains(field: string, value: unknown): FilterBuilder {\n this.filters.push({\n field,\n operator: FILTER_OPERATORS.ARRAY_CONTAINS,\n values: [value],\n });\n return this;\n }\n\n build(): ApiFilter[] {\n return [...this.filters];\n }\n\n clear(): FilterBuilder {\n this.filters = [];\n return this;\n }\n}\n\n/**\n * Helper function to create a new filter builder\n */\nexport function createFilter(): FilterBuilder {\n return new FilterBuilder();\n}\n","import {\n FieldDefinition,\n TableCreateRequest,\n TableQueryOptions,\n TableRecord,\n} from '../../types/api/table';\nimport { ApiFilter, buildApiFilters } from '../../utils/filters/filter-mapper';\n\nexport interface TableCreateApiRequest {\n name: string;\n description?: string;\n fields: FieldDefinition[];\n is_ai_generated_schema?: boolean;\n is_template?: boolean;\n}\n\nexport interface TableListApiRequest {\n page?: {\n page_no: number;\n page_size: number;\n };\n sort?: Array<{\n field: string;\n direction: 'asc' | 'desc';\n }>;\n filters?: ApiFilter[];\n}\n\nexport interface TableUpdateApiRequest {\n name?: string;\n description?: string;\n}\n\nexport interface TableListApiResponse {\n data: TableRecord[];\n pagination: {\n total_count: number;\n total_pages: number;\n current_page: number;\n per_page: number;\n type: string;\n };\n}\n\n/**\n * Transform SDK table create request to API format\n */\nexport function transformTableCreateRequest(\n request: TableCreateRequest,\n options: {\n is_ai_generated_schema?: boolean;\n is_template?: boolean;\n } = {}\n): TableCreateApiRequest {\n return {\n name: request.name,\n description: request.description,\n fields: request.fields.map(transformFieldDefinition),\n is_ai_generated_schema: options.is_ai_generated_schema || false,\n is_template: options.is_template || false,\n };\n}\n\n/**\n * Transform field definition to API format\n */\nfunction transformFieldDefinition(field: FieldDefinition): FieldDefinition {\n return {\n name: field.name,\n type: field.type,\n is_nullable: field.is_nullable ?? true,\n is_primary_key: field.is_primary_key ?? false,\n is_unique: field.is_unique ?? false,\n is_indexed: field.is_indexed ?? false,\n is_visible: field.is_visible ?? true,\n is_readonly: field.is_readonly ?? false,\n field_order: field.field_order ?? 1,\n alignment: field.alignment ?? 'left',\n timezone: field.timezone ?? undefined,\n date_format: field.date_format ?? undefined,\n time_format: field.time_format ?? undefined,\n decimals: field.decimals ?? undefined,\n currency_format: field.currency_format ?? undefined,\n selection_source:\n field.type === 'dropdown' && !field.selection_source\n ? 'provide-static-list'\n : (field.selection_source ?? undefined),\n selectable_items: field.selectable_items ?? undefined,\n multiple_selections: field.multiple_selections ?? false,\n phone_format: field.phone_format ?? undefined,\n vector_dimension: field.vector_dimension ?? undefined,\n description: field.description,\n default_value: field.default_value,\n };\n}\n\n/**\n * Transform SDK table query options to API list request\n */\nexport function transformTableListRequest(\n options: TableQueryOptions & {\n page?: number;\n pageSize?: number;\n } = {}\n): TableListApiRequest {\n const request: TableListApiRequest = {};\n\n // Add pagination\n if (options.page !== undefined || options.pageSize !== undefined) {\n request.page = {\n page_no: options.page ?? 1,\n page_size: options.pageSize ?? options.limit ?? 1000,\n };\n } else if (options.limit !== undefined) {\n request.page = {\n page_no: Math.floor((options.offset ?? 0) / options.limit) + 1,\n page_size: options.limit,\n };\n }\n\n // Add sorting\n if (options.sort?.length) {\n request.sort = options.sort.map((s) => ({\n field: s.field as string,\n direction: s.order,\n }));\n }\n\n // Add filters\n if (options.where) {\n const { filters } = buildApiFilters(options.where);\n request.filters = filters;\n }\n\n return request;\n}\n\n/**\n * Transform SDK table update request to API format\n */\nexport function transformTableUpdateRequest(updates: {\n name?: string;\n description?: string;\n}): TableUpdateApiRequest {\n const request: TableUpdateApiRequest = {};\n\n if (updates.name !== undefined) {\n request.name = updates.name;\n }\n\n if (updates.description !== undefined) {\n request.description = updates.description;\n }\n\n return request;\n}\n\n/**\n * Transform API table list response to SDK format\n */\nexport function transformTableListResponse(response: TableListApiResponse): {\n tables: TableRecord[];\n pagination: {\n total_count: number;\n total_pages: number;\n current_page: number;\n per_page: number;\n type: string;\n };\n} {\n return {\n tables: response.data,\n pagination: {\n total_count: response.pagination?.total_count,\n total_pages: response.pagination?.total_pages,\n current_page: response.pagination?.current_page,\n per_page: response.pagination?.per_page,\n type: response.pagination?.type,\n },\n };\n}\n","import {\n TableCreateRequest,\n TableCreateResponse,\n TableQueryOptions,\n TableRecord,\n} from '../../types/api/table';\nimport {\n BaseApiClient,\n type BaseApiClientConfig,\n type BolticSuccessResponse,\n type BolticListResponse,\n type BolticErrorResponse,\n} from '../../../../common';\nimport { filterArrayFields, filterObjectFields } from '../../utils/common';\nimport { addDbIdToUrl } from '../../utils/database/db-context';\nimport { buildEndpointPath, TABLE_ENDPOINTS } from '../endpoints/tables';\nimport { transformTableCreateRequest } from '../transformers/tables';\n\nexport type TablesApiClientConfig = BaseApiClientConfig;\n\nexport interface TableCreateOptions {\n is_ai_generated_schema?: boolean;\n is_template?: boolean;\n db_id?: string;\n}\n\nexport interface TableListOptions extends TableQueryOptions {\n page?: number;\n pageSize?: number;\n db_id?: string;\n}\n\nexport class TablesApiClient extends BaseApiClient {\n constructor(\n apiKey: string,\n config: Omit<BaseApiClientConfig, 'apiKey'> = {}\n ) {\n super(apiKey, config);\n }\n\n /**\n * Create a new table\n */\n async createTable(\n request: TableCreateRequest,\n options: TableCreateOptions = {}\n ): Promise<BolticSuccessResponse<TableCreateResponse> | BolticErrorResponse> {\n try {\n const endpoint = TABLE_ENDPOINTS.create;\n let url = `${this.baseURL}${endpoint.path}`;\n // Add db_id query parameter if provided\n url = addDbIdToUrl(url, options.db_id);\n // Transform the request to ensure proper formatting (e.g., selection_source for dropdowns)\n const transformedRequest = transformTableCreateRequest(request, options);\n\n const response = await this.httpAdapter.request({\n url,\n method: endpoint.method,\n headers: this.buildHeaders(),\n data: transformedRequest,\n timeout: this.config.timeout,\n });\n\n // Note: TableCreateResponse only contains id and message, so field filtering is not applicable\n // Return raw response without transformation\n return response.data as BolticSuccessResponse<TableCreateResponse>;\n } catch (error) {\n return this.formatErrorResponse(error);\n }\n }\n\n /**\n * List tables with filtering and pagination\n */\n async listTables(\n options: TableListOptions = {}\n ): Promise<BolticListResponse<TableRecord> | BolticErrorResponse> {\n try {\n const endpoint = TABLE_ENDPOINTS.list;\n let url = `${this.baseURL}${endpoint.path}`;\n\n // Add db_id query parameter if provided\n url = addDbIdToUrl(url, options.db_id);\n\n const response = await this.httpAdapter.request({\n url,\n method: endpoint.method,\n headers: this.buildHeaders(),\n data: options,\n timeout: this.config.timeout,\n });\n\n // Apply field filtering if fields are specified\n const responseData = response.data as BolticListResponse<TableRecord>;\n if (options.fields && responseData.data) {\n responseData.data = filterArrayFields(\n responseData.data as unknown as Record<string, unknown>[],\n options.fields\n ) as unknown as TableRecord[];\n }\n\n return responseData;\n } catch (error) {\n return this.formatErrorResponse(error);\n }\n }\n\n /**\n * Get a specific table by ID\n */\n async getTable(\n tableId: string,\n options: { fields?: Array<keyof TableRecord>; db_id?: string } = {}\n ): Promise<BolticSuccessResponse<TableRecord> | BolticErrorResponse> {\n try {\n const endpoint = TABLE_ENDPOINTS.get;\n let url = `${this.baseURL}${buildEndpointPath(endpoint, { table_id: tableId })}`;\n\n // Add db_id query parameter if provided\n url = addDbIdToUrl(url, options.db_id);\n\n const response = await this.httpAdapter.request({\n url,\n method: endpoint.method,\n headers: this.buildHeaders(),\n timeout: this.config.timeout,\n });\n\n // Apply field filtering if fields are specified\n const responseData = response.data as BolticSuccessResponse<TableRecord>;\n if (options.fields && responseData.data) {\n responseData.data = filterObjectFields(\n responseData.data as unknown as Record<string, unknown>,\n options.fields as string[]\n ) as unknown as TableRecord;\n }\n\n return responseData;\n } catch (error) {\n return this.formatErrorResponse(error);\n }\n }\n\n /**\n * Update an existing table\n */\n async updateTable(\n tableId: string,\n updates: {\n name?: string;\n description?: string;\n fields?: Array<keyof TableRecord>;\n db_id?: string;\n }\n ): Promise<BolticSuccessResponse<TableRecord> | BolticErrorResponse> {\n try {\n const { fields, db_id, ...updateData } = updates;\n const endpoint = TABLE_ENDPOINTS.update;\n let url = `${this.baseURL}${buildEndpointPath(endpoint, { table_id: tableId })}`;\n\n // Add db_id query parameter if provided\n url = addDbIdToUrl(url, db_id);\n\n const response = await this.httpAdapter.request({\n url,\n method: endpoint.method,\n headers: this.buildHeaders(),\n data: updateData,\n timeout: this.config.timeout,\n });\n\n // Apply field filtering if fields are specified\n const responseData = response.data as BolticSuccessResponse<TableRecord>;\n if (fields && responseData.data) {\n responseData.data = filterObjectFields(\n responseData.data as unknown as Record<string, unknown>,\n fields as string[]\n ) as unknown as TableRecord;\n }\n\n return responseData;\n } catch (error) {\n return this.formatErrorResponse(error);\n }\n }\n\n /**\n * Delete a table\n */\n async deleteTable(\n tableId: string,\n options: { db_id?: string } = {}\n ): Promise<BolticSuccessResponse<{ message: string }> | BolticErrorResponse> {\n try {\n const endpoint = TABLE_ENDPOINTS.delete;\n let url = `${this.baseURL}${buildEndpointPath(endpoint, { table_id: tableId })}`;\n\n // Add db_id query parameter if provided\n url = addDbIdToUrl(url, options.db_id);\n\n const response = await this.httpAdapter.request({\n url,\n method: endpoint.method,\n headers: this.buildHeaders(),\n timeout: this.config.timeout,\n });\n\n // Return raw response without transformation\n return response.data as BolticSuccessResponse<{ message: string }>;\n } catch (error) {\n return this.formatErrorResponse(error);\n }\n }\n}\n","import {\n TablesApiClient,\n TableListOptions,\n} from '../../api/clients/tables-api-client';\nimport {\n ApiError,\n ValidationError,\n type ApiResponse,\n type BolticSuccessResponse,\n type BolticErrorResponse,\n isErrorResponse,\n isListResponse,\n BaseClient,\n BaseResource,\n} from '../../../../common';\nimport {\n FieldDefinition,\n TableCreateRequest,\n TableCreateResponse,\n TableQueryOptions,\n TableRecord,\n TableUpdateRequest,\n} from '../../types/api/table';\n\nexport class TableResource extends BaseResource {\n private tablesApiClient: TablesApiClient;\n\n constructor(client: BaseClient) {\n super(client, '/v1/tables');\n\n // Initialize the API client\n const config = client.getConfig();\n this.tablesApiClient = new TablesApiClient(config.apiKey, {\n environment: config.environment,\n region: config.region,\n timeout: config.timeout,\n debug: config.debug,\n retryAttempts: config.retryAttempts,\n retryDelay: config.retryDelay,\n headers: config.headers,\n });\n }\n\n /**\n * Create a new table\n */\n async create(\n data: TableCreateRequest,\n dbId?: string\n ): Promise<BolticSuccessResponse<TableCreateResponse>> {\n try {\n // Process fields with defaults if any are provided\n const processedData = { ...data };\n if (data.fields && data.fields.length > 0) {\n processedData.fields = await this.processFieldsDefaults(data.fields);\n }\n\n const result = await this.tablesApiClient.createTable(\n processedData,\n dbId ? { db_id: dbId } : {}\n );\n\n if (isErrorResponse(result)) {\n throw new ApiError(\n result.error.message || 'Create table failed',\n 400,\n result.error\n );\n }\n\n return result as BolticSuccessResponse<TableCreateResponse>;\n } catch (error) {\n throw error instanceof ApiError\n ? error\n : new ApiError(this.formatError(error), 500);\n }\n }\n\n /**\n * Process fields with defaults for table creation\n */\n private async processFieldsDefaults(\n fields: FieldDefinition[]\n ): Promise<FieldDefinition[]> {\n const processedFields: FieldDefinition[] = [];\n\n for (let i = 0; i < fields.length; i++) {\n const field = fields[i];\n const processedField: FieldDefinition = { ...field };\n\n // Set default values for optional fields if not provided\n if (processedField.is_primary_key === undefined) {\n processedField.is_primary_key = false;\n }\n if (processedField.is_unique === undefined) {\n processedField.is_unique = false;\n }\n if (processedField.is_nullable === undefined) {\n processedField.is_nullable = true;\n }\n if (processedField.is_indexed === undefined) {\n processedField.is_indexed = false;\n }\n\n // Set defaults for encrypted columns\n if (processedField.type === 'encrypted') {\n if (processedField.show_decrypted === undefined) {\n processedField.show_decrypted = false;\n }\n if (processedField.is_deterministic === undefined) {\n processedField.is_deterministic = false;\n }\n if (\n processedField.default_value !== undefined &&\n processedField.default_value !== null\n ) {\n throw new Error('Encrypted columns do not accept a default value');\n }\n }\n\n // Auto-generate field_order if not provided (sequential for table creation)\n if (processedField.field_order === undefined) {\n processedField.field_order = i + 1;\n }\n\n // Validate field_order is within acceptable range\n if (\n processedField.field_order <= 0 ||\n processedField.field_order >= 2147483647\n ) {\n throw new Error(\n 'Field order must be a number greater than 0 and less than 2147483647'\n );\n }\n\n processedFields.push(processedField);\n }\n\n return processedFields;\n }\n\n /**\n * Transform SDK TableQueryOptions to API request format\n */\n private transformTableQueryToApiRequest(options: TableQueryOptions): {\n page: { page_no: number; page_size: number };\n filters: Array<{ field: string; operator: string; values: unknown[] }>;\n sort: Array<{ field: string; direction: string }>;\n } {\n const apiRequest: {\n page: { page_no: number; page_size: number };\n filters: Array<{ field: string; operator: string; values: unknown[] }>;\n sort: Array<{ field: string; direction: string }>;\n } = {\n page: {\n page_no: 1,\n page_size: options.limit || 100,\n },\n filters: [],\n sort: [],\n };\n\n // Handle pagination\n if (options.offset && options.limit) {\n const pageNo = Math.floor(options.offset / options.limit) + 1;\n apiRequest.page.page_no = pageNo;\n }\n\n // Transform where clause to filters\n if (options.where) {\n Object.entries(options.where).forEach(([field, value]) => {\n if (value !== undefined && value !== null) {\n apiRequest.filters.push({\n field,\n operator: '=',\n values: [value],\n });\n }\n });\n }\n\n // Transform sort\n if (options.sort) {\n apiRequest.sort = options.sort.map((s) => ({\n field: s.field,\n direction: s.order,\n }));\n }\n\n return apiRequest;\n }\n\n /**\n * Find all tables with optional filtering\n */\n async findAll(\n options: TableQueryOptions = {},\n dbId?: string\n ): Promise<ApiResponse<TableRecord>> {\n try {\n // Transform SDK format to API format\n const apiRequest = this.transformTableQueryToApiRequest(options);\n\n // Add db_id and resource_id as filters (not query params or top-level fields)\n const filters = [...apiRequest.filters];\n\n // Only add db_id filter if explicitly provided (backend uses default DB if not specified)\n if (dbId) {\n filters.push({\n field: 'db_id',\n operator: '=',\n values: [dbId],\n });\n }\n\n // Add resource_id filter: use from options if specified, otherwise default to 'boltic'\n const resourceId = options.where?.resource_id || 'boltic';\n filters.push({\n field: 'resource_id',\n operator: '=',\n values: [resourceId],\n });\n\n // Create request payload matching API format (not TableListOptions SDK format)\n const requestPayload = {\n page: apiRequest.page,\n filters,\n sort: apiRequest.sort,\n ...(options.fields && { fields: options.fields }),\n } as unknown as TableListOptions;\n\n const result = await this.tablesApiClient.listTables(requestPayload);\n\n if (isErrorResponse(result)) {\n throw new ApiError(\n result.error.message || 'List tables failed',\n 400,\n result.error\n );\n }\n\n return result;\n } catch (error) {\n throw error instanceof ApiError\n ? error\n : new ApiError(this.formatError(error), 500);\n }\n }\n\n /**\n * Find a single table by ID or name\n */\n async findOne(\n options: TableQueryOptions,\n dbId?: string\n ): Promise<BolticSuccessResponse<TableRecord | null> | BolticErrorResponse> {\n try {\n if (!options.where?.id && !options.where?.name) {\n throw new ValidationError(\n 'Either id or name must be provided in where clause'\n );\n }\n\n if (options.where?.id) {\n // Find by ID\n const result = await this.tablesApiClient.getTable(\n options.where.id as string,\n dbId ? { db_id: dbId } : {}\n );\n\n if (isErrorResponse(result)) {\n if (result.error.code === 'TABLE_NOT_FOUND') {\n return {\n data: null,\n message: 'Table not found',\n };\n }\n throw new ApiError(\n result.error.message || 'Get table failed',\n 400,\n result.error\n );\n }\n\n return result as BolticSuccessResponse<TableRecord>;\n } else {\n // Find by name - transform to API format\n const filters = [\n {\n field: 'name',\n operator: '=',\n values: [options.where!.name],\n },\n ];\n\n // Add db_id and resource_id as filters (not query params or top-level fields)\n // Only add db_id filter if explicitly provided (backend uses default DB if not specified)\n if (dbId) {\n filters.push({\n field: 'db_id',\n operator: '=',\n values: [dbId],\n });\n }\n\n // Add resource_id filter: use from options if specified, otherwise default to 'boltic'\n const resourceId = options.where?.resource_id || 'boltic';\n filters.push({\n field: 'resource_id',\n operator: '=',\n values: [resourceId],\n });\n\n const requestPayload = {\n page: { page_no: 1, page_size: 1 },\n filters,\n sort: [],\n } as unknown as TableListOptions;\n\n const listResult =\n await this.tablesApiClient.listTables(requestPayload);\n\n if (isErrorResponse(listResult)) {\n throw new ApiError(\n listResult.error.message || 'Find table by name failed',\n 400,\n listResult.error\n );\n }\n\n const table = isListResponse(listResult)\n ? (listResult.data[0] as TableRecord)\n : null;\n return {\n data: table || null,\n message: table ? 'Table found' : 'Table not found',\n };\n }\n } catch (error) {\n throw error instanceof ApiError || error instanceof ValidationError\n ? error\n : new ApiError(this.formatError(error), 500);\n }\n }\n\n /**\n * Find a single table by name\n */\n async findByName(\n name: string,\n dbId?: string\n ): Promise<BolticSuccessResponse<TableRecord | null> | BolticErrorResponse> {\n return this.findOne({ where: { name } }, dbId);\n }\n\n /**\n * Find a single table by ID\n */\n async findById(\n id: string,\n dbId?: string\n ): Promise<BolticSuccessResponse<TableRecord | null> | BolticErrorResponse> {\n return this.findOne({ where: { id } }, dbId);\n }\n\n /**\n * Update a table by name\n */\n async update(\n name: string,\n data: TableUpdateRequest,\n dbId?: string\n ): Promise<BolticSuccessResponse<TableRecord> | BolticErrorResponse> {\n try {\n // First find the table to get its ID\n const tableResult = await this.findByName(name, dbId);\n\n if (!tableResult.data) {\n throw new ApiError(`Table '${name}' not found`, 404);\n }\n\n // Check if the table is a snapshot and prevent updates\n if (tableResult.data.snapshot_url) {\n throw new ApiError(\n `Cannot update snapshot table '${name}'. Snapshots are read-only and cannot be modified.`,\n 400\n );\n }\n\n const result = await this.tablesApiClient.updateTable(\n tableResult.data.id,\n dbId ? { ...data, db_id: dbId } : data\n );\n\n if (isErrorResponse(result)) {\n throw new ApiError(\n result.error.message || 'Update table failed',\n 400,\n result.error\n );\n }\n\n return result as BolticSuccessResponse<TableRecord>;\n } catch (error) {\n throw error instanceof ApiError\n ? error\n : new ApiError(this.formatError(error), 500);\n }\n }\n\n /**\n * Delete a table by name\n */\n async delete(\n name: string,\n dbId?: string\n ): Promise<BolticSuccessResponse<{ message: string }> | BolticErrorResponse> {\n try {\n // First find the table to get its ID\n const tableResult = await this.findByName(name, dbId);\n\n if (!tableResult.data) {\n throw new ApiError(`Table '${name}' not found`, 404);\n }\n\n // Check if the table is a snapshot and prevent deletion\n if (tableResult.data.snapshot_url) {\n throw new ApiError(\n `Cannot delete snapshot table '${name}'. Snapshots are read-only and cannot be deleted.`,\n 400\n );\n }\n\n const result = await this.tablesApiClient.deleteTable(\n tableResult.data.id,\n dbId ? { db_id: dbId } : {}\n );\n\n if (isErrorResponse(result)) {\n throw new ApiError(\n result.error.message || 'Delete table failed',\n 400,\n result.error\n );\n }\n\n return result as BolticSuccessResponse<{ message: string }>;\n } catch (error) {\n throw error instanceof ApiError\n ? error\n : new ApiError(this.formatError(error), 500);\n }\n }\n\n /**\n * Rename a table\n */\n async rename(\n oldName: string,\n newName: string,\n dbId?: string\n ): Promise<BolticSuccessResponse<TableRecord>> {\n try {\n const result = await this.update(oldName, { name: newName }, dbId);\n // update throws on error, so cast to success\n return result as BolticSuccessResponse<TableRecord>;\n } catch (error) {\n throw error instanceof ApiError\n ? error\n : new ApiError(this.formatError(error), 500);\n }\n }\n\n // Helper method to format generic errors\n private formatError(error: unknown): string {\n if (error instanceof Error) {\n return error.message;\n }\n if (typeof error === 'string') {\n return error;\n }\n return 'An unexpected error occurred';\n }\n}\n","import { ColumnsApiClient } from '../../api/clients/columns-api-client';\nimport { TablesApiClient } from '../../api/clients/tables-api-client';\nimport {\n ColumnDetails,\n ColumnQueryOptions,\n ColumnRecord,\n ColumnUpdateRequest,\n} from '../../types/api/column';\nimport { FieldDefinition } from '../../types/api/table';\nimport {\n BolticErrorResponse,\n BolticListResponse,\n BolticSuccessResponse,\n isErrorResponse,\n BaseClient,\n BaseResource,\n} from '../../../../common';\nimport { TableResource } from './table';\n\nexport class ColumnResource extends BaseResource {\n private columnsApiClient: ColumnsApiClient;\n private tablesApiClient: TablesApiClient;\n\n constructor(client: BaseClient) {\n super(client, '/v1/tables');\n\n // Initialize the API clients\n const config = client.getConfig();\n this.columnsApiClient = new ColumnsApiClient(config.apiKey, {\n environment: config.environment,\n region: config.region,\n timeout: config.timeout,\n debug: config.debug,\n retryAttempts: config.retryAttempts,\n retryDelay: config.retryDelay,\n headers: config.headers,\n });\n\n this.tablesApiClient = new TablesApiClient(config.apiKey, {\n environment: config.environment,\n region: config.region,\n timeout: config.timeout,\n debug: config.debug,\n retryAttempts: config.retryAttempts,\n retryDelay: config.retryDelay,\n headers: config.headers,\n });\n }\n\n /**\n * Create a single column in a table\n */\n async create(\n tableName: string,\n column: FieldDefinition\n ): Promise<BolticSuccessResponse<ColumnRecord> | BolticErrorResponse> {\n try {\n // Get table information first\n const tableInfo = await this.getTableInfo(tableName);\n if (!tableInfo) {\n return {\n error: {\n code: 'TABLE_NOT_FOUND',\n message: `Table '${tableName}' not found`,\n },\n };\n }\n\n // Apply defaults and auto-generate field_order\n const processedColumn = await this.processColumnDefaults(\n tableInfo.id,\n column\n );\n\n const result = await this.columnsApiClient.createColumn(\n tableInfo.id,\n processedColumn\n );\n\n if (isErrorResponse(result)) {\n return result;\n }\n\n return result as BolticSuccessResponse<ColumnRecord>;\n } catch (error) {\n return {\n error: {\n code: 'CREATE_COLUMN_ERROR',\n message:\n error instanceof Error ? error.message : 'Unknown error occurred',\n },\n };\n }\n }\n\n /**\n * Process column defaults and auto-generate field_order\n */\n private async processColumnDefaults(\n tableId: string,\n column: FieldDefinition\n ): Promise<FieldDefinition> {\n const processedColumn: FieldDefinition = { ...column };\n\n // Set default values for optional fields if not provided\n if (processedColumn.is_primary_key === undefined) {\n processedColumn.is_primary_key = false;\n }\n if (processedColumn.is_unique === undefined) {\n processedColumn.is_unique = false;\n }\n if (processedColumn.is_nullable === undefined) {\n processedColumn.is_nullable = true;\n }\n if (processedColumn.is_indexed === undefined) {\n processedColumn.is_indexed = false;\n }\n\n // Set defaults for encrypted columns\n if (processedColumn.type === 'encrypted') {\n if (processedColumn.show_decrypted === undefined) {\n processedColumn.show_decrypted = false;\n }\n if (processedColumn.is_deterministic === undefined) {\n processedColumn.is_deterministic = false;\n }\n if (\n processedColumn.default_value !== undefined &&\n processedColumn.default_value !== null\n ) {\n throw new Error('Encrypted columns do not accept a default value');\n }\n }\n\n // Auto-generate field_order if not provided\n if (processedColumn.field_order === undefined) {\n processedColumn.field_order = await this.generateFieldOrder(tableId);\n }\n\n // Validate field_order is within acceptable range\n if (\n processedColumn.field_order <= 0 ||\n processedColumn.field_order >= 2147483647\n ) {\n throw new Error(\n 'Field order must be a number greater than 0 and less than 2147483647'\n );\n }\n\n return processedColumn;\n }\n\n /**\n * Generate the next available field_order for a table\n */\n private async generateFieldOrder(tableId: string): Promise<number> {\n try {\n // Get existing columns to find the highest field_order\n const existingColumns = await this.columnsApiClient.listColumns(tableId);\n\n let maxOrder = 0;\n if (\n !isErrorResponse(existingColumns) &&\n existingColumns.data &&\n Array.isArray(existingColumns.data)\n ) {\n for (const col of existingColumns.data) {\n if (col.field_order && col.field_order > maxOrder) {\n maxOrder = col.field_order;\n }\n }\n }\n\n // Return next available number (starting from 1 if no columns exist)\n return maxOrder + 1;\n } catch (error) {\n // Fallback to timestamp-based order if there's an error\n return Math.floor(Date.now() / 1000) % 2147483647;\n }\n }\n\n /**\n * Transform SDK ColumnQueryOptions to API request format\n */\n private transformColumnQueryToApiRequest(\n options: ColumnQueryOptions\n ): unknown {\n const apiRequest: {\n page: { page_no: number; page_size: number };\n filters: Array<{ field: string; operator: string; values: unknown[] }>;\n sort: Array<{ field: string; direction: string }>;\n } = {\n page: {\n page_no: 1,\n page_size: options.limit || 100,\n },\n filters: [],\n sort: [],\n };\n\n // Handle pagination\n if (options.offset && options.limit) {\n const pageNo = Math.floor(options.offset / options.limit) + 1;\n apiRequest.page.page_no = pageNo;\n }\n\n // Transform where clause to filters\n if (options.where) {\n Object.entries(options.where).forEach(([field, value]) => {\n if (value !== undefined && value !== null) {\n apiRequest.filters.push({\n field,\n operator: '=',\n values: [value],\n });\n }\n });\n }\n\n // Transform sort\n if (options.sort) {\n apiRequest.sort = options.sort.map((s) => ({\n field: s.field,\n direction: s.order,\n }));\n }\n\n return apiRequest;\n }\n\n /**\n * Add multiple columns to existing table\n */\n async createMany(\n tableName: string,\n columns: FieldDefinition[]\n ): Promise<BolticListResponse<ColumnRecord> | BolticErrorResponse> {\n try {\n // Get table information first\n const tableInfo = await this.getTableInfo(tableName);\n if (!tableInfo) {\n return {\n error: {\n code: 'TABLE_NOT_FOUND',\n message: `Table '${tableName}' not found`,\n },\n };\n }\n\n // Process all columns with defaults and auto-generate field_order\n const processedColumns: FieldDefinition[] = [];\n for (const column of columns) {\n const processedColumn = await this.processColumnDefaults(\n tableInfo.id,\n column\n );\n processedColumns.push(processedColumn);\n }\n\n const result = await this.columnsApiClient.createColumns(tableInfo.id, {\n columns: processedColumns,\n });\n\n if (isErrorResponse(result)) {\n return result;\n }\n\n return result as BolticListResponse<ColumnRecord>;\n } catch (error) {\n return {\n error: {\n code: 'CREATE_COLUMNS_ERROR',\n message:\n error instanceof Error ? error.message : 'Unknown error occurred',\n },\n };\n }\n }\n\n /**\n * Find all columns in a table (replaces list functionality)\n */\n async findAll(\n tableName: string,\n options: ColumnQueryOptions = {}\n ): Promise<BolticListResponse<ColumnDetails> | BolticErrorResponse> {\n try {\n // Get table information first\n const tableInfo = await this.getTableInfo(tableName);\n if (!tableInfo) {\n return {\n error: {\n code: 'TABLE_NOT_FOUND',\n message: `Table '${tableName}' not found`,\n },\n };\n }\n\n // Transform SDK format to API format\n const apiRequest = this.transformColumnQueryToApiRequest(options);\n\n const result = await this.columnsApiClient.listColumns(\n tableInfo.id,\n apiRequest as unknown as ColumnQueryOptions\n );\n\n if (isErrorResponse(result)) {\n return result;\n }\n\n return result as BolticListResponse<ColumnDetails>;\n } catch (error) {\n return {\n error: {\n code: 'LIST_COLUMNS_ERROR',\n message:\n error instanceof Error ? error.message : 'Unknown error occurred',\n },\n };\n }\n }\n\n /**\n * Get a single column by name\n */\n async get(\n tableName: string,\n columnName: string\n ): Promise<BolticSuccessResponse<ColumnDetails> | BolticErrorResponse> {\n try {\n // Get table information first\n const tableInfo = await this.getTableInfo(tableName);\n if (!tableInfo) {\n return {\n error: {\n code: 'TABLE_NOT_FOUND',\n message: `Table '${tableName}' not found`,\n },\n };\n }\n\n const result = await this.columnsApiClient.findColumnByName(\n tableInfo.id,\n columnName\n );\n\n if (isErrorResponse(result)) {\n return result;\n }\n\n if (!result.data) {\n return {\n error: {\n code: 'COLUMN_NOT_FOUND',\n message: `Column '${columnName}' not found in table '${tableName}'`,\n },\n };\n }\n\n return {\n data: result.data as ColumnDetails,\n message: 'Column found successfully',\n };\n } catch (error) {\n return {\n error: {\n code: 'GET_COLUMN_ERROR',\n message:\n error instanceof Error ? error.message : 'Unknown error occurred',\n },\n };\n }\n }\n\n async findById(\n tableName: string,\n columnId: string\n ): Promise<BolticSuccessResponse<ColumnDetails> | BolticErrorResponse> {\n try {\n // Get table information first\n const tableInfo = await this.getTableInfo(tableName);\n if (!tableInfo) {\n return {\n error: {\n code: 'TABLE_NOT_FOUND',\n message: `Table '${tableName}' not found`,\n },\n };\n }\n\n // Use the direct getColumn API method\n const result = await this.columnsApiClient.getColumn(\n tableInfo.id,\n columnId\n );\n\n if (isErrorResponse(result)) {\n return result;\n }\n\n return result as BolticSuccessResponse<ColumnDetails>;\n } catch (error) {\n return {\n error: {\n code: 'FIND_COLUMN_BY_ID_ERROR',\n message:\n error instanceof Error ? error.message : 'Unknown error occurred',\n },\n };\n }\n }\n\n /**\n * Update a column by name\n */\n async update(\n tableName: string,\n columnName: string,\n updates: ColumnUpdateRequest\n ): Promise<BolticSuccessResponse<ColumnDetails> | BolticErrorResponse> {\n try {\n // Get table information first\n const tableInfo = await this.getTableInfo(tableName);\n if (!tableInfo) {\n return {\n error: {\n code: 'TABLE_NOT_FOUND',\n message: `Table '${tableName}' not found`,\n },\n };\n }\n\n const result = await this.columnsApiClient.updateColumnByName(\n tableInfo.id,\n columnName,\n updates\n );\n\n if (isErrorResponse(result)) {\n return result;\n }\n\n return result as BolticSuccessResponse<ColumnDetails>;\n } catch (error) {\n return {\n error: {\n code: 'UPDATE_COLUMN_ERROR',\n message:\n error instanceof Error ? error.message : 'Unknown error occurred',\n },\n };\n }\n }\n\n /**\n * Delete a column by name\n */\n async delete(\n tableName: string,\n columnName: string\n ): Promise<\n | BolticSuccessResponse<{ success: boolean; message?: string }>\n | BolticErrorResponse\n > {\n try {\n // Get table information first\n const tableInfo = await this.getTableInfo(tableName);\n if (!tableInfo) {\n return {\n error: {\n code: 'TABLE_NOT_FOUND',\n message: `Table '${tableName}' not found`,\n },\n };\n }\n\n const result = await this.columnsApiClient.deleteColumnByName(\n tableInfo.id,\n columnName\n );\n\n if (isErrorResponse(result)) {\n return result;\n }\n\n return {\n data: {\n success: true,\n message: 'Column deleted successfully',\n },\n };\n } catch (error) {\n return {\n error: {\n code: 'DELETE_COLUMN_ERROR',\n message:\n error instanceof Error ? error.message : 'Unknown error occurred',\n },\n };\n }\n }\n\n /**\n * Helper method to get table information by name\n */\n private async getTableInfo(\n tableName: string\n ): Promise<{ id: string; snapshot_url?: string } | null> {\n try {\n // Use the table resource to find the table by name\n const tableResource = new TableResource(this.client);\n const tableResult = await tableResource.findByName(tableName);\n\n if (tableResult.data) {\n return {\n id: tableResult.data.id,\n snapshot_url: tableResult.data.snapshot_url,\n };\n }\n\n return null;\n } catch (error) {\n console.error('Error getting table info:', error);\n return null;\n }\n }\n\n /**\n * Helper method to get table ID by name (deprecated, use getTableInfo instead)\n */\n private async getTableId(tableName: string): Promise<string | null> {\n const tableInfo = await this.getTableInfo(tableName);\n return tableInfo?.id || null;\n }\n}\n","/**\n * Database Management API Endpoints\n * Based on DATABASE_MANAGEMENT_API_CONTRACT.md\n */\n\nimport { DatabaseApiEndpoint } from '../../types/api/database';\n\nexport interface DatabaseEndpoints {\n create: DatabaseApiEndpoint;\n list: DatabaseApiEndpoint;\n update: DatabaseApiEndpoint;\n delete: DatabaseApiEndpoint;\n listJobs: DatabaseApiEndpoint;\n pollDeleteStatus: DatabaseApiEndpoint;\n}\n\n/**\n * Database API endpoints configuration\n * Base path: /v1/tables/databases\n */\nexport const DATABASE_ENDPOINTS: DatabaseEndpoints = {\n create: {\n path: '/tables/databases',\n method: 'POST',\n authenticated: true,\n },\n list: {\n path: '/tables/databases/list',\n method: 'POST',\n authenticated: true,\n },\n update: {\n path: '/tables/databases/{db_id}',\n method: 'PATCH',\n authenticated: true,\n },\n delete: {\n path: '/tables/databases/{db_id}',\n method: 'DELETE',\n authenticated: true,\n },\n listJobs: {\n path: '/tables/databases/jobs/list',\n method: 'POST',\n authenticated: true,\n },\n pollDeleteStatus: {\n path: '/tables/databases/delete-status/{job_id}',\n method: 'GET',\n authenticated: true,\n },\n};\n\n/**\n * Build endpoint path with parameters\n */\nexport const buildDatabaseEndpointPath = (\n endpoint: DatabaseApiEndpoint,\n params: Record<string, string> = {}\n): string => {\n let path = endpoint.path;\n\n // Replace path parameters\n Object.entries(params).forEach(([key, value]) => {\n path = path.replace(`{${key}}`, value);\n });\n\n return path;\n};\n","/**\n * Database Management API Client\n * Handles all database-related API operations\n */\n\nimport {\n DatabaseCreateRequest,\n DatabaseDeletionJobResponse,\n DatabaseDeletionStatusResponse,\n DatabaseJobListRequest,\n DatabaseJobQueryOptions,\n DatabaseJobRecord,\n DatabaseListQueryParams,\n DatabaseListRequest,\n DatabaseQueryOptions,\n DatabaseRecord,\n DatabaseUpdateRequest,\n} from '../../types/api/database';\nimport {\n BaseApiClient,\n type BaseApiClientConfig,\n type BolticSuccessResponse,\n type BolticListResponse,\n type BolticErrorResponse,\n} from '../../../../common';\nimport { filterArrayFields } from '../../utils/common';\nimport {\n buildDatabaseEndpointPath,\n DATABASE_ENDPOINTS,\n} from '../endpoints/databases';\n\nexport type DatabasesApiClientConfig = BaseApiClientConfig;\n\ntype BolticResponse<T> = BolticSuccessResponse<T> | BolticErrorResponse;\ntype BolticListApiResponse<T> = BolticListResponse<T> | BolticErrorResponse;\n\nexport class DatabasesApiClient extends BaseApiClient {\n constructor(\n apiKey: string,\n config: Omit<BaseApiClientConfig, 'apiKey'> = {}\n ) {\n super(apiKey, config);\n }\n\n /**\n * Create a new database\n */\n async createDatabase(\n request: DatabaseCreateRequest\n ): Promise<BolticResponse<DatabaseRecord>> {\n try {\n const endpoint = DATABASE_ENDPOINTS.create;\n const url = `${this.baseURL}${endpoint.path}`;\n\n const response = await this.httpAdapter.request<\n BolticResponse<DatabaseRecord>\n >({\n url,\n method: endpoint.method,\n headers: this.buildHeaders(),\n data: request,\n timeout: this.config.timeout,\n });\n\n return response.data;\n } catch (error: unknown) {\n return this.formatErrorResponse(error);\n }\n }\n\n /**\n * List databases with pagination, sorting, and filtering\n */\n async listDatabases(\n request: DatabaseListRequest = {},\n queryParams?: DatabaseListQueryParams,\n options?: DatabaseQueryOptions\n ): Promise<BolticListApiResponse<DatabaseRecord>> {\n try {\n const endpoint = DATABASE_ENDPOINTS.list;\n let url = `${this.baseURL}${endpoint.path}`;\n\n // Add query parameters\n const params = new URLSearchParams();\n if (queryParams?.connector_id) {\n params.append('connector_id', queryParams.connector_id);\n }\n if (queryParams?.add_default_if_missing) {\n params.append(\n 'add_default_if_missing',\n queryParams.add_default_if_missing\n );\n }\n\n if (params.toString()) {\n url += `?${params.toString()}`;\n }\n\n const response = await this.httpAdapter.request<\n BolticListApiResponse<DatabaseRecord>\n >({\n url,\n method: endpoint.method,\n headers: this.buildHeaders(),\n data: request,\n timeout: this.config.timeout,\n });\n\n const result = response.data;\n\n // Apply field filtering if requested\n if (options?.fields && !('error' in result)) {\n return {\n ...result,\n data: filterArrayFields(\n result.data as unknown as Record<string, unknown>[],\n options.fields\n ) as unknown as DatabaseRecord[],\n };\n }\n\n return result;\n } catch (error: unknown) {\n return this.formatErrorResponse(error);\n }\n }\n\n /**\n * Update a database\n */\n async updateDatabase(\n dbId: string,\n request: DatabaseUpdateRequest\n ): Promise<BolticResponse<DatabaseRecord>> {\n try {\n const endpoint = DATABASE_ENDPOINTS.update;\n const path = buildDatabaseEndpointPath(endpoint, { db_id: dbId });\n const url = `${this.baseURL}${path}`;\n\n const response = await this.httpAdapter.request<\n BolticResponse<DatabaseRecord>\n >({\n url,\n method: endpoint.method,\n headers: this.buildHeaders(),\n data: request,\n timeout: this.config.timeout,\n });\n\n return response.data;\n } catch (error: unknown) {\n return this.formatErrorResponse(error);\n }\n }\n\n /**\n * Delete a database (initiates deletion job)\n */\n async deleteDatabase(\n dbId: string\n ): Promise<BolticResponse<DatabaseDeletionJobResponse>> {\n try {\n const endpoint = DATABASE_ENDPOINTS.delete;\n const path = buildDatabaseEndpointPath(endpoint, { db_id: dbId });\n const url = `${this.baseURL}${path}`;\n\n const response = await this.httpAdapter.request<\n BolticResponse<DatabaseDeletionJobResponse>\n >({\n url,\n method: endpoint.method,\n headers: this.buildHeaders(),\n timeout: this.config.timeout,\n });\n\n return response.data;\n } catch (error: unknown) {\n return this.formatErrorResponse(error);\n }\n }\n\n /**\n * List database jobs\n */\n async listDatabaseJobs(\n request: DatabaseJobListRequest = {},\n options?: DatabaseJobQueryOptions\n ): Promise<BolticListApiResponse<DatabaseJobRecord>> {\n try {\n const endpoint = DATABASE_ENDPOINTS.listJobs;\n const url = `${this.baseURL}${endpoint.path}`;\n\n const response = await this.httpAdapter.request<\n BolticListApiResponse<DatabaseJobRecord>\n >({\n url,\n method: endpoint.method,\n headers: this.buildHeaders(),\n data: request,\n timeout: this.config.timeout,\n });\n\n const result = response.data;\n\n // Apply field filtering if requested\n if (options?.fields && !('error' in result)) {\n return {\n ...result,\n data: filterArrayFields(\n result.data as unknown as Record<string, unknown>[],\n options.fields\n ) as unknown as DatabaseJobRecord[],\n };\n }\n\n return result;\n } catch (error: unknown) {\n return this.formatErrorResponse(error);\n }\n }\n\n /**\n * Poll deletion status for a database job\n */\n async pollDeleteStatus(\n jobId: string\n ): Promise<BolticResponse<DatabaseDeletionStatusResponse>> {\n try {\n const endpoint = DATABASE_ENDPOINTS.pollDeleteStatus;\n const path = buildDatabaseEndpointPath(endpoint, { job_id: jobId });\n const url = `${this.baseURL}${path}`;\n\n const response = await this.httpAdapter.request<\n BolticResponse<DatabaseDeletionStatusResponse>\n >({\n url,\n method: endpoint.method,\n headers: this.buildHeaders(),\n timeout: this.config.timeout,\n });\n\n return response.data;\n } catch (error: unknown) {\n return this.formatErrorResponse(error);\n }\n }\n}\n","/**\n * Database Resource\n * Provides database management operations\n */\n\nimport { DatabasesApiClient } from '../../api/clients/databases-api-client';\nimport {\n DatabaseCreateRequest,\n DatabaseDeletionJobResponse,\n DatabaseDeletionStatusResponse,\n DatabaseJobListRequest,\n DatabaseJobQueryOptions,\n DatabaseJobRecord,\n DatabaseListQueryParams,\n DatabaseListRequest,\n DatabaseQueryOptions,\n DatabaseRecord,\n DatabaseUpdateRequest,\n} from '../../types/api/database';\nimport {\n BolticErrorResponse,\n BolticListResponse,\n BolticSuccessResponse,\n isErrorResponse,\n BaseClient,\n BaseResource,\n} from '../../../../common';\n\n/**\n * Database Resource - handles database CRUD operations\n */\nexport class DatabaseResource extends BaseResource {\n private apiClient: DatabasesApiClient;\n\n constructor(client: BaseClient) {\n super(client, '/v1/tables/databases');\n\n // Initialize the API client with the client's configuration\n this.apiClient = new DatabasesApiClient(client.getConfig().apiKey, {\n environment: client.getConfig().environment,\n region: client.getConfig().region,\n timeout: client.getConfig().timeout,\n debug: client.getConfig().debug,\n });\n }\n\n /**\n * Create a new database\n *\n * @param request - Database creation request\n * @returns Promise with created database or error\n *\n * @example\n * ```typescript\n * const result = await client.databases.create({\n * db_name: 'My Database',\n * db_internal_name: 'my-database',\n * resource_id: 'boltic'\n * });\n * ```\n */\n async create(\n request: DatabaseCreateRequest\n ): Promise<BolticSuccessResponse<DatabaseRecord> | BolticErrorResponse> {\n const result = await this.apiClient.createDatabase(request);\n if (isErrorResponse(result)) {\n return {\n error: {\n code:\n typeof result.error.code === 'number'\n ? String(result.error.code)\n : result.error.code,\n message: result.error.message,\n meta: result.error.meta,\n },\n };\n }\n return result;\n }\n\n /**\n * List all databases with optional filtering and pagination\n * By default, only shows active databases\n *\n * @param options - Query options for listing databases\n * @returns Promise with list of databases or error\n *\n * @example\n * ```typescript\n * // List all active databases (default)\n * const result = await client.databases.findAll();\n *\n * // List with pagination\n * const result = await client.databases.findAll({\n * page: { page_no: 1, page_size: 10 }\n * });\n *\n * // List with sorting\n * const result = await client.databases.findAll({\n * sort: [{ field: 'db_name', direction: 'asc' }]\n * });\n * ```\n */\n async findAll(\n options?: DatabaseQueryOptions\n ): Promise<BolticListResponse<DatabaseRecord> | BolticErrorResponse> {\n const request: DatabaseListRequest = {};\n\n if (options?.page) {\n request.page = options.page;\n }\n\n if (options?.sort) {\n request.sort = options.sort;\n }\n\n // Always filter to show only active databases\n // Override any user-provided status filter with ACTIVE\n if (options?.filters) {\n // Remove any existing status filter and add ACTIVE filter\n const filtersWithoutStatus = options.filters.filter(\n (f) => f.field !== 'status'\n );\n request.filters = [\n ...filtersWithoutStatus,\n { field: 'status', operator: '=', values: ['ACTIVE'] },\n ];\n } else {\n // Default filter: only show active databases\n request.filters = [\n { field: 'status', operator: '=', values: ['ACTIVE'] },\n ];\n }\n\n const queryParams: DatabaseListQueryParams = {};\n if (options?.connector_id) {\n queryParams.connector_id = options.connector_id;\n }\n if (options?.add_default_if_missing !== undefined) {\n queryParams.add_default_if_missing = options.add_default_if_missing\n ? 'true'\n : 'false';\n }\n\n const result = await this.apiClient.listDatabases(\n request,\n queryParams,\n options\n );\n if (isErrorResponse(result)) {\n return {\n error: {\n code:\n typeof result.error.code === 'number'\n ? String(result.error.code)\n : result.error.code,\n message: result.error.message,\n meta: result.error.meta,\n },\n };\n }\n // Normalize pagination structure if needed\n if ('pagination' in result && result.pagination) {\n const pagination = result.pagination;\n return {\n ...result,\n pagination: {\n total_count: pagination.total_count,\n total_pages:\n pagination.total_pages ??\n Math.ceil(pagination.total_count / pagination.per_page),\n current_page: pagination.current_page,\n per_page: pagination.per_page,\n type: 'page',\n },\n } as BolticListResponse<DatabaseRecord>;\n }\n return result as BolticListResponse<DatabaseRecord>;\n }\n\n /**\n * Get a specific database by internal name (slug)\n *\n * @param dbInternalName - Database internal name (slug)\n * @param options - Query options (e.g., fields to return)\n * @returns Promise with database or error\n *\n * @example\n * ```typescript\n * const result = await client.databases.findOne('my_database_slug');\n * ```\n */\n async findOne(\n dbInternalName: string,\n options?: { fields?: string[] }\n ): Promise<BolticSuccessResponse<DatabaseRecord> | BolticErrorResponse> {\n // Get all databases and filter by internal name\n const result = await this.findAll({\n filters: [\n {\n field: 'db_internal_name',\n operator: '=',\n values: [dbInternalName],\n },\n ],\n fields: options?.fields,\n page: { page_no: 1, page_size: 1 },\n });\n\n if (isErrorResponse(result)) {\n return result;\n }\n\n if (result.data.length === 0) {\n return {\n error: {\n code: 'NOT_FOUND',\n message: `Database with internal name '${dbInternalName}' not found`,\n meta: [],\n },\n };\n }\n\n return {\n data: result.data[0],\n message: 'Database found',\n };\n }\n\n /**\n * Get the default database\n *\n * @returns Promise with default database or error\n *\n * @example\n * ```typescript\n * const result = await client.databases.getDefault();\n * ```\n */\n async getDefault(): Promise<\n BolticSuccessResponse<DatabaseRecord> | BolticErrorResponse\n > {\n const result = await this.findAll({\n filters: [{ field: 'is_default', operator: '=', values: [true] }],\n page: { page_no: 1, page_size: 1 },\n });\n\n if (isErrorResponse(result)) {\n return result;\n }\n\n if (result.data.length === 0) {\n return {\n error: {\n code: 'NOT_FOUND',\n message: 'Default database not found',\n meta: [],\n },\n };\n }\n\n return {\n data: result.data[0],\n message: 'Default database found',\n };\n }\n\n /**\n * Update a database\n * Only allows updating the display name (db_name)\n *\n * @param dbInternalName - Database internal name (slug)\n * @param request - Update request (only db_name is allowed)\n * @returns Promise with updated database or error\n *\n * @example\n * ```typescript\n * const result = await client.databases.update('my_database_slug', {\n * db_name: 'Updated Database Name'\n * });\n * ```\n */\n async update(\n dbInternalName: string,\n request: DatabaseUpdateRequest\n ): Promise<BolticSuccessResponse<DatabaseRecord> | BolticErrorResponse> {\n // Resolve database internal name to dbId\n const dbInfo = await this.findOne(dbInternalName);\n\n if (isErrorResponse(dbInfo)) {\n return {\n error: {\n code: 'DATABASE_NOT_FOUND',\n message: `Database with internal name '${dbInternalName}' not found`,\n meta: [],\n },\n };\n }\n\n const dbId = dbInfo.data.id;\n\n // Only allow updating db_name (display name)\n // Remove any other fields that might be present\n const updateRequest: DatabaseUpdateRequest = {\n db_name: request.db_name,\n };\n\n const result = await this.apiClient.updateDatabase(dbId, updateRequest);\n if (isErrorResponse(result)) {\n return {\n error: {\n code:\n typeof result.error.code === 'number'\n ? String(result.error.code)\n : result.error.code,\n message: result.error.message,\n meta: result.error.meta,\n },\n };\n }\n return result;\n }\n\n /**\n * Delete a database (initiates async deletion job)\n *\n * @param dbInternalName - Database internal name (slug)\n * @returns Promise with job details or error\n *\n * @example\n * ```typescript\n * const result = await client.databases.delete('my_database_slug');\n * if (!result.error) {\n * console.log('Deletion job started:', result.data.job_id);\n * // Poll for status\n * const status = await client.databases.pollDeleteStatus(result.data.job_id);\n * }\n * ```\n */\n async delete(\n dbInternalName: string\n ): Promise<\n BolticSuccessResponse<DatabaseDeletionJobResponse> | BolticErrorResponse\n > {\n // Resolve database internal name to dbId\n const dbInfo = await this.findOne(dbInternalName);\n\n if (isErrorResponse(dbInfo)) {\n return {\n error: {\n code: 'DATABASE_NOT_FOUND',\n message: `Database with internal name '${dbInternalName}' not found`,\n meta: [],\n },\n };\n }\n\n // Check if this is the default database - prevent deletion\n if (dbInfo.data.is_default) {\n return {\n error: {\n code: 'CANNOT_DELETE_DEFAULT',\n message: 'Cannot delete the default database',\n meta: [],\n },\n };\n }\n\n const dbId = dbInfo.data.id;\n const result = await this.apiClient.deleteDatabase(dbId);\n if (isErrorResponse(result)) {\n return {\n error: {\n code:\n typeof result.error.code === 'number'\n ? String(result.error.code)\n : result.error.code,\n message: result.error.message,\n meta: result.error.meta,\n },\n };\n }\n return result;\n }\n\n /**\n * List database jobs (e.g., deletion jobs)\n *\n * @param options - Query options for listing jobs\n * @returns Promise with list of jobs or error\n *\n * @example\n * ```typescript\n * // List all jobs\n * const result = await client.databases.listJobs();\n *\n * // List jobs deleted by current user\n * const result = await client.databases.listJobs({\n * deleted_by_me: true\n * });\n * ```\n */\n async listJobs(\n options?: DatabaseJobQueryOptions\n ): Promise<BolticListResponse<DatabaseJobRecord> | BolticErrorResponse> {\n const request: DatabaseJobListRequest = {};\n\n if (options?.deleted_by_me !== undefined) {\n request.deleted_by_me = options.deleted_by_me;\n }\n\n if (options?.page) {\n request.page = options.page;\n }\n\n if (options?.sort) {\n request.sort = options.sort;\n }\n\n if (options?.filters) {\n request.filters = options.filters;\n }\n\n const result = await this.apiClient.listDatabaseJobs(request, options);\n if (isErrorResponse(result)) {\n return {\n error: {\n code:\n typeof result.error.code === 'number'\n ? String(result.error.code)\n : result.error.code,\n message: result.error.message,\n meta: result.error.meta,\n },\n };\n }\n // Normalize pagination structure if needed\n if ('pagination' in result && result.pagination) {\n const pagination = result.pagination;\n const normalizedResult: BolticListResponse<DatabaseJobRecord> = {\n ...result,\n pagination: {\n total_count: pagination.total_count,\n total_pages:\n pagination.total_pages ??\n Math.ceil(pagination.total_count / pagination.per_page),\n current_page: pagination.current_page,\n per_page: pagination.per_page,\n type: 'page' as const,\n },\n };\n return normalizedResult;\n }\n // If no pagination, return as list response without pagination\n return {\n ...result,\n data: result.data || [],\n } as BolticListResponse<DatabaseJobRecord>;\n }\n\n /**\n * Poll the status of a database deletion job\n *\n * @param jobId - Job ID\n * @returns Promise with job status or error\n *\n * @example\n * ```typescript\n * const status = await client.databases.pollDeleteStatus('job-uuid');\n * if (!status.error) {\n * console.log('Job status:', status.data.status);\n * console.log('Message:', status.data.message);\n * }\n * ```\n */\n async pollDeleteStatus(\n jobId: string\n ): Promise<\n BolticSuccessResponse<DatabaseDeletionStatusResponse> | BolticErrorResponse\n > {\n const result = await this.apiClient.pollDeleteStatus(jobId);\n if (isErrorResponse(result)) {\n return {\n error: {\n code:\n typeof result.error.code === 'number'\n ? String(result.error.code)\n : result.error.code,\n message: result.error.message,\n meta: result.error.meta,\n },\n };\n }\n return result;\n }\n}\n","export interface IndexApiEndpoint {\n path: string;\n method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';\n authenticated: boolean;\n rateLimit?: {\n requests: number;\n window: number;\n };\n}\n\nexport interface IndexEndpoints {\n create: IndexApiEndpoint;\n list: IndexApiEndpoint;\n delete: IndexApiEndpoint;\n}\n\nexport const INDEX_ENDPOINTS: IndexEndpoints = {\n create: {\n path: '/tables/indexes/{table_id}',\n method: 'POST',\n authenticated: true,\n },\n list: {\n path: '/tables/indexes/{table_id}/list',\n method: 'POST',\n authenticated: true,\n },\n delete: {\n path: '/tables/indexes/{table_id}',\n method: 'DELETE',\n authenticated: true,\n },\n};\n\nexport const buildIndexEndpointPath = (\n endpoint: IndexApiEndpoint,\n params: Record<string, string> = {}\n): string => {\n let path = endpoint.path;\n\n Object.entries(params).forEach(([key, value]) => {\n path = path.replace(`{${key}}`, encodeURIComponent(value));\n });\n\n const unreplacedParams = path.match(/\\{([^}]+)\\}/g);\n if (unreplacedParams) {\n throw new Error(`Missing path parameters: ${unreplacedParams.join(', ')}`);\n }\n\n return path;\n};\n","import {\n AddIndexRequest,\n AddIndexResponse,\n DeleteIndexRequest,\n DeleteIndexResponse,\n ListIndexesQuery,\n ListIndexesResponse,\n} from '../../types/api/index';\nimport {\n BaseApiClient,\n type BaseApiClientConfig,\n type BolticSuccessResponse,\n type BolticErrorResponse,\n} from '../../../../common';\nimport { addDbIdToUrl } from '../../utils/database/db-context';\nimport { buildIndexEndpointPath, INDEX_ENDPOINTS } from '../endpoints/indexes';\n\nexport type IndexesApiClientConfig = BaseApiClientConfig;\n\nexport class IndexesApiClient extends BaseApiClient {\n constructor(\n apiKey: string,\n config: Omit<BaseApiClientConfig, 'apiKey'> = {}\n ) {\n super(apiKey, config);\n }\n\n async addIndex(\n tableId: string,\n request: AddIndexRequest,\n dbId?: string\n ): Promise<BolticSuccessResponse<AddIndexResponse> | BolticErrorResponse> {\n try {\n const endpoint = INDEX_ENDPOINTS.create;\n let url = `${this.baseURL}${buildIndexEndpointPath(endpoint, { table_id: tableId })}`;\n url = addDbIdToUrl(url, dbId);\n const response = await this.httpAdapter.request({\n url,\n method: endpoint.method,\n headers: this.buildHeaders(),\n data: request,\n timeout: this.config.timeout,\n });\n return response.data as BolticSuccessResponse<AddIndexResponse>;\n } catch (error) {\n return this.formatErrorResponse(error);\n }\n }\n\n async listIndexes(\n tableId: string,\n query: ListIndexesQuery,\n dbId?: string\n ): Promise<BolticSuccessResponse<ListIndexesResponse> | BolticErrorResponse> {\n try {\n const endpoint = INDEX_ENDPOINTS.list;\n let url = `${this.baseURL}${buildIndexEndpointPath(endpoint, { table_id: tableId })}`;\n url = addDbIdToUrl(url, dbId);\n\n const response = await this.httpAdapter.request({\n url,\n method: endpoint.method,\n headers: this.buildHeaders(),\n data: query,\n timeout: this.config.timeout,\n });\n\n return response.data as BolticSuccessResponse<ListIndexesResponse>;\n } catch (error) {\n return this.formatErrorResponse(error);\n }\n }\n\n async deleteIndex(\n tableId: string,\n request: DeleteIndexRequest,\n dbId?: string\n ): Promise<BolticSuccessResponse<DeleteIndexResponse> | BolticErrorResponse> {\n try {\n const endpoint = INDEX_ENDPOINTS.delete;\n let url = `${this.baseURL}${buildIndexEndpointPath(endpoint, { table_id: tableId })}`;\n url = addDbIdToUrl(url, dbId);\n\n const response = await this.httpAdapter.request({\n url,\n method: endpoint.method,\n headers: this.buildHeaders(),\n data: request,\n timeout: this.config.timeout,\n });\n\n return response.data as BolticSuccessResponse<DeleteIndexResponse>;\n } catch (error) {\n return this.formatErrorResponse(error);\n }\n }\n}\n","import { IndexesApiClient } from '../../api/clients/indexes-api-client';\nimport {\n AddIndexRequest,\n AddIndexResponse,\n DeleteIndexRequest,\n DeleteIndexResponse,\n ListIndexesQuery,\n ListIndexesResponse,\n} from '../../types/api/index';\nimport {\n type BolticErrorResponse,\n type BolticSuccessResponse,\n BaseClient,\n} from '../../../../common';\nimport { TableResource } from './table';\n\nexport class IndexResource {\n private apiClient: IndexesApiClient;\n private tableResource: TableResource;\n private client: BaseClient;\n\n constructor(client: BaseClient) {\n this.client = client;\n\n const config = client.getConfig();\n this.apiClient = new IndexesApiClient(config.apiKey, {\n environment: config.environment,\n region: config.region,\n timeout: config.timeout,\n debug: config.debug,\n retryAttempts: config.retryAttempts,\n retryDelay: config.retryDelay,\n headers: config.headers,\n });\n\n this.tableResource = new TableResource(client);\n }\n\n private async resolveTableId(\n tableName: string,\n dbId?: string\n ): Promise<string> {\n const tableResult = await this.tableResource.findByName(tableName, dbId);\n if (!tableResult.data) throw new Error(`Table not found: ${tableName}`);\n return tableResult.data.id;\n }\n\n async addIndex(\n tableName: string,\n request: AddIndexRequest,\n dbId?: string\n ): Promise<BolticSuccessResponse<AddIndexResponse> | BolticErrorResponse> {\n try {\n const tableId = await this.resolveTableId(tableName, dbId);\n return await this.apiClient.addIndex(tableId, request, dbId);\n } catch (error) {\n return {\n error: {\n code: 'CLIENT_ERROR',\n message: (error as Error)?.message || 'Failed to add index',\n meta: ['IndexResource.addIndex'],\n },\n };\n }\n }\n\n async listIndexes(\n tableName: string,\n query: ListIndexesQuery,\n dbId?: string\n ): Promise<BolticSuccessResponse<ListIndexesResponse> | BolticErrorResponse> {\n try {\n const tableId = await this.resolveTableId(tableName, dbId);\n return await this.apiClient.listIndexes(tableId, query, dbId);\n } catch (error) {\n return {\n error: {\n code: 'CLIENT_ERROR',\n message: (error as Error)?.message || 'Failed to list indexes',\n meta: ['IndexResource.listIndexes'],\n },\n };\n }\n }\n\n async deleteIndex(\n tableName: string,\n indexName: string,\n dbId?: string\n ): Promise<BolticSuccessResponse<DeleteIndexResponse> | BolticErrorResponse> {\n try {\n const tableId = await this.resolveTableId(tableName, dbId);\n const request: DeleteIndexRequest = { index_name: indexName };\n return await this.apiClient.deleteIndex(tableId, request, dbId);\n } catch (error) {\n return {\n error: {\n code: 'CLIENT_ERROR',\n message: (error as Error)?.message || 'Failed to delete index',\n meta: ['IndexResource.deleteIndex'],\n },\n };\n }\n }\n}\n","export interface RecordApiEndpoint {\n path: string;\n method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';\n authenticated: boolean;\n rateLimit?: {\n requests: number;\n window: number; // in milliseconds\n };\n}\n\nexport interface RecordEndpoints {\n insert: RecordApiEndpoint;\n insertMany: RecordApiEndpoint;\n list: RecordApiEndpoint;\n get: RecordApiEndpoint;\n update: RecordApiEndpoint;\n updateById: RecordApiEndpoint;\n delete: RecordApiEndpoint;\n}\n\nexport const RECORD_ENDPOINTS: RecordEndpoints = {\n insert: {\n path: '/tables/{table_id}/records',\n method: 'POST',\n authenticated: true,\n },\n insertMany: {\n path: '/tables/{table_id}/records/bulk-insert',\n method: 'POST',\n authenticated: true,\n },\n list: {\n path: '/tables/{table_id}/records/list',\n method: 'POST',\n authenticated: true,\n rateLimit: { requests: 200, window: 60000 },\n },\n get: {\n path: '/tables/{table_id}/records/{record_id}',\n method: 'GET',\n authenticated: true,\n rateLimit: { requests: 200, window: 60000 },\n },\n update: {\n path: '/tables/{table_id}/records/bulk-update',\n method: 'PUT',\n authenticated: true,\n },\n updateById: {\n path: '/tables/{table_id}/records/{record_id}',\n method: 'PATCH',\n authenticated: true,\n },\n\n delete: {\n path: '/tables/{table_id}/records/list',\n method: 'DELETE',\n authenticated: true,\n },\n};\n\nexport const buildRecordEndpointPath = (\n endpoint: RecordApiEndpoint,\n params: Record<string, string> = {}\n): string => {\n let path = endpoint.path;\n\n // Replace path parameters\n Object.entries(params).forEach(([key, value]) => {\n path = path.replace(`{${key}}`, encodeURIComponent(value));\n });\n\n // Check for unreplaced parameters\n const unreplacedParams = path.match(/\\{([^}]+)\\}/g);\n if (unreplacedParams) {\n throw new Error(`Missing path parameters: ${unreplacedParams.join(', ')}`);\n }\n\n return path;\n};\n","import {\n RecordBulkInsertOptions,\n RecordBulkInsertResponse,\n RecordData,\n RecordDeleteOptions,\n RecordQueryOptions,\n RecordUpdateByIdOptions,\n RecordUpdateOptions,\n RecordWithId,\n} from '../../types/api/record';\nimport {\n BaseApiClient,\n type BaseApiClientConfig,\n type BolticSuccessResponse,\n type BolticListResponse,\n type BolticErrorResponse,\n} from '../../../../common';\nimport { filterArrayFields, filterObjectFields } from '../../utils/common';\nimport { addDbIdToUrl } from '../../utils/database/db-context';\nimport {\n buildRecordEndpointPath,\n RECORD_ENDPOINTS,\n} from '../endpoints/records';\nimport { transformDeleteRequest } from '../transformers/records';\n\nexport type RecordsApiClientConfig = BaseApiClientConfig;\n\nexport class RecordsApiClient extends BaseApiClient {\n constructor(\n apiKey: string,\n config: Omit<BaseApiClientConfig, 'apiKey'> = {}\n ) {\n super(apiKey, config);\n }\n\n /**\n * Insert a single record\n */\n async insertRecord(\n request: RecordData & { table_id?: string },\n dbId?: string\n ): Promise<BolticSuccessResponse<RecordWithId> | BolticErrorResponse> {\n try {\n const { table_id, fields, ...recordData } = request;\n\n if (!table_id) {\n return this.formatErrorResponse(\n new Error('table_id is required for insert operation')\n );\n }\n\n const endpoint = RECORD_ENDPOINTS.insert;\n let url = `${this.baseURL}${buildRecordEndpointPath(endpoint, { table_id })}`;\n url = addDbIdToUrl(url, dbId);\n\n const response = await this.httpAdapter.request({\n url,\n method: endpoint.method,\n headers: this.buildHeaders(),\n data: recordData,\n timeout: this.config.timeout,\n });\n\n // Apply field filtering if fields are specified\n const responseData = response.data as BolticSuccessResponse<RecordWithId>;\n if (fields && responseData.data) {\n responseData.data = filterObjectFields(\n responseData.data,\n fields\n ) as RecordWithId;\n }\n\n return responseData;\n } catch (error) {\n return this.formatErrorResponse(error);\n }\n }\n\n /**\n * Insert multiple records in bulk\n */\n async insertManyRecords(\n records: RecordData[],\n tableId: string,\n options: RecordBulkInsertOptions = { validation: true },\n dbId?: string\n ): Promise<RecordBulkInsertResponse | BolticErrorResponse> {\n try {\n if (!tableId) {\n return this.formatErrorResponse(\n new Error('table_id is required for bulk insert operation')\n );\n }\n\n if (!records || !Array.isArray(records) || records.length === 0) {\n return this.formatErrorResponse(\n new Error('records array is required and cannot be empty')\n );\n }\n\n const endpoint = RECORD_ENDPOINTS.insertMany;\n let url = `${this.baseURL}${buildRecordEndpointPath(endpoint, { table_id: tableId })}`;\n\n // Add validation query parameter\n const queryParams = new URLSearchParams();\n if (options.validation !== undefined) {\n queryParams.append('validation', options.validation.toString());\n }\n\n if (queryParams.toString()) {\n url += `?${queryParams.toString()}`;\n }\n url = addDbIdToUrl(url, dbId);\n\n const response = await this.httpAdapter.request({\n url,\n method: endpoint.method,\n headers: this.buildHeaders(),\n data: records,\n timeout: this.config.timeout,\n });\n\n return response.data as RecordBulkInsertResponse;\n } catch (error) {\n return this.formatErrorResponse(error);\n }\n }\n\n /**\n * Get a single record by ID\n */\n async getRecord(\n recordId: string,\n tableId: string,\n options: { fields?: string[]; show_decrypted?: boolean } = {},\n dbId?: string\n ): Promise<BolticSuccessResponse<RecordWithId> | BolticErrorResponse> {\n try {\n if (!tableId) {\n return this.formatErrorResponse(\n new Error('table_id is required for get operation')\n );\n }\n\n const endpoint = RECORD_ENDPOINTS.get;\n let url = `${this.baseURL}${buildRecordEndpointPath(endpoint, {\n table_id: tableId,\n record_id: recordId,\n })}`;\n\n const queryParams = new URLSearchParams();\n if (options.show_decrypted) {\n queryParams.append('show_decrypted', 'true');\n }\n\n if (queryParams.toString()) {\n url += `?${queryParams.toString()}`;\n }\n\n url = addDbIdToUrl(url, dbId);\n\n const response = await this.httpAdapter.request({\n url,\n method: endpoint.method,\n headers: this.buildHeaders(),\n timeout: this.config.timeout,\n });\n\n // Apply field filtering if fields are specified\n const responseData = response.data as BolticSuccessResponse<RecordWithId>;\n if (options.fields && responseData.data) {\n responseData.data = filterObjectFields(\n responseData.data,\n options.fields\n ) as RecordWithId;\n }\n\n return responseData;\n } catch (error) {\n return this.formatErrorResponse(error);\n }\n }\n\n /**\n * List records with filtering and pagination\n */\n async listRecords(\n options: RecordQueryOptions & { table_id?: string } = {},\n dbId?: string\n ): Promise<BolticListResponse<RecordWithId> | BolticErrorResponse> {\n try {\n const { table_id, ...queryOptions } = options;\n\n if (!table_id) {\n return this.formatErrorResponse(\n new Error('table_id is required for list operation')\n );\n }\n\n const endpoint = RECORD_ENDPOINTS.list;\n let url = `${this.baseURL}${buildRecordEndpointPath(endpoint, { table_id })}`;\n url = addDbIdToUrl(url, dbId);\n\n const response = await this.httpAdapter.request({\n url,\n method: endpoint.method,\n headers: this.buildHeaders(),\n data: queryOptions,\n timeout: this.config.timeout,\n });\n\n // Apply field filtering if fields are specified\n const responseData = response.data as BolticListResponse<RecordWithId>;\n if (queryOptions.fields && responseData.data) {\n responseData.data = filterArrayFields(\n responseData.data,\n queryOptions.fields\n ) as RecordWithId[];\n }\n\n return responseData;\n } catch (error) {\n return this.formatErrorResponse(error);\n }\n }\n\n /**\n * Update records by filters\n */\n async updateRecords(\n request: RecordUpdateOptions & { table_id?: string },\n dbId?: string\n ): Promise<BolticListResponse<RecordWithId> | BolticErrorResponse> {\n try {\n const { table_id, set, filters, fields, show_decrypted, ...rest } =\n request;\n\n if (!table_id) {\n return this.formatErrorResponse(\n new Error('table_id is required for update operation')\n );\n }\n\n // Transform payload to use 'updates' instead of 'set' for API\n const apiPayload: Record<string, unknown> = {\n updates: set,\n filters,\n ...rest,\n };\n\n // Only include fields if specified\n if (fields) {\n apiPayload.fields = fields;\n }\n\n const endpoint = RECORD_ENDPOINTS.update;\n let url = `${this.baseURL}${buildRecordEndpointPath(endpoint, { table_id })}`;\n\n const queryParams = new URLSearchParams();\n if (show_decrypted) {\n queryParams.append('show_decrypted', 'true');\n }\n\n if (queryParams.toString()) {\n url += `?${queryParams.toString()}`;\n }\n\n url = addDbIdToUrl(url, dbId);\n\n const response = await this.httpAdapter.request({\n url,\n method: endpoint.method,\n headers: this.buildHeaders(),\n data: apiPayload,\n timeout: this.config.timeout,\n });\n\n // Apply field filtering if fields are specified in the request\n const responseData = response.data as BolticListResponse<RecordWithId>;\n if (fields && responseData.data) {\n responseData.data = filterArrayFields(\n responseData.data,\n fields\n ) as RecordWithId[];\n }\n\n return responseData;\n } catch (error) {\n return this.formatErrorResponse(error);\n }\n }\n\n /**\n * Update a single record by ID\n */\n async updateRecordById(\n recordId: string,\n request: RecordUpdateByIdOptions & { table_id?: string },\n dbId?: string\n ): Promise<BolticSuccessResponse<RecordWithId> | BolticErrorResponse> {\n try {\n const { table_id, show_decrypted, ...updateOptions } = request;\n\n if (!table_id) {\n return this.formatErrorResponse(\n new Error('table_id is required for updateById operation')\n );\n }\n\n const endpoint = RECORD_ENDPOINTS.updateById;\n let url = `${this.baseURL}${buildRecordEndpointPath(endpoint, {\n record_id: recordId,\n table_id,\n })}`;\n\n const queryParams = new URLSearchParams();\n if (show_decrypted) {\n queryParams.append('show_decrypted', 'true');\n }\n\n if (queryParams.toString()) {\n url += `?${queryParams.toString()}`;\n }\n\n url = addDbIdToUrl(url, dbId);\n\n const response = await this.httpAdapter.request({\n url,\n method: endpoint.method,\n headers: this.buildHeaders(),\n data: updateOptions.set,\n timeout: this.config.timeout,\n });\n\n // Apply field filtering if fields are specified\n const responseData = response.data as BolticSuccessResponse<RecordWithId>;\n if (updateOptions.fields && responseData.data) {\n responseData.data = filterObjectFields(\n responseData.data,\n updateOptions.fields\n ) as RecordWithId;\n }\n\n return responseData;\n } catch (error) {\n return this.formatErrorResponse(error);\n }\n }\n\n /**\n * Unified delete records method that supports both record_ids and filters\n */\n async deleteRecords(\n request: RecordDeleteOptions & { table_id?: string },\n dbId?: string\n ): Promise<BolticSuccessResponse<{ message: string }> | BolticErrorResponse> {\n try {\n const { table_id } = request;\n\n if (!table_id) {\n return this.formatErrorResponse(\n new Error('table_id is required for delete operation')\n );\n }\n\n // Transform the request to API format\n const transformedRequest = transformDeleteRequest(request);\n\n const endpoint = RECORD_ENDPOINTS.delete;\n let url = `${this.baseURL}${buildRecordEndpointPath(endpoint, { table_id })}`;\n url = addDbIdToUrl(url, dbId);\n\n const response = await this.httpAdapter.request({\n url,\n method: endpoint.method,\n headers: this.buildHeaders(),\n data: transformedRequest,\n timeout: this.config.timeout,\n });\n\n // Return raw response without transformation\n return response.data as BolticSuccessResponse<{ message: string }>;\n } catch (error) {\n return this.formatErrorResponse(error);\n }\n }\n\n /**\n * Delete a single record by ID\n */\n async deleteRecordById(\n recordId: string,\n request: { table_id?: string },\n dbId?: string\n ): Promise<BolticSuccessResponse<{ message: string }> | BolticErrorResponse> {\n // Use deleteRecords with a single ID\n return this.deleteRecords(\n {\n record_ids: [recordId],\n table_id: request.table_id,\n },\n dbId\n );\n }\n}\n","import {\n RecordData,\n RecordDeleteOptions,\n RecordDeleteResponse,\n RecordQueryOptions,\n RecordUpdateByIdOptions,\n RecordUpdateOptions,\n RecordWithId,\n} from '../../types/api/record';\nimport {\n ApiFilter,\n mapWhereToFilters,\n normalizeFilters,\n} from '../../utils/filters/filter-mapper';\n\n// API Request/Response interfaces\nexport interface RecordApiRequest {\n data?: RecordData;\n filters?: ApiFilter[];\n page?: {\n page_no: number;\n page_size: number;\n };\n sort?: Record<string, unknown>[];\n}\n\nexport interface RecordApiResponse {\n data: RecordWithId[];\n pagination: {\n total_count: number;\n total_pages: number;\n current_page: number;\n per_page: number;\n type: string;\n };\n}\n\nexport interface RecordInsertApiRequest {\n data: RecordData;\n}\n\nexport interface RecordInsertApiResponse {\n data: RecordWithId;\n}\n\nexport interface RecordUpdateApiRequest {\n set: RecordData;\n filters: ApiFilter[];\n}\n\nexport interface RecordUpdateApiResponse {\n data: RecordWithId[];\n}\n\nexport interface RecordUpdateByIdApiRequest {\n data: RecordData;\n}\n\nexport interface RecordUpdateByIdApiResponse {\n data: RecordWithId;\n}\n\nexport interface RecordDeleteApiRequest {\n filters?: ApiFilter[];\n record_ids?: string[];\n}\n\nexport interface RecordDeleteApiResponse {\n message: string;\n}\n\n// Transform SDK request to API format\nexport function transformInsertRequest(\n sdkRequest: RecordData\n): RecordInsertApiRequest {\n return {\n data: sdkRequest,\n };\n}\n\nexport function transformListRequest(\n sdkRequest: RecordQueryOptions\n): RecordApiRequest {\n return {\n filters: sdkRequest.filters\n ? normalizeFilters(sdkRequest.filters)\n : undefined,\n page: sdkRequest.page,\n sort: sdkRequest.sort,\n };\n}\n\nexport function transformUpdateRequest(\n sdkRequest: RecordUpdateOptions\n): RecordUpdateApiRequest {\n return {\n set: sdkRequest.set,\n filters: normalizeFilters(sdkRequest.filters),\n };\n}\n\nexport function transformUpdateByIdRequest(\n sdkRequest: RecordUpdateByIdOptions\n): RecordUpdateByIdApiRequest {\n return {\n data: sdkRequest.set,\n };\n}\n\n/**\n * Unified delete transformer that handles both record_ids and filters\n */\nexport function transformDeleteRequest(\n sdkRequest: RecordDeleteOptions & { table_id?: string }\n): RecordDeleteApiRequest {\n const result: RecordDeleteApiRequest = {};\n\n // Handle record_ids deletion\n if (sdkRequest.record_ids && sdkRequest.record_ids.length > 0) {\n result.record_ids = sdkRequest.record_ids;\n }\n\n // Handle filters deletion\n if (sdkRequest.filters) {\n if (Array.isArray(sdkRequest.filters)) {\n // If filters is already an array of filters, check if it's ApiFilter or needs conversion\n if (\n sdkRequest.filters.length > 0 &&\n typeof sdkRequest.filters[0] === 'object' &&\n 'field' in sdkRequest.filters[0] &&\n 'operator' in sdkRequest.filters[0] &&\n 'values' in sdkRequest.filters[0]\n ) {\n // Already ApiFilter format\n result.filters = sdkRequest.filters;\n } else {\n // Legacy Record<string, unknown>[] format - convert silently\n console.warn(\n 'Legacy Record<string, unknown>[] filter format detected. Please migrate to the new filter format.'\n );\n // For now, pass through and let backend handle\n result.filters = sdkRequest.filters as ApiFilter[];\n }\n } else {\n // If filters is a where clause object, convert it to API filter format\n result.filters = mapWhereToFilters(sdkRequest.filters);\n }\n }\n\n return result;\n}\n\n// Transform API response to SDK format\nexport function transformInsertResponse(\n apiResponse: RecordInsertApiResponse\n): RecordWithId {\n return apiResponse.data;\n}\n\nexport function transformListResponse(apiResponse: RecordApiResponse): {\n data: RecordWithId[];\n pagination: {\n total_count: number;\n total_pages: number;\n current_page: number;\n per_page: number;\n type: string;\n };\n} {\n return {\n data: apiResponse.data,\n pagination: apiResponse.pagination,\n };\n}\n\nexport function transformUpdateResponse(\n apiResponse: RecordUpdateApiResponse\n): RecordWithId[] {\n return apiResponse.data;\n}\n\nexport function transformUpdateByIdResponse(\n apiResponse: RecordUpdateByIdApiResponse\n): RecordWithId {\n return apiResponse.data;\n}\n\nexport function transformDeleteResponse(\n apiResponse: RecordDeleteApiResponse\n): RecordDeleteResponse {\n return {\n message: apiResponse.message,\n };\n}\n","import { RecordsApiClient } from '../../api/clients/records-api-client';\nimport { TablesApiClient } from '../../api/clients/tables-api-client';\nimport {\n RecordBulkInsertOptions,\n RecordBulkInsertResponse,\n RecordData,\n RecordDeleteOptions,\n RecordQueryOptions,\n RecordUpdateByIdOptions,\n RecordUpdateOptions,\n RecordWithId,\n} from '../../types/api/record';\nimport {\n BolticErrorResponse,\n BolticListResponse,\n BolticSuccessResponse,\n isErrorResponse,\n BaseClient,\n} from '../../../../common';\nimport { ColumnResource } from './column';\nimport { TableResource } from './table';\n\nexport class RecordResource {\n private apiClient: RecordsApiClient;\n private tablesApiClient: TablesApiClient;\n private client: BaseClient;\n\n constructor(client: BaseClient) {\n this.client = client;\n // Initialize the API client with the client's configuration\n this.apiClient = new RecordsApiClient(client.getConfig().apiKey, {\n environment: client.getConfig().environment,\n region: client.getConfig().region,\n timeout: client.getConfig().timeout,\n debug: client.getConfig().debug,\n });\n\n // Initialize the tables API client for getting table IDs\n this.tablesApiClient = new TablesApiClient(client.getConfig().apiKey, {\n environment: client.getConfig().environment,\n region: client.getConfig().region,\n timeout: client.getConfig().timeout,\n debug: client.getConfig().debug,\n });\n }\n\n /**\n * Insert a single record\n */\n async insert(\n tableName: string,\n data: RecordData,\n dbId?: string\n ): Promise<BolticSuccessResponse<RecordWithId> | BolticErrorResponse> {\n try {\n // Get table information first\n const tableInfo = await this.getTableInfo(tableName, dbId);\n if (!tableInfo) {\n return {\n error: {\n code: 'TABLE_NOT_FOUND',\n message: `Table '${tableName}' not found`,\n },\n };\n }\n\n // Get table columns to determine which fields might be missing\n const completeDataResult = await this.ensureCompleteRecordData(\n tableName,\n data\n );\n if ('error' in completeDataResult && completeDataResult.error) {\n return completeDataResult as BolticErrorResponse;\n }\n\n // Include table_id in the request payload\n const requestData = {\n ...(completeDataResult as RecordData),\n table_id: tableInfo.id,\n };\n const result = await this.apiClient.insertRecord(requestData, dbId);\n\n if (isErrorResponse(result)) {\n return result;\n }\n\n return result as BolticSuccessResponse<RecordWithId>;\n } catch (error) {\n return {\n error: {\n code: 'INSERT_ERROR',\n message:\n error instanceof Error ? error.message : 'Unknown error occurred',\n },\n };\n }\n }\n\n /**\n * Insert multiple records in bulk\n */\n async insertMany(\n tableName: string,\n records: RecordData[],\n options: RecordBulkInsertOptions = { validation: true },\n dbId?: string\n ): Promise<RecordBulkInsertResponse | BolticErrorResponse> {\n try {\n // Validate input\n if (!records || !Array.isArray(records) || records.length === 0) {\n return {\n error: {\n code: 'INVALID_INPUT',\n message: 'Records array is required and cannot be empty',\n },\n };\n }\n\n // Get table information first\n const tableInfo = await this.getTableInfo(tableName, dbId);\n if (!tableInfo) {\n return {\n error: {\n code: 'TABLE_NOT_FOUND',\n message: `Table '${tableName}' not found`,\n },\n };\n }\n\n // Send records as-is to API with validation parameter\n const result = await this.apiClient.insertManyRecords(\n records,\n tableInfo.id,\n options,\n dbId\n );\n\n if (isErrorResponse(result)) {\n return result;\n }\n\n return result as RecordBulkInsertResponse;\n } catch (error) {\n return {\n error: {\n code: 'INSERT_MANY_ERROR',\n message:\n error instanceof Error ? error.message : 'Unknown error occurred',\n },\n };\n }\n }\n\n /**\n * Get a single record by ID\n */\n async get(\n tableName: string,\n recordId: string,\n optionsOrDbId?: { show_decrypted?: boolean; dbId?: string } | string,\n dbId?: string\n ): Promise<BolticSuccessResponse<RecordWithId> | BolticErrorResponse> {\n try {\n let showDecrypted = false;\n let databaseId = dbId;\n\n if (typeof optionsOrDbId === 'string') {\n databaseId = optionsOrDbId;\n } else if (typeof optionsOrDbId === 'object') {\n showDecrypted = optionsOrDbId.show_decrypted || false;\n databaseId = optionsOrDbId.dbId || dbId;\n }\n\n // Get table information first\n const tableInfo = await this.getTableInfo(tableName, databaseId);\n if (!tableInfo) {\n return {\n error: {\n code: 'TABLE_NOT_FOUND',\n message: `Table '${tableName}' not found`,\n },\n };\n }\n\n const result = await this.apiClient.getRecord(\n recordId,\n tableInfo.id,\n { fields: undefined, show_decrypted: showDecrypted },\n databaseId\n );\n\n if (isErrorResponse(result)) {\n return result;\n }\n\n return result as BolticSuccessResponse<RecordWithId>;\n } catch (error) {\n return {\n error: {\n code: 'GET_ERROR',\n message:\n error instanceof Error ? error.message : 'Unknown error occurred',\n },\n };\n }\n }\n\n /**\n * List records with filtering and pagination\n */\n async list(\n tableName: string,\n options: RecordQueryOptions = {},\n dbId?: string\n ): Promise<BolticListResponse<RecordWithId> | BolticErrorResponse> {\n try {\n // Get table information first\n const tableInfo = await this.getTableInfo(tableName, dbId);\n if (!tableInfo) {\n return {\n error: {\n code: 'TABLE_NOT_FOUND',\n message: `Table '${tableName}' not found`,\n },\n };\n }\n\n // Include table_id in the request payload\n const requestOptions = { ...options, table_id: tableInfo.id };\n const result = await this.apiClient.listRecords(requestOptions, dbId);\n\n if (isErrorResponse(result)) {\n return result;\n }\n\n return result as BolticListResponse<RecordWithId>;\n } catch (error) {\n return {\n error: {\n code: 'LIST_ERROR',\n message:\n error instanceof Error ? error.message : 'Unknown error occurred',\n },\n };\n }\n }\n\n /**\n * Update records by filters\n */\n async update(\n tableName: string,\n options: RecordUpdateOptions,\n dbId?: string\n ): Promise<BolticListResponse<RecordWithId> | BolticErrorResponse> {\n try {\n // Get table information first\n const tableInfo = await this.getTableInfo(tableName, dbId);\n if (!tableInfo) {\n return {\n error: {\n code: 'TABLE_NOT_FOUND',\n message: `Table '${tableName}' not found`,\n },\n };\n }\n\n // Include table_id in the request payload\n const requestOptions = { ...options, table_id: tableInfo.id };\n const result = await this.apiClient.updateRecords(requestOptions, dbId);\n\n if (isErrorResponse(result)) {\n return result;\n }\n\n return result as BolticListResponse<RecordWithId>;\n } catch (error) {\n return {\n error: {\n code: 'UPDATE_ERROR',\n message:\n error instanceof Error ? error.message : 'Unknown error occurred',\n },\n };\n }\n }\n\n /**\n * Update a single record by ID\n */\n async updateById(\n tableName: string,\n recordId: string,\n data: RecordData,\n optionsOrDbId?: { show_decrypted?: boolean; dbId?: string } | string,\n dbId?: string\n ): Promise<BolticSuccessResponse<RecordWithId> | BolticErrorResponse> {\n try {\n let showDecrypted = false;\n let databaseId = dbId;\n\n if (typeof optionsOrDbId === 'string') {\n databaseId = optionsOrDbId;\n } else if (typeof optionsOrDbId === 'object') {\n showDecrypted = optionsOrDbId.show_decrypted || false;\n databaseId = optionsOrDbId.dbId || dbId;\n }\n\n // Get table information first\n const tableInfo = await this.getTableInfo(tableName, databaseId);\n if (!tableInfo) {\n return {\n error: {\n code: 'TABLE_NOT_FOUND',\n message: `Table '${tableName}' not found`,\n },\n };\n }\n\n // Include table_id in the request payload\n const requestOptions: RecordUpdateByIdOptions & { table_id: string } = {\n id: recordId,\n set: data,\n table_id: tableInfo.id,\n show_decrypted: showDecrypted,\n };\n const result = await this.apiClient.updateRecordById(\n recordId,\n requestOptions,\n databaseId\n );\n\n if (isErrorResponse(result)) {\n return result;\n }\n\n return result as BolticSuccessResponse<RecordWithId>;\n } catch (error) {\n return {\n error: {\n code: 'UPDATE_BY_ID_ERROR',\n message:\n error instanceof Error ? error.message : 'Unknown error occurred',\n },\n };\n }\n }\n\n /**\n * Unified delete method that supports both record IDs and filters\n */\n async delete(\n tableName: string,\n options: RecordDeleteOptions,\n dbId?: string\n ): Promise<BolticSuccessResponse<{ message: string }> | BolticErrorResponse> {\n try {\n // Get table information first\n const tableInfo = await this.getTableInfo(tableName, dbId);\n if (!tableInfo) {\n return {\n error: {\n code: 'TABLE_NOT_FOUND',\n message: `Table '${tableName}' not found`,\n },\n };\n }\n\n // Include table_id in the request payload\n const requestOptions = { ...options, table_id: tableInfo.id };\n const result = await this.apiClient.deleteRecords(requestOptions, dbId);\n\n if (isErrorResponse(result)) {\n return result;\n }\n\n return result as BolticSuccessResponse<{ message: string }>;\n } catch (error) {\n return {\n error: {\n code: 'DELETE_ERROR',\n message:\n error instanceof Error ? error.message : 'Unknown error occurred',\n },\n };\n }\n }\n\n /**\n * Delete a single record by ID\n */\n async deleteById(\n tableName: string,\n recordId: string,\n dbId?: string\n ): Promise<BolticSuccessResponse<{ message: string }> | BolticErrorResponse> {\n try {\n // Get table information first\n const tableInfo = await this.getTableInfo(tableName, dbId);\n if (!tableInfo) {\n return {\n error: {\n code: 'TABLE_NOT_FOUND',\n message: `Table '${tableName}' not found`,\n },\n };\n }\n\n const result = await this.apiClient.deleteRecordById(\n recordId,\n {\n table_id: tableInfo.id,\n },\n dbId\n );\n\n if (isErrorResponse(result)) {\n return result;\n }\n\n return result as BolticSuccessResponse<{ message: string }>;\n } catch (error) {\n return {\n error: {\n code: 'DELETE_BY_ID_ERROR',\n message:\n error instanceof Error ? error.message : 'Unknown error occurred',\n },\n };\n }\n }\n\n /**\n * Helper method to get table information by name\n */\n private async getTableInfo(\n tableName: string,\n dbId?: string\n ): Promise<{ id: string; snapshot_url?: string } | null> {\n try {\n // Use the table resource to find the table by name\n const tableResource = new TableResource(this.client);\n const tableResult = await tableResource.findByName(tableName, dbId);\n\n if (tableResult.data) {\n return {\n id: tableResult.data.id,\n snapshot_url: tableResult.data.snapshot_url,\n };\n }\n\n return null;\n } catch (error) {\n console.error('Error getting table info:', error);\n return null;\n }\n }\n\n /**\n * Helper method to ensure all required fields for a record are present,\n * filling missing ones with null.\n */\n private async ensureCompleteRecordData(\n tableName: string,\n data: RecordData\n ): Promise<RecordData | BolticErrorResponse> {\n try {\n const columnResource = new ColumnResource(this.client);\n const columnsResult = await columnResource.findAll(tableName);\n\n if (isErrorResponse(columnsResult)) {\n return columnsResult;\n }\n\n // Get the actual columns array from the response\n const columns = Array.isArray(columnsResult.data)\n ? columnsResult.data\n : [];\n\n // Create complete data object with all table columns\n const completeData: RecordData = { ...data };\n\n // Set missing fields to null (only for columns that are not system-generated)\n for (const column of columns) {\n // Skip system columns that are auto-generated\n if (\n column.name === 'id' ||\n column.name === 'created_at' ||\n column.name === 'updated_at'\n ) {\n continue;\n }\n\n // If field is missing from provided data, set it to null\n if (!(column.name in data)) {\n completeData[column.name] = null;\n }\n }\n\n return completeData;\n } catch (error) {\n return {\n error: {\n code: 'COMPLETE_DATA_ERROR',\n message:\n error instanceof Error ? error.message : 'Unknown error occurred',\n },\n };\n }\n }\n}\n","import {\n RecordData,\n RecordQueryOptions,\n RecordUpdateOptions,\n RecordWithId,\n} from '../../types/api/record';\nimport {\n type BolticErrorResponse,\n type BolticListResponse,\n type BolticSuccessResponse,\n} from '../../../../common';\nimport { RecordResource } from './record';\n\nexport interface RecordBuilderOptions {\n tableName: string;\n recordResource: RecordResource;\n}\n\n/**\n * Record Builder - provides a fluent interface for building record queries and operations\n */\nexport class RecordBuilder {\n private tableName: string;\n private recordResource: RecordResource;\n private queryOptions: RecordQueryOptions = {};\n private updateData: RecordData = {};\n\n constructor(options: RecordBuilderOptions) {\n this.tableName = options.tableName;\n this.recordResource = options.recordResource;\n }\n\n /**\n * Add filter conditions\n */\n where(conditions: Record<string, unknown>): RecordBuilder {\n if (!this.queryOptions.filters) {\n this.queryOptions.filters = [];\n }\n\n // Convert conditions to filter format\n Object.entries(conditions).forEach(([field, value]) => {\n this.queryOptions.filters!.push({\n field,\n operator: 'equals',\n values: [value],\n });\n });\n\n return this;\n }\n\n /**\n * Set sorting\n */\n orderBy(field: string, direction: 'asc' | 'desc' = 'asc'): RecordBuilder {\n if (!this.queryOptions.sort) {\n this.queryOptions.sort = [];\n }\n this.queryOptions.sort.push({ field, order: direction });\n return this;\n }\n\n /**\n * Set limit (using page)\n */\n limit(count: number): RecordBuilder {\n if (!this.queryOptions.page) {\n this.queryOptions.page = { page_no: 1, page_size: count };\n } else {\n this.queryOptions.page.page_size = count;\n }\n return this;\n }\n\n /**\n * Set offset (using page)\n */\n offset(count: number): RecordBuilder {\n if (!this.queryOptions.page) {\n this.queryOptions.page = {\n page_no: Math.floor(count / 50) + 1,\n page_size: 50,\n };\n } else {\n // Calculate page number based on offset and page size\n const pageSize = this.queryOptions.page.page_size || 50;\n this.queryOptions.page.page_no = Math.floor(count / pageSize) + 1;\n }\n return this;\n }\n\n /**\n * Set fields to select\n */\n select(fields: string[]): RecordBuilder {\n this.queryOptions.fields = fields;\n return this;\n }\n\n /**\n * Set data for update operations\n */\n set(data: RecordData): RecordBuilder {\n this.updateData = { ...this.updateData, ...data };\n return this;\n }\n\n /**\n * Set pagination\n */\n page(pageNo: number, pageSize: number = 50): RecordBuilder {\n this.queryOptions.page = {\n page_no: pageNo,\n page_size: pageSize,\n };\n return this;\n }\n\n /**\n * Execute list operation (was findAll)\n */\n async list(): Promise<\n BolticListResponse<RecordWithId> | BolticErrorResponse\n > {\n return this.recordResource.list(this.tableName, this.queryOptions);\n }\n\n /**\n * Execute findAll operation (alias for list)\n */\n async findAll(): Promise<\n BolticListResponse<RecordWithId> | BolticErrorResponse\n > {\n return this.recordResource.list(this.tableName, this.queryOptions);\n }\n\n /**\n * Execute findOne operation by getting first result from list\n */\n async findOne(): Promise<\n BolticSuccessResponse<RecordWithId | null> | BolticErrorResponse\n > {\n // Use limit 1 to get just one record\n const queryOptions = { ...this.queryOptions, limit: 1 };\n const result = await this.recordResource.list(this.tableName, queryOptions);\n\n if ('error' in result) {\n return result as BolticErrorResponse;\n }\n\n // Return the first record or null in success format\n const record = result.data.length > 0 ? result.data[0] : null;\n return {\n data: record,\n message: record ? 'Record found' : 'No record found',\n };\n }\n\n /**\n * Build where conditions from filters for API consumption\n */\n private buildWhereConditions(): Record<string, unknown> {\n const where: Record<string, unknown> = {};\n\n if (this.queryOptions.filters) {\n this.queryOptions.filters.forEach((filter) => {\n // Handle both ApiFilter and legacy Record<string, unknown> formats\n if ('field' in filter && 'values' in filter) {\n // ApiFilter format\n const apiFilter = filter as {\n field: string;\n operator: string;\n values: unknown[];\n };\n const fieldName = String(apiFilter.field);\n if (apiFilter.operator === 'equals') {\n where[fieldName] = apiFilter.values[0];\n } else if (apiFilter.operator === 'contains') {\n where[fieldName] = { $like: `%${String(apiFilter.values[0])}%` };\n } else {\n // For other operators, convert them appropriately\n where[fieldName] = apiFilter.values[0];\n }\n } else {\n // Legacy Record<string, unknown> format\n Object.assign(where, filter);\n }\n });\n }\n\n return where;\n }\n\n /**\n * Execute update operation - requires filters or record IDs\n */\n async update(): Promise<\n BolticListResponse<RecordWithId> | BolticErrorResponse\n > {\n if (!this.updateData) {\n return {\n error: {\n code: 'MISSING_UPDATE_DATA',\n message: 'Update data is required for update operation',\n },\n } as unknown as BolticErrorResponse;\n }\n\n const updateOptions: RecordUpdateOptions = {\n set: this.updateData,\n filters: this.queryOptions.filters || [],\n };\n\n return this.recordResource.update(this.tableName, updateOptions);\n }\n\n /**\n * Execute update by ID operation\n */\n async updateById(\n id: string\n ): Promise<BolticSuccessResponse<RecordWithId> | BolticErrorResponse> {\n return this.recordResource.updateById(this.tableName, id, this.updateData);\n }\n\n /**\n * Execute delete by single ID operation\n */\n async deleteById(\n id: string\n ): Promise<BolticSuccessResponse<{ message: string }> | BolticErrorResponse> {\n return this.recordResource.deleteById(this.tableName, id);\n }\n\n /**\n * Execute delete by IDs operation\n */\n async deleteByIds(\n ids: string[]\n ): Promise<BolticSuccessResponse<{ message: string }> | BolticErrorResponse> {\n return this.recordResource.delete(this.tableName, { record_ids: ids });\n }\n\n /**\n * Execute delete operation using filters\n */\n async delete(): Promise<\n BolticSuccessResponse<{ message: string }> | BolticErrorResponse\n > {\n if (!this.queryOptions.filters || this.queryOptions.filters.length === 0) {\n return {\n error: {\n code: 'MISSING_DELETE_CONDITIONS',\n message:\n 'Filter conditions are required for delete operation. Use where() to specify conditions.',\n },\n };\n }\n\n const deleteOptions = {\n filters: this.buildWhereConditions(),\n };\n\n return this.recordResource.delete(this.tableName, deleteOptions);\n }\n\n /**\n * Get the built query options (for debugging)\n */\n getQueryOptions(): RecordQueryOptions {\n return { ...this.queryOptions };\n }\n\n /**\n * Get the update data (for debugging)\n */\n getUpdateData(): RecordData {\n return { ...this.updateData };\n }\n\n /**\n * Execute insert operation\n */\n async insert(\n data: RecordData\n ): Promise<BolticSuccessResponse<RecordWithId> | BolticErrorResponse> {\n return this.recordResource.insert(this.tableName, data);\n }\n}\n\n/**\n * Create a new record builder\n */\nexport function createRecordBuilder(\n options: RecordBuilderOptions\n): RecordBuilder {\n return new RecordBuilder(options);\n}\n","export interface ApiEndpoint {\n path: string;\n method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';\n authenticated: boolean;\n rateLimit?: {\n requests: number;\n window: number; // in milliseconds\n };\n}\n\nexport interface SqlEndpoints {\n textToSQL: ApiEndpoint;\n executeSQL: ApiEndpoint;\n}\n\nexport const SQL_ENDPOINTS: SqlEndpoints = {\n textToSQL: {\n path: '/tables/query/text-to-sql',\n method: 'POST',\n authenticated: true,\n rateLimit: { requests: 100, window: 60000 }, // Limited due to AI processing\n },\n executeSQL: {\n path: '/tables/query/execute',\n method: 'POST',\n authenticated: true,\n rateLimit: { requests: 200, window: 60000 },\n },\n};\n\n/**\n * Build SQL endpoint path - all SQL endpoints are simple paths without parameters\n */\nexport const buildSqlEndpointPath = (\n endpoint: ApiEndpoint,\n params: Record<string, string> = {}\n): string => {\n let path = endpoint.path;\n\n // Replace path parameters if any (though SQL endpoints don't currently use them)\n Object.entries(params).forEach(([key, value]) => {\n path = path.replace(`{${key}}`, encodeURIComponent(value));\n });\n\n return path;\n};\n","import {\n ExecuteSQLApiRequest,\n ExecuteSQLApiResponse,\n TextToSQLApiRequest,\n TextToSQLApiResponse,\n} from '../../types/api/sql';\nimport {\n BaseApiClient,\n type BaseApiClientConfig,\n type BolticErrorResponse,\n} from '../../../../common';\nimport { SQL_ENDPOINTS, buildSqlEndpointPath } from '../endpoints/sql';\n\nexport interface SqlApiClientConfig extends BaseApiClientConfig {}\n\n/**\n * SQL API Client - handles all SQL-related API operations\n */\nexport class SqlApiClient extends BaseApiClient {\n constructor(apiKey: string, config: Omit<SqlApiClientConfig, 'apiKey'> = {}) {\n super(apiKey, config);\n }\n\n /**\n * Convert natural language to SQL query (streaming)\n */\n async textToSQL(\n request: TextToSQLApiRequest,\n dbId?: string\n ): Promise<AsyncIterable<string> | BolticErrorResponse> {\n try {\n const endpoint = SQL_ENDPOINTS.textToSQL;\n let url = `${this.baseURL}${buildSqlEndpointPath(endpoint)}`;\n\n if (dbId) {\n url += `?db_id=${encodeURIComponent(dbId)}`;\n }\n\n // For now, make a regular request and simulate streaming\n // TODO: Implement proper streaming when backend supports it\n const response = await this.httpAdapter.request({\n url,\n method: endpoint.method,\n headers: {\n ...this.buildHeaders(),\n 'x-request-source': 'sdk',\n },\n data: request,\n timeout: this.config.timeout,\n });\n\n // Check for error response\n if (response.status >= 400) {\n return this.formatErrorResponse(\n {\n response: { data: response.data, status: response.status },\n },\n 'SQL'\n );\n }\n\n // Convert to AsyncIterable for streaming interface\n const sqlResponse = response.data as TextToSQLApiResponse;\n return this.createAsyncIterable(sqlResponse.data);\n } catch (error) {\n return this.formatErrorResponse(error, 'SQL');\n }\n }\n\n /**\n * Execute SQL query\n */\n async executeSQL(\n request: ExecuteSQLApiRequest,\n dbId?: string\n ): Promise<ExecuteSQLApiResponse | BolticErrorResponse> {\n try {\n const endpoint = SQL_ENDPOINTS.executeSQL;\n let url = `${this.baseURL}${buildSqlEndpointPath(endpoint)}`;\n\n if (dbId) {\n url += `?db_id=${encodeURIComponent(dbId)}`;\n }\n\n const response = await this.httpAdapter.request({\n url,\n method: endpoint.method,\n headers: {\n ...this.buildHeaders(),\n 'x-request-source': 'sdk',\n },\n data: request,\n timeout: this.config.timeout,\n });\n\n // Check for error response\n if (response.status >= 400) {\n return this.formatErrorResponse(\n {\n response: { data: response.data, status: response.status },\n },\n 'SQL'\n );\n }\n\n // Return raw response without transformation\n return response.data as ExecuteSQLApiResponse;\n } catch (error) {\n return this.formatErrorResponse(error, 'SQL');\n }\n }\n\n /**\n * Helper method to create AsyncIterable from string data\n * TODO: Replace with proper streaming implementation when backend supports it\n */\n private async *createAsyncIterable(data: string): AsyncIterable<string> {\n // For now, just yield the complete string\n // In the future, this could be replaced with actual streaming chunks\n yield data;\n }\n}\n","import { SqlApiClient } from '../../api/clients/sql-api-client';\nimport { transformTextToSQLRequest } from '../../api/transformers/sql';\nimport { ExecuteSQLApiResponse } from '../../types/api/sql';\nimport {\n isErrorResponse,\n BaseClient,\n type BolticErrorResponse,\n} from '../../../../common';\nimport { TextToSQLOptions } from '../../types/sql';\n\nexport class SqlResource {\n private sqlApiClient: SqlApiClient;\n\n constructor(client: BaseClient) {\n // Initialize the SQL API client with the client's configuration\n const config = client.getConfig();\n this.sqlApiClient = new SqlApiClient(config.apiKey, {\n environment: config.environment,\n region: config.region,\n timeout: config.timeout,\n debug: config.debug,\n retryAttempts: config.retryAttempts,\n retryDelay: config.retryDelay,\n headers: config.headers,\n });\n }\n\n /**\n * Convert natural language to SQL query\n * Returns streaming results for real-time query generation\n *\n * @param prompt - Natural language description of the desired query\n * @param options - Optional parameters including currentQuery for refinement\n * @returns AsyncIterable<string> for streaming SQL generation\n *\n */\n async textToSQL(\n prompt: string,\n options: TextToSQLOptions = {},\n dbId?: string\n ): Promise<AsyncIterable<string>> {\n const request = transformTextToSQLRequest(prompt, options);\n const response = await this.sqlApiClient.textToSQL(request, dbId);\n\n // Check if response is an error by checking for the error property\n if ('error' in response && response.error !== undefined) {\n throw response; // Throw the API response directly\n }\n\n return response as AsyncIterable<string>;\n }\n\n /**\n * Execute SQL query with built-in safety measures and performance optimization\n *\n * @param query - SQL query string to execute\n * @returns Promise<ExecuteSQLApiResponse> with raw API response following Boltic API Response Structure\n *\n */\n async executeSQL(\n query: string,\n dbId?: string\n ): Promise<ExecuteSQLApiResponse | BolticErrorResponse> {\n const response = await this.sqlApiClient.executeSQL({ query }, dbId);\n\n if (isErrorResponse(response)) {\n return response; // Return error response for caller to handle\n }\n\n return response; // Return raw API response following Boltic API Response Structure\n }\n}\n","import { TextToSQLApiRequest } from '../../types/api/sql';\nimport { TextToSQLOptions } from '../../types/sql';\n\n/**\n * Transform SDK text-to-SQL options to API request\n */\nexport function transformTextToSQLRequest(\n prompt: string,\n options: TextToSQLOptions = {}\n): TextToSQLApiRequest {\n return {\n prompt,\n current_query: options.currentQuery,\n };\n}\n","import { TablesApiClient } from '../../api/clients/tables-api-client';\nimport {\n ValidationError,\n type BolticErrorResponse,\n type BolticSuccessResponse,\n} from '../../../../common';\nimport {\n FieldDefinition,\n TableCreateRequest,\n TableCreateResponse,\n} from '../../types/api/table';\n\nexport interface TableBuilderOptions {\n name: string;\n description?: string;\n is_ai_generated_schema?: boolean;\n}\n\n/**\n * Table Builder - provides a fluent interface for creating tables\n */\nexport class TableBuilder {\n private tableName: string;\n private description?: string;\n private fields: FieldDefinition[] = [];\n private tablesApiClient?: TablesApiClient;\n\n constructor(options: TableBuilderOptions, tablesApiClient?: TablesApiClient) {\n this.tableName = options.name;\n this.description = options.description;\n this.tablesApiClient = tablesApiClient;\n }\n\n /**\n * Set table name\n */\n name(name: string): TableBuilder {\n this.tableName = name;\n return this;\n }\n\n /**\n * Set table description\n */\n describe(description: string): TableBuilder {\n this.description = description;\n return this;\n }\n\n /**\n * Add a text field\n */\n text(\n name: string,\n options: {\n nullable?: boolean;\n unique?: boolean;\n indexed?: boolean;\n defaultValue?: string;\n description?: string;\n alignment?: 'left' | 'center' | 'right';\n } = {}\n ): TableBuilder {\n this.fields.push({\n name,\n type: 'text',\n is_nullable: options.nullable ?? true,\n is_unique: options.unique ?? false,\n is_indexed: options.indexed ?? false,\n is_primary_key: false,\n default_value: options.defaultValue,\n description: options.description,\n alignment: options.alignment || 'left',\n field_order: this.fields.length + 1,\n });\n return this;\n }\n\n /**\n * Add a long text field\n */\n longText(\n name: string,\n options: {\n nullable?: boolean;\n description?: string;\n alignment?: 'left' | 'center' | 'right';\n } = {}\n ): TableBuilder {\n this.fields.push({\n name,\n type: 'long-text',\n is_nullable: options.nullable ?? true,\n is_unique: false,\n is_indexed: false,\n is_primary_key: false,\n description: options.description,\n alignment: options.alignment || 'left',\n field_order: this.fields.length + 1,\n });\n return this;\n }\n\n /**\n * Add a number field\n */\n number(\n name: string,\n options: {\n nullable?: boolean;\n unique?: boolean;\n indexed?: boolean;\n defaultValue?: number;\n description?: string;\n decimals?: string;\n alignment?: 'left' | 'center' | 'right';\n } = {}\n ): TableBuilder {\n this.fields.push({\n name,\n type: 'number',\n is_nullable: options.nullable ?? true,\n is_unique: options.unique ?? false,\n is_indexed: options.indexed ?? false,\n is_primary_key: false,\n default_value: options.defaultValue,\n description: options.description,\n decimals: options.decimals,\n alignment: options.alignment || 'right',\n field_order: this.fields.length + 1,\n });\n return this;\n }\n\n /**\n * Add a currency field\n */\n currency(\n name: string,\n options: {\n nullable?: boolean;\n defaultValue?: number;\n description?: string;\n currencyFormat?: string;\n decimals?: string;\n } = {}\n ): TableBuilder {\n this.fields.push({\n name,\n type: 'currency',\n is_nullable: options.nullable ?? true,\n is_unique: false,\n is_indexed: false,\n is_primary_key: false,\n default_value: options.defaultValue,\n description: options.description,\n currency_format: options.currencyFormat,\n decimals: options.decimals,\n alignment: 'right',\n field_order: this.fields.length + 1,\n });\n return this;\n }\n\n /**\n * Add a checkbox field\n */\n checkbox(\n name: string,\n options: {\n nullable?: boolean;\n defaultValue?: boolean;\n description?: string;\n } = {}\n ): TableBuilder {\n this.fields.push({\n name,\n type: 'checkbox',\n is_nullable: options.nullable ?? true,\n is_unique: false,\n is_indexed: false,\n is_primary_key: false,\n default_value: options.defaultValue,\n description: options.description,\n alignment: 'center',\n field_order: this.fields.length + 1,\n });\n return this;\n }\n\n /**\n * Add a dropdown field\n */\n dropdown(\n name: string,\n items: string[],\n options: {\n nullable?: boolean;\n multiple?: boolean;\n defaultValue?: string | string[];\n description?: string;\n } = {}\n ): TableBuilder {\n this.fields.push({\n name,\n type: 'dropdown',\n is_nullable: options.nullable ?? true,\n is_unique: false,\n is_indexed: false,\n is_primary_key: false,\n default_value: options.defaultValue,\n description: options.description,\n selection_source: 'provide-static-list',\n selectable_items: items,\n multiple_selections: options.multiple ?? false,\n alignment: 'left',\n field_order: this.fields.length + 1,\n });\n return this;\n }\n\n /**\n * Add an email field\n */\n email(\n name: string,\n options: {\n nullable?: boolean;\n unique?: boolean;\n indexed?: boolean;\n description?: string;\n } = {}\n ): TableBuilder {\n this.fields.push({\n name,\n type: 'email',\n is_nullable: options.nullable ?? true,\n is_unique: options.unique ?? false,\n is_indexed: options.indexed ?? false,\n is_primary_key: false,\n description: options.description,\n alignment: 'left',\n field_order: this.fields.length + 1,\n });\n return this;\n }\n\n /**\n * Add a phone number field\n */\n phone(\n name: string,\n options: {\n nullable?: boolean;\n description?: string;\n format?: string;\n } = {}\n ): TableBuilder {\n this.fields.push({\n name,\n type: 'phone-number',\n is_nullable: options.nullable ?? true,\n is_unique: false,\n is_indexed: false,\n is_primary_key: false,\n description: options.description,\n phone_format: options.format,\n alignment: 'left',\n field_order: this.fields.length + 1,\n });\n return this;\n }\n\n /**\n * Add a link field\n */\n link(\n name: string,\n options: {\n nullable?: boolean;\n description?: string;\n } = {}\n ): TableBuilder {\n this.fields.push({\n name,\n type: 'link',\n is_nullable: options.nullable ?? true,\n is_unique: false,\n is_indexed: false,\n is_primary_key: false,\n description: options.description,\n alignment: 'left',\n field_order: this.fields.length + 1,\n });\n return this;\n }\n\n /**\n * Add a JSON field\n */\n json(\n name: string,\n options: {\n nullable?: boolean;\n description?: string;\n } = {}\n ): TableBuilder {\n this.fields.push({\n name,\n type: 'json',\n is_nullable: options.nullable ?? true,\n is_unique: false,\n is_indexed: false,\n is_primary_key: false,\n description: options.description,\n alignment: 'left',\n field_order: this.fields.length + 1,\n });\n return this;\n }\n\n /**\n * Add a date-time field\n */\n dateTime(\n name: string,\n options: {\n nullable?: boolean;\n description?: string;\n dateFormat?: string;\n timeFormat?: string;\n timezone?: string;\n } = {}\n ): TableBuilder {\n this.fields.push({\n name,\n type: 'date-time',\n is_nullable: options.nullable ?? true,\n is_unique: false,\n is_indexed: false,\n is_primary_key: false,\n description: options.description,\n date_format: options.dateFormat,\n time_format: options.timeFormat,\n timezone: options.timezone,\n alignment: 'left',\n field_order: this.fields.length + 1,\n });\n return this;\n }\n\n /**\n * Add a vector field\n */\n vector(\n name: string,\n dimension: number,\n options: {\n nullable?: boolean;\n description?: string;\n } = {}\n ): TableBuilder {\n this.fields.push({\n name,\n type: 'vector',\n is_nullable: options.nullable ?? true,\n is_unique: false,\n is_indexed: false,\n is_primary_key: false,\n description: options.description,\n vector_dimension: dimension,\n alignment: 'left',\n field_order: this.fields.length + 1,\n });\n return this;\n }\n\n /**\n * Add a custom field\n */\n addField(field: FieldDefinition): TableBuilder {\n this.fields.push({\n ...field,\n field_order: field.field_order || this.fields.length + 1,\n });\n return this;\n }\n\n /**\n * Remove a field by name\n */\n removeField(name: string): TableBuilder {\n this.fields = this.fields.filter((field) => field.name !== name);\n // Reorder remaining fields\n this.fields.forEach((field, index) => {\n field.field_order = index + 1;\n });\n return this;\n }\n\n /**\n * Get current fields\n */\n getFields(): FieldDefinition[] {\n return [...this.fields];\n }\n\n /**\n * Get current table name\n */\n getName(): string {\n return this.tableName;\n }\n\n /**\n * Get current description\n */\n getDescription(): string | undefined {\n return this.description;\n }\n\n /**\n * Build the table request object\n */\n build(): TableCreateRequest {\n if (!this.tableName) {\n throw new ValidationError('Table name is required', [\n { field: 'name', message: 'Table name cannot be empty' },\n ]);\n }\n\n if (this.fields.length === 0) {\n throw new ValidationError('At least one field is required', [\n { field: 'fields', message: 'Table must have at least one field' },\n ]);\n }\n\n return {\n name: this.tableName,\n description: this.description,\n fields: this.fields,\n };\n }\n\n /**\n * Build and create the table (requires API client)\n */\n async create(\n options: { is_ai_generated_schema?: boolean; is_template?: boolean } = {}\n ): Promise<BolticSuccessResponse<TableCreateResponse> | BolticErrorResponse> {\n if (!this.tablesApiClient) {\n throw new Error('TablesApiClient is required for table creation');\n }\n const request = this.build();\n return this.tablesApiClient.createTable(request, options);\n }\n}\n\n/**\n * Create a new table builder\n */\nexport function createTableBuilder(\n options: TableBuilderOptions,\n tablesApiClient?: TablesApiClient\n): TableBuilder {\n return new TableBuilder(options, tablesApiClient);\n}\n","/** Polling interval in milliseconds between execution status checks */\nexport const POLLING_INTERVAL_MS = 1000;\n\n/** Maximum number of polling attempts before a timeout error is returned */\nexport const MAX_POLLING_ATTEMPTS = 30;\n\n/** Default retry configuration applied to every activity execution */\nexport const DEFAULT_RETRY_CONFIG = {\n maximum_attempts: 1,\n backoff_coefficient: 2,\n initial_interval: 1000,\n maximum_interval: 100000,\n} as const;\n\n/** Whether activity execution should continue on failure */\nexport const CONTINUE_ON_FAILURE = true;\n\nexport const SCHEMA_TYPE_MAPPING = {\n string: { type: 'string', fallback_value: '' },\n number: { type: 'number', fallback_value: '' },\n boolean: { type: 'boolean', secondary_type: 'string', fallback_value: '' },\n int: { type: 'number', fallback_value: '' },\n integer: { type: 'number', fallback_value: '' },\n 'date-time': { type: 'date-time', secondary_type: 'string', fallback_value: '' },\n date: { type: 'date', secondary_type: 'string', fallback_value: '' },\n json: { type: 'object', fallback_value: {} },\n text: { type: 'string', fallback_value: '' },\n email: { type: 'string', fallback_value: '' },\n password: { type: 'string', fallback_value: '' },\n url: { type: 'string', fallback_value: '' },\n textarea: { type: 'string', fallback_value: '' },\n select: { type: 'string', fallback_value: '' },\n multiselect: { type: 'string', fallback_value: '' },\n autocomplete: { type: 'array', fallback_value: [] },\n radio: { type: 'string', fallback_value: '' },\n radiobuttons: { type: 'string', fallback_value: '' },\n checkbox: { type: 'array', fallback_value: [] },\n toggle: { type: 'boolean', fallback_value: '' },\n hidden: { type: 'string', fallback_value: '' },\n slider: { type: 'number', fallback_value: '' },\n datepicker: { type: 'string', fallback_value: '' },\n phoneinput: { type: 'string', fallback_value: '' },\n time: { type: 'string', fallback_value: '' },\n datetime: { type: 'string', fallback_value: '' },\n code: { type: 'string', fallback_value: '' },\n multitext: { type: 'array', fallback_value: [] },\n array: { type: 'array', fallback_value: [] },\n keyvalue: { type: 'object', fallback_value: {} },\n object: { type: 'object', fallback_value: {} },\n phone: { type: 'string', fallback_value: '' },\n 'number[]': { type: 'string', fallback_value: '' },\n 'number []': { type: 'string', fallback_value: '' },\n 'object | any': { type: 'string', fallback_value: '' },\n}\n","/**\n * Workflow API endpoint definitions.\n * Paths use `{param}` placeholders resolved at request time.\n */\n\nimport type { WorkflowApiEndpoint } from '../../types/workflow';\n\nexport interface WorkflowEndpoints {\n executeActivity: WorkflowApiEndpoint;\n getExecutionById: WorkflowApiEndpoint;\n getIntegrations: WorkflowApiEndpoint;\n getCredentials: WorkflowApiEndpoint;\n getIntegrationResource: WorkflowApiEndpoint;\n getIntegrationForm: WorkflowApiEndpoint;\n}\n\nexport const WORKFLOW_ENDPOINTS: WorkflowEndpoints = {\n executeActivity: {\n path: '/workflows/execute/activity',\n method: 'POST',\n authenticated: true,\n },\n getExecutionById: {\n path: '/workflows/run/{run_id}',\n method: 'GET',\n authenticated: true,\n },\n getIntegrations: {\n path: '/integrations',\n method: 'GET',\n authenticated: true,\n },\n getCredentials: {\n path: '/integrations/entity/{entity}',\n method: 'GET',\n authenticated: true,\n },\n getIntegrationResource: {\n path: '/integrations/{integration_slug}/schema',\n method: 'GET',\n authenticated: true,\n },\n getIntegrationForm: {\n path: '/integrations/{integration_slug}/fields',\n method: 'GET',\n authenticated: true,\n },\n};\n\n/** Resolve `{param}` placeholders in an endpoint path */\nexport function buildWorkflowEndpointPath(\n endpoint: WorkflowApiEndpoint,\n params: Record<string, string> = {}\n): string {\n let path = endpoint.path;\n for (const [key, value] of Object.entries(params)) {\n path = path.replace(`{${key}}`, value);\n }\n return path;\n}\n","/**\n * Workflow API Client\n * Extends BaseApiClient — shares auth, headers, error handling, and HTTP\n * infrastructure with the rest of the SDK via the common module.\n */\n\nimport {\n BaseApiClient,\n SERVICE_PATHS,\n type BaseApiClientConfig,\n type BolticErrorResponse,\n type BolticSuccessResponse,\n} from '../../../../common';\nimport type {\n CredentialsListData,\n ExecuteActivityRequestBody,\n ExecuteActivityResponseData,\n GetCredentialsParams,\n GetIntegrationFormParams,\n GetIntegrationResourceParams,\n GetIntegrationsParams,\n IntegrationExecutionData,\n IntegrationFormData,\n IntegrationResourceData,\n IntegrationsListData,\n} from '../../types/workflow';\nimport {\n WORKFLOW_ENDPOINTS,\n buildWorkflowEndpointPath,\n} from '../endpoints/workflows';\n\ntype WorkflowResponse<T> = BolticSuccessResponse<T> | BolticErrorResponse;\n\nexport class WorkflowApiClient extends BaseApiClient {\n private integrationBaseURL: string;\n\n constructor(\n apiKey: string,\n config: Omit<BaseApiClientConfig, 'apiKey'> = {}\n ) {\n super(apiKey, config, SERVICE_PATHS.WORKFLOW_TEMPORAL);\n this.integrationBaseURL = this.resolveAdditionalServiceURL(\n SERVICE_PATHS.INTEGRATION\n );\n }\n\n /**\n * Execute a workflow activity.\n *\n * @param body - The execute-activity request body\n */\n async executeActivity(\n body: ExecuteActivityRequestBody\n ): Promise<WorkflowResponse<ExecuteActivityResponseData>> {\n try {\n const endpoint = WORKFLOW_ENDPOINTS.executeActivity;\n const url = `${this.baseURL}${endpoint.path}`;\n\n const response = await this.httpAdapter.request<\n WorkflowResponse<ExecuteActivityResponseData>\n >({\n url,\n method: endpoint.method,\n headers: this.buildHeaders(),\n data: body,\n timeout: this.config.timeout,\n });\n\n return response.data;\n } catch (error: unknown) {\n return this.formatErrorResponse(error, 'WORKFLOW');\n }\n }\n\n /**\n * Fetch the result of a workflow execution by its run ID.\n *\n * @param runId - The execution run ID returned by `executeActivity`\n */\n async getExecutionById(\n runId: string\n ): Promise<WorkflowResponse<IntegrationExecutionData>> {\n try {\n const endpoint = WORKFLOW_ENDPOINTS.getExecutionById;\n const path = buildWorkflowEndpointPath(endpoint, { run_id: runId });\n const url = `${this.baseURL}${path}`;\n\n const response = await this.httpAdapter.request<\n WorkflowResponse<IntegrationExecutionData>\n >({\n url,\n method: endpoint.method,\n headers: this.buildHeaders(),\n timeout: this.config.timeout,\n });\n\n return response.data;\n } catch (error: unknown) {\n return this.formatErrorResponse(error, 'WORKFLOW');\n }\n }\n\n /**\n * Fetch the list of available integrations.\n *\n * @param params - Optional pagination parameters\n */\n async getIntegrations(\n params: GetIntegrationsParams = {}\n ): Promise<WorkflowResponse<IntegrationsListData>> {\n try {\n const endpoint = WORKFLOW_ENDPOINTS.getIntegrations;\n const query = new URLSearchParams({\n page: String(params.page ?? 1),\n per_page: String(params.per_page ?? 999),\n });\n const url = `${this.baseURL}${endpoint.path}?${query.toString()}`;\n\n const response = await this.httpAdapter.request<\n WorkflowResponse<IntegrationsListData>\n >({\n url,\n method: endpoint.method,\n headers: this.buildHeaders(),\n timeout: this.config.timeout,\n });\n\n return response.data;\n } catch (error: unknown) {\n return this.formatErrorResponse(error, 'WORKFLOW');\n }\n }\n\n /**\n * Fetch credentials for a given integration entity.\n *\n * @param params - Entity name (required) and optional pagination\n */\n async getCredentials(\n params: GetCredentialsParams\n ): Promise<WorkflowResponse<CredentialsListData>> {\n try {\n const endpoint = WORKFLOW_ENDPOINTS.getCredentials;\n const path = buildWorkflowEndpointPath(endpoint, {\n entity: params.entity.toUpperCase(),\n });\n const query = new URLSearchParams({\n current_page: String(params.current_page ?? 1),\n page_size: String(params.page_size ?? 999),\n });\n const url = `${this.integrationBaseURL}${path}?${query.toString()}`;\n\n const response = await this.httpAdapter.request<\n WorkflowResponse<CredentialsListData>\n >({\n url,\n method: endpoint.method,\n headers: this.buildHeaders(),\n timeout: this.config.timeout,\n });\n\n return response.data;\n } catch (error: unknown) {\n return this.formatErrorResponse(error, 'INTEGRATION');\n }\n }\n\n /**\n * Fetch the resource/operation schema for an integration.\n *\n * @param params - Integration slug identifier\n */\n async getIntegrationResource(\n params: GetIntegrationResourceParams\n ): Promise<WorkflowResponse<IntegrationResourceData>> {\n try {\n const endpoint = WORKFLOW_ENDPOINTS.getIntegrationResource;\n const path = buildWorkflowEndpointPath(endpoint, {\n integration_slug: params.integration_slug,\n });\n const url = `${this.baseURL}${path}`;\n\n const response = await this.httpAdapter.request<\n WorkflowResponse<IntegrationResourceData>\n >({\n url,\n method: endpoint.method,\n headers: this.buildHeaders(),\n timeout: this.config.timeout,\n });\n\n return response.data;\n } catch (error: unknown) {\n return this.formatErrorResponse(error, 'WORKFLOW');\n }\n }\n\n /**\n * Fetch the form schema (fields) for a specific integration resource + operation.\n *\n * @param params - Integration slug, resource, operation, and credential secret\n */\n async getIntegrationForm(\n params: GetIntegrationFormParams\n ): Promise<WorkflowResponse<IntegrationFormData>> {\n try {\n const endpoint = WORKFLOW_ENDPOINTS.getIntegrationForm;\n const path = buildWorkflowEndpointPath(endpoint, {\n integration_slug: params.integration_slug,\n });\n\n const query = new URLSearchParams({\n resource: params.resource,\n operation: params.operation,\n // getFormOnly: String(params.getFormOnly ?? true),\n secret: params.secret,\n });\n const url = `${this.baseURL}${path}?${query.toString()}`;\n\n const response = await this.httpAdapter.request<\n WorkflowResponse<IntegrationFormData>\n >({\n url,\n method: endpoint.method,\n headers: this.buildHeaders(),\n timeout: this.config.timeout,\n });\n\n return response.data;\n } catch (error: unknown) {\n return this.formatErrorResponse(error, 'WORKFLOW');\n }\n }\n}\n","import { SCHEMA_TYPE_MAPPING } from '../constants';\nimport type {\n FormField,\n IntegrationFormJsonSchema,\n JsonSchemaProperty,\n} from '../types/workflow';\n\nconst FORM_META_FIELDS = new Set(['resource', 'operation']);\n\nfunction getSchemaMapping(displayType: string): {\n type: string;\n fallback_value: unknown;\n} {\n return (\n (SCHEMA_TYPE_MAPPING as Record<string, { type: string; fallback_value: unknown }>)[displayType] ?? {\n type: 'string',\n fallback_value: '',\n }\n );\n}\n\n/**\n * Transform raw form fields into a flat JSON object with default/fallback\n * values for each field.\n *\n * Fields like `secret`, `resource`, and `operation` are skipped by default\n * since they are already handled by the SDK parameters.\n */\nexport function transformFormToDefaults(\n fields: FormField[],\n skipFields: Set<string> = FORM_META_FIELDS\n): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n\n for (const field of fields) {\n if (skipFields.has(field.name)) continue;\n\n const displayType = field.meta?.displayType || 'text';\n const mapping = getSchemaMapping(displayType);\n\n result[field.name] =\n field.meta?.value !== undefined\n ? field.meta.value\n : mapping.fallback_value;\n }\n\n return result;\n}\n\n/**\n * Transform raw form fields into a JSON Schema object describing the\n * expected input shape.\n *\n * Fields like `secret`, `resource`, and `operation` are skipped by default\n * since they are already handled by the SDK parameters.\n */\nexport function transformFormToJsonSchema(\n fields: FormField[],\n skipFields: Set<string> = FORM_META_FIELDS\n): IntegrationFormJsonSchema {\n const properties: Record<string, JsonSchemaProperty> = {};\n\n for (const field of fields) {\n if (skipFields.has(field.name)) continue;\n\n const displayType = field.meta?.displayType || 'text';\n const mapping = getSchemaMapping(displayType);\n const isRequired = field.meta?.validation?.required ?? false;\n const defaultValue =\n field.meta?.value !== undefined\n ? field.meta.value\n : mapping.fallback_value;\n\n const prop: JsonSchemaProperty = {\n type: mapping.type,\n required: isRequired,\n default: defaultValue,\n };\n\n if (field.meta?.description) {\n prop.description = field.meta.description;\n }\n\n if (\n field.meta?.options &&\n Array.isArray(field.meta.options) &&\n field.meta.options.length > 0\n ) {\n prop.enum = field.meta.options.map((opt) => opt.value);\n }\n\n properties[field.name] = prop;\n }\n\n return { type: 'object', properties };\n}\n","/**\n * Workflow Resource\n * Provides workflow integration execution and polling operations.\n * Extends BaseResource for consistency with other SDK modules.\n */\n\nimport { POLLING_INTERVAL_MS, MAX_POLLING_ATTEMPTS } from '../../constants';\nimport { WorkflowApiClient } from '../../api/clients/workflow-api-client';\nimport {\n BaseResource,\n BaseClient,\n isErrorResponse,\n type BolticErrorResponse,\n type BolticSuccessResponse,\n} from '../../../../common';\nimport type {\n ActivityNode,\n ActivityResultPayload,\n CredentialsListData,\n ExecuteActivityRequestBody,\n ExecuteActivityResponseData,\n ExecuteIntegrationParams,\n FormField,\n GetCredentialsParams,\n GetIntegrationFormParams,\n GetIntegrationResourceParams,\n GetIntegrationsParams,\n IntegrationExecutionData,\n IntegrationFormData,\n IntegrationFormJsonSchema,\n IntegrationResourceData,\n IntegrationsListData,\n} from '../../types/workflow';\nimport {\n transformFormToDefaults,\n transformFormToJsonSchema,\n} from '../../utils/form-transformer';\n\n// ---------------------------------------------------------------------------\n// Request body builder – isolated so defaults are easy to adjust later\n// ---------------------------------------------------------------------------\n\nfunction buildDefaultResultPayload(): ActivityResultPayload {\n return {\n payload: {},\n global_variables: {},\n };\n}\n\nfunction buildExecuteActivityBody(\n params: ExecuteIntegrationParams\n): ExecuteActivityRequestBody {\n const node: ActivityNode = {\n data: {\n type: params.data.type,\n name: params.data.name,\n properties: params.data.properties,\n },\n };\n\n return {\n nodes: [node],\n result: params.result ?? buildDefaultResultPayload(),\n };\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n// ---------------------------------------------------------------------------\n// Resource\n// ---------------------------------------------------------------------------\n\nexport class WorkflowResource extends BaseResource {\n private apiClient: WorkflowApiClient;\n\n constructor(client: BaseClient) {\n super(client, '/workflows');\n\n const config = client.getConfig();\n this.apiClient = new WorkflowApiClient(config.apiKey, {\n environment: config.environment,\n region: config.region,\n timeout: config.timeout,\n debug: config.debug,\n });\n }\n\n /**\n * Execute a workflow integration activity.\n *\n * When `executeOnly` is `true`, returns the immediate API response.\n * When `executeOnly` is `false` (default), polls until a terminal state\n * is reached and returns the final execution result.\n *\n * @param params - Execution parameters\n * @returns The execute response or the final polled result\n *\n * @example\n * ```typescript\n * const result = await client.workflow.executeIntegration({\n * data: { type: 'apiActivity', name: 'api1', properties: { method: 'get', endpoint: '...' } },\n * });\n *\n * const fire = await client.workflow.executeIntegration({\n * data: { type: 'apiActivity', name: 'api1', properties: { method: 'get', endpoint: '...' } },\n * executeOnly: true,\n * });\n * ```\n */\n async executeIntegration(\n params: ExecuteIntegrationParams\n ): Promise<\n | BolticSuccessResponse<\n ExecuteActivityResponseData | IntegrationExecutionData\n >\n | BolticErrorResponse\n > {\n const body = buildExecuteActivityBody(params);\n const executeResult = await this.apiClient.executeActivity(body);\n\n if (isErrorResponse(executeResult)) {\n return executeResult;\n }\n\n if (params.executeOnly) {\n return executeResult;\n }\n\n const executionId = executeResult.data?.execution_id;\n if (!executionId) {\n return {\n error: {\n code: 'MISSING_EXECUTION_ID',\n message: 'Execute API response did not contain an execution_id',\n meta: [],\n },\n };\n }\n\n return this.pollExecution(executionId);\n }\n\n /**\n * Retrieve the result of a workflow execution by its run/execution ID.\n *\n * @param executionId - The execution run ID\n * @returns The execution data or an error response\n *\n * @example\n * ```typescript\n * const result = await client.workflow.getIntegrationExecuteById('run-uuid');\n * ```\n */\n async getIntegrationExecuteById(\n executionId: string\n ): Promise<\n BolticSuccessResponse<IntegrationExecutionData> | BolticErrorResponse\n > {\n return this.apiClient.getExecutionById(executionId);\n }\n\n /**\n * Fetch the list of available integrations.\n *\n * @param params - Optional pagination parameters (`page`, `per_page`)\n * @returns The integrations list or an error response\n *\n * @example\n * ```typescript\n * const list = await client.workflow.getIntegrations();\n * ```\n */\n async getIntegrations(\n params: GetIntegrationsParams = {}\n ): Promise<\n BolticSuccessResponse<IntegrationsListData> | BolticErrorResponse\n > {\n return this.apiClient.getIntegrations(params);\n }\n\n /**\n * Fetch credentials for a given integration entity.\n *\n * @param params - Entity name (required), optional `current_page` and `page_size`\n * @returns The credentials list or an error response\n *\n * @example\n * ```typescript\n * const creds = await client.workflow.getCredentials({ entity: 'freshsales' });\n * ```\n */\n async getCredentials(\n params: GetCredentialsParams\n ): Promise<BolticSuccessResponse<CredentialsListData> | BolticErrorResponse> {\n return this.apiClient.getCredentials(params);\n }\n\n /**\n * Fetch the resource/operation schema for an integration.\n *\n * Returns the available resources and operations supported by the\n * specified integration (e.g. which resources like \"task\", \"project\"\n * are available and what operations can be performed on them).\n *\n * @param params - Integration slug identifier\n * @returns The integration resource schema or an error response\n *\n * @example\n * ```typescript\n * const schema = await client.workflow.getIntegrationResource({\n * integration_slug: 'blt-int.asana',\n * });\n * ```\n */\n async getIntegrationResource(\n params: GetIntegrationResourceParams\n ): Promise<\n BolticSuccessResponse<IntegrationResourceData> | BolticErrorResponse\n > {\n return this.apiClient.getIntegrationResource(params);\n }\n\n /**\n * Fetch the form schema (fields) for a specific integration resource + operation.\n *\n * By default, returns a flat JSON object with default/fallback values\n * for each input field. Set `asJsonSchema: true` to get a JSON Schema\n * object describing the expected input shape instead.\n *\n * Fields like `resource` and `operation` are automatically excluded\n * since they are already handled by the SDK parameters. The `secret`\n * field is included and populated with the value from `params.secret`.\n *\n * @param params - Integration slug, resource, operation, credential secret, and format flag\n * @returns Transformed form data or an error response\n *\n * @example\n * ```typescript\n * // Get flat defaults: { name: '', workspace: [], team: '', ... }\n * const defaults = await client.workflow.getIntegrationForm({\n * integration_slug: 'blt-int.asana',\n * resource: 'project',\n * operation: 'create',\n * secret: 'credential-secret-here',\n * });\n *\n * // Get JSON Schema: { type: 'object', properties: { name: { type: 'string', ... } } }\n * const schema = await client.workflow.getIntegrationForm({\n * integration_slug: 'blt-int.asana',\n * resource: 'project',\n * operation: 'create',\n * secret: 'credential-secret-here',\n * asJsonSchema: true,\n * });\n * ```\n */\n async getIntegrationForm(\n params: GetIntegrationFormParams\n ): Promise<\n | BolticSuccessResponse<\n Record<string, unknown> | IntegrationFormJsonSchema\n >\n | BolticErrorResponse\n > {\n const rawResult = await this.apiClient.getIntegrationForm(params);\n console.log('rawResult', JSON.stringify(rawResult, null, 2));\n if (isErrorResponse(rawResult)) {\n return rawResult;\n }\n const configuration = rawResult.data?.parameters as unknown as { data: FormField[] } || rawResult.data;\n const fields = (configuration as unknown as FormField[]) ?? [];\n\n const transformed = params.asJsonSchema\n ? transformFormToJsonSchema(fields)\n : transformFormToDefaults(fields);\n\n if (params.asJsonSchema) {\n const schema = transformed as IntegrationFormJsonSchema;\n if (schema.properties.secret) {\n schema.properties.secret.default = params.secret;\n }\n } else {\n const defaults = transformed as Record<string, unknown>;\n if ('secret' in defaults) {\n defaults.secret = params.secret;\n }\n }\n\n return {\n data: transformed,\n message: rawResult.message,\n };\n }\n\n /**\n * Internal polling loop.\n * Repeatedly calls `getExecutionById` until the response `data` object is\n * non-empty (execution finished) or max attempts are exhausted.\n */\n private async pollExecution(\n executionId: string\n ): Promise<\n BolticSuccessResponse<IntegrationExecutionData> | BolticErrorResponse\n > {\n const debug = this.client.getConfig().debug;\n\n for (let attempt = 0; attempt < MAX_POLLING_ATTEMPTS; attempt++) {\n const result = await this.apiClient.getExecutionById(executionId);\n\n if (isErrorResponse(result)) {\n return result;\n }\n\n if (result.data && Object.keys(result.data).length > 0) {\n if (debug) {\n // eslint-disable-next-line no-console\n console.log(\n `[WorkflowResource] Execution ${executionId} completed after ${attempt + 1} poll(s)`\n );\n }\n return result;\n }\n\n await sleep(POLLING_INTERVAL_MS);\n }\n\n return {\n error: {\n code: 'EXECUTION_TIMEOUT',\n message: `Execution ${executionId} did not complete within ${MAX_POLLING_ATTEMPTS} polling attempts`,\n meta: [\n `execution_id: ${executionId}`,\n `max_attempts: ${MAX_POLLING_ATTEMPTS}`,\n ],\n },\n };\n }\n}\n","/** Polling interval in milliseconds between status checks */\nexport const STATUS_POLLING_INTERVAL_MS = 5000;\n\n/** Maximum number of status polling attempts before timeout */\nexport const MAX_STATUS_POLLING_ATTEMPTS = 60;\n\n/** Serverless statuses that indicate the function has reached a terminal state */\nexport const TERMINAL_STATUSES = [\n 'running',\n 'failed',\n 'degraded',\n 'suspended',\n] as const;\n\nexport type TerminalStatus = (typeof TERMINAL_STATUSES)[number];\n\n/** Default resource allocation for new serverless functions */\nexport const DEFAULT_RESOURCES = {\n CPU: 0.1,\n MemoryMB: 128,\n MemoryMaxMB: 128,\n} as const;\n\n/** Default scaling configuration for new serverless functions */\nexport const DEFAULT_SCALING = {\n AutoStop: false,\n Min: 1,\n Max: 1,\n MaxIdleTime: 0,\n} as const;\n","/**\n * Serverless API endpoint definitions.\n * Paths use `{param}` placeholders resolved at request time.\n */\n\nimport type { ServerlessApiEndpoint } from '../../types/serverless';\n\nexport interface ServerlessEndpoints {\n list: ServerlessApiEndpoint;\n get: ServerlessApiEndpoint;\n create: ServerlessApiEndpoint;\n update: ServerlessApiEndpoint;\n getBuilds: ServerlessApiEndpoint;\n getLogs: ServerlessApiEndpoint;\n getBuildLogs: ServerlessApiEndpoint;\n}\n\nexport const SERVERLESS_ENDPOINTS: ServerlessEndpoints = {\n list: {\n path: '/apps',\n method: 'GET',\n authenticated: true,\n },\n get: {\n path: '/apps/{app_id}',\n method: 'GET',\n authenticated: true,\n },\n create: {\n path: '/apps',\n method: 'POST',\n authenticated: true,\n },\n update: {\n path: '/apps/{app_id}',\n method: 'PUT',\n authenticated: true,\n },\n getBuilds: {\n path: '/apps/{app_id}/builds',\n method: 'GET',\n authenticated: true,\n },\n getLogs: {\n path: '/apps/{app_id}/logs',\n method: 'GET',\n authenticated: true,\n },\n getBuildLogs: {\n path: '/apps/{app_id}/builds/{build_id}/logs',\n method: 'GET',\n authenticated: true,\n },\n};\n\n/** Resolve `{param}` placeholders in an endpoint path */\nexport function buildServerlessEndpointPath(\n endpoint: ServerlessApiEndpoint,\n params: Record<string, string> = {}\n): string {\n let path = endpoint.path;\n for (const [key, value] of Object.entries(params)) {\n path = path.replace(`{${key}}`, value);\n }\n return path;\n}\n","/**\n * Serverless API Client\n * Extends BaseApiClient — shares auth, headers, error handling, and HTTP\n * infrastructure with the rest of the SDK via the common module.\n */\n\nimport {\n BaseApiClient,\n SERVICE_PATHS,\n type BaseApiClientConfig,\n type BolticErrorResponse,\n type BolticSuccessResponse,\n} from '../../../../common';\nimport type {\n CreateServerlessParams,\n CreateServerlessData,\n GetServerlessData,\n GetBuildsData,\n GetBuildLogsData,\n GetLogsData,\n ListServerlessData,\n ListServerlessParams,\n GetBuildsParams,\n GetLogsParams,\n GetBuildLogsParams,\n UpdateServerlessParams,\n UpdateServerlessData,\n} from '../../types/serverless';\nimport {\n SERVERLESS_ENDPOINTS,\n buildServerlessEndpointPath,\n} from '../endpoints/serverless';\n\ntype ServerlessResponse<T> = BolticSuccessResponse<T> | BolticErrorResponse;\n\nexport class ServerlessApiClient extends BaseApiClient {\n constructor(\n apiKey: string,\n config: Omit<BaseApiClientConfig, 'apiKey'> = {}\n ) {\n super(apiKey, config, SERVICE_PATHS.SERVERLESS);\n }\n\n /**\n * List all serverless functions with optional pagination and search.\n */\n async list(\n params: ListServerlessParams = {}\n ): Promise<ServerlessResponse<ListServerlessData>> {\n try {\n const endpoint = SERVERLESS_ENDPOINTS.list;\n const query = new URLSearchParams({\n page: String(params.page ?? 1),\n limit: String(params.limit ?? 20),\n sortBy: params.sortBy ?? 'CreatedAt',\n sortOrder: params.sortOrder ?? 'desc',\n });\n if (params.query) {\n query.set('q', params.query);\n }\n const url = `${this.baseURL}${endpoint.path}?${query.toString()}`;\n\n const response = await this.httpAdapter.request<\n ServerlessResponse<ListServerlessData>\n >({\n url,\n method: endpoint.method,\n headers: this.buildHeaders(),\n timeout: this.config.timeout,\n });\n\n return response.data;\n } catch (error: unknown) {\n return this.formatErrorResponse(error, 'SERVERLESS');\n }\n }\n\n /**\n * Get a serverless function by its ID.\n */\n async get(appId: string): Promise<ServerlessResponse<GetServerlessData>> {\n try {\n const endpoint = SERVERLESS_ENDPOINTS.get;\n const path = buildServerlessEndpointPath(endpoint, { app_id: appId });\n const url = `${this.baseURL}${path}`;\n console.log('url', url);\n\n const response = await this.httpAdapter.request<\n ServerlessResponse<GetServerlessData>\n >({\n url,\n method: endpoint.method,\n headers: this.buildHeaders(),\n timeout: this.config.timeout,\n });\n console.log('response', response.data);\n\n return response.data;\n } catch (error: unknown) {\n return this.formatErrorResponse(error, 'SERVERLESS');\n }\n }\n\n /**\n * Create a new serverless function.\n */\n async create(\n payload: CreateServerlessParams\n ): Promise<ServerlessResponse<CreateServerlessData>> {\n try {\n const endpoint = SERVERLESS_ENDPOINTS.create;\n const url = `${this.baseURL}${endpoint.path}`;\n\n const response = await this.httpAdapter.request<\n ServerlessResponse<CreateServerlessData>\n >({\n url,\n method: endpoint.method,\n headers: this.buildHeaders(),\n data: payload,\n timeout: this.config.timeout,\n });\n\n return response.data;\n } catch (error: unknown) {\n return this.formatErrorResponse(error, 'SERVERLESS');\n }\n }\n\n /**\n * Update an existing serverless function.\n */\n async update(\n params: UpdateServerlessParams\n ): Promise<ServerlessResponse<UpdateServerlessData>> {\n try {\n const endpoint = SERVERLESS_ENDPOINTS.update;\n const path = buildServerlessEndpointPath(endpoint, {\n app_id: params.appId,\n });\n const url = `${this.baseURL}${path}`;\n\n const response = await this.httpAdapter.request<\n ServerlessResponse<UpdateServerlessData>\n >({\n url,\n method: endpoint.method,\n headers: this.buildHeaders(),\n data: params.payload,\n timeout: this.config.timeout,\n });\n\n return response.data;\n } catch (error: unknown) {\n return this.formatErrorResponse(error, 'SERVERLESS');\n }\n }\n\n /**\n * List builds for a serverless function.\n */\n async getBuilds(\n params: GetBuildsParams\n ): Promise<ServerlessResponse<GetBuildsData>> {\n try {\n const endpoint = SERVERLESS_ENDPOINTS.getBuilds;\n const path = buildServerlessEndpointPath(endpoint, {\n app_id: params.appId,\n });\n const query = new URLSearchParams({\n page: String(params.page ?? 1),\n limit: String(params.limit ?? 20),\n sortBy: 'CreatedAt',\n sortOrder: 'desc',\n });\n const url = `${this.baseURL}${path}?${query.toString()}`;\n\n const response = await this.httpAdapter.request<\n ServerlessResponse<GetBuildsData>\n >({\n url,\n method: endpoint.method,\n headers: this.buildHeaders(),\n timeout: this.config.timeout,\n });\n\n return response.data;\n } catch (error: unknown) {\n return this.formatErrorResponse(error, 'SERVERLESS');\n }\n }\n\n /**\n * Get runtime logs for a serverless function.\n */\n async getLogs(\n params: GetLogsParams\n ): Promise<ServerlessResponse<GetLogsData>> {\n try {\n const endpoint = SERVERLESS_ENDPOINTS.getLogs;\n const path = buildServerlessEndpointPath(endpoint, {\n app_id: params.appId,\n });\n\n const now = Math.floor(Date.now() / 1000);\n const defaultStart = now - 24 * 60 * 60;\n\n const query = new URLSearchParams({\n page: String(params.page ?? 1),\n limit: String(params.limit ?? 50),\n sortBy: 'Timestamp',\n sortOrder: params.sortOrder ?? 'DESC',\n timestampStart: String(params.timestampStart ?? defaultStart),\n timestampEnd: String(params.timestampEnd ?? now),\n metric_interval: '60',\n });\n const url = `${this.baseURL}${path}?${query.toString()}`;\n\n const response = await this.httpAdapter.request<\n ServerlessResponse<GetLogsData>\n >({\n url,\n method: endpoint.method,\n headers: this.buildHeaders(),\n timeout: this.config.timeout,\n });\n\n return response.data;\n } catch (error: unknown) {\n return this.formatErrorResponse(error, 'SERVERLESS');\n }\n }\n\n /**\n * Get build logs for a specific build of a serverless function.\n */\n async getBuildLogs(\n params: GetBuildLogsParams\n ): Promise<ServerlessResponse<GetBuildLogsData>> {\n try {\n const endpoint = SERVERLESS_ENDPOINTS.getBuildLogs;\n const path = buildServerlessEndpointPath(endpoint, {\n app_id: params.appId,\n build_id: params.buildId,\n });\n const query = new URLSearchParams({\n limit: '-1',\n tail: 'false',\n sortOrder: 'asc',\n sortBy: 'Timestamp',\n });\n const url = `${this.baseURL}${path}?${query.toString()}`;\n\n const response = await this.httpAdapter.request<\n ServerlessResponse<GetBuildLogsData>\n >({\n url,\n method: endpoint.method,\n headers: this.buildHeaders(),\n timeout: this.config.timeout,\n });\n\n return response.data;\n } catch (error: unknown) {\n return this.formatErrorResponse(error, 'SERVERLESS');\n }\n }\n}\n","/**\n * Serverless Resource\n * Provides serverless function management: CRUD, builds, logs, and status polling.\n * Extends BaseResource for consistency with other SDK modules.\n */\n\nimport {\n STATUS_POLLING_INTERVAL_MS,\n MAX_STATUS_POLLING_ATTEMPTS,\n TERMINAL_STATUSES,\n} from '../../constants';\nimport { ServerlessApiClient } from '../../api/clients/serverless-api-client';\nimport {\n BaseResource,\n BaseClient,\n isErrorResponse,\n type BolticErrorResponse,\n type BolticSuccessResponse,\n} from '../../../../common';\nimport type {\n CreateServerlessParams,\n CreateServerlessData,\n GetServerlessData,\n GetBuildsParams,\n GetBuildsData,\n GetLogsParams,\n GetLogsData,\n GetBuildLogsParams,\n GetBuildLogsData,\n ListServerlessParams,\n ListServerlessData,\n UpdateServerlessParams,\n UpdateServerlessData,\n ServerlessData,\n} from '../../types/serverless';\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nexport class ServerlessResource extends BaseResource {\n private apiClient: ServerlessApiClient;\n\n constructor(client: BaseClient) {\n super(client, '/serverless');\n\n const config = client.getConfig();\n this.apiClient = new ServerlessApiClient(config.apiKey, {\n environment: config.environment,\n region: config.region,\n timeout: config.timeout,\n debug: config.debug,\n });\n }\n\n /**\n * List all serverless functions with optional pagination and search.\n *\n * @param params - Optional pagination and filter parameters\n * @returns Paginated list of serverless functions\n *\n * @example\n * ```typescript\n * const list = await client.serverless.list();\n * const filtered = await client.serverless.list({ query: 'my-func', limit: 10 });\n * ```\n */\n async list(\n params: ListServerlessParams = {}\n ): Promise<BolticSuccessResponse<ListServerlessData> | BolticErrorResponse> {\n return this.apiClient.list(params);\n }\n\n /**\n * Get a serverless function by its ID.\n *\n * @param appId - The serverless function ID\n * @returns The serverless function details\n *\n * @example\n * ```typescript\n * const fn = await client.serverless.get('serverless-id');\n * ```\n */\n async get(\n appId: string\n ): Promise<BolticSuccessResponse<GetServerlessData> | BolticErrorResponse> {\n return this.apiClient.get(appId);\n }\n\n /**\n * Create a new serverless function.\n *\n * Supports three runtime types:\n * - `code` — deploy code directly (blueprint)\n * - `git` — deploy from a Git repository\n * - `container` — deploy a Docker container\n *\n * @param params - The serverless creation payload\n * @returns The created serverless function\n *\n * @example\n * ```typescript\n * const fn = await client.serverless.create({\n * Name: 'my-api',\n * Runtime: 'code',\n * Resources: { CPU: 0.1, MemoryMB: 128, MemoryMaxMB: 128 },\n * Scaling: { AutoStop: false, Min: 1, Max: 1, MaxIdleTime: 0 },\n * CodeOpts: { Language: 'nodejs/20', Code: 'module.exports.handler = ...' },\n * });\n * ```\n */\n async create(\n params: CreateServerlessParams\n ): Promise<\n BolticSuccessResponse<CreateServerlessData> | BolticErrorResponse\n > {\n return this.apiClient.create(params);\n }\n\n /**\n * Create a serverless function and poll until it reaches a terminal state.\n *\n * Combines `create()` + `pollStatus()` for a simpler workflow.\n *\n * @param params - The serverless creation payload\n * @returns The final serverless state after reaching a terminal status\n *\n * @example\n * ```typescript\n * const fn = await client.serverless.createAndWait({\n * Name: 'my-api',\n * Runtime: 'code',\n * CodeOpts: { Language: 'nodejs/20', Code: '...' },\n * Resources: { CPU: 0.1, MemoryMB: 128, MemoryMaxMB: 128 },\n * Scaling: { AutoStop: false, Min: 1, Max: 1, MaxIdleTime: 0 },\n * });\n * ```\n */\n async createAndWait(\n params: CreateServerlessParams\n ): Promise<BolticSuccessResponse<ServerlessData> | BolticErrorResponse> {\n const createResult = await this.apiClient.create(params);\n\n if (isErrorResponse(createResult)) {\n return createResult;\n }\n\n const appId = createResult.data?.ID;\n if (!appId) {\n return {\n error: {\n code: 'SERVERLESS_MISSING_ID',\n message: 'Create API response did not contain an ID',\n meta: [],\n },\n };\n }\n\n return this.pollStatus(appId);\n }\n\n /**\n * Update an existing serverless function.\n *\n * @param params - The update parameters (appId + partial payload)\n * @returns The updated serverless function\n *\n * @example\n * ```typescript\n * const updated = await client.serverless.update({\n * appId: 'serverless-id',\n * payload: { Scaling: { AutoStop: true, Min: 0, Max: 3, MaxIdleTime: 300 } },\n * });\n * ```\n */\n async update(\n params: UpdateServerlessParams\n ): Promise<\n BolticSuccessResponse<UpdateServerlessData> | BolticErrorResponse\n > {\n return this.apiClient.update(params);\n }\n\n /**\n * Update a serverless function and poll until it reaches a terminal state.\n *\n * @param params - The update parameters (appId + partial payload)\n * @returns The final serverless state after reaching a terminal status\n */\n async updateAndWait(\n params: UpdateServerlessParams\n ): Promise<BolticSuccessResponse<ServerlessData> | BolticErrorResponse> {\n const updateResult = await this.apiClient.update(params);\n\n if (isErrorResponse(updateResult)) {\n return updateResult;\n }\n\n return this.pollStatus(params.appId);\n }\n\n /**\n * List builds for a serverless function.\n *\n * @param params - The app ID and optional pagination\n * @returns List of builds\n *\n * @example\n * ```typescript\n * const builds = await client.serverless.getBuilds({ appId: 'serverless-id' });\n * ```\n */\n async getBuilds(\n params: GetBuildsParams\n ): Promise<BolticSuccessResponse<GetBuildsData> | BolticErrorResponse> {\n return this.apiClient.getBuilds(params);\n }\n\n /**\n * Get runtime logs for a serverless function.\n *\n * @param params - The app ID and optional time range / pagination\n * @returns Log entries\n *\n * @example\n * ```typescript\n * const logs = await client.serverless.getLogs({ appId: 'serverless-id' });\n * const recentLogs = await client.serverless.getLogs({\n * appId: 'serverless-id',\n * limit: 100,\n * sortOrder: 'DESC',\n * });\n * ```\n */\n async getLogs(\n params: GetLogsParams\n ): Promise<BolticSuccessResponse<GetLogsData> | BolticErrorResponse> {\n return this.apiClient.getLogs(params);\n }\n\n /**\n * Get build logs for a specific build.\n *\n * @param params - The app ID and build ID\n * @returns Build log entries\n *\n * @example\n * ```typescript\n * const logs = await client.serverless.getBuildLogs({\n * appId: 'serverless-id',\n * buildId: 'build-id',\n * });\n * ```\n */\n async getBuildLogs(\n params: GetBuildLogsParams\n ): Promise<BolticSuccessResponse<GetBuildLogsData> | BolticErrorResponse> {\n return this.apiClient.getBuildLogs(params);\n }\n\n /**\n * Poll a serverless function until it reaches a terminal status\n * (running, failed, degraded, or suspended).\n *\n * @param appId - The serverless function ID to poll\n * @param options - Optional polling configuration overrides\n * @returns The final serverless state or a timeout error\n *\n * @example\n * ```typescript\n * const result = await client.serverless.pollStatus('serverless-id');\n * ```\n */\n async pollStatus(\n appId: string,\n options: {\n intervalMs?: number;\n maxAttempts?: number;\n } = {}\n ): Promise<BolticSuccessResponse<ServerlessData> | BolticErrorResponse> {\n const interval = options.intervalMs ?? STATUS_POLLING_INTERVAL_MS;\n const maxAttempts = options.maxAttempts ?? MAX_STATUS_POLLING_ATTEMPTS;\n const debug = this.client.getConfig().debug;\n\n for (let attempt = 0; attempt < maxAttempts; attempt++) {\n const result = await this.apiClient.get(appId);\n\n if (isErrorResponse(result)) {\n return result;\n }\n\n const status = result.data?.Status;\n\n if (debug) {\n // eslint-disable-next-line no-console\n console.log(\n `[ServerlessResource] Poll #${attempt + 1}: status=${status}`\n );\n }\n\n if (\n status &&\n TERMINAL_STATUSES.includes(status as (typeof TERMINAL_STATUSES)[number])\n ) {\n if (debug) {\n // eslint-disable-next-line no-console\n console.log(\n `[ServerlessResource] Reached terminal state: ${status} after ${attempt + 1} poll(s)`\n );\n }\n return result;\n }\n\n await sleep(interval);\n }\n\n return {\n error: {\n code: 'SERVERLESS_STATUS_TIMEOUT',\n message: `Serverless ${appId} did not reach a terminal state within ${maxAttempts} polling attempts`,\n meta: [\n `app_id: ${appId}`,\n `max_attempts: ${maxAttempts}`,\n `interval_ms: ${interval}`,\n ],\n },\n };\n }\n}\n","/** Default backend storage driver (GCS). */\nexport const DEFAULT_STORAGE_TYPE = 'gcs' as const;\n\n/**\n * `expire_in` for upload temporary read URLs is **minutes**.\n * Backend caps TTL to 7 days.\n */\nexport const MAX_SIGNED_URL_EXPIRE_MINUTES = 7 * 24 * 60;\n","import type { StorageApiEndpoint } from '../../types/storage';\n\nexport interface StorageEndpoints {\n list: StorageApiEndpoint;\n upload: StorageApiEndpoint;\n directory: StorageApiEndpoint;\n deleteFile: StorageApiEndpoint;\n objectAccess: StorageApiEndpoint;\n /** Range download (`POST /file-export`). */\n fileExport: StorageApiEndpoint;\n}\n\nexport const STORAGE_ENDPOINTS: StorageEndpoints = {\n list: {\n path: '/storage/list',\n method: 'GET',\n authenticated: true,\n },\n upload: {\n path: '/storage/upload',\n method: 'POST',\n authenticated: true,\n },\n directory: {\n path: '/storage/directory',\n method: 'POST',\n authenticated: true,\n },\n deleteFile: {\n path: '/storage/file',\n method: 'DELETE',\n authenticated: true,\n },\n objectAccess: {\n path: '/storage/change-object-access',\n method: 'POST',\n authenticated: true,\n },\n fileExport: {\n path: '/storage/file-export',\n method: 'POST',\n authenticated: true,\n },\n};\n\nexport function buildStorageEndpointPath(endpoint: StorageApiEndpoint): string {\n return endpoint.path;\n}\n","/**\n * Storage API client — extends BaseApiClient like serverless/workflow clients.\n */\n\nimport {\n BaseApiClient,\n SERVICE_PATHS,\n type BaseApiClientConfig,\n type BolticErrorResponse,\n type HttpRequestConfig,\n} from '../../../../common';\nimport {\n DEFAULT_STORAGE_TYPE,\n MAX_SIGNED_URL_EXPIRE_MINUTES,\n} from '../../constants';\nimport type {\n ChangeObjectAccessParams,\n CreateFolderData,\n CreateFolderParams,\n DeleteFileParams,\n DownloadFileData,\n DownloadFileParams,\n ListStorageData,\n ListStorageParams,\n ObjectAccessSummary,\n StorageListItem,\n UploadData,\n UploadParams,\n} from '../../types/storage';\nimport {\n STORAGE_ENDPOINTS,\n buildStorageEndpointPath,\n} from '../endpoints/storage';\n\ntype StorageResult<T> = T | BolticErrorResponse;\n\nconst ERR_PREFIX = 'STORAGE' as const;\n\nexport class StorageApiClient extends BaseApiClient {\n constructor(\n apiKey: string,\n config: Omit<BaseApiClientConfig, 'apiKey'> = {}\n ) {\n super(apiKey, config, SERVICE_PATHS.STORAGE);\n }\n\n /** Shared try/catch + http — same idea as inlined blocks in serverless/workflow clients, but DRY for storage. */\n private async requestStorage<T>(\n config: HttpRequestConfig\n ): Promise<StorageResult<T>> {\n try {\n const response = await this.httpAdapter.request<StorageResult<T>>(config);\n return response.data;\n } catch (error: unknown) {\n return this.formatErrorResponse(error, ERR_PREFIX);\n }\n }\n\n private url(path: string, query?: URLSearchParams): string {\n const qs = query?.toString();\n return qs ? `${this.baseURL}${path}?${qs}` : `${this.baseURL}${path}`;\n }\n\n private storageTypeQuery(storageType?: string): URLSearchParams {\n const q = new URLSearchParams();\n q.set('storageType', storageType ?? DEFAULT_STORAGE_TYPE);\n return q;\n }\n\n private listQuery(params: ListStorageParams): URLSearchParams {\n const q = this.storageTypeQuery(params.storageType);\n if (params.basePath !== undefined) {\n q.set('basePath', params.basePath);\n }\n if (params.pageSize !== undefined) {\n q.set('pageSize', String(params.pageSize));\n }\n if (params.nextPageToken !== undefined) {\n q.set('nextPageToken', params.nextPageToken);\n }\n return q;\n }\n\n /** `expire_in` is minutes; clamp to max temporary URL lifetime (7 days). */\n private normalizeExpireInMinutes(raw: number | string): number {\n const n = typeof raw === 'number' ? raw : Number(raw);\n if (!Number.isFinite(n) || n <= 0) {\n throw new Error(\n 'expire_in must be a positive number of minutes (max 7 days for temporary signed URLs)'\n );\n }\n const truncated = Math.trunc(n);\n return Math.min(Math.max(1, truncated), MAX_SIGNED_URL_EXPIRE_MINUTES);\n }\n\n private isTruthyFormFlag(v: boolean | string | undefined): boolean {\n if (v === undefined) return false;\n if (typeof v === 'boolean') return v;\n const s = String(v).toLowerCase();\n return s === 'true' || s === '1' || s === 'yes';\n }\n\n /**\n * `public` shortcut: true + no expire_in → permanent; true + expire_in → temporary signed URL; false → private.\n * Legacy: omit `public` and pass `is_public` / `is_public_permanent` / `expire_in` as before.\n */\n private appendUploadVisibility(form: FormData, params: UploadParams): void {\n const hasPublic = Object.prototype.hasOwnProperty.call(params, 'public');\n if (hasPublic) {\n const pub = this.isTruthyFormFlag(params.public);\n if (!pub) {\n form.append('is_public', 'false');\n return;\n }\n if (params.expire_in !== undefined) {\n form.append('is_public', 'true');\n form.append(\n 'expire_in',\n String(this.normalizeExpireInMinutes(params.expire_in))\n );\n return;\n }\n form.append('is_public', 'false');\n form.append('is_public_permanent', 'true');\n return;\n }\n if (params.is_public !== undefined) {\n form.append('is_public', String(params.is_public));\n }\n if (params.expire_in !== undefined) {\n form.append(\n 'expire_in',\n String(this.normalizeExpireInMinutes(params.expire_in))\n );\n }\n if (params.is_public_permanent !== undefined) {\n form.append('is_public_permanent', String(params.is_public_permanent));\n }\n }\n\n private buildUploadForm(params: UploadParams): FormData {\n const logicalName = params.filename ?? params.file_name;\n if (logicalName == null || logicalName === '') {\n throw new Error('upload requires filename or file_name');\n }\n const form = new FormData();\n form.append('file', params.file, logicalName);\n form.append('filename', logicalName);\n if (params.filepath !== undefined) {\n form.append('filepath', params.filepath);\n }\n if (params.overwrite !== undefined) {\n form.append('overwrite', String(params.overwrite));\n }\n this.appendUploadVisibility(form, params);\n return form;\n }\n\n private isErrorResult(\n result: StorageResult<ListStorageData>\n ): result is BolticErrorResponse {\n return (\n typeof result === 'object' &&\n result !== null &&\n 'error' in result &&\n (result as BolticErrorResponse).error !== undefined\n );\n }\n\n private isAclErrorResult(\n result: StorageResult<unknown>\n ): result is BolticErrorResponse {\n return (\n typeof result === 'object' &&\n result !== null &&\n 'error' in result &&\n (result as BolticErrorResponse).error !== undefined\n );\n }\n\n private buildObjectAccessSummary(\n filePath: string,\n row: StorageListItem | null,\n fallbackPublic: boolean\n ): ObjectAccessSummary {\n return {\n name: row?.name ?? row?.fullPath ?? filePath,\n size: row?.size ?? null,\n updated: row?.updatedAt ?? null,\n public: row != null ? Boolean(row.isPublic) : fallbackPublic,\n };\n }\n\n /** Resolves the list row for a full object path (same folder semantics as download size resolution). */\n private async findFileListItem(\n filePath: string,\n storageType?: string\n ): Promise<StorageListItem | null | BolticErrorResponse> {\n const lastSlash = filePath.lastIndexOf('/');\n const nameOnly = lastSlash === -1 ? filePath : filePath.slice(lastSlash + 1);\n const folderPrefix = lastSlash === -1 ? '' : filePath.slice(0, lastSlash);\n const basePath = folderPrefix ? `${folderPrefix}/` : '';\n const result = await this.list({ basePath, storageType });\n if (this.isErrorResult(result)) return result;\n const rows = result.files?.data ?? [];\n return (\n rows.find(\n (r) =>\n r.fullPath === filePath ||\n (!r.isDirectory && (r.name === nameOnly || r.fullPath === filePath))\n ) ?? null\n );\n }\n\n /** Keep only SDK list fields; flatten metadata to `size` / `updatedAt`. */\n private normalizeListItem(raw: Record<string, unknown>): StorageListItem {\n const meta = (raw.metadata as Record<string, unknown>) ?? {};\n let size: string | undefined;\n if (meta.size !== undefined && meta.size !== null) {\n size = String(meta.size);\n }\n const updatedRaw = meta.updated ?? meta.timeUpdated;\n let updatedAt: string | undefined;\n if (updatedRaw !== undefined && updatedRaw !== null) {\n updatedAt = String(updatedRaw);\n }\n\n const name = raw.name as string | undefined;\n const parentPath = raw.parentPath as string | undefined;\n const isDirectory = Boolean(raw.isDirectory);\n let fullPath: string | undefined;\n if (!isDirectory && name) {\n fullPath = parentPath ? `${parentPath}/${name}` : name;\n }\n\n const cdnRaw = raw.cdnUrl;\n const cdnUrl =\n cdnRaw === undefined || cdnRaw === null\n ? null\n : (cdnRaw as string);\n\n const item: StorageListItem = {\n name,\n path: raw.path as string | undefined,\n folderName: raw.folderName as string | undefined,\n parentPath,\n isDirectory,\n isPublic: raw.isPublic as boolean | undefined,\n cdnUrl,\n fullPath,\n };\n if (size !== undefined) item.size = size;\n if (updatedAt !== undefined) item.updatedAt = updatedAt;\n return item;\n }\n\n /** Map wire `shareable_link` to `temporary_sharable_link`. */\n private normalizeUploadData(raw: Record<string, unknown>): UploadData {\n const message = String(raw.message ?? '');\n const path = String(raw.path ?? '');\n const out: UploadData = { message, path };\n const link = raw.temporary_sharable_link ?? raw.shareable_link;\n if (link !== undefined && link !== null && String(link) !== '') {\n out.temporary_sharable_link = String(link);\n }\n if (raw.public_url !== undefined && raw.public_url !== null) {\n out.public_url = String(raw.public_url);\n }\n return out;\n }\n\n private normalizeListResponse(data: ListStorageData): ListStorageData {\n const payload = data.files;\n if (!payload?.data) return data;\n return {\n files: {\n ...payload,\n data: payload.data.map((item) =>\n this.normalizeListItem(item as Record<string, unknown>)\n ),\n },\n };\n }\n\n async list(\n params: ListStorageParams = {}\n ): Promise<StorageResult<ListStorageData>> {\n const endpoint = STORAGE_ENDPOINTS.list;\n const path = buildStorageEndpointPath(endpoint);\n const result = await this.requestStorage<ListStorageData>({\n url: this.url(path, this.listQuery(params)),\n method: endpoint.method,\n headers: this.buildHeaders(),\n timeout: this.config.timeout,\n });\n if (this.isErrorResult(result)) return result;\n return this.normalizeListResponse(result);\n }\n\n async createFolder(\n body: CreateFolderParams\n ): Promise<StorageResult<CreateFolderData>> {\n const endpoint = STORAGE_ENDPOINTS.directory;\n const path = buildStorageEndpointPath(endpoint);\n const q = this.storageTypeQuery(body.storageType);\n return this.requestStorage<CreateFolderData>({\n url: this.url(path, q),\n method: endpoint.method,\n headers: this.buildHeaders(),\n data: { folder_path: body.folder_path },\n timeout: this.config.timeout,\n });\n }\n\n async deleteFile(\n params: DeleteFileParams\n ): Promise<StorageResult<{ message: unknown }>> {\n const endpoint = STORAGE_ENDPOINTS.deleteFile;\n const path = buildStorageEndpointPath(endpoint);\n const q = this.storageTypeQuery(params.storageType);\n q.set('filename', params.filename);\n\n const data: Record<string, unknown> = {};\n if (params.filepath !== undefined) {\n data.filepath = params.filepath;\n }\n if (params.totalsize !== undefined) {\n data.totalsize = params.totalsize;\n }\n\n return this.requestStorage<{ message: unknown }>({\n url: this.url(path, q),\n method: endpoint.method,\n headers: this.buildHeaders(),\n data: Object.keys(data).length ? data : undefined,\n timeout: this.config.timeout,\n });\n }\n\n /**\n * `POST /change-object-access` — used by `makePublic` / `makePrivate`.\n * On success, performs a list on the parent folder and returns `{ name, size, updated, public }` only.\n */\n async setObjectAccess(\n body: ChangeObjectAccessParams\n ): Promise<StorageResult<ObjectAccessSummary>> {\n const endpoint = STORAGE_ENDPOINTS.objectAccess;\n const path = buildStorageEndpointPath(endpoint);\n const acl = await this.requestStorage<unknown>({\n url: this.url(path),\n method: endpoint.method,\n headers: this.buildHeaders(),\n data: {\n file_path: body.file_path,\n public: body.public,\n },\n timeout: this.config.timeout,\n });\n if (this.isAclErrorResult(acl)) return acl;\n\n const row = await this.findFileListItem(body.file_path);\n if (this.isAclErrorResult(row)) return row;\n\n return this.buildObjectAccessSummary(body.file_path, row, body.public);\n }\n\n async upload(params: UploadParams): Promise<StorageResult<UploadData>> {\n const endpoint = STORAGE_ENDPOINTS.upload;\n const path = buildStorageEndpointPath(endpoint);\n const q = this.storageTypeQuery(params.storageType);\n const headers = { ...this.buildHeaders() };\n delete headers['Content-Type'];\n\n const result = await this.requestStorage<Record<string, unknown>>({\n url: this.url(path, q),\n method: endpoint.method,\n headers,\n data: this.buildUploadForm(params),\n timeout: this.config.timeout,\n });\n if (this.isAclErrorResult(result)) return result;\n return this.normalizeUploadData(result);\n }\n\n private async resolveFileSizeBytes(\n fileName: string,\n storageType?: string\n ): Promise<number> {\n const lastSlash = fileName.lastIndexOf('/');\n const nameOnly =\n lastSlash === -1 ? fileName : fileName.slice(lastSlash + 1);\n const folderPrefix = lastSlash === -1 ? '' : fileName.slice(0, lastSlash);\n const basePath = folderPrefix ? `${folderPrefix}/` : '';\n const result = await this.list({ basePath, storageType });\n if (this.isErrorResult(result)) {\n throw new Error(\n result.error?.message ?? 'List failed while resolving file size'\n );\n }\n const rows = result.files?.data ?? [];\n const hit = rows.find(\n (r) => r.fullPath === fileName || (!r.isDirectory && r.name === nameOnly)\n );\n const s = hit?.size;\n if (s === undefined) {\n throw new Error(\n `Could not resolve size for \"${fileName}\". Pass sizeBytes (from list() item size).`\n );\n }\n return Number(s);\n }\n\n /**\n * Download file bytes via `POST /file-export` (range 0..size-1).\n */\n async downloadFile(\n params: DownloadFileParams\n ): Promise<StorageResult<DownloadFileData>> {\n try {\n const sizeBytes =\n params.sizeBytes !== undefined\n ? Number(params.sizeBytes)\n : await this.resolveFileSizeBytes(\n params.file_name,\n params.storageType\n );\n if (!Number.isFinite(sizeBytes) || sizeBytes <= 0) {\n throw new Error(\n 'Invalid or unknown file size. Pass sizeBytes from list() item size.'\n );\n }\n const endpoint = STORAGE_ENDPOINTS.fileExport;\n const path = buildStorageEndpointPath(endpoint);\n const q = this.storageTypeQuery(params.storageType);\n const response = await this.httpAdapter.request<ArrayBuffer>({\n url: this.url(path, q),\n method: 'POST',\n headers: { ...this.buildHeaders(), Accept: '*/*' },\n data: {\n file_name: params.file_name,\n start_byte: 0,\n end_byte: sizeBytes - 1,\n },\n timeout: this.config.timeout,\n responseType: 'arraybuffer',\n });\n if (response.status < 200 || response.status >= 300) {\n const d = response.data as unknown;\n if (d && typeof d === 'object' && d !== null && 'error' in d) {\n return d as BolticErrorResponse;\n }\n return this.formatErrorResponse(\n new Error(`Download failed: HTTP ${response.status}`),\n ERR_PREFIX\n );\n }\n if (!(response.data instanceof ArrayBuffer)) {\n throw new Error('Expected binary response body');\n }\n const headers = response.headers as Record<string, string>;\n const ct =\n headers['content-type'] ?? headers['Content-Type'] ?? undefined;\n return {\n bytes: response.data,\n status: response.status,\n contentType: ct,\n };\n } catch (error: unknown) {\n return this.formatErrorResponse(error, ERR_PREFIX);\n }\n }\n}\n","import { StorageApiClient } from '../../api/clients/storage-api-client';\nimport { BaseResource, BaseClient } from '../../../../common';\nimport type {\n CreateFolderData,\n CreateFolderParams,\n DeleteFileParams,\n DownloadFileData,\n DownloadFileParams,\n ListStorageData,\n ListStorageParams,\n ObjectAccessSummary,\n StorageResponse,\n UploadData,\n UploadParams,\n} from '../../types/storage';\n\ntype StorageResult<T> = StorageResponse<T>;\n\nexport class StorageResource extends BaseResource {\n private apiClient: StorageApiClient;\n\n constructor(client: BaseClient) {\n super(client, '/storage');\n const config = client.getConfig();\n this.apiClient = new StorageApiClient(config.apiKey, {\n environment: config.environment,\n region: config.region,\n timeout: config.timeout,\n debug: config.debug,\n headers: config.headers,\n });\n }\n\n async list(\n params: ListStorageParams = {}\n ): Promise<StorageResult<ListStorageData>> {\n return this.apiClient.list(params);\n }\n\n /** Direct upload — `POST /upload` (multipart); server persists the object. */\n async upload(params: UploadParams): Promise<StorageResult<UploadData>> {\n return this.apiClient.upload(params);\n }\n\n async createFolder(\n params: CreateFolderParams\n ): Promise<StorageResult<CreateFolderData>> {\n return this.apiClient.createFolder(params);\n }\n\n async deleteFile(\n params: DeleteFileParams\n ): Promise<StorageResult<{ message: unknown }>> {\n return this.apiClient.deleteFile(params);\n }\n\n async makePublic(\n filePath: string\n ): Promise<StorageResult<ObjectAccessSummary>> {\n return this.apiClient.setObjectAccess({\n file_path: filePath,\n public: true,\n });\n }\n\n async makePrivate(\n filePath: string\n ): Promise<StorageResult<ObjectAccessSummary>> {\n return this.apiClient.setObjectAccess({\n file_path: filePath,\n public: false,\n });\n }\n\n /** Download file bytes via `POST /file-export` (full file). */\n async downloadFile(\n params: DownloadFileParams\n ): Promise<StorageResult<DownloadFileData>> {\n return this.apiClient.downloadFile(params);\n }\n}\n","import { ColumnQueryOptions, ColumnUpdateRequest } from '../types/api/column';\nimport {\n DatabaseCreateRequest,\n DatabaseJobQueryOptions,\n DatabaseQueryOptions,\n DatabaseUpdateRequest,\n} from '../types/api/database';\nimport { AddIndexRequest, ListIndexesQuery } from '../types/api/index';\nimport {\n RecordData,\n RecordDeleteOptions,\n RecordQueryOptions,\n RecordUpdateOptions,\n} from '../types/api/record';\nimport {\n FieldDefinition,\n TableCreateRequest,\n TableQueryOptions,\n TableUpdateRequest,\n} from '../types/api/table';\nimport {\n type BolticErrorResponse,\n type BolticSuccessResponse,\n isErrorResponse,\n type Environment,\n type EnvironmentConfig,\n type HttpRequestConfig,\n type HttpResponse,\n AuthManager,\n BaseClient,\n type ClientConfig,\n ConfigManager,\n} from '../../../common';\nimport { TextToSQLOptions } from '../types/sql';\nimport { ColumnResource } from './resources/column';\nimport { DatabaseResource } from './resources/database';\nimport { IndexResource } from './resources/indexes';\nimport { RecordResource } from './resources/record';\nimport { createRecordBuilder, RecordBuilder } from './resources/record-builder';\nimport { SqlResource } from './resources/sql';\nimport { TableResource } from './resources/table';\nimport { createTableBuilder, TableBuilder } from './resources/table-builder';\nimport { WorkflowResource } from '../../../workflows/src/client/resources/workflow';\nimport type {\n ExecuteIntegrationParams,\n GetCredentialsParams,\n GetIntegrationFormParams,\n GetIntegrationResourceParams,\n GetIntegrationsParams,\n} from '../../../workflows/src/types/workflow';\nimport { ServerlessResource } from '../../../serverless/src/client/resources/serverless';\nimport type {\n ListServerlessParams,\n CreateServerlessParams,\n UpdateServerlessParams,\n GetBuildsParams,\n GetLogsParams,\n GetBuildLogsParams,\n} from '../../../serverless/src/types/serverless';\nimport { StorageResource } from '../../../storage/src/client/resources/storage';\nimport type {\n CreateFolderParams,\n DeleteFileParams,\n DownloadFileParams,\n ListStorageParams,\n UploadParams,\n} from '../../../storage/src/types/storage';\n\nexport interface ClientOptions extends Partial<EnvironmentConfig> {\n environment?: Environment;\n region?: 'asia-south1' | 'us-central1';\n debug?: boolean;\n retryAttempts?: number;\n retryDelay?: number;\n}\n\ninterface DatabaseContext {\n databaseId?: string;\n dbInternalName?: string;\n}\n\nexport class BolticClient {\n private configManager: ConfigManager;\n private authManager: AuthManager;\n private baseClient: BaseClient;\n private tableResource: TableResource;\n private columnResource: ColumnResource;\n private recordResource: RecordResource;\n private sqlResource: SqlResource;\n private indexResource: IndexResource;\n private databaseResource: DatabaseResource;\n private workflowResource: WorkflowResource;\n private serverlessResource: ServerlessResource;\n private storageResource: StorageResource;\n private currentDatabase: DatabaseContext | null = null;\n private clientOptions: ClientOptions;\n\n constructor(apiKey: string, options: ClientOptions = {}) {\n // Store client options\n this.clientOptions = options;\n\n // Initialize configuration\n this.configManager = new ConfigManager(\n apiKey,\n options.environment || 'prod',\n options.region || 'asia-south1',\n options\n );\n const config = this.configManager.getConfig();\n\n // Initialize authentication\n this.authManager = new AuthManager({\n apiKey: config.apiKey,\n maxRetries: config.maxRetries,\n });\n\n // Initialize HTTP client\n this.baseClient = new BaseClient(config, this.authManager);\n\n // Initialize table operations\n this.tableResource = new TableResource(this.baseClient);\n\n // Initialize column operations\n this.columnResource = new ColumnResource(this.baseClient);\n\n // Initialize record operations\n this.recordResource = new RecordResource(this.baseClient);\n\n // Initialize SQL operations\n this.sqlResource = new SqlResource(this.baseClient);\n\n // Initialize Index operations\n this.indexResource = new IndexResource(this.baseClient);\n\n // Initialize Database operations\n this.databaseResource = new DatabaseResource(this.baseClient);\n\n // Initialize Workflow operations\n this.workflowResource = new WorkflowResource(this.baseClient);\n\n // Initialize Serverless operations\n this.serverlessResource = new ServerlessResource(this.baseClient);\n\n // Initialize Storage operations\n this.storageResource = new StorageResource(this.baseClient);\n\n // Set default database context (will use default database in API if not specified)\n this.currentDatabase = null;\n }\n\n /**\n * Get current database context\n */\n getCurrentDatabase(): DatabaseContext | null {\n return this.currentDatabase;\n }\n\n /**\n * Switch to a different database using its internal name (slug).\n * All subsequent operations will use this database.\n *\n * If no internal name is provided, the SDK will switch back to the default database.\n *\n * @param dbInternalName - Database internal name/slug to switch to. If omitted or empty, default DB is used.\n *\n * @example\n * ```typescript\n * // Switch to a specific database by slug\n * await client.useDatabase('my_database_slug');\n *\n * // Switch back to default database\n * await client.useDatabase();\n * ```\n */\n async useDatabase(dbInternalName?: string): Promise<void> {\n // Reset to default database if no slug is provided\n console.log(`Database internal name:${dbInternalName}`);\n if (!dbInternalName || dbInternalName === '') {\n this.currentDatabase = null;\n return;\n }\n\n // Look up the database by its internal name (slug)\n const result: BolticSuccessResponse<unknown> | BolticErrorResponse =\n await this.databaseResource.findOne(dbInternalName);\n console.log(`Result:${JSON.stringify(result, null, 2)}`);\n if (isErrorResponse(result)) {\n console.log(`Error:${result.error.message}`);\n throw new Error(\n result.error.message ||\n `Failed to switch database to internal name '${dbInternalName}'`\n );\n }\n\n const db = result.data as { id: string; db_internal_name?: string };\n\n this.currentDatabase = {\n databaseId: db.id,\n dbInternalName: db.db_internal_name || dbInternalName,\n };\n }\n\n // Direct database operations\n get databases() {\n return {\n create: (data: DatabaseCreateRequest) =>\n this.databaseResource.create(data),\n findAll: (options?: DatabaseQueryOptions) =>\n this.databaseResource.findAll(options),\n findOne: (dbInternalName: string, options?: { fields?: string[] }) =>\n this.databaseResource.findOne(dbInternalName, options),\n getDefault: () => this.databaseResource.getDefault(),\n update: (dbInternalName: string, data: DatabaseUpdateRequest) =>\n this.databaseResource.update(dbInternalName, data),\n delete: (dbInternalName: string) =>\n this.databaseResource.delete(dbInternalName),\n listJobs: (options?: DatabaseJobQueryOptions) =>\n this.databaseResource.listJobs(options),\n pollDeleteStatus: (jobId: string) =>\n this.databaseResource.pollDeleteStatus(jobId),\n };\n }\n\n // Direct table operations\n get tables() {\n const dbId = this.currentDatabase?.databaseId;\n return {\n create: (data: TableCreateRequest) =>\n this.tableResource.create(data, dbId),\n findAll: (options?: TableQueryOptions) =>\n this.tableResource.findAll(options, dbId),\n findById: (id: string) => this.tableResource.findById(id, dbId),\n findByName: (name: string) => this.tableResource.findByName(name, dbId),\n findOne: (options: TableQueryOptions) =>\n this.tableResource.findOne(options, dbId),\n update: (name: string, data: TableUpdateRequest) =>\n this.tableResource.update(name, data, dbId),\n delete: (name: string) => this.tableResource.delete(name, dbId),\n rename: (oldName: string, newName: string) =>\n this.tableResource.rename(oldName, newName, dbId),\n };\n }\n\n // Direct column operations\n get columns() {\n return {\n create: (tableName: string, column: FieldDefinition) =>\n this.columnResource.create(tableName, column),\n createMany: (tableName: string, columns: FieldDefinition[]) =>\n this.columnResource.createMany(tableName, columns),\n findAll: (tableName: string, options?: ColumnQueryOptions) =>\n this.columnResource.findAll(tableName, options),\n findOne: (tableName: string, columnName: string) =>\n this.columnResource.get(tableName, columnName),\n findById: (tableName: string, columnId: string) =>\n this.columnResource.findById(tableName, columnId),\n update: (\n tableName: string,\n columnName: string,\n updates: ColumnUpdateRequest\n ) => this.columnResource.update(tableName, columnName, updates),\n delete: (tableName: string, columnName: string) =>\n this.columnResource.delete(tableName, columnName),\n };\n }\n\n // Direct index operations\n get indexes() {\n return {\n addIndex: (tableName: string, payload: AddIndexRequest) =>\n this.indexResource.addIndex(tableName, payload),\n listIndexes: (tableName: string, query: ListIndexesQuery) =>\n this.indexResource.listIndexes(tableName, query),\n deleteIndex: (tableName: string, indexName: string) =>\n this.indexResource.deleteIndex(tableName, indexName),\n };\n }\n\n // Fluent table operations\n table(name: string): TableBuilder {\n const tableBuilder = createTableBuilder({ name });\n return tableBuilder;\n }\n\n // Table-scoped operations for method chaining\n from(tableName: string) {\n const dbId = this.currentDatabase?.databaseId;\n return {\n // Index operations for this table\n indexes: () => ({\n addIndex: (payload: AddIndexRequest) =>\n this.indexResource.addIndex(tableName, payload, dbId),\n listIndexes: (query: ListIndexesQuery) =>\n this.indexResource.listIndexes(tableName, query, dbId),\n deleteIndex: (indexName: string) =>\n this.indexResource.deleteIndex(tableName, indexName, dbId),\n }),\n // Record operations for this table\n records: () => ({\n insert: (data: RecordData) =>\n this.recordResource.insert(tableName, data, dbId),\n insertMany: (\n records: RecordData[],\n options?: { validation?: boolean }\n ) => this.recordResource.insertMany(tableName, records, options, dbId),\n findOne: (recordId: string) =>\n this.recordResource.get(tableName, recordId, dbId),\n update: (options: RecordUpdateOptions) =>\n this.recordResource.update(tableName, options, dbId),\n updateById: (recordId: string, data: RecordData) =>\n this.recordResource.updateById(tableName, recordId, data, dbId),\n delete: (options: RecordDeleteOptions) =>\n this.recordResource.delete(tableName, options, dbId),\n deleteById: (recordId: string) =>\n this.recordResource.deleteById(tableName, recordId, dbId),\n }),\n };\n }\n\n // Direct record operations\n get records() {\n const dbId = this.currentDatabase?.databaseId;\n return {\n insert: (tableName: string, data: RecordData) =>\n this.recordResource.insert(tableName, data, dbId),\n insertMany: (\n tableName: string,\n records: RecordData[],\n options?: { validation?: boolean }\n ) => this.recordResource.insertMany(tableName, records, options, dbId),\n findAll: (tableName: string, options?: RecordQueryOptions) =>\n this.recordResource.list(tableName, options, dbId),\n findOne: (\n tableName: string,\n recordId: string,\n options?: { show_decrypted?: boolean }\n ) => this.recordResource.get(tableName, recordId, options, dbId),\n update: (tableName: string, options: RecordUpdateOptions) =>\n this.recordResource.update(tableName, options, dbId),\n updateById: (\n tableName: string,\n recordId: string,\n data: RecordData,\n options?: { show_decrypted?: boolean }\n ) =>\n this.recordResource.updateById(\n tableName,\n recordId,\n data,\n options,\n dbId\n ),\n delete: (tableName: string, options: RecordDeleteOptions) =>\n this.recordResource.delete(tableName, options, dbId),\n deleteById: (tableName: string, recordId: string) =>\n this.recordResource.deleteById(tableName, recordId, dbId),\n };\n }\n\n // Method 4: Create fluent record builder\n record(tableName: string): RecordBuilder {\n return createRecordBuilder({\n tableName,\n recordResource: this.recordResource,\n });\n }\n\n // Direct SQL operations\n get sql() {\n const dbId = this.currentDatabase?.databaseId;\n return {\n textToSQL: (prompt: string, options?: TextToSQLOptions) =>\n this.sqlResource.textToSQL(prompt, options, dbId),\n executeSQL: (query: string) => this.sqlResource.executeSQL(query, dbId),\n };\n }\n\n /**\n * Workflow integration operations.\n *\n * @example\n * ```typescript\n * // Execute and poll for result\n * const result = await client.workflow.executeIntegration({\n * nodes: [{ id: 'api1', data: { ... }, activity_data: { ... } }],\n * });\n *\n * // Get execution result by ID\n * const exec = await client.workflow.getIntegrationExecuteById('run-uuid');\n *\n * // List integrations\n * const integrations = await client.workflow.getIntegrations();\n * ```\n */\n get workflow() {\n return {\n executeIntegration: (params: ExecuteIntegrationParams) =>\n this.workflowResource.executeIntegration(params),\n getIntegrationExecuteById: (executionId: string) =>\n this.workflowResource.getIntegrationExecuteById(executionId),\n getIntegrations: (params?: GetIntegrationsParams) =>\n this.workflowResource.getIntegrations(params),\n getCredentials: (params: GetCredentialsParams) =>\n this.workflowResource.getCredentials(params),\n getIntegrationResource: (params: GetIntegrationResourceParams) =>\n this.workflowResource.getIntegrationResource(params),\n getIntegrationForm: (params: GetIntegrationFormParams) =>\n this.workflowResource.getIntegrationForm(params),\n };\n }\n\n /**\n * Serverless function operations.\n *\n * @example\n * ```typescript\n * // List all serverless functions\n * const list = await client.serverless.list();\n *\n * // Create a new serverless function\n * const fn = await client.serverless.create({\n * Name: 'my-api',\n * Runtime: 'code',\n * CodeOpts: { Language: 'nodejs/20', Code: '...' },\n * Resources: { CPU: 0.1, MemoryMB: 128, MemoryMaxMB: 128 },\n * Scaling: { AutoStop: false, Min: 1, Max: 1, MaxIdleTime: 0 },\n * });\n *\n * // Get a serverless function by ID\n * const details = await client.serverless.get('serverless-id');\n *\n * // Get builds\n * const builds = await client.serverless.getBuilds({ appId: 'id' });\n *\n * // Get runtime logs\n * const logs = await client.serverless.getLogs({ appId: 'id' });\n * ```\n */\n get serverless() {\n return {\n list: (params?: ListServerlessParams) =>\n this.serverlessResource.list(params),\n get: (appId: string) => this.serverlessResource.get(appId),\n create: (params: CreateServerlessParams) =>\n this.serverlessResource.create(params),\n createAndWait: (params: CreateServerlessParams) =>\n this.serverlessResource.createAndWait(params),\n update: (params: UpdateServerlessParams) =>\n this.serverlessResource.update(params),\n updateAndWait: (params: UpdateServerlessParams) =>\n this.serverlessResource.updateAndWait(params),\n getBuilds: (params: GetBuildsParams) =>\n this.serverlessResource.getBuilds(params),\n getLogs: (params: GetLogsParams) =>\n this.serverlessResource.getLogs(params),\n getBuildLogs: (params: GetBuildLogsParams) =>\n this.serverlessResource.getBuildLogs(params),\n pollStatus: (\n appId: string,\n options?: { intervalMs?: number; maxAttempts?: number }\n ) => this.serverlessResource.pollStatus(appId, options),\n };\n }\n\n get storage() {\n return {\n list: (params?: ListStorageParams) => this.storageResource.list(params),\n upload: (params: UploadParams) => this.storageResource.upload(params),\n createFolder: (params: CreateFolderParams) =>\n this.storageResource.createFolder(params),\n deleteFile: (params: DeleteFileParams) =>\n this.storageResource.deleteFile(params),\n makePublic: (filePath: string) =>\n this.storageResource.makePublic(filePath),\n makePrivate: (filePath: string) =>\n this.storageResource.makePrivate(filePath),\n downloadFile: (params: DownloadFileParams) =>\n this.storageResource.downloadFile(params),\n };\n }\n\n // SQL resource access for testing\n getSqlResource(): SqlResource {\n return this.sqlResource;\n }\n\n // Configuration management\n updateApiKey(newApiKey: string): void {\n this.configManager.updateConfig({ apiKey: newApiKey });\n this.authManager.updateApiKey(newApiKey);\n }\n\n updateConfig(updates: Partial<ClientConfig>): void {\n this.configManager.updateConfig(updates);\n this.baseClient.updateConfig(this.configManager.getConfig());\n this.updateAllResourcesConfig();\n }\n\n getConfig(): ClientConfig {\n return this.configManager.getConfig();\n }\n\n // Authentication management\n async validateApiKey(): Promise<boolean> {\n return this.authManager.validateApiKeyAsync();\n }\n\n isAuthenticated(): boolean {\n return this.authManager.isAuthenticated();\n }\n\n // HTTP client access\n getHttpClient(): BaseClient {\n return this.baseClient;\n }\n\n // Interceptor management\n addRequestInterceptor(\n interceptor: (\n config: HttpRequestConfig\n ) => HttpRequestConfig | Promise<HttpRequestConfig>\n ): number {\n return this.baseClient.getInterceptors().request.use(interceptor);\n }\n\n addResponseInterceptor(\n onFulfilled?: (\n response: HttpResponse\n ) => HttpResponse | Promise<HttpResponse>,\n onRejected?: (error: unknown) => unknown\n ): number {\n return this.baseClient\n .getInterceptors()\n .response.use(onFulfilled, onRejected);\n }\n\n ejectRequestInterceptor(id: number): void {\n this.baseClient.getInterceptors().request.eject(id);\n }\n\n ejectResponseInterceptor(id: number): void {\n this.baseClient.getInterceptors().response.eject(id);\n }\n\n // Connection testing\n async testConnection(): Promise<boolean> {\n try {\n return await this.authManager.validateApiKeyAsync();\n } catch (error) {\n return false;\n }\n }\n\n // Get client version\n getVersion(): string {\n return '1.0.0';\n }\n\n // Environment helpers\n getEnvironment(): Environment {\n return this.configManager.getConfig().environment;\n }\n\n getRegion(): string {\n return this.configManager.getConfig().region;\n }\n\n // Debug helpers\n enableDebug(): void {\n this.configManager.updateConfig({ debug: true });\n this.baseClient.updateConfig(this.configManager.getConfig());\n this.updateAllResourcesConfig();\n }\n\n disableDebug(): void {\n this.configManager.updateConfig({ debug: false });\n this.baseClient.updateConfig(this.configManager.getConfig());\n this.updateAllResourcesConfig();\n }\n\n isDebugEnabled(): boolean {\n return this.configManager.getConfig().debug || false;\n }\n\n // Private method to update all resource configurations\n private updateAllResourcesConfig(): void {\n // Recreate all resources with updated config\n this.tableResource = new TableResource(this.baseClient);\n this.columnResource = new ColumnResource(this.baseClient);\n this.recordResource = new RecordResource(this.baseClient);\n this.sqlResource = new SqlResource(this.baseClient);\n this.indexResource = new IndexResource(this.baseClient);\n this.databaseResource = new DatabaseResource(this.baseClient);\n\n this.workflowResource = new WorkflowResource(this.baseClient);\n\n this.serverlessResource = new ServerlessResource(this.baseClient);\n\n this.storageResource = new StorageResource(this.baseClient);\n }\n\n // Security methods to prevent API key exposure\n toString(): string {\n const config = this.getConfig();\n return `BolticClient { environment: \"${config.environment}\", region: \"${config.region}\", debug: ${config.debug} }`;\n }\n\n toJSON(): object {\n const config = this.getConfig();\n return {\n environment: config.environment,\n region: config.region,\n debug: config.debug,\n timeout: config.timeout,\n version: this.getVersion(),\n };\n }\n\n // Custom inspect method for Node.js console logging\n [Symbol.for('nodejs.util.inspect.custom')](): string {\n return this.toString();\n }\n}\n","import { BolticClient } from '../client/boltic-client';\nimport { PaginationInfo } from '../types/common/operations';\n\nexport interface MockClientOptions {\n apiKey?: string;\n environment?: 'local' | 'sit' | 'uat' | 'prod';\n region?: 'asia-south1' | 'us-central1';\n mockResponses?: Record<string, unknown>;\n debug?: boolean;\n}\n\nexport function createTestClient(\n options: MockClientOptions = {}\n): BolticClient {\n return new BolticClient(options.apiKey || 'test-api-key-12345', {\n environment: 'local',\n region: 'asia-south1',\n debug: options.debug ?? true,\n timeout: 30000,\n ...options,\n });\n}\n\nexport function createMockResponse<T>(data: T, pagination?: PaginationInfo) {\n return {\n data,\n pagination,\n };\n}\n\nexport function createErrorResponse(error: string, details?: unknown) {\n return {\n error,\n details,\n };\n}\n"],"names":["REGION_CONFIGS","local","baseURL","timeout","debug","sit","uat","prod","ENV_CONFIGS","REGION_BASE_HOSTS","host","resolveServiceURL","region","environment","servicePath","regionConfig","Error","envConfig","isErrorResponse","response","error","isListResponse","ValidationError","constructor","message","failures","super","this","name","ApiError","statusCode","createErrorWithContext","context","getHttpStatusCode","status","formatError","formatted","JSON","stringify","String","decodeArrayBufferErrorBody","buffer","txt","TextDecoder","decode","parse","AxiosAdapter","axios","require","request","config","isFormData","FormData","data","headers","axiosConfig","url","method","toLowerCase","params","signal","validateStatus","responseType","responseData","ArrayBuffer","normalizeAxiosDataAfterResponse","trim","startsWith","includes","preMatch","match","statusText","isHtmlError","axiosError","code","networkError","errorCode","originalMessage","originalError","async","parseFetchResponseData","buf","arrayBuffer","parseFetchBodyArrayBuffer","contentType","get","json","text","parseFetchBodyDefault","FetchAdapter","URL","Object","entries","forEach","key","value","searchParams","append","headerMap","init","body","controller","AbortController","timeoutId","setTimeout","abort","combinedController","addEventListener","fetch","toString","clearTimeout","type","errorMessage","createHttpAdapter","AuthManager","tokenInfo","maxRetries","validateApiKey","apiKey","length","getAuthHeaders","updateApiKey","newApiKey","isAuthenticated","validateApiKeyAsync","getTokenInfo","getMaxRetries","toJSON","authenticated","Symbol","for","SERVICE_PATHS","BaseApiClient","httpAdapter","resolveAdditionalServiceURL","buildHeaders","Accept","formatErrorResponse","prefix","console","apiError","meta","safeConfig","client","InterceptorManagerImpl","requestInterceptors","Map","responseInterceptors","nextId","use","interceptor","id","set","eject","delete","onFulfilled","onRejected","fulfilled","rejected","executeRequestInterceptors","result","Array","from","values","executeResponseInterceptors","executeErrorInterceptors","BaseClient","authManager","interceptors","setupDefaultInterceptors","authHeaders","log","handleError","errorData","isClientError","isServerError","isAuthError","isNotFoundError","isRateLimitError","lastError","attempt","requestConfig","delay","retryDelay","Math","pow","Promise","resolve","post","put","patch","getInterceptors","updateConfig","updates","getConfig","BaseResource","basePath","getBasePath","makeRequest","path","options","buildQueryParams","fields","join","sort","map","s","field","order","limit","offset","where","handleResponse","ConfigManager","overrides","retryAttempts","filterObjectFields","obj","filtered","filterArrayFields","arr","addDbIdToUrl","dbId","separator","encodeURIComponent","COLUMN_ENDPOINTS","rateLimit","requests","window","buildEndpointPath","endpoint","replace","unreplacedParams","DateFormatEnum","freeze","MMDDYY","MMDDYYYY","MM_DD_YYYY","DD_MM_YYYY","DDMMYYYY","DDMMYY","YYYY_MM_DD","MMMM__DD__YYYY","MMM__DD__YYYY","ddd__MMM__DD__YYYY","TimeFormatEnum","HH_mm_ss","HH_mm_ssZ","HH_mm_ss_SSS","HH_mm_ss__Z","HH_mm__AMPM","HH_mm_ss__AMPM","FieldTypeEnum","ALLOWED_FIELD_TYPE_CONVERSIONS","email","number","currency","checkbox","dropdown","link","vector","sparsevec","halfvec","encrypted","FIELD_SPECIFIC_KEYS_MAP","transformColumnCreateRequest","is_nullable","is_primary_key","is_unique","is_visible","is_readonly","is_indexed","field_order","alignment","timezone","date_format","transformDateFormat","time_format","transformTimeFormat","decimals","currency_format","selection_source","selectable_items","multiple_selections","phone_format","vector_dimension","description","default_value","show_decrypted","is_deterministic","dateFormat","timeFormat","ColumnsApiClient","createColumn","tableId","table_id","transformedRequest","createColumns","columns","createdColumns","column","push","filteredColumns","splice","listColumns","db_id","getColumn","columnId","field_id","updateColumn","transformedUpdates","apiRequest","transformColumnUpdateRequest","deleteColumn","findColumnByName","columnName","page","page_no","page_size","filters","operator","listResult","convertColumnDetailsToUpdateRequest","columnDetails","updateColumnByName","findResult","mergedUpdates","deleteColumnByName","TABLE_ENDPOINTS","FILTER_OPERATORS","EQUALS","NOT_EQUALS","GREATER_THAN","GREATER_THAN_EQUAL","LESS_THAN","LESS_THAN_EQUAL","LIKE","ILIKE","STARTS_WITH","IN","NOT_IN","IS_EMPTY","IS_NULL","IS_NOT_NULL","BETWEEN","ARRAY_CONTAINS","ARRAY_NOT_CONTAINS","ANY","IS_ONE_OF_ARRAY","DROPDOWN_ITEM_STARTS_WITH","WITHIN","OPERATOR_MAPPING","$eq","$ne","$gt","$gte","$lt","$lte","$like","$ilike","$startsWith","$in","$notIn","$between","$isEmpty","$isNull","$isNotNull","$arrayContains","$arrayNotContains","$any","$isOneOfArray","$dropdownItemStartsWith","$within","normalizeFilters","isArray","warn","mapWhereToFilters","condition","apiOperator","FilterBuilder","equals","notEquals","greaterThan","lessThan","between","start","end","like","isEmpty","isNull","arrayContains","build","clear","transformFieldDefinition","TablesApiClient","createTable","is_ai_generated_schema","is_template","transformTableCreateRequest","listTables","getTable","updateTable","updateData","deleteTable","TableResource","tablesApiClient","create","processedData","processFieldsDefaults","processedFields","i","processedField","transformTableQueryToApiRequest","pageNo","floor","direction","findAll","resourceId","resource_id","requestPayload","findOne","table","findByName","findById","update","tableResult","snapshot_url","rename","oldName","newName","ColumnResource","columnsApiClient","tableName","tableInfo","getTableInfo","processedColumn","processColumnDefaults","generateFieldOrder","existingColumns","maxOrder","col","Date","now","transformColumnQueryToApiRequest","createMany","processedColumns","success","tableResource","getTableId","DATABASE_ENDPOINTS","buildDatabaseEndpointPath","DatabasesApiClient","createDatabase","listDatabases","queryParams","URLSearchParams","connector_id","add_default_if_missing","updateDatabase","deleteDatabase","listDatabaseJobs","pollDeleteStatus","jobId","job_id","DatabaseResource","apiClient","filtersWithoutStatus","filter","f","pagination","total_count","total_pages","ceil","per_page","current_page","dbInternalName","getDefault","dbInfo","updateRequest","db_name","is_default","listJobs","deleted_by_me","INDEX_ENDPOINTS","buildIndexEndpointPath","IndexesApiClient","addIndex","listIndexes","query","deleteIndex","IndexResource","resolveTableId","indexName","index_name","RECORD_ENDPOINTS","buildRecordEndpointPath","RecordsApiClient","insertRecord","recordData","insertManyRecords","records","validation","getRecord","recordId","record_id","listRecords","queryOptions","updateRecords","rest","apiPayload","updateRecordById","updateOptions","deleteRecords","sdkRequest","record_ids","transformDeleteRequest","deleteRecordById","RecordResource","insert","completeDataResult","ensureCompleteRecordData","requestData","insertMany","optionsOrDbId","showDecrypted","databaseId","list","requestOptions","updateById","deleteById","columnResource","columnsResult","completeData","RecordBuilder","recordResource","conditions","orderBy","count","pageSize","select","record","buildWhereConditions","apiFilter","fieldName","assign","deleteByIds","ids","deleteOptions","getQueryOptions","getUpdateData","createRecordBuilder","SQL_ENDPOINTS","buildSqlEndpointPath","SqlApiClient","textToSQL","sqlResponse","createAsyncIterable","executeSQL","SqlResource","sqlApiClient","prompt","current_query","currentQuery","transformTextToSQLRequest","TableBuilder","describe","nullable","unique","indexed","defaultValue","longText","currencyFormat","items","multiple","phone","format","dateTime","dimension","addField","removeField","index","getFields","getName","getDescription","createTableBuilder","SCHEMA_TYPE_MAPPING","string","fallback_value","boolean","secondary_type","int","integer","date","password","textarea","multiselect","autocomplete","radio","radiobuttons","toggle","hidden","slider","datepicker","phoneinput","time","datetime","multitext","array","keyvalue","object","WORKFLOW_ENDPOINTS","buildWorkflowEndpointPath","WorkflowApiClient","integrationBaseURL","executeActivity","getExecutionById","runId","run_id","getIntegrations","getCredentials","entity","toUpperCase","getIntegrationResource","integration_slug","getIntegrationForm","resource","operation","secret","FORM_META_FIELDS","Set","getSchemaMapping","displayType","sleep","ms","WorkflowResource","executeIntegration","nodes","properties","payload","global_variables","buildExecuteActivityBody","executeResult","executeOnly","executionId","execution_id","pollExecution","getIntegrationExecuteById","rawResult","parameters","transformed","asJsonSchema","skipFields","has","mapping","isRequired","required","prop","default","enum","opt","transformFormToJsonSchema","transformFormToDefaults","schema","keys","TERMINAL_STATUSES","SERVERLESS_ENDPOINTS","buildServerlessEndpointPath","ServerlessApiClient","sortBy","sortOrder","appId","app_id","getBuilds","getLogs","defaultStart","timestampStart","timestampEnd","metric_interval","getBuildLogs","build_id","buildId","tail","ServerlessResource","createAndWait","createResult","ID","pollStatus","updateAndWait","updateResult","interval","intervalMs","maxAttempts","Status","STORAGE_ENDPOINTS","buildStorageEndpointPath","ERR_PREFIX","StorageApiClient","requestStorage","qs","storageTypeQuery","storageType","q","listQuery","nextPageToken","normalizeExpireInMinutes","raw","n","Number","isFinite","truncated","trunc","min","max","isTruthyFormFlag","v","appendUploadVisibility","form","prototype","hasOwnProperty","call","public","expire_in","is_public","is_public_permanent","buildUploadForm","logicalName","filename","file_name","file","filepath","overwrite","isErrorResult","isAclErrorResult","buildObjectAccessSummary","filePath","row","fallbackPublic","fullPath","size","updated","updatedAt","Boolean","isPublic","findFileListItem","lastSlash","lastIndexOf","nameOnly","slice","folderPrefix","files","find","r","isDirectory","normalizeListItem","metadata","updatedRaw","timeUpdated","parentPath","cdnRaw","cdnUrl","item","folderName","normalizeUploadData","out","temporary_sharable_link","shareable_link","public_url","normalizeListResponse","createFolder","folder_path","deleteFile","totalsize","setObjectAccess","acl","file_path","upload","resolveFileSizeBytes","fileName","hit","downloadFile","sizeBytes","start_byte","end_byte","d","ct","bytes","StorageResource","makePublic","makePrivate","BolticClient","currentDatabase","clientOptions","configManager","baseClient","sqlResource","indexResource","databaseResource","workflowResource","serverlessResource","storageResource","getCurrentDatabase","useDatabase","db","db_internal_name","databases","tables","indexes","sql","workflow","serverless","storage","getSqlResource","updateAllResourcesConfig","getHttpClient","addRequestInterceptor","addResponseInterceptor","ejectRequestInterceptor","ejectResponseInterceptor","testConnection","getVersion","getEnvironment","getRegion","enableDebug","disableDebug","isDebugEnabled","version","whereOrFilters","whereOperator","details","reverseMapping","sdkOp","apiOp","sdkOperator","fieldCondition"],"mappings":"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"}