New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

money-calc

Package Overview
Dependencies
Maintainers
2
Versions
3
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

money-calc - npm Package Compare versions

Comparing version

to
1.3.0

LICENSE.md

4

dist/index.d.ts

@@ -52,3 +52,3 @@ import BigDecimal from 'js-big-decimal';

div(...amounts: MoneyInput[]): Money;
mod(...amounts: MoneyInput[]): Money;
mod(amount: MoneyInput): Money;
percent(amount: MoneyInput): Money;

@@ -65,2 +65,2 @@ negate(): Money;

export { ComparisonResult, Currency, MoneyAmount, Money as default };
export { ComparisonResult, Currency, Money, MoneyAmount, Money as default };

@@ -0,1 +1,56 @@

function _arrayLikeToArray(arr, len) {
if (len == null || len > arr.length) len = arr.length;
for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
return arr2;
}
function _arrayWithoutHoles(arr) {
if (Array.isArray(arr)) return _arrayLikeToArray(arr);
}
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
function _defineProperties(target, props) {
for(var i = 0; i < props.length; i++){
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor) descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
}
}
function _createClass(Constructor, protoProps, staticProps) {
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
if (staticProps) _defineProperties(Constructor, staticProps);
return Constructor;
}
function _instanceof(left, right) {
if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) {
return right[Symbol.hasInstance](left);
} else {
return left instanceof right;
}
}
function _iterableToArray(iter) {
if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
}
function _nonIterableSpread() {
throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
function _toConsumableArray(arr) {
return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread();
}
var _typeof = function(obj) {
"@swc/helpers - typeof";
return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj;
};
function _unsupportedIterableToArray(o, minLen) {
if (!o) return;
if (typeof o === "string") return _arrayLikeToArray(o, minLen);
var n = Object.prototype.toString.call(o).slice(8, -1);
if (n === "Object" && o.constructor) n = o.constructor.name;
if (n === "Map" || n === "Set") return Array.from(n);
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
}
var __create = Object.create;

@@ -7,160 +62,289 @@ var __defProp = Object.defineProperty;

var __hasOwnProp = Object.prototype.hasOwnProperty;
var __markAsModule = (target) => __defProp(target, "__esModule", { value: true });
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
var __defNormalProp = function(obj, key, value) {
return key in obj ? __defProp(obj, key, {
enumerable: true,
configurable: true,
writable: true,
value: value
}) : obj[key] = value;
};
var __reExport = (target, module2, copyDefault, desc) => {
if (module2 && typeof module2 === "object" || typeof module2 === "function") {
for (let key of __getOwnPropNames(module2))
if (!__hasOwnProp.call(target, key) && (copyDefault || key !== "default"))
__defProp(target, key, { get: () => module2[key], enumerable: !(desc = __getOwnPropDesc(module2, key)) || desc.enumerable });
}
return target;
var __markAsModule = function(target) {
return __defProp(target, "__esModule", {
value: true
});
};
var __toESM = (module2, isNodeMode) => {
return __reExport(__markAsModule(__defProp(module2 != null ? __create(__getProtoOf(module2)) : {}, "default", !isNodeMode && module2 && module2.__esModule ? { get: () => module2.default, enumerable: true } : { value: module2, enumerable: true })), module2);
var __export = function(target, all) {
for(var name in all)__defProp(target, name, {
get: all[name],
enumerable: true
});
};
var __toCommonJS = /* @__PURE__ */ ((cache) => {
return (module2, temp) => {
return cache && cache.get(module2) || (temp = __reExport(__markAsModule({}), module2, 1), cache && cache.set(module2, temp), temp);
};
})(typeof WeakMap !== "undefined" ? /* @__PURE__ */ new WeakMap() : 0);
var __reExport = function(target, module2, copyDefault, desc) {
if (module2 && typeof module2 === "object" || typeof module2 === "function") {
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
try {
var _loop = function(_iterator, _step) {
var key = _step.value;
if (!__hasOwnProp.call(target, key) && (copyDefault || key !== "default")) __defProp(target, key, {
get: function() {
return module2[key];
},
enumerable: !(desc = __getOwnPropDesc(module2, key)) || desc.enumerable
});
};
for(var _iterator = __getOwnPropNames(module2)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true)_loop(_iterator, _step);
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally{
try {
if (!_iteratorNormalCompletion && _iterator.return != null) {
_iterator.return();
}
} finally{
if (_didIteratorError) {
throw _iteratorError;
}
}
}
}
return target;
};
var __toESM = function(module2, isNodeMode) {
return __reExport(__markAsModule(__defProp(module2 != null ? __create(__getProtoOf(module2)) : {}, "default", !isNodeMode && module2 && module2.__esModule ? {
get: function() {
return module2.default;
},
enumerable: true
} : {
value: module2,
enumerable: true
})), module2);
};
var __toCommonJS = /* @__PURE__ */ function(cache) {
return function(module2, temp) {
return cache && cache.get(module2) || (temp = __reExport(__markAsModule({}), module2, 1), cache && cache.set(module2, temp), temp);
};
}(typeof WeakMap !== "undefined" ? /* @__PURE__ */ new WeakMap() : 0);
var __publicField = function(obj, key, value) {
__defNormalProp(obj, (typeof key === "undefined" ? "undefined" : _typeof(key)) !== "symbol" ? key + "" : key, value);
return value;
};
// src/index.ts
var src_exports = {};
__export(src_exports, {
ComparisonResult: () => ComparisonResult,
Currency: () => Currency,
default: () => src_default
ComparisonResult: function() {
return ComparisonResult;
},
Currency: function() {
return Currency;
},
Money: function() {
return Money;
},
default: function() {
return Money;
}
});
// src/Money.ts
var import_js_big_decimal = __toESM(require("js-big-decimal"));
var RoundingModes = import_js_big_decimal.default.RoundingModes;
var Money = class {
currency;
value;
get amount() {
return this.value.round(2, RoundingModes.HALF_EVEN).getValue();
}
static getBigDecimalValue(amount) {
if (typeof amount === "string") {
return new import_js_big_decimal.default(amount);
var Money = /*#__PURE__*/ function() {
"use strict";
function _class(amount, currency) {
_classCallCheck(this, _class);
__publicField(this, "currency");
__publicField(this, "value");
this.value = Money.getBigDecimalValue(amount);
var ref;
this.currency = (ref = currency !== null && currency !== void 0 ? currency : amount.currency) !== null && ref !== void 0 ? ref : "USD";
}
if (typeof amount === "object") {
if (amount instanceof import_js_big_decimal.default) {
return new import_js_big_decimal.default(amount.getValue());
}
if ("amount" in amount) {
if (amount.value !== void 0) {
return new import_js_big_decimal.default(amount.value.getValue());
_createClass(_class, [
{
key: "amount",
get: function get() {
return this.value.round(2, RoundingModes.HALF_EVEN).getValue();
}
},
{
key: "add",
value: function add() {
for(var _len = arguments.length, amounts = new Array(_len), _key = 0; _key < _len; _key++){
amounts[_key] = arguments[_key];
}
return this.performOperation.apply(this, [
"add"
].concat(_toConsumableArray(amounts)));
}
},
{
key: "subtract",
value: function subtract() {
for(var _len = arguments.length, amounts = new Array(_len), _key = 0; _key < _len; _key++){
amounts[_key] = arguments[_key];
}
return this.performOperation.apply(this, [
"subtract"
].concat(_toConsumableArray(amounts)));
}
},
{
key: "mul",
value: function mul() {
for(var _len = arguments.length, amounts = new Array(_len), _key = 0; _key < _len; _key++){
amounts[_key] = arguments[_key];
}
return this.performOperation.apply(this, [
"multiply"
].concat(_toConsumableArray(amounts)));
}
},
{
key: "div",
value: function div() {
for(var _len = arguments.length, amounts = new Array(_len), _key = 0; _key < _len; _key++){
amounts[_key] = arguments[_key];
}
return this.performOperation.apply(this, [
"divide"
].concat(_toConsumableArray(amounts)));
}
},
{
key: "mod",
value: function mod(amount) {
var modulus = new Money(amount);
if (!this.amount.endsWith(".00") || !modulus.amount.endsWith(".00")) {
throw new TypeError("Modulus of non-integers not supported");
}
var value = this.value.round(0, RoundingModes.HALF_EVEN).modulus(modulus.value.round(0, RoundingModes.HALF_EVEN));
return new Money(value, this.currency);
}
},
{
key: "percent",
value: function percent(amount) {
var percent1 = Money.getBigDecimalValue(amount).divide(new import_js_big_decimal.default(100), 8);
return this.performOperation("multiply", percent1);
}
},
{
key: "negate",
value: function negate() {
return new Money(this.value.negate(), this.currency);
}
},
{
key: "cmp",
value: function cmp(amount) {
return this.value.compareTo(Money.getBigDecimalValue(amount));
}
},
{
key: "toJSON",
value: function toJSON() {
var ref = this, amount = ref.amount, currency = ref.currency;
return {
amount: amount,
currency: currency
};
}
},
{
key: "toString",
value: function toString() {
var number = Number(this.amount);
if (Number.isNaN(number)) {
throw new TypeError("Money amount is not a number");
}
return number.toLocaleString("en-US", {
style: "currency",
currency: this.currency,
minimumFractionDigits: 2,
maximumFractionDigits: 2
});
}
},
{
key: "performOperation",
value: function performOperation(operation) {
for(var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++){
args[_key - 1] = arguments[_key];
}
var method = import_js_big_decimal.default.prototype[operation];
var value = args.reduce(function(value2, arg) {
return method.call(value2, Money.getBigDecimalValue(arg));
}, this.value);
return new Money(value, this.currency);
}
}
return new import_js_big_decimal.default(amount.amount);
}
if ("_bsontype" in amount && amount._bsontype === "Decimal128") {
return new import_js_big_decimal.default(amount.toString());
}
}
throw new TypeError("Invalid MoneyInput type");
}
constructor(amount, currency) {
var _a;
this.value = Money.getBigDecimalValue(amount);
this.currency = (_a = currency != null ? currency : amount.currency) != null ? _a : "USD";
}
add(...amounts) {
return this.performOperation("add", ...amounts);
}
subtract(...amounts) {
return this.performOperation("subtract", ...amounts);
}
mul(...amounts) {
return this.performOperation("multiply", ...amounts);
}
div(...amounts) {
return this.performOperation("divide", ...amounts);
}
mod(...amounts) {
return this.performOperation("modulus", ...amounts);
}
percent(amount) {
let percent = Money.getBigDecimalValue(amount).divide(new import_js_big_decimal.default(100), 8);
return this.performOperation("multiply", percent);
}
negate() {
return new Money(this.value.negate(), this.currency);
}
cmp(amount) {
return this.value.compareTo(Money.getBigDecimalValue(amount));
}
toJSON() {
let { amount, currency } = this;
return { amount, currency };
}
toString() {
let number = Number(this.amount);
if (Number.isNaN(number)) {
throw new TypeError("Money amount is not a number");
}
return number.toLocaleString("en-US", {
style: "currency",
currency: this.currency,
minimumFractionDigits: 2,
maximumFractionDigits: 2
});
}
performOperation(operation, ...args) {
let method = import_js_big_decimal.default.prototype[operation];
let value = args.reduce((value2, arg) => method.call(value2, Money.getBigDecimalValue(arg)), this.value);
return new Money(value, this.currency);
}
};
], [
{
key: "getBigDecimalValue",
value: function getBigDecimalValue(amount) {
if (typeof amount === "string") {
return new import_js_big_decimal.default(amount);
} else if (typeof amount === "object" && amount !== null) {
if (_instanceof(amount, import_js_big_decimal.default)) {
return new import_js_big_decimal.default(amount.getValue());
}
if ("amount" in amount) {
if (amount.value !== void 0) {
return new import_js_big_decimal.default(amount.value.getValue());
}
return new import_js_big_decimal.default(amount.amount);
}
if ("_bsontype" in amount && amount._bsontype === "Decimal128") {
return new import_js_big_decimal.default(amount.toString());
}
}
throw new TypeError("Invalid MoneyInput type");
}
}
]);
return _class;
}();
// src/Currency.ts
var Currency = /* @__PURE__ */ ((Currency2) => {
Currency2["USD"] = "USD";
Currency2["EUR"] = "EUR";
Currency2["GBP"] = "GBP";
Currency2["INR"] = "INR";
Currency2["AUD"] = "AUD";
Currency2["CAD"] = "CAD";
Currency2["ZAR"] = "ZAR";
Currency2["NZD"] = "NZD";
Currency2["JPY"] = "JPY";
Currency2["SGD"] = "SGD";
Currency2["CNY"] = "CNY";
Currency2["CHF"] = "CHF";
Currency2["MYR"] = "MYR";
Currency2["HUF"] = "HUF";
Currency2["HKD"] = "HKD";
Currency2["AED"] = "AED";
Currency2["THB"] = "THB";
Currency2["KRW"] = "KRW";
Currency2["SEK"] = "SEK";
Currency2["PHP"] = "PHP";
Currency2["ILS"] = "ILS";
Currency2["TRY"] = "TRY";
Currency2["PLN"] = "PLN";
Currency2["MXN"] = "MXN";
Currency2["NOK"] = "NOK";
Currency2["DKK"] = "DKK";
return Currency2;
})(Currency || {});
var Currency = /* @__PURE__ */ function(Currency2) {
Currency2["USD"] = "USD";
Currency2["EUR"] = "EUR";
Currency2["GBP"] = "GBP";
Currency2["INR"] = "INR";
Currency2["AUD"] = "AUD";
Currency2["CAD"] = "CAD";
Currency2["ZAR"] = "ZAR";
Currency2["NZD"] = "NZD";
Currency2["JPY"] = "JPY";
Currency2["SGD"] = "SGD";
Currency2["CNY"] = "CNY";
Currency2["CHF"] = "CHF";
Currency2["MYR"] = "MYR";
Currency2["HUF"] = "HUF";
Currency2["HKD"] = "HKD";
Currency2["AED"] = "AED";
Currency2["THB"] = "THB";
Currency2["KRW"] = "KRW";
Currency2["SEK"] = "SEK";
Currency2["PHP"] = "PHP";
Currency2["ILS"] = "ILS";
Currency2["TRY"] = "TRY";
Currency2["PLN"] = "PLN";
Currency2["MXN"] = "MXN";
Currency2["NOK"] = "NOK";
Currency2["DKK"] = "DKK";
return Currency2;
}(Currency || {});
// src/ComparisonResult.ts
var ComparisonResult = /* @__PURE__ */ ((ComparisonResult2) => {
ComparisonResult2[ComparisonResult2["Ascending"] = -1] = "Ascending";
ComparisonResult2[ComparisonResult2["Same"] = 0] = "Same";
ComparisonResult2[ComparisonResult2["Descending"] = 1] = "Descending";
return ComparisonResult2;
})(ComparisonResult || {});
// src/index.ts
var src_default = Money;
var ComparisonResult = /* @__PURE__ */ function(ComparisonResult2) {
ComparisonResult2[ComparisonResult2["Ascending"] = -1] = "Ascending";
ComparisonResult2[ComparisonResult2["Same"] = 0] = "Same";
ComparisonResult2[ComparisonResult2["Descending"] = 1] = "Descending";
return ComparisonResult2;
}(ComparisonResult || {});
module.exports = __toCommonJS(src_exports);
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
ComparisonResult,
Currency
ComparisonResult: ComparisonResult,
Currency: Currency,
Money: Money
});
{
"name": "money-calc",
"version": "1.2.0",
"version": "1.3.0",
"description": "Helper class for calculating money amounts without rounding errors.",

@@ -21,5 +21,9 @@ "author": "Adam Demasi <adam@chariz.com>",

"scripts": {
"build": "tsup ./src/index.ts --format cjs,esm --dts --clean",
"build": "tsup ./src/index.ts --format cjs,esm --target es5 --dts --clean",
"lint": "eslint ./src",
"lint:fix": "pnpm -s lint -- --fix",
"prepublishOnly": "pnpm run build",
"push": "np --no-tests"
"push": "np",
"test": "pnpm -s lint && pnpm -s test:jest",
"test:jest": "node --experimental-vm-modules node_modules/jest/bin/jest.js"
},

@@ -55,4 +59,12 @@ "keywords": [

"devDependencies": {
"@swc/core": "^1.2.144",
"@types/jest": "^27.4.0",
"@types/node": "^17.0.14",
"@typescript-eslint/eslint-plugin": "^5.10.2",
"@typescript-eslint/parser": "^5.10.2",
"eslint": "^8.8.0",
"eslint-config-chariz": "^1.1.0",
"jest": "^27.4.7",
"np": "^7.6.0",
"ts-jest": "^27.1.3",
"tsup": "^5.11.11",

@@ -59,0 +71,0 @@ "typescript": "^4.4.3"

@@ -19,2 +19,97 @@ <h2 align="center">

## Example
```typescript
import Money, { MoneyAmount } from "money-calc";
interface Product {
name: string;
manufacturer: string;
weightKg: MoneyAmount;
unitsPerPack: MoneyAmount;
price: MoneyAmount;
}
interface Discount {
percent: MoneyAmount;
}
let product: Product = {
name: "Mr Sparkle Dishwashing Detergent Powder, 2kg, 66 Washes",
manufacturer: "Matsumura Fishworks & Tamaribuchi Heavy Manufacturing Concern",
weightKg: "2.00",
unitsPerPack: "66.00",
price: {
amount: "19.99",
currency: "AUD"
},
shippingFee: {
amount: "4.18",
currency: "AUD"
}
};
let discount: Discount = {
percent: "20.00"
};
let discountRemainder = new Money("100.00")
.subtract(discount.percent);
let originalPrice = new Money(product.price);
let finalPrice = new Money(originalPrice)
.percent(discountRemainder)
.add(product.shippingFee);
let pricePerKg = new Money(finalPrice)
.div(product.weightKg);
let pricePerUnit = new Money(finalPrice)
.div(product.unitsPerPack);
console.log(`Was ${originalPrice}, now ${finalPrice} w/shipping!`);
console.log(`Price per kilogram: ${pricePerKg}`);
console.log(`Price per unit: ${pricePerUnit}`);
let response = {
product,
discount,
originalPrice,
finalPrice,
pricePerKg,
pricePerUnit
};
// Stringify and then parse the object back in, to simulate sending the data
// over the wire to an API client.
let jsonified = JSON.parse(JSON.stringify(response));
console.log("JSON response:");
console.log(jsonified);
```
Running this script produces the following output:
```
Was A$19.99, now A$20.17!
Price per kilogram: A$10.09
Price per unit: A$0.31
JSON response:
{
product: {
name: 'Mr Sparkle Dishwashing Detergent Powder, 2kg, 66 Washes',
manufacturer: 'Matsumura Fishworks & Tamaribuchi Heavy Manufacturing Concern',
weightKg: '2.00',
unitsPerPack: '66.00',
price: { amount: '19.99', currency: 'AUD' },
shippingFee: { amount: '4.18', currency: 'AUD' }
},
discount: { percent: '20.00' },
originalPrice: { amount: '19.99', currency: 'AUD' },
finalPrice: { amount: '20.17', currency: 'AUD' },
pricePerKg: { amount: '10.09', currency: 'AUD' },
pricePerUnit: { amount: '0.31', currency: 'AUD' }
}
```
## Usage

@@ -31,3 +126,3 @@ ### MoneyAmount

* An instance of the [Decimal128](https://mongodb.github.io/node-mongodb-native/4.1/classes/Decimal128.html) type, as exported by [bson](https://www.npmjs.com/package/bson) (the same type is also re-exported by the [MongoDB driver](https://www.npmjs.com/package/mongodb)). In MongoDB, this is called [NumberDecimal](https://docs.mongodb.com/manual/core/shell-types/#numberdecimal), meaning you can store a NumberDecimal in a MongoDB document, then retrieve and pass it directly to Money.
* You can also pass another instance of Money, or the simplified object returned by [`Money.toJSON()`](#tojson).
* You can also pass another instance of Money, or the simplified object returned by [`Money.toJSON()`](#tojson--amount-moneyamount-currency-currency-).

@@ -85,2 +180,4 @@ ### Currency

`toJSON()` is [called by](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#tojson_behavior) `JSON.stringify()` to retrieve a variant of the object that can be represented in JSON. As such, you likely won’t need to call this directly.
#### `amount: string`

@@ -102,2 +199,2 @@ The string value that can be stored in a database or serialized into a payload such as JSON. This amount is rounded to 2 decimal places, and is intended to be machine-readable. For a human-readable string, use [`toString()`](#tostring-string).

## License
Licensed under the Apache License, version 2.0. Refer to [LICENSE.md](https://github.com/chariz/express-flash/blob/main/LICENSE.md).
Licensed under the Apache License, version 2.0. Refer to [LICENSE.md](https://github.com/chariz/money-calc/blob/main/LICENSE.md).

Sorry, the diff of this file is not supported yet