boolean.js 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332
  1. 'use strict';
  2. /*!
  3. * Module dependencies.
  4. */
  5. const CastError = require('../error/cast');
  6. const SchemaType = require('../schemaType');
  7. const castBoolean = require('../cast/boolean');
  8. const createJSONSchemaTypeDefinition = require('../helpers/createJSONSchemaTypeDefinition');
  9. /**
  10. * Boolean SchemaType constructor.
  11. *
  12. * @param {String} path
  13. * @param {Object} options
  14. * @param {Object} schemaOptions
  15. * @param {Schema} parentSchema
  16. * @inherits SchemaType
  17. * @api public
  18. */
  19. function SchemaBoolean(path, options, _schemaOptions, parentSchema) {
  20. SchemaType.call(this, path, options, 'Boolean', parentSchema);
  21. }
  22. /**
  23. * This schema type's name, to defend against minifiers that mangle
  24. * function names.
  25. *
  26. * @api public
  27. */
  28. SchemaBoolean.schemaName = 'Boolean';
  29. SchemaBoolean.defaultOptions = {};
  30. /*!
  31. * Inherits from SchemaType.
  32. */
  33. SchemaBoolean.prototype = Object.create(SchemaType.prototype);
  34. SchemaBoolean.prototype.constructor = SchemaBoolean;
  35. /*!
  36. * ignore
  37. */
  38. SchemaBoolean._cast = castBoolean;
  39. /**
  40. * Sets a default option for all Boolean instances.
  41. *
  42. * #### Example:
  43. *
  44. * // Make all booleans have `default` of false.
  45. * mongoose.Schema.Boolean.set('default', false);
  46. *
  47. * const Order = mongoose.model('Order', new Schema({ isPaid: Boolean }));
  48. * new Order({ }).isPaid; // false
  49. *
  50. * @param {String} option The option you'd like to set the value for
  51. * @param {Any} value value for option
  52. * @return {undefined}
  53. * @function set
  54. * @static
  55. * @api public
  56. */
  57. SchemaBoolean.set = SchemaType.set;
  58. SchemaBoolean.setters = [];
  59. /**
  60. * Attaches a getter for all Boolean instances
  61. *
  62. * #### Example:
  63. *
  64. * mongoose.Schema.Boolean.get(v => v === true ? 'yes' : 'no');
  65. *
  66. * const Order = mongoose.model('Order', new Schema({ isPaid: Boolean }));
  67. * new Order({ isPaid: false }).isPaid; // 'no'
  68. *
  69. * @param {Function} getter
  70. * @return {this}
  71. * @function get
  72. * @static
  73. * @api public
  74. */
  75. SchemaBoolean.get = SchemaType.get;
  76. /**
  77. * Get/set the function used to cast arbitrary values to booleans.
  78. *
  79. * #### Example:
  80. *
  81. * // Make Mongoose cast empty string '' to false.
  82. * const original = mongoose.Schema.Boolean.cast();
  83. * mongoose.Schema.Boolean.cast(v => {
  84. * if (v === '') {
  85. * return false;
  86. * }
  87. * return original(v);
  88. * });
  89. *
  90. * // Or disable casting entirely
  91. * mongoose.Schema.Boolean.cast(false);
  92. *
  93. * @param {Function} caster
  94. * @return {Function}
  95. * @function cast
  96. * @static
  97. * @api public
  98. */
  99. SchemaBoolean.cast = function cast(caster) {
  100. if (arguments.length === 0) {
  101. return this._cast;
  102. }
  103. if (caster === false) {
  104. caster = this._defaultCaster;
  105. }
  106. this._cast = caster;
  107. return this._cast;
  108. };
  109. /*!
  110. * ignore
  111. */
  112. SchemaBoolean._defaultCaster = v => {
  113. if (v != null && typeof v !== 'boolean') {
  114. throw new Error();
  115. }
  116. return v;
  117. };
  118. /*!
  119. * ignore
  120. */
  121. SchemaBoolean._checkRequired = v => v === true || v === false;
  122. /**
  123. * Override the function the required validator uses to check whether a boolean
  124. * passes the `required` check.
  125. *
  126. * @param {Function} fn
  127. * @return {Function}
  128. * @function checkRequired
  129. * @static
  130. * @api public
  131. */
  132. SchemaBoolean.checkRequired = SchemaType.checkRequired;
  133. /**
  134. * Check if the given value satisfies a required validator. For a boolean
  135. * to satisfy a required validator, it must be strictly equal to true or to
  136. * false.
  137. *
  138. * @param {Any} value
  139. * @return {Boolean}
  140. * @api public
  141. */
  142. SchemaBoolean.prototype.checkRequired = function(value) {
  143. return this.constructor._checkRequired(value);
  144. };
  145. /**
  146. * Configure which values get casted to `true`.
  147. *
  148. * #### Example:
  149. *
  150. * const M = mongoose.model('Test', new Schema({ b: Boolean }));
  151. * new M({ b: 'affirmative' }).b; // undefined
  152. * mongoose.Schema.Boolean.convertToTrue.add('affirmative');
  153. * new M({ b: 'affirmative' }).b; // true
  154. *
  155. * @property convertToTrue
  156. * @static
  157. * @memberOf SchemaBoolean
  158. * @type {Set}
  159. * @api public
  160. */
  161. Object.defineProperty(SchemaBoolean, 'convertToTrue', {
  162. get: () => castBoolean.convertToTrue,
  163. set: v => { castBoolean.convertToTrue = v; }
  164. });
  165. /**
  166. * Configure which values get casted to `false`.
  167. *
  168. * #### Example:
  169. *
  170. * const M = mongoose.model('Test', new Schema({ b: Boolean }));
  171. * new M({ b: 'nay' }).b; // undefined
  172. * mongoose.Schema.Types.Boolean.convertToFalse.add('nay');
  173. * new M({ b: 'nay' }).b; // false
  174. *
  175. * @property convertToFalse
  176. * @static
  177. * @memberOf SchemaBoolean
  178. * @type {Set}
  179. * @api public
  180. */
  181. Object.defineProperty(SchemaBoolean, 'convertToFalse', {
  182. get: () => castBoolean.convertToFalse,
  183. set: v => { castBoolean.convertToFalse = v; }
  184. });
  185. /**
  186. * Casts to boolean
  187. *
  188. * @param {Object} value
  189. * @param {Object} model this value is optional
  190. * @api private
  191. */
  192. SchemaBoolean.prototype.cast = function(value) {
  193. let castBoolean;
  194. if (typeof this._castFunction === 'function') {
  195. castBoolean = this._castFunction;
  196. } else if (typeof this.constructor.cast === 'function') {
  197. castBoolean = this.constructor.cast();
  198. } else {
  199. castBoolean = SchemaBoolean.cast();
  200. }
  201. try {
  202. return castBoolean(value);
  203. } catch (error) {
  204. throw new CastError('Boolean', value, this.path, error, this);
  205. }
  206. };
  207. const $conditionalHandlers = { ...SchemaType.prototype.$conditionalHandlers };
  208. /**
  209. * Contains the handlers for different query operators for this schema type.
  210. * For example, `$conditionalHandlers.$in` is the function Mongoose calls to cast `$in` filter operators.
  211. *
  212. * @property $conditionalHandlers
  213. * @memberOf SchemaBoolean
  214. * @instance
  215. * @api public
  216. */
  217. Object.defineProperty(SchemaBoolean.prototype, '$conditionalHandlers', {
  218. enumerable: false,
  219. value: $conditionalHandlers
  220. });
  221. /**
  222. * Casts contents for queries.
  223. *
  224. * @param {String} $conditional
  225. * @param {any} val
  226. * @api private
  227. */
  228. SchemaBoolean.prototype.castForQuery = function($conditional, val, context) {
  229. let handler;
  230. if ($conditional != null) {
  231. handler = this.$conditionalHandlers[$conditional];
  232. if (handler) {
  233. return handler.call(this, val);
  234. }
  235. return this.applySetters(val, context);
  236. }
  237. try {
  238. return this.applySetters(val, context);
  239. } catch (err) {
  240. if (err instanceof CastError && err.path === this.path && this.$fullPath != null) {
  241. err.path = this.$fullPath;
  242. }
  243. throw err;
  244. }
  245. };
  246. /**
  247. *
  248. * @api private
  249. */
  250. SchemaBoolean.prototype._castNullish = function _castNullish(v) {
  251. if (typeof v === 'undefined') {
  252. return v;
  253. }
  254. const castBoolean = typeof this.constructor.cast === 'function' ?
  255. this.constructor.cast() :
  256. SchemaBoolean.cast();
  257. if (castBoolean == null) {
  258. return v;
  259. }
  260. if (castBoolean.convertToFalse instanceof Set && castBoolean.convertToFalse.has(v)) {
  261. return false;
  262. }
  263. if (castBoolean.convertToTrue instanceof Set && castBoolean.convertToTrue.has(v)) {
  264. return true;
  265. }
  266. return v;
  267. };
  268. /**
  269. * Returns this schema type's representation in a JSON schema.
  270. *
  271. * @param [options]
  272. * @param [options.useBsonType=false] If true, return a representation with `bsonType` for use with MongoDB's `$jsonSchema`.
  273. * @returns {Object} JSON schema properties
  274. */
  275. SchemaBoolean.prototype.toJSONSchema = function toJSONSchema(options) {
  276. const isRequired = this.options.required && typeof this.options.required !== 'function';
  277. return createJSONSchemaTypeDefinition('boolean', 'bool', options?.useBsonType, isRequired);
  278. };
  279. SchemaBoolean.prototype.autoEncryptionType = function autoEncryptionType() {
  280. return 'bool';
  281. };
  282. /*!
  283. * Module exports.
  284. */
  285. module.exports = SchemaBoolean;