All files sql.ts

87.5% Statements 35/40
80% Branches 16/20
90% Functions 9/10
89.19% Lines 33/37
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 801x 1x   1x     1x 43x       43x       43x       43x 8x     35x 8x   8x   6x     8x     27x         4x     6x   1x 16x   16x 31x   31x       31x 18x     31x 8x   23x 23x     16x 31x 31x         16x     1x        
import { NonEmptyArray } from "fp-ts/lib/NonEmptyArray";
import { None, Some } from "fp-ts/lib/Option";
import { mixed } from "io-ts";
import { forOwn, isPlainObject, isEqual } from "lodash";
import * as pg from "pg";
 
const normaliseValue = (value: any): any => {
  Iif (value == null) {
    return value;
  }
 
  Iif (value instanceof NonEmptyArray) {
    return normaliseValue(value.toArray());
  }
 
  Iif (value instanceof None || value instanceof Some) {
    return normaliseValue(value.toUndefined());
  }
 
  if (Array.isArray(value)) {
    return value.map(normaliseValue);
  }
 
  if (isPlainObject(value)) {
    const next: any = {};
 
    forOwn(value, (v, k) => {
      // tslint:disable-next-line:no-expression-statement no-object-mutation
      next[k] = normaliseValue(v);
    });
 
    return next;
  }
 
  return value;
};
 
type IndexGetter = (value: mixed) => string;
 
export const SQLFragment = (parts: TemplateStringsArray, ...inValues: mixed[]) => (
  getValueIndex: IndexGetter,
): string =>
  parts.reduce((prev, curr, valIdx) => `${prev}${getValueIndex(inValues[valIdx - 1])}${curr}`);
 
export const SQL = (parts: TemplateStringsArray, ...inValues: any[]): pg.QueryConfig => {
  const outValues: mixed[] = [];
 
  const getValueIndex = (value: mixed): string => {
    const normalisedValue = normaliseValue(value);
 
    Iif (normalisedValue == null) {
      return `NULL`;
    }
 
    const found = outValues.findIndex(
      o => !Array.isArray(normalisedValue) && isEqual(o, normalisedValue),
    );
 
    if (found > -1) {
      return `$${found + 1}`;
    }
    outValues.push(normalisedValue);
    return `$${outValues.length}`;
  };
 
  const outText = parts.reduce((prev, curr) => {
    const value = inValues.shift();
    return typeof value === "function"
      ? `${prev}${value(getValueIndex)}${curr}`
      : `${prev}${getValueIndex(value)}${curr}`;
  });
 
  return { text: outText, values: outValues };
};
 
export const named = (name: string, query: pg.QueryConfig) => ({
  ...query,
  name,
});