@thefoxjob/js-meta
Version:
Stores meta data of various kinds about given target classes or methods
365 lines (295 loc) • 9.95 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _Data = require('./Meta/Data');
var _Data2 = _interopRequireDefault(_Data);
var _ClassData = require('./Meta/ClassData');
var _ClassData2 = _interopRequireDefault(_ClassData);
var _MethodData = require('./Meta/MethodData');
var _MethodData2 = _interopRequireDefault(_MethodData);
var _InvalidTarget = require('./Exceptions/InvalidTarget');
var _InvalidTarget2 = _interopRequireDefault(_InvalidTarget);
var _InvalidData = require('./Exceptions/InvalidData');
var _InvalidData2 = _interopRequireDefault(_InvalidData);
var _MetaError = require('./Exceptions/MetaError');
var _MetaError2 = _interopRequireDefault(_MetaError);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
/**
* Mata Map symbol
*
* @type {Symbol}
*/
var map = Symbol('meta-map');
/**
* @class Meta
*
* @description Stores meta data of various kinds about given target classes or methods
*
* @author Alin Eugen Deac <aedart@gmail.com>
*/
var Meta = function () {
/**
* @constructor
*/
function Meta() {
_classCallCheck(this, Meta);
this[map] = new WeakMap();
}
/**
* Set meta data for target
*
* Method will overwrite any existing meta data for target
*
* @param {Function|Object} target
* @param {Data} data
*
* @returns {Meta}
*
* @throws {MetaError} If target or given data is invalid
*/
_createClass(Meta, [{
key: 'set',
value: function set(target, data) {
// Fail if invalid target
var type = typeof target === 'undefined' ? 'undefined' : _typeof(target);
if (!(type === 'function' || type === 'object')) {
throw new _InvalidTarget2.default();
}
// Fail if invalid data
if (!(data instanceof _Data2.default)) {
throw new _InvalidData2.default();
}
this[map].set(target, data);
return this;
}
/**
* Add meta data for target
*
* Fails if there already exists meta data for target
*
* @param {Function|Object} target
* @param {Data} data
*
* @returns {Meta}
*
* @throws {MetaError} If target or given data is invalid OR if meta data has already been added for target
*/
}, {
key: 'add',
value: function add(target, data) {
this._assertTargetDoesNotExist(target);
return this.set(target, data);
}
/**
* Set meta class data for target
*
* By using this method, you "label" (associate) the target to be
* a class.
*
* Method will overwrite any existing meta data for target
*
* @param {Function|Object} target
* @param {ClassData|Object} [data]
*
* @returns {ClassData}
*
* @throws {MetaError} If target or given data is invalid
*/
}, {
key: 'setClass',
value: function setClass(target) {
var data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var classData = data;
if (!(data instanceof _ClassData2.default)) {
classData = new _ClassData2.default(target, data);
}
this.set(target, classData);
return classData;
}
/**
* Add meta class data for target
*
* By using this method, you "label" (associate) the target to be
* a class.
*
* Fails if there already exists meta data for target
*
* @param {Function|Object} target
* @param {ClassData|Object} [data]
*
* @returns {ClassData}
*
* @throws {MetaError} If target or given data is invalid OR if meta data has already been added for target
*/
}, {
key: 'addClass',
value: function addClass(target) {
var data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
this._assertTargetDoesNotExist(target);
return this.setClass(target, data);
}
/**
* Check if target has been "labelled" (associated) with
* meta class data.
*
* @see Meta.setClass()
* @see Meta.addClass()
*
* @param {Function|Object} target
*
* @returns {boolean}
*/
}, {
key: 'hasClass',
value: function hasClass(target) {
if (!this.has(target)) {
return false;
}
var meta = this.get(target);
return meta instanceof _ClassData2.default;
}
/**
* Set meta method data for target
*
* By using this method, you "label" (associate) the target to be
* a method.
*
* Method will overwrite any existing meta data for target
*
* @param {Function|Object} target
* @param {MethodData|Object} [data]
*
* @returns {MethodData}
*
* @throws {MetaError} If target or given data is invalid
*/
}, {
key: 'setMethod',
value: function setMethod(target) {
var data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var methodData = data;
if (!(data instanceof _MethodData2.default)) {
methodData = new _MethodData2.default(target, data);
}
this.set(target, methodData);
return methodData;
}
/**
* Add meta method data for target
*
* By using this method, you "label" (associate) the target to be
* a method.
*
* Fails if there already exists meta data for target
*
* @param {Function|Object} target
* @param {MethodData|Object} [data]
*
* @returns {MethodData}
*
* @throws {MetaError} If target or given data is invalid OR if meta data has already been added for target
*/
}, {
key: 'addMethod',
value: function addMethod(target) {
var data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
this._assertTargetDoesNotExist(target);
return this.setMethod(target, data);
}
/**
* Check if target has been "labelled" (associated) with
* meta method data.
*
* @see Meta.setMethod()
* @see Meta.addMethod()
*
* @param {Function|Object} target
*
* @returns {boolean}
*/
}, {
key: 'hasMethod',
value: function hasMethod(target) {
if (!this.has(target)) {
return false;
}
var meta = this.get(target);
return meta instanceof _MethodData2.default;
}
/**
* Returns meta data for the given target
*
* @param {Function|Object} target
*
* @returns {Data|undefined}
*/
}, {
key: 'get',
value: function get(target) {
return this[map].get(target);
}
/**
* Check if target has meta data
*
* @param {Function|Object} target
*
* @returns {boolean}
*/
}, {
key: 'has',
value: function has(target) {
return this[map].has(target);
}
/**
* Delete target meta data
*
* @param {Function|Object} target
*
* @returns {boolean}
*/
}, {
key: 'delete',
value: function _delete(target) {
return this[map].delete(target);
}
/**
* Alias for delete
*
* @see Meta.delete()
*
* @param {Function|Object} target
*
* @returns {boolean}
*/
}, {
key: 'forget',
value: function forget(target) {
return this.delete(target);
}
/**
* Assert that given target does not already
* exist in Meta
*
* @param {Function|Object} target
*
* @private
*
* @throws {MetaError}
*/
}, {
key: '_assertTargetDoesNotExist',
value: function _assertTargetDoesNotExist(target) {
if (this.has(target)) {
throw new _MetaError2.default('Target already has meta defined');
}
}
}]);
return Meta;
}();
var instance = new Meta();
Object.freeze(instance);
exports.default = instance;