JSON Model-to-Model Projection (JM2MP) Documentation

JSON Model-to-Model Projection (JM2MP) Documentation

source

modules/helpers.js

The file helpers.js contains the module [helpers]{@link module:jm2mp/modules/helpers}, which implements helper functions related with JM2MP projection modules.

Author

  • Luis Maria CAMARA ROSSI

Copyright

  • Universidad Nacional de Educación a Distancia (U.N.E.D.) 2026

License

  • BSD-3-Clause
/**
 * @author Luis Maria CAMARA ROSSI
 * @copyright Universidad Nacional de Educación a Distancia (U.N.E.D.) 2026
 * @license BSD-3-Clause
 * @file
 * The file `helpers.js` contains the module
 * [helpers]{@link module:jm2mp/modules/helpers}, which implements
 * helper functions related with `JM2MP` _projection modules_.
**/

/**
 * @module jm2mp/modules/helpers
 * @description
 * The module [helpers]{@link module:jm2mp/modules/helpers} implements
 * helper functions related with `JM2MP` _projection modules_.
**/

/* ------------------------------------------------------------------ */
/* ------------------------------------------------------------------ */

import { ValidationError } from "../errors.js";

/* ------------------------------------------------------------------ */
/* ------------------------------------------------------------------ */

/**
 * @constant {string}
 * @description
 * The name of the **root template** of any **JM2MP projection**.
 * Its value is `'$'`.
 */
export const ROOT_TEMPLATE_NAME = '$' ;

/* ------------------------------------------------------------------ */

/**
 * @description
 * It tests if the `module` JSON value can be used (considered) as a
 * _projection module_ or not.
 * 
 * A JSON value can be used as a _projection module_ if:
 * - It is an object.
 * - It is not `null`.
 * - It is not an array.
 * 
 * @param {*} module
 * The actual JSON value to test as a valid _projection module_.
 * @returns {boolean}
 * `true` whenever `module` is valid as a _projection module_;
 * `false` otherwise.
 */
export function isModule(module)
{
  return (
    (typeof module === "object") &&
    (module !== null) &&
    ( ! Array.isArray(module) )
  );
}

/* ------------------------------------------------------------------ */

/**
 * @description
 * It throws an [ValidationError]{@link module:jm2mp/errors.ValidationError}
 * whenever `module` is not a valid module.
 * @param {*} module
 * The actual JSON value to test as a valid _projection module_.
 * @throws {module:jm2mp/errors.ValidationError}
 * Raised whenever `module` is not a valid module.
 * @see {@link module:jm2mp/modules/helpers.isModule}
 */
export function ThrowsValidationErrorWhenIsNotAModule(module)
{
  if ( ! isModule(module) )
  {
    throw new ValidationError("A module must be a non-null JSON object.");
  }
}

/* ------------------------------------------------------------------ */

/**
* It builds a simple _projection module_ starting from the _root
 * template_, neither adding _options_, _schema_ nor _named templates_.
 *
 * It is usually used as part of unit and integrations tests.
 *
 * @param {*} rootProjection
 * The JSON value for the _root projection_ of the _projection module_
 * built by this function.
 * @returns {object}
 * The _projection module_ built using `rootProjection`'s value as its
 * _root projection_.
 */
export function moduleOf(rootProjection)
{
  const result = new Object();
  result[ROOT_TEMPLATE_NAME] = rootProjection ;
  return result ;
}

/* ------------------------------------------------------------------ */

/**
 * @description
 * It builds a _projection module_ using `rootProjection`'s value as its
 * _root projection_ and `namedTemplates` as the rest of templates.
 * 
 * If `namedTemplates` also contains a _root projection_ it will be
 * lost, overriden by `rootProjection`.
 *
 * @param {*} rootProjection
 * The JSON value for the _root projection_ of the _projection module_
 * built by this function.
 * @param {object} [namedTemplates]
 * Other _named templates_ to be added to the resulting _projection
 * module_.
 * @returns {object}
 * The _projection module_ built using `rootProjection`'s value as its
 * _root projection_ and `namedTemplates` as the rest of templates.
**/
export function moduleWith(rootProjection, namedTemplates = {})
{
  return { ...namedTemplates, ...moduleOf(rootProjection) };
}

/* ------------------------------------------------------------------ */

/**
 * @description
 * It detects if a package (ESM module) can be imported dynamically.
 *
 * It is usefull for skip tests whenever an optional dependency is not
 * installed.
 *
 * @param {string} moduleName
 * @returns {Promise<boolean>}
 * `true` whenever `moduleName` can be
 * [import]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import}'ed;
 * `false` otherwise.
**/
export async function isPackagedEsmModuleAvailable(moduleName)
{
  try
  {
    await import(moduleName);
    return true;
  }
  catch
  {
    return false;
  }
}

/* ------------------------------------------------------------------ */
/* ------------------------------------------------------------------ */
/* End of file: ${JM2MP.JS}/src/modules/helpers.js                    */