UNPKG

@142vip/data-source

Version:

通用型数据源,支持多种数据库、API、CSV等形式的数据源管理

1,663 lines (1,532 loc) 857 kB
'use strict'; const aliyunApiGateway = require('aliyun-api-gateway'); const axios = require('axios'); const crypto = require('node:crypto'); const clickhouse = require('clickhouse'); const lodash = require('lodash'); const pg = require('pg'); const mongodb = require('mongodb'); const require$$0$3 = require('events'); const require$$0$2 = require('process'); const require$$0$6 = require('net'); const require$$1$3 = require('tls'); const require$$1$1 = require('timers'); const require$$2 = require('stream'); const require$$1 = require('buffer'); const require$$0 = require('iconv-lite'); const require$$0$1 = require('crypto'); const require$$0$4 = require('zlib'); const require$$1$2 = require('util'); const require$$0$5 = require('url'); const os = require('node:os'); const sqlServer = require('mssql'); const sync = require('csv-parse/sync'); const jsCharDet = require('jschardet'); function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; } const axios__default = /*#__PURE__*/_interopDefaultCompat(axios); const crypto__default = /*#__PURE__*/_interopDefaultCompat(crypto); const require$$0__default$3 = /*#__PURE__*/_interopDefaultCompat(require$$0$3); const require$$0__default$2 = /*#__PURE__*/_interopDefaultCompat(require$$0$2); const require$$0__default$6 = /*#__PURE__*/_interopDefaultCompat(require$$0$6); const require$$1__default$3 = /*#__PURE__*/_interopDefaultCompat(require$$1$3); const require$$1__default$1 = /*#__PURE__*/_interopDefaultCompat(require$$1$1); const require$$2__default = /*#__PURE__*/_interopDefaultCompat(require$$2); const require$$1__default = /*#__PURE__*/_interopDefaultCompat(require$$1); const require$$0__default = /*#__PURE__*/_interopDefaultCompat(require$$0); const require$$0__default$1 = /*#__PURE__*/_interopDefaultCompat(require$$0$1); const require$$0__default$4 = /*#__PURE__*/_interopDefaultCompat(require$$0$4); const require$$1__default$2 = /*#__PURE__*/_interopDefaultCompat(require$$1$2); const require$$0__default$5 = /*#__PURE__*/_interopDefaultCompat(require$$0$5); const os__default = /*#__PURE__*/_interopDefaultCompat(os); const sqlServer__default = /*#__PURE__*/_interopDefaultCompat(sqlServer); const jsCharDet__default = /*#__PURE__*/_interopDefaultCompat(jsCharDet); function testURL(url) { return /(?:http|ftp|https):\/\/[\w\-]+(?:\.[\w\-]+)+(?:[\w\-.,@?^=%&:/~+#]*[\w\-@?^=%&/~+#])?/.test(url); } function checkPasswordIsNil(password) { return isEmpty(password) ? { password: null } : { password: "******" }; } function isEmpty(value) { return value == null || value === ""; } function handlerDataSourceConnectError(dataSourceName, error) { let message = `${dataSourceName}\u6570\u636E\u6E90\uFF0C\u6267\u884C\u5931\u8D25`; if (!isEmpty(error?.message)) { message = JSON.stringify(error.message); } return { success: false, message }; } const AliGateway_API_TIMEOUT = 3e4; class VipAliGatewayApi { /** * 获取连接数据 */ async getConnectionData(params) { try { const aliClient = new aliyunApiGateway.Client(params.appKey, params.appSecret); const data = await aliClient[params.method](params.url, { timeout: AliGateway_API_TIMEOUT, data: params.bodyParams, headers: params.headerParams }); return { success: true, data }; } catch (error) { return handlerDataSourceConnectError(VipAliGatewayApi.name, error); } } } class VipHttpApi { /** * 获取连接数据 */ async getConnectionData(options) { const { data, status } = await axios__default(options); if (status === 200) { return data; } return { success: false }; } } const DEFAULT_DTABLE_API_URL = "https://oapi.dtable.cloud/v0"; const DEFAULT_MAX_RECORDS = 1e3; class VipDTableApi { vipHttpApi = new VipHttpApi(); /** * 获取连接数据 */ async getConnectionData(options) { try { const data = await this.getTableAllRecords(options); return { success: true, data }; } catch (error) { return handlerDataSourceConnectError(VipDTableApi.name, error); } } /** * 并发获取所有记录,提高获取速度 * @param options */ async getConnectionDataByConcurrency(options) { try { const data = await this.getTableAllRecordsByConcurrency(options); return { success: true, data }; } catch (error) { return handlerDataSourceConnectError(VipDTableApi.name, error); } } /** * 获取分页表总数量 * @private */ async getPaginationTotal(options) { const apiConfig = this.getApiConfig(options, { page: 1, size: 5 }); const data = await this.vipHttpApi.getConnectionData(apiConfig); return data.data?.total ?? 0; } /** * 循环获取所有记录,同步获取 */ async getTableAllRecords(options) { const total = await this.getPaginationTotal(options); const maxPageSize = this.getMaxPageSize(options.maxRecords); const pageCount = Math.ceil(total / maxPageSize); const allFields = []; for (let page = 1; page <= pageCount; page++) { const apiConfig = this.getApiConfig(options, { page, size: maxPageSize }); const data = await this.vipHttpApi.getConnectionData(apiConfig); const currentFields = data.data?.records.map((record) => record.fields) ?? []; allFields.push(...currentFields); } return allFields; } /** * 并发获取所有记录,提高获取速度 */ async getTableAllRecordsByConcurrency(options) { const total = await this.getPaginationTotal(options); const maxPageSize = this.getMaxPageSize(options.maxRecords); const pageCount = Math.ceil(total / maxPageSize); const promises = Array.from({ length: pageCount }, (_, index) => { const page = index + 1; const apiConfig = this.getApiConfig(options, { page, size: maxPageSize }); return this.vipHttpApi.getConnectionData(apiConfig).then((data) => data.data?.records.map((record) => record.fields) ?? []); }); const allFlatFields = await Promise.all(promises); return allFlatFields.flat(); } /** * 分页最大数量 * @private */ getMaxPageSize(maxRecords) { if (maxRecords == null || maxRecords <= 0 || maxRecords > DEFAULT_MAX_RECORDS) { return DEFAULT_MAX_RECORDS; } return maxRecords; } /** * 获取请求配置 * @private */ getApiConfig(options, pageOptions) { return { url: `${DEFAULT_DTABLE_API_URL}/tables/${options.tableId}/records`, method: "GET", params: { view_id: options.viewId, page: pageOptions?.page ?? 1, size: pageOptions?.size ?? 1e3 }, headers: { Authorization: `Bearer ${options.apiKey}` } }; } } class VipDtStackApi { /** * 获取连接数据 */ async getConnectionData(options) { try { const apiConfig = this.getConfig(options); return new VipHttpApi().getConnectionData(apiConfig); } catch (error) { return handlerDataSourceConnectError(VipDtStackApi.name, error); } } /** * 获取数栈请求时配置 * @param apiParams * @private */ getConfig(apiParams) { const timestamp = (/* @__PURE__ */ new Date()).getDate().toString(); const signToStr = [ ...Object.entries(apiParams.bodyParams), ...Object.entries(apiParams.headerParams), ...Object.entries(apiParams.queryParams), ["X-Auth-Key", apiParams.appKey], ["X-Auth-ActionId", apiParams.apiId], ["X-Auth-Timestamp", timestamp] ].sort().map(([key, value]) => { return `${key}=${value}`; }).concat(apiParams.appSecret).join("&"); const signature = this.getSignature(signToStr); const baseUrl = new URL(apiParams.url); baseUrl.pathname = apiParams.pathParams.replace(/^\//, ""); const apiUrl = baseUrl.toString(); return { url: apiUrl, method: apiParams.method, // query参数 params: apiParams.queryParams, // body参数 data: apiParams.bodyParams, // timeout: APIDTSightConfig.API_TIMEOUT * 1000, headers: { ...apiParams.headerParams, "X-Auth-Key": apiParams.appKey, "X-Auth-ActionId": apiParams.apiId, "X-Auth-Signature": signature, "X-Auth-Timestamp": timestamp } }; } /** * 字符串进行MD5加密 * - 数栈请求数据,加密获取签名 */ getSignature(strToSign) { return crypto__default.createHash("md5").update(strToSign, "utf8").digest("hex"); } } class VipClickhouse { /** * 获取连接数据 */ async getConnectionData(options) { try { const ch = new clickhouse.ClickHouse({ url: options.host, port: options.port, basicAuth: { username: options.username, password: options.password }, config: { session_timeout: 60, enable_http_compression: 0, database: options.database } }); const data = await ch.query(options.querySql).toPromise(); return { success: true, data }; } catch (error) { return handlerDataSourceConnectError(VipClickhouse.name, error); } } } class VipDameng { /** * 获取连接数据 */ async getConnectionData(options) { const dmdb = require("dmdb"); let connection; let dmPool; try { dmdb.fetchAsString = [dmdb.CLOB, dmdb.BUFFER]; dmdb.fetchAsBuffer = [dmdb.BLOB]; dmPool = await dmdb.createPool({ connectString: `dm://${options.username}:${options.password}@${options.host}:${options.port}`, poolMax: 10, poolMin: 1 }); connection = await dmPool.getConnection(); const result = await connection.execute(options.querySql, [], { outFormat: dmdb.OUT_FORMAT_OBJECT }); const data = result.rows?.map( (item) => lodash.mapValues(item, (value) => typeof value === "bigint" ? value.toString() : value) ); return { success: true, data }; } catch (error) { return handlerDataSourceConnectError(VipDameng.name, error); } finally { await dmPool?.close(); await connection?.close(); } } } class VipIbmDB { /** * 获取连接数据 */ async getConnectionData(options) { const ibmDB = require("ibm_db"); let connection; try { connection = ibmDB(); const connectURL = this.getConnectURL(options); await connection.open(connectURL); } catch (error) { return handlerDataSourceConnectError(VipIbmDB.name, error); } try { const data = await connection.query(options.querySql); return { success: true, data }; } catch (error) { return handlerDataSourceConnectError(VipIbmDB.name, error); } finally { await connection.close(); } } /** * 获取链接URL * @param options * @private */ getConnectURL(options) { return `DATABASE=${options.database};HOSTNAME=${options.host};PORT=${options.port};PROTOCOL=TCPIP;UID=${options.username};PWD=${options.password}`; } } class VipKingBase { /** * 获取连接数据 */ async getConnectionData(options) { let connection; try { connection = new pg.Pool({ host: options.host, port: options.port, database: options.database, user: options.username, password: options.password }); const queryResult = await connection.query(options.querySql); const data = queryResult.rows != null ? queryResult.rows : []; return { success: true, data }; } catch (error) { return handlerDataSourceConnectError(VipKingBase.name, error); } finally { await connection?.end(); } } } const MONGO_DEFAULT_TIMEOUT = 60 * 1e3; class VipMongo { /** * 获取连接数据 */ async getConnectionData(options) { let client; try { client = await this.getMongoClient(options); const mongoDB = client.db(options.database); return await this.findTableData(mongoDB, options); } catch (error) { return handlerDataSourceConnectError(VipMongo.name, error); } finally { await client?.close(); } } /** * 查询表中的数据 * @private */ async findTableData(mongoDB, options) { const filter = options.findFilter == null ? {} : options.findFilter; const findOptions = { maxTimeMS: MONGO_DEFAULT_TIMEOUT, ...options.findOptions == null ? {} : options.findOptions }; const data = await mongoDB.collection(options.table).find(filter, findOptions).toArray(); return { success: true, data }; } /** * 建立连接,获取MongoDB客户端 * @private */ async getMongoClient(options) { const url = `mongodb://${options.host}:${options.port}`; return await mongodb.MongoClient.connect(url, { auth: { username: options.username, password: options.password } }); } } function getDefaultExportFromCjs (x) { return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; } function getAugmentedNamespace(n) { if (n.__esModule) return n; var f = n.default; if (typeof f == "function") { var a = function a () { if (this instanceof a) { return Reflect.construct(f, arguments, this.constructor); } return f.apply(this, arguments); }; a.prototype = f.prototype; } else a = {}; Object.defineProperty(a, '__esModule', {value: true}); Object.keys(n).forEach(function (k) { var d = Object.getOwnPropertyDescriptor(n, k); Object.defineProperty(a, k, d.get ? d : { enumerable: true, get: function () { return n[k]; } }); }); return a; } var promise = {}; var SqlString = {}; var hasRequiredSqlString; function requireSqlString () { if (hasRequiredSqlString) return SqlString; hasRequiredSqlString = 1; (function (exports) { var SqlString = exports; var ID_GLOBAL_REGEXP = /`/g; var QUAL_GLOBAL_REGEXP = /\./g; var CHARS_GLOBAL_REGEXP = /[\0\b\t\n\r\x1a\"\'\\]/g; // eslint-disable-line no-control-regex var CHARS_ESCAPE_MAP = { '\0' : '\\0', '\b' : '\\b', '\t' : '\\t', '\n' : '\\n', '\r' : '\\r', '\x1a' : '\\Z', '"' : '\\"', '\'' : '\\\'', '\\' : '\\\\' }; SqlString.escapeId = function escapeId(val, forbidQualified) { if (Array.isArray(val)) { var sql = ''; for (var i = 0; i < val.length; i++) { sql += (i === 0 ? '' : ', ') + SqlString.escapeId(val[i], forbidQualified); } return sql; } else if (forbidQualified) { return '`' + String(val).replace(ID_GLOBAL_REGEXP, '``') + '`'; } else { return '`' + String(val).replace(ID_GLOBAL_REGEXP, '``').replace(QUAL_GLOBAL_REGEXP, '`.`') + '`'; } }; SqlString.escape = function escape(val, stringifyObjects, timeZone) { if (val === undefined || val === null) { return 'NULL'; } switch (typeof val) { case 'boolean': return (val) ? 'true' : 'false'; case 'number': return val + ''; case 'object': if (Object.prototype.toString.call(val) === '[object Date]') { return SqlString.dateToString(val, timeZone || 'local'); } else if (Array.isArray(val)) { return SqlString.arrayToList(val, timeZone); } else if (Buffer.isBuffer(val)) { return SqlString.bufferToString(val); } else if (typeof val.toSqlString === 'function') { return String(val.toSqlString()); } else if (stringifyObjects) { return escapeString(val.toString()); } else { return SqlString.objectToValues(val, timeZone); } default: return escapeString(val); } }; SqlString.arrayToList = function arrayToList(array, timeZone) { var sql = ''; for (var i = 0; i < array.length; i++) { var val = array[i]; if (Array.isArray(val)) { sql += (i === 0 ? '' : ', ') + '(' + SqlString.arrayToList(val, timeZone) + ')'; } else { sql += (i === 0 ? '' : ', ') + SqlString.escape(val, true, timeZone); } } return sql; }; SqlString.format = function format(sql, values, stringifyObjects, timeZone) { if (values == null) { return sql; } if (!Array.isArray(values)) { values = [values]; } var chunkIndex = 0; var placeholdersRegex = /\?+/g; var result = ''; var valuesIndex = 0; var match; while (valuesIndex < values.length && (match = placeholdersRegex.exec(sql))) { var len = match[0].length; if (len > 2) { continue; } var value = len === 2 ? SqlString.escapeId(values[valuesIndex]) : SqlString.escape(values[valuesIndex], stringifyObjects, timeZone); result += sql.slice(chunkIndex, match.index) + value; chunkIndex = placeholdersRegex.lastIndex; valuesIndex++; } if (chunkIndex === 0) { // Nothing was replaced return sql; } if (chunkIndex < sql.length) { return result + sql.slice(chunkIndex); } return result; }; SqlString.dateToString = function dateToString(date, timeZone) { var dt = new Date(date); if (isNaN(dt.getTime())) { return 'NULL'; } var year; var month; var day; var hour; var minute; var second; var millisecond; if (timeZone === 'local') { year = dt.getFullYear(); month = dt.getMonth() + 1; day = dt.getDate(); hour = dt.getHours(); minute = dt.getMinutes(); second = dt.getSeconds(); millisecond = dt.getMilliseconds(); } else { var tz = convertTimezone(timeZone); if (tz !== false && tz !== 0) { dt.setTime(dt.getTime() + (tz * 60000)); } year = dt.getUTCFullYear(); month = dt.getUTCMonth() + 1; day = dt.getUTCDate(); hour = dt.getUTCHours(); minute = dt.getUTCMinutes(); second = dt.getUTCSeconds(); millisecond = dt.getUTCMilliseconds(); } // YYYY-MM-DD HH:mm:ss.mmm var str = zeroPad(year, 4) + '-' + zeroPad(month, 2) + '-' + zeroPad(day, 2) + ' ' + zeroPad(hour, 2) + ':' + zeroPad(minute, 2) + ':' + zeroPad(second, 2) + '.' + zeroPad(millisecond, 3); return escapeString(str); }; SqlString.bufferToString = function bufferToString(buffer) { return 'X' + escapeString(buffer.toString('hex')); }; SqlString.objectToValues = function objectToValues(object, timeZone) { var sql = ''; for (var key in object) { var val = object[key]; if (typeof val === 'function') { continue; } sql += (sql.length === 0 ? '' : ', ') + SqlString.escapeId(key) + ' = ' + SqlString.escape(val, true, timeZone); } return sql; }; SqlString.raw = function raw(sql) { if (typeof sql !== 'string') { throw new TypeError('argument sql must be a string'); } return { toSqlString: function toSqlString() { return sql; } }; }; function escapeString(val) { var chunkIndex = CHARS_GLOBAL_REGEXP.lastIndex = 0; var escapedVal = ''; var match; while ((match = CHARS_GLOBAL_REGEXP.exec(val))) { escapedVal += val.slice(chunkIndex, match.index) + CHARS_ESCAPE_MAP[match[0]]; chunkIndex = CHARS_GLOBAL_REGEXP.lastIndex; } if (chunkIndex === 0) { // Nothing was escaped return "'" + val + "'"; } if (chunkIndex < val.length) { return "'" + escapedVal + val.slice(chunkIndex) + "'"; } return "'" + escapedVal + "'"; } function zeroPad(number, length) { number = number.toString(); while (number.length < length) { number = '0' + number; } return number; } function convertTimezone(tz) { if (tz === 'Z') { return 0; } var m = tz.match(/([\+\-\s])(\d\d):?(\d\d)?/); if (m) { return (m[1] === '-' ? -1 : 1) * (parseInt(m[2], 10) + ((m[3] ? parseInt(m[3], 10) : 0) / 60)) * 60; } return false; } } (SqlString)); return SqlString; } var sqlstring; var hasRequiredSqlstring; function requireSqlstring () { if (hasRequiredSqlstring) return sqlstring; hasRequiredSqlstring = 1; sqlstring = requireSqlString(); return sqlstring; } var lib$2 = {}; var hasRequiredLib$1; function requireLib$1 () { if (hasRequiredLib$1) return lib$2; hasRequiredLib$1 = 1; Object.defineProperty(lib$2, "__esModule", { value: true }); lib$2.createLRU = void 0; const createLRU = (options) => { let { max, onEviction } = options; if (!(Number.isInteger(max) && max > 0)) throw new TypeError('`max` must be a positive integer'); let size = 0; let head = 0; let tail = 0; let free = []; const keyMap = new Map(); const keyList = new Array(max).fill(undefined); const valList = new Array(max).fill(undefined); const next = new Array(max).fill(0); const prev = new Array(max).fill(0); const setTail = (index, type) => { if (index === tail) return; const nextIndex = next[index]; const prevIndex = prev[index]; if (index === head) head = nextIndex; else if (type === 'get' || prevIndex !== 0) next[prevIndex] = nextIndex; if (nextIndex !== 0) prev[nextIndex] = prevIndex; next[tail] = index; prev[index] = tail; next[index] = 0; tail = index; }; const _evict = () => { const evictHead = head; const key = keyList[evictHead]; onEviction === null || onEviction === void 0 ? void 0 : onEviction(key, valList[evictHead]); keyMap.delete(key); keyList[evictHead] = undefined; valList[evictHead] = undefined; head = next[evictHead]; if (head !== 0) prev[head] = 0; size--; if (size === 0) head = tail = 0; free.push(evictHead); return evictHead; }; return { /** Adds a key-value pair to the cache. Updates the value if the key already exists. */ set(key, value) { if (key === undefined) return; let index = keyMap.get(key); if (index === undefined) { index = size === max ? _evict() : free.length > 0 ? free.pop() : size; keyMap.set(key, index); keyList[index] = key; size++; } else onEviction === null || onEviction === void 0 ? void 0 : onEviction(key, valList[index]); valList[index] = value; if (size === 1) head = tail = index; else setTail(index, 'set'); }, /** Retrieves the value for a given key and moves the key to the most recent position. */ get(key) { const index = keyMap.get(key); if (index === undefined) return; if (index !== tail) setTail(index, 'get'); return valList[index]; }, /** Retrieves the value for a given key without changing its position. */ peek: (key) => { const index = keyMap.get(key); return index !== undefined ? valList[index] : undefined; }, /** Checks if a key exists in the cache. */ has: (key) => keyMap.has(key), /** Iterates over all keys in the cache, from most recent to least recent. */ *keys() { let current = tail; for (let i = 0; i < size; i++) { yield keyList[current]; current = prev[current]; } }, /** Iterates over all values in the cache, from most recent to least recent. */ *values() { let current = tail; for (let i = 0; i < size; i++) { yield valList[current]; current = prev[current]; } }, /** Iterates over `[key, value]` pairs in the cache, from most recent to least recent. */ *entries() { let current = tail; for (let i = 0; i < size; i++) { yield [keyList[current], valList[current]]; current = prev[current]; } }, /** Iterates over each value-key pair in the cache, from most recent to least recent. */ forEach: (callback) => { let current = tail; for (let i = 0; i < size; i++) { const key = keyList[current]; const value = valList[current]; callback(value, key); current = prev[current]; } }, /** Deletes a key-value pair from the cache. */ delete(key) { const index = keyMap.get(key); if (index === undefined) return false; onEviction === null || onEviction === void 0 ? void 0 : onEviction(key, valList[index]); keyMap.delete(key); free.push(index); keyList[index] = undefined; valList[index] = undefined; const prevIndex = prev[index]; const nextIndex = next[index]; if (prevIndex !== 0) next[prevIndex] = nextIndex; if (nextIndex !== 0) prev[nextIndex] = prevIndex; if (index === head) head = nextIndex; if (index === tail) tail = prevIndex; size--; return true; }, /** Evicts the oldest item or the specified number of the oldest items from the cache. */ evict: (number) => { let toPrune = Math.min(number, size); while (toPrune > 0) { _evict(); toPrune--; } }, /** Clears all key-value pairs from the cache. */ clear() { if (typeof onEviction === 'function') { const iterator = keyMap.values(); for (let result = iterator.next(); !result.done; result = iterator.next()) onEviction(keyList[result.value], valList[result.value]); } keyMap.clear(); keyList.fill(undefined); valList.fill(undefined); free = []; size = 0; head = tail = 0; }, /** Resizes the cache to a new maximum size, evicting items if necessary. */ resize: (newMax) => { if (!(Number.isInteger(newMax) && newMax > 0)) throw new TypeError('`max` must be a positive integer'); if (newMax === max) return; if (newMax < max) { let current = tail; const preserve = Math.min(size, newMax); const remove = size - preserve; const newKeyList = new Array(newMax); const newValList = new Array(newMax); const newNext = new Array(newMax); const newPrev = new Array(newMax); for (let i = 1; i <= remove; i++) onEviction === null || onEviction === void 0 ? void 0 : onEviction(keyList[i], valList[i]); for (let i = preserve - 1; i >= 0; i--) { newKeyList[i] = keyList[current]; newValList[i] = valList[current]; newNext[i] = i + 1; newPrev[i] = i - 1; keyMap.set(newKeyList[i], i); current = prev[current]; } head = 0; tail = preserve - 1; size = preserve; keyList.length = newMax; valList.length = newMax; next.length = newMax; prev.length = newMax; for (let i = 0; i < preserve; i++) { keyList[i] = newKeyList[i]; valList[i] = newValList[i]; next[i] = newNext[i]; prev[i] = newPrev[i]; } free = []; for (let i = preserve; i < newMax; i++) free.push(i); } else { const fill = newMax - max; keyList.push(...new Array(fill).fill(undefined)); valList.push(...new Array(fill).fill(undefined)); next.push(...new Array(fill).fill(0)); prev.push(...new Array(fill).fill(0)); } max = newMax; }, /** Returns the maximum number of items that can be stored in the cache. */ get max() { return max; }, /** Returns the number of items currently stored in the cache. */ get size() { return size; }, /** Returns the number of currently available slots in the cache before reaching the maximum size. */ get available() { return max - size; }, }; }; lib$2.createLRU = createLRU; return lib$2; } var parser_cache; var hasRequiredParser_cache; function requireParser_cache () { if (hasRequiredParser_cache) return parser_cache; hasRequiredParser_cache = 1; const { createLRU } = requireLib$1(); const parserCache = createLRU({ max: 15000, }); function keyFromFields(type, fields, options, config) { const res = [ type, typeof options.nestTables, options.nestTables, Boolean(options.rowsAsArray), Boolean(options.supportBigNumbers || config.supportBigNumbers), Boolean(options.bigNumberStrings || config.bigNumberStrings), typeof options.typeCast, options.timezone || config.timezone, Boolean(options.decimalNumbers), options.dateStrings, ]; for (let i = 0; i < fields.length; ++i) { const field = fields[i]; res.push([ field.name, field.columnType, field.length, field.schema, field.table, field.flags, field.characterSet, ]); } return JSON.stringify(res, null, 0); } function getParser(type, fields, options, config, compiler) { const key = keyFromFields(type, fields, options, config); let parser = parserCache.get(key); if (parser) { return parser; } parser = compiler(fields, options, config); parserCache.set(key, parser); return parser; } function setMaxCache(max) { parserCache.resize(max); } function clearCache() { parserCache.clear(); } parser_cache = { getParser: getParser, setMaxCache: setMaxCache, clearCache: clearCache, _keyFromFields: keyFromFields, }; return parser_cache; } var denque; var hasRequiredDenque; function requireDenque () { if (hasRequiredDenque) return denque; hasRequiredDenque = 1; /** * Custom implementation of a double ended queue. */ function Denque(array, options) { var options = options || {}; this._capacity = options.capacity; this._head = 0; this._tail = 0; if (Array.isArray(array)) { this._fromArray(array); } else { this._capacityMask = 0x3; this._list = new Array(4); } } /** * -------------- * PUBLIC API * ------------- */ /** * Returns the item at the specified index from the list. * 0 is the first element, 1 is the second, and so on... * Elements at negative values are that many from the end: -1 is one before the end * (the last element), -2 is two before the end (one before last), etc. * @param index * @returns {*} */ Denque.prototype.peekAt = function peekAt(index) { var i = index; // expect a number or return undefined if ((i !== (i | 0))) { return void 0; } var len = this.size(); if (i >= len || i < -len) return undefined; if (i < 0) i += len; i = (this._head + i) & this._capacityMask; return this._list[i]; }; /** * Alias for peekAt() * @param i * @returns {*} */ Denque.prototype.get = function get(i) { return this.peekAt(i); }; /** * Returns the first item in the list without removing it. * @returns {*} */ Denque.prototype.peek = function peek() { if (this._head === this._tail) return undefined; return this._list[this._head]; }; /** * Alias for peek() * @returns {*} */ Denque.prototype.peekFront = function peekFront() { return this.peek(); }; /** * Returns the item that is at the back of the queue without removing it. * Uses peekAt(-1) */ Denque.prototype.peekBack = function peekBack() { return this.peekAt(-1); }; /** * Returns the current length of the queue * @return {Number} */ Object.defineProperty(Denque.prototype, 'length', { get: function length() { return this.size(); } }); /** * Return the number of items on the list, or 0 if empty. * @returns {number} */ Denque.prototype.size = function size() { if (this._head === this._tail) return 0; if (this._head < this._tail) return this._tail - this._head; else return this._capacityMask + 1 - (this._head - this._tail); }; /** * Add an item at the beginning of the list. * @param item */ Denque.prototype.unshift = function unshift(item) { if (arguments.length === 0) return this.size(); var len = this._list.length; this._head = (this._head - 1 + len) & this._capacityMask; this._list[this._head] = item; if (this._tail === this._head) this._growArray(); if (this._capacity && this.size() > this._capacity) this.pop(); if (this._head < this._tail) return this._tail - this._head; else return this._capacityMask + 1 - (this._head - this._tail); }; /** * Remove and return the first item on the list, * Returns undefined if the list is empty. * @returns {*} */ Denque.prototype.shift = function shift() { var head = this._head; if (head === this._tail) return undefined; var item = this._list[head]; this._list[head] = undefined; this._head = (head + 1) & this._capacityMask; if (head < 2 && this._tail > 10000 && this._tail <= this._list.length >>> 2) this._shrinkArray(); return item; }; /** * Add an item to the bottom of the list. * @param item */ Denque.prototype.push = function push(item) { if (arguments.length === 0) return this.size(); var tail = this._tail; this._list[tail] = item; this._tail = (tail + 1) & this._capacityMask; if (this._tail === this._head) { this._growArray(); } if (this._capacity && this.size() > this._capacity) { this.shift(); } if (this._head < this._tail) return this._tail - this._head; else return this._capacityMask + 1 - (this._head - this._tail); }; /** * Remove and return the last item on the list. * Returns undefined if the list is empty. * @returns {*} */ Denque.prototype.pop = function pop() { var tail = this._tail; if (tail === this._head) return undefined; var len = this._list.length; this._tail = (tail - 1 + len) & this._capacityMask; var item = this._list[this._tail]; this._list[this._tail] = undefined; if (this._head < 2 && tail > 10000 && tail <= len >>> 2) this._shrinkArray(); return item; }; /** * Remove and return the item at the specified index from the list. * Returns undefined if the list is empty. * @param index * @returns {*} */ Denque.prototype.removeOne = function removeOne(index) { var i = index; // expect a number or return undefined if ((i !== (i | 0))) { return void 0; } if (this._head === this._tail) return void 0; var size = this.size(); var len = this._list.length; if (i >= size || i < -size) return void 0; if (i < 0) i += size; i = (this._head + i) & this._capacityMask; var item = this._list[i]; var k; if (index < size / 2) { for (k = index; k > 0; k--) { this._list[i] = this._list[i = (i - 1 + len) & this._capacityMask]; } this._list[i] = void 0; this._head = (this._head + 1 + len) & this._capacityMask; } else { for (k = size - 1 - index; k > 0; k--) { this._list[i] = this._list[i = (i + 1 + len) & this._capacityMask]; } this._list[i] = void 0; this._tail = (this._tail - 1 + len) & this._capacityMask; } return item; }; /** * Remove number of items from the specified index from the list. * Returns array of removed items. * Returns undefined if the list is empty. * @param index * @param count * @returns {array} */ Denque.prototype.remove = function remove(index, count) { var i = index; var removed; var del_count = count; // expect a number or return undefined if ((i !== (i | 0))) { return void 0; } if (this._head === this._tail) return void 0; var size = this.size(); var len = this._list.length; if (i >= size || i < -size || count < 1) return void 0; if (i < 0) i += size; if (count === 1 || !count) { removed = new Array(1); removed[0] = this.removeOne(i); return removed; } if (i === 0 && i + count >= size) { removed = this.toArray(); this.clear(); return removed; } if (i + count > size) count = size - i; var k; removed = new Array(count); for (k = 0; k < count; k++) { removed[k] = this._list[(this._head + i + k) & this._capacityMask]; } i = (this._head + i) & this._capacityMask; if (index + count === size) { this._tail = (this._tail - count + len) & this._capacityMask; for (k = count; k > 0; k--) { this._list[i = (i + 1 + len) & this._capacityMask] = void 0; } return removed; } if (index === 0) { this._head = (this._head + count + len) & this._capacityMask; for (k = count - 1; k > 0; k--) { this._list[i = (i + 1 + len) & this._capacityMask] = void 0; } return removed; } if (i < size / 2) { this._head = (this._head + index + count + len) & this._capacityMask; for (k = index; k > 0; k--) { this.unshift(this._list[i = (i - 1 + len) & this._capacityMask]); } i = (this._head - 1 + len) & this._capacityMask; while (del_count > 0) { this._list[i = (i - 1 + len) & this._capacityMask] = void 0; del_count--; } if (index < 0) this._tail = i; } else { this._tail = i; i = (i + count + len) & this._capacityMask; for (k = size - (count + index); k > 0; k--) { this.push(this._list[i++]); } i = this._tail; while (del_count > 0) { this._list[i = (i + 1 + len) & this._capacityMask] = void 0; del_count--; } } if (this._head < 2 && this._tail > 10000 && this._tail <= len >>> 2) this._shrinkArray(); return removed; }; /** * Native splice implementation. * Remove number of items from the specified index from the list and/or add new elements. * Returns array of removed items or empty array if count == 0. * Returns undefined if the list is empty. * * @param index * @param count * @param {...*} [elements] * @returns {array} */ Denque.prototype.splice = function splice(index, count) { var i = index; // expect a number or return undefined if ((i !== (i | 0))) { return void 0; } var size = this.size(); if (i < 0) i += size; if (i > size) return void 0; if (arguments.length > 2) { var k; var temp; var removed; var arg_len = arguments.length; var len = this._list.length; var arguments_index = 2; if (!size || i < size / 2) { temp = new Array(i); for (k = 0; k < i; k++) { temp[k] = this._list[(this._head + k) & this._capacityMask]; } if (count === 0) { removed = []; if (i > 0) { this._head = (this._head + i + len) & this._capacityMask; } } else { removed = this.remove(i, count); this._head = (this._head + i + len) & this._capacityMask; } while (arg_len > arguments_index) { this.unshift(arguments[--arg_len]); } for (k = i; k > 0; k--) { this.unshift(temp[k - 1]); } } else { temp = new Array(size - (i + count)); var leng = temp.length; for (k = 0; k < leng; k++) { temp[k] = this._list[(this._head + i + count + k) & this._capacityMask]; } if (count === 0) { removed = []; if (i != size) { this._tail = (this._head + i + len) & this._capacityMask; } } else { removed = this.remove(i, count); this._tail = (this._tail - leng + len) & this._capacityMask; } while (arguments_index < arg_len) { this.push(arguments[arguments_index++]); } for (k = 0; k < leng; k++) { this.push(temp[k]); } } return removed; } else { return this.remove(i, count); } }; /** * Soft clear - does not reset capacity. */ Denque.prototype.clear = function clear() { this._list = new Array(this._list.length); this._head = 0; this._tail = 0; }; /** * Returns true or false whether the list is empty. * @returns {boolean} */ Denque.prototype.isEmpty = function isEmpty() { return this._head === this._tail; }; /** * Returns an array of all queue items. * @returns {Array} */ Denque.prototype.toArray = function toArray() { return this._copyArray(false); }; /** * ------------- * INTERNALS * ------------- */ /** * Fills the queue with items from an array * For use in the constructor * @param array * @private */ Denque.prototype._fromArray = function _fromArray(array) { var length = array.length; var capacity = this._nextPowerOf2(length); this._list = new Array(capacity); this._capacityMask = capacity - 1; this._tail = length; for (var i = 0; i < length; i++) this._list[i] = array[i]; }; /** * * @param fullCopy * @param size Initialize the array with a specific size. Will default to the current list size * @returns {Array} * @private */ Denque.prototype._copyArray = function _copyArray(fullCopy, size) { var src = this._list; var capacity = src.length; var length = this.length; size = size | length; // No prealloc requested and the buffer is contiguous if (size == length && this._head < this._tail) { // Simply do a fast slice copy return this._list.slice(this._head, this._tail); } var dest = new Array(size); var k = 0; var i; if (fullCopy || this._head > this._tail) { for (i = this._head; i < capacity; i++) dest[k++] = src[i]; for (i = 0; i < this._tail; i++) dest[k++] = src[i]; } else { for (i = this._head; i < this._tail; i++) dest[k++] = src[i]; } return dest; }; /** * Grows the internal list array. * @private */ Denque.prototype._growArray = function _growArray() { if (this._head != 0) { // double array size and copy existing data, head to end, then beginning to tail. var newList = this._copyArray(true, this._list.length << 1); this._tail = this._list.length; this._head = 0; this._list = newList; } else { this._tail = this._list.length; this._list.length <<= 1; } this._capacityMask = (this._capacityMask << 1) | 1; }; /** * Shrinks the internal list array. * @private */ Denque.prototype._shrinkArray = function _shrinkArray() { this._list.length >>>= 1; this._capacityMask >>>= 1; }; /** * Find the next power of 2, at least 4 * @private * @param {number} num * @returns {number} */ Denque.prototype._nextPowerOf2 = function _nextPowerOf2(num) { var log2 = Math.log(num) / Math.log(2); var nextPow2 = 1 << (log2 + 1); return Math.max(nextPow2, 4); }; denque = Denque; return denque; } var errors = {}; var hasRequiredErrors; function requireErrors () { if (hasRequiredErrors) return errors; hasRequiredErrors = 1; (function (exports) { // originally copied from https://raw.githubusercontent.com/mysqljs/mysql/7770ee5bb13260c56a160b91fe480d9165dbeeba/lib/protocol/constants/errors.js // (c) node-mysql authors // updated to contain error codes as is contained in MySQL 8.0 // by adapting node-mysql: /.../generate-error-constants.js /** * MySQL error constants * * Extracted from version 8.0.33 * * !! Generated by generate-error-constants.js, do not modify by hand !! */ exports.EE_CANTCREATEFILE = 1; exports.EE_READ = 2; exports.EE_WRITE = 3; exports.EE_BADCLOSE = 4; exports.EE_OUTOFMEMORY = 5; exports.EE_DELETE = 6; exports.EE_LINK = 7; exports.EE_EOFERR = 9; exports.EE_CANTLOCK = 10; exports.EE_CANTUNLOCK = 11; exports.EE_DIR = 12; exports.EE_STAT = 13; exports.EE_CANT_CHSIZE = 14; exports.EE_CANT_OPEN_STREAM = 15; exports.EE_GETWD = 16; exports.EE_SETWD = 17; exports.EE_LINK_WARNING = 18; exports.EE_OPEN_WARNING = 19; exports.EE_DISK_FULL = 20; exports.EE_CANT_MKDIR = 21; exports.EE_UNKNOWN_CHARSET = 22; exports.EE_OUT_OF_FILERESOURCES = 23; exports.EE_CANT_READLINK = 24; exports.EE_CANT_SYMLINK = 25; exports.EE_REALPATH = 26; exports.EE_SYNC = 27; exports.EE_UNKNOWN_COLLATION = 28; exports.EE_FILENOTFOUND = 29; exports.EE_FILE_NOT_CLOSED = 30; exports.EE_CHANGE_OWNERSHIP = 31; exports.EE_CHANGE_PERMISSIONS = 32; exports.EE_CANT_SEEK = 33; exports.EE_CAPACITY_EXCEEDED = 34; exports.EE_DISK_FULL_WITH_RETRY_MSG = 35; exports.EE_FAILED_TO_CREATE_TIMER = 36; exports.EE_FAILED_TO_DELETE_TIMER = 37; exports.EE_FAILED_TO_CREATE_TIMER_QUEUE = 38; exports.EE_FAILED_TO_START_TIMER_NOTIFY_THREAD = 39; exports.EE_FAILED_TO_CREATE_TIMER_NOTIFY_THREAD_INTERRUPT_EVENT = 40; exports.EE_EXITING_TIMER_NOTIFY_THREAD = 41; exports.EE_WIN_LIBRARY_LOAD_FAILED = 42; exports.EE_WIN_RUN_TIME_ERROR_CHECK = 43; exports.EE_FAILED_TO_DETERMINE_LARGE_PAGE_SIZE = 44; exports.EE_FAILED_TO_KILL_ALL_THREADS = 45; exports.EE_FAILED_TO_CREATE_IO_COMPLETION_PORT = 46; exports.EE_FAILED_TO_OPEN_DEFAULTS_FILE = 47; exports.EE_FAILED_TO_HANDLE_DEFAULTS_FILE = 48; exports.EE_WRONG_DIRECTIVE_IN_CONFIG_FILE = 49; exports.EE_SKIPPING_DIRECTIVE_DUE_TO_MAX_INCLUDE_RECURSION = 50; exports.EE_INCORRECT_GRP_DEFINITION_IN_CONFIG_FILE = 51; exports.EE_OPTION_WITHOUT_GRP_IN_CONFIG_FILE = 52; exports.EE_CONFIG_FILE_PERMISSION_ERROR = 53; exports.EE_IGNORE_WORLD_WRITABLE_CONFIG_FILE = 54; exports.EE_USING_DISABLED_OPTION = 55; exports.EE_USING_DISABLED_SHORT_OPTION = 56; exports.EE_USING_PASSWORD_ON_CLI_IS_INSECURE = 57; exports.EE_UNKNOWN_SUFFIX_FOR_VARIABLE = 58; exports.EE_SSL_ERROR_FROM_FILE = 59; exports.EE_SSL_ERROR = 60; exports.EE_NET_SEND_ERROR_IN_BOOTSTRAP = 61; exports.EE_PACKETS_OUT_OF_ORDER = 62; exports.EE_UNKNOWN_PROTOCOL_OPTION = 63; exports.EE_FAILED_TO_LOCATE_SERVER_PUBLIC_KEY = 64; exports.EE_PUBLIC_KEY_NOT_IN_PEM_FORMAT = 65; exports.EE_DEBUG_INFO = 66; exports.EE_UNKNOWN_VARIABLE = 67; exports.EE_UNKNOWN_OPTION = 68; exports.EE_UNKNOWN_SHORT_OPTION = 69; exports.EE_OPTION_WITHOUT_ARGUMENT = 70; exports.EE_OPTION_REQUIRES_ARGUMENT = 71; exports.EE_SHORT_OPTION_REQUIRES_ARGUMENT = 72; exports.EE_OPTION_IGNORED_DUE_TO_INVALID_VALUE = 73; exports.EE_OPTION_WITH_EMPTY_VALUE = 74; exports.EE_FAILED_TO_ASSIGN_MAX_VALUE_TO_OPTION = 75; exports.EE_INCORRECT_BOOLEAN_VALUE_FOR_OPTION = 76; exports.EE_FAILED_TO_SET_OPTION_VALUE = 77; exports.EE_INCORRECT_INT_VALUE_FOR_OPTION = 78; exports.EE_INCORRECT_UINT_VALUE_FOR_OPTION = 79; exports.EE_ADJUSTED_SIGNED_VALUE_FOR_OPTION = 80; exports.EE_ADJUSTED_UNSIGNED_VALUE_FOR_OPTION = 81; exports.EE_ADJUSTED_ULONGLONG_VALUE_FOR_OPTION = 82; exports.EE_ADJUSTED_DOUBLE_VALUE_FOR_OPTION = 83; exports.EE_INVALID_DECIMAL_VALUE_FOR_OPTION = 84; exports.EE_COLLATION_PARSER_ERROR = 85; exports.EE_FAILED_TO_RESET_BEFORE_PRIMARY_IGNORABLE_CHAR = 86; exports.EE_FAILED_TO_RESET_BEFORE_TERTIARY_IGNORABLE_CHAR = 87; exports.EE_SHIFT_CHAR_OUT_OF_RANGE = 88; exports.EE_RESET_CHAR_OUT_OF_RANGE = 89; exports.EE_UNKNOWN_LDML_TAG = 90; exports.EE_FAILED_TO_RESET_BEFORE_SECONDARY_IGNORABLE_CHAR = 91; exports.EE_FAILED_PROCESSING_DIRECTIVE = 92; exports.EE_PTHREAD_KILL_FAILED = 93; exports.HA_ERR_KEY_NOT_FOUND = 120; exports.HA_ERR_FOUND_DUPP_KEY = 121; exports.HA_ERR_INTERNAL_ERROR = 122; exports.HA_ERR_RECORD_CHANGED = 123; exports.HA_ERR_WRONG_INDEX = 124; exports.HA_ERR_ROLLED_BACK = 125; exports.HA_ERR_CRASHED = 126; exports.HA_ERR_WRONG_IN_RECORD = 127; exports.HA_ERR_OUT_OF_MEM = 128; exports.HA_ERR_NOT_A_TABLE = 130; exports.HA_ERR_WRONG_COMMAND = 131; exports.HA_ERR_OLD_FILE = 132; exports.HA_ERR_NO_ACTIVE_RECORD = 133; exports.HA_ERR_RECORD_DELETED = 134; exports.HA_ERR_RECORD_FILE_FULL = 135; exports.HA_ERR_INDEX_FILE_FULL = 136; exports.HA_ERR_END_OF_FILE = 137; exports.HA_ERR_UNSUPPORTED = 138; exports.HA_ERR_TOO_BIG_ROW = 139; exports.HA_WRONG_CREATE_OPTION = 140; exports.HA_ERR_FOUND_DUPP_UNIQUE = 141; exports.HA_ERR_UNKNOWN_CHARSET = 142; exports.HA_ERR_WRONG_MRG_TABLE_DEF = 143; exports.HA_ERR_CRASHED_ON_REPAIR = 144; exports.HA_ERR_CRASHED_ON_USAGE = 145; exports.HA_ERR_LOCK_WAIT_TIMEOUT = 146; exports.HA_ERR_LOCK_TABLE_FULL = 147; exports.HA_ERR_READ_ONLY_TRANSACTION = 148; exports.HA_ERR_LOCK_DEADLOCK = 149; exports.HA_ERR_CANNOT_ADD_FOREIGN = 150; exports.HA_ERR_NO_REFERENCED_ROW = 151; exports.HA_ERR_ROW_IS_REFERENCED = 152; exports.HA_ERR_NO_SAVEPOINT = 153; exports.HA_ERR_NON_UNIQUE_BLOCK_SIZE = 154; exports.HA_ERR_NO_SUCH_TABLE = 155; exports.HA_ERR_TABLE_EXIST = 156; exports.HA_ERR_NO_CONNECTION = 157; exports.HA_ERR_NULL_IN_SPATIAL = 158; exports.HA_ERR_TABLE_DEF_CHANGED = 159; exports.HA_ERR_NO_PARTITION_FOUND = 160; exports.HA_ERR_RBR_LOGGING_FAILED = 161; exports.HA_ERR_DROP_INDEX_FK = 162; exports.HA_ERR_FOREIGN_DUPLICATE_KEY = 163; exports.HA_ERR_TABLE_NEEDS_UPGRADE = 164; exports.HA_ERR_TABLE_READONLY