offensive
Version:
Fast and boilerplate-free precondition checks for javascript.
115 lines (114 loc) • 4.89 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Registry = void 0;
var NoDsl_1 = require("./NoDsl");
/**
* @author Maciej Chałapuk (maciej@chalapuk.pl)
*/
var Registry = /** @class */ (function () {
function Registry() {
this.contextProto = {
assertions: {},
operators: {},
connectors: {},
};
this.traces = {};
this.entities = {};
var _a = this.contextProto, assertions = _a.assertions, operators = _a.operators, connectors = _a.connectors;
Object.setPrototypeOf(assertions, connectors);
Object.setPrototypeOf(operators, connectors);
// Fields names of `Result` interface are reserved
// as `OperatorBuilder` implements `Result`.
var trace = prepareTrace();
this.traces['success'] = this.traces['message'] = trace;
this.entities['success'] = this.entities['message'] = {};
}
Registry.prototype.addAssertion = function (assertions) {
var newAssertions = this.filterAlreadyRegistered(assertions);
this.extendPrototype(this.contextProto.assertions, newAssertions, function getAssertion(assertion) {
return this.__pushAssertion(assertion);
});
return this;
};
Registry.prototype.addAssertionFactory = function (factories) {
var newFactories = this.filterAlreadyRegistered(factories);
this.extendPrototype(this.contextProto.assertions, newFactories, function getAssertionFactory(factory) {
var _this = this;
return function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
return _this.__pushAssertionFactory(factory, args);
};
});
return this;
};
Registry.prototype.addUnaryOperator = function (operators) {
var newOperators = this.filterAlreadyRegistered(operators);
// Unary operators must be added on prototype of `AssertionBuilder`.
this.extendPrototype(this.contextProto.assertions, newOperators, function getUnaryOperator(operator) {
return this.__pushUnaryOperator(operator);
});
return this;
};
Registry.prototype.addBinaryOperator = function (operators) {
var newOperators = this.filterAlreadyRegistered(operators);
this.extendPrototype(this.contextProto.operators, newOperators, function getBinaryOperator(operator) {
return this.__pushBinaryOperator(operator);
});
return this;
};
Registry.prototype.addConnectors = function (connectors) {
var newConnectors = this.filterAlreadyRegistered(connectors);
this.extendPrototype(this.contextProto.connectors, newConnectors, function getConnector() {
// noop
return this;
});
return this;
};
Registry.prototype.filterAlreadyRegistered = function (entities) {
var _this = this;
var trace = prepareTrace();
return Object.keys(entities)
.filter(function (name) {
NoDsl_1.default.check(name.length !== 0, 'name.length must be > 0 (got \'', name, '\')');
NoDsl_1.default.check(name[0] !== '_', 'name must not start with underscore (got \'', name, '\')');
var alreadyRegistered = _this.entities[name];
if (alreadyRegistered === undefined) {
return true;
}
NoDsl_1.default.check(alreadyRegistered === entities[name], 'Entity of name ', name, ' already registered.\n', 'PREVIOUS REGISTRATION STACK TRACE:\n', _this.traces[name], 'CURRENT REGISTRATION STACK TRACE:\n');
return false;
})
.reduce(function (result, name) {
_this.traces[name] = trace;
_this.entities[name] = entities[name];
result[name] = entities[name];
return result;
}, {});
};
Registry.prototype.extendPrototype = function (proto, newElements, getter) {
var enumerable = true;
var names = Object.keys(newElements);
names.forEach(function (name) {
function get() {
return getter.call(this, newElements[name]);
}
Object.defineProperty(proto, name, { get: get, enumerable: enumerable });
});
};
Registry.instance = new Registry();
return Registry;
}());
exports.Registry = Registry;
exports.default = Registry;
function prepareTrace() {
var stack = new Error().stack;
var firstNewlineIndex = stack.indexOf('\n');
var secondNewlineIndex = stack.indexOf('\n', firstNewlineIndex + 1);
var trace = stack.substring(secondNewlineIndex + 1)
.split('\n')
.map(function (line) { return " ".concat(line); })
.join('\n');
}