UNPKG

pricing4ts

Version:

![NPM Version](https://img.shields.io/npm/v/pricing4ts) Pricing4TS is a TypeScript-based toolkit designed to enhance the server-side functionality of a pricing-driven SaaS by enabling the seamless integration of pricing plans into the application logic. T

192 lines (191 loc) 8.82 kB
"use strict"; var __assign = (this && this.__assign) || function () { __assign = Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.explain = explain; var number_utils_1 = require("./dzn-exporter/number-utils"); function explain(minizincError, pricing) { var message = minizincError.message; if (!message) { return JSON.stringify(minizincError); } var _a = message.split(':'), errorId = _a[0], errorMessage = _a[1]; switch (errorId) { case 'InvalidUsageLimitValueError': return explainUsageLimitWithoutValueError(pricing, errorMessage); case 'DeadFeatureError': return explainDeadFeatureError(pricing, errorMessage); case 'DeadUsageLimitError': return explainDeadUsageLimitError(pricing, errorMessage); default: return message; } } function explainUsageLimitWithoutValueError(pricing, errorMessage) { var pricingUsageLimits = pricing.usageLimits; var usageLimitsWithoutValue = []; var featuresLinkedToManyUsageLimits = _findFeaturesLinkedToManyUsageLimits(pricing); for (var _i = 0, _a = Object.values(pricingUsageLimits); _i < _a.length; _i++) { var usageLimit = _a[_i]; var plansWithUsageLimitInactive = _plansWithInactiveUsageLimit(usageLimit.name, usageLimit.linkedFeatures, pricing, featuresLinkedToManyUsageLimits); var isUsageLimitInvalid = plansWithUsageLimitInactive.length > 0; if (isUsageLimitInvalid) { usageLimitsWithoutValue.push("".concat(usageLimit.name, " in [").concat(plansWithUsageLimitInactive, "]")); } } return ("".concat(errorMessage, " Found usage limits without value > 0: ") + usageLimitsWithoutValue.join(', ')); } function explainDeadFeatureError(pricing, errorMessage) { var pricingFeatures = Object.keys(pricing.features); var deadFeatures = []; for (var _i = 0, pricingFeatures_1 = pricingFeatures; _i < pricingFeatures_1.length; _i++) { var feature = pricingFeatures_1[_i]; var isFeatureDead = !(_isFeatureInAnyPlan(feature, pricing.plans) || _isFeatureInAnyAddOn(feature, pricing.addOns)); if (isFeatureDead) { deadFeatures.push(feature); } } return "".concat(errorMessage, " Found dead features: ") + deadFeatures.join(', '); } function explainDeadUsageLimitError(pricing, errorMessage) { var pricingUsageLimits = Object.keys(pricing.usageLimits); var deadUsageLimits = []; for (var _i = 0, pricingUsageLimits_1 = pricingUsageLimits; _i < pricingUsageLimits_1.length; _i++) { var usageLimit = pricingUsageLimits_1[_i]; var isUsageLimitDead = !(_isUsageLimitInAnyPlan(usageLimit, pricing.plans) || _isUsageLimitInAnyAddOn(usageLimit, pricing.usageLimits[usageLimit].valueType, pricing.addOns)); if (isUsageLimitDead) { deadUsageLimits.push(usageLimit); } } return "".concat(errorMessage, " Found dead usage limits: ") + deadUsageLimits.join(', '); } function _isFeatureInAnyPlan(feature, plans) { if (plans) { for (var _i = 0, _a = Object.values(plans); _i < _a.length; _i++) { var plan = _a[_i]; if (plan.features[feature].value || plan.features[feature].defaultValue) { return true; } } } return false; } function _isUsageLimitInAnyPlan(usageLimit, plans) { if (plans) { for (var _i = 0, _a = Object.values(plans); _i < _a.length; _i++) { var plan = _a[_i]; if ((0, number_utils_1.calculateOverriddenValue)(plan.usageLimits[usageLimit]) > 0) { return true; } } } return false; } function _isFeatureInAnyAddOn(feature, addOns) { var _a, _b; if (addOns) { for (var _i = 0, _c = Object.values(addOns); _i < _c.length; _i++) { var addOn = _c[_i]; if ((_b = (_a = addOn.features) === null || _a === void 0 ? void 0 : _a[feature]) === null || _b === void 0 ? void 0 : _b.value) { return true; } } } return false; } function _isUsageLimitInAnyAddOn(usageLimit, usageLimitValueType, addOns) { var _a, _b, _c, _d; if (addOns) { for (var _i = 0, _e = Object.values(addOns); _i < _e.length; _i++) { var addOn = _e[_i]; // If the usage limit has a value in the add-on, or extend the plan's value, it is considered active if ((((_a = addOn.usageLimits) === null || _a === void 0 ? void 0 : _a[usageLimit]) && (0, number_utils_1.calculateOverriddenValue)(__assign(__assign({}, (_b = addOn.usageLimits) === null || _b === void 0 ? void 0 : _b[usageLimit]), { valueType: usageLimitValueType })) > 0) || (((_c = addOn.usageLimitsExtensions) === null || _c === void 0 ? void 0 : _c[usageLimit]) && (0, number_utils_1.calculateOverriddenValue)(__assign(__assign({}, (_d = addOn.usageLimitsExtensions) === null || _d === void 0 ? void 0 : _d[usageLimit]), { valueType: usageLimitValueType })) > 0)) { return true; } } } return false; } function _plansWithInactiveUsageLimit(usageLimit, linkedFeatures, pricing, featuresLinkedToManyUsageLimits) { var plansWithInactiveUsageLimit = []; if (pricing.plans && linkedFeatures && linkedFeatures.length > 0) { var _loop_1 = function (plan) { var planFeatures = plan.features; var isPlanWithLinkedFeatureActive = false; var _loop_2 = function (feature) { if (linkedFeatures.includes(feature.name)) { if (!featuresLinkedToManyUsageLimits.includes(feature.name) && (feature.value || feature.defaultValue)) { isPlanWithLinkedFeatureActive = true; return "break"; } else if (featuresLinkedToManyUsageLimits.includes(feature.name)) { var usageLimitsLinkedToFeature = Object.values(pricing.usageLimits).map(function (u) { var _a; return (_a = u.linkedFeatures) === null || _a === void 0 ? void 0 : _a.includes(feature.name); }); if (usageLimitsLinkedToFeature.some(function (u) { return (0, number_utils_1.calculateOverriddenValue)(plan.usageLimits[usageLimit]) > 0; })) { isPlanWithLinkedFeatureActive = true; return "break"; } } } }; // If no feature linked to the limit is active in the plan, an inactive usage limit is not invalid, so there is no need to perform the evaluation for (var _b = 0, _c = Object.values(planFeatures); _b < _c.length; _b++) { var feature = _c[_b]; var state_1 = _loop_2(feature); if (state_1 === "break") break; } if (!isPlanWithLinkedFeatureActive) { return "continue"; } var overridenValue = (0, number_utils_1.calculateOverriddenValue)(plan.usageLimits[usageLimit]); if (overridenValue === 0) { plansWithInactiveUsageLimit.push(plan.name); } }; for (var _i = 0, _a = Object.values(pricing.plans); _i < _a.length; _i++) { var plan = _a[_i]; _loop_1(plan); } } return plansWithInactiveUsageLimit; } function _findFeaturesLinkedToManyUsageLimits(pricing) { var pricingUsageLimits = pricing.usageLimits; var linkedFeaturesCounter = {}; for (var _i = 0, _a = Object.values(pricingUsageLimits); _i < _a.length; _i++) { var usageLimit = _a[_i]; var linkedFeatures = usageLimit.linkedFeatures; if (linkedFeatures) { for (var _b = 0, linkedFeatures_1 = linkedFeatures; _b < linkedFeatures_1.length; _b++) { var feature = linkedFeatures_1[_b]; if (!linkedFeaturesCounter[feature]) { linkedFeaturesCounter[feature] = 0; } linkedFeaturesCounter[feature] += 1; } } } return Object.entries(linkedFeaturesCounter) .filter(function (_a) { var _ = _a[0], count = _a[1]; return count > 1; }) .map(function (_a) { var feature = _a[0]; return feature; }); }