rqlite-js 2.5.7 → 3.0.0

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.
Files changed (71) hide show
  1. package/README.md +354 -157
  2. package/dist/index.cjs +904 -0
  3. package/dist/index.cjs.map +1 -0
  4. package/dist/index.d.cts +329 -0
  5. package/dist/index.d.ts +329 -0
  6. package/dist/index.js +865 -0
  7. package/dist/index.js.map +1 -0
  8. package/docs/MIGRATION-v2-to-v3.md +71 -0
  9. package/package.json +73 -42
  10. package/src/api/backup/index.ts +69 -0
  11. package/src/api/backup-formats.ts +8 -0
  12. package/src/api/client/index.ts +97 -0
  13. package/src/api/consistency-levels.ts +10 -0
  14. package/src/api/data/index.ts +87 -0
  15. package/src/api/paths.ts +13 -0
  16. package/src/api/query-params.ts +15 -0
  17. package/src/api/results/data-result-error.ts +41 -0
  18. package/src/api/results/data-result.ts +91 -0
  19. package/src/api/results/data-results.ts +91 -0
  20. package/src/api/results/index.ts +7 -0
  21. package/src/api/results/result-fields.ts +14 -0
  22. package/src/api/status/index.ts +53 -0
  23. package/src/http-request/auth-keys.ts +14 -0
  24. package/{es6/http-request/errors.js → src/http-request/errors.ts} +4 -3
  25. package/src/http-request/http-headers.ts +19 -0
  26. package/{es6/http-request/http-methods.js → src/http-request/http-methods.ts} +0 -27
  27. package/src/http-request/index.ts +676 -0
  28. package/{es6/http-request/retryable.js → src/http-request/retryable.ts} +1 -1
  29. package/src/index.ts +38 -0
  30. package/.eslintrc +0 -20
  31. package/.travis.yml +0 -24
  32. package/es6/api/backup/index.js +0 -71
  33. package/es6/api/client/index.js +0 -83
  34. package/es6/api/data/index.js +0 -129
  35. package/es6/api/results/data-result-error.js +0 -32
  36. package/es6/api/results/data-result.js +0 -134
  37. package/es6/api/results/data-results.js +0 -121
  38. package/es6/api/results/index.js +0 -7
  39. package/es6/api/status/index.js +0 -54
  40. package/es6/http-request/index.js +0 -743
  41. package/es6/index.js +0 -19
  42. package/jsconfig.json +0 -19
  43. package/lib/api/backup/index.js +0 -72
  44. package/lib/api/backup/index.js.map +0 -1
  45. package/lib/api/client/index.js +0 -84
  46. package/lib/api/client/index.js.map +0 -1
  47. package/lib/api/data/index.js +0 -130
  48. package/lib/api/data/index.js.map +0 -1
  49. package/lib/api/results/data-result-error.js +0 -33
  50. package/lib/api/results/data-result-error.js.map +0 -1
  51. package/lib/api/results/data-result.js +0 -135
  52. package/lib/api/results/data-result.js.map +0 -1
  53. package/lib/api/results/data-results.js +0 -122
  54. package/lib/api/results/data-results.js.map +0 -1
  55. package/lib/api/results/index.js +0 -8
  56. package/lib/api/results/index.js.map +0 -1
  57. package/lib/api/status/index.js +0 -55
  58. package/lib/api/status/index.js.map +0 -1
  59. package/lib/http-request/content-types.js +0 -5
  60. package/lib/http-request/content-types.js.map +0 -1
  61. package/lib/http-request/errors.js +0 -17
  62. package/lib/http-request/errors.js.map +0 -1
  63. package/lib/http-request/http-methods.js +0 -40
  64. package/lib/http-request/http-methods.js.map +0 -1
  65. package/lib/http-request/index.js +0 -744
  66. package/lib/http-request/index.js.map +0 -1
  67. package/lib/http-request/retryable.js +0 -42
  68. package/lib/http-request/retryable.js.map +0 -1
  69. package/lib/index.js +0 -20
  70. package/lib/index.js.map +0 -1
  71. /package/{es6/http-request/content-types.js → src/http-request/content-types.ts} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":["parsedHostToFind: URL","fetchInit: RequestInit & { dispatcher?: unknown }","location: string | undefined","responseBody: unknown","query: Record<string, unknown>","obj: Record<string, unknown>","response: HttpResponse"],"sources":["../src/http-request/http-methods.ts","../src/http-request/content-types.ts","../src/http-request/errors.ts","../src/http-request/retryable.ts","../src/http-request/auth-keys.ts","../src/http-request/http-headers.ts","../src/http-request/index.ts","../src/api/query-params.ts","../src/api/client/index.ts","../src/api/results/result-fields.ts","../src/api/results/data-result.ts","../src/api/results/data-result-error.ts","../src/api/results/data-results.ts","../src/api/paths.ts","../src/api/consistency-levels.ts","../src/api/data/index.ts","../src/api/backup-formats.ts","../src/api/backup/index.ts","../src/api/status/index.ts","../src/index.ts"],"sourcesContent":["/**\n * Http methods\n * @module http-request/http-methods\n */\n\nexport const HTTP_METHOD_DELETE = 'DELETE'\nexport const HTTP_METHOD_GET = 'GET'\nexport const HTTP_METHOD_HEAD = 'HEAD'\nexport const HTTP_METHOD_OPTIONS = 'OPTIONS'\nexport const HTTP_METHOD_PATCH = 'PATCH'\nexport const HTTP_METHOD_POST = 'POST'\nexport const HTTP_METHOD_PUT = 'PUT'\n","export const CONTENT_TYPE_TEXT_PLAIN = 'text/plain'\nexport const CONTENT_TYPE_APPLICATION_JSON = 'application/json'\nexport const CONTENT_TYPE_APPLICATION_X_WWW_FORM_URLENCODED = 'application/x-www-form-urlencoded'\nexport const CONTENT_TYPE_APPLICATION_OCTET_STREAM = 'application/octet-stream'\n","/**\n * Http request errors\n * @module http-request/errors\n */\n\n/**\n * Error when max redirect attempts have been reached\n */\nexport class ERROR_HTTP_REQUEST_MAX_REDIRECTS extends Error {\n code: string\n\n constructor (...args: ConstructorParameters<typeof Error>) {\n super(...args)\n this.name = this.constructor.name\n this.code = this.constructor.name\n }\n}\n","import {\n HTTP_METHOD_DELETE,\n HTTP_METHOD_GET,\n HTTP_METHOD_HEAD,\n HTTP_METHOD_OPTIONS,\n HTTP_METHOD_PATCH,\n HTTP_METHOD_POST,\n HTTP_METHOD_PUT,\n} from './http-methods.js'\n\n/**\n * Error codes which can be retried\n */\nexport const RETRYABLE_ERROR_CODES = new Set([\n 'EADDRINUSE',\n 'EAI_AGAIN',\n 'ECONNREFUSED',\n 'ECONNRESET',\n 'ENETUNREACH',\n 'ENOTFOUND',\n 'EPIPE',\n 'ETIMEDOUT',\n])\n\n/**\n * HTTP status codes which can be retried\n */\nexport const RETRYABLE_STATUS_CODES = new Set([408, 413, 429, 500, 502, 503, 504, 521, 522, 524])\n\n/**\n * HTTP methods which can be retried\n */\nexport const RETRYABLE_HTTP_METHODS = new Set([\n HTTP_METHOD_DELETE,\n HTTP_METHOD_GET,\n HTTP_METHOD_HEAD,\n HTTP_METHOD_OPTIONS,\n HTTP_METHOD_PATCH,\n HTTP_METHOD_POST,\n HTTP_METHOD_PUT,\n])\n","/**\n * Authentication Map key constants\n * @module http-request/auth-keys\n */\n\n/**\n * Username key for authentication\n */\nexport const AUTH_USERNAME = 'username'\n\n/**\n * Password key for authentication\n */\nexport const AUTH_PASSWORD = 'password'\n","/**\n * HTTP header name constants used by RQLite clients\n * @module http-request/http-headers\n */\n\n/**\n * Accept request header\n */\nexport const HTTP_HEADER_ACCEPT = 'Accept'\n\n/**\n * Content-Type request header\n */\nexport const HTTP_HEADER_CONTENT_TYPE = 'Content-Type'\n\n/**\n * Location response header (redirects)\n */\nexport const HTTP_HEADER_LOCATION = 'Location'\n","/**\n * Plain HTTP client to be used when creating RQLite specific API HTTP clients\n * @module http-request\n * @see https://rqlite.io/docs/api/api/\n */\nimport { Readable } from 'node:stream'\nimport type { Agent as HttpAgent } from 'node:http'\nimport type { Agent as HttpsAgent } from 'node:https'\nimport {\n HTTP_METHOD_GET,\n HTTP_METHOD_POST,\n} from './http-methods.js'\nimport {\n CONTENT_TYPE_APPLICATION_JSON,\n} from './content-types.js'\nimport { ERROR_HTTP_REQUEST_MAX_REDIRECTS } from './errors.js'\nimport {\n RETRYABLE_ERROR_CODES,\n RETRYABLE_HTTP_METHODS,\n RETRYABLE_STATUS_CODES,\n} from './retryable.js'\nimport { AUTH_PASSWORD, AUTH_USERNAME } from './auth-keys.js'\nimport {\n HTTP_HEADER_ACCEPT,\n HTTP_HEADER_CONTENT_TYPE,\n HTTP_HEADER_LOCATION,\n} from './http-headers.js'\n\nexport type HttpAuthentication = {\n username?: string\n password?: string\n}\n\nexport type HttpRequestOptions = {\n auth?: HttpAuthentication\n body?: unknown\n headers?: Record<string, string>\n httpMethod?: string\n query?: Record<string, unknown>\n stream?: boolean\n timeout?: number\n uri?: string\n useLeader?: boolean\n retries?: number\n maxRedirects?: number\n attempt?: number\n retryAttempt?: number\n redirectAttempt?: number\n attemptHostIndex?: number\n exponentailBackoffBase?: number\n exponentailBackoffExponent?: number\n json?: boolean\n httpAgent?: HttpAgent | DispatcherLike\n httpsAgent?: HttpsAgent | DispatcherLike\n}\n\n/** Minimal undici/Node fetch dispatcher shape */\nexport type DispatcherLike = {\n dispatch?: (...args: unknown[]) => unknown\n close?: () => Promise<void>\n destroy?: () => Promise<void>\n}\n\nexport type HttpResponse = {\n status: number\n body: unknown\n}\n\nexport type HttpRequestConstructorOptions = {\n authentication?: HttpAuthentication\n activeHostRoundRobin?: boolean\n httpAgent?: HttpAgent | DispatcherLike\n httpsAgent?: HttpsAgent | DispatcherLike\n retryableErrorCodes?: Set<string> | string[]\n retryableStatusCodes?: Set<number> | number[]\n retryableHttpMethods?: Set<string> | string[]\n exponentailBackoffBase?: number\n exponentailBackoffExponent?: number\n}\n\n/**\n * The default timeout value\n */\nexport const DEAULT_TIMEOUT = 30000\n\n/**\n * The default to retry a request using the next host in the chain\n */\nexport const DEAULT_RETRY_DELAY = 30000\n\n/**\n * Create default header for all HTTP requests\n */\nexport function createDefaultHeaders (headers: Record<string, string> = {}): Record<string, string> {\n const accept = headers[HTTP_HEADER_ACCEPT] || CONTENT_TYPE_APPLICATION_JSON\n return { ...headers, [HTTP_HEADER_ACCEPT]: accept }\n}\n\n/**\n * Clean the request path remove / from the beginning\n */\nfunction cleanPath (path: string): string {\n return String(path).replace(/^\\//, '')\n}\n\n/**\n * Serialize query params similar to qs arrayFormat: 'brackets'\n */\nexport function stringifyQuery (params: Record<string, unknown> = {}): string {\n const search = new URLSearchParams()\n Object.entries(params).forEach(([key, value]) => {\n if (typeof value === 'undefined') {\n return\n }\n if (Array.isArray(value)) {\n value.forEach((entry) => {\n search.append(`${key}[]`, String(entry))\n })\n return\n }\n search.append(key, String(value))\n })\n return search.toString()\n}\n\nfunction basicAuthHeader (username: string, password: string): string {\n const token = Buffer.from(`${username}:${password}`).toString('base64')\n return `Basic ${token}`\n}\n\nfunction getErrorCode (error: unknown): string | undefined {\n if (!error || typeof error !== 'object') {\n return undefined\n }\n const err = error as { code?: string, cause?: { code?: string }, name?: string }\n if (typeof err.code === 'string') {\n return err.code\n }\n if (err.cause && typeof err.cause.code === 'string') {\n return err.cause.code\n }\n if (err.name === 'AbortError' || err.name === 'TimeoutError') {\n return 'ETIMEDOUT'\n }\n return undefined\n}\n\n/**\n * Returns the next wait interval, in milliseconds, using an exponential\n * backoff algorithm.\n */\nexport function getWaitTimeExponential (attempt = 0, base = 100, exponent = 2): number {\n if (attempt === 0) {\n return 0\n }\n return (exponent ** attempt) * base\n}\n\n/**\n * Generic HTTP Request class which all RQLiteJS clients should extend\n */\nexport default class HttpRequest {\n activeHostIndex = 0\n\n activeHostRoundRobin = true\n\n absoluteUriPattern = /^https?:\\/\\//\n\n hosts: string[] = []\n\n httpAgent?: HttpAgent | DispatcherLike\n\n httpsAgent?: HttpsAgent | DispatcherLike\n\n leaderHostIndex = 0\n\n retryableErrorCodes: Set<string> = RETRYABLE_ERROR_CODES\n\n retryableStatusCodes: Set<number> = RETRYABLE_STATUS_CODES\n\n retryableHttpMethods: Set<string> = RETRYABLE_HTTP_METHODS\n\n exponentailBackoffBase = 100\n\n exponentailBackoffExponent = 1.1\n\n authentication = new Map<string, string>()\n\n constructor (hosts: string[] | string, options: HttpRequestConstructorOptions = {}) {\n this.setHosts(hosts)\n if (this.getTotalHosts() === 0) {\n throw new Error('At least one host must be provided')\n }\n const {\n activeHostRoundRobin = true,\n httpAgent,\n httpsAgent,\n retryableErrorCodes,\n retryableStatusCodes,\n retryableHttpMethods,\n exponentailBackoffExponent,\n exponentailBackoffBase,\n authentication,\n } = options\n if (typeof authentication === 'object') {\n const { username, password } = authentication\n if (username) {\n this.authentication.set(AUTH_USERNAME, username)\n }\n if (password) {\n this.authentication.set(AUTH_PASSWORD, password)\n }\n }\n if (typeof activeHostRoundRobin !== 'undefined') {\n this.setActiveHostRoundRobin(activeHostRoundRobin)\n }\n if (typeof httpAgent !== 'undefined') {\n this.setHttpAgent(httpAgent)\n }\n if (typeof httpsAgent !== 'undefined') {\n this.setHttpsAgent(httpsAgent)\n }\n if (retryableErrorCodes instanceof Set || Array.isArray(retryableErrorCodes)) {\n this.setRetryableErrorCodes(\n Array.isArray(retryableErrorCodes) ? new Set(retryableErrorCodes) : retryableErrorCodes,\n )\n }\n if (retryableStatusCodes instanceof Set || Array.isArray(retryableStatusCodes)) {\n this.setRetryableStatusCodes(\n Array.isArray(retryableStatusCodes) ? new Set(retryableStatusCodes) : retryableStatusCodes,\n )\n }\n if (retryableHttpMethods instanceof Set || Array.isArray(retryableHttpMethods)) {\n this.setRetryableHttpMethods(\n Array.isArray(retryableHttpMethods) ? new Set(retryableHttpMethods) : retryableHttpMethods,\n )\n }\n if (Number.isFinite(exponentailBackoffBase)) {\n this.setExponentailBackoffBase(exponentailBackoffBase as number)\n }\n if (Number.isFinite(exponentailBackoffExponent)) {\n this.setExponentailBackoffExponent(exponentailBackoffExponent as number)\n }\n }\n\n setAuthentication (authentication: HttpAuthentication = {}): void {\n const { username, password } = authentication\n if (username) {\n this.authentication.set(AUTH_USERNAME, username)\n }\n if (password) {\n this.authentication.set(AUTH_PASSWORD, password)\n }\n }\n\n setExponentailBackoffBase (exponentailBackoffBase: number): void {\n this.exponentailBackoffBase = exponentailBackoffBase\n }\n\n getExponentailBackoffBase (): number {\n return this.exponentailBackoffBase\n }\n\n setExponentailBackoffExponent (exponentailBackoffExponent: number): void {\n this.exponentailBackoffExponent = exponentailBackoffExponent\n }\n\n getExponentailBackoffExponent (): number {\n return this.exponentailBackoffExponent\n }\n\n setRetryableErrorCodes (retryableErrorCodes: Set<string>): void {\n this.retryableErrorCodes = retryableErrorCodes\n }\n\n getRetryableErrorCodes (): Set<string> {\n return this.retryableErrorCodes\n }\n\n setRetryableStatusCodes (retryableStatusCodes: Set<number>): void {\n this.retryableStatusCodes = retryableStatusCodes\n }\n\n getRetryableStatusCodes (): Set<number> {\n return this.retryableStatusCodes\n }\n\n setRetryableHttpMethods (retryableHttpMethods: Set<string>): void {\n this.retryableHttpMethods = retryableHttpMethods\n }\n\n getRetryableHttpMethods (): Set<string> {\n return this.retryableHttpMethods\n }\n\n setHttpAgent (httpAgent: HttpAgent | DispatcherLike): void {\n this.httpAgent = httpAgent\n }\n\n getHttpAgent (): HttpAgent | DispatcherLike | undefined {\n return this.httpAgent\n }\n\n setHttpsAgent (httpsAgent: HttpsAgent | DispatcherLike): void {\n this.httpsAgent = httpsAgent\n }\n\n getHttpsAgent (): HttpsAgent | DispatcherLike | undefined {\n return this.httpsAgent\n }\n\n setHosts (hosts: string[] | string): void {\n const list = !Array.isArray(hosts) ? String(hosts).split(',') : hosts\n this.hosts = list.reduce<string[]>((acc, v) => {\n const host = String(v).trim().replace(/\\/$/, '')\n if (!host) {\n return acc\n }\n return acc.concat(host)\n }, [])\n }\n\n getHosts (): string[] {\n return this.hosts\n }\n\n findHostIndex (host: string): number {\n let parsedHostToFind: URL\n try {\n parsedHostToFind = new URL(host)\n } catch {\n return -1\n }\n return this.getHosts().findIndex((v) => {\n try {\n const parsedHost = new URL(v)\n return (['hostname', 'protocol', 'port', 'pathname'] as const).every(\n (field) => parsedHostToFind[field] === parsedHost[field],\n )\n } catch {\n return false\n }\n })\n }\n\n getActiveHost (useLeader?: boolean): string {\n const activeHostIndex = useLeader ? this.getLeaderHostIndex() : this.getActiveHostIndex()\n return this.getHosts()[activeHostIndex]\n }\n\n setActiveHostIndex (activeHostIndex: number): number {\n if (!Number.isFinite(activeHostIndex)) {\n throw new Error('The activeHostIndex should be a finite number')\n }\n const totalHosts = this.getTotalHosts()\n if (activeHostIndex < 0) {\n this.activeHostIndex = 0\n } else if (activeHostIndex >= totalHosts) {\n this.activeHostIndex = totalHosts - 1\n } else {\n this.activeHostIndex = activeHostIndex\n }\n return this.activeHostIndex\n }\n\n getLeaderHostIndex (): number {\n return this.leaderHostIndex\n }\n\n setLeaderHostIndex (leaderHostIndex: number): number {\n if (!Number.isFinite(leaderHostIndex)) {\n throw new Error('The leaderHostIndex should be a finite number')\n }\n const totalHosts = this.getTotalHosts()\n if (leaderHostIndex < 0) {\n this.leaderHostIndex = 0\n } else if (leaderHostIndex > totalHosts) {\n this.leaderHostIndex = totalHosts - 1\n } else {\n this.leaderHostIndex = leaderHostIndex\n }\n return this.leaderHostIndex\n }\n\n getActiveHostIndex (): number {\n return this.activeHostIndex\n }\n\n setActiveHostRoundRobin (activeHostRoundRobin: boolean): void {\n if (typeof activeHostRoundRobin !== 'boolean') {\n throw new Error('The activeHostRoundRobin argument must be boolean')\n }\n this.activeHostRoundRobin = activeHostRoundRobin\n }\n\n getActiveHostRoundRobin (): boolean {\n return this.activeHostRoundRobin\n }\n\n getNextActiveHostIndex (activeHostIndex = this.getActiveHostIndex()): number {\n const totalHosts = this.getTotalHosts()\n const nextIndex = activeHostIndex + 1\n if (totalHosts === nextIndex) {\n return 0\n }\n return nextIndex\n }\n\n setNextActiveHostIndex (): void {\n if (!this.getActiveHostRoundRobin()) {\n return\n }\n const totalHosts = this.getTotalHosts()\n if (this.getActiveHostRoundRobin() && totalHosts <= 1) {\n return\n }\n this.setActiveHostIndex(this.getNextActiveHostIndex())\n }\n\n getTotalHosts (): number {\n return this.getHosts().length\n }\n\n uriIsAbsolute (uri: string): boolean {\n return this.absoluteUriPattern.test(uri)\n }\n\n requestIsRetryable (options: {\n statusCode?: number\n errorCode?: string\n httpMethod?: string\n } = {}): boolean {\n const {\n statusCode,\n errorCode,\n httpMethod,\n } = options\n if (!httpMethod || !this.getRetryableHttpMethods().has(httpMethod)) {\n return false\n }\n if (statusCode && this.getRetryableStatusCodes().has(statusCode)) {\n return true\n }\n if (errorCode && this.getRetryableErrorCodes().has(errorCode)) {\n return true\n }\n return false\n }\n\n /**\n * Perform an HTTP request using the provided options\n */\n async fetch (options: HttpRequestOptions = {}): Promise<HttpResponse | Readable> {\n const {\n body,\n headers = {},\n httpMethod = HTTP_METHOD_GET,\n query,\n stream = false,\n timeout = DEAULT_TIMEOUT,\n useLeader = false,\n retries = this.getTotalHosts() * 3,\n maxRedirects = 10,\n attempt = 0,\n retryAttempt = 0,\n redirectAttempt = 0,\n attemptHostIndex,\n exponentailBackoffExponent = this.getExponentailBackoffExponent(),\n exponentailBackoffBase = this.getExponentailBackoffBase(),\n httpAgent = this.getHttpAgent(),\n httpsAgent = this.getHttpsAgent(),\n } = options\n\n const activeHost = Number.isFinite(attemptHostIndex)\n ? this.getHosts()[attemptHostIndex as number]\n : this.getActiveHost(useLeader)\n\n let { uri } = options\n if (!uri) {\n throw new Error('The uri option is required')\n }\n uri = this.uriIsAbsolute(uri) ? uri : `${activeHost}/${cleanPath(uri)}`\n\n const requestHeaders = createDefaultHeaders(headers)\n if (this.authentication.size) {\n const username = this.authentication.get(AUTH_USERNAME) || ''\n const password = this.authentication.get(AUTH_PASSWORD) || ''\n requestHeaders.Authorization = basicAuthHeader(username, password)\n }\n\n const url = new URL(uri)\n if (query && typeof query === 'object') {\n const serialized = stringifyQuery(query as Record<string, unknown>)\n if (serialized) {\n url.search = serialized\n }\n }\n\n const controller = new AbortController()\n const timeoutId = setTimeout(() => controller.abort(), timeout)\n\n const fetchInit: RequestInit & { dispatcher?: unknown } = {\n method: httpMethod,\n headers: requestHeaders,\n redirect: 'manual',\n signal: controller.signal,\n }\n\n // Only pass undici-compatible dispatchers. Node http(s).Agent is still\n // accepted via options for API compatibility but is not a fetch dispatcher.\n const agent = url.protocol === 'https:' ? httpsAgent : httpAgent\n if (agent && typeof (agent as DispatcherLike).dispatch === 'function') {\n // undici Dispatcher; cast avoids Node http.Agent type conflict\n const init = fetchInit as { dispatcher?: unknown }\n init.dispatcher = agent\n }\n\n if (typeof body !== 'undefined' && body !== null) {\n if (Buffer.isBuffer(body) || typeof body === 'string') {\n fetchInit.body = body as string | Buffer\n } else {\n fetchInit.body = JSON.stringify(body)\n if (!requestHeaders[HTTP_HEADER_ACCEPT]) {\n requestHeaders[HTTP_HEADER_ACCEPT] = CONTENT_TYPE_APPLICATION_JSON\n }\n if (!(HTTP_HEADER_CONTENT_TYPE in requestHeaders)\n && !Object.keys(requestHeaders).some((k) => k.toLowerCase() === 'content-type')) {\n requestHeaders[HTTP_HEADER_CONTENT_TYPE] = CONTENT_TYPE_APPLICATION_JSON\n }\n fetchInit.headers = requestHeaders\n }\n }\n\n const retryOrRedirect = async (\n responseStatus: number | undefined,\n responseHeaders: Headers | Record<string, string> | undefined,\n errorCode: string | undefined,\n error: unknown,\n ): Promise<HttpResponse | Readable> => {\n const retryable = this.requestIsRetryable({\n statusCode: responseStatus,\n errorCode,\n httpMethod,\n })\n\n let nextAttemptHostIndex = Number.isFinite(attemptHostIndex)\n ? (attemptHostIndex as number)\n : this.getActiveHostIndex()\n nextAttemptHostIndex += 1\n if (nextAttemptHostIndex === this.getTotalHosts()) {\n nextAttemptHostIndex = 0\n }\n\n if (responseStatus === 301 || responseStatus === 302) {\n if (redirectAttempt >= maxRedirects) {\n throw new ERROR_HTTP_REQUEST_MAX_REDIRECTS(\n `The maximum number of redirects ${maxRedirects} has been reached`,\n )\n }\n let location: string | undefined\n if (responseHeaders && typeof (responseHeaders as Headers).get === 'function') {\n location = (responseHeaders as Headers).get(HTTP_HEADER_LOCATION)\n || (responseHeaders as Headers).get(HTTP_HEADER_LOCATION.toLowerCase())\n || undefined\n } else if (responseHeaders && typeof responseHeaders === 'object') {\n const headerMap = responseHeaders as Record<string, string>\n location = headerMap[HTTP_HEADER_LOCATION.toLowerCase()]\n || headerMap[HTTP_HEADER_LOCATION]\n }\n if (useLeader && location) {\n const newLeaderHostIndex = this.findHostIndex(location)\n if (newLeaderHostIndex > -1) {\n this.setLeaderHostIndex(newLeaderHostIndex)\n }\n }\n return this.fetch({\n ...options,\n uri: location,\n attempt: attempt + 1,\n redirectAttempt: redirectAttempt + 1,\n attemptHostIndex: nextAttemptHostIndex,\n })\n }\n\n if (retryable && retryAttempt < retries) {\n const waitTime = getWaitTimeExponential(\n retryAttempt,\n exponentailBackoffBase,\n exponentailBackoffExponent,\n )\n await new Promise<void>((resolve) => {\n setTimeout(() => resolve(), waitTime)\n })\n return this.fetch({\n ...options,\n attempt: attempt + 1,\n retryAttempt: retryAttempt + 1,\n attemptHostIndex: nextAttemptHostIndex,\n })\n }\n\n if (error instanceof Error) {\n throw error\n }\n const wrapped = new Error(\n (error as { message?: string })?.message || String(error),\n )\n Object.assign(wrapped, error)\n throw wrapped\n }\n\n try {\n const response = await fetch(url as unknown as string, fetchInit as RequestInit)\n clearTimeout(timeoutId)\n\n if (response.status === 301 || response.status === 302) {\n return retryOrRedirect(response.status, response.headers, undefined, new Error(\n `Redirect ${response.status}`,\n ))\n }\n\n // Match axios: non-2xx responses reject (after retry logic when applicable)\n if (response.status >= 400) {\n return retryOrRedirect(\n response.status,\n response.headers,\n undefined,\n Object.assign(new Error(`HTTP ${response.status}`), {\n response: {\n status: response.status,\n headers: Object.fromEntries(response.headers.entries()),\n },\n }),\n )\n }\n\n if (stream) {\n if (!response.body) {\n return Readable.from([])\n }\n return Readable.fromWeb(response.body as import('stream/web').ReadableStream)\n }\n\n const contentType = response.headers.get('content-type') || ''\n let responseBody: unknown\n if (contentType.includes('application/json')) {\n responseBody = await response.json()\n } else {\n responseBody = await response.text()\n }\n\n return {\n body: responseBody,\n status: response.status,\n }\n } catch (e) {\n clearTimeout(timeoutId)\n const errorCode = getErrorCode(e)\n const err = e as { response?: { status?: number, headers?: Record<string, string> } }\n const responseStatus = err.response?.status\n const responseHeaders = err.response?.headers\n return retryOrRedirect(responseStatus, responseHeaders, errorCode, e)\n }\n }\n\n // Rest args keep subclass ApiClient get(path, sql, options) compatible (v2 JS shape)\n async get (...args: any[]): Promise<HttpResponse | Readable> {\n const options = (args[0] || {}) as HttpRequestOptions\n return this.fetch({ ...options, httpMethod: HTTP_METHOD_GET })\n }\n\n async post (...args: any[]): Promise<HttpResponse | Readable> {\n const options = (args[0] || {}) as HttpRequestOptions\n return this.fetch({ ...options, httpMethod: HTTP_METHOD_POST })\n }\n}\n","/**\n * RQLite HTTP query parameter name constants\n * @module api/query-params\n * @see https://rqlite.io/docs/api/api/\n * @see https://rqlite.io/docs/api/read-consistency/\n * @see https://rqlite.io/docs/guides/backup/\n */\n\nexport const QUERY_PARAM_LEVEL = 'level'\nexport const QUERY_PARAM_PRETTY = 'pretty'\nexport const QUERY_PARAM_TIMINGS = 'timings'\nexport const QUERY_PARAM_ATOMIC = 'atomic'\nexport const QUERY_PARAM_TRANSACTION = 'transaction'\nexport const QUERY_PARAM_Q = 'q'\nexport const QUERY_PARAM_FMT = 'fmt'\n","/**\n * Base API client for RQLite which abstracts the HTTP calls\n * @module api/client\n * @see https://rqlite.io/docs/api/api/\n */\nimport HttpRequest from '../../http-request/index.js'\nimport type { HttpRequestOptions, HttpResponse } from '../../http-request/index.js'\nimport { HTTP_METHOD_GET, HTTP_METHOD_POST } from '../../http-request/http-methods.js'\nimport {\n QUERY_PARAM_ATOMIC,\n QUERY_PARAM_LEVEL,\n QUERY_PARAM_PRETTY,\n QUERY_PARAM_Q,\n QUERY_PARAM_TIMINGS,\n QUERY_PARAM_TRANSACTION,\n} from '../query-params.js'\n\nexport type ApiClientRequestOptions = {\n useLeader?: boolean\n level?: string\n pretty?: boolean\n timings?: boolean\n atomic?: boolean\n transaction?: boolean\n raw?: boolean\n}\n\n/**\n * Create the base HTTP query options from RQLite API options\n * @see https://rqlite.io/docs/api/api/\n * @see module:api/query-params\n */\nexport function createQuery (options: ApiClientRequestOptions = {}): Record<string, unknown> {\n const { level, pretty, timings, atomic, transaction } = options\n\n const query: Record<string, unknown> = {\n [QUERY_PARAM_LEVEL]: level,\n [QUERY_PARAM_PRETTY]: pretty,\n [QUERY_PARAM_TIMINGS]: timings,\n [QUERY_PARAM_ATOMIC]: atomic,\n [QUERY_PARAM_TRANSACTION]: transaction,\n }\n return Object.entries(query).reduce<Record<string, unknown>>((acc, entry) => {\n const [key, val] = entry\n if (typeof val !== 'undefined') {\n acc[key] = val\n }\n return acc\n }, {})\n}\n\n/**\n * Base API client for RQLite which abstracts the HTTP calls from the user\n */\nexport default class ApiClient extends HttpRequest {\n /**\n * Perform a RQLite data API get request\n * @see https://rqlite.io/docs/api/api/\n */\n async get (...args: any[]): Promise<HttpResponse> {\n const path = args[0] as string\n const sql = args[1] as string\n const options = (args[2] || {}) as ApiClientRequestOptions\n const { useLeader } = options\n if (!path) {\n throw new Error('The path argument is required')\n }\n return super.get({\n useLeader,\n uri: path,\n httpMethod: HTTP_METHOD_GET,\n query: { ...createQuery(options), [QUERY_PARAM_Q]: sql },\n } as HttpRequestOptions) as Promise<HttpResponse>\n }\n\n /**\n * Perform a RQLite data API post request\n * @see https://rqlite.io/docs/api/api/\n */\n async post (...args: any[]): Promise<HttpResponse> {\n const path = args[0] as string\n const sql = args[1] as string | string[]\n const options = (args[2] || {}) as ApiClientRequestOptions\n const { useLeader } = options\n if (!path) {\n throw new Error('The path argument is required')\n }\n return super.post({\n useLeader,\n uri: path,\n httpMethod: HTTP_METHOD_POST,\n query: createQuery(options),\n body: Array.isArray(sql) ? sql : [sql],\n } as HttpRequestOptions) as Promise<HttpResponse>\n }\n}\n\n","/**\n * RQLite JSON response field name constants\n * @module api/results/result-fields\n * @see https://rqlite.io/docs/api/api/\n */\n\nexport const RESULT_FIELD_TIME = 'time'\nexport const RESULT_FIELD_ROWS_AFFECTED = 'rows_affected'\nexport const RESULT_FIELD_LAST_INSERT_ID = 'last_insert_id'\nexport const RESULT_FIELD_COLUMNS = 'columns'\nexport const RESULT_FIELD_VALUES = 'values'\nexport const RESULT_FIELD_ERROR = 'error'\nexport const RESULT_FIELD_ERROR_V2 = 'error_v2'\nexport const RESULT_FIELD_RESULTS = 'results'\n","/**\n * Class for handling single RQLite data api result\n * @module api/results/data-result\n * @see https://rqlite.io/docs/api/api/\n * @see module:api/results/result-fields\n */\nimport {\n RESULT_FIELD_COLUMNS,\n RESULT_FIELD_LAST_INSERT_ID,\n RESULT_FIELD_ROWS_AFFECTED,\n RESULT_FIELD_TIME,\n RESULT_FIELD_VALUES,\n} from './result-fields.js'\n\nexport type RqliteSingleResult = {\n [RESULT_FIELD_TIME]?: number | string\n [RESULT_FIELD_ROWS_AFFECTED]?: number | string\n [RESULT_FIELD_LAST_INSERT_ID]?: number\n [RESULT_FIELD_COLUMNS]?: string[]\n [RESULT_FIELD_VALUES]?: unknown[][]\n [key: string]: unknown\n}\n\n/**\n * A class that represents one data result from an RQLite query or execute API call\n * @see https://rqlite.io/docs/api/api/\n */\nexport default class DataResult {\n time = 0.0\n\n lastInsertId?: number\n\n rowsAffected = 0\n\n data: Record<string, unknown> = {}\n\n constructor (result: RqliteSingleResult, valuesIndex?: number) {\n if (typeof result !== 'object' || result === null) {\n throw new Error('The result argument is required to be an object')\n }\n if (typeof valuesIndex !== 'undefined' && !Number.isFinite(valuesIndex)) {\n throw new Error('The valuesIndex argument is required to be a finite number when provided')\n }\n this.time = parseFloat(String(result[RESULT_FIELD_TIME] || 0.0))\n this.rowsAffected = parseInt(String(result[RESULT_FIELD_ROWS_AFFECTED] || 0), 10)\n this.lastInsertId = result[RESULT_FIELD_LAST_INSERT_ID] as number | undefined\n if (Number.isFinite(valuesIndex)) {\n const columns = result[RESULT_FIELD_COLUMNS] as string[]\n const resultValues = (result[RESULT_FIELD_VALUES] as unknown[][])[valuesIndex as number]\n if (resultValues) {\n this.data = resultValues.reduce<Record<string, unknown>>((acc, val, i) => {\n const col = columns[i]\n acc[col] = val\n return acc\n }, {})\n }\n }\n }\n\n get (property: string): unknown {\n return this.data[property]\n }\n\n getTime (): number {\n return this.time\n }\n\n getLastInsertId (): number | undefined {\n return this.lastInsertId\n }\n\n getRowsAffected (): number {\n return this.rowsAffected\n }\n\n toObject (): Record<string, unknown> {\n return JSON.parse(JSON.stringify(this.data)) as Record<string, unknown>\n }\n\n toArray (): unknown[] {\n return Object.values(this.data)\n }\n\n toColumnsArray (): string[] {\n return Object.keys(this.data)\n }\n\n toString (): string {\n return JSON.stringify(this.data)\n }\n}\n","/**\n * Class for handling RQLite data api result error\n * @module api/results/data-result-error\n * @see https://rqlite.io/docs/api/api/\n */\nimport { RESULT_FIELD_ERROR, RESULT_FIELD_ERROR_V2 } from './result-fields.js'\n\n/**\n * A class that represents one data error result from an RQLite query or execute API call\n * @see https://rqlite.io/docs/api/api/\n */\nexport default class DataResultError extends Error {\n code: string\n\n errorV2?: Record<string, unknown>\n\n constructor (message: string, errorV2?: Record<string, unknown>) {\n super(message)\n this.name = this.constructor.name\n this.code = this.constructor.name\n if (errorV2) {\n this.errorV2 = errorV2\n }\n }\n\n getErrorV2 (): Record<string, unknown> | undefined {\n return this.errorV2\n }\n\n toObject (): Record<string, unknown> {\n const obj: Record<string, unknown> = { [RESULT_FIELD_ERROR]: this.message }\n if (this.errorV2) {\n obj[RESULT_FIELD_ERROR_V2] = this.errorV2\n }\n return obj\n }\n\n toString (): string {\n return JSON.stringify(this.toObject())\n }\n}\n","/**\n * Class for handling many RQLite data api results\n * @module api/results/data-results\n * @see https://rqlite.io/docs/api/api/\n * @see module:api/results/result-fields\n */\nimport DataResult from './data-result.js'\nimport type { RqliteSingleResult } from './data-result.js'\nimport DataResultError from './data-result-error.js'\nimport {\n RESULT_FIELD_ERROR,\n RESULT_FIELD_ERROR_V2,\n RESULT_FIELD_RESULTS,\n RESULT_FIELD_TIME,\n RESULT_FIELD_VALUES,\n} from './result-fields.js'\n\nexport type RqliteApiData = {\n [RESULT_FIELD_TIME]?: number | string\n [RESULT_FIELD_RESULTS]: RqliteSingleResult[]\n}\n\n/**\n * A class to manage a list of results from an RQLite query or execute API response\n * @see https://rqlite.io/docs/api/api/\n */\nexport default class DataResults {\n time = 0.0\n\n results: Array<DataResult | DataResultError> = []\n\n constructor (data: RqliteApiData) {\n this.setApiData(data)\n }\n\n setApiData (data: RqliteApiData): void {\n if (typeof data !== 'object' || data === null) {\n throw new Error('The data argument is required to be an object')\n }\n if (!data[RESULT_FIELD_RESULTS]) {\n throw new Error('The data object is required to have a results property')\n }\n this.time = parseFloat(String(data[RESULT_FIELD_TIME] || 0.0))\n const results = data[RESULT_FIELD_RESULTS] || []\n this.results = results.reduce<Array<DataResult | DataResultError>>((acc, result) => {\n if (typeof result === 'object' && result !== null && result[RESULT_FIELD_ERROR]) {\n return acc.concat(\n new DataResultError(\n String(result[RESULT_FIELD_ERROR]),\n result[RESULT_FIELD_ERROR_V2] as Record<string, unknown> | undefined,\n ),\n )\n }\n const vals = result[RESULT_FIELD_VALUES]\n if (!vals) {\n return acc.concat(new DataResult(result))\n }\n const dataResults = vals.map((_v, valuesIndex) => new DataResult(result, valuesIndex))\n return acc.concat(dataResults)\n }, [])\n }\n\n hasError (): boolean {\n return !!this.getFirstError()\n }\n\n getFirstError (): DataResultError | undefined {\n return this.results.find((v) => v instanceof DataResultError) as DataResultError | undefined\n }\n\n getTime (): number {\n return this.time\n }\n\n get (index: number): DataResult | DataResultError | undefined {\n return this.results[index]\n }\n\n getResults (): Array<DataResult | DataResultError> {\n return this.results\n }\n\n toArray (): Record<string, unknown>[] {\n return this.results.map((result) => result.toObject())\n }\n\n toString (): string {\n const list = this.results.map((result) => result.toObject())\n return JSON.stringify(list)\n }\n}\n","/**\n * RQLite HTTP API path constants\n * @module api/paths\n * @see https://rqlite.io/docs/api/api/\n * @see https://rqlite.io/docs/guides/backup/\n * @see https://rqlite.io/docs/guides/monitoring-rqlite/\n */\n\nexport const PATH_QUERY = '/db/query'\nexport const PATH_EXECUTE = '/db/execute'\nexport const PATH_LOAD = '/db/load'\nexport const PATH_BACKUP = '/db/backup'\nexport const PATH_STATUS = '/status'\n","/**\n * RQLite read consistency level constants\n * @module api/consistency-levels\n * @see https://rqlite.io/docs/api/read-consistency/\n */\n\nexport const CONSISTENCY_LEVEL_NONE = 'none'\nexport const CONSISTENCY_LEVEL_STRONG = 'strong'\nexport const CONSISTENCY_LEVEL_LINEARIZABLE = 'linearizable'\nexport const CONSISTENCY_LEVEL_WEAK = 'weak'\n","/**\n * Data api client to perform RQLite data operations such as query and execute\n * @module api/data\n * @see https://rqlite.io/docs/api/api/\n * @see https://rqlite.io/docs/api/read-consistency/\n */\nimport ApiClient from '../client/index.js'\nimport type { ApiClientRequestOptions } from '../client/index.js'\nimport type { HttpResponse } from '../../http-request/index.js'\nimport { DataResults } from '../results/index.js'\nimport type { RqliteApiData } from '../results/data-results.js'\nimport { PATH_EXECUTE, PATH_QUERY } from '../paths.js'\nimport { CONSISTENCY_LEVEL_NONE } from '../consistency-levels.js'\n\nexport {\n PATH_QUERY,\n PATH_EXECUTE,\n} from '../paths.js'\n\nexport {\n CONSISTENCY_LEVEL_NONE,\n CONSISTENCY_LEVEL_STRONG,\n CONSISTENCY_LEVEL_LINEARIZABLE,\n CONSISTENCY_LEVEL_WEAK,\n} from '../consistency-levels.js'\n\nexport type DataRequestBaseOptions = {\n raw?: boolean\n}\n\nexport type QueryRequestOptions = ApiClientRequestOptions & DataRequestBaseOptions\nexport type ExecuteRequestOptions = ApiClientRequestOptions & DataRequestBaseOptions\n\nfunction handleResponse (\n response: HttpResponse,\n options: DataRequestBaseOptions = {},\n): DataResults | HttpResponse {\n const { raw } = options\n const { body } = response\n if (raw) {\n return response\n }\n return new DataResults(body as RqliteApiData)\n}\n\n/**\n * Data api client to perform RQLite queries\n */\nexport default class DataApiClient extends ApiClient {\n /**\n * Send an RQLite query API request to the RQLite server\n * @see https://rqlite.io/docs/api/api/\n * @see https://rqlite.io/docs/api/read-consistency/\n */\n async query (\n sql: string | string[],\n options: QueryRequestOptions = {},\n ): Promise<DataResults | HttpResponse> {\n const { level } = options\n let { useLeader } = options\n if (level !== CONSISTENCY_LEVEL_NONE) {\n useLeader = true\n }\n let response: HttpResponse\n if (Array.isArray(sql)) {\n response = await super.post(PATH_QUERY, sql, { ...options, useLeader })\n } else {\n response = await super.get(PATH_QUERY, sql, { ...options, useLeader })\n }\n if (!useLeader) {\n this.setNextActiveHostIndex()\n }\n return handleResponse(response, options)\n }\n\n /**\n * Send an RQLite execute API request to the RQLite server\n * @see https://rqlite.io/docs/api/api/\n */\n async execute (\n sql: string | string[],\n options: ExecuteRequestOptions = {},\n ): Promise<DataResults | HttpResponse> {\n const response = await super.post(PATH_EXECUTE, sql, options)\n return handleResponse(response, options)\n }\n}\n","/**\n * RQLite backup data format constants\n * @module api/backup-formats\n * @see https://rqlite.io/docs/guides/backup/\n */\n\nexport const BACKUP_DATA_FORMAT_SQL = 'sql'\nexport const BACKUP_DATA_FORMAT_DUMP = 'dump'\n","/**\n * Backup api client to perform RQLite backup and load operations\n * @module api/backup\n * @see https://rqlite.io/docs/guides/backup/\n */\nimport type { Readable } from 'node:stream'\nimport HttpRequest from '../../http-request/index.js'\nimport {\n CONTENT_TYPE_APPLICATION_OCTET_STREAM,\n CONTENT_TYPE_TEXT_PLAIN,\n} from '../../http-request/content-types.js'\nimport {\n HTTP_HEADER_ACCEPT,\n HTTP_HEADER_CONTENT_TYPE,\n} from '../../http-request/http-headers.js'\nimport { PATH_BACKUP, PATH_LOAD } from '../paths.js'\nimport { BACKUP_DATA_FORMAT_DUMP, BACKUP_DATA_FORMAT_SQL } from '../backup-formats.js'\nimport { QUERY_PARAM_FMT } from '../query-params.js'\n\nexport { PATH_LOAD, PATH_BACKUP } from '../paths.js'\nexport { BACKUP_DATA_FORMAT_SQL, BACKUP_DATA_FORMAT_DUMP } from '../backup-formats.js'\n\n/**\n * Backup api client to perform RQLite back up and load operations\n */\nexport default class BackupApiClient extends HttpRequest {\n /**\n * Perform a SQL dump backup from the RQLite server\n * @see https://rqlite.io/docs/guides/backup/\n * @see module:api/backup-formats\n */\n async backup (format: string = BACKUP_DATA_FORMAT_DUMP): Promise<Readable> {\n return super.get({\n headers: {\n [HTTP_HEADER_ACCEPT]: CONTENT_TYPE_APPLICATION_OCTET_STREAM,\n },\n query: {\n [QUERY_PARAM_FMT]: format === BACKUP_DATA_FORMAT_SQL ? format : undefined,\n },\n json: false,\n stream: true,\n uri: PATH_BACKUP,\n useLeader: true,\n }) as Promise<Readable>\n }\n\n /**\n * Perform a SQL restore by sending data the RQLite server\n * @see https://rqlite.io/docs/guides/backup/\n * @see module:api/backup-formats\n */\n async load (\n data: Buffer | string,\n format: string = BACKUP_DATA_FORMAT_SQL,\n ): Promise<Readable> {\n return super.post({\n body: data,\n headers: {\n [HTTP_HEADER_CONTENT_TYPE]: format === BACKUP_DATA_FORMAT_SQL\n ? CONTENT_TYPE_TEXT_PLAIN\n : CONTENT_TYPE_APPLICATION_OCTET_STREAM,\n },\n json: false,\n stream: true,\n uri: PATH_LOAD,\n useLeader: true,\n }) as Promise<Readable>\n }\n}\n","/**\n * Status api client to perform RQLite status and diagnostics operations\n * @module api/status\n * @see https://rqlite.io/docs/guides/monitoring-rqlite/\n */\nimport ApiClient from '../client/index.js'\nimport type { HttpResponse } from '../../http-request/index.js'\nimport { HTTP_METHOD_GET } from '../../http-request/http-methods.js'\nimport { PATH_STATUS } from '../paths.js'\n\nexport { PATH_STATUS } from '../paths.js'\n\nexport type StatusRequestOptions = {\n raw?: boolean\n attemptHostIndex?: number\n useLeader?: boolean\n}\n\nexport type StatusAllHostsResponse = {\n response: HttpResponse\n host: string\n}\n\n/**\n * Data api client to perform RQLite status queries\n */\nexport default class StatusApiClient extends ApiClient {\n /**\n * Get the RQLite server status which defaults to the leader host\n * @see https://rqlite.io/docs/guides/monitoring-rqlite/\n */\n async status (options: StatusRequestOptions = {}): Promise<HttpResponse> {\n return this.fetch({\n ...options,\n uri: PATH_STATUS,\n httpMethod: HTTP_METHOD_GET,\n useLeader: typeof options.useLeader === 'boolean' ? options.useLeader : true,\n }) as Promise<HttpResponse>\n }\n\n /**\n * Get the RQLite server status for all hosts\n * @see https://rqlite.io/docs/guides/monitoring-rqlite/\n */\n async statusAllHosts (options: StatusRequestOptions = {}): Promise<StatusAllHostsResponse[]> {\n const hosts = this.getHosts()\n const promises = hosts.map(async (_host, attemptHostIndex) => {\n const response = await this.status({ ...options, useLeader: false, attemptHostIndex })\n return { response, host: hosts[attemptHostIndex] }\n })\n return Promise.all(promises)\n }\n}\n","/**\n * RQLite JS client which export all of the api clients\n * @module rqlite-js\n * @see https://rqlite.io/docs/api/api/\n */\nimport DataApiClient from './api/data/index.js'\nimport BackupApiClient from './api/backup/index.js'\nimport StatusApiClient from './api/status/index.js'\n\nexport {\n DataApiClient,\n BackupApiClient,\n StatusApiClient,\n}\n\nexport {\n PATH_QUERY,\n PATH_EXECUTE,\n CONSISTENCY_LEVEL_NONE,\n CONSISTENCY_LEVEL_STRONG,\n CONSISTENCY_LEVEL_LINEARIZABLE,\n CONSISTENCY_LEVEL_WEAK,\n} from './api/data/index.js'\n\nexport {\n PATH_BACKUP,\n PATH_LOAD,\n BACKUP_DATA_FORMAT_SQL,\n BACKUP_DATA_FORMAT_DUMP,\n} from './api/backup/index.js'\n\nexport { PATH_STATUS } from './api/status/index.js'\n\nexport default {\n DataApiClient,\n BackupApiClient,\n StatusApiClient,\n}\n"],"mappings":";;;;;;;AAKA,MAAa,qBAAqB;AAClC,MAAa,kBAAkB;AAC/B,MAAa,mBAAmB;AAChC,MAAa,sBAAsB;AACnC,MAAa,oBAAoB;AACjC,MAAa,mBAAmB;AAChC,MAAa,kBAAkB;;;;ACX/B,MAAa,0BAA0B;AACvC,MAAa,gCAAgC;AAE7C,MAAa,wCAAwC;;;;;;;;;;;ACKrD,IAAa,mCAAb,cAAsD,MAAM;CAC1D;CAEA,YAAa,GAAG,MAA2C;AACzD,QAAM,GAAG,KAAK;AACd,OAAK,OAAO,KAAK,YAAY;AAC7B,OAAK,OAAO,KAAK,YAAY;;;;;;;;;ACDjC,MAAa,wBAAwB,IAAI,IAAI;CAC3C;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD,CAAC;;;;AAKF,MAAa,yBAAyB,IAAI,IAAI;CAAC;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAI,CAAC;;;;AAKjG,MAAa,yBAAyB,IAAI,IAAI;CAC5C;CACA;CACA;CACA;CACA;CACA;CACA;CACD,CAAC;;;;;;;;;;;AChCF,MAAa,gBAAgB;;;;AAK7B,MAAa,gBAAgB;;;;;;;;;;;ACL7B,MAAa,qBAAqB;;;;AAKlC,MAAa,2BAA2B;;;;AAKxC,MAAa,uBAAuB;;;;;;;ACiEpC,MAAa,iBAAiB;;;;AAU9B,SAAgB,qBAAsB,UAAkC,EAAE,EAA0B;CAClG,MAAM,SAAS,QAAQ,uBAAuB;AAC9C,QAAO;EAAE,GAAG;GAAU,qBAAqB;EAAQ;;;;;AAMrD,SAAS,UAAW,MAAsB;AACxC,QAAO,OAAO,KAAK,CAAC,QAAQ,OAAO,GAAG;;;;;AAMxC,SAAgB,eAAgB,SAAkC,EAAE,EAAU;CAC5E,MAAM,SAAS,IAAI,iBAAiB;AACpC,QAAO,QAAQ,OAAO,CAAC,SAAS,CAAC,KAAK,WAAW;AAC/C,MAAI,OAAO,UAAU,YACnB;AAEF,MAAI,MAAM,QAAQ,MAAM,EAAE;AACxB,SAAM,SAAS,UAAU;AACvB,WAAO,OAAO,GAAG,IAAI,KAAK,OAAO,MAAM,CAAC;KACxC;AACF;;AAEF,SAAO,OAAO,KAAK,OAAO,MAAM,CAAC;GACjC;AACF,QAAO,OAAO,UAAU;;AAG1B,SAAS,gBAAiB,UAAkB,UAA0B;AAEpE,QAAO,SADO,OAAO,KAAK,GAAG,SAAS,GAAG,WAAW,CAAC,SAAS,SAAS;;AAIzE,SAAS,aAAc,OAAoC;AACzD,KAAI,CAAC,SAAS,OAAO,UAAU,SAC7B;CAEF,MAAM,MAAM;AACZ,KAAI,OAAO,IAAI,SAAS,SACtB,QAAO,IAAI;AAEb,KAAI,IAAI,SAAS,OAAO,IAAI,MAAM,SAAS,SACzC,QAAO,IAAI,MAAM;AAEnB,KAAI,IAAI,SAAS,gBAAgB,IAAI,SAAS,eAC5C,QAAO;;;;;;AASX,SAAgB,uBAAwB,UAAU,GAAG,OAAO,KAAK,WAAW,GAAW;AACrF,KAAI,YAAY,EACd,QAAO;AAET,QAAQ,YAAY,UAAW;;;;;AAMjC,IAAqB,cAArB,MAAiC;CAC/B,kBAAkB;CAElB,uBAAuB;CAEvB,qBAAqB;CAErB,QAAkB,EAAE;CAEpB;CAEA;CAEA,kBAAkB;CAElB,sBAAmC;CAEnC,uBAAoC;CAEpC,uBAAoC;CAEpC,yBAAyB;CAEzB,6BAA6B;CAE7B,iCAAiB,IAAI,KAAqB;CAE1C,YAAa,OAA0B,UAAyC,EAAE,EAAE;AAClF,OAAK,SAAS,MAAM;AACpB,MAAI,KAAK,eAAe,KAAK,EAC3B,OAAM,IAAI,MAAM,qCAAqC;EAEvD,MAAM,EACJ,uBAAuB,MACvB,WACA,YACA,qBACA,sBACA,sBACA,4BACA,wBACA,mBACE;AACJ,MAAI,OAAO,mBAAmB,UAAU;GACtC,MAAM,EAAE,UAAU,aAAa;AAC/B,OAAI,SACF,MAAK,eAAe,IAAI,eAAe,SAAS;AAElD,OAAI,SACF,MAAK,eAAe,IAAI,eAAe,SAAS;;AAGpD,MAAI,OAAO,yBAAyB,YAClC,MAAK,wBAAwB,qBAAqB;AAEpD,MAAI,OAAO,cAAc,YACvB,MAAK,aAAa,UAAU;AAE9B,MAAI,OAAO,eAAe,YACxB,MAAK,cAAc,WAAW;AAEhC,MAAI,+BAA+B,OAAO,MAAM,QAAQ,oBAAoB,CAC1E,MAAK,uBACH,MAAM,QAAQ,oBAAoB,GAAG,IAAI,IAAI,oBAAoB,GAAG,oBACrE;AAEH,MAAI,gCAAgC,OAAO,MAAM,QAAQ,qBAAqB,CAC5E,MAAK,wBACH,MAAM,QAAQ,qBAAqB,GAAG,IAAI,IAAI,qBAAqB,GAAG,qBACvE;AAEH,MAAI,gCAAgC,OAAO,MAAM,QAAQ,qBAAqB,CAC5E,MAAK,wBACH,MAAM,QAAQ,qBAAqB,GAAG,IAAI,IAAI,qBAAqB,GAAG,qBACvE;AAEH,MAAI,OAAO,SAAS,uBAAuB,CACzC,MAAK,0BAA0B,uBAAiC;AAElE,MAAI,OAAO,SAAS,2BAA2B,CAC7C,MAAK,8BAA8B,2BAAqC;;CAI5E,kBAAmB,iBAAqC,EAAE,EAAQ;EAChE,MAAM,EAAE,UAAU,aAAa;AAC/B,MAAI,SACF,MAAK,eAAe,IAAI,eAAe,SAAS;AAElD,MAAI,SACF,MAAK,eAAe,IAAI,eAAe,SAAS;;CAIpD,0BAA2B,wBAAsC;AAC/D,OAAK,yBAAyB;;CAGhC,4BAAqC;AACnC,SAAO,KAAK;;CAGd,8BAA+B,4BAA0C;AACvE,OAAK,6BAA6B;;CAGpC,gCAAyC;AACvC,SAAO,KAAK;;CAGd,uBAAwB,qBAAwC;AAC9D,OAAK,sBAAsB;;CAG7B,yBAAuC;AACrC,SAAO,KAAK;;CAGd,wBAAyB,sBAAyC;AAChE,OAAK,uBAAuB;;CAG9B,0BAAwC;AACtC,SAAO,KAAK;;CAGd,wBAAyB,sBAAyC;AAChE,OAAK,uBAAuB;;CAG9B,0BAAwC;AACtC,SAAO,KAAK;;CAGd,aAAc,WAA6C;AACzD,OAAK,YAAY;;CAGnB,eAAwD;AACtD,SAAO,KAAK;;CAGd,cAAe,YAA+C;AAC5D,OAAK,aAAa;;CAGpB,gBAA0D;AACxD,SAAO,KAAK;;CAGd,SAAU,OAAgC;AAExC,OAAK,SADQ,CAAC,MAAM,QAAQ,MAAM,GAAG,OAAO,MAAM,CAAC,MAAM,IAAI,GAAG,OAC9C,QAAkB,KAAK,MAAM;GAC7C,MAAM,OAAO,OAAO,EAAE,CAAC,MAAM,CAAC,QAAQ,OAAO,GAAG;AAChD,OAAI,CAAC,KACH,QAAO;AAET,UAAO,IAAI,OAAO,KAAK;KACtB,EAAE,CAAC;;CAGR,WAAsB;AACpB,SAAO,KAAK;;CAGd,cAAe,MAAsB;EACnC,IAAIA;AACJ,MAAI;AACF,sBAAmB,IAAI,IAAI,KAAK;UAC1B;AACN,UAAO;;AAET,SAAO,KAAK,UAAU,CAAC,WAAW,MAAM;AACtC,OAAI;IACF,MAAM,aAAa,IAAI,IAAI,EAAE;AAC7B,WAAQ;KAAC;KAAY;KAAY;KAAQ;KAAW,CAAW,OAC5D,UAAU,iBAAiB,WAAW,WAAW,OACnD;WACK;AACN,WAAO;;IAET;;CAGJ,cAAe,WAA6B;EAC1C,MAAM,kBAAkB,YAAY,KAAK,oBAAoB,GAAG,KAAK,oBAAoB;AACzF,SAAO,KAAK,UAAU,CAAC;;CAGzB,mBAAoB,iBAAiC;AACnD,MAAI,CAAC,OAAO,SAAS,gBAAgB,CACnC,OAAM,IAAI,MAAM,gDAAgD;EAElE,MAAM,aAAa,KAAK,eAAe;AACvC,MAAI,kBAAkB,EACpB,MAAK,kBAAkB;WACd,mBAAmB,WAC5B,MAAK,kBAAkB,aAAa;MAEpC,MAAK,kBAAkB;AAEzB,SAAO,KAAK;;CAGd,qBAA8B;AAC5B,SAAO,KAAK;;CAGd,mBAAoB,iBAAiC;AACnD,MAAI,CAAC,OAAO,SAAS,gBAAgB,CACnC,OAAM,IAAI,MAAM,gDAAgD;EAElE,MAAM,aAAa,KAAK,eAAe;AACvC,MAAI,kBAAkB,EACpB,MAAK,kBAAkB;WACd,kBAAkB,WAC3B,MAAK,kBAAkB,aAAa;MAEpC,MAAK,kBAAkB;AAEzB,SAAO,KAAK;;CAGd,qBAA8B;AAC5B,SAAO,KAAK;;CAGd,wBAAyB,sBAAqC;AAC5D,MAAI,OAAO,yBAAyB,UAClC,OAAM,IAAI,MAAM,oDAAoD;AAEtE,OAAK,uBAAuB;;CAG9B,0BAAoC;AAClC,SAAO,KAAK;;CAGd,uBAAwB,kBAAkB,KAAK,oBAAoB,EAAU;EAC3E,MAAM,aAAa,KAAK,eAAe;EACvC,MAAM,YAAY,kBAAkB;AACpC,MAAI,eAAe,UACjB,QAAO;AAET,SAAO;;CAGT,yBAAgC;AAC9B,MAAI,CAAC,KAAK,yBAAyB,CACjC;EAEF,MAAM,aAAa,KAAK,eAAe;AACvC,MAAI,KAAK,yBAAyB,IAAI,cAAc,EAClD;AAEF,OAAK,mBAAmB,KAAK,wBAAwB,CAAC;;CAGxD,gBAAyB;AACvB,SAAO,KAAK,UAAU,CAAC;;CAGzB,cAAe,KAAsB;AACnC,SAAO,KAAK,mBAAmB,KAAK,IAAI;;CAG1C,mBAAoB,UAIhB,EAAE,EAAW;EACf,MAAM,EACJ,YACA,WACA,eACE;AACJ,MAAI,CAAC,cAAc,CAAC,KAAK,yBAAyB,CAAC,IAAI,WAAW,CAChE,QAAO;AAET,MAAI,cAAc,KAAK,yBAAyB,CAAC,IAAI,WAAW,CAC9D,QAAO;AAET,MAAI,aAAa,KAAK,wBAAwB,CAAC,IAAI,UAAU,CAC3D,QAAO;AAET,SAAO;;;;;CAMT,MAAM,MAAO,UAA8B,EAAE,EAAoC;EAC/E,MAAM,EACJ,MACA,UAAU,EAAE,EACZ,aAAa,iBACb,OACA,SAAS,OACT,UAAU,gBACV,YAAY,OACZ,UAAU,KAAK,eAAe,GAAG,GACjC,eAAe,IACf,UAAU,GACV,eAAe,GACf,kBAAkB,GAClB,kBACA,6BAA6B,KAAK,+BAA+B,EACjE,yBAAyB,KAAK,2BAA2B,EACzD,YAAY,KAAK,cAAc,EAC/B,aAAa,KAAK,eAAe,KAC/B;EAEJ,MAAM,aAAa,OAAO,SAAS,iBAAiB,GAChD,KAAK,UAAU,CAAC,oBAChB,KAAK,cAAc,UAAU;EAEjC,IAAI,EAAE,QAAQ;AACd,MAAI,CAAC,IACH,OAAM,IAAI,MAAM,6BAA6B;AAE/C,QAAM,KAAK,cAAc,IAAI,GAAG,MAAM,GAAG,WAAW,GAAG,UAAU,IAAI;EAErE,MAAM,iBAAiB,qBAAqB,QAAQ;AACpD,MAAI,KAAK,eAAe,KAGtB,gBAAe,gBAAgB,gBAFd,KAAK,eAAe,IAAI,cAAc,IAAI,IAC1C,KAAK,eAAe,IAAI,cAAc,IAAI,GACO;EAGpE,MAAM,MAAM,IAAI,IAAI,IAAI;AACxB,MAAI,SAAS,OAAO,UAAU,UAAU;GACtC,MAAM,aAAa,eAAe,MAAiC;AACnE,OAAI,WACF,KAAI,SAAS;;EAIjB,MAAM,aAAa,IAAI,iBAAiB;EACxC,MAAM,YAAY,iBAAiB,WAAW,OAAO,EAAE,QAAQ;EAE/D,MAAMC,YAAoD;GACxD,QAAQ;GACR,SAAS;GACT,UAAU;GACV,QAAQ,WAAW;GACpB;EAID,MAAM,QAAQ,IAAI,aAAa,WAAW,aAAa;AACvD,MAAI,SAAS,OAAQ,MAAyB,aAAa,YAAY;GAErE,MAAM,OAAO;AACb,QAAK,aAAa;;AAGpB,MAAI,OAAO,SAAS,eAAe,SAAS,KAC1C,KAAI,OAAO,SAAS,KAAK,IAAI,OAAO,SAAS,SAC3C,WAAU,OAAO;OACZ;AACL,aAAU,OAAO,KAAK,UAAU,KAAK;AACrC,OAAI,CAAC,eAAe,oBAClB,gBAAe,sBAAsB;AAEvC,OAAI,EAAE,4BAA4B,mBAC7B,CAAC,OAAO,KAAK,eAAe,CAAC,MAAM,MAAM,EAAE,aAAa,KAAK,eAAe,CAC/E,gBAAe,4BAA4B;AAE7C,aAAU,UAAU;;EAIxB,MAAM,kBAAkB,OACtB,gBACA,iBACA,WACA,UACqC;GACrC,MAAM,YAAY,KAAK,mBAAmB;IACxC,YAAY;IACZ;IACA;IACD,CAAC;GAEF,IAAI,uBAAuB,OAAO,SAAS,iBAAiB,GACvD,mBACD,KAAK,oBAAoB;AAC7B,2BAAwB;AACxB,OAAI,yBAAyB,KAAK,eAAe,CAC/C,wBAAuB;AAGzB,OAAI,mBAAmB,OAAO,mBAAmB,KAAK;AACpD,QAAI,mBAAmB,aACrB,OAAM,IAAI,iCACR,mCAAmC,aAAa,mBACjD;IAEH,IAAIC;AACJ,QAAI,mBAAmB,OAAQ,gBAA4B,QAAQ,WACjE,YAAY,gBAA4B,IAAI,qBAAqB,IAC3D,gBAA4B,IAAI,qBAAqB,aAAa,CAAC,IACpE;aACI,mBAAmB,OAAO,oBAAoB,UAAU;KACjE,MAAM,YAAY;AAClB,gBAAW,UAAU,qBAAqB,aAAa,KAClD,UAAU;;AAEjB,QAAI,aAAa,UAAU;KACzB,MAAM,qBAAqB,KAAK,cAAc,SAAS;AACvD,SAAI,qBAAqB,GACvB,MAAK,mBAAmB,mBAAmB;;AAG/C,WAAO,KAAK,MAAM;KAChB,GAAG;KACH,KAAK;KACL,SAAS,UAAU;KACnB,iBAAiB,kBAAkB;KACnC,kBAAkB;KACnB,CAAC;;AAGJ,OAAI,aAAa,eAAe,SAAS;IACvC,MAAM,WAAW,uBACf,cACA,wBACA,2BACD;AACD,UAAM,IAAI,SAAe,YAAY;AACnC,sBAAiB,SAAS,EAAE,SAAS;MACrC;AACF,WAAO,KAAK,MAAM;KAChB,GAAG;KACH,SAAS,UAAU;KACnB,cAAc,eAAe;KAC7B,kBAAkB;KACnB,CAAC;;AAGJ,OAAI,iBAAiB,MACnB,OAAM;GAER,MAAM,UAAU,IAAI,MACjB,OAAgC,WAAW,OAAO,MAAM,CAC1D;AACD,UAAO,OAAO,SAAS,MAAM;AAC7B,SAAM;;AAGR,MAAI;GACF,MAAM,WAAW,MAAM,MAAM,KAA0B,UAAyB;AAChF,gBAAa,UAAU;AAEvB,OAAI,SAAS,WAAW,OAAO,SAAS,WAAW,IACjD,QAAO,gBAAgB,SAAS,QAAQ,SAAS,SAAS,wBAAW,IAAI,MACvE,YAAY,SAAS,SACtB,CAAC;AAIJ,OAAI,SAAS,UAAU,IACrB,QAAO,gBACL,SAAS,QACT,SAAS,SACT,QACA,OAAO,uBAAO,IAAI,MAAM,QAAQ,SAAS,SAAS,EAAE,EAClD,UAAU;IACR,QAAQ,SAAS;IACjB,SAAS,OAAO,YAAY,SAAS,QAAQ,SAAS,CAAC;IACxD,EACF,CAAC,CACH;AAGH,OAAI,QAAQ;AACV,QAAI,CAAC,SAAS,KACZ,QAAO,SAAS,KAAK,EAAE,CAAC;AAE1B,WAAO,SAAS,QAAQ,SAAS,KAA4C;;GAG/E,MAAM,cAAc,SAAS,QAAQ,IAAI,eAAe,IAAI;GAC5D,IAAIC;AACJ,OAAI,YAAY,SAAS,mBAAmB,CAC1C,gBAAe,MAAM,SAAS,MAAM;OAEpC,gBAAe,MAAM,SAAS,MAAM;AAGtC,UAAO;IACL,MAAM;IACN,QAAQ,SAAS;IAClB;WACM,GAAG;AACV,gBAAa,UAAU;GACvB,MAAM,YAAY,aAAa,EAAE;GACjC,MAAM,MAAM;GACZ,MAAM,iBAAiB,IAAI,UAAU;GACrC,MAAM,kBAAkB,IAAI,UAAU;AACtC,UAAO,gBAAgB,gBAAgB,iBAAiB,WAAW,EAAE;;;CAKzE,MAAM,IAAK,GAAG,MAA+C;EAC3D,MAAM,UAAW,KAAK,MAAM,EAAE;AAC9B,SAAO,KAAK,MAAM;GAAE,GAAG;GAAS,YAAY;GAAiB,CAAC;;CAGhE,MAAM,KAAM,GAAG,MAA+C;EAC5D,MAAM,UAAW,KAAK,MAAM,EAAE;AAC9B,SAAO,KAAK,MAAM;GAAE,GAAG;GAAS,YAAY;GAAkB,CAAC;;;;;;;;;;;;;ACzpBnE,MAAa,oBAAoB;AACjC,MAAa,qBAAqB;AAClC,MAAa,sBAAsB;AACnC,MAAa,qBAAqB;AAClC,MAAa,0BAA0B;AACvC,MAAa,gBAAgB;AAC7B,MAAa,kBAAkB;;;;;;;;;ACkB/B,SAAgB,YAAa,UAAmC,EAAE,EAA2B;CAC3F,MAAM,EAAE,OAAO,QAAQ,SAAS,QAAQ,gBAAgB;CAExD,MAAMC,QAAiC;GACpC,oBAAoB;GACpB,qBAAqB;GACrB,sBAAsB;GACtB,qBAAqB;GACrB,0BAA0B;EAC5B;AACD,QAAO,OAAO,QAAQ,MAAM,CAAC,QAAiC,KAAK,UAAU;EAC3E,MAAM,CAAC,KAAK,OAAO;AACnB,MAAI,OAAO,QAAQ,YACjB,KAAI,OAAO;AAEb,SAAO;IACN,EAAE,CAAC;;;;;AAMR,IAAqB,YAArB,cAAuC,YAAY;;;;;CAKjD,MAAM,IAAK,GAAG,MAAoC;EAChD,MAAM,OAAO,KAAK;EAClB,MAAM,MAAM,KAAK;EACjB,MAAM,UAAW,KAAK,MAAM,EAAE;EAC9B,MAAM,EAAE,cAAc;AACtB,MAAI,CAAC,KACH,OAAM,IAAI,MAAM,gCAAgC;AAElD,SAAO,MAAM,IAAI;GACf;GACA,KAAK;GACL,YAAY;GACZ,OAAO;IAAE,GAAG,YAAY,QAAQ;KAAG,gBAAgB;IAAK;GACzD,CAAuB;;;;;;CAO1B,MAAM,KAAM,GAAG,MAAoC;EACjD,MAAM,OAAO,KAAK;EAClB,MAAM,MAAM,KAAK;EACjB,MAAM,UAAW,KAAK,MAAM,EAAE;EAC9B,MAAM,EAAE,cAAc;AACtB,MAAI,CAAC,KACH,OAAM,IAAI,MAAM,gCAAgC;AAElD,SAAO,MAAM,KAAK;GAChB;GACA,KAAK;GACL,YAAY;GACZ,OAAO,YAAY,QAAQ;GAC3B,MAAM,MAAM,QAAQ,IAAI,GAAG,MAAM,CAAC,IAAI;GACvC,CAAuB;;;;;;;;;;;ACvF5B,MAAa,oBAAoB;AACjC,MAAa,6BAA6B;AAC1C,MAAa,8BAA8B;AAC3C,MAAa,uBAAuB;AACpC,MAAa,sBAAsB;AACnC,MAAa,qBAAqB;AAClC,MAAa,wBAAwB;AACrC,MAAa,uBAAuB;;;;;;;;ACcpC,IAAqB,aAArB,MAAgC;CAC9B,OAAO;CAEP;CAEA,eAAe;CAEf,OAAgC,EAAE;CAElC,YAAa,QAA4B,aAAsB;AAC7D,MAAI,OAAO,WAAW,YAAY,WAAW,KAC3C,OAAM,IAAI,MAAM,kDAAkD;AAEpE,MAAI,OAAO,gBAAgB,eAAe,CAAC,OAAO,SAAS,YAAY,CACrE,OAAM,IAAI,MAAM,2EAA2E;AAE7F,OAAK,OAAO,WAAW,OAAO,OAAO,sBAAsB,EAAI,CAAC;AAChE,OAAK,eAAe,SAAS,OAAO,OAAO,+BAA+B,EAAE,EAAE,GAAG;AACjF,OAAK,eAAe,OAAO;AAC3B,MAAI,OAAO,SAAS,YAAY,EAAE;GAChC,MAAM,UAAU,OAAO;GACvB,MAAM,eAAgB,OAAO,qBAAqC;AAClE,OAAI,aACF,MAAK,OAAO,aAAa,QAAiC,KAAK,KAAK,MAAM;IACxE,MAAM,MAAM,QAAQ;AACpB,QAAI,OAAO;AACX,WAAO;MACN,EAAE,CAAC;;;CAKZ,IAAK,UAA2B;AAC9B,SAAO,KAAK,KAAK;;CAGnB,UAAmB;AACjB,SAAO,KAAK;;CAGd,kBAAuC;AACrC,SAAO,KAAK;;CAGd,kBAA2B;AACzB,SAAO,KAAK;;CAGd,WAAqC;AACnC,SAAO,KAAK,MAAM,KAAK,UAAU,KAAK,KAAK,CAAC;;CAG9C,UAAsB;AACpB,SAAO,OAAO,OAAO,KAAK,KAAK;;CAGjC,iBAA4B;AAC1B,SAAO,OAAO,KAAK,KAAK,KAAK;;CAG/B,WAAoB;AAClB,SAAO,KAAK,UAAU,KAAK,KAAK;;;;;;;;;;AC7EpC,IAAqB,kBAArB,cAA6C,MAAM;CACjD;CAEA;CAEA,YAAa,SAAiB,SAAmC;AAC/D,QAAM,QAAQ;AACd,OAAK,OAAO,KAAK,YAAY;AAC7B,OAAK,OAAO,KAAK,YAAY;AAC7B,MAAI,QACF,MAAK,UAAU;;CAInB,aAAmD;AACjD,SAAO,KAAK;;CAGd,WAAqC;EACnC,MAAMC,MAA+B,GAAG,qBAAqB,KAAK,SAAS;AAC3E,MAAI,KAAK,QACP,KAAI,yBAAyB,KAAK;AAEpC,SAAO;;CAGT,WAAoB;AAClB,SAAO,KAAK,UAAU,KAAK,UAAU,CAAC;;;;;;;;;;ACZ1C,IAAqB,cAArB,MAAiC;CAC/B,OAAO;CAEP,UAA+C,EAAE;CAEjD,YAAa,MAAqB;AAChC,OAAK,WAAW,KAAK;;CAGvB,WAAY,MAA2B;AACrC,MAAI,OAAO,SAAS,YAAY,SAAS,KACvC,OAAM,IAAI,MAAM,gDAAgD;AAElE,MAAI,CAAC,KAAK,sBACR,OAAM,IAAI,MAAM,yDAAyD;AAE3E,OAAK,OAAO,WAAW,OAAO,KAAK,sBAAsB,EAAI,CAAC;AAE9D,OAAK,WADW,KAAK,yBAAyB,EAAE,EACzB,QAA6C,KAAK,WAAW;AAClF,OAAI,OAAO,WAAW,YAAY,WAAW,QAAQ,OAAO,oBAC1D,QAAO,IAAI,OACT,IAAI,gBACF,OAAO,OAAO,oBAAoB,EAClC,OAAO,uBACR,CACF;GAEH,MAAM,OAAO,OAAO;AACpB,OAAI,CAAC,KACH,QAAO,IAAI,OAAO,IAAI,WAAW,OAAO,CAAC;GAE3C,MAAM,cAAc,KAAK,KAAK,IAAI,gBAAgB,IAAI,WAAW,QAAQ,YAAY,CAAC;AACtF,UAAO,IAAI,OAAO,YAAY;KAC7B,EAAE,CAAC;;CAGR,WAAqB;AACnB,SAAO,CAAC,CAAC,KAAK,eAAe;;CAG/B,gBAA8C;AAC5C,SAAO,KAAK,QAAQ,MAAM,MAAM,aAAa,gBAAgB;;CAG/D,UAAmB;AACjB,SAAO,KAAK;;CAGd,IAAK,OAAyD;AAC5D,SAAO,KAAK,QAAQ;;CAGtB,aAAmD;AACjD,SAAO,KAAK;;CAGd,UAAsC;AACpC,SAAO,KAAK,QAAQ,KAAK,WAAW,OAAO,UAAU,CAAC;;CAGxD,WAAoB;EAClB,MAAM,OAAO,KAAK,QAAQ,KAAK,WAAW,OAAO,UAAU,CAAC;AAC5D,SAAO,KAAK,UAAU,KAAK;;;;;;;;;;;;;AChF/B,MAAa,aAAa;AAC1B,MAAa,eAAe;AAC5B,MAAa,YAAY;AACzB,MAAa,cAAc;AAC3B,MAAa,cAAc;;;;;;;;;ACN3B,MAAa,yBAAyB;AACtC,MAAa,2BAA2B;AACxC,MAAa,iCAAiC;AAC9C,MAAa,yBAAyB;;;;ACwBtC,SAAS,eACP,UACA,UAAkC,EAAE,EACR;CAC5B,MAAM,EAAE,QAAQ;CAChB,MAAM,EAAE,SAAS;AACjB,KAAI,IACF,QAAO;AAET,QAAO,IAAI,YAAY,KAAsB;;;;;AAM/C,IAAqB,gBAArB,cAA2C,UAAU;;;;;;CAMnD,MAAM,MACJ,KACA,UAA+B,EAAE,EACI;EACrC,MAAM,EAAE,UAAU;EAClB,IAAI,EAAE,cAAc;AACpB,MAAI,UAAU,uBACZ,aAAY;EAEd,IAAIC;AACJ,MAAI,MAAM,QAAQ,IAAI,CACpB,YAAW,MAAM,MAAM,KAAK,YAAY,KAAK;GAAE,GAAG;GAAS;GAAW,CAAC;MAEvE,YAAW,MAAM,MAAM,IAAI,YAAY,KAAK;GAAE,GAAG;GAAS;GAAW,CAAC;AAExE,MAAI,CAAC,UACH,MAAK,wBAAwB;AAE/B,SAAO,eAAe,UAAU,QAAQ;;;;;;CAO1C,MAAM,QACJ,KACA,UAAiC,EAAE,EACE;AAErC,SAAO,eADU,MAAM,MAAM,KAAK,cAAc,KAAK,QAAQ,EAC7B,QAAQ;;;;;;;;;;;AC9E5C,MAAa,yBAAyB;AACtC,MAAa,0BAA0B;;;;;;;ACkBvC,IAAqB,kBAArB,cAA6C,YAAY;;;;;;CAMvD,MAAM,OAAQ,SAAiB,yBAA4C;AACzE,SAAO,MAAM,IAAI;GACf,SAAS,GACN,qBAAqB,uCACvB;GACD,OAAO,GACJ,kBAAkB,WAAW,yBAAyB,SAAS,QACjE;GACD,MAAM;GACN,QAAQ;GACR,KAAK;GACL,WAAW;GACZ,CAAC;;;;;;;CAQJ,MAAM,KACJ,MACA,SAAiB,wBACE;AACnB,SAAO,MAAM,KAAK;GAChB,MAAM;GACN,SAAS,GACN,2BAA2B,WAAW,yBACnC,0BACA,uCACL;GACD,MAAM;GACN,QAAQ;GACR,KAAK;GACL,WAAW;GACZ,CAAC;;;;;;;;;ACxCN,IAAqB,kBAArB,cAA6C,UAAU;;;;;CAKrD,MAAM,OAAQ,UAAgC,EAAE,EAAyB;AACvE,SAAO,KAAK,MAAM;GAChB,GAAG;GACH,KAAK;GACL,YAAY;GACZ,WAAW,OAAO,QAAQ,cAAc,YAAY,QAAQ,YAAY;GACzE,CAAC;;;;;;CAOJ,MAAM,eAAgB,UAAgC,EAAE,EAAqC;EAC3F,MAAM,QAAQ,KAAK,UAAU;EAC7B,MAAM,WAAW,MAAM,IAAI,OAAO,OAAO,qBAAqB;AAE5D,UAAO;IAAE,UADQ,MAAM,KAAK,OAAO;KAAE,GAAG;KAAS,WAAW;KAAO;KAAkB,CAAC;IACnE,MAAM,MAAM;IAAmB;IAClD;AACF,SAAO,QAAQ,IAAI,SAAS;;;;;;ACjBhC,kBAAe;CACb;CACA;CACA;CACD"}
@@ -0,0 +1,71 @@
1
+ # Migrating from rqlite-js v2 to v3
2
+
3
+ v3 keeps the same client-facing API intent (`DataApiClient`, `BackupApiClient`, `StatusApiClient`, query/execute/backup/status, auth, hosts, retries) while replacing the support stack: TypeScript source, tsdown dual ESM/CJS builds, native `fetch`, Jest tests, and **zero runtime npm dependencies**.
4
+
5
+ ## Breaking changes
6
+
7
+ ### Node.js engines
8
+
9
+ - **v2:** `>=18`
10
+ - **v3:** `>=20.19`
11
+
12
+ Native `fetch` and modern package `exports` are required.
13
+
14
+ ### Package layout and imports
15
+
16
+ | v2 | v3 |
17
+ |----|----|
18
+ | Published `lib/` (Babel output) | Published `dist/` (JS + `.d.ts`) and `src/` (TypeScript) |
19
+ | `main`: `lib/index.js` | Dual `exports` for ESM + CJS + types |
20
+ | Deep imports like `rqlite-js/lib/...` | **Unsupported** — import from `rqlite-js` only |
21
+
22
+ ```js
23
+ // ESM
24
+ import { DataApiClient } from 'rqlite-js'
25
+
26
+ // CommonJS
27
+ const { DataApiClient } = require('rqlite-js')
28
+ ```
29
+
30
+ Types ship in-box (`dist/*.d.ts` / `*.d.cts`). No `@types/rqlite-js` package.
31
+
32
+ ### HTTP stack (axios → fetch)
33
+
34
+ - **Removed runtime deps:** `axios`, `qs`
35
+ - HTTP uses platform **`fetch`** and **`URLSearchParams`**
36
+ - Non-2xx responses still reject (axios-compatible behavior)
37
+ - Redirects (301/302) are still followed manually so request bodies can be replayed
38
+ - `stream: true` (backup/load) returns a Node **`Readable`** created from the fetch body (`Readable.fromWeb`)
39
+
40
+ `httpAgent` / `httpsAgent` option names are unchanged. For keepalive with native fetch, pass an **undici-compatible `Dispatcher`** (object with a `dispatch` method). Classic `http.Agent` / `https.Agent` instances are still stored and returned by getters for API compatibility, but are not attached to `fetch` unless they expose `dispatch`.
41
+
42
+ ### Removed tooling (authors / contributors)
43
+
44
+ - Babel / `es6/` / `lib/` pipeline → TypeScript `src/` + tsdown `dist/`
45
+ - Mocha / Chai → Jest
46
+ - `jsconfig` + `checkJs` → `tsconfig` + real types
47
+
48
+ Consumers do not install these; they are `devDependencies` only.
49
+
50
+ ## What stayed the same
51
+
52
+ - Public class names and primary methods: `query`, `execute`, `backup`, `load`, `status`, `statusAllHosts`
53
+ - Result helpers: `DataResults`, `DataResult`, `DataResultError`
54
+ - Exported path/level/format constants
55
+ - Host lists (array or comma-separated string), authentication map, retry/backoff options (including historical `DEAULT_*` / `exponentail*` spellings)
56
+ - Default export object `{ DataApiClient, BackupApiClient, StatusApiClient }`
57
+
58
+ ## Suggested upgrade steps
59
+
60
+ 1. Upgrade Node to `>=20.19`.
61
+ 2. `npm install rqlite-js@3`.
62
+ 3. Replace any deep `lib/` imports with package-root imports.
63
+ 4. Re-run your app tests; adjust only if you depended on axios error shapes or raw axios streams.
64
+ 5. If you customised keepalive agents for fetch, switch to an undici `Agent` / `Dispatcher`.
65
+
66
+ ## Verify locally (maintainers)
67
+
68
+ ```bash
69
+ npm run verify
70
+ npm run verify:integrations
71
+ ```
package/package.json CHANGED
@@ -1,25 +1,60 @@
1
1
  {
2
2
  "name": "rqlite-js",
3
- "version": "2.5.7",
4
- "description": "A client library for RQLite written in Javascript that works in NodeJS or the browser.",
5
- "main": "lib/index.js",
3
+ "version": "3.0.0",
4
+ "description": "A client library for RQLite written in TypeScript that works in NodeJS or the browser.",
5
+ "type": "module",
6
+ "main": "./dist/index.cjs",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "import": {
12
+ "types": "./dist/index.d.ts",
13
+ "default": "./dist/index.js"
14
+ },
15
+ "require": {
16
+ "types": "./dist/index.d.cts",
17
+ "default": "./dist/index.cjs"
18
+ },
19
+ "default": "./dist/index.js"
20
+ },
21
+ "./package.json": "./package.json"
22
+ },
23
+ "engines": {
24
+ "node": ">=20.19"
25
+ },
26
+ "files": [
27
+ "dist",
28
+ "src",
29
+ "!src/**/*.test.ts",
30
+ "!src/**/*.integration.test.ts",
31
+ "!src/test/**",
32
+ "docs/MIGRATION-v2-to-v3.md",
33
+ "LICENSE",
34
+ "README.md"
35
+ ],
36
+ "sideEffects": false,
6
37
  "scripts": {
7
- "build": "babel es6 --out-dir lib --source-maps --ignore es6/**/*.unit.js,es6/**/*.integration.js,es6/test",
8
- "build-all": "babel es6 --out-dir lib --source-maps",
9
- "build-clean": "rm -rf lib",
38
+ "build": "tsdown",
39
+ "build-all": "tsdown",
40
+ "build-clean": "rm -rf dist",
10
41
  "build-release": "npm run build && npm run test-build",
11
- "docker-build": "docker-compose -p rqlitejs build",
12
- "docker-down": "docker-compose -p rqlitejs down",
13
- "docker-logs": "docker-compose -p rqlitejs logs",
14
- "docker-run-test": "docker-compose -p rqlitejs run test",
15
- "docker-stop": "docker-compose -p rqlitejs stop",
16
- "lint": "eslint es6/**/*.js",
17
- "release": "npm run lint && npm run build-all && npm run test-build && standard-version",
18
- "test": "mocha --require @babel/register es6/test/unit/index.unit.js es6/**/*.unit.js",
19
- "test-integrations": "mocha --require @babel/register --timeout 10000 lib/**/*.integration.js",
20
- "test-build": "mocha lib/test/unit/index.unit.js lib/**/*.unit.js",
21
- "test-build-integrations": "mocha --timeout 30000 lib/**/*.integration.js",
22
- "prepublishOnly": "npm run lint && npm run build && npm run test-build"
42
+ "docker-build": "docker compose -p rqlitejs build",
43
+ "docker-down": "docker compose -p rqlitejs down",
44
+ "docker-logs": "docker compose -p rqlitejs logs",
45
+ "docker-run-test": "docker compose -p rqlitejs run --rm test",
46
+ "docker-stop": "docker compose -p rqlitejs stop",
47
+ "lint": "ESLINT_USE_FLAT_CONFIG=false eslint src",
48
+ "type-check": "tsc -p tsconfig.json --noEmit",
49
+ "verify": "npm run lint && npm run type-check && npm test && npm run build && npm run test-build && npm run check-pack",
50
+ "verify:integrations": "npm run docker-build && npm run docker-run-test",
51
+ "release": "npm run verify",
52
+ "test": "NODE_OPTIONS=--experimental-vm-modules jest --config jest.config.cjs --testPathIgnorePatterns=integration",
53
+ "test-integrations": "NODE_OPTIONS=--experimental-vm-modules jest --config jest.config.cjs --testPathPatterns=integration --runInBand --testTimeout=30000",
54
+ "test-build": "NODE_OPTIONS=--experimental-vm-modules jest --config jest.config.cjs --testPathIgnorePatterns=integration",
55
+ "test-build-integrations": "NODE_OPTIONS=--experimental-vm-modules jest --config jest.config.cjs --testPathPatterns=integration --runInBand --testTimeout=30000",
56
+ "check-pack": "npm pack --dry-run && publint && attw --pack . --profile node16",
57
+ "prepublishOnly": "npm run lint && npm run type-check && npm run build && npm run test-build"
23
58
  },
24
59
  "repository": {
25
60
  "type": "git",
@@ -28,7 +63,8 @@
28
63
  "keywords": [
29
64
  "rqlite",
30
65
  "client",
31
- "nodejs"
66
+ "nodejs",
67
+ "typescript"
32
68
  ],
33
69
  "author": "Justin Morant",
34
70
  "license": "ISC",
@@ -36,31 +72,26 @@
36
72
  "url": "https://github.com/rqlite/rqlite-js/issues"
37
73
  },
38
74
  "homepage": "https://github.com/rqlite/rqlite-js#readme",
75
+ "dependencies": {},
39
76
  "devDependencies": {
40
- "@babel/cli": "^7.26.4",
41
- "@babel/core": "^7.26.0",
42
- "@babel/eslint-parser": "^7.25.9",
43
- "@babel/plugin-proposal-class-properties": "^7.18.6",
44
- "@babel/plugin-transform-runtime": "^7.25.9",
45
- "@babel/preset-env": "^7.26.0",
46
- "@babel/register": "^7.25.9",
47
- "@babel/runtime": "^7.26.0",
48
- "babel-plugin-add-module-exports": "^1.0.4",
49
- "chai": "^4.5.0",
50
- "chai-as-promised": "^7.1.2",
77
+ "@arethetypeswrong/cli": "^0.18.2",
78
+ "@swc/core": "^1.13.5",
79
+ "@swc/jest": "^0.2.39",
80
+ "@types/jest": "^30.0.0",
81
+ "@types/node": "^22.20.5",
82
+ "@typescript-eslint/eslint-plugin": "^8.46.1",
83
+ "@typescript-eslint/parser": "^8.46.1",
51
84
  "eslint": "^8.57.1",
52
- "eslint-config-airbnb-base": "^15.0.0",
53
- "eslint-plugin-babel": "^5.3.1",
54
- "eslint-plugin-import": "^2.31.0",
55
- "eslint-plugin-mocha": "^10.5.0",
56
- "mocha": "^10.8.2",
57
- "nock": "^13.5.6",
58
- "retry-as-promised": "^7.0.4",
59
- "standard-version": "^9.5.0"
85
+ "eslint-import-resolver-typescript": "^4.4.5",
86
+ "eslint-plugin-import": "^2.32.0",
87
+ "eslint-plugin-jest": "^28.14.0",
88
+ "jest": "^30.2.0",
89
+ "nock": "^14.0.10",
90
+ "publint": "^0.3.14",
91
+ "tsdown": "^0.15.12",
92
+ "typescript": "^5.9.3"
60
93
  },
61
- "dependencies": {
62
- "axios": "^1.7.9",
63
- "install": "^0.13.0",
64
- "qs": "^6.13.1"
94
+ "allowScripts": {
95
+ "@swc/core@1.16.22": true
65
96
  }
66
97
  }
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Backup api client to perform RQLite backup and load operations
3
+ * @module api/backup
4
+ * @see https://rqlite.io/docs/guides/backup/
5
+ */
6
+ import type { Readable } from 'node:stream'
7
+ import HttpRequest from '../../http-request/index.js'
8
+ import {
9
+ CONTENT_TYPE_APPLICATION_OCTET_STREAM,
10
+ CONTENT_TYPE_TEXT_PLAIN,
11
+ } from '../../http-request/content-types.js'
12
+ import {
13
+ HTTP_HEADER_ACCEPT,
14
+ HTTP_HEADER_CONTENT_TYPE,
15
+ } from '../../http-request/http-headers.js'
16
+ import { PATH_BACKUP, PATH_LOAD } from '../paths.js'
17
+ import { BACKUP_DATA_FORMAT_DUMP, BACKUP_DATA_FORMAT_SQL } from '../backup-formats.js'
18
+ import { QUERY_PARAM_FMT } from '../query-params.js'
19
+
20
+ export { PATH_LOAD, PATH_BACKUP } from '../paths.js'
21
+ export { BACKUP_DATA_FORMAT_SQL, BACKUP_DATA_FORMAT_DUMP } from '../backup-formats.js'
22
+
23
+ /**
24
+ * Backup api client to perform RQLite back up and load operations
25
+ */
26
+ export default class BackupApiClient extends HttpRequest {
27
+ /**
28
+ * Perform a SQL dump backup from the RQLite server
29
+ * @see https://rqlite.io/docs/guides/backup/
30
+ * @see module:api/backup-formats
31
+ */
32
+ async backup (format: string = BACKUP_DATA_FORMAT_DUMP): Promise<Readable> {
33
+ return super.get({
34
+ headers: {
35
+ [HTTP_HEADER_ACCEPT]: CONTENT_TYPE_APPLICATION_OCTET_STREAM,
36
+ },
37
+ query: {
38
+ [QUERY_PARAM_FMT]: format === BACKUP_DATA_FORMAT_SQL ? format : undefined,
39
+ },
40
+ json: false,
41
+ stream: true,
42
+ uri: PATH_BACKUP,
43
+ useLeader: true,
44
+ }) as Promise<Readable>
45
+ }
46
+
47
+ /**
48
+ * Perform a SQL restore by sending data the RQLite server
49
+ * @see https://rqlite.io/docs/guides/backup/
50
+ * @see module:api/backup-formats
51
+ */
52
+ async load (
53
+ data: Buffer | string,
54
+ format: string = BACKUP_DATA_FORMAT_SQL,
55
+ ): Promise<Readable> {
56
+ return super.post({
57
+ body: data,
58
+ headers: {
59
+ [HTTP_HEADER_CONTENT_TYPE]: format === BACKUP_DATA_FORMAT_SQL
60
+ ? CONTENT_TYPE_TEXT_PLAIN
61
+ : CONTENT_TYPE_APPLICATION_OCTET_STREAM,
62
+ },
63
+ json: false,
64
+ stream: true,
65
+ uri: PATH_LOAD,
66
+ useLeader: true,
67
+ }) as Promise<Readable>
68
+ }
69
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * RQLite backup data format constants
3
+ * @module api/backup-formats
4
+ * @see https://rqlite.io/docs/guides/backup/
5
+ */
6
+
7
+ export const BACKUP_DATA_FORMAT_SQL = 'sql'
8
+ export const BACKUP_DATA_FORMAT_DUMP = 'dump'
@@ -0,0 +1,97 @@
1
+ /**
2
+ * Base API client for RQLite which abstracts the HTTP calls
3
+ * @module api/client
4
+ * @see https://rqlite.io/docs/api/api/
5
+ */
6
+ import HttpRequest from '../../http-request/index.js'
7
+ import type { HttpRequestOptions, HttpResponse } from '../../http-request/index.js'
8
+ import { HTTP_METHOD_GET, HTTP_METHOD_POST } from '../../http-request/http-methods.js'
9
+ import {
10
+ QUERY_PARAM_ATOMIC,
11
+ QUERY_PARAM_LEVEL,
12
+ QUERY_PARAM_PRETTY,
13
+ QUERY_PARAM_Q,
14
+ QUERY_PARAM_TIMINGS,
15
+ QUERY_PARAM_TRANSACTION,
16
+ } from '../query-params.js'
17
+
18
+ export type ApiClientRequestOptions = {
19
+ useLeader?: boolean
20
+ level?: string
21
+ pretty?: boolean
22
+ timings?: boolean
23
+ atomic?: boolean
24
+ transaction?: boolean
25
+ raw?: boolean
26
+ }
27
+
28
+ /**
29
+ * Create the base HTTP query options from RQLite API options
30
+ * @see https://rqlite.io/docs/api/api/
31
+ * @see module:api/query-params
32
+ */
33
+ export function createQuery (options: ApiClientRequestOptions = {}): Record<string, unknown> {
34
+ const { level, pretty, timings, atomic, transaction } = options
35
+
36
+ const query: Record<string, unknown> = {
37
+ [QUERY_PARAM_LEVEL]: level,
38
+ [QUERY_PARAM_PRETTY]: pretty,
39
+ [QUERY_PARAM_TIMINGS]: timings,
40
+ [QUERY_PARAM_ATOMIC]: atomic,
41
+ [QUERY_PARAM_TRANSACTION]: transaction,
42
+ }
43
+ return Object.entries(query).reduce<Record<string, unknown>>((acc, entry) => {
44
+ const [key, val] = entry
45
+ if (typeof val !== 'undefined') {
46
+ acc[key] = val
47
+ }
48
+ return acc
49
+ }, {})
50
+ }
51
+
52
+ /**
53
+ * Base API client for RQLite which abstracts the HTTP calls from the user
54
+ */
55
+ export default class ApiClient extends HttpRequest {
56
+ /**
57
+ * Perform a RQLite data API get request
58
+ * @see https://rqlite.io/docs/api/api/
59
+ */
60
+ async get (...args: any[]): Promise<HttpResponse> {
61
+ const path = args[0] as string
62
+ const sql = args[1] as string
63
+ const options = (args[2] || {}) as ApiClientRequestOptions
64
+ const { useLeader } = options
65
+ if (!path) {
66
+ throw new Error('The path argument is required')
67
+ }
68
+ return super.get({
69
+ useLeader,
70
+ uri: path,
71
+ httpMethod: HTTP_METHOD_GET,
72
+ query: { ...createQuery(options), [QUERY_PARAM_Q]: sql },
73
+ } as HttpRequestOptions) as Promise<HttpResponse>
74
+ }
75
+
76
+ /**
77
+ * Perform a RQLite data API post request
78
+ * @see https://rqlite.io/docs/api/api/
79
+ */
80
+ async post (...args: any[]): Promise<HttpResponse> {
81
+ const path = args[0] as string
82
+ const sql = args[1] as string | string[]
83
+ const options = (args[2] || {}) as ApiClientRequestOptions
84
+ const { useLeader } = options
85
+ if (!path) {
86
+ throw new Error('The path argument is required')
87
+ }
88
+ return super.post({
89
+ useLeader,
90
+ uri: path,
91
+ httpMethod: HTTP_METHOD_POST,
92
+ query: createQuery(options),
93
+ body: Array.isArray(sql) ? sql : [sql],
94
+ } as HttpRequestOptions) as Promise<HttpResponse>
95
+ }
96
+ }
97
+
@@ -0,0 +1,10 @@
1
+ /**
2
+ * RQLite read consistency level constants
3
+ * @module api/consistency-levels
4
+ * @see https://rqlite.io/docs/api/read-consistency/
5
+ */
6
+
7
+ export const CONSISTENCY_LEVEL_NONE = 'none'
8
+ export const CONSISTENCY_LEVEL_STRONG = 'strong'
9
+ export const CONSISTENCY_LEVEL_LINEARIZABLE = 'linearizable'
10
+ export const CONSISTENCY_LEVEL_WEAK = 'weak'
@@ -0,0 +1,87 @@
1
+ /**
2
+ * Data api client to perform RQLite data operations such as query and execute
3
+ * @module api/data
4
+ * @see https://rqlite.io/docs/api/api/
5
+ * @see https://rqlite.io/docs/api/read-consistency/
6
+ */
7
+ import ApiClient from '../client/index.js'
8
+ import type { ApiClientRequestOptions } from '../client/index.js'
9
+ import type { HttpResponse } from '../../http-request/index.js'
10
+ import { DataResults } from '../results/index.js'
11
+ import type { RqliteApiData } from '../results/data-results.js'
12
+ import { PATH_EXECUTE, PATH_QUERY } from '../paths.js'
13
+ import { CONSISTENCY_LEVEL_NONE } from '../consistency-levels.js'
14
+
15
+ export {
16
+ PATH_QUERY,
17
+ PATH_EXECUTE,
18
+ } from '../paths.js'
19
+
20
+ export {
21
+ CONSISTENCY_LEVEL_NONE,
22
+ CONSISTENCY_LEVEL_STRONG,
23
+ CONSISTENCY_LEVEL_LINEARIZABLE,
24
+ CONSISTENCY_LEVEL_WEAK,
25
+ } from '../consistency-levels.js'
26
+
27
+ export type DataRequestBaseOptions = {
28
+ raw?: boolean
29
+ }
30
+
31
+ export type QueryRequestOptions = ApiClientRequestOptions & DataRequestBaseOptions
32
+ export type ExecuteRequestOptions = ApiClientRequestOptions & DataRequestBaseOptions
33
+
34
+ function handleResponse (
35
+ response: HttpResponse,
36
+ options: DataRequestBaseOptions = {},
37
+ ): DataResults | HttpResponse {
38
+ const { raw } = options
39
+ const { body } = response
40
+ if (raw) {
41
+ return response
42
+ }
43
+ return new DataResults(body as RqliteApiData)
44
+ }
45
+
46
+ /**
47
+ * Data api client to perform RQLite queries
48
+ */
49
+ export default class DataApiClient extends ApiClient {
50
+ /**
51
+ * Send an RQLite query API request to the RQLite server
52
+ * @see https://rqlite.io/docs/api/api/
53
+ * @see https://rqlite.io/docs/api/read-consistency/
54
+ */
55
+ async query (
56
+ sql: string | string[],
57
+ options: QueryRequestOptions = {},
58
+ ): Promise<DataResults | HttpResponse> {
59
+ const { level } = options
60
+ let { useLeader } = options
61
+ if (level !== CONSISTENCY_LEVEL_NONE) {
62
+ useLeader = true
63
+ }
64
+ let response: HttpResponse
65
+ if (Array.isArray(sql)) {
66
+ response = await super.post(PATH_QUERY, sql, { ...options, useLeader })
67
+ } else {
68
+ response = await super.get(PATH_QUERY, sql, { ...options, useLeader })
69
+ }
70
+ if (!useLeader) {
71
+ this.setNextActiveHostIndex()
72
+ }
73
+ return handleResponse(response, options)
74
+ }
75
+
76
+ /**
77
+ * Send an RQLite execute API request to the RQLite server
78
+ * @see https://rqlite.io/docs/api/api/
79
+ */
80
+ async execute (
81
+ sql: string | string[],
82
+ options: ExecuteRequestOptions = {},
83
+ ): Promise<DataResults | HttpResponse> {
84
+ const response = await super.post(PATH_EXECUTE, sql, options)
85
+ return handleResponse(response, options)
86
+ }
87
+ }
@@ -0,0 +1,13 @@
1
+ /**
2
+ * RQLite HTTP API path constants
3
+ * @module api/paths
4
+ * @see https://rqlite.io/docs/api/api/
5
+ * @see https://rqlite.io/docs/guides/backup/
6
+ * @see https://rqlite.io/docs/guides/monitoring-rqlite/
7
+ */
8
+
9
+ export const PATH_QUERY = '/db/query'
10
+ export const PATH_EXECUTE = '/db/execute'
11
+ export const PATH_LOAD = '/db/load'
12
+ export const PATH_BACKUP = '/db/backup'
13
+ export const PATH_STATUS = '/status'