UNPKG

modm

Version:

A MongoDB Object Document Mapper (ODM)

171 lines (123 loc) 3.96 kB
var prepare = require("./options").prepare; // class Schema function Schema(obj, indexes) { if (!obj || obj.constructor.name !== "Object") { throw new Error("First argument must be an object."); } this.paths = {}; this.add(obj); // prepare indexes if (indexes && indexes.constructor.name === "Array") { this.indexes = prepareIndexes(indexes); } } // add paths to schema Schema.prototype.add = function(obj, prefix) { prefix = prefix || ""; for (var key in obj) { if (obj[key] === null) { throw new TypeError("Invalid value for schema path `" + prefix + key + "`"); } // get type and definition var type = obj[key].constructor.name; var object = obj[key]; // handle array structures if (type === "Array" && obj[key].length > 0) { type = obj[key][0].constructor.name; object = obj[key][0]; } // check if obj[key] is an object and not a type with options if (type === "Object" && typeof object.type === "undefined") { // handle nested objects if (Object.keys(object).length) { //this.nested[prefix + key] = true; this.add(object, prefix + key + "."); } else { path.call(this, prefix + key, object); } // handle nested schemas } else if (type === "Schema" && object.paths) { this.add(object.paths, prefix + key + "."); // create path } else { path.call(this, prefix + key, object); } } }; function getType(value) { if (typeof value === "string") { return value.toLowerCase(); } return (value.name || value.constructor.name).toLowerCase(); } // prepare schema path options function path(opt_path, options) { // convert type to string var type; if (typeof options.type === "undefined") { type = getType(options); options = { type: type }; } else { type = getType(options.type); options.type = type; } // add to required if (options.required) { if (!this.required) { this.required = []; } this.required.push(opt_path); } // add to default if (options.default) { if (!this.default) { this.default = {}; } this.default[opt_path] = options.default; } // prepare options this.paths[opt_path] = prepare(options); } function prepareIndexes(indexes) { var _indexes = []; for (var i in indexes) { // handle fields if (!indexes[i].fields) { continue; } var name; if (indexes[i].fields.constructor.name === "Array") { name = indexes[i].fields.join(""); } else { name = indexes[i].fields.toString(); } // handle options if (typeof indexes[i].options === "object") { var sorted = []; for (var option in indexes[i].options) { if (!indexes[i].options && option !== "w" && option !== "v") { continue; } sorted.push(option); } sorted.sort(); for (var ii in sorted) { if (indexes[i].options[sorted[ii]]) { // convert boolean to number if (typeof indexes[i].options[sorted[ii]] === "boolean") { indexes[i].options[sorted[ii]] = 1; } name += sorted[ii] + indexes[i].options[sorted[ii]]; } } } else { indexes[i].options = {}; } indexes[i].options.name = name; _indexes.push([indexes[i].fields, indexes[i].options]); } return _indexes; } module.exports = Schema;