hydrate-mongodb
Version:
An Object Document Mapper (ODM) for MongoDB.
129 lines (128 loc) • 5.07 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var mappingModel_1 = require("../mappingModel");
var mappingBuilderContext_1 = require("./mappingBuilderContext");
var mappingBuilder_1 = require("./mappingBuilder");
var persistenceError_1 = require("../../persistenceError");
var AnnotationMappingProvider = (function () {
function AnnotationMappingProvider(modules) {
this._modules = [];
if (modules) {
if (!Array.isArray(modules)) {
modules = [modules];
}
this.addModules(modules);
}
}
AnnotationMappingProvider.prototype.addModule = function (module) {
if (module) {
this._modules.push(module);
}
};
AnnotationMappingProvider.prototype.addModules = function (modules) {
if (modules) {
for (var _i = 0, modules_1 = modules; _i < modules_1.length; _i++) {
var module_1 = modules_1[_i];
this.addModule(module_1);
}
}
};
AnnotationMappingProvider.prototype.getMapping = function (config, callback) {
var builder = new Builder(config);
var mappings = builder.build(this._modules);
if (builder.hasErrors) {
callback(new persistenceError_1.PersistenceError(builder.getErrorMessage()), null);
return;
}
process.nextTick(function () { return callback(null, mappings); });
};
return AnnotationMappingProvider;
}());
exports.AnnotationMappingProvider = AnnotationMappingProvider;
var Builder = (function () {
function Builder(config) {
this._seenTypes = new Set();
this._context = new mappingBuilderContext_1.MappingBuilderContext(config);
}
Builder.prototype.build = function (modules) {
this._addGlobalMapping("String", mappingModel_1.MappingModel.createStringMapping());
this._addGlobalMapping("Number", mappingModel_1.MappingModel.createNumberMapping());
this._addGlobalMapping("Boolean", mappingModel_1.MappingModel.createBooleanMapping());
this._addGlobalMapping("Date", mappingModel_1.MappingModel.createDateMapping());
this._addGlobalMapping("RegExp", mappingModel_1.MappingModel.createRegExpMapping());
this._addGlobalMapping("Buffer", mappingModel_1.MappingModel.createBufferMapping());
for (var _i = 0, modules_2 = modules; _i < modules_2.length; _i++) {
var module_2 = modules_2[_i];
this._processModule(module_2);
}
return this._context.populateMappings();
};
Object.defineProperty(Builder.prototype, "hasErrors", {
get: function () {
return this._context.errors.length > 0;
},
enumerable: true,
configurable: true
});
Builder.prototype.getErrorMessage = function () {
return "Unable to build type mappings:\n" + this._context.errors.join("\n");
};
Builder.prototype._addGlobalMapping = function (name, mapping) {
var ctr = global[name];
if (!ctr) {
this._context.addError("Could not find global type '" + name + '.');
return;
}
var type = this._context.getType(ctr);
this._context.addBuilder(new mappingBuilder_1.MappingBuilder(this._context, type, mapping));
};
Builder.prototype._processModule = function (obj) {
if (typeof obj === "function") {
this._findTypes(this._context.getType(obj));
}
else if (typeof obj !== "object") {
return;
}
for (var p in obj) {
if (obj.hasOwnProperty(p)) {
this._processModule(obj[p]);
}
}
};
Builder.prototype._findTypes = function (type) {
if (!type || this._seenTypes.has(type)) {
return;
}
this._seenTypes.add(type);
if (type.baseType) {
this._findTypes(type.baseType);
}
for (var _i = 0, _a = type.getAnnotations(); _i < _a.length; _i++) {
var annotation = _a[_i];
if (annotation.createBuilder) {
this._context.addBuilder(annotation.createBuilder(this._context, type));
break;
}
}
this._scanPropertiesForTypes(type);
};
Builder.prototype._scanPropertiesForTypes = function (type) {
for (var _i = 0, _a = type.properties; _i < _a.length; _i++) {
var property = _a[_i];
this._findTypes(this._getPropertyTypeToScan(property));
}
};
Builder.prototype._getPropertyTypeToScan = function (property) {
for (var _i = 0, _a = property.getAnnotations(); _i < _a.length; _i++) {
var annotation = _a[_i];
if (annotation.target) {
if (typeof annotation.target === "string") {
return null;
}
return this._context.getType(annotation.target);
}
}
return property.type;
};
return Builder;
}());