@sqlitecloud/drivers 0.0.56 → 1.0.122
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/lib/drivers/connection-ws.js +3 -3
- package/lib/drivers/connection.d.ts +11 -1
- package/lib/drivers/connection.js +58 -3
- package/lib/drivers/database.js +3 -3
- package/lib/drivers/types.d.ts +24 -17
- package/lib/drivers/utilities.d.ts +10 -2
- package/lib/drivers/utilities.js +87 -28
- package/lib/index.d.ts +1 -1
- package/lib/index.js +2 -2
- package/lib/sqlitecloud.drivers.dev.js +6 -6
- package/lib/sqlitecloud.drivers.js +1 -1
- package/package.json +6 -8
|
@@ -37,7 +37,7 @@ eval("\n/**\n * connection-tls.ts - connection via tls socket and sqlitecloud pr
|
|
|
37
37
|
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
38
38
|
|
|
39
39
|
"use strict";
|
|
40
|
-
eval("\n/**\n * transport-ws.ts - handles low level communication with sqlitecloud server via socket.io websocket\n */\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.SQLiteCloudWebsocketConnection = void 0;\nconst types_1 = __webpack_require__(/*! ./types */ \"./lib/drivers/types.js\");\nconst rowset_1 = __webpack_require__(/*! ./rowset */ \"./lib/drivers/rowset.js\");\nconst connection_1 = __webpack_require__(/*! ./connection */ \"./lib/drivers/connection.js\");\nconst socket_io_client_1 = __webpack_require__(/*! socket.io-client */ \"./node_modules/socket.io-client/build/cjs/index.js\");\n/**\n * Implementation of TransportConnection that connects to the database indirectly\n * via SQLite Cloud Gateway, a socket.io based deamon that responds to sql query\n * requests by returning results and rowsets in json format. The gateway handles\n * connect, disconnect, retries, order of operations, timeouts, etc.\n */\nclass SQLiteCloudWebsocketConnection extends connection_1.SQLiteCloudConnection {\n /** True if connection is open */\n get connected() {\n return !!this.socket;\n }\n /* Opens a connection with the server and sends the initialization commands. Will throw in case of errors. */\n connectTransport(config, callback) {\n var _a;\n try {\n // connection established while we were waiting in line?\n console.assert(!this.connected, 'Connection already established');\n if (!this.socket) {\n this.config = config;\n const
|
|
40
|
+
eval("\n/**\n * transport-ws.ts - handles low level communication with sqlitecloud server via socket.io websocket\n */\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.SQLiteCloudWebsocketConnection = void 0;\nconst types_1 = __webpack_require__(/*! ./types */ \"./lib/drivers/types.js\");\nconst rowset_1 = __webpack_require__(/*! ./rowset */ \"./lib/drivers/rowset.js\");\nconst connection_1 = __webpack_require__(/*! ./connection */ \"./lib/drivers/connection.js\");\nconst socket_io_client_1 = __webpack_require__(/*! socket.io-client */ \"./node_modules/socket.io-client/build/cjs/index.js\");\n/**\n * Implementation of TransportConnection that connects to the database indirectly\n * via SQLite Cloud Gateway, a socket.io based deamon that responds to sql query\n * requests by returning results and rowsets in json format. The gateway handles\n * connect, disconnect, retries, order of operations, timeouts, etc.\n */\nclass SQLiteCloudWebsocketConnection extends connection_1.SQLiteCloudConnection {\n /** True if connection is open */\n get connected() {\n return !!this.socket;\n }\n /* Opens a connection with the server and sends the initialization commands. Will throw in case of errors. */\n connectTransport(config, callback) {\n var _a;\n try {\n // connection established while we were waiting in line?\n console.assert(!this.connected, 'Connection already established');\n if (!this.socket) {\n this.config = config;\n const connectionstring = this.config.connectionstring;\n const gatewayUrl = ((_a = this.config) === null || _a === void 0 ? void 0 : _a.gatewayurl) || `${this.config.host === 'localhost' ? 'ws' : 'wss'}://${this.config.host}:4000`;\n this.socket = (0, socket_io_client_1.io)(gatewayUrl, { auth: { token: connectionstring } });\n }\n callback === null || callback === void 0 ? void 0 : callback.call(this, null);\n }\n catch (error) {\n callback === null || callback === void 0 ? void 0 : callback.call(this, error);\n }\n return this;\n }\n /** Will send a command immediately (no queueing), return the rowset/result or throw an error */\n transportCommands(commands, callback) {\n // connection needs to be established?\n if (!this.socket) {\n callback === null || callback === void 0 ? void 0 : callback.call(this, new types_1.SQLiteCloudError('Connection not established', { errorCode: 'ERR_CONNECTION_NOT_ESTABLISHED' }));\n return this;\n }\n this.socket.emit('v1/sql', { sql: commands, row: 'array' }, (response) => {\n if (response === null || response === void 0 ? void 0 : response.error) {\n const error = new types_1.SQLiteCloudError(response.error.detail, Object.assign({}, response.error));\n callback === null || callback === void 0 ? void 0 : callback.call(this, error);\n }\n else {\n const { data, metadata } = response;\n if (data && metadata) {\n if (metadata.numberOfRows !== undefined && metadata.numberOfColumns !== undefined && metadata.columns !== undefined) {\n console.assert(Array.isArray(data), 'SQLiteCloudWebsocketConnection.transportCommands - data is not an array');\n // we can recreate a SQLiteCloudRowset from the response which we know to be an array of arrays\n // eslint-disable-next-line @typescript-eslint/no-unsafe-call\n const rowset = new rowset_1.SQLiteCloudRowset(metadata, data.flat());\n callback === null || callback === void 0 ? void 0 : callback.call(this, null, rowset);\n return;\n }\n }\n callback === null || callback === void 0 ? void 0 : callback.call(this, null, response === null || response === void 0 ? void 0 : response.data);\n }\n });\n return this;\n }\n /** Disconnect socket.io from server */\n close() {\n var _a;\n console.assert(this.socket !== null, 'SQLiteCloudWebsocketConnection.close - connection already closed');\n if (this.socket) {\n (_a = this.socket) === null || _a === void 0 ? void 0 : _a.close();\n this.socket = undefined;\n }\n this.operations.clear();\n this.socket = undefined;\n return this;\n }\n}\nexports.SQLiteCloudWebsocketConnection = SQLiteCloudWebsocketConnection;\nexports[\"default\"] = SQLiteCloudWebsocketConnection;\n\n\n//# sourceURL=webpack://sqlitecloud/./lib/drivers/connection-ws.js?");
|
|
41
41
|
|
|
42
42
|
/***/ }),
|
|
43
43
|
|
|
@@ -45,10 +45,10 @@ eval("\n/**\n * transport-ws.ts - handles low level communication with sqliteclo
|
|
|
45
45
|
/*!***********************************!*\
|
|
46
46
|
!*** ./lib/drivers/connection.js ***!
|
|
47
47
|
\***********************************/
|
|
48
|
-
/***/ ((__unused_webpack_module, exports, __webpack_require__)
|
|
48
|
+
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
|
49
49
|
|
|
50
50
|
"use strict";
|
|
51
|
-
eval("\n/**\n * connection.ts - base abstract class for sqlitecloud server connections\n */\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.SQLiteCloudConnection = void 0;\nconst types_1 = __webpack_require__(/*! ./types */ \"./lib/drivers/types.js\");\nconst utilities_1 = __webpack_require__(/*! ./utilities */ \"./lib/drivers/utilities.js\");\nconst queue_1 = __webpack_require__(/*! ./queue */ \"./lib/drivers/queue.js\");\nconst utilities_2 = __webpack_require__(/*! ./utilities */ \"./lib/drivers/utilities.js\");\n/**\n * Base class for SQLiteCloudConnection handles basics and defines methods.\n * Actual connection management and communication with the server in concrete classes.\n */\nclass SQLiteCloudConnection {\n /** Parse and validate provided
|
|
51
|
+
eval("\n/**\n * connection.ts - base abstract class for sqlitecloud server connections\n */\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.SQLiteCloudConnection = void 0;\nconst types_1 = __webpack_require__(/*! ./types */ \"./lib/drivers/types.js\");\nconst utilities_1 = __webpack_require__(/*! ./utilities */ \"./lib/drivers/utilities.js\");\nconst queue_1 = __webpack_require__(/*! ./queue */ \"./lib/drivers/queue.js\");\nconst utilities_2 = __webpack_require__(/*! ./utilities */ \"./lib/drivers/utilities.js\");\n/**\n * Base class for SQLiteCloudConnection handles basics and defines methods.\n * Actual connection management and communication with the server in concrete classes.\n */\nclass SQLiteCloudConnection {\n /** Parse and validate provided connectionstring or configuration */\n constructor(config, callback) {\n /** Operations are serialized by waiting an any pending promises */\n this.operations = new queue_1.OperationsQueue();\n if (typeof config === 'string') {\n this.config = (0, utilities_1.validateConfiguration)({ connectionstring: config });\n }\n else {\n this.config = (0, utilities_1.validateConfiguration)(config);\n }\n // connect transport layer to server\n this.connect(callback);\n }\n /** Returns the connection's configuration */\n getConfig() {\n return Object.assign({}, this.config);\n }\n //\n // internal methods (some are implemented in concrete classes using different transport layers)\n //\n /** Connect will establish a tls or websocket transport to the server based on configuration and environment */\n connect(callback) {\n this.operations.enqueue(done => {\n this.connectTransport(this.config, error => {\n if (error) {\n console.error(`SQLiteCloudConnection.connect - error connecting ${this.config.host}:${this.config.port} ${error.toString()}`, error);\n this.close();\n }\n if (callback) {\n callback.call(this, error || null);\n }\n done(error);\n });\n });\n return this;\n }\n /** Will log to console if verbose mode is enabled */\n log(message, ...optionalParams) {\n if (this.config.verbose) {\n message = (0, utilities_2.anonimizeCommand)(message);\n console.log(`${new Date().toISOString()} ${this.config.clientid}: ${message}`, ...optionalParams);\n }\n }\n /** Enable verbose logging for debug purposes */\n verbose() {\n this.config.verbose = true;\n }\n /** Will enquee a command to be executed and callback with the resulting rowset/result/error */\n sendCommands(commands, callback) {\n this.operations.enqueue(done => {\n if (!this.connected) {\n const error = new types_1.SQLiteCloudError('Connection not established', { errorCode: 'ERR_CONNECTION_NOT_ESTABLISHED' });\n callback === null || callback === void 0 ? void 0 : callback.call(this, error);\n done(error);\n }\n else {\n this.transportCommands(commands, (error, result) => {\n callback === null || callback === void 0 ? void 0 : callback.call(this, error, result);\n done(error);\n });\n }\n });\n return this;\n }\n /**\n * Sql is a promise based API for executing SQL statements. You can\n * pass a simple string with a SQL statement or a template string\n * using backticks and parameters in ${parameter} format. These parameters\n * will be properly escaped and quoted like when using a prepared statement.\n * @param sql A sql string or a template string in `backticks` format\n * @returns An array of rows in case of selections or an object with\n * metadata in case of insert, update, delete.\n */\n sql(sql, ...values) {\n return __awaiter(this, void 0, void 0, function* () {\n let preparedSql = '';\n // sql is a TemplateStringsArray, the 'raw' property is specific to TemplateStringsArray\n if (Array.isArray(sql) && 'raw' in sql) {\n sql.forEach((string, i) => {\n preparedSql += string + (i < values.length ? '?' : '');\n });\n preparedSql = (0, utilities_1.prepareSql)(preparedSql, ...values);\n }\n else {\n if (typeof sql === 'string') {\n if ((values === null || values === void 0 ? void 0 : values.length) > 0) {\n preparedSql = (0, utilities_1.prepareSql)(sql, ...values);\n }\n else {\n preparedSql = sql;\n }\n }\n else {\n throw new Error('Invalid sql');\n }\n }\n return new Promise((resolve, reject) => {\n this.sendCommands(preparedSql, (error, results) => {\n if (error) {\n reject(error);\n }\n else {\n // metadata for operations like insert, update, delete?\n const context = (0, utilities_2.getUpdateResults)(results);\n resolve(context ? context : results);\n }\n });\n });\n });\n }\n}\nexports.SQLiteCloudConnection = SQLiteCloudConnection;\n\n\n//# sourceURL=webpack://sqlitecloud/./lib/drivers/connection.js?");
|
|
52
52
|
|
|
53
53
|
/***/ }),
|
|
54
54
|
|
|
@@ -59,7 +59,7 @@ eval("\n/**\n * connection.ts - base abstract class for sqlitecloud server conne
|
|
|
59
59
|
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
|
60
60
|
|
|
61
61
|
"use strict";
|
|
62
|
-
eval("\n//\n// database.ts - database driver api, implements and extends sqlite3\n//\nvar __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n var desc = Object.getOwnPropertyDescriptor(m, k);\n if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\n desc = { enumerable: true, get: function() { return m[k]; } };\n }\n Object.defineProperty(o, k2, desc);\n}) : (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n o[k2] = m[k];\n}));\nvar __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n o[\"default\"] = v;\n});\nvar __importStar = (this && this.__importStar) || function (mod) {\n if (mod && mod.__esModule) return mod;\n var result = {};\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\n __setModuleDefault(result, mod);\n return result;\n};\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n};\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.Database = void 0;\nconst rowset_1 = __webpack_require__(/*! ./rowset */ \"./lib/drivers/rowset.js\");\nconst types_1 = __webpack_require__(/*! ./types */ \"./lib/drivers/types.js\");\nconst utilities_1 = __webpack_require__(/*! ./utilities */ \"./lib/drivers/utilities.js\");\nconst statement_1 = __webpack_require__(/*! ./statement */ \"./lib/drivers/statement.js\");\nconst eventemitter3_1 = __importDefault(__webpack_require__(/*! eventemitter3 */ \"./node_modules/eventemitter3/index.js\"));\nconst utilities_2 = __webpack_require__(/*! ./utilities */ \"./lib/drivers/utilities.js\");\n// Uses eventemitter3 instead of node events for browser compatibility\n// https://github.com/primus/eventemitter3\n/**\n * Creating a Database object automatically opens a connection to the SQLite database.\n * When the connection is established the Database object emits an open event and calls\n * the optional provided callback. If the connection cannot be established an error event\n * will be emitted and the optional callback is called with the error information.\n */\nclass Database extends eventemitter3_1.default {\n constructor(config, mode, callback) {\n super();\n /** Database connections */\n this.connections = [];\n this.config = typeof config === 'string' ? { connectionString: config } : config;\n // mode is optional and so is callback\n // https://github.com/TryGhost/node-sqlite3/wiki/API#new-sqlite3databasefilename--mode--callback\n if (typeof mode === 'function') {\n callback = mode;\n mode = undefined;\n }\n // mode is ignored for now\n // opens first connection to the database automatically\n this.getConnection((error, _connection) => {\n if (callback) {\n callback.call(this, error);\n }\n });\n }\n //\n // private methods\n //\n /** Returns first available connection from connection pool */\n getConnection(callback) {\n var _a, _b, _c;\n // TODO sqlitecloud-js / implement database connection pool #10\n if (((_a = this.connections) === null || _a === void 0 ? void 0 : _a.length) > 0) {\n callback === null || callback === void 0 ? void 0 : callback.call(this, null, this.connections[0]);\n }\n else {\n // connect using websocket if tls is not supported or if explicitly requested\n const useWebsocket = utilities_2.isBrowser || ((_b = this.config) === null || _b === void 0 ? void 0 : _b.useWebsocket) || ((_c = this.config) === null || _c === void 0 ? void 0 : _c.gatewayUrl);\n if (useWebsocket) {\n // socket.io transport works in both node.js and browser environments and connects via SQLite Cloud Gateway\n Promise.resolve().then(() => __importStar(__webpack_require__(/*! ./connection-ws */ \"./lib/drivers/connection-ws.js\"))).then(module => {\n this.connections.push(new module.default(this.config, error => {\n if (error) {\n this.handleError(this.connections[0], error, callback);\n }\n else {\n console.assert;\n callback === null || callback === void 0 ? void 0 : callback.call(this, null, this.connections[0]);\n this.emitEvent('open');\n }\n }));\n })\n .catch(error => {\n this.handleError(null, error, callback);\n });\n }\n else {\n // tls sockets work only in node.js environments\n Promise.resolve().then(() => __importStar(__webpack_require__(/*! ./connection-tls */ \"./lib/drivers/connection-tls.js\"))).then(module => {\n this.connections.push(new module.default(this.config, error => {\n if (error) {\n this.handleError(this.connections[0], error, callback);\n }\n else {\n console.assert;\n callback === null || callback === void 0 ? void 0 : callback.call(this, null, this.connections[0]);\n this.emitEvent('open');\n }\n }));\n })\n .catch(error => {\n this.handleError(null, error, callback);\n });\n }\n }\n }\n /** Handles an error by closing the connection, calling the callback and/or emitting an error event */\n handleError(connection, error, callback) {\n // an errored connection is thrown out\n if (connection) {\n this.connections = this.connections.filter(c => c !== connection);\n connection.close();\n }\n if (callback) {\n callback.call(this, error);\n }\n else {\n this.emitEvent('error', error);\n }\n }\n /**\n * Some queries like inserts or updates processed via run or exec may generate\n * an empty result (eg. no data was selected), but still have some metadata.\n * For example the server may pass the id of the last row that was modified.\n * In this case the callback results should be empty but the context may contain\n * additional information like lastID, etc.\n * @see https://github.com/TryGhost/node-sqlite3/wiki/API#runsql--param---callback\n * @param results Results received from the server\n * @returns A context object if one makes sense, otherwise undefined\n */\n processContext(results) {\n if (results) {\n if (Array.isArray(results) && results.length > 0) {\n switch (results[0]) {\n case types_1.SQLiteCloudArrayType.ARRAY_TYPE_SQLITE_EXEC:\n return {\n lastID: results[2],\n changes: results[3],\n totalChanges: results[4],\n finalized: results[5] // FINALIZED\n };\n }\n }\n }\n return undefined;\n }\n /** Emits given event with optional arguments on the next tick so callbacks can complete first */\n emitEvent(event, ...args) {\n setTimeout(() => {\n this.emit(event, ...args);\n }, 0);\n }\n //\n // public methods\n //\n /**\n * Returns the configuration with which this database was opened.\n * The configuration is readonly and cannot be changed as there may\n * be multiple connections using the same configuration.\n * @returns {SQLiteCloudConfig} A configuration object\n */\n getConfiguration() {\n return JSON.parse(JSON.stringify(this.config));\n }\n /** Enable verbose mode */\n verbose() {\n this.config.verbose = true;\n for (const connection of this.connections) {\n connection.verbose();\n }\n return this;\n }\n /** Set a configuration option for the database */\n configure(_option, _value) {\n // https://github.com/TryGhost/node-sqlite3/wiki/API#configureoption-value\n return this;\n }\n run(sql, ...params) {\n const { args, callback } = (0, utilities_1.popCallback)(params);\n const preparedSql = (args === null || args === void 0 ? void 0 : args.length) > 0 ? (0, utilities_1.prepareSql)(sql, ...args) : sql;\n this.getConnection((error, connection) => {\n if (error || !connection) {\n this.handleError(null, error, callback);\n }\n else {\n connection.sendCommands(preparedSql, (error, results) => {\n if (error) {\n this.handleError(connection, error, callback);\n }\n else {\n // context may include id of last row inserted, total changes, etc...\n const context = this.processContext(results);\n callback === null || callback === void 0 ? void 0 : callback.call(context || this, null, context ? undefined : results);\n }\n });\n }\n });\n return this;\n }\n get(sql, ...params) {\n const { args, callback } = (0, utilities_1.popCallback)(params);\n const preparedSql = (args === null || args === void 0 ? void 0 : args.length) > 0 ? (0, utilities_1.prepareSql)(sql, ...args) : sql;\n this.getConnection((error, connection) => {\n if (error || !connection) {\n this.handleError(null, error, callback);\n }\n else {\n connection.sendCommands(preparedSql, (error, results) => {\n if (error) {\n this.handleError(connection, error, callback);\n }\n else {\n if (results && results instanceof rowset_1.SQLiteCloudRowset && results.length > 0) {\n callback === null || callback === void 0 ? void 0 : callback.call(this, null, results[0]);\n }\n else {\n callback === null || callback === void 0 ? void 0 : callback.call(this, null);\n }\n }\n });\n }\n });\n return this;\n }\n all(sql, ...params) {\n const { args, callback } = (0, utilities_1.popCallback)(params);\n const preparedSql = (args === null || args === void 0 ? void 0 : args.length) > 0 ? (0, utilities_1.prepareSql)(sql, ...args) : sql;\n this.getConnection((error, connection) => {\n if (error || !connection) {\n this.handleError(null, error, callback);\n }\n else {\n connection.sendCommands(preparedSql, (error, results) => {\n if (error) {\n this.handleError(connection, error, callback);\n }\n else {\n if (results && results instanceof rowset_1.SQLiteCloudRowset) {\n callback === null || callback === void 0 ? void 0 : callback.call(this, null, results);\n }\n else {\n callback === null || callback === void 0 ? void 0 : callback.call(this, null);\n }\n }\n });\n }\n });\n return this;\n }\n each(sql, ...params) {\n // extract optional parameters and one or two callbacks\n const { args, callback, complete } = (0, utilities_1.popCallback)(params);\n const preparedSql = (args === null || args === void 0 ? void 0 : args.length) > 0 ? (0, utilities_1.prepareSql)(sql, ...args) : sql;\n this.getConnection((error, connection) => {\n if (error || !connection) {\n this.handleError(null, error, callback);\n }\n else {\n connection.sendCommands(preparedSql, (error, rowset) => {\n if (error) {\n this.handleError(connection, error, callback);\n }\n else {\n if (rowset && rowset instanceof rowset_1.SQLiteCloudRowset) {\n if (callback) {\n for (const row of rowset) {\n callback.call(this, null, row);\n }\n }\n if (complete) {\n ;\n complete.call(this, null, rowset.numberOfRows);\n }\n }\n else {\n callback === null || callback === void 0 ? void 0 : callback.call(this, new types_1.SQLiteCloudError('Invalid rowset'));\n }\n }\n });\n }\n });\n return this;\n }\n /**\n * Prepares the SQL statement and optionally binds the specified parameters and\n * calls the callback when done. The function returns a Statement object.\n * When preparing was successful, the first and only argument to the callback\n * is null, otherwise it is the error object. When bind parameters are supplied,\n * they are bound to the prepared statement before calling the callback.\n */\n prepare(sql, ...params) {\n const { args, callback } = (0, utilities_1.popCallback)(params);\n return new statement_1.Statement(this, sql, ...args, callback);\n }\n /**\n * Runs all SQL queries in the supplied string. No result rows are retrieved.\n * The function returns the Database object to allow for function chaining.\n * If a query fails, no subsequent statements will be executed (wrap it in a\n * transaction if you want all or none to be executed). When all statements\n * have been executed successfully, or when an error occurs, the callback\n * function is called, with the first parameter being either null or an error\n * object. When no callback is provided and an error occurs, an error event\n * will be emitted on the database object.\n */\n exec(sql, callback) {\n this.getConnection((error, connection) => {\n if (error || !connection) {\n this.handleError(null, error, callback);\n }\n else {\n connection.sendCommands(sql, (error, results) => {\n if (error) {\n this.handleError(connection, error, callback);\n }\n else {\n const context = this.processContext(results);\n callback === null || callback === void 0 ? void 0 : callback.call(context ? context : this, null);\n }\n });\n }\n });\n return this;\n }\n /**\n * If the optional callback is provided, this function will be called when the\n * database was closed successfully or when an error occurred. The first argument\n * is an error object. When it is null, closing succeeded. If no callback is provided\n * and an error occurred, an error event with the error object as the only parameter\n * will be emitted on the database object. If closing succeeded, a close event with no\n * parameters is emitted, regardless of whether a callback was provided or not.\n */\n close(callback) {\n var _a;\n if (((_a = this.connections) === null || _a === void 0 ? void 0 : _a.length) > 0) {\n for (const connection of this.connections) {\n connection.close();\n }\n }\n callback === null || callback === void 0 ? void 0 : callback.call(this, null);\n this.emitEvent('close');\n }\n /**\n * Loads a compiled SQLite extension into the database connection object.\n * @param path Filename of the extension to load.\n * @param callback If provided, this function will be called when the extension\n * was loaded successfully or when an error occurred. The first argument is an\n * error object. When it is null, loading succeeded. If no callback is provided\n * and an error occurred, an error event with the error object as the only parameter\n * will be emitted on the database object.\n */\n loadExtension(_path, callback) {\n // TODO sqlitecloud-js / implement database loadExtension #17\n if (callback) {\n callback.call(this, new Error('Database.loadExtension - Not implemented'));\n }\n else {\n this.emitEvent('error', new Error('Database.loadExtension - Not implemented'));\n }\n return this;\n }\n /**\n * Allows the user to interrupt long-running queries. Wrapper around\n * sqlite3_interrupt and causes other data-fetching functions to be\n * passed an err with code = sqlite3.INTERRUPT. The database must be\n * open to use this function.\n */\n interrupt() {\n // TODO sqlitecloud-js / implement database interrupt #13\n }\n //\n // extended APIs\n //\n /**\n * Sql is a promise based API for executing SQL statements. You can\n * pass a simple string with a SQL statement or a template string\n * using backticks and parameters in ${parameter} format. These parameters\n * will be properly escaped and quoted like when using a prepared statement.\n * @param sql A sql string or a template string in `backticks` format\n * @returns An array of rows in case of selections or an object with\n * metadata in case of insert, update, delete.\n */\n sql(sql, ...values) {\n return __awaiter(this, void 0, void 0, function* () {\n let preparedSql = '';\n // sql is a TemplateStringsArray, the 'raw' property is specific to TemplateStringsArray\n if (Array.isArray(sql) && 'raw' in sql) {\n sql.forEach((string, i) => {\n preparedSql += string + (i < values.length ? '?' : '');\n });\n preparedSql = (0, utilities_1.prepareSql)(preparedSql, ...values);\n }\n else {\n if (typeof sql === 'string') {\n if ((values === null || values === void 0 ? void 0 : values.length) > 0) {\n preparedSql = (0, utilities_1.prepareSql)(sql, ...values);\n }\n else {\n preparedSql = sql;\n }\n }\n else {\n throw new Error('Invalid sql');\n }\n }\n return new Promise((resolve, reject) => {\n this.getConnection((error, connection) => {\n if (error || !connection) {\n reject(error);\n }\n else {\n connection.sendCommands(preparedSql, (error, results) => {\n if (error) {\n reject(error);\n }\n else {\n // metadata for operations like insert, update, delete?\n const context = this.processContext(results);\n resolve(context ? context : results);\n }\n });\n }\n });\n });\n });\n }\n}\nexports.Database = Database;\n\n\n//# sourceURL=webpack://sqlitecloud/./lib/drivers/database.js?");
|
|
62
|
+
eval("\n//\n// database.ts - database driver api, implements and extends sqlite3\n//\nvar __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n var desc = Object.getOwnPropertyDescriptor(m, k);\n if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\n desc = { enumerable: true, get: function() { return m[k]; } };\n }\n Object.defineProperty(o, k2, desc);\n}) : (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n o[k2] = m[k];\n}));\nvar __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n o[\"default\"] = v;\n});\nvar __importStar = (this && this.__importStar) || function (mod) {\n if (mod && mod.__esModule) return mod;\n var result = {};\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\n __setModuleDefault(result, mod);\n return result;\n};\nvar __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n};\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.Database = void 0;\nconst rowset_1 = __webpack_require__(/*! ./rowset */ \"./lib/drivers/rowset.js\");\nconst types_1 = __webpack_require__(/*! ./types */ \"./lib/drivers/types.js\");\nconst utilities_1 = __webpack_require__(/*! ./utilities */ \"./lib/drivers/utilities.js\");\nconst statement_1 = __webpack_require__(/*! ./statement */ \"./lib/drivers/statement.js\");\nconst eventemitter3_1 = __importDefault(__webpack_require__(/*! eventemitter3 */ \"./node_modules/eventemitter3/index.js\"));\nconst utilities_2 = __webpack_require__(/*! ./utilities */ \"./lib/drivers/utilities.js\");\n// Uses eventemitter3 instead of node events for browser compatibility\n// https://github.com/primus/eventemitter3\n/**\n * Creating a Database object automatically opens a connection to the SQLite database.\n * When the connection is established the Database object emits an open event and calls\n * the optional provided callback. If the connection cannot be established an error event\n * will be emitted and the optional callback is called with the error information.\n */\nclass Database extends eventemitter3_1.default {\n constructor(config, mode, callback) {\n super();\n /** Database connections */\n this.connections = [];\n this.config = typeof config === 'string' ? { connectionstring: config } : config;\n // mode is optional and so is callback\n // https://github.com/TryGhost/node-sqlite3/wiki/API#new-sqlite3databasefilename--mode--callback\n if (typeof mode === 'function') {\n callback = mode;\n mode = undefined;\n }\n // mode is ignored for now\n // opens first connection to the database automatically\n this.getConnection((error, _connection) => {\n if (callback) {\n callback.call(this, error);\n }\n });\n }\n //\n // private methods\n //\n /** Returns first available connection from connection pool */\n getConnection(callback) {\n var _a, _b, _c;\n // TODO sqlitecloud-js / implement database connection pool #10\n if (((_a = this.connections) === null || _a === void 0 ? void 0 : _a.length) > 0) {\n callback === null || callback === void 0 ? void 0 : callback.call(this, null, this.connections[0]);\n }\n else {\n // connect using websocket if tls is not supported or if explicitly requested\n const useWebsocket = utilities_2.isBrowser || ((_b = this.config) === null || _b === void 0 ? void 0 : _b.usewebsocket) || ((_c = this.config) === null || _c === void 0 ? void 0 : _c.gatewayurl);\n if (useWebsocket) {\n // socket.io transport works in both node.js and browser environments and connects via SQLite Cloud Gateway\n Promise.resolve().then(() => __importStar(__webpack_require__(/*! ./connection-ws */ \"./lib/drivers/connection-ws.js\"))).then(module => {\n this.connections.push(new module.default(this.config, error => {\n if (error) {\n this.handleError(this.connections[0], error, callback);\n }\n else {\n console.assert;\n callback === null || callback === void 0 ? void 0 : callback.call(this, null, this.connections[0]);\n this.emitEvent('open');\n }\n }));\n })\n .catch(error => {\n this.handleError(null, error, callback);\n });\n }\n else {\n // tls sockets work only in node.js environments\n Promise.resolve().then(() => __importStar(__webpack_require__(/*! ./connection-tls */ \"./lib/drivers/connection-tls.js\"))).then(module => {\n this.connections.push(new module.default(this.config, error => {\n if (error) {\n this.handleError(this.connections[0], error, callback);\n }\n else {\n console.assert;\n callback === null || callback === void 0 ? void 0 : callback.call(this, null, this.connections[0]);\n this.emitEvent('open');\n }\n }));\n })\n .catch(error => {\n this.handleError(null, error, callback);\n });\n }\n }\n }\n /** Handles an error by closing the connection, calling the callback and/or emitting an error event */\n handleError(connection, error, callback) {\n // an errored connection is thrown out\n if (connection) {\n this.connections = this.connections.filter(c => c !== connection);\n connection.close();\n }\n if (callback) {\n callback.call(this, error);\n }\n else {\n this.emitEvent('error', error);\n }\n }\n /**\n * Some queries like inserts or updates processed via run or exec may generate\n * an empty result (eg. no data was selected), but still have some metadata.\n * For example the server may pass the id of the last row that was modified.\n * In this case the callback results should be empty but the context may contain\n * additional information like lastID, etc.\n * @see https://github.com/TryGhost/node-sqlite3/wiki/API#runsql--param---callback\n * @param results Results received from the server\n * @returns A context object if one makes sense, otherwise undefined\n */\n processContext(results) {\n if (results) {\n if (Array.isArray(results) && results.length > 0) {\n switch (results[0]) {\n case types_1.SQLiteCloudArrayType.ARRAY_TYPE_SQLITE_EXEC:\n return {\n lastID: results[2],\n changes: results[3],\n totalChanges: results[4],\n finalized: results[5] // FINALIZED\n };\n }\n }\n }\n return undefined;\n }\n /** Emits given event with optional arguments on the next tick so callbacks can complete first */\n emitEvent(event, ...args) {\n setTimeout(() => {\n this.emit(event, ...args);\n }, 0);\n }\n //\n // public methods\n //\n /**\n * Returns the configuration with which this database was opened.\n * The configuration is readonly and cannot be changed as there may\n * be multiple connections using the same configuration.\n * @returns {SQLiteCloudConfig} A configuration object\n */\n getConfiguration() {\n return JSON.parse(JSON.stringify(this.config));\n }\n /** Enable verbose mode */\n verbose() {\n this.config.verbose = true;\n for (const connection of this.connections) {\n connection.verbose();\n }\n return this;\n }\n /** Set a configuration option for the database */\n configure(_option, _value) {\n // https://github.com/TryGhost/node-sqlite3/wiki/API#configureoption-value\n return this;\n }\n run(sql, ...params) {\n const { args, callback } = (0, utilities_1.popCallback)(params);\n const preparedSql = (args === null || args === void 0 ? void 0 : args.length) > 0 ? (0, utilities_1.prepareSql)(sql, ...args) : sql;\n this.getConnection((error, connection) => {\n if (error || !connection) {\n this.handleError(null, error, callback);\n }\n else {\n connection.sendCommands(preparedSql, (error, results) => {\n if (error) {\n this.handleError(connection, error, callback);\n }\n else {\n // context may include id of last row inserted, total changes, etc...\n const context = this.processContext(results);\n callback === null || callback === void 0 ? void 0 : callback.call(context || this, null, context ? context : results);\n }\n });\n }\n });\n return this;\n }\n get(sql, ...params) {\n const { args, callback } = (0, utilities_1.popCallback)(params);\n const preparedSql = (args === null || args === void 0 ? void 0 : args.length) > 0 ? (0, utilities_1.prepareSql)(sql, ...args) : sql;\n this.getConnection((error, connection) => {\n if (error || !connection) {\n this.handleError(null, error, callback);\n }\n else {\n connection.sendCommands(preparedSql, (error, results) => {\n if (error) {\n this.handleError(connection, error, callback);\n }\n else {\n if (results && results instanceof rowset_1.SQLiteCloudRowset && results.length > 0) {\n callback === null || callback === void 0 ? void 0 : callback.call(this, null, results[0]);\n }\n else {\n callback === null || callback === void 0 ? void 0 : callback.call(this, null);\n }\n }\n });\n }\n });\n return this;\n }\n all(sql, ...params) {\n const { args, callback } = (0, utilities_1.popCallback)(params);\n const preparedSql = (args === null || args === void 0 ? void 0 : args.length) > 0 ? (0, utilities_1.prepareSql)(sql, ...args) : sql;\n this.getConnection((error, connection) => {\n if (error || !connection) {\n this.handleError(null, error, callback);\n }\n else {\n connection.sendCommands(preparedSql, (error, results) => {\n if (error) {\n this.handleError(connection, error, callback);\n }\n else {\n if (results && results instanceof rowset_1.SQLiteCloudRowset) {\n callback === null || callback === void 0 ? void 0 : callback.call(this, null, results);\n }\n else {\n callback === null || callback === void 0 ? void 0 : callback.call(this, null);\n }\n }\n });\n }\n });\n return this;\n }\n each(sql, ...params) {\n // extract optional parameters and one or two callbacks\n const { args, callback, complete } = (0, utilities_1.popCallback)(params);\n const preparedSql = (args === null || args === void 0 ? void 0 : args.length) > 0 ? (0, utilities_1.prepareSql)(sql, ...args) : sql;\n this.getConnection((error, connection) => {\n if (error || !connection) {\n this.handleError(null, error, callback);\n }\n else {\n connection.sendCommands(preparedSql, (error, rowset) => {\n if (error) {\n this.handleError(connection, error, callback);\n }\n else {\n if (rowset && rowset instanceof rowset_1.SQLiteCloudRowset) {\n if (callback) {\n for (const row of rowset) {\n callback.call(this, null, row);\n }\n }\n if (complete) {\n ;\n complete.call(this, null, rowset.numberOfRows);\n }\n }\n else {\n callback === null || callback === void 0 ? void 0 : callback.call(this, new types_1.SQLiteCloudError('Invalid rowset'));\n }\n }\n });\n }\n });\n return this;\n }\n /**\n * Prepares the SQL statement and optionally binds the specified parameters and\n * calls the callback when done. The function returns a Statement object.\n * When preparing was successful, the first and only argument to the callback\n * is null, otherwise it is the error object. When bind parameters are supplied,\n * they are bound to the prepared statement before calling the callback.\n */\n prepare(sql, ...params) {\n const { args, callback } = (0, utilities_1.popCallback)(params);\n return new statement_1.Statement(this, sql, ...args, callback);\n }\n /**\n * Runs all SQL queries in the supplied string. No result rows are retrieved.\n * The function returns the Database object to allow for function chaining.\n * If a query fails, no subsequent statements will be executed (wrap it in a\n * transaction if you want all or none to be executed). When all statements\n * have been executed successfully, or when an error occurs, the callback\n * function is called, with the first parameter being either null or an error\n * object. When no callback is provided and an error occurs, an error event\n * will be emitted on the database object.\n */\n exec(sql, callback) {\n this.getConnection((error, connection) => {\n if (error || !connection) {\n this.handleError(null, error, callback);\n }\n else {\n connection.sendCommands(sql, (error, results) => {\n if (error) {\n this.handleError(connection, error, callback);\n }\n else {\n const context = this.processContext(results);\n callback === null || callback === void 0 ? void 0 : callback.call(context ? context : this, null);\n }\n });\n }\n });\n return this;\n }\n /**\n * If the optional callback is provided, this function will be called when the\n * database was closed successfully or when an error occurred. The first argument\n * is an error object. When it is null, closing succeeded. If no callback is provided\n * and an error occurred, an error event with the error object as the only parameter\n * will be emitted on the database object. If closing succeeded, a close event with no\n * parameters is emitted, regardless of whether a callback was provided or not.\n */\n close(callback) {\n var _a;\n if (((_a = this.connections) === null || _a === void 0 ? void 0 : _a.length) > 0) {\n for (const connection of this.connections) {\n connection.close();\n }\n }\n callback === null || callback === void 0 ? void 0 : callback.call(this, null);\n this.emitEvent('close');\n }\n /**\n * Loads a compiled SQLite extension into the database connection object.\n * @param path Filename of the extension to load.\n * @param callback If provided, this function will be called when the extension\n * was loaded successfully or when an error occurred. The first argument is an\n * error object. When it is null, loading succeeded. If no callback is provided\n * and an error occurred, an error event with the error object as the only parameter\n * will be emitted on the database object.\n */\n loadExtension(_path, callback) {\n // TODO sqlitecloud-js / implement database loadExtension #17\n if (callback) {\n callback.call(this, new Error('Database.loadExtension - Not implemented'));\n }\n else {\n this.emitEvent('error', new Error('Database.loadExtension - Not implemented'));\n }\n return this;\n }\n /**\n * Allows the user to interrupt long-running queries. Wrapper around\n * sqlite3_interrupt and causes other data-fetching functions to be\n * passed an err with code = sqlite3.INTERRUPT. The database must be\n * open to use this function.\n */\n interrupt() {\n // TODO sqlitecloud-js / implement database interrupt #13\n }\n //\n // extended APIs\n //\n /**\n * Sql is a promise based API for executing SQL statements. You can\n * pass a simple string with a SQL statement or a template string\n * using backticks and parameters in ${parameter} format. These parameters\n * will be properly escaped and quoted like when using a prepared statement.\n * @param sql A sql string or a template string in `backticks` format\n * @returns An array of rows in case of selections or an object with\n * metadata in case of insert, update, delete.\n */\n sql(sql, ...values) {\n return __awaiter(this, void 0, void 0, function* () {\n let preparedSql = '';\n // sql is a TemplateStringsArray, the 'raw' property is specific to TemplateStringsArray\n if (Array.isArray(sql) && 'raw' in sql) {\n sql.forEach((string, i) => {\n preparedSql += string + (i < values.length ? '?' : '');\n });\n preparedSql = (0, utilities_1.prepareSql)(preparedSql, ...values);\n }\n else {\n if (typeof sql === 'string') {\n if ((values === null || values === void 0 ? void 0 : values.length) > 0) {\n preparedSql = (0, utilities_1.prepareSql)(sql, ...values);\n }\n else {\n preparedSql = sql;\n }\n }\n else {\n throw new Error('Invalid sql');\n }\n }\n return new Promise((resolve, reject) => {\n this.getConnection((error, connection) => {\n if (error || !connection) {\n reject(error);\n }\n else {\n connection.sendCommands(preparedSql, (error, results) => {\n if (error) {\n reject(error);\n }\n else {\n // metadata for operations like insert, update, delete?\n const context = this.processContext(results);\n resolve(context ? context : results);\n }\n });\n }\n });\n });\n });\n }\n}\nexports.Database = Database;\n\n\n//# sourceURL=webpack://sqlitecloud/./lib/drivers/database.js?");
|
|
63
63
|
|
|
64
64
|
/***/ }),
|
|
65
65
|
|
|
@@ -125,7 +125,7 @@ eval("\n/**\n * types.ts - shared types and interfaces\n */\nObject.defineProper
|
|
|
125
125
|
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
126
126
|
|
|
127
127
|
"use strict";
|
|
128
|
-
eval("\n//\n// utilities.ts - utility methods to manipulate SQL statements\n//\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.parseBoolean = exports.parseConnectionString = exports.validateConfiguration = exports.popCallback = exports.prepareSql = exports.escapeSqlParameter = exports.getInitializationCommands = exports.anonimizeError = exports.anonimizeCommand = exports.isNode = exports.isBrowser = void 0;\nconst types_1 = __webpack_require__(/*! ./types */ \"./lib/drivers/types.js\");\n//\n// determining running environment, thanks to browser-or-node\n// https://www.npmjs.com/package/browser-or-node\n//\nexports.isBrowser = typeof window !== 'undefined' && typeof window.document !== 'undefined';\nexports.isNode = typeof process !== 'undefined' && process.versions != null && process.versions.node != null;\n//\n// utility methods\n//\n/** Messages going to the server are sometimes logged when error conditions occour and need to be stripped of user credentials */\nfunction anonimizeCommand(message) {\n // hide password in AUTH command if needed\n message = message.replace(/USER \\S+/, 'USER ******');\n message = message.replace(/PASSWORD \\S+?(?=;)/, 'PASSWORD ******');\n message = message.replace(/HASH \\S+?(?=;)/, 'HASH ******');\n return message;\n}\nexports.anonimizeCommand = anonimizeCommand;\n/** Strip message code in error of user credentials */\nfunction anonimizeError(error) {\n if (error === null || error === void 0 ? void 0 : error.message) {\n error.message = anonimizeCommand(error.message);\n }\n return error;\n}\nexports.anonimizeError = anonimizeError;\n/** Initialization commands sent to database when connection is established */\nfunction getInitializationCommands(config) {\n // first user authentication, then all other commands\n let commands = `AUTH USER ${config.username || ''} ${config.passwordHashed ? 'HASH' : 'PASSWORD'} ${config.password || ''}; `;\n if (config.database) {\n if (config.createDatabase && !config.dbMemory) {\n commands += `CREATE DATABASE ${config.database} IF NOT EXISTS; `;\n }\n commands += `USE DATABASE ${config.database}; `;\n }\n if (config.compression) {\n commands += 'SET CLIENT KEY COMPRESSION TO 1; ';\n }\n if (config.nonlinearizable) {\n commands += 'SET CLIENT KEY NONLINEARIZABLE TO 1; ';\n }\n if (config.noBlob) {\n commands += 'SET CLIENT KEY NOBLOB TO 1; ';\n }\n if (config.maxData) {\n commands += `SET CLIENT KEY MAXDATA TO ${config.maxData}; `;\n }\n if (config.maxRows) {\n commands += `SET CLIENT KEY MAXROWS TO ${config.maxRows}; `;\n }\n if (config.maxRowset) {\n commands += `SET CLIENT KEY MAXROWSET TO ${config.maxRowset}; `;\n }\n return commands;\n}\nexports.getInitializationCommands = getInitializationCommands;\n/** Takes a generic value and escapes it so it can replace ? as a binding in a prepared SQL statement */\nfunction escapeSqlParameter(param) {\n if (param === null || param === undefined) {\n return 'NULL';\n }\n if (typeof param === 'string') {\n // replace single quote with two single quotes\n param = param.replace(/'/g, \"''\");\n return `'${param}'`;\n }\n if (typeof param === 'number') {\n return param.toString();\n }\n if (typeof param === 'boolean') {\n return param ? '1' : '0';\n }\n // serialize buffer as X'...' hex encoded string\n if (Buffer.isBuffer(param)) {\n return `X'${param.toString('hex')}'`;\n }\n if (typeof param === 'object') {\n // serialize json then escape single quotes\n let json = JSON.stringify(param);\n json = json.replace(/'/g, \"''\");\n return `'${json}'`;\n }\n throw new types_1.SQLiteCloudError(`Unsupported parameter type: ${typeof param}`);\n}\nexports.escapeSqlParameter = escapeSqlParameter;\n/** Take a sql statement and replaces ? or $named parameters that are properly serialized and escaped. */\nfunction prepareSql(sql, ...params) {\n // parameters where passed as an array of parameters?\n if ((params === null || params === void 0 ? void 0 : params.length) === 1 && Array.isArray(params[0])) {\n params = params[0];\n }\n // replace ? or ?idx parameters passed as args or as an array\n let parameterIndex = 1;\n let preparedSql = sql.replace(/\\?(\\d+)?/g, (match, matchIndex) => {\n const index = matchIndex ? parseInt(matchIndex) : parameterIndex;\n parameterIndex++;\n let sqlParameter;\n if (params[0] && typeof params[0] === 'object' && !(params[0] instanceof Buffer)) {\n sqlParameter = params[0][index];\n }\n if (!sqlParameter) {\n if (index > params.length) {\n throw new types_1.SQLiteCloudError('Not enough parameters');\n }\n sqlParameter = params[index - 1];\n }\n return sqlParameter !== null && sqlParameter !== undefined ? escapeSqlParameter(sqlParameter) : 'NULL';\n });\n // replace $named or :named parameters passed as an object\n if ((params === null || params === void 0 ? void 0 : params.length) === 1 && params[0] && typeof params[0] === 'object') {\n const namedParams = params[0];\n for (const [paramKey, param] of Object.entries(namedParams)) {\n const firstChar = paramKey.charAt(0);\n if (firstChar == '$' || firstChar == ':' || firstChar == '@') {\n const escapedParam = escapeSqlParameter(param);\n preparedSql = preparedSql.replace(new RegExp(`\\\\${paramKey}`, 'g'), escapedParam);\n }\n }\n }\n return preparedSql;\n}\nexports.prepareSql = prepareSql;\n/**\n * Many of the methods in our API may contain a callback as their last argument.\n * This method will take the arguments array passed to the method and return an object\n * containing the arguments array with the callbacks removed (if any), and the callback itself.\n * If there are multiple callbacks, the first one is returned as 'callback' and the last one\n * as 'completeCallback'.\n */\nfunction popCallback(args) {\n const remaining = args;\n // at least 1 callback?\n if (args && args.length > 0 && typeof args[args.length - 1] === 'function') {\n // at least 2 callbacks?\n if (args.length > 1 && typeof args[args.length - 2] === 'function') {\n return { args: remaining.slice(0, -2), callback: args[args.length - 2], complete: args[args.length - 1] };\n }\n return { args: remaining.slice(0, -1), callback: args[args.length - 1] };\n }\n return { args: remaining };\n}\nexports.popCallback = popCallback;\n//\n// configuration validation\n//\n/** Validate configuration, apply defaults, throw if something is missing or misconfigured */\nfunction validateConfiguration(config) {\n console.assert(config, 'SQLiteCloudConnection.validateConfiguration - missing config');\n if (config.connectionString) {\n config = Object.assign(Object.assign(Object.assign({}, config), parseConnectionString(config.connectionString)), { connectionString: config.connectionString // keep original connection string\n });\n }\n // apply defaults where needed\n config.port || (config.port = types_1.DEFAULT_PORT);\n config.timeout = config.timeout && config.timeout > 0 ? config.timeout : types_1.DEFAULT_TIMEOUT;\n config.clientId || (config.clientId = 'SQLiteCloud');\n config.verbose = parseBoolean(config.verbose);\n config.noBlob = parseBoolean(config.noBlob);\n config.compression = parseBoolean(config.compression);\n config.createDatabase = parseBoolean(config.createDatabase);\n config.nonlinearizable = parseBoolean(config.nonlinearizable);\n config.insecure = parseBoolean(config.insecure);\n if (!config.username || !config.password || !config.host) {\n console.error('SQLiteCloudConnection.validateConfiguration - missing arguments', config);\n throw new types_1.SQLiteCloudError('The user, password and host arguments must be specified.', { errorCode: 'ERR_MISSING_ARGS' });\n }\n if (!config.connectionString) {\n // build connection string from configuration, values are already validated\n // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n config.connectionString = `sqlitecloud://${encodeURIComponent(config.username)}:${encodeURIComponent(config.password)}@${config.host}:${config.port}/${config.database}`;\n }\n return config;\n}\nexports.validateConfiguration = validateConfiguration;\n/** Parse connectionString like sqlitecloud://username:password@host:port/database?option1=xxx&option2=xxx into its components */\nfunction parseConnectionString(connectionString) {\n try {\n // The URL constructor throws a TypeError if the URL is not valid.\n // in spite of having the same structure as a regular url\n // protocol://username:password@host:port/database?option1=xxx&option2=xxx)\n // the sqlitecloud: protocol is not recognized by the URL constructor in browsers\n // so we need to replace it with https: to make it work\n const knownProtocolUrl = connectionString.replace('sqlitecloud:', 'https:');\n const url = new URL(knownProtocolUrl);\n const options = {};\n url.searchParams.forEach((value, key) => {\n options[key] = value;\n });\n const config = Object.assign({ username: decodeURIComponent(url.username), password: decodeURIComponent(url.password), host: url.hostname, port: url.port ? parseInt(url.port) : undefined }, options);\n const database = url.pathname.replace('/', ''); // pathname is database name, remove the leading slash\n if (database) {\n config.database = database;\n }\n return config;\n }\n catch (error) {\n throw new types_1.SQLiteCloudError(`Invalid connection string: ${connectionString}`);\n }\n}\nexports.parseConnectionString = parseConnectionString;\n/** Returns true if value is 1 or true */\nfunction parseBoolean(value) {\n if (typeof value === 'string') {\n return value.toLowerCase() === 'true' || value === '1';\n }\n return value ? true : false;\n}\nexports.parseBoolean = parseBoolean;\n\n\n//# sourceURL=webpack://sqlitecloud/./lib/drivers/utilities.js?");
|
|
128
|
+
eval("\n//\n// utilities.ts - utility methods to manipulate SQL statements\n//\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.parseBooleanToZeroOne = exports.parseBoolean = exports.parseconnectionstring = exports.validateConfiguration = exports.popCallback = exports.getUpdateResults = exports.prepareSql = exports.escapeSqlParameter = exports.getInitializationCommands = exports.anonimizeError = exports.anonimizeCommand = exports.isNode = exports.isBrowser = void 0;\nconst types_1 = __webpack_require__(/*! ./types */ \"./lib/drivers/types.js\");\nconst types_2 = __webpack_require__(/*! ./types */ \"./lib/drivers/types.js\");\n//\n// determining running environment, thanks to browser-or-node\n// https://www.npmjs.com/package/browser-or-node\n//\nexports.isBrowser = typeof window !== 'undefined' && typeof window.document !== 'undefined';\nexports.isNode = typeof process !== 'undefined' && process.versions != null && process.versions.node != null;\n//\n// utility methods\n//\n/** Messages going to the server are sometimes logged when error conditions occour and need to be stripped of user credentials */\nfunction anonimizeCommand(message) {\n // hide password in AUTH command if needed\n message = message.replace(/USER \\S+/, 'USER ******');\n message = message.replace(/PASSWORD \\S+?(?=;)/, 'PASSWORD ******');\n message = message.replace(/HASH \\S+?(?=;)/, 'HASH ******');\n return message;\n}\nexports.anonimizeCommand = anonimizeCommand;\n/** Strip message code in error of user credentials */\nfunction anonimizeError(error) {\n if (error === null || error === void 0 ? void 0 : error.message) {\n error.message = anonimizeCommand(error.message);\n }\n return error;\n}\nexports.anonimizeError = anonimizeError;\n/** Initialization commands sent to database when connection is established */\nfunction getInitializationCommands(config) {\n // first user authentication, then all other commands\n let commands = '';\n if (config.apikey) {\n commands = `AUTH APIKEY ${config.apikey}; `;\n }\n else {\n commands = `AUTH USER ${config.username || ''} ${config.password_hashed ? 'HASH' : 'PASSWORD'} ${config.password || ''}; `;\n }\n if (config.database) {\n if (config.create && !config.memory) {\n commands += `CREATE DATABASE ${config.database} IF NOT EXISTS; `;\n }\n commands += `USE DATABASE ${config.database}; `;\n }\n if (config.compression) {\n commands += 'SET CLIENT KEY COMPRESSION TO 1; ';\n }\n if (config.zerotext) {\n commands += 'SET CLIENT KEY ZEROTEXT TO 1; ';\n }\n if (config.non_linearizable) {\n commands += 'SET CLIENT KEY NONLINEARIZABLE TO 1; ';\n }\n if (config.noblob) {\n commands += 'SET CLIENT KEY NOBLOB TO 1; ';\n }\n if (config.maxdata) {\n commands += `SET CLIENT KEY MAXDATA TO ${config.maxdata}; `;\n }\n if (config.maxrows) {\n commands += `SET CLIENT KEY MAXROWS TO ${config.maxrows}; `;\n }\n if (config.maxrowset) {\n commands += `SET CLIENT KEY MAXROWSET TO ${config.maxrowset}; `;\n }\n return commands;\n}\nexports.getInitializationCommands = getInitializationCommands;\n/** Takes a generic value and escapes it so it can replace ? as a binding in a prepared SQL statement */\nfunction escapeSqlParameter(param) {\n if (param === null || param === undefined) {\n return 'NULL';\n }\n if (typeof param === 'string') {\n // replace single quote with two single quotes\n param = param.replace(/'/g, \"''\");\n return `'${param}'`;\n }\n if (typeof param === 'number' || typeof param === 'bigint') {\n return param.toString();\n }\n if (typeof param === 'boolean') {\n return param ? '1' : '0';\n }\n // serialize buffer as X'...' hex encoded string\n if (Buffer.isBuffer(param)) {\n return `X'${param.toString('hex')}'`;\n }\n if (typeof param === 'object') {\n // serialize json then escape single quotes\n let json = JSON.stringify(param);\n json = json.replace(/'/g, \"''\");\n return `'${json}'`;\n }\n throw new types_1.SQLiteCloudError(`Unsupported parameter type: ${typeof param}`);\n}\nexports.escapeSqlParameter = escapeSqlParameter;\n/** Take a sql statement and replaces ? or $named parameters that are properly serialized and escaped. */\nfunction prepareSql(sql, ...params) {\n // parameters where passed as an array of parameters?\n if ((params === null || params === void 0 ? void 0 : params.length) === 1 && Array.isArray(params[0])) {\n params = params[0];\n }\n // replace ? or ?idx parameters passed as args or as an array\n let parameterIndex = 1;\n let preparedSql = sql.replace(/\\?(\\d+)?/g, (match, matchIndex) => {\n const index = matchIndex ? parseInt(matchIndex) : parameterIndex;\n parameterIndex++;\n let sqlParameter;\n if (params[0] && typeof params[0] === 'object' && !(params[0] instanceof Buffer)) {\n sqlParameter = params[0][index];\n }\n if (!sqlParameter) {\n if (index > params.length) {\n throw new types_1.SQLiteCloudError('Not enough parameters');\n }\n sqlParameter = params[index - 1];\n }\n return sqlParameter !== null && sqlParameter !== undefined ? escapeSqlParameter(sqlParameter) : 'NULL';\n });\n // replace $named or :named parameters passed as an object\n if ((params === null || params === void 0 ? void 0 : params.length) === 1 && params[0] && typeof params[0] === 'object') {\n const namedParams = params[0];\n for (const [paramKey, param] of Object.entries(namedParams)) {\n const firstChar = paramKey.charAt(0);\n if (firstChar == '$' || firstChar == ':' || firstChar == '@') {\n const escapedParam = escapeSqlParameter(param);\n preparedSql = preparedSql.replace(new RegExp(`\\\\${paramKey}`, 'g'), escapedParam);\n }\n }\n }\n return preparedSql;\n}\nexports.prepareSql = prepareSql;\n/** Converts results of an update or insert call into a more meaning full result set */\nfunction getUpdateResults(results) {\n if (results) {\n if (Array.isArray(results) && results.length > 0) {\n switch (results[0]) {\n case types_2.SQLiteCloudArrayType.ARRAY_TYPE_SQLITE_EXEC:\n return {\n type: results[0],\n index: results[1],\n lastID: results[2],\n changes: results[3],\n totalChanges: results[4],\n finalized: results[5],\n //\n rowId: results[2] // same as lastId\n };\n }\n }\n }\n return undefined;\n}\nexports.getUpdateResults = getUpdateResults;\n/**\n * Many of the methods in our API may contain a callback as their last argument.\n * This method will take the arguments array passed to the method and return an object\n * containing the arguments array with the callbacks removed (if any), and the callback itself.\n * If there are multiple callbacks, the first one is returned as 'callback' and the last one\n * as 'completeCallback'.\n */\nfunction popCallback(args) {\n const remaining = args;\n // at least 1 callback?\n if (args && args.length > 0 && typeof args[args.length - 1] === 'function') {\n // at least 2 callbacks?\n if (args.length > 1 && typeof args[args.length - 2] === 'function') {\n return { args: remaining.slice(0, -2), callback: args[args.length - 2], complete: args[args.length - 1] };\n }\n return { args: remaining.slice(0, -1), callback: args[args.length - 1] };\n }\n return { args: remaining };\n}\nexports.popCallback = popCallback;\n//\n// configuration validation\n//\n/** Validate configuration, apply defaults, throw if something is missing or misconfigured */\nfunction validateConfiguration(config) {\n console.assert(config, 'SQLiteCloudConnection.validateConfiguration - missing config');\n if (config.connectionstring) {\n config = Object.assign(Object.assign(Object.assign({}, config), parseconnectionstring(config.connectionstring)), { connectionstring: config.connectionstring // keep original connection string\n });\n }\n // apply defaults where needed\n config.port || (config.port = types_1.DEFAULT_PORT);\n config.timeout = config.timeout && config.timeout > 0 ? config.timeout : types_1.DEFAULT_TIMEOUT;\n config.clientid || (config.clientid = 'SQLiteCloud');\n config.verbose = parseBoolean(config.verbose);\n config.noblob = parseBoolean(config.noblob);\n config.compression = parseBoolean(config.compression);\n config.create = parseBoolean(config.create);\n config.non_linearizable = parseBoolean(config.non_linearizable);\n config.insecure = parseBoolean(config.insecure);\n const hasCredentials = (config.username && config.password) || config.apikey;\n if (!config.host || !hasCredentials) {\n console.error('SQLiteCloudConnection.validateConfiguration - missing arguments', config);\n throw new types_1.SQLiteCloudError('The user, password and host arguments or the ?apikey= must be specified.', { errorCode: 'ERR_MISSING_ARGS' });\n }\n if (!config.connectionstring) {\n // build connection string from configuration, values are already validated\n // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n if (config.apikey) {\n config.connectionstring = `sqlitecloud://${config.host}:${config.port}/${config.database || ''}?apikey=${config.apikey}`;\n }\n else {\n config.connectionstring = `sqlitecloud://${encodeURIComponent(config.username || '')}:${encodeURIComponent(config.password || '')}@${config.host}:${config.port}/${config.database}`;\n }\n }\n return config;\n}\nexports.validateConfiguration = validateConfiguration;\n/**\n * Parse connectionstring like sqlitecloud://username:password@host:port/database?option1=xxx&option2=xxx\n * or sqlitecloud://host.sqlite.cloud:8860/chinook.sqlite?apikey=mIiLARzKm9XBVllbAzkB1wqrgijJ3Gx0X5z1Agm3xBo\n * into its basic components.\n */\nfunction parseconnectionstring(connectionstring) {\n try {\n // The URL constructor throws a TypeError if the URL is not valid.\n // in spite of having the same structure as a regular url\n // protocol://username:password@host:port/database?option1=xxx&option2=xxx)\n // the sqlitecloud: protocol is not recognized by the URL constructor in browsers\n // so we need to replace it with https: to make it work\n const knownProtocolUrl = connectionstring.replace('sqlitecloud:', 'https:');\n const url = new URL(knownProtocolUrl);\n // all lowecase options\n const options = {};\n url.searchParams.forEach((value, key) => {\n options[key.toLowerCase().replaceAll('-', '_')] = value;\n });\n const config = Object.assign({ username: decodeURIComponent(url.username), password: decodeURIComponent(url.password), host: url.hostname, port: url.port ? parseInt(url.port) : undefined }, options);\n // either you use an apikey or username and password\n if (config.apikey) {\n if (config.username || config.password) {\n console.warn('SQLiteCloudConnection.parseconnectionstring - apikey and username/password are both specified, using apikey');\n }\n delete config.username;\n delete config.password;\n }\n const database = url.pathname.replace('/', ''); // pathname is database name, remove the leading slash\n if (database) {\n config.database = database;\n }\n return config;\n }\n catch (error) {\n throw new types_1.SQLiteCloudError(`Invalid connection string: ${connectionstring}`);\n }\n}\nexports.parseconnectionstring = parseconnectionstring;\n/** Returns true if value is 1 or true */\nfunction parseBoolean(value) {\n if (typeof value === 'string') {\n return value.toLowerCase() === 'true' || value === '1';\n }\n return value ? true : false;\n}\nexports.parseBoolean = parseBoolean;\n/** Returns true if value is 1 or true */\nfunction parseBooleanToZeroOne(value) {\n if (typeof value === 'string') {\n return value.toLowerCase() === 'true' || value === '1' ? 1 : 0;\n }\n return value ? 1 : 0;\n}\nexports.parseBooleanToZeroOne = parseBooleanToZeroOne;\n\n\n//# sourceURL=webpack://sqlitecloud/./lib/drivers/utilities.js?");
|
|
129
129
|
|
|
130
130
|
/***/ }),
|
|
131
131
|
|
|
@@ -136,7 +136,7 @@ eval("\n//\n// utilities.ts - utility methods to manipulate SQL statements\n//\n
|
|
|
136
136
|
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
137
137
|
|
|
138
138
|
"use strict";
|
|
139
|
-
eval("\n//\n// index.ts - export drivers classes, utilities, types\n//\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.validateConfiguration = exports.
|
|
139
|
+
eval("\n//\n// index.ts - export drivers classes, utilities, types\n//\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\nexports.validateConfiguration = exports.parseconnectionstring = exports.prepareSql = exports.escapeSqlParameter = exports.SQLiteCloudRow = exports.SQLiteCloudRowset = exports.SQLiteCloudError = exports.SQLiteCloudConnection = exports.Statement = exports.Database = void 0;\n// include ONLY packages used by drivers\n// do NOT include anything related to gateway or bun or express\n// connection-tls does not want/need to load on browser and is loaded dynamically by Database\n// connection-ws does not want/need to load on node and is loaded dynamically by Database\nvar database_1 = __webpack_require__(/*! ./drivers/database */ \"./lib/drivers/database.js\");\nObject.defineProperty(exports, \"Database\", ({ enumerable: true, get: function () { return database_1.Database; } }));\nvar statement_1 = __webpack_require__(/*! ./drivers/statement */ \"./lib/drivers/statement.js\");\nObject.defineProperty(exports, \"Statement\", ({ enumerable: true, get: function () { return statement_1.Statement; } }));\nvar connection_1 = __webpack_require__(/*! ./drivers/connection */ \"./lib/drivers/connection.js\");\nObject.defineProperty(exports, \"SQLiteCloudConnection\", ({ enumerable: true, get: function () { return connection_1.SQLiteCloudConnection; } }));\nvar types_1 = __webpack_require__(/*! ./drivers/types */ \"./lib/drivers/types.js\");\nObject.defineProperty(exports, \"SQLiteCloudError\", ({ enumerable: true, get: function () { return types_1.SQLiteCloudError; } }));\nvar rowset_1 = __webpack_require__(/*! ./drivers/rowset */ \"./lib/drivers/rowset.js\");\nObject.defineProperty(exports, \"SQLiteCloudRowset\", ({ enumerable: true, get: function () { return rowset_1.SQLiteCloudRowset; } }));\nObject.defineProperty(exports, \"SQLiteCloudRow\", ({ enumerable: true, get: function () { return rowset_1.SQLiteCloudRow; } }));\nvar utilities_1 = __webpack_require__(/*! ./drivers/utilities */ \"./lib/drivers/utilities.js\");\nObject.defineProperty(exports, \"escapeSqlParameter\", ({ enumerable: true, get: function () { return utilities_1.escapeSqlParameter; } }));\nObject.defineProperty(exports, \"prepareSql\", ({ enumerable: true, get: function () { return utilities_1.prepareSql; } }));\nObject.defineProperty(exports, \"parseconnectionstring\", ({ enumerable: true, get: function () { return utilities_1.parseconnectionstring; } }));\nObject.defineProperty(exports, \"validateConfiguration\", ({ enumerable: true, get: function () { return utilities_1.validateConfiguration; } }));\n\n\n//# sourceURL=webpack://sqlitecloud/./lib/index.js?");
|
|
140
140
|
|
|
141
141
|
/***/ }),
|
|
142
142
|
|