pricing4ts
Version:
 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
767 lines (766 loc) • 37.4 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.validateName = validateName;
exports.validateSyntaxVersion = validateSyntaxVersion;
exports.validateVersion = validateVersion;
exports.validateCreatedAt = validateCreatedAt;
exports.validateCurrency = validateCurrency;
exports.validateDescription = validateDescription;
exports.validateValueType = validateValueType;
exports.validateDefaultValue = validateDefaultValue;
exports.validateExpression = validateExpression;
exports.validateValue = validateValue;
exports.validateFeatureType = validateFeatureType;
exports.validateFeatureIntegrationType = validateFeatureIntegrationType;
exports.validateFeatureAutomationType = validateFeatureAutomationType;
exports.validateUnit = validateUnit;
exports.validateUsageLimitType = validateUsageLimitType;
exports.validateLinkedFeatures = validateLinkedFeatures;
exports.validateRenderMode = validateRenderMode;
exports.validatePlanFeatures = validatePlanFeatures;
exports.validatePlanUsageLimits = validatePlanUsageLimits;
exports.validatePrice = validatePrice;
exports.validateAddonFeatures = validateAddonFeatures;
exports.validateAddonUsageLimits = validateAddonUsageLimits;
exports.validateAddonUsageLimitsExtensions = validateAddonUsageLimitsExtensions;
exports.validateAvailableFor = validateAvailableFor;
exports.validateDependsOnOrExcludes = validateDependsOnOrExcludes;
exports.postValidateDependsOnOrExclude = postValidateDependsOnOrExclude;
exports.validateTags = validateTags;
exports.validatePlan = validatePlan;
exports.validatePlans = validatePlans;
exports.validateFeatures = validateFeatures;
exports.validateFeature = validateFeature;
exports.validateUsageLimits = validateUsageLimits;
exports.validateUsageLimit = validateUsageLimit;
exports.validateBilling = validateBilling;
exports.validateVariables = validateVariables;
exports.validateUrl = validateUrl;
exports.validatePrivate = validatePrivate;
exports.validatePricingUrls = validatePricingUrls;
exports.validateDocUrl = validateDocUrl;
exports.validatePeriodUnit = validatePeriodUnit;
exports.validatePeriodValue = validatePeriodValue;
exports.validateTrackable = validateTrackable;
exports.validateSubscriptionConstraintMinQuantity = validateSubscriptionConstraintMinQuantity;
exports.validateSubscriptionConstraintMaxQuantity = validateSubscriptionConstraintMaxQuantity;
exports.validateSubscriptionConstraintQuantityStep = validateSubscriptionConstraintQuantityStep;
var cc = __importStar(require("currency-codes"));
var feature_1 = require("../models/pricing2yaml/feature");
var VERSION_REGEXP = /^\d+\.\d+$/;
var unlimitedValue = 100000000;
function validateName(name, item) {
if (name === null || name === undefined) {
throw new Error("The ".concat(item, " must have a name"));
}
if (typeof name !== 'string') {
throw new Error("The ".concat(item, " name must be a string"));
}
var trimmedName = name.trim();
if (trimmedName.length === 0) {
throw new Error("The ".concat(item, " name must not be empty"));
}
if (trimmedName.length < 3) {
throw new Error("The ".concat(item, " name must have at least 3 characters"));
}
if (trimmedName.length > 255) {
throw new Error("The ".concat(item, " name must have at most 255 characters"));
}
return trimmedName;
}
function validateSyntaxVersion(version) {
if (version === null || version === undefined) {
throw new Error("The syntaxVersion field of the pricing must not be null or undefined. Please ensure that the syntaxVersion field is present and correctly formatted");
}
if (typeof version !== 'string' || !VERSION_REGEXP.test(version)) {
throw new Error("The syntaxVersion field of the pricing does not follow the required structure: X.Y (being X and Y numbers). Please ensure it is a string in the format X.Y");
}
return version;
}
function validateVersion(version, createdAt) {
if (version === null || version === undefined) {
version = "".concat(createdAt.getFullYear(), "-").concat(createdAt.getMonth() + 1, "-").concat(createdAt.getDate());
}
if (typeof version !== 'string') {
throw new Error("The version field of the pricing must be a string. Please ensure that the version field is present and correctly formatted");
}
return version;
}
function validateCreatedAt(createdAt) {
if (createdAt === null || createdAt === undefined) {
throw new Error("The createdAt field must not be null or undefined. Please ensure that the createdAt field is present and correctly formatted (as Date or string)");
}
if (typeof createdAt === 'string') {
if (/^\d{4}-\d{2}-\d{2}$/.test(createdAt)) {
createdAt = new Date(createdAt);
}
else {
throw new Error("The createdAt field must be a string in the format yyyy-mm-dd or a valid Date object");
}
}
if (!(createdAt instanceof Date) || isNaN(createdAt.getTime())) {
throw new Error("The createdAt field must be a valid Date object or a string in a recognized date format");
}
var now = new Date();
if (createdAt > now) {
throw new Error("The createdAt field must not be a future date");
}
return createdAt;
}
function validateCurrency(currency) {
if (currency === null || currency === undefined) {
throw new Error("The currency field of the pricing must not be null or undefined. Please ensure that the currency field is present and correctly formatted");
}
if (typeof currency !== 'string') {
throw new Error("The currency field of the pricing must be a string");
}
var trimmedCurrency = currency.trim();
if (trimmedCurrency.length === 0) {
throw new Error("The currency field of the pricing must not be empty");
}
var currencyCode = cc.code(trimmedCurrency);
if (!currencyCode) {
throw new Error("The currency code ".concat(trimmedCurrency, " is not a valid ISO 4217 currency code"));
}
return currency;
}
function validateDescription(description) {
if (description === null) {
description = undefined;
}
return description;
}
function validateValueType(valueType) {
if (valueType === null || valueType === undefined) {
throw new Error("The valueType field of a feature must not be null or undefined. Please ensure that the valueType field is present and it's value correspond to either BOOLEAN, NUMERIC or TEXT");
}
if (typeof valueType !== 'string') {
throw new Error("The valueType field of a feature must be a string, and its value must be either BOOLEAN, NUMERIC or TEXT. Received: ".concat(valueType, " "));
}
valueType = valueType.trim().toUpperCase();
if (!['NUMERIC', 'BOOLEAN', 'TEXT'].includes(valueType)) {
throw new Error("The valueType field of a feature must be one of NUMERIC, BOOLEAN, or TEXT. Received: ".concat(valueType));
}
return valueType;
}
function validateDefaultValue(elem, item) {
if (elem.defaultValue === null || elem.defaultValue === undefined) {
throw new Error("The defaultValue field of a ".concat(item, " must not be null or undefined. Please ensure that the defaultValue field is present and its defaultValue type correspond to the declared valueType"));
}
switch (elem.valueType) {
case 'NUMERIC':
if (typeof elem.defaultValue !== 'number') {
throw new Error("The defaultValue field of a ".concat(item, " must be a number when its valueType is NUMERIC. Received: ").concat(elem.defaultValue));
}
if (elem.defaultValue > unlimitedValue) {
elem.defaultValue = unlimitedValue;
}
break;
case 'BOOLEAN':
if (typeof elem.defaultValue !== 'boolean') {
throw new Error("The defaultValue field of a ".concat(item, " must be a boolean when its valueType is BOOLEAN. Received: ").concat(elem.defaultValue));
}
break;
case 'TEXT':
if (elem.type === 'PAYMENT') {
if (!(elem.defaultValue instanceof Array)) {
throw new Error("Payment method value must be an array of payment methods");
}
for (var _i = 0, _a = elem.defaultValue; _i < _a.length; _i++) {
var paymentMethod = _a[_i];
if (!['CARD', 'GATEWAY', 'INVOICE', 'ACH', 'WIRE_TRANSFER', 'OTHER'].includes(paymentMethod)) {
throw new Error("Invalid payment method: ".concat(paymentMethod, ". Please provide one of the following: CARD, GATEWAY, INVOICE, ACH, WIRE_TRANSFER, OTHER"));
}
}
break;
}
if (typeof elem.defaultValue !== 'string') {
throw new Error("The defaultValue field of a ".concat(item, " must be a string when its valueType is TEXT. Received: ").concat(elem.defaultValue));
}
break;
default:
throw new Error("The valueType field of a ".concat(item, " must be either BOOLEAN, NUMERIC or TEXT. Received: ").concat(elem.valueType));
}
return elem.defaultValue;
}
function validateExpression(expression, item) {
if (expression === null) {
expression = undefined;
}
if (typeof expression === 'string') {
if (expression.trim().length === 0) {
throw new Error("The ".concat(item, " field of a feature must not be empty. If you don't want to declare an expression for this feature, either use null or undefined"));
}
}
return expression;
}
function validateValue(elem, item, valueType) {
if (valueType === void 0) { valueType = undefined; }
if (elem.value === null || elem.value === undefined) {
elem.value = undefined;
}
var valueTypeToValidate = valueType || elem.valueType;
switch (valueTypeToValidate) {
case 'NUMERIC':
if (typeof elem.value !== 'number' && elem.value !== undefined) {
throw new Error("The value field of a ".concat(item, " must be a number when its valueType is NUMERIC. Received: ").concat(elem.value));
}
if (elem.value > unlimitedValue) {
elem.value = unlimitedValue;
}
break;
case 'BOOLEAN':
if (typeof elem.value !== 'boolean' && elem.value !== undefined) {
throw new Error("The value field of a ".concat(item, " must be a boolean when its valueType is BOOLEAN. Received: ").concat(elem.value));
}
break;
case 'TEXT':
if (elem.type === 'PAYMENT' && elem.value !== undefined) {
if (!(elem.value instanceof Array)) {
throw new Error("Payment method value must be an array of payment methods");
}
for (var _i = 0, _a = elem.value; _i < _a.length; _i++) {
var paymentMethod = _a[_i];
if (!['CARD', 'GATEWAY', 'INVOICE', 'ACH', 'WIRE_TRANSFER', 'OTHER'].includes(paymentMethod)) {
throw new Error("Invalid payment method: ".concat(paymentMethod, ". Please provide one of the following: CARD, GATEWAY, INVOICE, ACH, WIRE_TRANSFER, OTHER"));
}
}
break;
}
if (typeof elem.value !== 'string' && elem.value !== undefined) {
throw new Error("The value field of a ".concat(item, " must be a string when its valueType is TEXT. Received: ").concat(elem.value));
}
break;
default:
throw new Error("The valueType field of a ".concat(item, " must be either BOOLEAN, NUMERIC or TEXT. Received: ").concat(elem.valueType));
}
return elem.value;
}
function validateFeatureType(type) {
if (type === null || type === undefined) {
throw new Error("The type field of a feature must not be null or undefined. Please ensure that the type field is present and it's value correspond to either INFORMATION, INTEGRATION, DOMAIN, AUTOMATION, MANAGEMENT, GUARANTEE, SUPPORT or PAYMENT");
}
if (typeof type !== 'string') {
throw new Error("The type field of a feature must be a string, and its value must be either INFORMATION, INTEGRATION, DOMAIN, AUTOMATION, MANAGEMENT, GUARANTEE, SUPPORT or PAYMENT. Received: ".concat(type, " "));
}
type = type.trim().toUpperCase();
if (![
'INFORMATION',
'INTEGRATION',
'DOMAIN',
'AUTOMATION',
'MANAGEMENT',
'GUARANTEE',
'SUPPORT',
'PAYMENT',
].includes(type)) {
throw new Error("The type field of a feature must be one of INFORMATION, INTEGRATION, DOMAIN, AUTOMATION, MANAGEMENT, GUARANTEE, SUPPORT or PAYMENT. Received: ".concat(type));
}
return type;
}
function validateFeatureIntegrationType(integrationType, featureType) {
if (integrationType === null || integrationType === undefined) {
integrationType = undefined;
}
if (integrationType && typeof integrationType !== 'string') {
throw new Error("The integrationType field of a feature must be an IntegrationType ('API' | 'EXTENSION' | 'IDENTITY_PROVIDER' | 'WEB_SAAS' | 'MARKETPLACE' | 'EXTERNAL_DEVICE'). Received: ".concat(integrationType));
}
else if (featureType === 'INTEGRATION' && !integrationType) {
throw new Error("The integrationType field of a feature of type INTEGRATION must not be null or undefined. Please ensure that the integrationType field is present and it's value correspond to either API, EXTENSION, IDENTITY_PROVIDER, WEB_SAAS, MARKETPLACE or EXTERNAL_DEVICE");
}
else if (integrationType && typeof integrationType === "string" && !(0, feature_1.isIntegrationType)(integrationType)) {
throw new Error("The integrationType field of a feature must be one of API, EXTENSION, IDENTITY_PROVIDER, WEB_SAAS, MARKETPLACE or EXTERNAL_DEVICE. Received: ".concat(integrationType));
}
return integrationType;
}
function validateFeatureAutomationType(automationType, featureType) {
if (automationType === null || automationType === undefined) {
automationType = undefined;
}
if (automationType && typeof automationType !== 'string') {
throw new Error("The automationType field of a feature must be an AutomationType ('BOT' | 'FILTERING' | 'TRACKING' | 'TASK_AUTOMATION'). Received: ".concat(automationType));
}
else if (featureType === 'AUTOMATION' && !automationType) {
throw new Error("The automationType field of a feature of type AUTOMATION must not be null or undefined. Please ensure that the automationType field is present and its value corresponds to either BOT, FILTERING, TRACKING, or TASK_AUTOMATION");
}
else if (automationType && typeof automationType === "string" && !(0, feature_1.isAutomationType)(automationType)) {
throw new Error("The automationType field of a feature must be one of BOT, FILTERING, TRACKING, or TASK_AUTOMATION. Received: ".concat(automationType));
}
return automationType;
}
function validateUnit(unit) {
if (unit === null || unit === undefined) {
unit = '';
}
if (typeof unit !== 'string') {
throw new Error("The unit field of a usage limit must be a string. Received: ".concat(unit, " "));
}
return unit;
}
function validateUsageLimitType(type) {
if (type === null || type === undefined) {
throw new Error("The type field of a usage limit must not be null or undefined. Please ensure that the type field is present and it's value correspond to either RENEWABLE or NON_RENEWABLE");
}
if (typeof type !== 'string') {
throw new Error("The type field of a usage limit must be a string, and its value must be either RENEWABLE or NON_RENEWABLE. Received: ".concat(type, " "));
}
type = type.trim().toUpperCase();
if (!['RENEWABLE', 'NON_RENEWABLE'].includes(type)) {
throw new Error("The type field of a usage limit must be one of RENEWABLE or NON_RENEWABLE. Received: ".concat(type));
}
return type;
}
function validateLinkedFeatures(linkedFeatures, pricing) {
if (linkedFeatures === null) {
linkedFeatures = undefined;
}
// Check if linked features is an array
if (Array.isArray(linkedFeatures)) {
var pricingFeatures = Object.values(pricing.features).map(function (f) { return f.name; });
for (var _i = 0, linkedFeatures_1 = linkedFeatures; _i < linkedFeatures_1.length; _i++) {
var featureName = linkedFeatures_1[_i];
if (!pricingFeatures.includes(featureName)) {
throw new Error("The feature ".concat(featureName, ", declared as a linked feature for an usage limit, is not defined in the global features"));
}
}
}
return linkedFeatures;
}
function validateRenderMode(renderMode) {
if (renderMode === null || renderMode === undefined) {
renderMode = 'AUTO';
}
renderMode = renderMode.toUpperCase();
if (!['AUTO', 'ENABLED', 'DISABLED'].includes(renderMode)) {
throw new Error("The render field of a feature or usage limit must be one of AUTO, ENABLED or DISABLED. Received: ".concat(renderMode));
}
return renderMode;
}
function validatePlanFeatures(plan, planFeatures) {
var featuresModifiedByPlan = plan.features;
plan.features = planFeatures;
var _loop_1 = function (planFeature) {
try {
if (!Object.values(planFeatures).some(function (f) { return f.name === planFeature.name; })) {
throw new Error("Feature ".concat(planFeature.name, " is not defined in the global features."));
}
var featureWithDefaultValue = Object.values(plan.features).find(function (f) { return f.name === planFeature.name; });
featureWithDefaultValue.value = planFeature.value;
featureWithDefaultValue.value = validateValue(featureWithDefaultValue, 'feature');
}
catch (err) {
throw new Error("Error while parsing the feature ".concat(planFeature.name, " of the plan ").concat(plan.name, ". Error: ").concat(err.message));
}
};
for (var _i = 0, _a = Object.values(featuresModifiedByPlan); _i < _a.length; _i++) {
var planFeature = _a[_i];
_loop_1(planFeature);
}
return plan.features;
}
function validatePlanUsageLimits(plan, planUsageLimits) {
var usageLimitsModifiedByPlan = plan.usageLimits;
plan.usageLimits = planUsageLimits;
var _loop_2 = function (planUsageLimit) {
try {
if (!Object.values(planUsageLimits).some(function (l) { return l.name === planUsageLimit.name; })) {
throw new Error("Usage limit ".concat(planUsageLimit.name, " is not defined in the global usage limits."));
}
var globalUsageLimit = Object.values(planUsageLimits).find(function (l) { return l.name === planUsageLimit.name; });
globalUsageLimit.value = planUsageLimit.value;
globalUsageLimit.value = validateValue(globalUsageLimit, 'usage limit');
}
catch (err) {
throw new Error("Error while parsing the usage limit ".concat(planUsageLimit.name, " of the plan ").concat(plan.name, ". Error: ").concat(err.message));
}
};
for (var _i = 0, _a = Object.values(usageLimitsModifiedByPlan); _i < _a.length; _i++) {
var planUsageLimit = _a[_i];
_loop_2(planUsageLimit);
}
return plan.usageLimits;
}
function validatePrice(price, variables) {
if (price === null || price === undefined) {
throw new Error("The price field must not be null or undefined. Please ensure that the price field is present and it's a number");
}
if (typeof price !== 'string' && typeof price !== 'number') {
throw new Error("The price field must be a number or a string (which can contain a formula). Received: ".concat(price));
}
if (typeof price === 'number' && price < 0) {
throw new Error("The price field must be a positive number. Received: ".concat(price, " "));
}
if (typeof price === 'string') {
if (price.includes('#')) {
for (var _i = 0, _a = Object.entries(variables); _i < _a.length; _i++) {
var _b = _a[_i], variable = _b[0], value = _b[1];
price = price.replace("#".concat(variable), "".concat(typeof value === 'string' ? "'".concat(value, "'") : value));
}
try {
// eslint-disable-next-line no-eval
var evaluatedPrice = eval(price);
if (typeof evaluatedPrice !== 'number' || isNaN(evaluatedPrice)) {
throw new Error("The evaluated price must result in a valid number. Current result after evaluation: ".concat(evaluatedPrice));
}
price = evaluatedPrice;
}
catch (err) {
throw new Error("Error evaluating the price formula: ".concat(err.message));
}
}
else if (price.match(/^[0-9]+(\.[0-9]+)?$/)) {
price = parseFloat(price);
}
}
return price;
}
function validateAddonFeatures(addon, addOnFeatures) {
var _loop_3 = function (addOnFeature) {
try {
if (!Object.values(addOnFeatures).some(function (f) { return f.name === addOnFeature.name; })) {
throw new Error("Feature ".concat(addOnFeature.name, " is not defined in the global features."));
}
addon.features[addOnFeature.name].value = addOnFeature.value;
addon.features[addOnFeature.name].value = validateValue(addon.features[addOnFeature.name], 'feature', addOnFeatures[addOnFeature.name].valueType);
}
catch (err) {
throw new Error("Error while parsing the feature ".concat(addOnFeature.name, " of the plan ").concat(addon.name, ". Error: ").concat(err.message));
}
};
for (var _i = 0, _a = Object.values(addon.features); _i < _a.length; _i++) {
var addOnFeature = _a[_i];
_loop_3(addOnFeature);
}
return addon.features;
}
function validateAddonUsageLimits(addon, addonUsageLimits) {
var _loop_4 = function (addonUsageLimit) {
try {
if (!Object.values(addonUsageLimits).some(function (l) { return l.name === addonUsageLimit.name; })) {
throw new Error("Usage limit ".concat(addonUsageLimit.name, " is not defined in the global usage limits."));
}
if (!('value' in addonUsageLimit)) {
throw new Error("When declaring a new value for an usage limit or a usage limit extension within an add-on, it must be provided through the 'value' field");
}
addon.usageLimits[addonUsageLimit.name].value = addonUsageLimit.value;
addon.usageLimits[addonUsageLimit.name].value = validateValue(addon.usageLimits[addonUsageLimit.name], 'usage limit', addonUsageLimits[addonUsageLimit.name].valueType);
}
catch (err) {
throw new Error("Error while parsing the usage limit ".concat(addonUsageLimit.name, " of the add-on ").concat(addon.name, ". Error: ").concat(err.message));
}
};
for (var _i = 0, _a = Object.values(addon.usageLimits); _i < _a.length; _i++) {
var addonUsageLimit = _a[_i];
_loop_4(addonUsageLimit);
}
return addon.usageLimits;
}
function validateAddonUsageLimitsExtensions(addon, addonUsageLimits) {
var _loop_5 = function (addonUsageLimitExtension) {
try {
if (!Object.values(addonUsageLimits).some(function (l) { return l.name === addonUsageLimitExtension.name; })) {
throw new Error("Usage limit ".concat(addonUsageLimitExtension.name, " is not defined in the global usage limits."));
}
if (!('value' in addonUsageLimitExtension)) {
throw new Error("When declaring a new value for an usage limit or a usage limit extension within an add-on, it must be provided through the 'value' field");
}
addon.usageLimitsExtensions[addonUsageLimitExtension.name].value =
addonUsageLimitExtension.value;
addon.usageLimitsExtensions[addonUsageLimitExtension.name].value = validateValue(addon.usageLimitsExtensions[addonUsageLimitExtension.name], 'usage limit', addonUsageLimits[addonUsageLimitExtension.name].valueType);
}
catch (err) {
throw new Error("Error while parsing the usage limit ".concat(addonUsageLimitExtension.name, " of the add-on ").concat(addon.name, ". Error: ").concat(err.message));
}
};
for (var _i = 0, _a = Object.values(addon.usageLimitsExtensions); _i < _a.length; _i++) {
var addonUsageLimitExtension = _a[_i];
_loop_5(addonUsageLimitExtension);
}
return addon.usageLimitsExtensions;
}
function validateAvailableFor(availableFor, pricing) {
var planNames = pricing.plans ? Object.values(pricing.plans).map(function (p) { return p.name; }) : [];
if (availableFor === null || availableFor === undefined) {
availableFor = planNames;
}
if (!Array.isArray(availableFor)) {
throw new Error("The availableFor field must be an array of the plan names for which the addon can be contracted. Received: ".concat(availableFor));
}
for (var _i = 0, availableFor_1 = availableFor; _i < availableFor_1.length; _i++) {
var planName = availableFor_1[_i];
if (!planNames.includes(planName)) {
throw new Error("The plan ".concat(planName, " is not defined in the pricing."));
}
}
return availableFor;
}
function validateDependsOnOrExcludes(fieldValue, pricing, fieldType) {
var addonNames = pricing.addOns ? Object.values(pricing.addOns).map(function (a) { return a.name; }) : [];
if (fieldValue === null || fieldValue === undefined) {
fieldValue = [];
}
if (!Array.isArray(addonNames)) {
throw new Error("The ".concat(fieldType, " field must be an array of the addons required to contract the addon. Received: ").concat(fieldValue));
}
return fieldValue;
}
function postValidateDependsOnOrExclude(fieldValue, pricing) {
var addonNames = pricing.addOns ? Object.values(pricing.addOns).map(function (a) { return a.name; }) : [];
if (!fieldValue)
return;
for (var _i = 0, fieldValue_1 = fieldValue; _i < fieldValue_1.length; _i++) {
var addonName = fieldValue_1[_i];
if (!addonNames.includes(addonName)) {
throw new Error("The addon ".concat(addonName, " is not defined in the pricing."));
}
}
}
function validateTags(tags) {
if (tags === null || tags === undefined) {
return [];
}
if (!Array.isArray(tags) || tags.some(function (tag) { return typeof tag !== 'string'; })) {
throw new Error("The tags field must be an array of strings.");
}
return tags;
}
function validatePlan(plan) {
if (typeof plan === 'object' && 'features' in plan) {
return;
}
else {
throw new Error("The plan must be an object of type Plan");
}
}
function validatePlans(plans) {
if (!(typeof plans === 'object')) {
throw new Error("The plans field must be a map of Plan objects");
}
}
function validateFeatures(features) {
if (!(typeof features === 'object') || features === null || features === undefined) {
throw new Error("The features field must be a map of Feature objects");
}
}
function validateFeature(feature) {
if (typeof feature === 'object' &&
'type' in feature &&
'valueType' in feature &&
'defaultValue' in feature) {
return;
}
else {
throw new Error("The feature must be an object of type Feature");
}
}
function validateUsageLimits(usageLimits) {
if (!(typeof usageLimits === 'object')) {
throw new Error("The usageLimits field must be a map of UsageLimit objects or undefined");
}
}
function validateUsageLimit(usageLimit) {
if (typeof usageLimit === 'object' &&
'type' in usageLimit &&
'valueType' in usageLimit &&
'defaultValue' in usageLimit) {
return;
}
else {
throw new Error("The usage limit must be an object of type UsageLimit");
}
}
function validateBilling(billing) {
if (billing === undefined || billing === null) {
billing = {
monthly: 1,
};
}
if (!(typeof billing === 'object')) {
throw new Error("The billing field must be an object of type {[key: string]: number}");
}
for (var _i = 0, _a = Object.entries(billing); _i < _a.length; _i++) {
var _b = _a[_i], key = _b[0], value = _b[1];
if (typeof value !== 'number') {
throw new Error("The billing entry for ".concat(key, " must be a number. Received: ").concat(value));
}
if (value <= 0 || value > 1) {
throw new Error("The billing entry for ".concat(key, " must be a value in the range (0,1]. Received: ").concat(value));
}
}
return billing;
}
function validateVariables(variables) {
if (variables === undefined || variables === null) {
variables = {};
}
if (typeof variables !== 'object') {
throw new Error("The billing field must be an object of type {[key: string]: number | string | boolean}");
}
for (var _i = 0, _a = Object.entries(variables); _i < _a.length; _i++) {
var _b = _a[_i], key = _b[0], value = _b[1];
if (typeof value !== 'number' && typeof value !== 'string' && typeof value !== 'boolean') {
throw new Error("The billing entry for ".concat(key, " must be either a number, a string or a boolean. Received: ").concat(value));
}
}
return variables;
}
function validateUrl(url) {
if (url === undefined || url === null) {
url = undefined;
return;
}
if (typeof url !== 'string') {
throw new Error("The url field must be a string. Received: ".concat(url));
}
var urlPattern = /^(https?):\/\/[^\s\/$.?#].[^\s]*$/i;
if (!urlPattern.test(url)) {
throw new Error("The url field must be a valid URL with the http or https protocol. Received: ".concat(url));
}
return url;
}
function validatePrivate(isPrivate) {
if (isPrivate === undefined || isPrivate === null) {
isPrivate = false;
}
if (typeof isPrivate !== 'boolean') {
throw new Error("The private field must be a boolean. Received: ".concat(isPrivate));
}
return isPrivate;
}
function validatePricingUrls(featureType, featureIntegrationType, pricingUrls) {
if (pricingUrls === undefined || pricingUrls === null) {
pricingUrls = undefined;
}
else {
if (!Array.isArray(pricingUrls) || pricingUrls.some(function (url) { return typeof url !== 'string'; })) {
throw new Error("The pricingUrls field must be an array of strings.");
}
for (var _i = 0, pricingUrls_1 = pricingUrls; _i < pricingUrls_1.length; _i++) {
var url = pricingUrls_1[_i];
var urlPattern = /^(https?):\/\/[^\s\/$.?#].[^\s]*$/i;
if (!urlPattern.test(url)) {
throw new Error("The pricingUrls field must contain only valid URLs. Invalid URL: ".concat(url));
}
}
if (featureType !== 'INTEGRATION' || featureIntegrationType !== 'WEB_SAAS') {
console.log("[WARNING] The pricingUrls field is only valid for features of 'type' INTEGRATION and 'integrationType' WEB_SAAS. The field will be ignored.");
pricingUrls = undefined;
}
}
return pricingUrls;
}
function validateDocUrl(featureType, docUrl) {
if (docUrl === undefined || docUrl === null) {
docUrl = undefined;
}
else {
if (typeof docUrl !== 'string') {
throw new Error("The docUrl field must be a string.");
}
var urlPattern = /^(https?):\/\/[^\s\/$.?#].[^\s]*$/i;
if (!urlPattern.test(docUrl)) {
throw new Error("The docUrl field must be a valid URL with the http or https protocol. Received: ".concat(docUrl));
}
if (featureType !== 'GUARANTEE') {
console.log("[WARNING] The docUrl field is only valid for features of 'type' GUARANTEE. The field will be ignored.");
docUrl = undefined;
}
}
return docUrl;
}
function validatePeriodUnit(periodUnit) {
if (periodUnit === undefined || periodUnit === null) {
periodUnit = 'MONTH';
}
if (typeof periodUnit !== 'string') {
throw new Error("The periodUnit field must be one of the following string values: \"SEC\" | \"MIN\" | \"HOUR\" | \"DAY\" | \"MONTH\" | \"YEAR\". Received: ".concat(periodUnit));
}
periodUnit = periodUnit.toUpperCase();
if (!["SEC", "MIN", "HOUR", "DAY", "MONTH", "YEAR"].includes(periodUnit)) {
throw new Error("The periodUnit field must be one of \"SEC\" | \"MIN\" | \"HOUR\" | \"DAY\" | \"MONTH\" | \"YEAR\". Received: ".concat(periodUnit));
}
return periodUnit;
}
function validatePeriodValue(periodValue) {
if (periodValue === undefined || periodValue === null) {
periodValue = 1;
}
if (typeof periodValue !== 'number') {
throw new Error("The periodValue field must be a number. Received: ".concat(periodValue));
}
if (periodValue <= 0) {
throw new Error("The periodValue field must be a positive number. Received: ".concat(periodValue));
}
return periodValue;
}
function validateTrackable(trackable) {
if (trackable === undefined || trackable === null) {
trackable = false;
}
if (typeof trackable === 'string') {
trackable = trackable.toLowerCase() === 'true';
}
if (typeof trackable !== 'boolean') {
throw new Error("The trackable field must be a boolean. Received: ".concat(trackable));
}
return trackable;
}
function validateSubscriptionConstraintMinQuantity(subscriptionConstraintMinQuantity) {
if (subscriptionConstraintMinQuantity === undefined || subscriptionConstraintMinQuantity === null) {
subscriptionConstraintMinQuantity = 1;
}
if (typeof subscriptionConstraintMinQuantity !== 'number') {
throw new Error("The subscriptionConstraintMinQuantity field must be a number. Received: ".concat(subscriptionConstraintMinQuantity));
}
if (subscriptionConstraintMinQuantity < 0) {
throw new Error("The subscriptionConstraintMinQuantity field must be a positive number. Received: ".concat(subscriptionConstraintMinQuantity));
}
return subscriptionConstraintMinQuantity;
}
function validateSubscriptionConstraintMaxQuantity(subscriptionConstraintMaxQuantity, minQuantity) {
if (subscriptionConstraintMaxQuantity === undefined || subscriptionConstraintMaxQuantity === null) {
subscriptionConstraintMaxQuantity = unlimitedValue;
}
if (typeof subscriptionConstraintMaxQuantity !== 'number') {
throw new Error("The subscriptionConstraintMaxQuantity field must be a number. Received: ".concat(subscriptionConstraintMaxQuantity));
}
if (subscriptionConstraintMaxQuantity < minQuantity) {
throw new Error("The subscriptionConstraintMaxQuantity field must be greater than or equal to the min quantity. Received: ".concat(subscriptionConstraintMaxQuantity));
}
return subscriptionConstraintMaxQuantity;
}
function validateSubscriptionConstraintQuantityStep(subscriptionConstraintQuantityStep, minQuantity) {
if (subscriptionConstraintQuantityStep === undefined || subscriptionConstraintQuantityStep === null) {
subscriptionConstraintQuantityStep = 1;
}
if (typeof subscriptionConstraintQuantityStep !== 'number') {
throw new Error("The subscriptionConstraintQuantityStep field must be a number. Received: ".concat(subscriptionConstraintQuantityStep));
}
if (!(minQuantity % subscriptionConstraintQuantityStep === 0)) {
throw new Error("The subscriptionConstraintQuantityStep field must be a divisor of, at least, the min quantity. Received: ".concat(subscriptionConstraintQuantityStep));
}
return subscriptionConstraintQuantityStep;
}