2
2
// utilities.ts - utility methods to manipulate SQL statements
3
3
//
4
4
5
- import { SQLiteCloudConfig , SQLiteCloudError , SQLiteCloudDataTypes , DEFAULT_PORT , DEFAULT_TIMEOUT } from './types'
6
- import { SQLiteCloudArrayType } from './types'
5
+ import { DEFAULT_PORT , DEFAULT_TIMEOUT , SQLiteCloudArrayType , SQLiteCloudConfig , SQLiteCloudDataTypes , SQLiteCloudError } from './types'
7
6
8
7
// explicitly importing these libraries to allow cross-platform support by replacing them
9
8
import { URL } from 'whatwg-url'
10
- import { Buffer } from 'buffer'
11
9
12
10
//
13
11
// determining running environment, thanks to browser-or-node
@@ -42,45 +40,47 @@ export function anonimizeError(error: Error): Error {
42
40
export function getInitializationCommands ( config : SQLiteCloudConfig ) : string {
43
41
// we check the credentials using non linearizable so we're quicker
44
42
// then we bring back linearizability unless specified otherwise
45
- let commands = 'SET CLIENT KEY NONLINEARIZABLE TO 1; '
43
+ let commands = 'SET CLIENT KEY NONLINEARIZABLE TO 1;'
46
44
47
45
// first user authentication, then all other commands
48
46
if ( config . apikey ) {
49
- commands += `AUTH APIKEY ${ config . apikey } ; `
47
+ commands += `AUTH APIKEY ${ config . apikey } ;`
48
+ } else if ( config . token ) {
49
+ commands += `AUTH TOKEN ${ config . token } ;`
50
50
} else {
51
- commands += `AUTH USER ${ config . username || '' } ${ config . password_hashed ? 'HASH' : 'PASSWORD' } ${ config . password || '' } ; `
51
+ commands += `AUTH USER ${ config . username || '' } ${ config . password_hashed ? 'HASH' : 'PASSWORD' } ${ config . password || '' } ;`
52
52
}
53
53
54
54
if ( config . compression ) {
55
- commands += 'SET CLIENT KEY COMPRESSION TO 1; '
55
+ commands += 'SET CLIENT KEY COMPRESSION TO 1;'
56
56
}
57
57
if ( config . zerotext ) {
58
- commands += 'SET CLIENT KEY ZEROTEXT TO 1; '
58
+ commands += 'SET CLIENT KEY ZEROTEXT TO 1;'
59
59
}
60
60
if ( config . noblob ) {
61
- commands += 'SET CLIENT KEY NOBLOB TO 1; '
61
+ commands += 'SET CLIENT KEY NOBLOB TO 1;'
62
62
}
63
63
if ( config . maxdata ) {
64
- commands += `SET CLIENT KEY MAXDATA TO ${ config . maxdata } ; `
64
+ commands += `SET CLIENT KEY MAXDATA TO ${ config . maxdata } ;`
65
65
}
66
66
if ( config . maxrows ) {
67
- commands += `SET CLIENT KEY MAXROWS TO ${ config . maxrows } ; `
67
+ commands += `SET CLIENT KEY MAXROWS TO ${ config . maxrows } ;`
68
68
}
69
69
if ( config . maxrowset ) {
70
- commands += `SET CLIENT KEY MAXROWSET TO ${ config . maxrowset } ; `
70
+ commands += `SET CLIENT KEY MAXROWSET TO ${ config . maxrowset } ;`
71
71
}
72
72
73
73
// we ALWAYS set non linearizable to 1 when we start so we can be quicker on login
74
74
// but then we need to put it back to its default value if "linearizable" unless set
75
75
if ( ! config . non_linearizable ) {
76
- commands += 'SET CLIENT KEY NONLINEARIZABLE TO 0; '
76
+ commands += 'SET CLIENT KEY NONLINEARIZABLE TO 0;'
77
77
}
78
78
79
79
if ( config . database ) {
80
80
if ( config . create && ! config . memory ) {
81
- commands += `CREATE DATABASE ${ config . database } IF NOT EXISTS; `
81
+ commands += `CREATE DATABASE ${ config . database } IF NOT EXISTS;`
82
82
}
83
- commands += `USE DATABASE ${ config . database } ; `
83
+ commands += `USE DATABASE ${ config . database } ;`
84
84
}
85
85
86
86
return commands
@@ -109,13 +109,12 @@ export function getUpdateResults(results?: any): Record<string, any> | undefined
109
109
switch ( results [ 0 ] ) {
110
110
case SQLiteCloudArrayType . ARRAY_TYPE_SQLITE_EXEC :
111
111
return {
112
- type : results [ 0 ] ,
113
- index : results [ 1 ] ,
112
+ type : Number ( results [ 0 ] ) ,
113
+ index : Number ( results [ 1 ] ) ,
114
114
lastID : results [ 2 ] , // ROWID (sqlite3_last_insert_rowid)
115
115
changes : results [ 3 ] , // CHANGES(sqlite3_changes)
116
116
totalChanges : results [ 4 ] , // TOTAL_CHANGES (sqlite3_total_changes)
117
- finalized : results [ 5 ] , // FINALIZED
118
- //
117
+ finalized : Number ( results [ 5 ] ) , // FINALIZED
119
118
rowId : results [ 2 ] // same as lastId
120
119
}
121
120
}
@@ -177,16 +176,19 @@ export function validateConfiguration(config: SQLiteCloudConfig): SQLiteCloudCon
177
176
config . non_linearizable = parseBoolean ( config . non_linearizable )
178
177
config . insecure = parseBoolean ( config . insecure )
179
178
180
- const hasCredentials = ( config . username && config . password ) || config . apikey
179
+ const hasCredentials = ( config . username && config . password ) || config . apikey || config . token
181
180
if ( ! config . host || ! hasCredentials ) {
182
181
console . error ( 'SQLiteCloudConnection.validateConfiguration - missing arguments' , config )
183
- throw new SQLiteCloudError ( 'The user, password and host arguments or the ?apikey = must be specified.' , { errorCode : 'ERR_MISSING_ARGS' } )
182
+ throw new SQLiteCloudError ( 'The user, password and host arguments, the ?apikey= or the ?token = must be specified.' , { errorCode : 'ERR_MISSING_ARGS' } )
184
183
}
185
184
186
185
if ( ! config . connectionstring ) {
187
186
// build connection string from configuration, values are already validated
187
+ config . connectionstring = `sqlitecloud://${ config . host } :${ config . port } /${ config . database || '' } `
188
188
if ( config . apikey ) {
189
- config . connectionstring = `sqlitecloud://${ config . host } :${ config . port } /${ config . database || '' } ?apikey=${ config . apikey } `
189
+ config . connectionstring += `?apikey=${ config . apikey } `
190
+ } else if ( config . token ) {
191
+ config . connectionstring += `?token=${ config . token } `
190
192
} else {
191
193
config . connectionstring = `sqlitecloud://${ encodeURIComponent ( config . username || '' ) } :${ encodeURIComponent ( config . password || '' ) } @${ config . host } :${
192
194
config . port
@@ -215,13 +217,13 @@ export function parseconnectionstring(connectionstring: string): SQLiteCloudConf
215
217
// all lowecase options
216
218
const options : { [ key : string ] : string } = { }
217
219
url . searchParams . forEach ( ( value , key ) => {
218
- options [ key . toLowerCase ( ) . replace ( / - / g, '_' ) ] = value
220
+ options [ key . toLowerCase ( ) . replace ( / - / g, '_' ) ] = value . trim ( )
219
221
} )
220
222
221
223
const config : SQLiteCloudConfig = {
222
224
...options ,
223
- username : decodeURIComponent ( url . username ) ,
224
- password : decodeURIComponent ( url . password ) ,
225
+ username : url . username ? decodeURIComponent ( url . username ) : undefined ,
226
+ password : url . password ? decodeURIComponent ( url . password ) : undefined ,
225
227
password_hashed : options . password_hashed ? parseBoolean ( options . password_hashed ) : undefined ,
226
228
host : url . hostname ,
227
229
// type cast values
@@ -241,13 +243,10 @@ export function parseconnectionstring(connectionstring: string): SQLiteCloudConf
241
243
verbose : options . verbose ? parseBoolean ( options . verbose ) : undefined
242
244
}
243
245
244
- // either you use an apikey or username and password
245
- if ( config . apikey ) {
246
- if ( config . username || config . password ) {
247
- console . warn ( 'SQLiteCloudConnection.parseconnectionstring - apikey and username/password are both specified, using apikey' )
248
- }
249
- delete config . username
250
- delete config . password
246
+ // either you use an apikey, token or username and password
247
+ if ( Number ( ! ! config . apikey ) + Number ( ! ! config . token ) + Number ( ! ! ( config . username || config . password ) ) > 1 ) {
248
+ console . error ( 'SQLiteCloudConnection.parseconnectionstring - choose between apikey, token or username/password' )
249
+ throw new SQLiteCloudError ( 'Choose between apikey, token or username/password' )
251
250
}
252
251
253
252
const database = url . pathname . replace ( '/' , '' ) // pathname is database name, remove the leading slash
@@ -257,7 +256,7 @@ export function parseconnectionstring(connectionstring: string): SQLiteCloudConf
257
256
258
257
return config
259
258
} catch ( error ) {
260
- throw new SQLiteCloudError ( `Invalid connection string: ${ connectionstring } ` )
259
+ throw new SQLiteCloudError ( `Invalid connection string: ${ connectionstring } - error: ${ error } ` )
261
260
}
262
261
}
263
262
0 commit comments