MetadataStorage.js 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. var __values = (this && this.__values) || function(o) {
  2. var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
  3. if (m) return m.call(o);
  4. if (o && typeof o.length === "number") return {
  5. next: function () {
  6. if (o && i >= o.length) o = void 0;
  7. return { value: o && o[i++], done: !o };
  8. }
  9. };
  10. throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
  11. };
  12. var __read = (this && this.__read) || function (o, n) {
  13. var m = typeof Symbol === "function" && o[Symbol.iterator];
  14. if (!m) return o;
  15. var i = m.call(o), r, ar = [], e;
  16. try {
  17. while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
  18. }
  19. catch (error) { e = { error: error }; }
  20. finally {
  21. try {
  22. if (r && !r.done && (m = i["return"])) m.call(i);
  23. }
  24. finally { if (e) throw e.error; }
  25. }
  26. return ar;
  27. };
  28. var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
  29. if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
  30. if (ar || !(i in from)) {
  31. if (!ar) ar = Array.prototype.slice.call(from, 0, i);
  32. ar[i] = from[i];
  33. }
  34. }
  35. return to.concat(ar || Array.prototype.slice.call(from));
  36. };
  37. import { ValidationSchemaToMetadataTransformer } from '../validation-schema/ValidationSchemaToMetadataTransformer';
  38. import { getGlobal } from '../utils';
  39. /**
  40. * Storage all metadatas.
  41. */
  42. var MetadataStorage = /** @class */ (function () {
  43. function MetadataStorage() {
  44. // -------------------------------------------------------------------------
  45. // Private properties
  46. // -------------------------------------------------------------------------
  47. this.validationMetadatas = new Map();
  48. this.constraintMetadatas = new Map();
  49. }
  50. Object.defineProperty(MetadataStorage.prototype, "hasValidationMetaData", {
  51. get: function () {
  52. return !!this.validationMetadatas.size;
  53. },
  54. enumerable: false,
  55. configurable: true
  56. });
  57. // -------------------------------------------------------------------------
  58. // Public Methods
  59. // -------------------------------------------------------------------------
  60. /**
  61. * Adds a new validation metadata.
  62. */
  63. MetadataStorage.prototype.addValidationSchema = function (schema) {
  64. var _this = this;
  65. var validationMetadatas = new ValidationSchemaToMetadataTransformer().transform(schema);
  66. validationMetadatas.forEach(function (validationMetadata) { return _this.addValidationMetadata(validationMetadata); });
  67. };
  68. /**
  69. * Adds a new validation metadata.
  70. */
  71. MetadataStorage.prototype.addValidationMetadata = function (metadata) {
  72. var existingMetadata = this.validationMetadatas.get(metadata.target);
  73. if (existingMetadata) {
  74. existingMetadata.push(metadata);
  75. }
  76. else {
  77. this.validationMetadatas.set(metadata.target, [metadata]);
  78. }
  79. };
  80. /**
  81. * Adds a new constraint metadata.
  82. */
  83. MetadataStorage.prototype.addConstraintMetadata = function (metadata) {
  84. var existingMetadata = this.constraintMetadatas.get(metadata.target);
  85. if (existingMetadata) {
  86. existingMetadata.push(metadata);
  87. }
  88. else {
  89. this.constraintMetadatas.set(metadata.target, [metadata]);
  90. }
  91. };
  92. /**
  93. * Groups metadata by their property names.
  94. */
  95. MetadataStorage.prototype.groupByPropertyName = function (metadata) {
  96. var grouped = {};
  97. metadata.forEach(function (metadata) {
  98. if (!grouped[metadata.propertyName])
  99. grouped[metadata.propertyName] = [];
  100. grouped[metadata.propertyName].push(metadata);
  101. });
  102. return grouped;
  103. };
  104. /**
  105. * Gets all validation metadatas for the given object with the given groups.
  106. */
  107. MetadataStorage.prototype.getTargetValidationMetadatas = function (targetConstructor, targetSchema, always, strictGroups, groups) {
  108. var e_1, _a;
  109. var includeMetadataBecauseOfAlwaysOption = function (metadata) {
  110. // `metadata.always` overrides global default.
  111. if (typeof metadata.always !== 'undefined')
  112. return metadata.always;
  113. // `metadata.groups` overrides global default.
  114. if (metadata.groups && metadata.groups.length)
  115. return false;
  116. // Use global default.
  117. return always;
  118. };
  119. var excludeMetadataBecauseOfStrictGroupsOption = function (metadata) {
  120. if (strictGroups) {
  121. // Validation is not using groups.
  122. if (!groups || !groups.length) {
  123. // `metadata.groups` has at least one group.
  124. if (metadata.groups && metadata.groups.length)
  125. return true;
  126. }
  127. }
  128. return false;
  129. };
  130. // get directly related to a target metadatas
  131. var filteredForOriginalMetadatasSearch = this.validationMetadatas.get(targetConstructor) || [];
  132. var originalMetadatas = filteredForOriginalMetadatasSearch.filter(function (metadata) {
  133. if (metadata.target !== targetConstructor && metadata.target !== targetSchema)
  134. return false;
  135. if (includeMetadataBecauseOfAlwaysOption(metadata))
  136. return true;
  137. if (excludeMetadataBecauseOfStrictGroupsOption(metadata))
  138. return false;
  139. if (groups && groups.length > 0)
  140. return metadata.groups && !!metadata.groups.find(function (group) { return groups.indexOf(group) !== -1; });
  141. return true;
  142. });
  143. // get metadatas for inherited classes
  144. var filteredForInheritedMetadatasSearch = [];
  145. try {
  146. for (var _b = __values(this.validationMetadatas.entries()), _c = _b.next(); !_c.done; _c = _b.next()) {
  147. var _d = __read(_c.value, 2), key = _d[0], value = _d[1];
  148. if (targetConstructor.prototype instanceof key) {
  149. filteredForInheritedMetadatasSearch.push.apply(filteredForInheritedMetadatasSearch, __spreadArray([], __read(value), false));
  150. }
  151. }
  152. }
  153. catch (e_1_1) { e_1 = { error: e_1_1 }; }
  154. finally {
  155. try {
  156. if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
  157. }
  158. finally { if (e_1) throw e_1.error; }
  159. }
  160. var inheritedMetadatas = filteredForInheritedMetadatasSearch.filter(function (metadata) {
  161. // if target is a string it's means we validate against a schema, and there is no inheritance support for schemas
  162. if (typeof metadata.target === 'string')
  163. return false;
  164. if (metadata.target === targetConstructor)
  165. return false;
  166. if (metadata.target instanceof Function && !(targetConstructor.prototype instanceof metadata.target))
  167. return false;
  168. if (includeMetadataBecauseOfAlwaysOption(metadata))
  169. return true;
  170. if (excludeMetadataBecauseOfStrictGroupsOption(metadata))
  171. return false;
  172. if (groups && groups.length > 0)
  173. return metadata.groups && !!metadata.groups.find(function (group) { return groups.indexOf(group) !== -1; });
  174. return true;
  175. });
  176. // filter out duplicate metadatas, prefer original metadatas instead of inherited metadatas
  177. var uniqueInheritedMetadatas = inheritedMetadatas.filter(function (inheritedMetadata) {
  178. return !originalMetadatas.find(function (originalMetadata) {
  179. return (originalMetadata.propertyName === inheritedMetadata.propertyName &&
  180. originalMetadata.type === inheritedMetadata.type);
  181. });
  182. });
  183. return originalMetadatas.concat(uniqueInheritedMetadatas);
  184. };
  185. /**
  186. * Gets all validator constraints for the given object.
  187. */
  188. MetadataStorage.prototype.getTargetValidatorConstraints = function (target) {
  189. return this.constraintMetadatas.get(target) || [];
  190. };
  191. return MetadataStorage;
  192. }());
  193. export { MetadataStorage };
  194. /**
  195. * Gets metadata storage.
  196. * Metadata storage follows the best practices and stores metadata in a global variable.
  197. */
  198. export function getMetadataStorage() {
  199. var global = getGlobal();
  200. if (!global.classValidatorMetadataStorage) {
  201. global.classValidatorMetadataStorage = new MetadataStorage();
  202. }
  203. return global.classValidatorMetadataStorage;
  204. }
  205. //# sourceMappingURL=MetadataStorage.js.map