Ohm-Management - Projektarbeit B-ME
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

map.js 4.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. 'use strict';
  2. const Mixed = require('../schema/mixed');
  3. const get = require('../helpers/get');
  4. const util = require('util');
  5. const utils = require('../utils');
  6. /*!
  7. * ignore
  8. */
  9. class MongooseMap extends Map {
  10. constructor(v, path, doc, schemaType) {
  11. if (v != null && v.constructor.name === 'Object') {
  12. v = Object.keys(v).reduce((arr, key) => arr.concat([[key, v[key]]]), []);
  13. }
  14. super(v);
  15. this.$__parent = doc != null && doc.$__ != null ? doc : null;
  16. this.$__path = path;
  17. this.$__schemaType = schemaType == null ? new Mixed(path) : schemaType;
  18. this.$__runDeferred();
  19. }
  20. $init(key, value) {
  21. checkValidKey(key);
  22. super.set(key, value);
  23. if (value != null && value.$isSingleNested) {
  24. value.$basePath = this.$__path + '.' + key;
  25. }
  26. }
  27. $__set(key, value) {
  28. super.set(key, value);
  29. }
  30. set(key, value) {
  31. checkValidKey(key);
  32. // Weird, but because you can't assign to `this` before calling `super()`
  33. // you can't get access to `$__schemaType` to cast in the initial call to
  34. // `set()` from the `super()` constructor.
  35. if (this.$__schemaType == null) {
  36. this.$__deferred = this.$__deferred || [];
  37. this.$__deferred.push({ key: key, value: value });
  38. return;
  39. }
  40. const fullPath = this.$__path + '.' + key;
  41. const populated = this.$__parent != null && this.$__parent.$__ ?
  42. this.$__parent.populated(fullPath) || this.$__parent.populated(this.$__path) :
  43. null;
  44. if (populated != null) {
  45. if (value.$__ == null) {
  46. value = new populated.options.model(value);
  47. }
  48. value.$__.wasPopulated = true;
  49. } else {
  50. try {
  51. value = this.$__schemaType.
  52. applySetters(value, this.$__parent, false, this.get(key));
  53. } catch (error) {
  54. if (this.$__parent != null && this.$__parent.$__ != null) {
  55. this.$__parent.invalidate(fullPath, error);
  56. return;
  57. }
  58. throw error;
  59. }
  60. }
  61. super.set(key, value);
  62. if (value != null && value.$isSingleNested) {
  63. value.$basePath = this.$__path + '.' + key;
  64. }
  65. if (this.$__parent != null && this.$__parent.$__) {
  66. this.$__parent.markModified(this.$__path + '.' + key);
  67. }
  68. }
  69. delete(key) {
  70. this.set(key, undefined);
  71. super.delete(key);
  72. }
  73. toBSON() {
  74. return new Map(this);
  75. }
  76. toObject(options) {
  77. if (get(options, 'flattenMaps')) {
  78. const ret = {};
  79. const keys = this.keys();
  80. for (const key of keys) {
  81. ret[key] = this.get(key);
  82. }
  83. return ret;
  84. }
  85. return new Map(this);
  86. }
  87. toJSON() {
  88. const ret = {};
  89. const keys = this.keys();
  90. for (const key of keys) {
  91. ret[key] = this.get(key);
  92. }
  93. return ret;
  94. }
  95. inspect() {
  96. return new Map(this);
  97. }
  98. $__runDeferred() {
  99. if (!this.$__deferred) {
  100. return;
  101. }
  102. for (let i = 0; i < this.$__deferred.length; ++i) {
  103. this.set(this.$__deferred[i].key, this.$__deferred[i].value);
  104. }
  105. this.$__deferred = null;
  106. }
  107. }
  108. if (util.inspect.custom) {
  109. Object.defineProperty(MongooseMap.prototype, util.inspect.custom, {
  110. enumerable: false,
  111. writable: false,
  112. configurable: false,
  113. value: MongooseMap.prototype.inspect
  114. });
  115. }
  116. Object.defineProperty(MongooseMap.prototype, '$__set', {
  117. enumerable: false,
  118. writable: true,
  119. configurable: false
  120. });
  121. Object.defineProperty(MongooseMap.prototype, '$__parent', {
  122. enumerable: false,
  123. writable: true,
  124. configurable: false
  125. });
  126. Object.defineProperty(MongooseMap.prototype, '$__path', {
  127. enumerable: false,
  128. writable: true,
  129. configurable: false
  130. });
  131. Object.defineProperty(MongooseMap.prototype, '$__schemaType', {
  132. enumerable: false,
  133. writable: true,
  134. configurable: false
  135. });
  136. Object.defineProperty(MongooseMap.prototype, '$isMongooseMap', {
  137. enumerable: false,
  138. writable: false,
  139. configurable: false,
  140. value: true
  141. });
  142. Object.defineProperty(MongooseMap.prototype, '$__deferredCalls', {
  143. enumerable: false,
  144. writable: false,
  145. configurable: false,
  146. value: true
  147. });
  148. /*!
  149. * Since maps are stored as objects under the hood, keys must be strings
  150. * and can't contain any invalid characters
  151. */
  152. function checkValidKey(key) {
  153. const keyType = typeof key;
  154. if (keyType !== 'string') {
  155. throw new TypeError(`Mongoose maps only support string keys, got ${keyType}`);
  156. }
  157. if (key.startsWith('$')) {
  158. throw new Error(`Mongoose maps do not support keys that start with "$", got "${key}"`);
  159. }
  160. if (key.includes('.')) {
  161. throw new Error(`Mongoose maps do not support keys that contain ".", got "${key}"`);
  162. }
  163. if (utils.specialProperties.has(key)) {
  164. throw new Error(`Mongoose maps do not support reserved key name "${key}"`);
  165. }
  166. }
  167. module.exports = MongooseMap;