Plato on Github
Report Home
src/define/check.js
Maintainability
79.47
Lines of code
307
Difficulty
21.04
Estimated Errors
0.86
Function weight
By Complexity
By SLOC
/** * @file Check entity definition * @since 0.1.6 */ /*#ifndef(UMD)*/ "use strict"; /*global _GpfEntityDefinition*/ // Entity definition /*global _gpfCreateAbstractFunction*/ // Build a function that throws the abstractMethod exception /*global _gpfErrorDeclare*/ // Declare new gpf.Error names /*global _gpfFunc*/ // Create a new function using the source /*global _gpfIgnore*/ // Helper to remove unused parameter warning /*global _gpfObjectForEach*/ // Similar to [].forEach but for objects /*#endif*/ _gpfErrorDeclare("define/check", { /** * ### Summary * * One of the $ properties is invalid in the definition passed to {@link gpf.define} * * ### Description * * The list of possible $ properties is fixed and depends on the entity type. * This error is thrown when one $ property is not allowed. * @since 0.1.6 */ invalidEntity$Property: "Invalid entity $ property", /** * ### Summary * * Entity name is missing in the definition passed to {@link gpf.define} * * ### Description * * This error is thrown when the entity name is missing * @since 0.1.6 */ missingEntityName: "Missing entity name", /** * ### Summary * * Entity namespace is invalid in the definition passed to {@link gpf.define} * * ### Description * * This error is thrown when the namespace is invalid * @since 0.1.6 */ invalidEntityNamespace: "Invalid entity namespace" }); function _gpfDefineEntityCheck$PropertyInAllowed$Properties (name, allowedList) { if (!allowedList.includes(name)) { gpf.Error.invalidEntity$Property(); } } var _GPF_DEFINE_SPECIAL_PROPERTY_PREFIX = "$"; function _gpfDefineEntityCheckProperty (value, name) { /*jshint -W040*/ /*eslint-disable no-invalid-this*/ // bound through thisArg if (name.startsWith(_GPF_DEFINE_SPECIAL_PROPERTY_PREFIX)) { this._check$Property(name.substring(_GPF_DEFINE_SPECIAL_PROPERTY_PREFIX.length), value); } else { this._checkProperty(name, value); } /*jshint -W040*/ /*eslint-enable no-invalid-this*/ } Object.assign(_GpfEntityDefinition.prototype, { /** * Entity type (class...) * * @readonly * @since 0.1.6 */ _type: "", /** * List of allowed $ properties * * @type {String[]} * @readonly * @since 0.1.6 */ _allowed$Properties: "type,name,namespace".split(","), /** * Check if the $ property is allowed * * @param {String} name $ Property name (without the starting $) * @param {*} value $ Property value * @since 0.1.6 */ _check$Property: function (name, value) { _gpfIgnore(value); if (name !== this._type) { _gpfDefineEntityCheck$PropertyInAllowed$Properties(name, this._allowed$Properties); } }, /** * Throw the invalid property error * * @abstract * @protected * @since 0.1.8 */ _throwInvalidProperty: _gpfCreateAbstractFunction(), /** * Regular expression used to validate member name * * @type {RegExp} * @readonly * @protected * @since 0.1.8 */ _reMemberName: new RegExp(".*"), /** * Check that the member name is a valid one * * @param {String} name Member name * @since 0.1.8 */ _checkMemberName: function (name) { if (!this._reMemberName.exec(name)) { this._throwInvalidProperty(); } }, /** * List of reserved member names * * @type {String[]} * @readonly * @constant * @since 0.1.8 */ _reservedNames: "super,class,public,private,protected,static,mixin".split(","), /** * Check that the member name is not a reserved one * * @param {String} name Member name * @since 0.1.6 */ _checkReservedMemberName: function (name) { if (this._reservedNames.includes(name)) { this._throwInvalidProperty(); } }, /** * Check the value of the member * * @param {String} name Property name * @param {*} value Property value * @protected * @since 0.1.8 */ _checkMemberValue: _gpfFunc(["name", "value"], " "), /** * Check if the property is allowed * NOTE: $ properties are handled by {@link _check$Property} * * @param {String} name Property name * @param {*} value Property value * @since 0.1.6 */ _checkProperty: function (name, value) { this._checkMemberName(name); this._checkReservedMemberName(name); this._checkMemberValue(name, value); }, /** * Check the properties contained in the definition passed to {@link gpf.define} * @since 0.1.6 */ _checkProperties: function () { _gpfObjectForEach(this._initialDefinition, _gpfDefineEntityCheckProperty, this); }, /** * Entity name * @since 0.1.6 */ _name: "", /** * Compute name property * @since 0.1.6 */ _readName: function () { var definition = this._initialDefinition; this._name = definition["$" + this._type] || definition.$name; }, /** * Check if name property is not empty (throw the error otherwise) * * @throws {gpf.Error.MissingEntityName} * @since 0.1.6 */ _checkNameIsNotEmpty: function () { if (!this._name) { gpf.Error.missingEntityName(); } }, /** * Throw the invalid name error * * @abstract * @protected * @since 0.1.8 */ _throwInvalidName: _gpfCreateAbstractFunction(), /** * Regular expression used to validate entity name * * @type {RegExp} * @readonly * @protected * @since 0.1.8 */ _reName: new RegExp(".*"), /** * Check name property (content) * * @since 0.1.6 */ _checkName: function () { if (!this._reName.exec(this._name)) { this._throwInvalidName(); } }, /** * Entity namespace * @since 0.1.6 */ _namespace: "", /** * If the name is prefixed with a namespace, isolate it and update name property * * @return {String|undefined} Namespace contained in the name or undefined if none * @since 0.1.6 */ _extractRelativeNamespaceFromName: function () { var parts = new RegExp("(.*)\\.([^\\.]+)$").exec(this._name), NAME_PART = 2, NAMESPACE_PART = 1; if (parts) { this._name = parts[NAME_PART]; return parts[NAMESPACE_PART]; } }, /** * Compute namespace property * @since 0.1.6 */ _readNamespace: function () { var namespaces = [ this._initialDefinition.$namespace, this._extractRelativeNamespaceFromName() ].filter(function (namespacePart) { return namespacePart; }); if (namespaces.length) { this._namespace = namespaces.join("."); } }, /** * Check namespace property * * @throws {gpf.Error.InvalidEntityNamespace} * @since 0.1.6 */ _checkNamespace: function () { if (!new RegExp("^(:?[a-z_$][a-zA-Z0-9]+(:?\\.[a-z_$][a-zA-Z0-9]+)*)?$").exec(this._namespace)) { gpf.Error.invalidEntityNamespace(); } }, check: function () { this._checkProperties(); this._readName(); this._checkNameIsNotEmpty(); this._readNamespace(); this._checkName(); this._checkNamespace(); } });