@omniconvert/server-side-testing-sdk
Version:
TypeScript SDK for server-side A/B testing and experimentation
154 lines • 5.82 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Experiment = void 0;
/**
* Experiment entity representing an A/B test configuration
*/
class Experiment {
constructor(data) {
const rawData = data;
this.id = rawData.id;
this.name = rawData.name;
this.type = rawData.type;
this.targetPlatform = rawData.targetPlatform || rawData.target_platform;
this.priority = rawData.priority;
this.visitorsLimit = rawData.visitorsLimit || rawData.visitors_limit || 0;
this.visitorsNow = rawData.visitorsNow || rawData.visitors_now || 0;
this.globalJavascript = rawData.globalJavascript || rawData.global_javascript || '';
this.globalCss = rawData.globalCss || rawData.global_css || '';
this.deviceType = rawData.deviceType || rawData.device_type;
this.traficAllocation = rawData.traficAllocation || rawData.trafic_allocation || 0;
this.exclusive = rawData.exclusive;
this.whereIncluded = rawData.whereIncluded || rawData.where_included || [];
this.whereExcluded = rawData.whereExcluded || rawData.where_excluded || [];
this.whenRestriction = rawData.whenRestriction || rawData.when_restriction || [];
this.whenTimezone = rawData.whenTimezone || rawData.when_timezone || '';
// Handle both camelCase and snake_case date formats
this.whenStart = this.parseDate(rawData.whenStart || rawData.when_start);
this.whenEnd = this.parseDate(rawData.whenEnd || rawData.when_end);
this.slug = rawData.slug;
this.segment = rawData.segment;
this.variations = rawData.variations;
this.clicks = rawData.clicks || [];
this.trackEngagement = rawData.trackEngagement || rawData.track_engagement || false;
this.trackBounce = rawData.trackBounce || rawData.track_bounce || false;
this.goalTimeout = rawData.goalTimeout || rawData.goal_timeout || 0;
}
/**
* Get a variation by its key
*/
getVariation(variationKey) {
return Object.values(this.variations).find(variation => variation.slug === variationKey);
}
/**
* Get a variation by its ID
*/
getVariationById(variationId) {
return this.variations[variationId];
}
/**
* Get all variation keys
*/
getVariationKeys() {
return Object.values(this.variations).map(variation => variation.slug);
}
/**
* Get all variation IDs
*/
getVariationIds() {
return Object.keys(this.variations);
}
/**
* Check if the experiment is currently active based on timing
*/
isActive(currentTime = new Date()) {
// If no start date, assume it has started
const hasStarted = !this.whenStart || currentTime >= this.whenStart;
// If no end date, assume it hasn't ended
const hasNotEnded = !this.whenEnd || currentTime <= this.whenEnd;
return hasStarted && hasNotEnded;
}
/**
* Check if the experiment has variations
*/
hasVariations() {
return Object.keys(this.variations).length > 0;
}
/**
* Calculate total traffic allocation across all variations
*/
getTotalVariationAllocation() {
return Object.values(this.variations).reduce((total, variation) => total + (variation.traffic_allocation || 0), 0);
}
/**
* Convert to plain object for serialization
*/
toObject() {
return {
id: this.id,
name: this.name,
type: this.type,
targetPlatform: this.targetPlatform,
priority: this.priority,
visitorsLimit: this.visitorsLimit,
visitorsNow: this.visitorsNow,
globalJavascript: this.globalJavascript,
globalCss: this.globalCss,
deviceType: this.deviceType,
traficAllocation: this.traficAllocation,
exclusive: this.exclusive,
whereIncluded: this.whereIncluded,
whereExcluded: this.whereExcluded,
whenRestriction: this.whenRestriction,
whenTimezone: this.whenTimezone,
whenStart: this.whenStart ? this.whenStart.toISOString() : '',
whenEnd: this.whenEnd ? this.whenEnd.toISOString() : '',
slug: this.slug,
segment: this.segment,
variations: this.variations,
clicks: this.clicks,
trackEngagement: this.trackEngagement,
trackBounce: this.trackBounce,
goalTimeout: this.goalTimeout,
};
}
/**
* Create experiment from plain object
*/
static fromObject(obj) {
return new Experiment(obj);
}
/**
* Convert to JSON
*/
toJSON() {
return this.toObject();
}
/**
* Parse date string from API format to Date object
* Handles format: "2025-04-23 00:00:01" -> valid Date
* Returns null if no date string is provided
*/
parseDate(dateString) {
if (!dateString) {
return null;
}
// Convert "2025-04-23 00:00:01" to "2025-04-23T00:00:01" (ISO format)
const isoString = dateString.replace(' ', 'T');
const date = new Date(isoString);
// Check if the date is valid
if (isNaN(date.getTime())) {
console.warn(`Invalid date format: "${dateString}", returning null`);
return null;
}
return date;
}
}
exports.Experiment = Experiment;
Experiment.DEVICE_TYPE_MOBILE = 'mobile';
Experiment.DEVICE_TYPE_DESKTOP = 'desktop';
Experiment.DEVICE_TYPE_TABLET = 'tablet';
Experiment.DEVICE_TYPE_ALL = 'all';
Experiment.PLATFORM_SERVER_SIDE = 'server_side';
Experiment.PLATFORM_MOBILE = 'mobile';
//# sourceMappingURL=Experiment.js.map