UNPKG

@visactor/vmind

Version:

<div align="center"> <a href="https://github.com/VisActor#gh-light-mode-only" target="_blank"> <img alt="VisActor Logo" width="200" src="https://github.com/VisActor/.github/blob/main/profile/logo_500_200_light.svg"/> </a> <a href="https://githu

177 lines (144 loc) 8.81 kB
"use strict"; var __importDefault = this && this.__importDefault || function(mod) { return mod && mod.__esModule ? mod : { default: mod }; }; Object.defineProperty(exports, "__esModule", { value: !0 }), exports.parseRespondField = exports.convertGroupByToString = exports.sumAllMeasureFields = exports.replaceBlankSpace = exports.matchColumnName = exports.mergeMap = exports.replaceInvalidWords = exports.getValueByAttributeName = exports.replaceDataset = exports.replaceString = exports.replaceByMap = exports.swapMap = exports.removeEmptyLines = exports.parseSQLResponse = exports.generateRandomString = void 0; const json5_1 = __importDefault(require("json5")), vutils_1 = require("@visactor/vutils"), text_1 = require("../../utils/text"), const_1 = require("./const"), types_1 = require("../../types"), alasql_1 = __importDefault(require("alasql")), field_1 = require("../../utils/field"); function generateRandomString(len) { const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; let result = ""; for (let i = 0; i < len; i++) result += chars.charAt(Math.floor(52 * Math.random())); return result; } exports.generateRandomString = generateRandomString; const operatorList = [ [ "+", `_${generateRandomString(3)}_PLUS_${generateRandomString(3)}_` ], [ "-", `_${generateRandomString(3)}_DASH_${generateRandomString(3)}_` ], [ "*", `_${generateRandomString(3)}_ASTERISK_${generateRandomString(3)}_` ], [ "/", `_${generateRandomString(3)}_SLASH_${generateRandomString(3)}_` ] ], operators = operatorList.map((op => op[0])), RESERVE_REPLACE_MAP = new Map([ ...operatorList, ...const_1.alasqlKeywordList.map((keyword => [ keyword, generateRandomString(10) ])) ]), parseSQLResponse = response => { const sql = response.match(/sql:\n?```(.*?)```/s)[1], fieldInfoStr = response.match(/fieldInfo:\n?```(.*?)```/s)[1]; let fieldInfo = []; try { const tempFieldInfo = json5_1.default.parse(fieldInfoStr); fieldInfo = (0, vutils_1.isArray)(tempFieldInfo) ? tempFieldInfo : tempFieldInfo.fieldInfo; } catch (e) { fieldInfo = json5_1.default.parse(`[${fieldInfoStr}]`); } return { sql: sql, llmFieldInfo: fieldInfo, thoughts: "" }; }; function removeEmptyLines(str) { return str.replace(/\n\s*\n/g, "\n"); } exports.parseSQLResponse = parseSQLResponse, exports.removeEmptyLines = removeEmptyLines; const swapMap = map => { const swappedMap = new Map; return map.forEach(((value, key) => { swappedMap.set(value, key); })), swappedMap; }; exports.swapMap = swapMap; const replaceByMap = (str, replaceMap) => [ ...replaceMap.keys() ].reduce(((prev, cur) => { const originColumnName = cur, validColumnName = replaceMap.get(cur); return (0, text_1.replaceAll)(prev, originColumnName, validColumnName); }), str); exports.replaceByMap = replaceByMap; const replaceNonASCIICharacters = str => { const nonAsciiCharMap = new Map; return { validStr: str.replace(/([^\x00-\x7F]+)/g, (m => { let replacement; return nonAsciiCharMap.has(m) ? replacement = nonAsciiCharMap.get(m) : (replacement = generateRandomString(10), nonAsciiCharMap.set(m, replacement)), replacement; })), replaceMap: nonAsciiCharMap }; }, replaceString = (str, replaceMap) => { if (!(0, vutils_1.isString)(str)) return str; if (replaceMap.has(str)) return replaceMap.get(str); return [ ...replaceMap.keys() ].sort(((a, b) => b.length - a.length)).reduce(((prev, cur) => (0, text_1.replaceAll)(prev, cur, replaceMap.get(cur))), str); }; exports.replaceString = replaceString; const replaceDataset = (dataset, replaceMap, keysOnly) => dataset.map((d => Object.keys(d).reduce(((prev, cur) => { const replacedKey = (0, exports.replaceString)(cur, replaceMap), replacedValue = (0, exports.replaceString)(d[cur], replaceMap); return prev[replacedKey] = keysOnly ? d[cur] : replacedValue, prev; }), {}))); exports.replaceDataset = replaceDataset; const getValueByAttributeName = (obj, outterKey) => { const values = []; for (const key in obj) if (key === outterKey && "string" == typeof obj[key]) values.push(obj[key]); else if ("object" == typeof obj[key]) { const childValues = (0, exports.getValueByAttributeName)(obj[key], outterKey); values.push(...childValues); } return (0, vutils_1.uniqArray)(values); }; exports.getValueByAttributeName = getValueByAttributeName; const replaceInvalidWords = (sql, columns) => { const operatorReplaceMap = new Map, validColumnNames = columns.map((column => [ ...RESERVE_REPLACE_MAP.keys() ].reduce(((prev, cur) => { const replaceStr = [ cur.toUpperCase(), cur.toLowerCase(), (0, text_1.capitalize)(cur) ].find((str => operators.includes(cur) ? prev.includes(str) : prev === str)); return replaceStr ? (operatorReplaceMap.has(replaceStr) || operatorReplaceMap.set(replaceStr, RESERVE_REPLACE_MAP.get(cur)), (0, text_1.replaceAll)(prev, replaceStr, RESERVE_REPLACE_MAP.get(cur))) : prev; }), column))), columnReplaceMap = new Map(columns.map(((column, index) => { const validStr = validColumnNames[index]; if (column !== validStr) return [ column, validStr ]; })).filter(Boolean)), sqlWithoutOperator = (0, exports.replaceByMap)(sql, columnReplaceMap), {validStr: sqlWithoutAscii, replaceMap: asciiReplaceMap} = replaceNonASCIICharacters(sqlWithoutOperator); return { validStr: sqlWithoutAscii, columnReplaceMap: operatorReplaceMap, sqlReplaceMap: asciiReplaceMap }; }; exports.replaceInvalidWords = replaceInvalidWords; const mergeMap = (map1, map2) => (map2.forEach(((value, key) => { map1.set(key, value); })), map1); exports.mergeMap = mergeMap; const matchColumnName = (columnName, fieldName) => { const fieldWithoutSpace = fieldName.replace(/\s/g, ""); return columnName.replace(/\s/g, "") === fieldWithoutSpace; }; exports.matchColumnName = matchColumnName; const replaceBlankSpace = (sql, fieldNames) => { const ast = alasql_1.default.parse(sql), columnsInSql = (0, exports.getValueByAttributeName)(ast.statements[0], "columnid"), validColumnNames = columnsInSql.map((column => { const matchedFieldName = fieldNames.find((field => (0, exports.matchColumnName)(column, field))); return null != matchedFieldName ? matchedFieldName : column; })); return columnsInSql.reduce(((prev, _cur, index) => { const originColumnName = columnsInSql[index], validColumnName = validColumnNames[index]; return validColumnName !== originColumnName ? (0, text_1.replaceAll)(prev, originColumnName, validColumnName) : prev; }), sql); }; exports.replaceBlankSpace = replaceBlankSpace; const sumAllMeasureFields = (sql, fieldInfo, columnReplaceMap, sqlReplaceMap) => { var _a; const measureFieldsInSql = fieldInfo.filter((field => field.role === types_1.ROLE.MEASURE)).map((field => { const {fieldName: fieldName} = field, replacedName1 = (0, exports.replaceString)(fieldName, columnReplaceMap); return (0, exports.replaceString)(replacedName1, sqlReplaceMap); })), ast = alasql_1.default.parse(sql), selectedColumns = ast.statements[0].columns, nonAggregatedColumns = selectedColumns.filter((column => !column.aggregatorid)).map((column => column.columnid)), groupByColumns = (null !== (_a = ast.statements[0].group) && void 0 !== _a ? _a : []).map((column => column.columnid)); let needAggregateColumns = []; groupByColumns.length > 0 && nonAggregatedColumns.length !== selectedColumns.length && (needAggregateColumns = nonAggregatedColumns.filter((column => measureFieldsInSql.includes(column))).filter((column => !groupByColumns.includes(column)))); const patchedFields = needAggregateColumns.map((column => `SUM(\`${column}\`) as ${column}`)); return needAggregateColumns.reduce(((prev, cur, index) => { const regex = new RegExp(`\`?${cur}\`?`, "g"); return prev.replace(regex, patchedFields[index]); }), sql); }; exports.sumAllMeasureFields = sumAllMeasureFields; const convertGroupByToString = (sql, dataset) => { const groupByColumns = alasql_1.default.parse(sql).statements[0].group.map((column => column.columnid)); dataset.forEach((item => { groupByColumns.forEach((column => { item[column] = item[column].toString(); })); })); }; exports.convertGroupByToString = convertGroupByToString; const parseRespondField = (responseFieldInfo, dataset) => responseFieldInfo.map((field => Object.assign(Object.assign({}, field), (0, field_1.detectFieldType)(dataset, field.fieldName)))); exports.parseRespondField = parseRespondField; //# sourceMappingURL=utils.js.map