UNPKG

@omniconvert/server-side-testing-sdk

Version:

TypeScript SDK for server-side A/B testing and experimentation

154 lines 5.82 kB
"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