UNPKG

nukak

Version:

flexible and efficient ORM, with declarative JSON syntax and smart type-safety

78 lines 11.1 kB
import { getKeys, hasKeys } from './object.util.js'; export function flatObject(obj, pre) { return getKeys(obj).reduce((acc, key) => flatObjectEntry(acc, key, obj[key], typeof obj[key] === 'object' ? '' : pre), {}); } function flatObjectEntry(map, key, val, pre) { const prefix = pre ? `${pre}.${key}` : key; return typeof val === 'object' ? getKeys(val).reduce((acc, prop) => flatObjectEntry(acc, prop, val[prop], prefix), map) : { ...map, [prefix]: val }; } export function unflatObjects(objects) { if (!Array.isArray(objects) || !objects.length) { return objects; } const attrsPaths = obtainAttrsPaths(objects[0]); if (!hasKeys(attrsPaths)) { return objects; } return objects.map((row) => { const dto = {}; for (const col in row) { if (row[col] === null) { continue; } const attrPath = attrsPaths[col]; if (attrPath) { const target = attrPath.slice(0, -1).reduce((acc, key) => { if (typeof acc[key] !== 'object') { acc[key] = {}; } return acc[key]; }, dto); target[attrPath[attrPath.length - 1]] = row[col]; } else { dto[col] = row[col]; } } return dto; }); } export function obtainAttrsPaths(row) { return getKeys(row).reduce((acc, col) => { // Support both dot notation (legacy) and underscore notation (new) if (col.includes('.')) { acc[col] = col.split('.'); } else if (col.includes('_') && col !== col.toUpperCase()) { // Convert underscore to dot notation for nested paths // Skip all-uppercase (like UPPER_CASE constants) acc[col] = col.split('_'); } return acc; }, {}); } /** * Escape a SQL identifier (table name, column name, etc.) * @param val the identifier to escape * @param escapeIdChar the escape character to use (e.g. ` or ") * @param forbidQualified whether to forbid qualified identifiers (containing dots) * @param addDot whether to add a dot suffix */ export function escapeSqlId(val, escapeIdChar = '`', forbidQualified, addDot) { if (!val) { return ''; } if (!forbidQualified && val.includes('.')) { const result = val .split('.') .map((it) => escapeSqlId(it, escapeIdChar, true)) .join('.'); return addDot ? result + '.' : result; } const escaped = escapeIdChar + val.replace(new RegExp(escapeIdChar, 'g'), escapeIdChar + escapeIdChar) + escapeIdChar; const suffix = addDot ? '.' : ''; return escaped + suffix; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3FsLnV0aWwuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdXRpbC9zcWwudXRpbC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEVBQUUsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBRXBELE1BQU0sVUFBVSxVQUFVLENBQUksR0FBTSxFQUFFLEdBQVk7SUFDaEQsT0FBTyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUMsTUFBTSxDQUN4QixDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsRUFBRSxDQUFDLGVBQWUsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsQ0FBQyxHQUFhLENBQUMsRUFBRSxPQUFPLEdBQUcsQ0FBQyxHQUFhLENBQUMsS0FBSyxRQUFRLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEVBQzlHLEVBQU8sQ0FDUixDQUFDO0FBQ0osQ0FBQztBQUVELFNBQVMsZUFBZSxDQUFJLEdBQU0sRUFBRSxHQUFXLEVBQUUsR0FBUSxFQUFFLEdBQVk7SUFDckUsTUFBTSxNQUFNLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsSUFBSSxHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDO0lBQzNDLE9BQU8sT0FBTyxHQUFHLEtBQUssUUFBUTtRQUM1QixDQUFDLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsRUFBRSxJQUFJLEVBQUUsRUFBRSxDQUFDLGVBQWUsQ0FBQyxHQUFHLEVBQUUsSUFBSSxFQUFFLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRSxNQUFNLENBQUMsRUFBRSxHQUFHLENBQUM7UUFDeEYsQ0FBQyxDQUFDLEVBQUUsR0FBRyxHQUFHLEVBQUUsQ0FBQyxNQUFNLENBQUMsRUFBRSxHQUFHLEVBQUUsQ0FBQztBQUNoQyxDQUFDO0FBRUQsTUFBTSxVQUFVLGFBQWEs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QUNmLEtBQUssQ0FBQyxHQUFHLENBQUM7YUFDVixHQUFHLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLFdBQVcsQ0FBQyxFQUFFLEVBQUUsWUFBWSxFQUFFLElBQUksQ0FBQyxDQUFDO2FBQ2hELElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUNiLE9BQU8sTUFBTSxDQUFDLENBQUMsQ0FBQyxNQUFNLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUM7SUFDeEMsQ0FBQztJQUVELE1BQU0sT0FBTyxHQUFHLFlBQVksR0FBRyxHQUFHLENBQUMsT0FBTyxDQUFDLElBQUksTUFBTSxDQUFDLFlBQVksRUFBRSxHQUFHLENBQUMsRUFBRSxZQUFZLEdBQUcsWUFBWSxDQUFDLEdBQUcsWUFBWSxDQUFDO0lBRXRILE1BQU0sTUFBTSxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7SUFFakMsT0FBTyxPQUFPLEdBQUcsTUFBTSxDQUFDO0FBQzFCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgdHlwZSB7IEZpZWxkVmFsdWUsIEtleSB9IGZyb20gJ251a2FrL3R5cGUnO1xuaW1wb3J0IHsgZ2V0S2V5cywgaGFzS2V5cyB9IGZyb20gJy4vb2JqZWN0LnV0aWwuanMnO1xuXG5leHBvcnQgZnVuY3Rpb24gZmxhdE9iamVjdDxFPihvYmo6IEUsIHByZT86IHN0cmluZyk6IEUge1xuICByZXR1cm4gZ2V0S2V5cyhvYmopLnJlZHVjZShcbiAgICAoYWNjLCBrZXkpID0+IGZsYXRPYmplY3RFbnRyeShhY2MsIGtleSwgb2JqW2tleSBhcyBLZXk8RT5dLCB0eXBlb2Ygb2JqW2tleSBhcyBLZXk8RT5dID09PSAnb2JqZWN0JyA/ICcnIDogcHJlKSxcbiAgICB7fSBhcyBFLFxuICApO1xufVxuXG5mdW5jdGlvbiBmbGF0T2JqZWN0RW50cnk8RT4obWFwOiBFLCBrZXk6IHN0cmluZywgdmFsOiBhbnksIHByZT86IHN0cmluZyk6IEUge1xuICBjb25zdCBwcmVmaXggPSBwcmUgPyBgJHtwcmV9LiR7a2V5fWAgOiBrZXk7XG4gIHJldHVybiB0eXBlb2YgdmFsID09PSAnb2JqZWN0J1xuICAgID8gZ2V0S2V5cyh2YWwpLnJlZHVjZSgoYWNjLCBwcm9wKSA9PiBmbGF0T2JqZWN0RW50cnkoYWNjLCBwcm9wLCB2YWxbcHJvcF0sIHByZWZpeCksIG1hcClcbiAgICA6IHsgLi4ubWFwLCBbcHJlZml4XTogdmFsIH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiB1bmZsYXRPYmplY3RzPFQ+KG9iamVjdHM6IFRbXSk6IFRbXSB7XG4gIGlmICghQXJyYXkuaXNBcnJheShvYmplY3RzKSB8fCAhb2JqZWN0cy5sZW5ndGgpIHtcbiAgICByZXR1cm4gb2JqZWN0cztcbiAgfVxuXG4gIGNvbnN0IGF0dHJzUGF0aHMgPSBvYnRhaW5BdHRyc1BhdGhzKG9iamVjdHNbMF0pO1xuXG4gIGlmICghaGFzS2V5cyhhdHRyc1BhdGhzKSkge1xuICAgIHJldHVybiBvYmplY3RzO1xuICB9XG5cbiAgcmV0dXJuIG9iamVjdHMubWFwKChyb3cpID0+IHtcbiAgICBjb25zdCBkdG8gPSB7fSBhcyBUO1xuXG4gICAgZm9yIChjb25zdCBjb2wgaW4gcm93KSB7XG4gICAgICBpZiAocm93W2NvbF0gPT09IG51bGwpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBjb25zdCBhdHRyUGF0aCA9IGF0dHJzUGF0aHNbY29sXTtcbiAgICAgIGlmIChhdHRyUGF0aCkge1xuICAgICAgICBjb25zdCB0YXJnZXQgPSBhdHRyUGF0aC5zbGljZSgwLCAtMSkucmVkdWNlKFxuICAgICAgICAgIChhY2MsIGtleSkgPT4ge1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBhY2Nba2V5IGFzIEtleTxUPl0gIT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgICAgIGFjY1trZXkgYXMgS2V5PFQ+XSA9IHt9IGFzIEZpZWxkVmFsdWU8VD47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gYWNjW2tleSBhcyBLZXk8VD5dO1xuICAgICAgICAgIH0sXG4gICAgICAgICAgZHRvIGFzIFJlY29yZDxzdHJpbmcsIGFueT4sXG4gICAgICAgICk7XG4gICAgICAgIHRhcmdldFthdHRyUGF0aFthdHRyUGF0aC5sZW5ndGggLSAxXV0gPSByb3dbY29sXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGR0b1tjb2xdID0gcm93W2NvbF07XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGR0bztcbiAgfSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBvYnRhaW5BdHRyc1BhdGhzPFQ+KHJvdzogVCkge1xuICByZXR1cm4gZ2V0S2V5cyhyb3cpLnJlZHVjZShcbiAgICAoYWNjLCBjb2wpID0+IHtcbiAgICAgIC8vIFN1cHBvcnQgYm90aCBkb3Qgbm90YXRpb24gKGxlZ2FjeSkgYW5kIHVuZGVyc2NvcmUgbm90YXRpb24gKG5ldylcbiAgICAgIGlmIChjb2wuaW5jbHVkZXMoJy4nKSkge1xuICAgICAgICBhY2NbY29sXSA9IGNvbC5zcGxpdCgnLicpO1xuICAgICAgfSBlbHNlIGlmIChjb2wuaW5jbHVkZXMoJ18nKSAmJiBjb2wgIT09IGNvbC50b1VwcGVyQ2FzZSgpKSB7XG4gICAgICAgIC8vIENvbnZlcnQgdW5kZXJzY29yZSB0byBkb3Qgbm90YXRpb24gZm9yIG5lc3RlZCBwYXRoc1xuICAgICAgICAvLyBTa2lwIGFsbC11cHBlcmNhc2UgKGxpa2UgVVBQRVJfQ0FTRSBjb25zdGFudHMpXG4gICAgICAgIGFjY1tjb2xdID0gY29sLnNwbGl0KCdfJyk7XG4gICAgICB9XG4gICAgICByZXR1cm4gYWNjO1xuICAgIH0sXG4gICAge30gYXMgeyBbazogc3RyaW5nXTogc3RyaW5nW10gfSxcbiAgKTtcbn1cblxuLyoqXG4gKiBFc2NhcGUgYSBTUUwgaWRlbnRpZmllciAodGFibGUgbmFtZSwgY29sdW1uIG5hbWUsIGV0Yy4pXG4gKiBAcGFyYW0gdmFsIHRoZSBpZGVudGlmaWVyIHRvIGVzY2FwZVxuICogQHBhcmFtIGVzY2FwZUlkQ2hhciB0aGUgZXNjYXBlIGNoYXJhY3RlciB0byB1c2UgKGUuZy4gYCBvciBcIilcbiAqIEBwYXJhbSBmb3JiaWRRdWFsaWZpZWQgd2hldGhlciB0byBmb3JiaWQgcXVhbGlmaWVkIGlkZW50aWZpZXJzIChjb250YWluaW5nIGRvdHMpXG4gKiBAcGFyYW0gYWRkRG90IHdoZXRoZXIgdG8gYWRkIGEgZG90IHN1ZmZpeFxuICovXG5leHBvcnQgZnVuY3Rpb24gZXNjYXBlU3FsSWQoXG4gIHZhbDogc3RyaW5nLFxuICBlc2NhcGVJZENoYXI6ICdgJyB8ICdcIicgPSAnYCcsXG4gIGZvcmJpZFF1YWxpZmllZD86IGJvb2xlYW4sXG4gIGFkZERvdD86IGJvb2xlYW4sXG4pOiBzdHJpbmcge1xuICBpZiAoIXZhbCkge1xuICAgIHJldHVybiAnJztcbiAgfVxuXG4gIGlmICghZm9yYmlkUXVhbGlmaWVkICYmIHZhbC5pbmNsdWRlcygnLicpKSB7XG4gICAgY29uc3QgcmVzdWx0ID0gdmFsXG4gICAgICAuc3BsaXQoJy4nKVxuICAgICAgLm1hcCgoaXQpID0+IGVzY2FwZVNxbElkKGl0LCBlc2NhcGVJZENoYXIsIHRydWUpKVxuICAgICAgLmpvaW4oJy4nKTtcbiAgICByZXR1cm4gYWRkRG90ID8gcmVzdWx0ICsgJy4nIDogcmVzdWx0O1xuICB9XG5cbiAgY29uc3QgZXNjYXBlZCA9IGVzY2FwZUlkQ2hhciArIHZhbC5yZXBsYWNlKG5ldyBSZWdFeHAoZXNjYXBlSWRDaGFyLCAnZycpLCBlc2NhcGVJZENoYXIgKyBlc2NhcGVJZENoYXIpICsgZXNjYXBlSWRDaGFyO1xuXG4gIGNvbnN0IHN1ZmZpeCA9IGFkZERvdCA/ICcuJyA6ICcnO1xuXG4gIHJldHVybiBlc2NhcGVkICsgc3VmZml4O1xufVxuIl19