Home Manual Reference Source Test

src/lib/model/NodeId.js

const idTypeForIdentifier = {};
const idTypeForValue = {};

let NumericIdType;
let StringIdType;
let GUIDIdType;
let BytestringIdType;

/**
 * A NodeId's type. **Never create instances of this class, always use the exported constant ones.**
 *
 * @example
 * import { NodeIdType } from 'atvise-scm';
 *
 * const numericType = NodeIdType.Numeric;
 * const stringType = NodeIdType.String;
 * const guidType = NodeIdType.GUID;
 * const bytestringType = NodeIdType.Bytestring;
 */
export class NodeIdType {

  /**
   * Creates a new NodeIdType.
   * @deprecated Never create instances directly, use one of `NodeIdType.Numeric`,
   * `NodeIdType.String`, `NodeIdType.GUID` and `NodeIdType.Bytestring`.
   * @param {String} name The new type's name.
   * @param {Number} value The new type's value.
   * @param {String} identifier The identivier to use when converting to and from String.
   */
  constructor(name, value, identifier) {
    /**
     * The name of a type.
     * @type {String}
     */
    this.name = name;

    /**
     * The numeric value of a type.
     * @type {Number}
     */
    this.value = value;

    /**
     * The identivier to use when converting to and from String.
     * @type {String}
     */
    this.identifier = identifier;

    idTypeForIdentifier[identifier] = this;
    idTypeForValue[value] = this;
  }

  /**
   * Compares two NodeIdTypes. Needed internally by `node-opcua`.
   * @param {NodeIdType} type The type to compare
   * @return {Boolean} If `type` matches the current instance.
   */
  is(type) {
    return type.value === this.value;
  }

  /**
   * Returns the string representation of a NodeIdType.
   * @return {String} A string representing the NodeIdType.
   */
  toString() {
    return `NodeIdType.${this.name}{${this.value}`;
  }

  /**
   * Returns the type for an identifier.
   * @param {String} identifier The identifier to get a NodeIdType for.
   * @returns {NodeIdType} The corresponding type.
   */
  static forIdentifier(identifier) {
    return idTypeForIdentifier[identifier];
  }

  /**
   * Returns the type for a value.
   * @param {Number} value The numeric value to get a NodeIdType for.
   * @returns {NodeIdType} The corresponding type.
   */
  static forValue(value) {
    return idTypeForValue[value];
  }

  /**
   * Numeric id type.
   * @type {NodeIdType}
   */
  static get Numeric() {
    return NumericIdType;
  }

  /**
   * String id type.
   * @type {NodeIdType}
   */
  static get String() {
    return StringIdType;
  }

  /**
   * GUID id type.
   * @type {NodeIdType}
   */
  static get GUID() {
    return GUIDIdType;
  }

  /**
   * Bytestring id type.
   * @type {NodeIdType}
   */
  static get Bytestring() {
    return BytestringIdType;
  }

}

NumericIdType = new NodeIdType('Numeric', 0x01, 'i');
StringIdType = new NodeIdType('String', 0x02, 's');
GUIDIdType = new NodeIdType('GUID', 0x03, 'g');
BytestringIdType = new NodeIdType('Bytestring', 0x04, 'b');

const NodeIdStringRegExp = /ns=([0-9]+);(.)=(.*)/;

/**
 * An OPC-UA node's id.
 */
export default class NodeId {

  /**
   * Creates a new NodeId based on it's type, value and (optional) namespace.
   * @param {String|Number} value The NodeId's value (e.g. a path or numeric reference).
   * @param {NodeIdType} [type] The NodeId's type. Defaults to {@link NodeIdType.Numeric} or
   * {@link NodeIdType.String} based on the type of `value`.
   * @param {Number} [namespace=1] The NodeId's namespace. Defaults to 1
   */
  constructor(value, type, namespace = 1) {
    /**
     * The NodeId's value (e.g. a path or numeric reference).
     * @type {String|Number}
     */
    this.value = value;

    /**
     * The NodeId's namespace.
     * @type {Number}
     */
    this.namespace = namespace;

    /**
     * The NodeId's type.
     * @type {NodeIdType}
     */
    this.identifierType = type;
    if (this.identifierType === undefined) {
      this.identifierType = (typeof value === 'number') ?
        NodeIdType.Numeric :
        NodeIdType.String;
    }
  }

  /**
   * Creates a new NodeId based on its string representation.
   * @param {String} string The NodeId's string representation.
   * @return {NodeId}
   */
  static fromString(string) {
    const match = string.match(NodeIdStringRegExp);

    if (!match) {
      throw new Error(`Could not parse ${string}`);
    }

    return new NodeId(match[3], NodeIdType.forIdentifier[match[2]], match[1]);
  }

  /**
   * Returns the string representation of a NodeId.
   * @return {String}
   *
   * @example
   * const nodeId = new NodeId('AGENT', NodeIdType.String, 1);
   *
   * console.log(nodeId.toString());
   * // Output: 'ns=1;s=AGENT'
   */
  toString() {
    return `ns=${this.namespace};${this.identifierType.identifier}=${this.value}`;
  }

}