deno.land / x / mongoose@6.7.5 / lib / helpers / document / compile.js
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228'use strict';
const documentSchemaSymbol = require('../../helpers/symbols').documentSchemaSymbol;const internalToObjectOptions = require('../../options').internalToObjectOptions;const utils = require('../../utils');
let Document;const getSymbol = require('../../helpers/symbols').getSymbol;const scopeSymbol = require('../../helpers/symbols').scopeSymbol;
const isPOJO = utils.isPOJO;
/*! * exports */
exports.compile = compile;exports.defineKey = defineKey;
const _isEmptyOptions = Object.freeze({ minimize: true, virtuals: false, getters: false, transform: false});
/** * Compiles schemas. * @param {Object} tree * @param {Any} proto * @param {String} prefix * @param {Object} options * @api private */
function compile(tree, proto, prefix, options) { Document = Document || require('../../document'); const typeKey = options.typeKey;
for (const key of Object.keys(tree)) { const limb = tree[key];
const hasSubprops = isPOJO(limb) && Object.keys(limb).length > 0 && (!limb[typeKey] || (typeKey === 'type' && isPOJO(limb.type) && limb.type.type)); const subprops = hasSubprops ? limb : null;
defineKey({ prop: key, subprops: subprops, prototype: proto, prefix: prefix, options: options }); }}
/** * Defines the accessor named prop on the incoming prototype. * @param {Object} options * @param {String} options.prop * @param {Boolean} options.subprops * @param {Any} options.prototype * @param {String} [options.prefix] * @param {Object} options.options * @api private */
function defineKey({ prop, subprops, prototype, prefix, options }) { Document = Document || require('../../document'); const path = (prefix ? prefix + '.' : '') + prop; prefix = prefix || '';
if (subprops) { Object.defineProperty(prototype, prop, { enumerable: true, configurable: true, get: function() { const _this = this; if (!this.$__.getters) { this.$__.getters = {}; }
if (!this.$__.getters[path]) { const nested = Object.create(Document.prototype, getOwnPropertyDescriptors(this));
// save scope for nested getters/setters if (!prefix) { nested.$__[scopeSymbol] = this; } nested.$__.nestedPath = path;
Object.defineProperty(nested, 'schema', { enumerable: false, configurable: true, writable: false, value: prototype.schema });
Object.defineProperty(nested, '$__schema', { enumerable: false, configurable: true, writable: false, value: prototype.schema });
Object.defineProperty(nested, documentSchemaSymbol, { enumerable: false, configurable: true, writable: false, value: prototype.schema });
Object.defineProperty(nested, 'toObject', { enumerable: false, configurable: true, writable: false, value: function() { return utils.clone(_this.get(path, null, { virtuals: this && this.schema && this.schema.options && this.schema.options.toObject && this.schema.options.toObject.virtuals || null })); } });
Object.defineProperty(nested, '$__get', { enumerable: false, configurable: true, writable: false, value: function() { return _this.get(path, null, { virtuals: this && this.schema && this.schema.options && this.schema.options.toObject && this.schema.options.toObject.virtuals || null }); } });
Object.defineProperty(nested, 'toJSON', { enumerable: false, configurable: true, writable: false, value: function() { return _this.get(path, null, { virtuals: this && this.schema && this.schema.options && this.schema.options.toJSON && this.schema.options.toJSON.virtuals || null }); } });
Object.defineProperty(nested, '$__isNested', { enumerable: false, configurable: true, writable: false, value: true });
Object.defineProperty(nested, '$isEmpty', { enumerable: false, configurable: true, writable: false, value: function() { return Object.keys(this.get(path, null, _isEmptyOptions) || {}).length === 0; } });
Object.defineProperty(nested, '$__parent', { enumerable: false, configurable: true, writable: false, value: this });
compile(subprops, nested, path, options); this.$__.getters[path] = nested; }
return this.$__.getters[path]; }, set: function(v) { if (v != null && v.$__isNested) { // Convert top-level to POJO, but leave subdocs hydrated so `$set` // can handle them. See gh-9293. v = v.$__get(); } else if (v instanceof Document && !v.$__isNested) { v = v.$toObject(internalToObjectOptions); } const doc = this.$__[scopeSymbol] || this; doc.$set(path, v); } }); } else { Object.defineProperty(prototype, prop, { enumerable: true, configurable: true, get: function() { return this[getSymbol].call(this.$__[scopeSymbol] || this, path); }, set: function(v) { this.$set.call(this.$__[scopeSymbol] || this, path, v); } }); }}
// gets descriptors for all properties of `object`// makes all properties non-enumerable to match previous behavior to #2211function getOwnPropertyDescriptors(object) { const result = {};
Object.getOwnPropertyNames(object).forEach(function(key) { const skip = [ 'isNew', '$__', '$errors', 'errors', '_doc', '$locals', '$op', '__parentArray', '__index', '$isDocumentArrayElement' ].indexOf(key) === -1; if (skip) { return; }
result[key] = Object.getOwnPropertyDescriptor(object, key); result[key].enumerable = false; });
return result;}
Version Info