bson 5.4.0 → 5.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/bson.d.ts CHANGED
@@ -392,6 +392,26 @@ export declare class Decimal128 extends BSONValue {
392
392
  * @param representation - a numeric string representation.
393
393
  */
394
394
  static fromString(representation: string): Decimal128;
395
+ /**
396
+ * Create a Decimal128 instance from a string representation, allowing for rounding to 34
397
+ * significant digits
398
+ *
399
+ * @example Example of a number that will be rounded
400
+ * ```ts
401
+ * > let d = Decimal128.fromString('37.499999999999999196428571428571375')
402
+ * Uncaught:
403
+ * BSONError: "37.499999999999999196428571428571375" is not a valid Decimal128 string - inexact rounding
404
+ * at invalidErr (/home/wajames/js-bson/lib/bson.cjs:1402:11)
405
+ * at Decimal128.fromStringInternal (/home/wajames/js-bson/lib/bson.cjs:1633:25)
406
+ * at Decimal128.fromString (/home/wajames/js-bson/lib/bson.cjs:1424:27)
407
+ *
408
+ * > d = Decimal128.fromStringWithRounding('37.499999999999999196428571428571375')
409
+ * new Decimal128("37.49999999999999919642857142857138")
410
+ * ```
411
+ * @param representation - a numeric string representation.
412
+ */
413
+ static fromStringWithRounding(representation: string): Decimal128;
414
+ private static _fromString;
395
415
  /** Create a string representation of the raw Decimal128 value */
396
416
  toString(): string;
397
417
  toJSON(): Decimal128Extended;
@@ -96,7 +96,7 @@ class BSONVersionError extends BSONError {
96
96
  return 'BSONVersionError';
97
97
  }
98
98
  constructor() {
99
- super(`Unsupported BSON version, bson types must be from bson ${BSON_MAJOR_VERSION}.0 or later`);
99
+ super(`Unsupported BSON version, bson types must be from bson ${BSON_MAJOR_VERSION}.x.x`);
100
100
  }
101
101
  }
102
102
  class BSONRuntimeError extends BSONError {
@@ -1437,7 +1437,14 @@ class Decimal128 extends BSONValue {
1437
1437
  }
1438
1438
  }
1439
1439
  static fromString(representation) {
1440
+ return Decimal128._fromString(representation, { allowRounding: false });
1441
+ }
1442
+ static fromStringWithRounding(representation) {
1443
+ return Decimal128._fromString(representation, { allowRounding: true });
1444
+ }
1445
+ static _fromString(representation, options) {
1440
1446
  let isNegative = false;
1447
+ let sawSign = false;
1441
1448
  let sawRadix = false;
1442
1449
  let foundNonZero = false;
1443
1450
  let significantDigits = 0;
@@ -1448,10 +1455,8 @@ class Decimal128 extends BSONValue {
1448
1455
  const digits = [0];
1449
1456
  let nDigitsStored = 0;
1450
1457
  let digitsInsert = 0;
1451
- let firstDigit = 0;
1452
1458
  let lastDigit = 0;
1453
1459
  let exponent = 0;
1454
- let i = 0;
1455
1460
  let significandHigh = new Long(0, 0);
1456
1461
  let significandLow = new Long(0, 0);
1457
1462
  let biasedExponent = 0;
@@ -1479,6 +1484,7 @@ class Decimal128 extends BSONValue {
1479
1484
  }
1480
1485
  }
1481
1486
  if (representation[index] === '+' || representation[index] === '-') {
1487
+ sawSign = true;
1482
1488
  isNegative = representation[index++] === '-';
1483
1489
  }
1484
1490
  if (!isDigit(representation[index]) && representation[index] !== '.') {
@@ -1497,7 +1503,7 @@ class Decimal128 extends BSONValue {
1497
1503
  index = index + 1;
1498
1504
  continue;
1499
1505
  }
1500
- if (nDigitsStored < 34) {
1506
+ if (nDigitsStored < MAX_DIGITS) {
1501
1507
  if (representation[index] !== '0' || foundNonZero) {
1502
1508
  if (!foundNonZero) {
1503
1509
  firstNonZero = nDigitsRead;
@@ -1525,10 +1531,7 @@ class Decimal128 extends BSONValue {
1525
1531
  }
1526
1532
  if (representation[index])
1527
1533
  return new Decimal128(NAN_BUFFER);
1528
- firstDigit = 0;
1529
1534
  if (!nDigitsStored) {
1530
- firstDigit = 0;
1531
- lastDigit = 0;
1532
1535
  digits[0] = 0;
1533
1536
  nDigits = 1;
1534
1537
  nDigitsStored = 1;
@@ -1538,12 +1541,12 @@ class Decimal128 extends BSONValue {
1538
1541
  lastDigit = nDigitsStored - 1;
1539
1542
  significantDigits = nDigits;
1540
1543
  if (significantDigits !== 1) {
1541
- while (digits[firstNonZero + significantDigits - 1] === 0) {
1544
+ while (representation[firstNonZero + significantDigits - 1 + Number(sawSign) + Number(sawRadix)] === '0') {
1542
1545
  significantDigits = significantDigits - 1;
1543
1546
  }
1544
1547
  }
1545
1548
  }
1546
- if (exponent <= radixPosition && radixPosition - exponent > 1 << 14) {
1549
+ if (exponent <= radixPosition && radixPosition > exponent + (1 << 14)) {
1547
1550
  exponent = EXPONENT_MIN;
1548
1551
  }
1549
1552
  else {
@@ -1551,9 +1554,8 @@ class Decimal128 extends BSONValue {
1551
1554
  }
1552
1555
  while (exponent > EXPONENT_MAX) {
1553
1556
  lastDigit = lastDigit + 1;
1554
- if (lastDigit - firstDigit > MAX_DIGITS) {
1555
- const digitsString = digits.join('');
1556
- if (digitsString.match(/^0+$/)) {
1557
+ if (lastDigit >= MAX_DIGITS) {
1558
+ if (significantDigits === 0) {
1557
1559
  exponent = EXPONENT_MAX;
1558
1560
  break;
1559
1561
  }
@@ -1561,69 +1563,116 @@ class Decimal128 extends BSONValue {
1561
1563
  }
1562
1564
  exponent = exponent - 1;
1563
1565
  }
1564
- while (exponent < EXPONENT_MIN || nDigitsStored < nDigits) {
1565
- if (lastDigit === 0 && significantDigits < nDigitsStored) {
1566
- exponent = EXPONENT_MIN;
1567
- significantDigits = 0;
1568
- break;
1569
- }
1570
- if (nDigitsStored < nDigits) {
1571
- nDigits = nDigits - 1;
1572
- }
1573
- else {
1574
- lastDigit = lastDigit - 1;
1575
- }
1576
- if (exponent < EXPONENT_MAX) {
1577
- exponent = exponent + 1;
1578
- }
1579
- else {
1580
- const digitsString = digits.join('');
1581
- if (digitsString.match(/^0+$/)) {
1582
- exponent = EXPONENT_MAX;
1566
+ if (options.allowRounding) {
1567
+ while (exponent < EXPONENT_MIN || nDigitsStored < nDigits) {
1568
+ if (lastDigit === 0 && significantDigits < nDigitsStored) {
1569
+ exponent = EXPONENT_MIN;
1570
+ significantDigits = 0;
1583
1571
  break;
1584
1572
  }
1585
- invalidErr(representation, 'overflow');
1586
- }
1587
- }
1588
- if (lastDigit - firstDigit + 1 < significantDigits) {
1589
- let endOfString = nDigitsRead;
1590
- if (sawRadix) {
1591
- firstNonZero = firstNonZero + 1;
1592
- endOfString = endOfString + 1;
1593
- }
1594
- if (isNegative) {
1595
- firstNonZero = firstNonZero + 1;
1596
- endOfString = endOfString + 1;
1597
- }
1598
- const roundDigit = parseInt(representation[firstNonZero + lastDigit + 1], 10);
1599
- let roundBit = 0;
1600
- if (roundDigit >= 5) {
1601
- roundBit = 1;
1602
- if (roundDigit === 5) {
1603
- roundBit = digits[lastDigit] % 2 === 1 ? 1 : 0;
1604
- for (i = firstNonZero + lastDigit + 2; i < endOfString; i++) {
1605
- if (parseInt(representation[i], 10)) {
1606
- roundBit = 1;
1607
- break;
1608
- }
1573
+ if (nDigitsStored < nDigits) {
1574
+ nDigits = nDigits - 1;
1575
+ }
1576
+ else {
1577
+ lastDigit = lastDigit - 1;
1578
+ }
1579
+ if (exponent < EXPONENT_MAX) {
1580
+ exponent = exponent + 1;
1581
+ }
1582
+ else {
1583
+ const digitsString = digits.join('');
1584
+ if (digitsString.match(/^0+$/)) {
1585
+ exponent = EXPONENT_MAX;
1586
+ break;
1609
1587
  }
1588
+ invalidErr(representation, 'overflow');
1610
1589
  }
1611
1590
  }
1612
- if (roundBit) {
1613
- let dIdx = lastDigit;
1614
- for (; dIdx >= 0; dIdx--) {
1615
- if (++digits[dIdx] > 9) {
1616
- digits[dIdx] = 0;
1617
- if (dIdx === 0) {
1618
- if (exponent < EXPONENT_MAX) {
1619
- exponent = exponent + 1;
1620
- digits[dIdx] = 1;
1591
+ if (lastDigit + 1 < significantDigits) {
1592
+ let endOfString = nDigitsRead;
1593
+ if (sawRadix) {
1594
+ firstNonZero = firstNonZero + 1;
1595
+ endOfString = endOfString + 1;
1596
+ }
1597
+ if (sawSign) {
1598
+ firstNonZero = firstNonZero + 1;
1599
+ endOfString = endOfString + 1;
1600
+ }
1601
+ const roundDigit = parseInt(representation[firstNonZero + lastDigit + 1], 10);
1602
+ let roundBit = 0;
1603
+ if (roundDigit >= 5) {
1604
+ roundBit = 1;
1605
+ if (roundDigit === 5) {
1606
+ roundBit = digits[lastDigit] % 2 === 1 ? 1 : 0;
1607
+ for (let i = firstNonZero + lastDigit + 2; i < endOfString; i++) {
1608
+ if (parseInt(representation[i], 10)) {
1609
+ roundBit = 1;
1610
+ break;
1621
1611
  }
1622
- else {
1623
- return new Decimal128(isNegative ? INF_NEGATIVE_BUFFER : INF_POSITIVE_BUFFER);
1612
+ }
1613
+ }
1614
+ }
1615
+ if (roundBit) {
1616
+ let dIdx = lastDigit;
1617
+ for (; dIdx >= 0; dIdx--) {
1618
+ if (++digits[dIdx] > 9) {
1619
+ digits[dIdx] = 0;
1620
+ if (dIdx === 0) {
1621
+ if (exponent < EXPONENT_MAX) {
1622
+ exponent = exponent + 1;
1623
+ digits[dIdx] = 1;
1624
+ }
1625
+ else {
1626
+ return new Decimal128(isNegative ? INF_NEGATIVE_BUFFER : INF_POSITIVE_BUFFER);
1627
+ }
1624
1628
  }
1625
1629
  }
1630
+ else {
1631
+ break;
1632
+ }
1633
+ }
1634
+ }
1635
+ }
1636
+ }
1637
+ else {
1638
+ while (exponent < EXPONENT_MIN || nDigitsStored < nDigits) {
1639
+ if (lastDigit === 0) {
1640
+ if (significantDigits === 0) {
1641
+ exponent = EXPONENT_MIN;
1642
+ break;
1626
1643
  }
1644
+ invalidErr(representation, 'exponent underflow');
1645
+ }
1646
+ if (nDigitsStored < nDigits) {
1647
+ if (representation[nDigits - 1 + Number(sawSign) + Number(sawRadix)] !== '0' &&
1648
+ significantDigits !== 0) {
1649
+ invalidErr(representation, 'inexact rounding');
1650
+ }
1651
+ nDigits = nDigits - 1;
1652
+ }
1653
+ else {
1654
+ if (digits[lastDigit] !== 0) {
1655
+ invalidErr(representation, 'inexact rounding');
1656
+ }
1657
+ lastDigit = lastDigit - 1;
1658
+ }
1659
+ if (exponent < EXPONENT_MAX) {
1660
+ exponent = exponent + 1;
1661
+ }
1662
+ else {
1663
+ invalidErr(representation, 'overflow');
1664
+ }
1665
+ }
1666
+ if (lastDigit + 1 < significantDigits) {
1667
+ if (sawRadix) {
1668
+ firstNonZero = firstNonZero + 1;
1669
+ }
1670
+ if (sawSign) {
1671
+ firstNonZero = firstNonZero + 1;
1672
+ }
1673
+ const roundDigit = parseInt(representation[firstNonZero + lastDigit + 1], 10);
1674
+ if (roundDigit !== 0) {
1675
+ invalidErr(representation, 'inexact rounding');
1627
1676
  }
1628
1677
  }
1629
1678
  }
@@ -1633,8 +1682,8 @@ class Decimal128 extends BSONValue {
1633
1682
  significandHigh = Long.fromNumber(0);
1634
1683
  significandLow = Long.fromNumber(0);
1635
1684
  }
1636
- else if (lastDigit - firstDigit < 17) {
1637
- let dIdx = firstDigit;
1685
+ else if (lastDigit < 17) {
1686
+ let dIdx = 0;
1638
1687
  significandLow = Long.fromNumber(digits[dIdx++]);
1639
1688
  significandHigh = new Long(0, 0);
1640
1689
  for (; dIdx <= lastDigit; dIdx++) {
@@ -1643,7 +1692,7 @@ class Decimal128 extends BSONValue {
1643
1692
  }
1644
1693
  }
1645
1694
  else {
1646
- let dIdx = firstDigit;
1695
+ let dIdx = 0;
1647
1696
  significandHigh = Long.fromNumber(digits[dIdx++]);
1648
1697
  for (; dIdx <= lastDigit - 17; dIdx++) {
1649
1698
  significandHigh = significandHigh.multiply(Long.fromNumber(10));