@itwin/ecschema-metadata
Version:
ECObjects core concepts in typescript
195 lines • 9.79 kB
JavaScript
"use strict";
/*---------------------------------------------------------------------------------------------
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
/** @packageDocumentation
* @module Metadata
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.MutableEnumeration = exports.Enumeration = void 0;
const Helper_1 = require("../Deserialization/Helper");
const ECObjects_1 = require("../ECObjects");
const Exception_1 = require("../Exception");
const ECName_1 = require("../ECName");
const SchemaItem_1 = require("./SchemaItem");
/**
* A Typescript class representation of an ECEnumeration.
* @public @preview
*/
class Enumeration extends SchemaItem_1.SchemaItem {
schemaItemType = Enumeration.schemaItemType;
/** @internal */
static get schemaItemType() { return ECObjects_1.SchemaItemType.Enumeration; }
_type;
_isStrict;
_enumerators;
get enumerators() { return this._enumerators; }
get type() { return this._type; }
get isStrict() { return this._isStrict; }
/** @internal */
constructor(schema, name, primitiveType) {
super(schema, name);
this._type = primitiveType;
this._isStrict = true;
this._enumerators = [];
}
get isInt() { return this._type === ECObjects_1.PrimitiveType.Integer; }
get isString() { return this._type === ECObjects_1.PrimitiveType.String; }
/**
* Gets an enumerator that matches the name provided.
* @param name The ECName of the Enumerator to find.
*/
getEnumeratorByName(name) {
return this.enumerators.find((item) => item.name.toLowerCase() === name.toLowerCase());
}
getEnumerator(value) {
return this.enumerators.find((item) => item.value === value);
}
/**
* Checks whether there already exists an enumerator with this name or this value
* @param name The name of the enumerator we are trying to create
* @param value The value of the enumerator we are trying to create
* @internal
*/
findDuplicateEnumerators(name, value) {
this._enumerators.forEach((element) => {
if (element.name.toLowerCase() === name.toLowerCase())
throw new Exception_1.ECSchemaError(Exception_1.ECSchemaStatus.InvalidECJson, `The Enumeration ${this.name} has a duplicate Enumerator with name '${name}'.`);
if (element.value === value)
throw new Exception_1.ECSchemaError(Exception_1.ECSchemaStatus.InvalidECJson, `The Enumeration ${this.name} has a duplicate Enumerator with value '${value}'.`);
});
}
/**
* Creates an Enumerator with the provided name and value as well as optional parameters label and description
* @param name The name of the enumerator
* @param value The value of the enumerator. The type of this value is dependent on the backing type of the this Enumeration.
* @param label A localized display label that is used instead of the name in a GUI.
* @param description A localized description for the enumerator.
* @return AnyEnumerator object
* @internal
*/
createEnumerator(name, value, label, description) {
if (this.isInt && typeof (value) === "string") // throws if backing type is int and value is string
throw new Exception_1.ECSchemaError(Exception_1.ECSchemaStatus.InvalidECJson, `The Enumeration ${this.name} has a backing type 'integer' and an enumerator with value of type 'string'.`);
if (!this.isInt && typeof (value) === "number") // also throws if backing type is string and value is number
throw new Exception_1.ECSchemaError(Exception_1.ECSchemaStatus.InvalidECJson, `The Enumeration ${this.name} has a backing type 'string' and an enumerator with value of type 'integer'.`);
this.findDuplicateEnumerators(name, value); // check for duplicates; throw if there are any
if (!ECName_1.ECName.validate(name))
throw new Exception_1.ECSchemaError(Exception_1.ECSchemaStatus.InvalidECName, `The Enumeration ${this.name} has an enumerator with an invalid 'name' attribute. ${name} is not a valid ECName.`);
return { name, value, label, description };
}
/**
* Adds enumerator to list of enumerators on this Enumeration
* @param enumerator The enumerator to add
* @internal
*/
addEnumerator(enumerator) {
this._enumerators.push(enumerator);
}
/**
* Save this Enumeration's properties to an object for serializing to JSON.
* @param standalone Serialization includes only this object (as opposed to the full schema).
* @param includeSchemaVersion Include the Schema's version information in the serialized object.
*/
toJSON(standalone = false, includeSchemaVersion = false) {
const schemaJson = super.toJSON(standalone, includeSchemaVersion);
schemaJson.type = (this.isInt) ? "int" : "string";
schemaJson.isStrict = this.isStrict;
schemaJson.enumerators = this._enumerators.map(({ name, label, value, description }) => {
const enumJson = { name, value };
if (undefined !== label)
enumJson.label = label;
if (undefined !== description)
enumJson.description = description;
return enumJson;
});
return schemaJson;
}
/** @internal */
async toXml(schemaXml) {
const itemElement = await super.toXml(schemaXml);
if (undefined !== this.type)
itemElement.setAttribute("backingTypeName", (0, ECObjects_1.primitiveTypeToString)(this.type));
itemElement.setAttribute("isStrict", String(this.isStrict));
for (const enumerator of this.enumerators) {
const enumElement = schemaXml.createElement("ECEnumerator");
enumElement.setAttribute("name", enumerator.name);
const enumValue = typeof enumerator.value === "string" ? enumerator.value : enumerator.value.toString();
enumElement.setAttribute("value", enumValue);
if (undefined !== enumerator.label)
enumElement.setAttribute("displayLabel", enumerator.label);
if (undefined !== enumerator.description)
enumElement.setAttribute("description", enumerator.description);
itemElement.appendChild(enumElement);
}
return itemElement;
}
fromJSONSync(enumerationProps) {
super.fromJSONSync(enumerationProps);
if (undefined === this._type) {
if (/int/i.test(enumerationProps.type)) {
this._type = ECObjects_1.PrimitiveType.Integer;
}
else if (/string/i.test(enumerationProps.type)) {
this._type = ECObjects_1.PrimitiveType.String;
}
else {
if (Helper_1.SchemaReadHelper.isECSpecVersionNewer({ readVersion: enumerationProps.originalECSpecMajorVersion, writeVersion: enumerationProps.originalECSpecMinorVersion }))
this._type = ECObjects_1.PrimitiveType.String;
else
throw new Exception_1.ECSchemaError(Exception_1.ECSchemaStatus.InvalidECJson, `The Enumeration ${this.name} has an invalid 'type' attribute. It should be either "int" or "string".`);
}
}
else {
const primitiveTypePattern = (this.isInt) ? /int/i : /string/i;
if (!primitiveTypePattern.test(enumerationProps.type))
throw new Exception_1.ECSchemaError(Exception_1.ECSchemaStatus.InvalidECJson, `The Enumeration ${this.name} has an incompatible type. It must be "${(this.isInt) ? "int" : "string"}", not "${(this.isInt) ? "string" : "int"}".`);
}
this._isStrict = enumerationProps.isStrict;
if (undefined !== enumerationProps.enumerators) {
enumerationProps.enumerators.forEach((enumerator) => {
// Creates a new enumerator (with the specified name, value, label and description- label and description are optional) and adds to the list of enumerators.
// Throws ECSchemaError if there are duplicate names or values present in the enumeration
this.addEnumerator(this.createEnumerator(enumerator.name, enumerator.value, enumerator.label, enumerator.description));
});
}
}
async fromJSON(enumerationProps) {
this.fromJSONSync(enumerationProps);
}
/**
* @internal
*/
setIsStrict(isStrict) {
this._isStrict = isStrict;
}
/**
* Type guard to check if the SchemaItem is of type Enumeration.
* @param item The SchemaItem to check.
* @returns True if the item is an Enumeration, false otherwise.
*/
static isEnumeration(item) {
return item?.schemaItemType === ECObjects_1.SchemaItemType.Enumeration;
}
/**
* Type assertion to check if the SchemaItem is of type Enumeration.
* @param item The SchemaItem to check.
* @returns The item cast to Enumeration if it is an Enumeration, undefined otherwise.
* @internal
*/
static assertIsEnumeration(item) {
if (!this.isEnumeration(item))
throw new Exception_1.ECSchemaError(Exception_1.ECSchemaStatus.InvalidSchemaItemType, `Expected '${ECObjects_1.SchemaItemType.Enumeration}' (Enumeration)`);
}
}
exports.Enumeration = Enumeration;
/**
* An abstract class used for schema editing.
*
* @internal
*/
class MutableEnumeration extends Enumeration {
}
exports.MutableEnumeration = MutableEnumeration;
//# sourceMappingURL=Enumeration.js.map