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
package/src/index.ts ADDED
@@ -0,0 +1,38 @@
1
+ /**
2
+ * RQLite JS client which export all of the api clients
3
+ * @module rqlite-js
4
+ * @see https://rqlite.io/docs/api/api/
5
+ */
6
+ import DataApiClient from './api/data/index.js'
7
+ import BackupApiClient from './api/backup/index.js'
8
+ import StatusApiClient from './api/status/index.js'
9
+
10
+ export {
11
+ DataApiClient,
12
+ BackupApiClient,
13
+ StatusApiClient,
14
+ }
15
+
16
+ export {
17
+ PATH_QUERY,
18
+ PATH_EXECUTE,
19
+ CONSISTENCY_LEVEL_NONE,
20
+ CONSISTENCY_LEVEL_STRONG,
21
+ CONSISTENCY_LEVEL_LINEARIZABLE,
22
+ CONSISTENCY_LEVEL_WEAK,
23
+ } from './api/data/index.js'
24
+
25
+ export {
26
+ PATH_BACKUP,
27
+ PATH_LOAD,
28
+ BACKUP_DATA_FORMAT_SQL,
29
+ BACKUP_DATA_FORMAT_DUMP,
30
+ } from './api/backup/index.js'
31
+
32
+ export { PATH_STATUS } from './api/status/index.js'
33
+
34
+ export default {
35
+ DataApiClient,
36
+ BackupApiClient,
37
+ StatusApiClient,
38
+ }
package/.eslintrc DELETED
@@ -1,20 +0,0 @@
1
- {
2
- "env": {
3
- "node": true,
4
- "mocha": true
5
- },
6
- "extends": "airbnb-base",
7
- "plugins": [
8
- "mocha",
9
- "babel"
10
- ],
11
- "rules": {
12
- "import/no-extraneous-dependencies": ["error", { "devDependencies": true }],
13
- "mocha/no-exclusive-tests": "error",
14
- "object-curly-newline": 0,
15
- "object-curly-spacing": [2, "always"],
16
- "semi": [2, "never"],
17
- "space-before-function-paren": [2, "always"]
18
- },
19
- "parser": "@babel/eslint-parser"
20
- }
package/.travis.yml DELETED
@@ -1,24 +0,0 @@
1
- sudo: required
2
-
3
- services:
4
- - docker
5
-
6
- language: node_js
7
-
8
- node_js:
9
- - "14"
10
-
11
- cache:
12
- directories:
13
- - "node_modules"
14
-
15
- before_install:
16
- - docker pull rqlite/rqlite:5.12.1
17
- - docker run -d -p 4001:4001 -p 4002:4002 --name=rqlite-js rqlite/rqlite:5.12.1
18
-
19
- script:
20
- - npm run build-all
21
- - npm run test-build -- --reporter tap
22
- - npm run test-build-integrations -- --reporter tap
23
- - docker stop rqlite-js
24
- - docker rm rqlite-js
@@ -1,71 +0,0 @@
1
- /**
2
- * Backup api client to perform RQLite back and load operations
3
- * @module api/backup
4
- */
5
- import HttpRequest from '../../http-request'
6
- import { CONTENT_TYPE_APPLICATION_OCTET_STREAM, CONTENT_TYPE_TEXT_PLAIN } from '../../http-request/content-types'
7
-
8
- /**
9
- * The RQLite load api path
10
- */
11
- export const PATH_LOAD = '/db/load'
12
-
13
- /**
14
- * The RQLite backup api path
15
- */
16
- export const PATH_BACKUP = '/db/backup'
17
-
18
- /**
19
- * Use plain SQL dump as the back up format
20
- */
21
- export const BACKUP_DATA_FORMAT_SQL = 'sql'
22
-
23
- /**
24
- * Use sqlite3 dump as the back up format
25
- */
26
- export const BACKUP_DATA_FORMAT_DUMP = 'dump'
27
-
28
- /**
29
- * Backup api client to perform RQLite back up and load operations
30
- */
31
- export default class BackupApiClient extends HttpRequest {
32
- /**
33
- * Perform a SQL dump backup from the RQLite server
34
- * @param {String} [format=BACKUP_DATA_FORMAT_DUMP] The backup data format
35
- * @returns {Stream} The response stream
36
- */
37
- async backup (format = BACKUP_DATA_FORMAT_DUMP) {
38
- const stream = super.get({
39
- headers: {
40
- // Always sends application/octet-stream from the server in RQLite v4.x
41
- Accept: CONTENT_TYPE_APPLICATION_OCTET_STREAM,
42
- },
43
- query: { fmt: format === BACKUP_DATA_FORMAT_SQL ? format : undefined },
44
- json: false,
45
- stream: true,
46
- uri: PATH_BACKUP,
47
- useLeader: true,
48
- })
49
- return stream
50
- }
51
-
52
- /**
53
- * Perform a SQL restore by sending data the RQLite server
54
- * @param {Buffer|String} data The data to be loaded
55
- * @param {String} [format=BACKUP_DATA_FORMAT_SQL] The backup data format
56
- * @returns {Stream} The response stream
57
- */
58
- async load (data, format = BACKUP_DATA_FORMAT_SQL) {
59
- return super.post({
60
- body: data,
61
- headers: {
62
- // eslint-disable-next-line max-len
63
- 'Content-Type': format === BACKUP_DATA_FORMAT_SQL ? CONTENT_TYPE_TEXT_PLAIN : CONTENT_TYPE_APPLICATION_OCTET_STREAM,
64
- },
65
- json: false,
66
- stream: true,
67
- uri: PATH_LOAD,
68
- useLeader: true,
69
- })
70
- }
71
- }
@@ -1,83 +0,0 @@
1
- /**
2
- * Base API client for RQLite which abstracts the HTTP calls
3
- * @module api/client
4
- */
5
- import HttpRequest from '../../http-request'
6
- import { HTTP_METHOD_GET, HTTP_METHOD_POST } from '../../http-request/http-methods'
7
-
8
- /**
9
- * @typedef HttpRequestOptions
10
- * @type {import('../../http-request').HttpRequestOptions}
11
- */
12
-
13
- /**
14
- * Create the base HTTP query options from RQLite API options
15
- * @param {Object} [options={}] The RQLite API options
16
- * @param {String} [options.level] The consistency level
17
- * @param {String} [options.pretty] Pretty print the response body
18
- * @param {String} [options.timings] Provide query timings
19
- * @param {String} [options.atomic] Treat all commands in the request as a single transaction
20
- * for RQLite v5 and higher
21
- * @param {String} [options.transaction] Treat all commands in the request as a single transaction
22
- * for RQLite v4 and lower
23
- * @returns {Object} The HTTP query
24
- */
25
- export function createQuery (options = {}) {
26
- const { level, pretty, timings, atomic, transaction } = options
27
-
28
- // Remove all undefined values
29
- const query = { level, pretty, timings, atomic, transaction }
30
- return Object.entries(query).reduce((acc, entry) => {
31
- const [key, val] = entry
32
- // Only take defined values
33
- if (typeof val !== 'undefined') {
34
- acc[key] = val
35
- }
36
- return acc
37
- }, {})
38
- }
39
-
40
- /**
41
- * Base API client for RQLite which abstracts the HTTP calls
42
- * from the user
43
- */
44
- export default class ApiClient extends HttpRequest {
45
- /**
46
- * Perform a RQLite data API get request
47
- * @param {String} path The path for the request i.e. /db/query
48
- * @param {String} sql The SQL query
49
- * @param {HttpRequestOptions} [options={}] RQLite API options
50
- */
51
- async get (path, sql, options = {}) {
52
- const { useLeader } = options
53
- if (!path) {
54
- throw new Error('The path argument is required')
55
- }
56
- return super.get({
57
- useLeader,
58
- uri: path,
59
- httpMethod: HTTP_METHOD_GET,
60
- query: { ...createQuery(options), q: sql },
61
- })
62
- }
63
-
64
- /**
65
- * Perform a RQLite data API post request
66
- * @param {String} path The path for the request i.e. /db/query
67
- * @param {String} sql The SQL query
68
- * @param {HttpRequestOptions} [options={}] RQLite API options
69
- */
70
- async post (path, sql, options = {}) {
71
- const { useLeader } = options
72
- if (!path) {
73
- throw new Error('The path argument is required')
74
- }
75
- return super.post({
76
- useLeader,
77
- uri: path,
78
- httpMethod: HTTP_METHOD_POST,
79
- query: createQuery(options),
80
- body: Array.isArray(sql) ? sql : [sql],
81
- })
82
- }
83
- }
@@ -1,129 +0,0 @@
1
- /**
2
- * Data api client to perform RQLite data operations such
3
- * as query and execute
4
- * @module api/data
5
- */
6
- import ApiClient from '../client'
7
- import { DataResults } from '../results'
8
-
9
- /**
10
- * The RQLite query api path
11
- */
12
- export const PATH_QUERY = '/db/query'
13
-
14
- /**
15
- * The RQLite execute api path
16
- */
17
- export const PATH_EXECUTE = '/db/execute'
18
-
19
- /**
20
- * Read query consistency level none which means
21
- * any node can respond
22
- */
23
- export const CONSISTENCY_LEVEL_NONE = 'none'
24
-
25
- /**
26
- * Read query consistency strong which must come from
27
- * the master node
28
- */
29
- export const CONSISTENCY_LEVEL_STRONG = 'strong'
30
-
31
- /**
32
- * Read query consistency linearizable which must come from
33
- * the master node
34
- */
35
- export const CONSISTENCY_LEVEL_LINEARIZABLE = 'linearizable'
36
-
37
- /**
38
- * Read query consistency weak which must come from
39
- * the master node
40
- */
41
- export const CONSISTENCY_LEVEL_WEAK = 'weak'
42
-
43
- /**
44
- * @typedef HttpRequestOptions
45
- * @type {import('../../http-request').HttpRequestOptions}
46
- */
47
-
48
- /**
49
- * Data request base options
50
- * @typedef DataRequestBaseOptions
51
- * @type {Object}
52
- * @property {Boolean} [raw] If true return the raw http response from
53
- * RQLite response
54
- */
55
-
56
- /**
57
- * Data query request base options
58
- * @typedef QueryRequestBaseOptions
59
- * @type {Object}
60
- * @property {String} level The api consistency level
61
- */
62
-
63
- /**
64
- * Data query request options
65
- * @typedef QueryRequestOptions
66
- * @type {HttpRequestOptions & DataRequestBaseOptions & QueryRequestBaseOptions}
67
- */
68
-
69
- /**
70
- * Data execute request options
71
- * @typedef ExecuteRequestOptions
72
- * @type {HttpRequestOptions & DataRequestBaseOptions}
73
- */
74
-
75
- /**
76
- * Send an RQLite query API request to the RQLite server
77
- * @param {String} sql The SQL string to excute on the server
78
- * @param {DataRequestBaseOptions} [options={}] RQLite api options
79
- */
80
- function handleResponse (response, options = {}) {
81
- const { raw } = options
82
- const { body } = response
83
- if (raw) {
84
- return response
85
- }
86
- return new DataResults(body)
87
- }
88
-
89
- /**
90
- * Data api client to perform RQLite queries
91
- */
92
- export default class DataApiClient extends ApiClient {
93
- /**
94
- * Send an RQLite query API request to the RQLite server
95
- * @param {String} sql The SQL string to excute on the server
96
- * @param {QueryRequestOptions} [options={}] RQLite api options
97
- */
98
- async query (sql, options = {}) {
99
- const { level } = options
100
- let { useLeader } = options
101
- // Weak and strong consistency will be redirect to the master anyway
102
- // so skip the redirect HTTP response and got right to the master
103
- if (level !== CONSISTENCY_LEVEL_NONE) {
104
- useLeader = true
105
- }
106
- let response
107
- if (Array.isArray(sql)) {
108
- response = await super.post(PATH_QUERY, sql, { ...options, useLeader })
109
- } else {
110
- response = await super.get(PATH_QUERY, sql, { ...options, useLeader })
111
- }
112
- // If round robin is true try and balance selects across hosts when
113
- // the master node is not queried directly
114
- if (!useLeader) {
115
- this.setNextActiveHostIndex()
116
- }
117
- return handleResponse(response, options)
118
- }
119
-
120
- /**
121
- * Send an RQLite execute API request to the RQLite server
122
- * @param {String} sql The SQL string to excute on the server
123
- * @param {ExecuteRequestOptions} [options={}] RQLite execute api options
124
- */
125
- async execute (sql, options = {}) {
126
- const response = await super.post(PATH_EXECUTE, sql, options)
127
- return handleResponse(response, options)
128
- }
129
- }
@@ -1,32 +0,0 @@
1
- /**
2
- * Class for handling RQLite data api result error
3
- * @module api/results/data-results
4
- */
5
-
6
- /**
7
- * A class that represents one data error result from an RQLite query or execute
8
- * API call
9
- */
10
- export default class DataResultError extends Error {
11
- constructor (...args) {
12
- super(...args)
13
- this.name = this.constructor.name
14
- this.code = this.constructor.name
15
- }
16
-
17
- /**
18
- * Get the result data error as plain object
19
- * @returns {Object} The data as an object
20
- */
21
- toObject () {
22
- return { error: this.message }
23
- }
24
-
25
- /**
26
- * Convert the result data error to a JSON string
27
- * @returns {String} The JSON string for the data object
28
- */
29
- toString () {
30
- return JSON.stringify(this.toObject())
31
- }
32
- }
@@ -1,134 +0,0 @@
1
- /**
2
- * Class for handling single RQLite data api result
3
- * @module api/results/data-result
4
- */
5
-
6
- /**
7
- * A class that represents one data result from an RQLite query or execute
8
- * API call
9
- */
10
- export default class DataResult {
11
- /**
12
- * The time the results query took to complete
13
- * @type {Number}
14
- */
15
- time = 0.0
16
-
17
- /**
18
- * The last insert id
19
- * @type {Number}
20
- */
21
- lastInsertId
22
-
23
- /**
24
- * The rows affected
25
- * @type {Number}
26
- */
27
- rowsAffected = 0
28
-
29
- /**
30
- * An array of DataResult and/or DataResultError instances
31
- * @type {Array<DataResult|DataResultError>}
32
- */
33
- results = []
34
-
35
- /**
36
- * An object after the columns and values are mapped from
37
- * an RQLite response
38
- */
39
- data = {}
40
-
41
- /**
42
- * The data result constructor
43
- * @param {Array} result An API response individual result
44
- * @param {Array} [valuesIndex] The index to get the values from the result
45
- */
46
- constructor (result, valuesIndex) {
47
- if (typeof result !== 'object') {
48
- throw new Error('The result argument is required to be an object')
49
- }
50
- if (typeof valuesIndex !== 'undefined' && !Number.isFinite(valuesIndex)) {
51
- throw new Error('The valuesIndex argument is required to be a finite number when provided')
52
- }
53
- this.time = parseFloat(result.time || 0.0)
54
- this.rowsAffected = parseInt(result.rows_affected || 0, 10)
55
- this.lastInsertId = result.last_insert_id
56
- // Map the values array to an object where columns are the properties
57
- if (Number.isFinite(valuesIndex)) {
58
- const { columns } = result
59
- const resultValues = result.values[valuesIndex]
60
- if (resultValues) {
61
- this.data = resultValues.reduce((acc, val, i) => {
62
- const col = columns[i]
63
- acc[col] = val
64
- return acc
65
- }, {})
66
- }
67
- }
68
- }
69
-
70
- /**
71
- * Return the value a property or undefined if it does not exist
72
- * @returns {*} The value of the property or undefined
73
- */
74
- get (property) {
75
- return this.data[property]
76
- }
77
-
78
- /**
79
- * Get the time the result took
80
- * @returns {Number} The time the query took
81
- */
82
- getTime () {
83
- return this.time
84
- }
85
-
86
- /**
87
- * Get the last insert id
88
- * @returns {Number|undefined}
89
- */
90
- getLastInsertId () {
91
- return this.lastInsertId
92
- }
93
-
94
- /**
95
- * Get the row affected
96
- * @returns {Number|undefined}
97
- */
98
- getRowsAffected () {
99
- return this.rowsAffected
100
- }
101
-
102
- /**
103
- * Get the result data as plain object
104
- * @returns {Object} The data as an object
105
- */
106
- toObject () {
107
- // Clone deep
108
- return JSON.parse(JSON.stringify(this.data))
109
- }
110
-
111
- /**
112
- * Map the data values to an array
113
- * @returns {Array}
114
- */
115
- toArray () {
116
- return Object.values(this.data)
117
- }
118
-
119
- /**
120
- * Map the data properites to an array
121
- * @returns {String[]}
122
- */
123
- toColumnsArray () {
124
- return Object.keys(this.data)
125
- }
126
-
127
- /**
128
- * Convert the result data to a JSON string
129
- * @returns {String} The JSON string for the data object
130
- */
131
- toString () {
132
- return JSON.stringify(this.data)
133
- }
134
- }
@@ -1,121 +0,0 @@
1
- /**
2
- * Class for handling many RQLite data api results
3
- * @module api/results/data-results
4
- */
5
- import DataResult from './data-result'
6
- import DataResultError from './data-result-error'
7
-
8
- /**
9
- * A class to manage a list of results from an RQLite query or execute API response
10
- */
11
- export default class DataResults {
12
- /**
13
- * The time the results took to return from the
14
- * RQLite api
15
- * @type {Number}
16
- */
17
- time = 0.0
18
-
19
- /**
20
- * The results which is an empty arry to start
21
- * @type {DataResult[]}
22
- */
23
- results = []
24
-
25
- /**
26
- * The data result list constructor
27
- * @param {Object} data The data object sent from a RQLite API response
28
- * @param {Number} data.time The time the API response took to complete
29
- * @param {Object[{error:String,values:Object}]} data.results The results array
30
- */
31
- constructor (data) {
32
- this.setApiData(data)
33
- }
34
-
35
- /**
36
- * Set the api as results
37
- * @param {Object} data Api data
38
- */
39
- setApiData (data) {
40
- if (typeof data !== 'object') {
41
- throw new Error('The data argument is required to be an object')
42
- }
43
- if (!data.results) {
44
- throw new Error('The data object is required to have a results property')
45
- }
46
- this.time = parseFloat(data.time || 0.0)
47
- const { results = [] } = data
48
- this.results = results.reduce((acc, result) => {
49
- // If there is an error property this is an error
50
- if (typeof result === 'object' && result.error) {
51
- return acc.concat(new DataResultError(result.error))
52
- }
53
- const { values: vals } = result
54
- // We don't have values so this is a single result row
55
- if (!vals) {
56
- return acc.concat(new DataResult(result))
57
- }
58
- // Map the values to DataResult instances
59
- const dataResults = vals.map((_v, valuesIndex) => new DataResult(result, valuesIndex))
60
- return acc.concat(dataResults)
61
- }, [])
62
- }
63
-
64
- /**
65
- * Returns true if an instance of DataResultError exists in the results
66
- * @returns {Boolean} True if a DataResultError instance exists
67
- */
68
- hasError () {
69
- return !!this.getFirstError()
70
- }
71
-
72
- /**
73
- * Get the first error that occured
74
- * @returns {DataResultError|undefined}
75
- */
76
- getFirstError () {
77
- return this.results.find((v) => v instanceof DataResultError)
78
- }
79
-
80
- /**
81
- * Get the time the results took
82
- * @returns {Number} The time the query took
83
- */
84
- getTime () {
85
- return this.time
86
- }
87
-
88
- /**
89
- * Return one result at a specific index or undefined it it does not exist
90
- * @returns {DataResult|DataResultError|undefined}
91
- */
92
- get (index) {
93
- return this.results[index]
94
- }
95
-
96
- /**
97
- * Return the results array
98
- * @returns {Array<DataResult|DataResultError>}
99
- */
100
- getResults () {
101
- return this.results
102
- }
103
-
104
- /**
105
- * Get the result data list as array of plain objects
106
- * @returns {Object[]} The data as an array or objects
107
- */
108
- toArray () {
109
- return this.results.map((result) => result.toObject())
110
- }
111
-
112
- /**
113
- * Convert the result data list to a JSON string that is an
114
- * array of objects
115
- * @returns {String} A JSON string
116
- */
117
- toString () {
118
- const list = this.results.map((result) => result.toObject())
119
- return JSON.stringify(list)
120
- }
121
- }
@@ -1,7 +0,0 @@
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'
6
- export { default as DataResultError } from './data-result-error'
7
- export { default as DataResults } from './data-results'