vwo-fme-node-sdk
Version:
VWO Node/JavaScript SDK for Feature Management and Experimentation
176 lines (161 loc) • 6.49 kB
text/typescript
/**
* Copyright 2024-2025 Wingify Software Pvt. Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { CampaignTypeEnum } from '../enums/CampaignTypeEnum';
import { CampaignModel } from '../models/campaign/CampaignModel';
import { FeatureModel } from '../models/campaign/FeatureModel';
import { SettingsModel } from '../models/settings/SettingsModel';
import { dynamic } from '../types/Common';
import { isString } from './DataTypeUtil';
/**
* Clones an object deeply.
* @param {dynamic} obj - The object to clone.
* @returns {any} The cloned object.
*/
export function cloneObject(obj: dynamic): any {
if (!obj) {
// Return the original object if it is null or undefined
return obj;
}
// Use JSON stringify and parse method to perform a deep clone
const clonedObj = JSON.parse(JSON.stringify(obj));
return clonedObj;
}
/**
* Gets the current time in ISO string format.
* @returns {string} The current time in ISO string format.
*/
export function getCurrentTime(): string {
return new Date().toISOString();
}
/**
* Gets the current Unix timestamp in seconds.
* @returns {number} The current Unix timestamp.
*/
export function getCurrentUnixTimestamp(): number {
// Convert the current date to Unix timestamp in seconds
return Math.ceil(+new Date() / 1000);
}
/**
* Gets the current Unix timestamp in milliseconds.
* @returns {number} The current Unix timestamp in milliseconds.
*/
export function getCurrentUnixTimestampInMillis(): number {
// Convert the current date to Unix timestamp in milliseconds
return +new Date();
}
/**
* Generates a random number between 0 and 1.
* @returns {number} A random number.
*/
export function getRandomNumber(): number {
// Use Math.random to generate a random number
return Math.random();
}
/**
* Retrieves specific rules based on the type from a feature.
* @param {FeatureModel} feature - The key of the feature.
* @param {CampaignTypeEnum | null} type - The type of the rules to retrieve.
* @returns {Array} An array of rules that match the type.
*/
export function getSpecificRulesBasedOnType(feature: FeatureModel, type: CampaignTypeEnum = null) {
// Return an empty array if no linked campaigns are found
if (feature && !feature?.getRulesLinkedCampaign()) {
return [];
}
// Filter the rules by type if a type is specified and is a string
if (feature && feature.getRulesLinkedCampaign() && type && isString(type)) {
return feature.getRulesLinkedCampaign().filter((rule) => {
const ruleModel = new CampaignModel().modelFromDictionary(rule);
return ruleModel.getType() === type;
});
}
// Return all linked campaigns if no type is specified
return feature.getRulesLinkedCampaign();
}
/**
* Retrieves all AB and Personalize rules from a feature.
* @param {any} settings - The settings containing features.
* @param {string} featureKey - The key of the feature.
* @returns {Array} An array of AB and Personalize rules.
*/
export function getAllExperimentRules(feature: FeatureModel) {
// Retrieve the feature by its key
// Filter the rules to include only AB and Personalize types
return (
feature
?.getRulesLinkedCampaign()
.filter((rule) => rule.getType() === CampaignTypeEnum.AB || rule.getType() === CampaignTypeEnum.PERSONALIZE) || []
);
}
/**
* Retrieves a feature by its key from the settings.
* @param {any} settings - The settings containing features.
* @param {string} featureKey - The key of the feature to find.
* @returns {any} The feature if found, otherwise undefined.
*/
export function getFeatureFromKey(settings: SettingsModel, featureKey: string) {
// Find the feature by its key
return settings?.getFeatures()?.find((feature) => feature.getKey() === featureKey);
}
/**
* Checks if an event exists within any feature's metrics.
* @param {string} eventName - The name of the event to check.
* @param {any} settings - The settings containing features.
* @returns {boolean} True if the event exists, otherwise false.
*/
export function doesEventBelongToAnyFeature(eventName: string, settings: SettingsModel): boolean {
// Use the `some` method to check if any feature contains the event in its metrics
return settings
.getFeatures()
.some((feature) => feature.getMetrics().some((metric) => metric.getIdentifier() === eventName));
}
/**
* Adds linked campaigns to each feature in the settings based on rules.
* @param {any} settings - The settings file to modify.
*/
export function addLinkedCampaignsToSettings(settings: SettingsModel): void {
// Create maps for quick access to campaigns and variations
const campaignMap = new Map<number, CampaignModel>(
settings.getCampaigns().map((campaign) => [campaign.getId(), campaign]),
);
// Loop over all features
for (const feature of settings.getFeatures()) {
const rulesLinkedCampaign = feature
.getRules()
.map((rule) => {
const campaign: CampaignModel = campaignMap.get(rule.getCampaignId());
if (!campaign) return null;
// Create a linked campaign object with the rule and campaign
const linkedCampaign: any = { key: campaign.getKey(), ...campaign, ruleKey: rule.getRuleKey() };
// If a variationId is specified, find and add the variation
if (rule.getVariationId()) {
const variation = campaign.getVariations().find((v) => v.getId() === rule.getVariationId());
if (variation) {
linkedCampaign.variations = [variation];
}
}
return linkedCampaign;
})
.filter((campaign) => campaign !== null); // Filter out any null entries
const rulesLinkedCampaignModel = rulesLinkedCampaign.map((campaign) => {
const campaignModel = new CampaignModel();
campaignModel.modelFromDictionary(campaign);
return campaignModel;
});
// Assign the linked campaigns to the feature
feature.setRulesLinkedCampaign(rulesLinkedCampaignModel);
}
}