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

271 lines (270 loc) 20.3 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); }; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __generator = (this && this.__generator) || function (thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype); return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (g && (g = 0, op[0] && (_ = 0)), _) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); var minizinc_1 = __importDefault(require("../models/minizinc/minizinc")); var pricing_dzn_exporter_1 = require("../utils/dzn-exporter/pricing-dzn-exporter"); var minizinc_2 = require("../models/minizinc/minizinc"); var minizinc_explanator_1 = require("../utils/minizinc-explanator"); var plan_1 = require("../../main/models/pricing2yaml/plan"); var addon_1 = require("../../main/models/pricing2yaml/addon"); var defaultAnalyticsOptions = { printDzn: false }; var PricingService = /** @class */ (function () { function PricingService(pricing) { this.pricing = pricing; } PricingService.prototype.runPricingOperation = function (pricingOperation) { return __awaiter(this, void 0, void 0, function () { var dznPricing, model; return __generator(this, function (_a) { dznPricing = (0, pricing_dzn_exporter_1.pricing2DZN)(this.pricing); model = new minizinc_1.default(); return [2 /*return*/, model.runPricingOperation(pricingOperation, dznPricing)]; }); }); }; PricingService.prototype.getConfigurationSpace = function () { return __awaiter(this, void 0, void 0, function () { var dznPricing, configurationSpace, result, allSolutions, _i, allSolutions_1, solution, selectedPlan, selectedAddons, subscriptionFeatures, subscriptionUsageLimits, e_1; var _this = this; return __generator(this, function (_a) { switch (_a.label) { case 0: dznPricing = (0, pricing_dzn_exporter_1.pricing2DZN)(this.pricing); _a.label = 1; case 1: _a.trys.push([1, 3, , 4]); configurationSpace = []; return [4 /*yield*/, this._getConfigurationSpace(dznPricing)]; case 2: result = _a.sent(); allSolutions = result.allSolutions; for (_i = 0, allSolutions_1 = allSolutions; _i < allSolutions_1.length; _i++) { solution = allSolutions_1[_i]; selectedPlan = Object.keys(this.pricing.plans)[solution.selected_plan - 1]; selectedAddons = solution.selected_addons.map(function (addonIndex, index) { return addonIndex === 1 ? Object.keys(_this.pricing.addOns)[index] : null; }).filter(function (addon) { return addon !== null; }); subscriptionFeatures = solution.subscription_features.map(function (featureIndex, index) { return featureIndex === 1 ? Object.keys(_this.pricing.features)[index] : null; }).filter(function (feature) { return feature !== null; }); subscriptionUsageLimits = solution.subscription_usage_limits.map(function (usageLimitIndex, index) { return usageLimitIndex === 1 ? Object.keys(_this.pricing.usageLimits)[index] : null; }).filter(function (usageLimit) { return usageLimit !== null; }); configurationSpace.push({ selectedPlan: selectedPlan, selectedAddons: selectedAddons, subscriptionFeatures: subscriptionFeatures, subscriptionUsageLimits: subscriptionUsageLimits, subscriptionCost: solution.subscription_cost }); } return [2 /*return*/, configurationSpace]; case 3: e_1 = _a.sent(); throw new Error(e_1.message); case 4: return [2 /*return*/]; } }); }); }; PricingService.prototype.getAnalytics = function (analyticsOptions) { return __awaiter(this, void 0, void 0, function () { var dznPricing, _a, configurationSpaceResult, minSubscriptionPriceResult, maxSubscriptionPriceResult, informationFeatures, integrationFeatures, domainFeatures, automationFeatures, managementFeatures, guaranteeFeatures, supportFeatures, paymentFeatures, numberOfFeatures, numberOfInformationFeatures, numberOfIntegrationFeatures, numberOfIntegrationApiFeatures, numberOfIntegrationExtensionFeatures, numberOfIntegrationIdentityProviderFeatures, numberOfIntegrationWebSaaSFeatures, numberOfIntegrationMarketplaceFeatures, numberOfIntegrationExternalDeviceFeatures, numberOfDomainFeatures, numberOfAutomationFeatures, numberOfBotAutomationFeatures, numberOfFilteringAutomationFeatures, numberOfTrackingAutomationFeatures, numberOfTaskAutomationFeatures, numberOfManagementFeatures, numberOfGuaranteeFeatures, numberOfSupportFeatures, numberOfPaymentFeatures, numberOfUsageLimits, numberOfRenewableUsageLimits, numberOfNonRenewableUsageLimits, numberOfPlans, numberOfFreePlans, numberOfPaidPlans, numberOfAddOns, numberOfReplacementAddons, numberOfExtensionAddons, configurationSpaceSize, minSubscriptionPrice, maxSubscriptionPrice, e_2; var _this = this; return __generator(this, function (_b) { switch (_b.label) { case 0: if (!analyticsOptions) { analyticsOptions = defaultAnalyticsOptions; } else { analyticsOptions = __assign(__assign({}, defaultAnalyticsOptions), analyticsOptions); } _b.label = 1; case 1: _b.trys.push([1, 3, , 4]); dznPricing = (0, pricing_dzn_exporter_1.pricing2DZN)(this.pricing); if (analyticsOptions.printDzn) { console.log(dznPricing); } return [4 /*yield*/, Promise.all([ this._getConfigurationSpace(dznPricing), this._getMinSubscriptionPrice(dznPricing), this._getMaxSubscriptionPrice(dznPricing) ]).catch(function (e) { throw new Error((0, minizinc_explanator_1.explain)(e, _this.pricing)); })]; case 2: _a = _b.sent(), configurationSpaceResult = _a[0], minSubscriptionPriceResult = _a[1], maxSubscriptionPriceResult = _a[2]; informationFeatures = Object.values(this.pricing.features).filter(function (f) { return f.type === "INFORMATION"; }); integrationFeatures = Object.values(this.pricing.features).filter(function (f) { return f.type === "INTEGRATION"; }); domainFeatures = Object.values(this.pricing.features).filter(function (f) { return f.type === "DOMAIN"; }); automationFeatures = Object.values(this.pricing.features).filter(function (f) { return f.type === "AUTOMATION"; }); managementFeatures = Object.values(this.pricing.features).filter(function (f) { return f.type === "MANAGEMENT"; }); guaranteeFeatures = Object.values(this.pricing.features).filter(function (f) { return f.type === "GUARANTEE"; }); supportFeatures = Object.values(this.pricing.features).filter(function (f) { return f.type === "SUPPORT"; }); paymentFeatures = Object.values(this.pricing.features).filter(function (f) { return f.type === "PAYMENT"; }); numberOfFeatures = Object.values(this.pricing.features).length; numberOfInformationFeatures = informationFeatures.length; numberOfIntegrationFeatures = integrationFeatures.length; numberOfIntegrationApiFeatures = integrationFeatures.filter(function (f) { return f.integrationType === "API"; }).length; numberOfIntegrationExtensionFeatures = integrationFeatures.filter(function (f) { return f.integrationType === "EXTENSION"; }).length; numberOfIntegrationIdentityProviderFeatures = integrationFeatures.filter(function (f) { return f.integrationType === "IDENTITY_PROVIDER"; }).length; numberOfIntegrationWebSaaSFeatures = integrationFeatures.filter(function (f) { return f.integrationType === "WEB_SAAS"; }).length; numberOfIntegrationMarketplaceFeatures = integrationFeatures.filter(function (f) { return f.integrationType === "MARKETPLACE"; }).length; numberOfIntegrationExternalDeviceFeatures = integrationFeatures.filter(function (f) { return f.integrationType === "EXTERNAL_DEVICE"; }).length; numberOfDomainFeatures = domainFeatures.length; numberOfAutomationFeatures = automationFeatures.length; numberOfBotAutomationFeatures = automationFeatures.filter(function (f) { return f.automationType === "BOT"; }).length; numberOfFilteringAutomationFeatures = automationFeatures.filter(function (f) { return f.automationType === "FILTERING"; }).length; numberOfTrackingAutomationFeatures = automationFeatures.filter(function (f) { return f.automationType === "TRACKING"; }).length; numberOfTaskAutomationFeatures = automationFeatures.filter(function (f) { return f.automationType === "TASK_AUTOMATION"; }).length; numberOfManagementFeatures = managementFeatures.length; numberOfGuaranteeFeatures = guaranteeFeatures.length; numberOfSupportFeatures = supportFeatures.length; numberOfPaymentFeatures = paymentFeatures.length; numberOfUsageLimits = this.pricing.usageLimits ? Object.values(this.pricing.usageLimits).length : 0; numberOfRenewableUsageLimits = this.pricing.usageLimits ? Object.values(this.pricing.usageLimits).filter(function (ul) { return ul.type === "RENEWABLE"; }).length : 0; numberOfNonRenewableUsageLimits = this.pricing.usageLimits ? Object.values(this.pricing.usageLimits).filter(function (ul) { return ul.type === "NON_RENEWABLE"; }).length : 0; numberOfPlans = this.pricing.plans ? Object.values(this.pricing.plans).length : 0; numberOfFreePlans = this.pricing.plans ? Object.values(this.pricing.plans).filter(function (p) { return p.price === 0; }).length : 0; numberOfPaidPlans = this.pricing.plans ? Object.values(this.pricing.plans).filter(function (p) { return typeof (p.price) === "number" ? p.price > 0 : true; }).length : 0; numberOfAddOns = this.pricing.addOns ? Object.values(this.pricing.addOns).length : 0; numberOfReplacementAddons = this.pricing.addOns ? Object.values(this.pricing.addOns).filter(function (a) { return a.features || a.usageLimits; }).length : 0; numberOfExtensionAddons = this.pricing.addOns ? Object.values(this.pricing.addOns).filter(function (a) { return a.features || a.usageLimits ? false : a.usageLimitsExtensions; }).length : 0; configurationSpaceSize = configurationSpaceResult.statistics.nSolutions; minSubscriptionPrice = configurationSpaceSize !== 0 ? this._computeConfigurationPrice(minSubscriptionPriceResult.solution.output.json) : NaN; maxSubscriptionPrice = configurationSpaceSize !== 0 ? this._computeConfigurationPrice(maxSubscriptionPriceResult.solution.output.json) : NaN; return [2 /*return*/, { numberOfFeatures: numberOfFeatures, numberOfInformationFeatures: numberOfInformationFeatures, numberOfIntegrationFeatures: numberOfIntegrationFeatures, numberOfIntegrationApiFeatures: numberOfIntegrationApiFeatures, numberOfIntegrationExtensionFeatures: numberOfIntegrationExtensionFeatures, numberOfIntegrationIdentityProviderFeatures: numberOfIntegrationIdentityProviderFeatures, numberOfIntegrationWebSaaSFeatures: numberOfIntegrationWebSaaSFeatures, numberOfIntegrationMarketplaceFeatures: numberOfIntegrationMarketplaceFeatures, numberOfIntegrationExternalDeviceFeatures: numberOfIntegrationExternalDeviceFeatures, numberOfDomainFeatures: numberOfDomainFeatures, numberOfAutomationFeatures: numberOfAutomationFeatures, numberOfBotAutomationFeatures: numberOfBotAutomationFeatures, numberOfFilteringAutomationFeatures: numberOfFilteringAutomationFeatures, numberOfTrackingAutomationFeatures: numberOfTrackingAutomationFeatures, numberOfTaskAutomationFeatures: numberOfTaskAutomationFeatures, numberOfManagementFeatures: numberOfManagementFeatures, numberOfGuaranteeFeatures: numberOfGuaranteeFeatures, numberOfSupportFeatures: numberOfSupportFeatures, numberOfPaymentFeatures: numberOfPaymentFeatures, numberOfUsageLimits: numberOfUsageLimits, numberOfRenewableUsageLimits: numberOfRenewableUsageLimits, numberOfNonRenewableUsageLimits: numberOfNonRenewableUsageLimits, numberOfPlans: numberOfPlans, numberOfFreePlans: numberOfFreePlans, numberOfPaidPlans: numberOfPaidPlans, numberOfAddOns: numberOfAddOns, numberOfReplacementAddons: numberOfReplacementAddons, numberOfExtensionAddons: numberOfExtensionAddons, configurationSpaceSize: configurationSpaceSize, minSubscriptionPrice: parseFloat(minSubscriptionPrice.toFixed(2)), maxSubscriptionPrice: parseFloat(maxSubscriptionPrice.toFixed(2)), }]; case 3: e_2 = _b.sent(); throw new Error(e_2.message); case 4: return [2 /*return*/]; } }); }); }; PricingService.prototype._getConfigurationSpace = function (dznPricing) { return __awaiter(this, void 0, void 0, function () { var model; return __generator(this, function (_a) { model = new minizinc_1.default(); return [2 /*return*/, model.runPricingOperation(minizinc_2.PricingOperation.CONFIGURATION_SPACE, dznPricing)]; }); }); }; PricingService.prototype._getMinSubscriptionPrice = function (dznPricing) { return __awaiter(this, void 0, void 0, function () { var model; return __generator(this, function (_a) { model = new minizinc_1.default(); return [2 /*return*/, model.runPricingOperation(minizinc_2.PricingOperation.CHEAPEST_SUBSCRIPTION, dznPricing)]; }); }); }; PricingService.prototype._getMaxSubscriptionPrice = function (dznPricing) { return __awaiter(this, void 0, void 0, function () { var model; return __generator(this, function (_a) { model = new minizinc_1.default(); return [2 /*return*/, model.runPricingOperation(minizinc_2.PricingOperation.MOST_EXPENSIVE_SUBSCRIPTION, dznPricing)]; }); }); }; PricingService.prototype._computeConfigurationPrice = function (minizincSolution) { var plansPrices = (0, plan_1.getPlanPrices)(this.pricing.plans); var addOnPrices = (0, addon_1.getAddOnPrices)(this.pricing.addOns); var configurationPrice = 0; if (plansPrices.length > 0) { configurationPrice += plansPrices[minizincSolution.selected_plan - 1]; } if (addOnPrices.length > 0) { for (var i = 0; i < minizincSolution.selected_addons.length; i++) { var item = minizincSolution.selected_addons[i]; if (item === 1) { configurationPrice += addOnPrices[i]; } } } return configurationPrice; }; return PricingService; }()); exports.default = PricingService;