rqlite-js 2.6.0 → 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 (98) hide show
  1. package/README.md +207 -29
  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 +56 -35
  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/src/http-request/content-types.ts +4 -0
  25. package/src/http-request/errors.ts +17 -0
  26. package/src/http-request/http-headers.ts +19 -0
  27. package/src/http-request/http-methods.ts +12 -0
  28. package/src/http-request/index.ts +676 -0
  29. package/src/http-request/retryable.ts +41 -0
  30. package/src/index.ts +38 -0
  31. package/lib/api/backup/index.js +0 -72
  32. package/lib/api/backup/index.js.map +0 -1
  33. package/lib/api/backup/test.unit.js +0 -45
  34. package/lib/api/backup/test.unit.js.map +0 -1
  35. package/lib/api/backup-formats.js +0 -16
  36. package/lib/api/backup-formats.js.map +0 -1
  37. package/lib/api/client/index.js +0 -105
  38. package/lib/api/client/index.js.map +0 -1
  39. package/lib/api/client/test.unit.js +0 -53
  40. package/lib/api/client/test.unit.js.map +0 -1
  41. package/lib/api/consistency-levels.js +0 -30
  42. package/lib/api/consistency-levels.js.map +0 -1
  43. package/lib/api/data/index.js +0 -108
  44. package/lib/api/data/index.js.map +0 -1
  45. package/lib/api/data/test.unit.js +0 -98
  46. package/lib/api/data/test.unit.js.map +0 -1
  47. package/lib/api/paths.js +0 -33
  48. package/lib/api/paths.js.map +0 -1
  49. package/lib/api/query-params.js +0 -43
  50. package/lib/api/query-params.js.map +0 -1
  51. package/lib/api/results/data-result-error.js +0 -62
  52. package/lib/api/results/data-result-error.js.map +0 -1
  53. package/lib/api/results/data-result.js +0 -141
  54. package/lib/api/results/data-result.js.map +0 -1
  55. package/lib/api/results/data-results.js +0 -142
  56. package/lib/api/results/data-results.js.map +0 -1
  57. package/lib/api/results/index.js +0 -8
  58. package/lib/api/results/index.js.map +0 -1
  59. package/lib/api/results/result-fields.js +0 -47
  60. package/lib/api/results/result-fields.js.map +0 -1
  61. package/lib/api/results/test.unit.js +0 -238
  62. package/lib/api/results/test.unit.js.map +0 -1
  63. package/lib/api/status/index.js +0 -67
  64. package/lib/api/status/index.js.map +0 -1
  65. package/lib/api/status/test.unit.js +0 -57
  66. package/lib/api/status/test.unit.js.map +0 -1
  67. package/lib/http-request/auth-keys.js +0 -15
  68. package/lib/http-request/auth-keys.js.map +0 -1
  69. package/lib/http-request/content-types.js +0 -5
  70. package/lib/http-request/content-types.js.map +0 -1
  71. package/lib/http-request/errors.js +0 -17
  72. package/lib/http-request/errors.js.map +0 -1
  73. package/lib/http-request/http-headers.js +0 -20
  74. package/lib/http-request/http-headers.js.map +0 -1
  75. package/lib/http-request/http-methods.js +0 -40
  76. package/lib/http-request/http-methods.js.map +0 -1
  77. package/lib/http-request/index.js +0 -764
  78. package/lib/http-request/index.js.map +0 -1
  79. package/lib/http-request/retryable.js +0 -42
  80. package/lib/http-request/retryable.js.map +0 -1
  81. package/lib/http-request/test.unit.js +0 -560
  82. package/lib/http-request/test.unit.js.map +0 -1
  83. package/lib/index.js +0 -39
  84. package/lib/index.js.map +0 -1
  85. package/lib/test/api-data-execute-nock.js +0 -142
  86. package/lib/test/api-data-execute-nock.js.map +0 -1
  87. package/lib/test/api-data-query-nock.js +0 -210
  88. package/lib/test/api-data-query-nock.js.map +0 -1
  89. package/lib/test/backups/backup-nock.js +0 -29
  90. package/lib/test/backups/backup-nock.js.map +0 -1
  91. package/lib/test/backups/restore-nock.js +0 -30
  92. package/lib/test/backups/restore-nock.js.map +0 -1
  93. package/lib/test/env.js +0 -15
  94. package/lib/test/env.js.map +0 -1
  95. package/lib/test/unit/index.unit.js +0 -27
  96. package/lib/test/unit/index.unit.js.map +0 -1
  97. package/lib/test.integration.js +0 -238
  98. package/lib/test.integration.js.map +0 -1
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Class for handling RQLite data api result error
3
+ * @module api/results/data-result-error
4
+ * @see https://rqlite.io/docs/api/api/
5
+ */
6
+ import { RESULT_FIELD_ERROR, RESULT_FIELD_ERROR_V2 } from './result-fields.js'
7
+
8
+ /**
9
+ * A class that represents one data error result from an RQLite query or execute API call
10
+ * @see https://rqlite.io/docs/api/api/
11
+ */
12
+ export default class DataResultError extends Error {
13
+ code: string
14
+
15
+ errorV2?: Record<string, unknown>
16
+
17
+ constructor (message: string, errorV2?: Record<string, unknown>) {
18
+ super(message)
19
+ this.name = this.constructor.name
20
+ this.code = this.constructor.name
21
+ if (errorV2) {
22
+ this.errorV2 = errorV2
23
+ }
24
+ }
25
+
26
+ getErrorV2 (): Record<string, unknown> | undefined {
27
+ return this.errorV2
28
+ }
29
+
30
+ toObject (): Record<string, unknown> {
31
+ const obj: Record<string, unknown> = { [RESULT_FIELD_ERROR]: this.message }
32
+ if (this.errorV2) {
33
+ obj[RESULT_FIELD_ERROR_V2] = this.errorV2
34
+ }
35
+ return obj
36
+ }
37
+
38
+ toString (): string {
39
+ return JSON.stringify(this.toObject())
40
+ }
41
+ }
@@ -0,0 +1,91 @@
1
+ /**
2
+ * Class for handling single RQLite data api result
3
+ * @module api/results/data-result
4
+ * @see https://rqlite.io/docs/api/api/
5
+ * @see module:api/results/result-fields
6
+ */
7
+ import {
8
+ RESULT_FIELD_COLUMNS,
9
+ RESULT_FIELD_LAST_INSERT_ID,
10
+ RESULT_FIELD_ROWS_AFFECTED,
11
+ RESULT_FIELD_TIME,
12
+ RESULT_FIELD_VALUES,
13
+ } from './result-fields.js'
14
+
15
+ export type RqliteSingleResult = {
16
+ [RESULT_FIELD_TIME]?: number | string
17
+ [RESULT_FIELD_ROWS_AFFECTED]?: number | string
18
+ [RESULT_FIELD_LAST_INSERT_ID]?: number
19
+ [RESULT_FIELD_COLUMNS]?: string[]
20
+ [RESULT_FIELD_VALUES]?: unknown[][]
21
+ [key: string]: unknown
22
+ }
23
+
24
+ /**
25
+ * A class that represents one data result from an RQLite query or execute API call
26
+ * @see https://rqlite.io/docs/api/api/
27
+ */
28
+ export default class DataResult {
29
+ time = 0.0
30
+
31
+ lastInsertId?: number
32
+
33
+ rowsAffected = 0
34
+
35
+ data: Record<string, unknown> = {}
36
+
37
+ constructor (result: RqliteSingleResult, valuesIndex?: number) {
38
+ if (typeof result !== 'object' || result === null) {
39
+ throw new Error('The result argument is required to be an object')
40
+ }
41
+ if (typeof valuesIndex !== 'undefined' && !Number.isFinite(valuesIndex)) {
42
+ throw new Error('The valuesIndex argument is required to be a finite number when provided')
43
+ }
44
+ this.time = parseFloat(String(result[RESULT_FIELD_TIME] || 0.0))
45
+ this.rowsAffected = parseInt(String(result[RESULT_FIELD_ROWS_AFFECTED] || 0), 10)
46
+ this.lastInsertId = result[RESULT_FIELD_LAST_INSERT_ID] as number | undefined
47
+ if (Number.isFinite(valuesIndex)) {
48
+ const columns = result[RESULT_FIELD_COLUMNS] as string[]
49
+ const resultValues = (result[RESULT_FIELD_VALUES] as unknown[][])[valuesIndex as number]
50
+ if (resultValues) {
51
+ this.data = resultValues.reduce<Record<string, unknown>>((acc, val, i) => {
52
+ const col = columns[i]
53
+ acc[col] = val
54
+ return acc
55
+ }, {})
56
+ }
57
+ }
58
+ }
59
+
60
+ get (property: string): unknown {
61
+ return this.data[property]
62
+ }
63
+
64
+ getTime (): number {
65
+ return this.time
66
+ }
67
+
68
+ getLastInsertId (): number | undefined {
69
+ return this.lastInsertId
70
+ }
71
+
72
+ getRowsAffected (): number {
73
+ return this.rowsAffected
74
+ }
75
+
76
+ toObject (): Record<string, unknown> {
77
+ return JSON.parse(JSON.stringify(this.data)) as Record<string, unknown>
78
+ }
79
+
80
+ toArray (): unknown[] {
81
+ return Object.values(this.data)
82
+ }
83
+
84
+ toColumnsArray (): string[] {
85
+ return Object.keys(this.data)
86
+ }
87
+
88
+ toString (): string {
89
+ return JSON.stringify(this.data)
90
+ }
91
+ }
@@ -0,0 +1,91 @@
1
+ /**
2
+ * Class for handling many RQLite data api results
3
+ * @module api/results/data-results
4
+ * @see https://rqlite.io/docs/api/api/
5
+ * @see module:api/results/result-fields
6
+ */
7
+ import DataResult from './data-result.js'
8
+ import type { RqliteSingleResult } from './data-result.js'
9
+ import DataResultError from './data-result-error.js'
10
+ import {
11
+ RESULT_FIELD_ERROR,
12
+ RESULT_FIELD_ERROR_V2,
13
+ RESULT_FIELD_RESULTS,
14
+ RESULT_FIELD_TIME,
15
+ RESULT_FIELD_VALUES,
16
+ } from './result-fields.js'
17
+
18
+ export type RqliteApiData = {
19
+ [RESULT_FIELD_TIME]?: number | string
20
+ [RESULT_FIELD_RESULTS]: RqliteSingleResult[]
21
+ }
22
+
23
+ /**
24
+ * A class to manage a list of results from an RQLite query or execute API response
25
+ * @see https://rqlite.io/docs/api/api/
26
+ */
27
+ export default class DataResults {
28
+ time = 0.0
29
+
30
+ results: Array<DataResult | DataResultError> = []
31
+
32
+ constructor (data: RqliteApiData) {
33
+ this.setApiData(data)
34
+ }
35
+
36
+ setApiData (data: RqliteApiData): void {
37
+ if (typeof data !== 'object' || data === null) {
38
+ throw new Error('The data argument is required to be an object')
39
+ }
40
+ if (!data[RESULT_FIELD_RESULTS]) {
41
+ throw new Error('The data object is required to have a results property')
42
+ }
43
+ this.time = parseFloat(String(data[RESULT_FIELD_TIME] || 0.0))
44
+ const results = data[RESULT_FIELD_RESULTS] || []
45
+ this.results = results.reduce<Array<DataResult | DataResultError>>((acc, result) => {
46
+ if (typeof result === 'object' && result !== null && result[RESULT_FIELD_ERROR]) {
47
+ return acc.concat(
48
+ new DataResultError(
49
+ String(result[RESULT_FIELD_ERROR]),
50
+ result[RESULT_FIELD_ERROR_V2] as Record<string, unknown> | undefined,
51
+ ),
52
+ )
53
+ }
54
+ const vals = result[RESULT_FIELD_VALUES]
55
+ if (!vals) {
56
+ return acc.concat(new DataResult(result))
57
+ }
58
+ const dataResults = vals.map((_v, valuesIndex) => new DataResult(result, valuesIndex))
59
+ return acc.concat(dataResults)
60
+ }, [])
61
+ }
62
+
63
+ hasError (): boolean {
64
+ return !!this.getFirstError()
65
+ }
66
+
67
+ getFirstError (): DataResultError | undefined {
68
+ return this.results.find((v) => v instanceof DataResultError) as DataResultError | undefined
69
+ }
70
+
71
+ getTime (): number {
72
+ return this.time
73
+ }
74
+
75
+ get (index: number): DataResult | DataResultError | undefined {
76
+ return this.results[index]
77
+ }
78
+
79
+ getResults (): Array<DataResult | DataResultError> {
80
+ return this.results
81
+ }
82
+
83
+ toArray (): Record<string, unknown>[] {
84
+ return this.results.map((result) => result.toObject())
85
+ }
86
+
87
+ toString (): string {
88
+ const list = this.results.map((result) => result.toObject())
89
+ return JSON.stringify(list)
90
+ }
91
+ }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Features for handle RQLite data api responses for success and errors
3
+ * @module api/results
4
+ */
5
+ export { default as DataResult } from './data-result.js'
6
+ export { default as DataResultError } from './data-result-error.js'
7
+ export { default as DataResults } from './data-results.js'
@@ -0,0 +1,14 @@
1
+ /**
2
+ * RQLite JSON response field name constants
3
+ * @module api/results/result-fields
4
+ * @see https://rqlite.io/docs/api/api/
5
+ */
6
+
7
+ export const RESULT_FIELD_TIME = 'time'
8
+ export const RESULT_FIELD_ROWS_AFFECTED = 'rows_affected'
9
+ export const RESULT_FIELD_LAST_INSERT_ID = 'last_insert_id'
10
+ export const RESULT_FIELD_COLUMNS = 'columns'
11
+ export const RESULT_FIELD_VALUES = 'values'
12
+ export const RESULT_FIELD_ERROR = 'error'
13
+ export const RESULT_FIELD_ERROR_V2 = 'error_v2'
14
+ export const RESULT_FIELD_RESULTS = 'results'
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Status api client to perform RQLite status and diagnostics operations
3
+ * @module api/status
4
+ * @see https://rqlite.io/docs/guides/monitoring-rqlite/
5
+ */
6
+ import ApiClient from '../client/index.js'
7
+ import type { HttpResponse } from '../../http-request/index.js'
8
+ import { HTTP_METHOD_GET } from '../../http-request/http-methods.js'
9
+ import { PATH_STATUS } from '../paths.js'
10
+
11
+ export { PATH_STATUS } from '../paths.js'
12
+
13
+ export type StatusRequestOptions = {
14
+ raw?: boolean
15
+ attemptHostIndex?: number
16
+ useLeader?: boolean
17
+ }
18
+
19
+ export type StatusAllHostsResponse = {
20
+ response: HttpResponse
21
+ host: string
22
+ }
23
+
24
+ /**
25
+ * Data api client to perform RQLite status queries
26
+ */
27
+ export default class StatusApiClient extends ApiClient {
28
+ /**
29
+ * Get the RQLite server status which defaults to the leader host
30
+ * @see https://rqlite.io/docs/guides/monitoring-rqlite/
31
+ */
32
+ async status (options: StatusRequestOptions = {}): Promise<HttpResponse> {
33
+ return this.fetch({
34
+ ...options,
35
+ uri: PATH_STATUS,
36
+ httpMethod: HTTP_METHOD_GET,
37
+ useLeader: typeof options.useLeader === 'boolean' ? options.useLeader : true,
38
+ }) as Promise<HttpResponse>
39
+ }
40
+
41
+ /**
42
+ * Get the RQLite server status for all hosts
43
+ * @see https://rqlite.io/docs/guides/monitoring-rqlite/
44
+ */
45
+ async statusAllHosts (options: StatusRequestOptions = {}): Promise<StatusAllHostsResponse[]> {
46
+ const hosts = this.getHosts()
47
+ const promises = hosts.map(async (_host, attemptHostIndex) => {
48
+ const response = await this.status({ ...options, useLeader: false, attemptHostIndex })
49
+ return { response, host: hosts[attemptHostIndex] }
50
+ })
51
+ return Promise.all(promises)
52
+ }
53
+ }
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Authentication Map key constants
3
+ * @module http-request/auth-keys
4
+ */
5
+
6
+ /**
7
+ * Username key for authentication
8
+ */
9
+ export const AUTH_USERNAME = 'username'
10
+
11
+ /**
12
+ * Password key for authentication
13
+ */
14
+ export const AUTH_PASSWORD = 'password'
@@ -0,0 +1,4 @@
1
+ export const CONTENT_TYPE_TEXT_PLAIN = 'text/plain'
2
+ export const CONTENT_TYPE_APPLICATION_JSON = 'application/json'
3
+ export const CONTENT_TYPE_APPLICATION_X_WWW_FORM_URLENCODED = 'application/x-www-form-urlencoded'
4
+ export const CONTENT_TYPE_APPLICATION_OCTET_STREAM = 'application/octet-stream'
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Http request errors
3
+ * @module http-request/errors
4
+ */
5
+
6
+ /**
7
+ * Error when max redirect attempts have been reached
8
+ */
9
+ export class ERROR_HTTP_REQUEST_MAX_REDIRECTS extends Error {
10
+ code: string
11
+
12
+ constructor (...args: ConstructorParameters<typeof Error>) {
13
+ super(...args)
14
+ this.name = this.constructor.name
15
+ this.code = this.constructor.name
16
+ }
17
+ }
@@ -0,0 +1,19 @@
1
+ /**
2
+ * HTTP header name constants used by RQLite clients
3
+ * @module http-request/http-headers
4
+ */
5
+
6
+ /**
7
+ * Accept request header
8
+ */
9
+ export const HTTP_HEADER_ACCEPT = 'Accept'
10
+
11
+ /**
12
+ * Content-Type request header
13
+ */
14
+ export const HTTP_HEADER_CONTENT_TYPE = 'Content-Type'
15
+
16
+ /**
17
+ * Location response header (redirects)
18
+ */
19
+ export const HTTP_HEADER_LOCATION = 'Location'
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Http methods
3
+ * @module http-request/http-methods
4
+ */
5
+
6
+ export const HTTP_METHOD_DELETE = 'DELETE'
7
+ export const HTTP_METHOD_GET = 'GET'
8
+ export const HTTP_METHOD_HEAD = 'HEAD'
9
+ export const HTTP_METHOD_OPTIONS = 'OPTIONS'
10
+ export const HTTP_METHOD_PATCH = 'PATCH'
11
+ export const HTTP_METHOD_POST = 'POST'
12
+ export const HTTP_METHOD_PUT = 'PUT'