@sqlitecloud/drivers 1.0.715 → 1.0.738-rc.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.
- package/README.md +10 -3
- package/lib/drivers/connection-tls.js +24 -42
- package/lib/drivers/protocol.d.ts +0 -1
- package/lib/drivers/protocol.js +20 -17
- package/lib/drivers/safe-imports.d.ts +31 -0
- package/lib/drivers/safe-imports.js +87 -0
- package/lib/drivers/utilities.js +5 -2
- package/lib/sqlitecloud.drivers.dev.js +15 -4
- package/lib/sqlitecloud.drivers.js +1 -1
- package/package.json +15 -1
package/README.md
CHANGED
|
@@ -8,18 +8,25 @@
|
|
|
8
8
|
|
|
9
9
|
## Install
|
|
10
10
|
|
|
11
|
+
### Web / Node.js / Next.js
|
|
12
|
+
|
|
11
13
|
```bash
|
|
12
14
|
npm install @sqlitecloud/drivers
|
|
13
15
|
```
|
|
14
16
|
|
|
15
|
-
|
|
17
|
+
No additional dependencies required - the package works out of the box.
|
|
18
|
+
|
|
19
|
+
### React Native / Expo
|
|
16
20
|
|
|
17
|
-
|
|
21
|
+
When using this package in React Native or Expo projects, you must install the required peer dependencies. These dependencies are optional and not installed automatically to avoid polluting web and Node.js projects with unnecessary packages.
|
|
18
22
|
|
|
19
23
|
```bash
|
|
20
|
-
npm install @sqlitecloud/drivers
|
|
24
|
+
npm install @sqlitecloud/drivers
|
|
25
|
+
npm install react-native-tcp-socket react-native-quick-base64 @craftzdog/react-native-buffer react-native-url-polyfill
|
|
21
26
|
```
|
|
22
27
|
|
|
28
|
+
If you forget to install these dependencies, the package will throw clear error messages indicating which dependency is missing and how to install it.
|
|
29
|
+
|
|
23
30
|
React Native run iOS
|
|
24
31
|
|
|
25
32
|
```bash
|
|
@@ -2,48 +2,21 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* connection-tls.ts - connection via tls socket and sqlitecloud protocol
|
|
4
4
|
*/
|
|
5
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
6
|
-
if (k2 === undefined) k2 = k;
|
|
7
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
8
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
9
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
10
|
-
}
|
|
11
|
-
Object.defineProperty(o, k2, desc);
|
|
12
|
-
}) : (function(o, m, k, k2) {
|
|
13
|
-
if (k2 === undefined) k2 = k;
|
|
14
|
-
o[k2] = m[k];
|
|
15
|
-
}));
|
|
16
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
17
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
18
|
-
}) : function(o, v) {
|
|
19
|
-
o["default"] = v;
|
|
20
|
-
});
|
|
21
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
22
|
-
var ownKeys = function(o) {
|
|
23
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
24
|
-
var ar = [];
|
|
25
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
26
|
-
return ar;
|
|
27
|
-
};
|
|
28
|
-
return ownKeys(o);
|
|
29
|
-
};
|
|
30
|
-
return function (mod) {
|
|
31
|
-
if (mod && mod.__esModule) return mod;
|
|
32
|
-
var result = {};
|
|
33
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
34
|
-
__setModuleDefault(result, mod);
|
|
35
|
-
return result;
|
|
36
|
-
};
|
|
37
|
-
})();
|
|
38
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
6
|
exports.SQLiteCloudTlsConnection = void 0;
|
|
40
7
|
const connection_1 = require("./connection");
|
|
41
8
|
const protocol_1 = require("./protocol");
|
|
42
9
|
const types_1 = require("./types");
|
|
43
10
|
const utilities_1 = require("./utilities");
|
|
11
|
+
const safe_imports_1 = require("./safe-imports");
|
|
44
12
|
// explicitly importing buffer library to allow cross-platform support by replacing it
|
|
45
|
-
|
|
46
|
-
|
|
13
|
+
// In React Native: Metro resolves 'buffer' to '@craftzdog/react-native-buffer' via package.json react-native field
|
|
14
|
+
// In Web/Node: Uses standard buffer package
|
|
15
|
+
const Buffer = (0, safe_imports_1.getSafeBuffer)();
|
|
16
|
+
// In React Native: Metro resolves 'tls' to 'react-native-tcp-socket' via package.json react-native field
|
|
17
|
+
// In Node: Uses native tls module
|
|
18
|
+
// In Browser: Returns null (browser field sets tls to false)
|
|
19
|
+
const tls = (0, safe_imports_1.getSafeTLS)();
|
|
47
20
|
/**
|
|
48
21
|
* Implementation of SQLiteCloudConnection that connects to the database using specific tls APIs
|
|
49
22
|
* that connect to native sockets or tls sockets and communicates via raw, binary protocol.
|
|
@@ -55,7 +28,7 @@ class SQLiteCloudTlsConnection extends connection_1.SQLiteCloudConnection {
|
|
|
55
28
|
// onData is called when data is received, it will process the data until all data is retrieved for a response
|
|
56
29
|
// when response is complete or there's an error, finish is called to call the results callback set by processCommands...
|
|
57
30
|
// buffer to accumulate incoming data until an whole command is received and can be parsed
|
|
58
|
-
this.buffer =
|
|
31
|
+
this.buffer = Buffer.alloc(0);
|
|
59
32
|
this.startedOn = new Date();
|
|
60
33
|
this.pendingChunks = [];
|
|
61
34
|
}
|
|
@@ -66,6 +39,15 @@ class SQLiteCloudTlsConnection extends connection_1.SQLiteCloudConnection {
|
|
|
66
39
|
/* Opens a connection with the server and sends the initialization commands. Will throw in case of errors. */
|
|
67
40
|
connectTransport(config, callback) {
|
|
68
41
|
console.assert(!this.connected, 'SQLiteCloudTlsConnection.connect - connection already established');
|
|
42
|
+
// Check if tls is available (it's null in browser contexts)
|
|
43
|
+
if (!tls) {
|
|
44
|
+
const error = new types_1.SQLiteCloudError('TLS connections are not available in this environment. Use WebSocket connections instead by setting usewebsocket: true in your configuration.', { errorCode: 'ERR_TLS_NOT_AVAILABLE' });
|
|
45
|
+
if (callback) {
|
|
46
|
+
callback.call(this, error);
|
|
47
|
+
return this;
|
|
48
|
+
}
|
|
49
|
+
throw error;
|
|
50
|
+
}
|
|
69
51
|
if (this.config.verbose) {
|
|
70
52
|
console.debug(`-> connecting ${config === null || config === void 0 ? void 0 : config.host}:${config === null || config === void 0 ? void 0 : config.port}`);
|
|
71
53
|
}
|
|
@@ -106,10 +88,10 @@ class SQLiteCloudTlsConnection extends connection_1.SQLiteCloudConnection {
|
|
|
106
88
|
// disable Nagle algorithm because we want our writes to be sent ASAP
|
|
107
89
|
// https://brooker.co.za/blog/2024/05/09/nagle.html
|
|
108
90
|
this.socket.setNoDelay(true);
|
|
109
|
-
this.socket.on('data', data => {
|
|
91
|
+
this.socket.on('data', (data) => {
|
|
110
92
|
this.processCommandsData(data);
|
|
111
93
|
});
|
|
112
|
-
this.socket.on('error', error => {
|
|
94
|
+
this.socket.on('error', (error) => {
|
|
113
95
|
this.close();
|
|
114
96
|
this.processCommandsFinish(new types_1.SQLiteCloudError('Connection error', { errorCode: 'ERR_CONNECTION_ERROR', cause: error }));
|
|
115
97
|
});
|
|
@@ -140,7 +122,7 @@ class SQLiteCloudTlsConnection extends connection_1.SQLiteCloudConnection {
|
|
|
140
122
|
commands = { query: commands };
|
|
141
123
|
}
|
|
142
124
|
// reset buffer and rowset chunks, define response callback
|
|
143
|
-
this.buffer =
|
|
125
|
+
this.buffer = Buffer.alloc(0);
|
|
144
126
|
this.startedOn = new Date();
|
|
145
127
|
this.processCallback = callback;
|
|
146
128
|
this.executingCommands = commands;
|
|
@@ -173,7 +155,7 @@ class SQLiteCloudTlsConnection extends connection_1.SQLiteCloudConnection {
|
|
|
173
155
|
// append data to buffer as it arrives
|
|
174
156
|
if (data.length && data.length > 0) {
|
|
175
157
|
// console.debug(`processCommandsData - received ${data.length} bytes`)
|
|
176
|
-
this.buffer =
|
|
158
|
+
this.buffer = Buffer.concat([this.buffer, data]);
|
|
177
159
|
}
|
|
178
160
|
let dataType = (_a = this.buffer) === null || _a === void 0 ? void 0 : _a.subarray(0, 1).toString();
|
|
179
161
|
if ((0, protocol_1.hasCommandLength)(dataType)) {
|
|
@@ -194,7 +176,7 @@ class SQLiteCloudTlsConnection extends connection_1.SQLiteCloudConnection {
|
|
|
194
176
|
if (decompressResults.dataType === protocol_1.CMD_ROWSET_CHUNK) {
|
|
195
177
|
this.pendingChunks.push(decompressResults.buffer);
|
|
196
178
|
this.buffer = decompressResults.remainingBuffer;
|
|
197
|
-
this.processCommandsData(
|
|
179
|
+
this.processCommandsData(Buffer.alloc(0));
|
|
198
180
|
return;
|
|
199
181
|
}
|
|
200
182
|
else {
|
|
@@ -247,7 +229,7 @@ class SQLiteCloudTlsConnection extends connection_1.SQLiteCloudConnection {
|
|
|
247
229
|
if (this.processCallback) {
|
|
248
230
|
this.processCallback(error, result);
|
|
249
231
|
}
|
|
250
|
-
this.buffer =
|
|
232
|
+
this.buffer = Buffer.alloc(0);
|
|
251
233
|
this.pendingChunks = [];
|
|
252
234
|
}
|
|
253
235
|
/** Disconnect immediately, release connection, no events. */
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { SQLiteCloudRowset } from './rowset';
|
|
2
2
|
import { SQLiteCloudCommand, type SQLCloudRowsetMetadata, type SQLiteCloudDataTypes } from './types';
|
|
3
|
-
import { Buffer } from 'buffer';
|
|
4
3
|
export declare const CMD_STRING = "+";
|
|
5
4
|
export declare const CMD_ZEROSTRING = "!";
|
|
6
5
|
export declare const CMD_ERROR = "-";
|
package/lib/drivers/protocol.js
CHANGED
|
@@ -17,8 +17,11 @@ exports.popData = popData;
|
|
|
17
17
|
exports.formatCommand = formatCommand;
|
|
18
18
|
const rowset_1 = require("./rowset");
|
|
19
19
|
const types_1 = require("./types");
|
|
20
|
+
const safe_imports_1 = require("./safe-imports");
|
|
20
21
|
// explicitly importing buffer library to allow cross-platform support by replacing it
|
|
21
|
-
|
|
22
|
+
// In React Native: Metro resolves 'buffer' to '@craftzdog/react-native-buffer' via package.json react-native field
|
|
23
|
+
// In Web/Node: Uses standard buffer package
|
|
24
|
+
const Buffer = (0, safe_imports_1.getSafeBuffer)();
|
|
22
25
|
// https://www.npmjs.com/package/lz4js
|
|
23
26
|
const lz4 = require('lz4js');
|
|
24
27
|
// The server communicates with clients via commands defined in
|
|
@@ -70,12 +73,12 @@ function decompressBuffer(buffer) {
|
|
|
70
73
|
commandBuffer = commandBuffer.subarray(commandBuffer.indexOf(' ') + 1);
|
|
71
74
|
// extract compressed dataType
|
|
72
75
|
const dataType = commandBuffer.subarray(0, 1).toString('utf8');
|
|
73
|
-
let decompressedBuffer =
|
|
76
|
+
let decompressedBuffer = Buffer.alloc(decompressedSize);
|
|
74
77
|
const compressedBuffer = commandBuffer.subarray(commandBuffer.length - compressedSize);
|
|
75
78
|
// lz4js library is javascript and doesn't have types so we silence the type check
|
|
76
79
|
const decompressionResult = lz4.decompressBlock(compressedBuffer, decompressedBuffer, 0, compressedSize, 0);
|
|
77
80
|
// the entire command is composed of the header (which is not compressed) + the decompressed block
|
|
78
|
-
decompressedBuffer =
|
|
81
|
+
decompressedBuffer = Buffer.concat([commandBuffer.subarray(0, commandBuffer.length - compressedSize), decompressedBuffer]);
|
|
79
82
|
if (decompressionResult <= 0 || decompressionResult !== decompressedSize) {
|
|
80
83
|
throw new Error(`lz4 decompression error at offset ${decompressionResult}`);
|
|
81
84
|
}
|
|
@@ -199,7 +202,7 @@ function bufferEndsWith(buffer, suffix) {
|
|
|
199
202
|
* @see https://github.com/sqlitecloud/sdk/blob/master/PROTOCOL.md#scsp-rowset-chunk
|
|
200
203
|
*/
|
|
201
204
|
function parseRowsetChunks(buffers) {
|
|
202
|
-
let buffer =
|
|
205
|
+
let buffer = Buffer.concat(buffers);
|
|
203
206
|
if (!bufferStartsWith(buffer, exports.CMD_ROWSET_CHUNK) || !bufferEndsWith(buffer, exports.ROWSET_CHUNKS_END)) {
|
|
204
207
|
throw new Error('SQLiteCloudConnection.parseRowsetChunks - invalid chunks buffer');
|
|
205
208
|
}
|
|
@@ -251,7 +254,7 @@ function popData(buffer) {
|
|
|
251
254
|
return { data, fwdBuffer };
|
|
252
255
|
}
|
|
253
256
|
// first character is the data type
|
|
254
|
-
console.assert(buffer && buffer instanceof
|
|
257
|
+
console.assert(buffer && buffer instanceof Buffer);
|
|
255
258
|
let dataType = buffer.subarray(0, 1).toString('utf8');
|
|
256
259
|
if (dataType == exports.CMD_COMPRESSED)
|
|
257
260
|
throw new Error('Compressed data should be decompressed before parsing');
|
|
@@ -324,15 +327,15 @@ function formatCommand(command) {
|
|
|
324
327
|
}
|
|
325
328
|
function serializeCommand(data, zeroString = false) {
|
|
326
329
|
const n = data.length;
|
|
327
|
-
let serializedData =
|
|
330
|
+
let serializedData = Buffer.from(`${n} `);
|
|
328
331
|
for (let i = 0; i < n; i++) {
|
|
329
332
|
// the first string is the sql and it must be zero-terminated
|
|
330
333
|
const zs = i == 0 || zeroString;
|
|
331
|
-
serializedData =
|
|
334
|
+
serializedData = Buffer.concat([serializedData, serializeData(data[i], zs)]);
|
|
332
335
|
}
|
|
333
336
|
const bytesTotal = serializedData.byteLength;
|
|
334
|
-
const header =
|
|
335
|
-
return
|
|
337
|
+
const header = Buffer.from(`${exports.CMD_ARRAY}${bytesTotal} `);
|
|
338
|
+
return Buffer.concat([header, serializedData]);
|
|
336
339
|
}
|
|
337
340
|
function serializeData(data, zeroString = false) {
|
|
338
341
|
if (typeof data === 'string') {
|
|
@@ -341,26 +344,26 @@ function serializeData(data, zeroString = false) {
|
|
|
341
344
|
cmd = exports.CMD_ZEROSTRING;
|
|
342
345
|
data += '\0';
|
|
343
346
|
}
|
|
344
|
-
const header = `${cmd}${
|
|
345
|
-
return
|
|
347
|
+
const header = `${cmd}${Buffer.byteLength(data, 'utf-8')} `;
|
|
348
|
+
return Buffer.from(header + data);
|
|
346
349
|
}
|
|
347
350
|
if (typeof data === 'number') {
|
|
348
351
|
if (Number.isInteger(data)) {
|
|
349
|
-
return
|
|
352
|
+
return Buffer.from(`${exports.CMD_INT}${data} `);
|
|
350
353
|
}
|
|
351
354
|
else {
|
|
352
|
-
return
|
|
355
|
+
return Buffer.from(`${exports.CMD_FLOAT}${data} `);
|
|
353
356
|
}
|
|
354
357
|
}
|
|
355
358
|
if (typeof data === 'bigint') {
|
|
356
|
-
return
|
|
359
|
+
return Buffer.from(`${exports.CMD_INT}${data} `);
|
|
357
360
|
}
|
|
358
|
-
if (
|
|
361
|
+
if (Buffer.isBuffer(data)) {
|
|
359
362
|
const header = `${exports.CMD_BLOB}${data.byteLength} `;
|
|
360
|
-
return
|
|
363
|
+
return Buffer.concat([Buffer.from(header), data]);
|
|
361
364
|
}
|
|
362
365
|
if (data === null || data === undefined) {
|
|
363
|
-
return
|
|
366
|
+
return Buffer.from(`${exports.CMD_NULL} `);
|
|
364
367
|
}
|
|
365
368
|
if (Array.isArray(data)) {
|
|
366
369
|
return serializeCommand(data, zeroString);
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* safe-imports.ts - Safe imports for optional React Native dependencies
|
|
3
|
+
*
|
|
4
|
+
* This module provides safe imports for dependencies that are optional peer dependencies.
|
|
5
|
+
* When these dependencies are not installed (e.g., using the package in a web/Next.js context),
|
|
6
|
+
* the imports will still work. However, in React Native contexts where these dependencies are
|
|
7
|
+
* required but not installed, clear error messages will be thrown.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Detects if we're running in React Native environment
|
|
11
|
+
*/
|
|
12
|
+
export declare function isReactNative(): boolean;
|
|
13
|
+
/**
|
|
14
|
+
* Safely imports the URL class from whatwg-url or react-native-url-polyfill
|
|
15
|
+
* In React Native: Uses react-native-url-polyfill (via react-native field mapping)
|
|
16
|
+
* In Web/Node: Uses whatwg-url
|
|
17
|
+
*/
|
|
18
|
+
export declare function getSafeURL(): typeof import('whatwg-url').URL;
|
|
19
|
+
/**
|
|
20
|
+
* Safely imports the Buffer class from buffer or @craftzdog/react-native-buffer
|
|
21
|
+
* In React Native: Uses @craftzdog/react-native-buffer (via react-native field mapping)
|
|
22
|
+
* In Web/Node: Uses buffer package
|
|
23
|
+
*/
|
|
24
|
+
export declare function getSafeBuffer(): typeof import('buffer').Buffer;
|
|
25
|
+
/**
|
|
26
|
+
* Safely imports the tls module or react-native-tcp-socket
|
|
27
|
+
* In React Native: Uses react-native-tcp-socket (via react-native field mapping)
|
|
28
|
+
* In Node: Uses native tls module
|
|
29
|
+
* In Browser: Will return null (browser field sets tls to false)
|
|
30
|
+
*/
|
|
31
|
+
export declare function getSafeTLS(): typeof import('tls') | null;
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* safe-imports.ts - Safe imports for optional React Native dependencies
|
|
4
|
+
*
|
|
5
|
+
* This module provides safe imports for dependencies that are optional peer dependencies.
|
|
6
|
+
* When these dependencies are not installed (e.g., using the package in a web/Next.js context),
|
|
7
|
+
* the imports will still work. However, in React Native contexts where these dependencies are
|
|
8
|
+
* required but not installed, clear error messages will be thrown.
|
|
9
|
+
*/
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.isReactNative = isReactNative;
|
|
12
|
+
exports.getSafeURL = getSafeURL;
|
|
13
|
+
exports.getSafeBuffer = getSafeBuffer;
|
|
14
|
+
exports.getSafeTLS = getSafeTLS;
|
|
15
|
+
const types_1 = require("./types");
|
|
16
|
+
/**
|
|
17
|
+
* Detects if we're running in React Native environment
|
|
18
|
+
*/
|
|
19
|
+
function isReactNative() {
|
|
20
|
+
return typeof navigator !== 'undefined' && navigator.product === 'ReactNative';
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Safely imports the URL class from whatwg-url or react-native-url-polyfill
|
|
24
|
+
* In React Native: Uses react-native-url-polyfill (via react-native field mapping)
|
|
25
|
+
* In Web/Node: Uses whatwg-url
|
|
26
|
+
*/
|
|
27
|
+
function getSafeURL() {
|
|
28
|
+
try {
|
|
29
|
+
// In React Native, Metro bundler will resolve this to react-native-url-polyfill
|
|
30
|
+
// In Web/Node, this will resolve to whatwg-url
|
|
31
|
+
const { URL } = require('whatwg-url');
|
|
32
|
+
return URL;
|
|
33
|
+
}
|
|
34
|
+
catch (error) {
|
|
35
|
+
if (isReactNative()) {
|
|
36
|
+
throw new types_1.SQLiteCloudError('Missing required React Native dependency: react-native-url-polyfill. ' +
|
|
37
|
+
'Please install it using: npm install react-native-url-polyfill', { errorCode: 'ERR_MISSING_DEPENDENCY', cause: error });
|
|
38
|
+
}
|
|
39
|
+
throw new types_1.SQLiteCloudError('Failed to load URL parser. Please ensure whatwg-url is installed.', { errorCode: 'ERR_MISSING_DEPENDENCY', cause: error });
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Safely imports the Buffer class from buffer or @craftzdog/react-native-buffer
|
|
44
|
+
* In React Native: Uses @craftzdog/react-native-buffer (via react-native field mapping)
|
|
45
|
+
* In Web/Node: Uses buffer package
|
|
46
|
+
*/
|
|
47
|
+
function getSafeBuffer() {
|
|
48
|
+
try {
|
|
49
|
+
// In React Native, Metro bundler will resolve this to @craftzdog/react-native-buffer
|
|
50
|
+
// In Web/Node, this will resolve to buffer package
|
|
51
|
+
const { Buffer } = require('buffer');
|
|
52
|
+
return Buffer;
|
|
53
|
+
}
|
|
54
|
+
catch (error) {
|
|
55
|
+
if (isReactNative()) {
|
|
56
|
+
throw new types_1.SQLiteCloudError('Missing required React Native dependency: @craftzdog/react-native-buffer. ' +
|
|
57
|
+
'Please install it using: npm install @craftzdog/react-native-buffer', { errorCode: 'ERR_MISSING_DEPENDENCY', cause: error });
|
|
58
|
+
}
|
|
59
|
+
throw new types_1.SQLiteCloudError('Failed to load Buffer library. Please ensure buffer package is installed.', { errorCode: 'ERR_MISSING_DEPENDENCY', cause: error });
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Safely imports the tls module or react-native-tcp-socket
|
|
64
|
+
* In React Native: Uses react-native-tcp-socket (via react-native field mapping)
|
|
65
|
+
* In Node: Uses native tls module
|
|
66
|
+
* In Browser: Will return null (browser field sets tls to false)
|
|
67
|
+
*/
|
|
68
|
+
function getSafeTLS() {
|
|
69
|
+
try {
|
|
70
|
+
// In React Native, Metro bundler will resolve this to react-native-tcp-socket
|
|
71
|
+
// In Node, this will resolve to native tls module
|
|
72
|
+
// In Browser, the browser field in package.json sets tls to false
|
|
73
|
+
const tls = require('tls');
|
|
74
|
+
if (tls === false || !tls) {
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
return tls;
|
|
78
|
+
}
|
|
79
|
+
catch (error) {
|
|
80
|
+
if (isReactNative()) {
|
|
81
|
+
throw new types_1.SQLiteCloudError('Missing required React Native dependency: react-native-tcp-socket. ' +
|
|
82
|
+
'Please install it using: npm install react-native-tcp-socket', { errorCode: 'ERR_MISSING_DEPENDENCY', cause: error });
|
|
83
|
+
}
|
|
84
|
+
// In browser context, tls is not available (WebSocket should be used instead)
|
|
85
|
+
return null;
|
|
86
|
+
}
|
|
87
|
+
}
|
package/lib/drivers/utilities.js
CHANGED
|
@@ -15,8 +15,11 @@ exports.parseconnectionstring = parseconnectionstring;
|
|
|
15
15
|
exports.parseBoolean = parseBoolean;
|
|
16
16
|
exports.parseBooleanToZeroOne = parseBooleanToZeroOne;
|
|
17
17
|
const types_1 = require("./types");
|
|
18
|
+
const safe_imports_1 = require("./safe-imports");
|
|
18
19
|
// explicitly importing these libraries to allow cross-platform support by replacing them
|
|
19
|
-
|
|
20
|
+
// In React Native: Metro resolves 'whatwg-url' to 'react-native-url-polyfill' via package.json react-native field
|
|
21
|
+
// In Web/Node: Uses standard whatwg-url package
|
|
22
|
+
const URL = (0, safe_imports_1.getSafeURL)();
|
|
20
23
|
//
|
|
21
24
|
// determining running environment, thanks to browser-or-node
|
|
22
25
|
// https://www.npmjs.com/package/browser-or-node
|
|
@@ -193,7 +196,7 @@ function parseconnectionstring(connectionstring) {
|
|
|
193
196
|
// the sqlitecloud: protocol is not recognized by the URL constructor in browsers
|
|
194
197
|
// so we need to replace it with https: to make it work
|
|
195
198
|
const knownProtocolUrl = connectionstring.replace('sqlitecloud:', 'https:');
|
|
196
|
-
const url = new
|
|
199
|
+
const url = new URL(knownProtocolUrl);
|
|
197
200
|
// all lowecase options
|
|
198
201
|
const options = {};
|
|
199
202
|
url.searchParams.forEach((value, key) => {
|