@itwin/ecschema-metadata
Version:
ECObjects core concepts in typescript
87 lines • 3.86 kB
JavaScript
;
/*---------------------------------------------------------------------------------------------
* 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.ECName = void 0;
const core_bentley_1 = require("@itwin/core-bentley");
const Exception_1 = require("./Exception");
const validECNameRegex = /^[a-zA-Z_]\w*$/i;
const ecNameReplacerRegex = /__x([0-9a-fA-F]{4})__/g;
const leadingDigits = ["0000", "000", "00", "0", ""];
function isDigit(character) {
(0, core_bentley_1.assert)(1 === character.length);
return character >= "0" && character <= "9";
}
function isValidAlphaNumericCharacter(c) {
(0, core_bentley_1.assert)(1 === c.length);
return (((c >= "0" && c <= "9") || (c >= "A" && c <= "Z") || (c >= "a" && c <= "z") || c === "_"));
}
/** The name of an item in a [[Schema]], encoded to meet restrictions on the characters usable in such names.
* An ECName meets the following criteria:
* - Contains at least one character.
* - Does not begin with a digit.
* - Consists entirely of characters in the ASCII ranges A-Z, a-z, and 0-9; and the underscore ("_") character.
*
* All characters not meeting the above criteria are encoded as "__x####__" where "####" is the UTF-16 character code.
* Such names are often automatically generated from the item's display label, which is unrestricted in the characters it may contain.
* @public
*/
class ECName {
_name;
/** Construct a new ECName from a valid EC name.
* throws ECSchemaError if `name` does not meet the criteria for a valid EC name.
*/
constructor(name) {
if (!ECName.validate(name))
throw new Exception_1.ECSchemaError(Exception_1.ECSchemaStatus.InvalidECName);
this._name = name;
}
/** Returns true if a string meets the criteria of a valid EC name. */
static validate(name) {
return validECNameRegex.test(name);
}
/** The underlying name as a string. */
get name() {
return this._name;
}
/** Create an ECName from an arbitrary string, encoding any special characters as "__x####__" where "####" is the UTF-16 character code.
* @throws ECSchemaError if `input` is an empty string.
*/
static encode(input) {
if (0 === input.length)
throw new Exception_1.ECSchemaError(Exception_1.ECSchemaStatus.InvalidECName);
if (ECName.validate(input)) {
// It's already a valid EC name.
return new ECName(input);
}
let output = "";
function appendEncodedCharacter(index) {
const hex = input.charCodeAt(index).toString(16).toUpperCase();
(0, core_bentley_1.assert)(hex.length > 0 && hex.length < 5);
output += `__x${leadingDigits[hex.length]}${hex}__`;
}
// First character cannot be a digit.
const firstCharIsDigit = isDigit(input[0]);
if (firstCharIsDigit)
appendEncodedCharacter(0);
for (let i = firstCharIsDigit ? 1 : 0; i < input.length; i++) {
const char = input[i];
if (!isValidAlphaNumericCharacter(char))
appendEncodedCharacter(i);
else
output += char;
}
return new ECName(output);
}
/** Decode this ECName, replacing encoded special characters with the characters they encode. */
decode() {
return this.name.replace(ecNameReplacerRegex, (_match, hex) => String.fromCharCode(Number.parseInt(hex, 16)));
}
}
exports.ECName = ECName;
//# sourceMappingURL=ECName.js.map