All files / lib/model/oasis/dataSource EntityContainer.js

100% Statements 30/30
100% Branches 10/10
100% Functions 11/11
100% Lines 28/28

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 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123    1x 1x 1x 1x 1x 1x   1x                                               28x 112x 106x   112x 110x                                       29x                     3x 2x 1x         1x                     28x                       27x 26x   104x       26x 1x 25x 1x         24x     25x       1x  
"use strict";
 
const _ = require("lodash");
const ActionImport = require("./ActionImport");
const AnnotationTarget = require("../annotations/AnnotationTarget");
const EntitySet = require("./EntitySet");
const FunctionImport = require("./FunctionImport");
const Singleton = require("./Singleton");
 
const childCollections = [
  {
    name: "actionImports",
    sourceElement: "ActionImport",
    Class: ActionImport,
  },
  {
    name: "entitySets",
    sourceElement: "EntitySet",
    Class: EntitySet,
  },
  {
    name: "functionImports",
    sourceElement: "FunctionImport",
    Class: FunctionImport,
  },
  {
    name: "singletons",
    sourceElement: "Singleton",
    Class: Singleton,
  },
];
 
function initChildProperties(container, schema) {
  childCollections.forEach((collection) => {
    let child = _.get(container.raw, collection.sourceElement, []).map(
      (t) => new collection.Class(t, schema)
    );
    Object.defineProperty(container, collection.name, {
      get: () => child,
    });
  });
}
 
/**
 * Envelopes an EntityContainer.
 *
 * http://docs.oasis-open.org/odata/odata-csdl-xml/v4.01/cs01/odata-csdl-xml-v4.01-cs01.html#sec_EntityContainer
 *
 * @class EntityContainer
 * @extends {AnnotationTarget}
 */
class EntityContainer extends AnnotationTarget {
  /**
   * Creates an instance of EntityContainer.
   * @param {Object} rawMetadata raw metadata object for entity container
   * @memberof EntityContainer
   */
  constructor(rawMetadata) {
    super(rawMetadata);
  }
 
  /**
   * Gets an EntitySet defined in container
   *
   * @param {string} [name] entity set name
   * @returns {EntitySet} set with given name
   * @memberof EntityContainer
   */
  getEntitySet(name) {
    let set = this.entitySets.find((s) => s.name === name);
    if (!set) {
      throw new Error(
        `EntitySet '${name}' not found in entity container '${this.name}'`
      );
    }
 
    return set;
  }
 
  /**
   * Initializes entity container child collection properties. Decoupled from constructor,
   * because it needs to resolve schema references and entity container elements.
   *
   * @param {CsdlSchema} schema to resolve references
   * @memberof EntityContainer
   */
  initSchemaDependentProperties(schema) {
    initChildProperties(this, schema);
  }
 
  /**
   * Resolves model path within this entity container.
   *
   * @param {strin} [path] model path
   * @returns {Object} resolved container element
   * @memberof EntityContainer
   */
  resolveModelPath(path) {
    let element;
    if (path) {
      let children = childCollections
        .map((collection) =>
          this[collection.name].find((item) => item.name === path)
        )
        .filter(Boolean);
 
      if (children.length === 0) {
        throw new Error(`Can't find schema element for path "${path}".`);
      } else if (children.length > 1) {
        throw new Error(
          `Schema error: "${path}" matched ${children.length} schema elememts.`
        );
      }
 
      element = children[0];
    }
 
    return element ? element : this;
  }
}
 
module.exports = EntityContainer;