From c88c52ebed6c9dda3b514ca6b6d65168de51042b Mon Sep 17 00:00:00 2001 From: Aditi Khare Date: Tue, 12 Nov 2024 18:39:58 -0500 Subject: [PATCH] casted --- docs/schematypes.md | 1 - lib/cast/double.js | 52 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 lib/cast/double.js diff --git a/docs/schematypes.md b/docs/schematypes.md index e9e1281a16e..c6cdd386f3c 100644 --- a/docs/schematypes.md +++ b/docs/schematypes.md @@ -682,7 +682,6 @@ The values `null` and `undefined` are not cast. The following inputs will result will all result in a [CastError](validation.html#cast-errors) once validated, meaning that it will not throw on initialization, only when validated: * strings that do not represent a numeric string, a NaN or a null-ish value -* numbers in non-decimal or exponential format * objects that don't have a `valueOf()` function * an input that represents a value outside the bounds of a IEEE 754-2008 floating point diff --git a/lib/cast/double.js b/lib/cast/double.js new file mode 100644 index 00000000000..9d4315c3503 --- /dev/null +++ b/lib/cast/double.js @@ -0,0 +1,52 @@ +'use strict'; + +const assert = require('assert'); +const BSON = require('bson'); + +/** + * Given a value, cast it to a IEEE 754-2008 floating point, or throw an `Error` if the value + * cannot be casted. `null`, `undefined`, and `NaN` are considered valid inputs. + * + * @param {Any} value + * @return {Number} + * @throws {Error} if `value` does not represent a IEEE 754-2008 floating point. If casting from a string, see BSON Double.fromString API documentation + * @api private + */ + +module.exports = function castDouble(val) { + if (val == null) { + return val; + } + if (val === '') { + return null; + } + + let coercedVal; + if (val instanceof BSON.Int32 || val instanceof BSON.Double) { + coercedVal = val.value; + } else if (val instanceof BSON.Long) { + coercedVal = val.toNumber(); + } else if (typeof val === 'string') { + try { + coercedVal = BSON.Double.fromString(val); + } catch { + assert.ok(false); + } + } else if (typeof val === 'object') { + const tempVal = val.valueOf() ?? val.toString(); + // ex: { a: 'im an object, valueOf: () => 'helloworld' } // throw an error + if (typeof tempVal === 'string') { + try { + coercedVal = BSON.Double.fromString(val); + } catch { + assert.ok(false); + } + } else { + coercedVal = Number(tempVal); + } + } { + coercedVal = Number(val); + } + + return coercedVal; +};