All files dynamo-expr.ts

100% Statements 22/22
100% Branches 2/2
100% Functions 3/3
100% Lines 22/22

Press n or j to go to the next uncovered block, b, p or k for the previous block.

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    1x 1x                                                 1x         3x 3x                   3x     3x 3x 3x 5x 1x 1x 1x 1x 1x   4x 4x 4x 4x 4x     3x 3x      
import { DynamoAttributeValue } from "@aws-cdk/aws-stepfunctions-tasks";
import { DynamoAttributeName } from "./attribute-name";
import { RefCounter, createRefCounter } from "./counter";
import { Placeholder, isAttrName } from "./placeholder";
 
export interface ExpressionAggregate {
  /**
   * Built expression that contains calculated placeholders.
   */
  readonly expression: string;
 
  /**
   * attribute values that used to substitute expression's placeholders by DynamoDB.
   */
  readonly expressionAttributeValues: { [key: string]: DynamoAttributeValue };
 
  /**
   * attribute names that used to substitute expression's placeholders by DynamoDB.
   */
  readonly expressionAttributeNames: { [key: string]: DynamoAttributeName };
}
 
/**
 * An ExpressionBuilder instance builds the expression using calculated placeholders by referred attribute names and values.
 *
 * Each instance must correspond to the DynamoDB requests that using the expression.
 * If instances are used across different requests, the names and values that substitutes the placeholders may misplaced.
 */
export class ExpressionBuilder {
  private readonly valuesRefCounter: RefCounter;
  private readonly namesRefCounter: RefCounter;
 
  constructor() {
    this.valuesRefCounter = createRefCounter();
    this.namesRefCounter = createRefCounter();
  }
 
  /**
   * Builds an expression and expression attribute values from template string.
   */
  public expr(
    literals: TemplateStringsArray,
    ...placeholers: Placeholder[]
  ): ExpressionAggregate {
    let expression = "";
    const expressionAttributeValues: {
      [key: string]: DynamoAttributeValue;
    } = {};
    const expressionAttributeNames: { [key: string]: DynamoAttributeName } = {};
    placeholers.forEach((pv, idx) => {
      if (isAttrName(pv)) {
        const { value } = this.namesRefCounter.next();
        const placeholder = `#${value}`;
        expression += literals[idx];
        expression += placeholder;
        expressionAttributeNames[placeholder] = pv;
      } else {
        const { value } = this.valuesRefCounter.next();
        const ref = `:v${value}`;
        expression += literals[idx];
        expression += ref;
        expressionAttributeValues[ref] = pv;
      }
    });
    expression += literals[literals.length - 1];
    return { expression, expressionAttributeValues, expressionAttributeNames };
  }
}