@vizbeetv/homesso-sdk-qa 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/es6/index.cjs ADDED
@@ -0,0 +1,1722 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ /******************************************************************************
6
+ Copyright (c) Microsoft Corporation.
7
+
8
+ Permission to use, copy, modify, and/or distribute this software for any
9
+ purpose with or without fee is hereby granted.
10
+
11
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
12
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13
+ AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
14
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
16
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17
+ PERFORMANCE OF THIS SOFTWARE.
18
+ ***************************************************************************** */
19
+
20
+ function __awaiter(thisArg, _arguments, P, generator) {
21
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
22
+ return new (P || (P = Promise))(function (resolve, reject) {
23
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
24
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
25
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
26
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
27
+ });
28
+ }
29
+
30
+ typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
31
+ var e = new Error(message);
32
+ return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
33
+ };
34
+
35
+ /**
36
+ * @const VizbeeConstants
37
+ * @description Metrics Constants used throughout the Vizbee Home SSO implementation
38
+ */
39
+ const VizbeeMetricsConstants = {
40
+ // Events
41
+ METRICS_EVENT_SCREEN_HOMESSO_SIGNIN_RECEIVED: 'SCREEN_HOMESSO_SIGNIN_RECEIVED',
42
+ METRICS_EVENT_SCREEN_HOMESSO_SIGNIN_STATUS: 'SCREEN_HOMESSO_SIGNIN_STATUS',
43
+ // Attributes
44
+ METRICS_ATTR_SCREEN_HOMESSO_SDK_VERSION: 'SCREEN_HOMESSO_SDK_VERSION',
45
+ METRICS_ATTR_IS_SCREEN_SIGNED_IN: 'IS_SCREEN_SIGNED_IN',
46
+ METRICS_ATTR_IS_REMOTE_SIGNED_IN: 'IS_REMOTE_SIGNED_IN',
47
+ METRICS_ATTR_IS_SCREEN_SIGN_IN_STATUS: 'SCREEN_SIGN_IN_STATUS',
48
+ METRICS_ATTR_SCREEN_HOMESSO_USER_ID: 'SCREEN_HOMESSO_USER_ID',
49
+ METRICS_ATTR_SCREEN_HOMESSO_USER_INFO: 'SCREEN_HOMESSO_USER_INFO',
50
+ METRICS_ATTR_HOMESSO_SIGN_IN_TYPE: 'HOMESSO_SIGN_IN_TYPE',
51
+ METRICS_ATTR_REMOTE_DEVICE_ID: 'REMOTE_DEVICE_ID',
52
+ METRICS_ATTR_REMOTE_DEVICE_TYPE: 'REMOTE_DEVICE_TYPE',
53
+ METRICS_ATTR_REMOTE_FRIENDLY_NAME: 'REMOTE_FRIENDLY_NAME',
54
+ METRICS_ATTR_REMOTE_NETWORK_SESSION_ID: 'REMOTE_NETWORK_SESSION_ID',
55
+ METRICS_ATTR_USER_LOGIN_TYPE: 'user_login_type',
56
+ METRICS_ATTR_USER_IS_SIGNED_IN: 'user_is_signed_in',
57
+ METRICS_ATTR_USER_LOGIN: 'user_login',
58
+ METRICS_ATTR_USER_NAME: 'user_name',
59
+ METRICS_ATTR_USER_SUBSCRIPTION_TYPE: 'user_subscription_type',
60
+ METRICS_ATTR_USER_SUBSCRIPTION_VALUE: 'user_subscription_value',
61
+ METRICS_ATTR_USER_SUBSCRIPTION_RENEWAL_TYPE: 'user_subscription_renewal_type',
62
+ METRICS_ATTR_USER_ADDITIONAL_INFO: 'user_additional_info',
63
+ };
64
+
65
+ /**
66
+ * Logger
67
+ * A flexible logging system for TypeScript SDK with
68
+ * enable/disable capabilities and different log levels.
69
+ *
70
+ * Features:
71
+ * - Multiple severity levels from ERROR to TRACE
72
+ * - Colored console output with timestamps
73
+ * - Local storage persistence with size management
74
+ * - Environment-aware execution (handles environments without localStorage)
75
+ * - Export and clearing capabilities
76
+ */
77
+ /**
78
+ * Defines logging severity levels in ascending order of verbosity.
79
+ * Lower values indicate higher severity. This hierarchy ensures
80
+ * that when a specific level is set, all logs of that level and
81
+ * higher severity (lower enum value) will be captured.
82
+ */
83
+ exports.LogLevel = void 0;
84
+ (function (LogLevel) {
85
+ /** Critical application errors that prevent proper functioning */
86
+ LogLevel[LogLevel["ERROR"] = 0] = "ERROR";
87
+ /** Important issues that don't stop execution but require attention */
88
+ LogLevel[LogLevel["WARN"] = 1] = "WARN";
89
+ /** General operational information about system behavior */
90
+ LogLevel[LogLevel["INFO"] = 2] = "INFO";
91
+ /** Detailed diagnostic information for troubleshooting */
92
+ LogLevel[LogLevel["DEBUG"] = 3] = "DEBUG";
93
+ /** Extremely verbose execution flow information */
94
+ LogLevel[LogLevel["TRACE"] = 4] = "TRACE";
95
+ })(exports.LogLevel || (exports.LogLevel = {}));
96
+ /**
97
+ * Default configuration applied when creating a new logger
98
+ * without explicit settings. These values can be overridden
99
+ * through the constructor or setConfig method.
100
+ */
101
+ const DEFAULT_CONFIG = {
102
+ enabled: false,
103
+ level: exports.LogLevel.ERROR,
104
+ useTimestamp: true,
105
+ useColors: true,
106
+ logToConsole: true,
107
+ logToStorage: false,
108
+ maxStorageLogs: 1000,
109
+ };
110
+ /**
111
+ * Core logger implementation that provides multiple severity levels,
112
+ * configurable outputs, and flexible message formatting.
113
+ *
114
+ * The logger handles both console output and storage persistence,
115
+ * with environment detection to gracefully handle different contexts.
116
+ */
117
+ class Logger {
118
+ /**
119
+ * Creates a new logger instance with optional custom configuration.
120
+ * The provided configuration is merged with default settings.
121
+ *
122
+ * @param config - Partial configuration to override default values
123
+ */
124
+ constructor(config = {}) {
125
+ /**
126
+ * Storage key used for persisting logs in localStorage.
127
+ * Prefixed with 'vizbee_homesso_' to avoid collisions.
128
+ */
129
+ this.storageKey = 'vizbee_homesso_logs';
130
+ this.config = Object.assign(Object.assign({}, DEFAULT_CONFIG), config);
131
+ // Initialize storage if enabled in the configuration
132
+ if (this.config.logToStorage) {
133
+ this.initializeStorage();
134
+ }
135
+ }
136
+ /**
137
+ * Enables or disables all logging functionality.
138
+ * When disabled, no logs will be output regardless of level.
139
+ *
140
+ * @param enabled - Whether logging should be active (defaults to true)
141
+ */
142
+ enable(enabled = true) {
143
+ this.config.enabled = enabled;
144
+ this.info(`Logger ${enabled ? 'enabled' : 'disabled'}`);
145
+ }
146
+ /**
147
+ * Sets the minimum severity level for capturing logs.
148
+ * Only logs at this level and more severe levels will be processed.
149
+ *
150
+ * @param level - The minimum LogLevel to capture
151
+ */
152
+ setLevel(level) {
153
+ this.config.level = level;
154
+ this.info(`Log level set to ${exports.LogLevel[level]}`);
155
+ }
156
+ /**
157
+ * Returns a copy of the current logger configuration.
158
+ * Returns a new object to prevent accidental modification.
159
+ *
160
+ * @returns The complete current configuration
161
+ */
162
+ getConfig() {
163
+ return Object.assign({}, this.config);
164
+ }
165
+ /**
166
+ * Updates logger configuration with new settings.
167
+ * Merges the provided settings with the existing configuration.
168
+ *
169
+ * @param config - Partial configuration to apply
170
+ */
171
+ setConfig(config) {
172
+ // Store current storage setting to detect changes
173
+ const wasStorageEnabled = this.config.logToStorage;
174
+ // Update configuration by merging with existing settings
175
+ this.config = Object.assign(Object.assign({}, this.config), config);
176
+ // Initialize storage if it was just enabled
177
+ if (!wasStorageEnabled && this.config.logToStorage) {
178
+ this.initializeStorage();
179
+ }
180
+ this.info('Logger configuration updated');
181
+ }
182
+ /**
183
+ * Logs an error message (highest severity).
184
+ * Use for critical failures that prevent proper operation.
185
+ *
186
+ * @param message - The error message to log
187
+ * @param data - Optional supplementary information
188
+ */
189
+ error(message, ...data) {
190
+ this.log(exports.LogLevel.ERROR, message, data);
191
+ }
192
+ /**
193
+ * Logs a warning message.
194
+ * Use for potential issues that don't stop execution.
195
+ *
196
+ * @param message - The warning message to log
197
+ * @param data - Optional supplementary information
198
+ */
199
+ warn(message, ...data) {
200
+ this.log(exports.LogLevel.WARN, message, data);
201
+ }
202
+ /**
203
+ * Logs an informational message.
204
+ * Use for general application state and noteworthy events.
205
+ *
206
+ * @param message - The info message to log
207
+ * @param data - Optional supplementary information
208
+ */
209
+ info(message, ...data) {
210
+ this.log(exports.LogLevel.INFO, message, data);
211
+ }
212
+ /**
213
+ * Logs a debug message.
214
+ * Use for detailed information helpful during development.
215
+ *
216
+ * @param message - The debug message to log
217
+ * @param data - Optional supplementary information
218
+ */
219
+ debug(message, ...data) {
220
+ this.log(exports.LogLevel.DEBUG, message, data);
221
+ }
222
+ /**
223
+ * Logs a trace message (lowest severity/highest verbosity).
224
+ * Use for extremely detailed execution path tracking.
225
+ *
226
+ * @param message - The trace message to log
227
+ * @param data - Optional supplementary information
228
+ */
229
+ trace(message, ...data) {
230
+ this.log(exports.LogLevel.TRACE, message, data);
231
+ }
232
+ /**
233
+ * Core logging method that handles level filtering and message routing.
234
+ * Formats the message and sends it to appropriate outputs based on configuration.
235
+ *
236
+ * @param level - Log severity level
237
+ * @param message - The message to log
238
+ * @param data - Additional data to include with the log
239
+ */
240
+ log(level, message, data = []) {
241
+ // Early return if logging is disabled or level is too verbose
242
+ if (!this.config.enabled || level > this.config.level) {
243
+ return;
244
+ }
245
+ // Format components based on configuration
246
+ const timestamp = this.config.useTimestamp
247
+ ? `[${new Date().toISOString()}]`
248
+ : '';
249
+ const levelName = `[${exports.LogLevel[level]}]`;
250
+ // Create the formatted message with application prefix
251
+ const formattedMessage = `${timestamp}[VizbeeHomeSSO]${levelName}: ${message}`;
252
+ // Send to appropriate outputs based on configuration
253
+ if (this.config.logToConsole) {
254
+ this.logToConsole(level, formattedMessage, data);
255
+ }
256
+ if (this.config.logToStorage) {
257
+ this.logToStorage(formattedMessage, data);
258
+ }
259
+ }
260
+ /**
261
+ * Handles console output with optional color styling.
262
+ * Applies different colors based on log level for better readability.
263
+ *
264
+ * @param level - Log severity level
265
+ * @param message - Formatted message to output
266
+ * @param data - Additional data to log
267
+ */
268
+ logToConsole(level, message, data) {
269
+ const hasData = data && data.length > 0;
270
+ // Apply color styling if enabled
271
+ if (this.config.useColors) {
272
+ const styles = this.getConsoleStyles(level);
273
+ if (hasData) {
274
+ console.log(`%c${message}`, styles, ...data);
275
+ }
276
+ else {
277
+ console.log(`%c${message}`, styles);
278
+ }
279
+ }
280
+ else {
281
+ // Plain output without colors
282
+ if (hasData) {
283
+ console.log(message, ...data);
284
+ }
285
+ else {
286
+ console.log(message);
287
+ }
288
+ }
289
+ }
290
+ /**
291
+ * Determines CSS styling for console output based on log level.
292
+ * Returns different colors to visually distinguish log levels.
293
+ *
294
+ * @param level - Log severity level
295
+ * @returns CSS style string for console output
296
+ */
297
+ getConsoleStyles(level) {
298
+ switch (level) {
299
+ case exports.LogLevel.ERROR:
300
+ return 'color: #FF5252; font-weight: bold'; // Bright red, bold
301
+ case exports.LogLevel.WARN:
302
+ return 'color: #FFC107; font-weight: bold'; // Amber, bold
303
+ case exports.LogLevel.INFO:
304
+ return 'color: #2196F3'; // Blue
305
+ case exports.LogLevel.DEBUG:
306
+ return 'color: #4CAF50'; // Green
307
+ case exports.LogLevel.TRACE:
308
+ return 'color: #9E9E9E'; // Gray
309
+ default:
310
+ return '';
311
+ }
312
+ }
313
+ /**
314
+ * Sets up localStorage for persisting logs if available.
315
+ * Creates the initial empty logs array if not already present.
316
+ * Gracefully handles environments without localStorage access.
317
+ */
318
+ initializeStorage() {
319
+ try {
320
+ // Verify localStorage is available in this environment
321
+ if (typeof localStorage !== 'undefined') {
322
+ // Create empty logs array if not already initialized
323
+ if (!localStorage.getItem(this.storageKey)) {
324
+ localStorage.setItem(this.storageKey, JSON.stringify([]));
325
+ }
326
+ }
327
+ }
328
+ catch (error) {
329
+ // Handle environments where localStorage is not available or blocked
330
+ console.warn('localStorage not available for logging', error);
331
+ this.config.logToStorage = false;
332
+ }
333
+ }
334
+ /**
335
+ * Persists a log entry to localStorage with rotation management.
336
+ * Removes oldest entries when the maximum count is exceeded.
337
+ * Handles storage errors gracefully.
338
+ *
339
+ * @param message - Formatted message to store
340
+ * @param data - Additional data to include
341
+ */
342
+ logToStorage(message, data) {
343
+ try {
344
+ if (typeof localStorage !== 'undefined') {
345
+ // Retrieve current logs
346
+ const logs = JSON.parse(localStorage.getItem(this.storageKey) || '[]');
347
+ // Add new log entry
348
+ logs.push({
349
+ timestamp: new Date().toISOString(),
350
+ message,
351
+ data: data.length > 0 ? JSON.stringify(data) : undefined,
352
+ });
353
+ // Apply size limit by removing oldest logs if needed
354
+ if (logs.length > (this.config.maxStorageLogs || 1000)) {
355
+ logs.shift(); // Remove oldest log
356
+ }
357
+ // Save updated logs back to storage
358
+ localStorage.setItem(this.storageKey, JSON.stringify(logs));
359
+ }
360
+ }
361
+ catch (error) {
362
+ console.error('Failed to write logs to storage', error);
363
+ }
364
+ }
365
+ /**
366
+ * Exports all stored logs as a JSON string.
367
+ * Returns an empty array string if storage is unavailable.
368
+ *
369
+ * @returns JSON string containing all stored logs
370
+ */
371
+ exportLogs() {
372
+ try {
373
+ if (typeof localStorage !== 'undefined') {
374
+ const logs = localStorage.getItem(this.storageKey) || '[]';
375
+ return logs;
376
+ }
377
+ }
378
+ catch (error) {
379
+ console.error('Failed to export logs', error);
380
+ }
381
+ return '[]';
382
+ }
383
+ /**
384
+ * Clears all logs from storage.
385
+ * Replaces the current logs with an empty array.
386
+ */
387
+ clearLogs() {
388
+ try {
389
+ if (typeof localStorage !== 'undefined') {
390
+ localStorage.setItem(this.storageKey, JSON.stringify([]));
391
+ this.info('Logs cleared from storage');
392
+ }
393
+ }
394
+ catch (error) {
395
+ console.error('Failed to clear logs', error);
396
+ }
397
+ }
398
+ }
399
+ /**
400
+ * Default singleton logger instance with standard configuration.
401
+ * Available as a ready-to-use logger throughout the application.
402
+ * For custom configurations, create additional Logger instances.
403
+ */
404
+ const logger = new Logger();
405
+
406
+ const LOG_TAG$1 = 'VizbeeHomeSSOManager';
407
+ /* eslint-disable @typescript-eslint/no-explicit-any */
408
+ class VizbeeMetricsManager {
409
+ constructor() {
410
+ var _a, _b, _c;
411
+ this.senderInfo = null;
412
+ this.getSignInInfo = () => __awaiter(this, void 0, void 0, function* () { return []; });
413
+ if ((_c = (_b = (_a = window === null || window === void 0 ? void 0 : window.vizbee) === null || _a === void 0 ? void 0 : _a.continuity) === null || _b === void 0 ? void 0 : _b.analytics) === null || _c === void 0 ? void 0 : _c.AnalyticsProvider) {
414
+ this.metricsManager =
415
+ new window.vizbee.continuity.analytics.AnalyticsProvider();
416
+ // Create a wrapper with 'provider' property
417
+ const attributesProvider = {
418
+ getAttributes: () => this.getAttributes(),
419
+ };
420
+ this.metricsManager.addProvider(attributesProvider, '.*');
421
+ }
422
+ }
423
+ log(event, attributes, bypassAttributeProviders = false) {
424
+ if (!this.metricsManager) {
425
+ return;
426
+ }
427
+ logger.debug(`[${LOG_TAG$1}][log] - Logging metrics event: `, event, attributes, bypassAttributeProviders);
428
+ if (event ===
429
+ VizbeeMetricsConstants.METRICS_EVENT_SCREEN_HOMESSO_SIGNIN_RECEIVED) {
430
+ this.senderInfo = attributes.senderInfo;
431
+ }
432
+ const attributesToBeSent = this.addDefaultAttributes();
433
+ attributesToBeSent[VizbeeMetricsConstants.METRICS_ATTR_IS_SCREEN_SIGNED_IN] = attributes.isScreenSignedIn;
434
+ attributesToBeSent[VizbeeMetricsConstants.METRICS_ATTR_IS_REMOTE_SIGNED_IN] = attributes.isRemoteSignedIn;
435
+ attributesToBeSent[VizbeeMetricsConstants.METRICS_ATTR_HOMESSO_SIGN_IN_TYPE] = attributes.signInType;
436
+ attributesToBeSent[VizbeeMetricsConstants.METRICS_ATTR_IS_SCREEN_SIGN_IN_STATUS] = attributes.signInState;
437
+ if (attributes.userId) {
438
+ attributesToBeSent[VizbeeMetricsConstants.METRICS_ATTR_SCREEN_HOMESSO_USER_ID] = attributes.userId;
439
+ }
440
+ logger.debug(`[${LOG_TAG$1}][log] - Logging metrics event: `, event, attributesToBeSent);
441
+ this.metricsManager.logMetrics(event, attributesToBeSent);
442
+ }
443
+ setCustomAttributes(customAttributes) {
444
+ this.metricsManager.setCustomAttributes(customAttributes);
445
+ }
446
+ getAttributes() {
447
+ return this.createAttributesJson();
448
+ }
449
+ createAttributesJson() {
450
+ return __awaiter(this, void 0, void 0, function* () {
451
+ const attributes = {};
452
+ const userInfoArray = [];
453
+ const signInInfoList = yield this.getSignInInfo();
454
+ signInInfoList === null || signInInfoList === void 0 ? void 0 : signInInfoList.forEach((signInInfo) => {
455
+ const userInfoObject = this.createUserInfoObject(signInInfo);
456
+ userInfoArray.push(userInfoObject);
457
+ });
458
+ attributes[VizbeeMetricsConstants.METRICS_ATTR_SCREEN_HOMESSO_USER_INFO] =
459
+ userInfoArray;
460
+ return attributes;
461
+ });
462
+ }
463
+ createUserInfoObject(signInInfo) {
464
+ const UNKNOWN_VALUE = 'UNKNOWN';
465
+ const userInfo = {
466
+ [VizbeeMetricsConstants.METRICS_ATTR_USER_LOGIN_TYPE]: signInInfo.userLoginType,
467
+ [VizbeeMetricsConstants.METRICS_ATTR_USER_IS_SIGNED_IN]: signInInfo.isSignedIn,
468
+ [VizbeeMetricsConstants.METRICS_ATTR_USER_LOGIN]: signInInfo.userLogin || UNKNOWN_VALUE,
469
+ [VizbeeMetricsConstants.METRICS_ATTR_USER_NAME]: signInInfo.userName || UNKNOWN_VALUE,
470
+ [VizbeeMetricsConstants.METRICS_ATTR_USER_SUBSCRIPTION_TYPE]: signInInfo.userSubscriptionType || UNKNOWN_VALUE,
471
+ [VizbeeMetricsConstants.METRICS_ATTR_USER_SUBSCRIPTION_VALUE]: signInInfo.userSubscriptionValue || UNKNOWN_VALUE,
472
+ [VizbeeMetricsConstants.METRICS_ATTR_USER_SUBSCRIPTION_RENEWAL_TYPE]: signInInfo.userSubscriptionRenewalType || UNKNOWN_VALUE,
473
+ };
474
+ if (signInInfo.userAdditionalInfo) {
475
+ userInfo[VizbeeMetricsConstants.METRICS_ATTR_USER_ADDITIONAL_INFO] =
476
+ signInInfo.userAdditionalInfo || {};
477
+ }
478
+ return userInfo;
479
+ }
480
+ addDefaultAttributes() {
481
+ var _a, _b, _c, _d;
482
+ const attributes = {};
483
+ attributes[VizbeeMetricsConstants.METRICS_ATTR_SCREEN_HOMESSO_SDK_VERSION] =
484
+ '1.0.1';
485
+ attributes['REMOTE_FRIENDLY_NAME'] = (_a = this.senderInfo) === null || _a === void 0 ? void 0 : _a.friendlyName;
486
+ attributes['REMOTE_DEVICE_ID'] = (_b = this.senderInfo) === null || _b === void 0 ? void 0 : _b.deviceId;
487
+ attributes['REMOTE_DEVICE_TYPE'] = (_c = this.senderInfo) === null || _c === void 0 ? void 0 : _c.deviceType;
488
+ attributes['REMOTE_NETWORK_SESSION_ID'] = (_d = this.senderInfo) === null || _d === void 0 ? void 0 : _d.networkSessionId;
489
+ return attributes;
490
+ }
491
+ }
492
+
493
+ /**
494
+ * @const VizbeeConstants
495
+ * @description Constants used throughout the Vizbee Home SSO implementation
496
+ */
497
+ const VizbeeConstants = {
498
+ EVENT_SSO_NAME: 'tv.vizbee.homesso.signin',
499
+ // Sign in event keys
500
+ KEY_SUB_TYPE: 'sub_type',
501
+ KEY_SIGN_IN_STATUS: 'sstatus',
502
+ KEY_STATE: 'sstate',
503
+ KEY_CUSTOM_DATA: 'custom_data',
504
+ KEY_REG_CODE: 'regcode',
505
+ // Custom metadata keys
506
+ KEY_START_SIGN_IN_INFO: 'sinfo',
507
+ KEY_IS_SIGNED_IN: 'is_signed_in',
508
+ KEY_SIGN_IN_TYPE: 'stype',
509
+ KEY_DEVICE_MODEL: 'device_model',
510
+ KEY_DEVICE_OS: 'device_os',
511
+ // Event subtypes
512
+ EVENT_SUBTYPE_START_SIGN_IN: 'start_sign_in',
513
+ EVENT_SUBTYPE_SIGN_IN_STATUS: 'sign_in_status',
514
+ // SDK events types
515
+ VIZBEE_SESSION_READY: 'vizbee-bicast-session-ready',
516
+ };
517
+ // Enum for sign in states
518
+ var VizbeeSignInState;
519
+ (function (VizbeeSignInState) {
520
+ VizbeeSignInState["SIGN_IN_NOT_STARTED"] = "not_started";
521
+ VizbeeSignInState["SIGN_IN_IN_PROGRESS"] = "in_progress";
522
+ VizbeeSignInState["SIGN_IN_COMPLETED"] = "completed";
523
+ VizbeeSignInState["SIGN_IN_FAILED"] = "failed";
524
+ VizbeeSignInState["SIGN_IN_CANCELLED"] = "cancelled";
525
+ })(VizbeeSignInState || (VizbeeSignInState = {}));
526
+
527
+ /* eslint-disable @typescript-eslint/no-explicit-any */
528
+ // Base abstract class for sign in status
529
+ class VizbeeSignInStatus {
530
+ constructor(signInType, customData) {
531
+ this.signInType = signInType;
532
+ this.customData = customData;
533
+ }
534
+ serialize() {
535
+ return {
536
+ [VizbeeConstants.KEY_SIGN_IN_TYPE]: this.signInType,
537
+ [VizbeeConstants.KEY_STATE]: this.getState(),
538
+ [VizbeeConstants.KEY_CUSTOM_DATA]: this.customData,
539
+ };
540
+ }
541
+ }
542
+ // Progress status class
543
+ class ProgressStatus extends VizbeeSignInStatus {
544
+ constructor(signInType, customData = null) {
545
+ super(signInType, customData);
546
+ this.signInType = signInType;
547
+ this.customData = customData;
548
+ }
549
+ getState() {
550
+ return VizbeeSignInState.SIGN_IN_IN_PROGRESS;
551
+ }
552
+ }
553
+ // Success status class
554
+ class SuccessStatus extends VizbeeSignInStatus {
555
+ constructor(signInType, userId = null, customData = null) {
556
+ super(signInType, customData);
557
+ this.signInType = signInType;
558
+ this.userId = userId;
559
+ this.customData = customData;
560
+ }
561
+ getState() {
562
+ return VizbeeSignInState.SIGN_IN_COMPLETED;
563
+ }
564
+ }
565
+ // Failure status class
566
+ class FailureStatus extends VizbeeSignInStatus {
567
+ constructor(signInType, isCancelled, reason = null, exception = null, customData = null) {
568
+ super(signInType, customData);
569
+ this.signInType = signInType;
570
+ this.isCancelled = isCancelled;
571
+ this.reason = reason;
572
+ this.exception = exception;
573
+ this.customData = customData;
574
+ }
575
+ getState() {
576
+ return this.isCancelled
577
+ ? VizbeeSignInState.SIGN_IN_CANCELLED
578
+ : VizbeeSignInState.SIGN_IN_FAILED;
579
+ }
580
+ }
581
+
582
+ /**
583
+ * @fileoverview Configuration and type definitions for Vizbee Home SSO UI components
584
+ * Defines interfaces and default configurations for various modal states and themes
585
+ */
586
+ /**
587
+ * Enum defining the different types of sign-in modals available in the system
588
+ */
589
+ var SignInModalType;
590
+ (function (SignInModalType) {
591
+ SignInModalType["INFORMATION"] = "information";
592
+ SignInModalType["PROGRESS"] = "progress";
593
+ SignInModalType["SUCCESS"] = "success";
594
+ })(SignInModalType || (SignInModalType = {}));
595
+ /**
596
+ * Default theme configuration with basic color scheme
597
+ */
598
+ const defaultTheme = {
599
+ primaryColor: '#000000',
600
+ secondaryColor: '#262626',
601
+ tertiaryColor: '#FFFFFF',
602
+ subTextColor: undefined,
603
+ primaryFont: undefined,
604
+ secondaryFont: undefined,
605
+ direction: 'ltr',
606
+ };
607
+ /**
608
+ * Collection of Base64 encoded icon images used in different modal states
609
+ */
610
+ const icons = {
611
+ vzb_unconnected: `data:image/png;base64,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`,
612
+ vzb_connection_progress_0: `data:image/png;base64,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`,
613
+ vzb_connection_progress_1: `data:image/png;base64,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`,
614
+ vzb_connection_progress_2: `data:image/png;base64,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`,
615
+ vzb_connected: `data:image/png;base64,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`,
616
+ };
617
+ /**
618
+ * Default configuration for informational sign-in modal
619
+ * Shown when initial sign-in process starts
620
+ */
621
+ const defaultInformationalModalConfig = {
622
+ enable: true,
623
+ options: {
624
+ width: undefined,
625
+ backgroundColor: undefined,
626
+ marginBottom: undefined,
627
+ marginRight: undefined,
628
+ direction: undefined,
629
+ iconBase64String: icons['vzb_unconnected'],
630
+ iconWidth: undefined,
631
+ iconHeight: undefined,
632
+ iconMarginRight: undefined,
633
+ titleText: 'Mobile Sign In',
634
+ titleTextFontFamily: undefined,
635
+ titleTextFontColor: undefined,
636
+ titleTextFontSize: undefined,
637
+ descriptionText: 'Please use your mobile app to complete the sign in process.',
638
+ descriptionTextFontFamily: undefined,
639
+ descriptionTextFontColor: undefined,
640
+ descriptionTextFontSize: undefined,
641
+ position: 'bottom-right',
642
+ borderColor: undefined,
643
+ borderWidth: undefined,
644
+ boxShadow: undefined,
645
+ height: undefined,
646
+ minHeight: undefined,
647
+ padding: undefined,
648
+ borderRadius: undefined,
649
+ edgeMargin: undefined,
650
+ marginTop: undefined,
651
+ marginLeft: undefined,
652
+ titleTextFontWeight: undefined,
653
+ titleTextLineHeight: undefined,
654
+ titleMarginBottom: undefined,
655
+ descriptionTextFontWeight: undefined,
656
+ descriptionTextLineHeight: undefined,
657
+ },
658
+ };
659
+ /**
660
+ * Default configuration for progress sign-in modal
661
+ * Shown while sign-in is in progress
662
+ */
663
+ const defaultProgressModalConfig = {
664
+ enable: true,
665
+ options: {
666
+ width: undefined,
667
+ backgroundColor: undefined,
668
+ marginBottom: undefined,
669
+ marginRight: undefined,
670
+ direction: undefined,
671
+ iconBase64String: icons['vzb_connection_progress_0'],
672
+ iconBase64Strings: [
673
+ icons['vzb_connection_progress_0'],
674
+ icons['vzb_connection_progress_1'],
675
+ icons['vzb_connection_progress_2'],
676
+ icons['vzb_connection_progress_1'],
677
+ ],
678
+ iconWidth: undefined,
679
+ iconHeight: undefined,
680
+ iconMarginRight: undefined,
681
+ titleText: undefined,
682
+ titleTextFontFamily: undefined,
683
+ titleTextFontColor: undefined,
684
+ titleTextFontSize: undefined,
685
+ descriptionText: 'Signing in using your mobile app ...',
686
+ descriptionTextFontFamily: undefined,
687
+ descriptionTextFontColor: undefined,
688
+ descriptionTextFontSize: undefined,
689
+ position: 'bottom-right',
690
+ borderColor: undefined,
691
+ borderWidth: undefined,
692
+ boxShadow: undefined,
693
+ height: undefined,
694
+ minHeight: undefined,
695
+ padding: undefined,
696
+ borderRadius: undefined,
697
+ edgeMargin: undefined,
698
+ marginTop: undefined,
699
+ marginLeft: undefined,
700
+ titleTextFontWeight: undefined,
701
+ titleTextLineHeight: undefined,
702
+ titleMarginBottom: undefined,
703
+ descriptionTextFontWeight: undefined,
704
+ descriptionTextLineHeight: undefined,
705
+ },
706
+ };
707
+ /**
708
+ * Default configuration for success sign-in modal
709
+ * Shown when sign-in process completes successfully
710
+ */
711
+ const defaultSuccessModalConfig = {
712
+ enable: true,
713
+ options: {
714
+ width: undefined,
715
+ backgroundColor: undefined,
716
+ marginBottom: undefined,
717
+ marginRight: undefined,
718
+ direction: undefined,
719
+ iconBase64String: icons['vzb_connected'],
720
+ iconWidth: undefined,
721
+ iconHeight: undefined,
722
+ iconMarginRight: undefined,
723
+ titleText: 'Mobile Sign In Successful!',
724
+ titleTextFontFamily: undefined,
725
+ titleTextFontColor: undefined,
726
+ titleTextFontSize: undefined,
727
+ descriptionText: 'Cast or select any content to start watching.',
728
+ descriptionTextFontFamily: undefined,
729
+ descriptionTextFontColor: undefined,
730
+ descriptionTextFontSize: undefined,
731
+ position: 'bottom-right',
732
+ duration: 10000,
733
+ borderColor: undefined,
734
+ borderWidth: undefined,
735
+ boxShadow: undefined,
736
+ height: undefined,
737
+ minHeight: undefined,
738
+ padding: undefined,
739
+ borderRadius: undefined,
740
+ edgeMargin: undefined,
741
+ marginTop: undefined,
742
+ marginLeft: undefined,
743
+ titleTextFontWeight: undefined,
744
+ titleTextLineHeight: undefined,
745
+ titleMarginBottom: undefined,
746
+ descriptionTextFontWeight: undefined,
747
+ descriptionTextLineHeight: undefined,
748
+ },
749
+ };
750
+
751
+ /* eslint-disable @typescript-eslint/no-explicit-any */
752
+ /**
753
+ * Singleton class responsible for managing UI configurations for Home SSO experience
754
+ * Handles theme customization and specific modal configurations for different sign-in states
755
+ */
756
+ class VizbeeHomeSSOUIManager {
757
+ /**
758
+ * Private constructor to enforce singleton pattern
759
+ * Initializes configurations with default values using deep merge
760
+ */
761
+ constructor() {
762
+ this.themeConfig = this.deepMerge({}, defaultTheme);
763
+ this.commonModalConfig = this.deepMerge({});
764
+ this.informationalModalConfig =
765
+ this.deepMerge(defaultInformationalModalConfig.options);
766
+ this.progressModalConfig = this.deepMerge(defaultProgressModalConfig.options);
767
+ this.successModalConfig = this.deepMerge(defaultSuccessModalConfig.options);
768
+ }
769
+ /**
770
+ * Gets the singleton instance of VizbeeHomeSSOUIManager
771
+ * Creates a new instance if one doesn't exist
772
+ * @returns The singleton instance of VizbeeHomeSSOUIManager
773
+ */
774
+ static getInstance() {
775
+ if (!VizbeeHomeSSOUIManager.instance) {
776
+ VizbeeHomeSSOUIManager.instance = new VizbeeHomeSSOUIManager();
777
+ }
778
+ return VizbeeHomeSSOUIManager.instance;
779
+ }
780
+ /**
781
+ * Creates a deep clone of an object or array
782
+ * @param obj - Object to clone
783
+ * @returns Deep cloned copy of the input
784
+ */
785
+ deepClone(obj) {
786
+ // Handle primitives and null
787
+ if (obj === null || typeof obj !== 'object') {
788
+ return obj;
789
+ }
790
+ try {
791
+ // Attempt JSON serialization - this will throw on circular references
792
+ return JSON.parse(JSON.stringify(obj));
793
+ }
794
+ catch (error) {
795
+ // Fall back to manual deep cloning when JSON serialization fails
796
+ return this.fallbackDeepClone(obj);
797
+ }
798
+ }
799
+ // Fallback manual deep clone that handles circular references
800
+ fallbackDeepClone(obj, visited = new Map()) {
801
+ if (obj === null || typeof obj !== 'object') {
802
+ return obj;
803
+ }
804
+ // Handle circular references
805
+ if (visited.has(obj)) {
806
+ return visited.get(obj);
807
+ }
808
+ // Handle arrays
809
+ if (Array.isArray(obj)) {
810
+ const clone = [];
811
+ visited.set(obj, clone);
812
+ for (let i = 0; i < obj.length; i++) {
813
+ clone[i] = this.fallbackDeepClone(obj[i], visited);
814
+ }
815
+ return clone;
816
+ }
817
+ // Handle objects
818
+ const clone = {};
819
+ visited.set(obj, clone);
820
+ Object.keys(obj).forEach(key => {
821
+ clone[key] = this.fallbackDeepClone(obj[key], visited);
822
+ });
823
+ return clone;
824
+ }
825
+ /**
826
+ * Performs a deep merge of multiple objects
827
+ * @param target - Base object to merge into
828
+ * @param sources - Array of objects to merge from
829
+ * @returns Merged object combining all sources into target
830
+ */
831
+ deepMerge(target, ...sources) {
832
+ const result = JSON.parse(JSON.stringify(target));
833
+ if (sources.length === 0)
834
+ return result;
835
+ for (const source of sources) {
836
+ if (!source)
837
+ continue;
838
+ for (const key of Object.keys(source)) {
839
+ const sourceValue = source[key];
840
+ if (sourceValue === undefined)
841
+ continue;
842
+ if (sourceValue === null) {
843
+ result[key] = null;
844
+ continue;
845
+ }
846
+ if (typeof sourceValue === 'object' && !Array.isArray(sourceValue)) {
847
+ if (!result[key] || typeof result[key] !== 'object') {
848
+ result[key] = {};
849
+ }
850
+ result[key] = this.deepMerge(result[key], sourceValue);
851
+ }
852
+ else {
853
+ result[key] = JSON.parse(JSON.stringify(sourceValue));
854
+ }
855
+ }
856
+ }
857
+ return result;
858
+ }
859
+ /**
860
+ * Maps theme configuration to modal configuration properties
861
+ * @param theme - Current theme configuration
862
+ * @returns Partial modal configuration based on theme
863
+ */
864
+ mapThemeToModalConfig(theme) {
865
+ return {
866
+ borderColor: theme.primaryColor,
867
+ backgroundColor: theme.secondaryColor,
868
+ titleTextFontColor: theme.tertiaryColor,
869
+ descriptionTextFontColor: theme.subTextColor,
870
+ titleTextFontFamily: theme.primaryFont,
871
+ descriptionTextFontFamily: theme.secondaryFont,
872
+ direction: theme.direction,
873
+ };
874
+ }
875
+ /**
876
+ * Returns default configurations for all modal types
877
+ * @returns Object containing default configs for informational, progress, and success modals
878
+ */
879
+ getDefaultConfig() {
880
+ const themeBasedConfig = this.mapThemeToModalConfig(this.themeConfig);
881
+ const informational = this.deepMerge(defaultInformationalModalConfig.options, themeBasedConfig);
882
+ const progress = this.deepMerge(defaultProgressModalConfig.options, themeBasedConfig);
883
+ const successBase = this.deepMerge(defaultSuccessModalConfig.options, themeBasedConfig);
884
+ return {
885
+ informational,
886
+ progress,
887
+ success: Object.assign(Object.assign({}, successBase), { duration: defaultSuccessModalConfig.options.duration }),
888
+ };
889
+ }
890
+ /**
891
+ * Updates the current theme configuration
892
+ * @param theme - Partial theme configuration to merge with current theme
893
+ */
894
+ setTheme(theme) {
895
+ this.themeConfig = this.deepMerge(defaultTheme, theme);
896
+ }
897
+ /**
898
+ * Retrieves current theme configuration
899
+ * @returns Deep clone of current theme configuration
900
+ */
901
+ getTheme() {
902
+ return this.deepClone(this.themeConfig);
903
+ }
904
+ /**
905
+ * Updates common modal configuration applied to all modal types
906
+ * @param config - Partial configuration to merge with current common config
907
+ */
908
+ setCommonModalConfig(config) {
909
+ this.commonModalConfig = this.deepMerge(this.commonModalConfig, config);
910
+ }
911
+ /**
912
+ * Updates informational sign-in modal configuration
913
+ * @param config - Partial configuration to merge with current informational config
914
+ */
915
+ setInformationalSignInModalConfig(config) {
916
+ this.informationalModalConfig = this.deepMerge(this.informationalModalConfig, config);
917
+ }
918
+ /**
919
+ * Updates progress sign-in modal configuration
920
+ * @param config - Partial configuration to merge with current progress config
921
+ */
922
+ setProgressSignInModalConfig(config) {
923
+ this.progressModalConfig = this.deepMerge(this.progressModalConfig, config);
924
+ }
925
+ /**
926
+ * Updates success sign-in modal configuration
927
+ * @param config - Partial configuration to merge with current success config
928
+ */
929
+ setSuccessSignInModalConfig(config) {
930
+ this.successModalConfig = this.deepMerge(this.successModalConfig, config);
931
+ }
932
+ /**
933
+ * Retrieves complete configuration for informational sign-in modal
934
+ * Combines default, theme-based, common, and specific configurations
935
+ * @returns Complete informational modal configuration
936
+ */
937
+ getInformationalSignInModalConfig() {
938
+ const themeBasedConfig = this.mapThemeToModalConfig(this.themeConfig);
939
+ return this.deepMerge(defaultInformationalModalConfig.options, themeBasedConfig, this.commonModalConfig, this.informationalModalConfig);
940
+ }
941
+ /**
942
+ * Retrieves complete configuration for progress sign-in modal
943
+ * Combines default, theme-based, common, and specific configurations
944
+ * @returns Complete progress modal configuration
945
+ */
946
+ getProgressSignInModalConfig() {
947
+ const themeBasedConfig = this.mapThemeToModalConfig(this.themeConfig);
948
+ return this.deepMerge(defaultProgressModalConfig.options, themeBasedConfig, this.commonModalConfig, this.progressModalConfig);
949
+ }
950
+ /**
951
+ * Retrieves complete configuration for success sign-in modal
952
+ * Combines default, theme-based, common, and specific configurations
953
+ * @returns Complete success modal configuration
954
+ */
955
+ getSuccessSignInModalConfig() {
956
+ const themeBasedConfig = this.mapThemeToModalConfig(this.themeConfig);
957
+ const baseConfig = this.deepMerge(defaultSuccessModalConfig.options, themeBasedConfig, this.commonModalConfig, this.successModalConfig);
958
+ return Object.assign(Object.assign({}, baseConfig), { duration: this.successModalConfig.duration });
959
+ }
960
+ }
961
+
962
+ /**
963
+ * A class that manages the display of snackbar notifications with customizable styling and animations
964
+ */
965
+ class VizbeeSnackbar {
966
+ /**
967
+ * Creates a new instance of VizbeeSnackbar
968
+ */
969
+ constructor() {
970
+ this.BASE_DIMENSIONS = {
971
+ REFERENCE_WIDTH: 1920,
972
+ REFERENCE_HEIGHT: 1080,
973
+ WIDTH: 720,
974
+ PADDING: 20,
975
+ BORDER_RADIUS: 20,
976
+ BORDER_WIDTH: 2,
977
+ MARGIN: 32,
978
+ ICON_SIZE: 40,
979
+ ICON_MARGIN: 12,
980
+ TITLE_FONT_SIZE: 32,
981
+ MESSAGE_FONT_SIZE: 28,
982
+ };
983
+ this.uiManager = VizbeeHomeSSOUIManager.getInstance();
984
+ this.setupContainer();
985
+ }
986
+ /**
987
+ * Shows the snackbar with the specified options
988
+ */
989
+ show(options) {
990
+ this.hide();
991
+ clearTimeout(this.showSnackbarTimerId);
992
+ this.showSnackbarTimerId = window.setTimeout(() => {
993
+ this.createSnackbar(options);
994
+ if (this.currentSnackbar) {
995
+ this.currentSnackbar.style.transform =
996
+ this.getSlideTransform('top-right');
997
+ }
998
+ if (options === null || options === void 0 ? void 0 : options.shouldAnimateIcon) {
999
+ this.startIconAnimation(options.iconBase64Strings);
1000
+ }
1001
+ if ((options === null || options === void 0 ? void 0 : options.duration) && options.duration > 0) {
1002
+ this.timeoutId = window.setTimeout(() => this.hide(), options.duration);
1003
+ }
1004
+ }, 1000);
1005
+ }
1006
+ /**
1007
+ * Hides the currently displayed snackbar
1008
+ */
1009
+ hide() {
1010
+ this.stopIconAnimation();
1011
+ if (this.timeoutId) {
1012
+ clearTimeout(this.timeoutId);
1013
+ this.timeoutId = undefined;
1014
+ }
1015
+ if (this.currentSnackbar) {
1016
+ this.currentSnackbar.style.transform = this.getSlideTransform('bottom-right', true);
1017
+ this.currentSnackbar.style.opacity = '0';
1018
+ setTimeout(() => {
1019
+ var _a;
1020
+ if (((_a = this.currentSnackbar) === null || _a === void 0 ? void 0 : _a.parentNode) === this.container) {
1021
+ this.container.removeChild(this.currentSnackbar);
1022
+ }
1023
+ this.currentSnackbar = undefined;
1024
+ }, 300);
1025
+ }
1026
+ }
1027
+ getScreenScale() {
1028
+ const width = window.innerWidth;
1029
+ return width / this.BASE_DIMENSIONS.REFERENCE_WIDTH;
1030
+ }
1031
+ scaleValue(value) {
1032
+ return Math.round(value * this.getScreenScale());
1033
+ }
1034
+ setupContainer() {
1035
+ this.container = document.createElement('div');
1036
+ this.container.style.cssText = `
1037
+ position: fixed;
1038
+ z-index: 9999;
1039
+ pointer-events: none;
1040
+ width: 100%;
1041
+ height: 100%;
1042
+ top: 0;
1043
+ left: 0;
1044
+ `;
1045
+ document.body.appendChild(this.container);
1046
+ }
1047
+ getSlideTransform(position, hide = false) {
1048
+ const transformValue = '150%';
1049
+ const isTop = position.includes('top');
1050
+ return `translateY(${(hide === isTop ? '-' : '') + transformValue})`;
1051
+ }
1052
+ getPositionStyles(position, edgeMargin) {
1053
+ const margin = edgeMargin || this.scaleValue(this.BASE_DIMENSIONS.MARGIN) + 'px';
1054
+ const positions = {
1055
+ 'top-right': `top: ${margin}; right: ${margin};`,
1056
+ 'top-left': `top: ${margin}; left: ${margin};`,
1057
+ 'bottom-right': `bottom: ${margin}; right: ${margin};`,
1058
+ 'bottom-left': `bottom: ${margin}; left: ${margin};`,
1059
+ };
1060
+ return positions[position];
1061
+ }
1062
+ startIconAnimation(iconBase64Strings) {
1063
+ if (this.animationInterval) {
1064
+ clearInterval(this.animationInterval);
1065
+ }
1066
+ if (!iconBase64Strings || iconBase64Strings.length === 0) {
1067
+ return;
1068
+ }
1069
+ let currentIndex = 0;
1070
+ this.animationInterval = window.setInterval(() => {
1071
+ if (this.currentIconElement) {
1072
+ currentIndex = (currentIndex + 1) % iconBase64Strings.length;
1073
+ this.currentIconElement.src = iconBase64Strings[currentIndex];
1074
+ }
1075
+ }, 500);
1076
+ }
1077
+ stopIconAnimation() {
1078
+ if (this.animationInterval) {
1079
+ clearInterval(this.animationInterval);
1080
+ this.animationInterval = undefined;
1081
+ }
1082
+ }
1083
+ /**
1084
+ * Whether the snackbar should render right-to-left.
1085
+ * Defaults to LTR when no direction is provided.
1086
+ */
1087
+ isRtl(options) {
1088
+ return ((options === null || options === void 0 ? void 0 : options.direction) || 'ltr') === 'rtl';
1089
+ }
1090
+ createSnackbar(options) {
1091
+ const snackbar = document.createElement('div');
1092
+ snackbar.style.cssText = this.getSnackbarStyles(options);
1093
+ const isRtl = this.isRtl(options);
1094
+ const contentWrapper = this.createContentWrapper(isRtl);
1095
+ const iconBase64 = options === null || options === void 0 ? void 0 : options.iconBase64String;
1096
+ if (iconBase64) {
1097
+ const iconWrapper = this.createIconWrapper(iconBase64, options.iconWidth, options.iconHeight, options.iconMarginRight, isRtl);
1098
+ contentWrapper.appendChild(iconWrapper);
1099
+ }
1100
+ const textWrapper = this.createTextWrapper(options);
1101
+ contentWrapper.appendChild(textWrapper);
1102
+ snackbar.appendChild(contentWrapper);
1103
+ this.container.appendChild(snackbar);
1104
+ this.currentSnackbar = snackbar;
1105
+ requestAnimationFrame(() => {
1106
+ snackbar.style.opacity = '1';
1107
+ snackbar.style.transform = 'translateY(0)';
1108
+ });
1109
+ }
1110
+ getSnackbarStyles(options) {
1111
+ var _a;
1112
+ const theme = this.uiManager.getTheme();
1113
+ const borderColor = (options === null || options === void 0 ? void 0 : options.borderColor) || theme.primaryColor;
1114
+ const borderWidth = (options === null || options === void 0 ? void 0 : options.borderWidth) ||
1115
+ this.scaleValue(this.BASE_DIMENSIONS.BORDER_WIDTH) + 'px';
1116
+ const boxShadow = (options === null || options === void 0 ? void 0 : options.boxShadow) ||
1117
+ `0 ${this.scaleValue(2)}px ${this.scaleValue(8)}px rgba(0, 0, 0, 0.4)`;
1118
+ const padding = (options === null || options === void 0 ? void 0 : options.padding) || this.scaleValue(this.BASE_DIMENSIONS.PADDING) + 'px';
1119
+ const borderRadius = (options === null || options === void 0 ? void 0 : options.borderRadius) ||
1120
+ this.scaleValue(this.BASE_DIMENSIONS.BORDER_RADIUS) + 'px';
1121
+ return `
1122
+ position: absolute;
1123
+ display: flex;
1124
+ background: ${(options === null || options === void 0 ? void 0 : options.backgroundColor) || 'rgba(0, 0, 0, 0.75)'};
1125
+ color: white;
1126
+ width: ${(options === null || options === void 0 ? void 0 : options.width) || this.scaleValue(this.BASE_DIMENSIONS.WIDTH) + 'px'};
1127
+ ${(options === null || options === void 0 ? void 0 : options.height) ? `height: ${options.height};` : ''}
1128
+ ${(options === null || options === void 0 ? void 0 : options.minHeight) ? `min-height: ${options.minHeight};` : ''}
1129
+ padding: ${padding};
1130
+ border-radius: ${borderRadius};
1131
+ border: ${borderWidth} solid ${borderColor};
1132
+ box-shadow: ${boxShadow};
1133
+ font-family: ${theme.primaryFont || '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif'};
1134
+ pointer-events: auto;
1135
+ transition: all 0.3s ease;
1136
+ opacity: 0;
1137
+ margin-top: ${(options === null || options === void 0 ? void 0 : options.marginTop) || '0'};
1138
+ margin-right: ${(options === null || options === void 0 ? void 0 : options.marginRight) || '0'};
1139
+ margin-bottom: ${(options === null || options === void 0 ? void 0 : options.marginBottom) || '0'};
1140
+ margin-left: ${(options === null || options === void 0 ? void 0 : options.marginLeft) || '0'};
1141
+ ${this.getPositionStyles((options === null || options === void 0 ? void 0 : options.position) || 'bottom-right', options === null || options === void 0 ? void 0 : options.edgeMargin)}
1142
+ transform: translateY(${((_a = options === null || options === void 0 ? void 0 : options.position) === null || _a === void 0 ? void 0 : _a.includes('top')) ? '-150%' : '150%'});
1143
+ `;
1144
+ }
1145
+ createContentWrapper(isRtl = false) {
1146
+ const wrapper = document.createElement('div');
1147
+ // `row-reverse` places the icon on the trailing (right) side for RTL.
1148
+ // Using an explicit flex-direction keeps ordering deterministic across TV
1149
+ // browsers rather than relying on `direction`-driven flex reordering.
1150
+ wrapper.style.cssText = `
1151
+ display: flex;
1152
+ flex-direction: ${isRtl ? 'row-reverse' : 'row'};
1153
+ align-items: flex-start;
1154
+ height: 100%;
1155
+ width: 100%;
1156
+ `;
1157
+ return wrapper;
1158
+ }
1159
+ createIconWrapper(iconBase64, width, height, marginRight, isRtl = false) {
1160
+ const wrapper = document.createElement('div');
1161
+ const iconSize = this.scaleValue(this.BASE_DIMENSIONS.ICON_SIZE);
1162
+ const iconGap = marginRight || this.scaleValue(this.BASE_DIMENSIONS.ICON_MARGIN) + 'px';
1163
+ // The gap always sits between the icon and the text. In RTL the icon is on
1164
+ // the right (row-reverse), so the gap belongs on its left instead.
1165
+ const iconGapSide = isRtl ? 'margin-left' : 'margin-right';
1166
+ wrapper.style.cssText = `
1167
+ ${iconGapSide}: ${iconGap};
1168
+ display: flex;
1169
+ align-items: flex-start;
1170
+ justify-content: center;
1171
+ min-width: ${width || iconSize + 'px'};
1172
+ width: ${width || iconSize + 'px'};
1173
+ height: ${height || iconSize + 'px'};
1174
+ color: white;
1175
+ margin-top: 0;
1176
+ `;
1177
+ const iconElement = document.createElement('img');
1178
+ iconElement.src = iconBase64;
1179
+ iconElement.style.cssText = `
1180
+ width: 100%;
1181
+ height: 100%;
1182
+ object-fit: contain;
1183
+ vertical-align: middle;
1184
+ `;
1185
+ this.currentIconElement = iconElement;
1186
+ wrapper.appendChild(iconElement);
1187
+ return wrapper;
1188
+ }
1189
+ createTextWrapper(options) {
1190
+ const isRtl = this.isRtl(options);
1191
+ const wrapper = document.createElement('div');
1192
+ // `direction` drives bidi text shaping; `text-align` aligns the title and
1193
+ // description to the leading edge. Both inherit to the child text elements.
1194
+ wrapper.style.cssText = `
1195
+ flex: 1;
1196
+ display: flex;
1197
+ flex-direction: column;
1198
+ justify-content: flex-start;
1199
+ direction: ${isRtl ? 'rtl' : 'ltr'};
1200
+ text-align: ${isRtl ? 'right' : 'left'};
1201
+ `;
1202
+ if (options === null || options === void 0 ? void 0 : options.titleText) {
1203
+ const titleElement = document.createElement('div');
1204
+ titleElement.style.cssText = `
1205
+ font-size: ${(options === null || options === void 0 ? void 0 : options.titleTextFontSize) || this.scaleValue(this.BASE_DIMENSIONS.TITLE_FONT_SIZE) + 'px'};
1206
+ font-family: ${(options === null || options === void 0 ? void 0 : options.titleTextFontFamily) || '-apple-system'};
1207
+ color: ${(options === null || options === void 0 ? void 0 : options.titleTextFontColor) || 'white'};
1208
+ font-weight: ${(options === null || options === void 0 ? void 0 : options.titleTextFontWeight) || '500'};
1209
+ margin-bottom: ${(options === null || options === void 0 ? void 0 : options.titleMarginBottom) || this.scaleValue(4) + 'px'};
1210
+ line-height: ${(options === null || options === void 0 ? void 0 : options.titleTextLineHeight) || '1.2'};
1211
+ `;
1212
+ titleElement.textContent = options.titleText;
1213
+ wrapper.appendChild(titleElement);
1214
+ }
1215
+ const messageElement = document.createElement('div');
1216
+ messageElement.style.cssText = `
1217
+ font-size: ${(options === null || options === void 0 ? void 0 : options.descriptionTextFontSize) ||
1218
+ this.scaleValue((options === null || options === void 0 ? void 0 : options.titleText)
1219
+ ? this.BASE_DIMENSIONS.MESSAGE_FONT_SIZE
1220
+ : this.BASE_DIMENSIONS.TITLE_FONT_SIZE) + 'px'};
1221
+ font-family: ${(options === null || options === void 0 ? void 0 : options.descriptionTextFontFamily) || '-apple-system'};
1222
+ color: ${(options === null || options === void 0 ? void 0 : options.descriptionTextFontColor) || 'rgba(255, 255, 255, 0.9)'};
1223
+ font-weight: ${(options === null || options === void 0 ? void 0 : options.descriptionTextFontWeight) || 'normal'};
1224
+ line-height: ${(options === null || options === void 0 ? void 0 : options.descriptionTextLineHeight) || '1.3'};
1225
+ `;
1226
+ messageElement.textContent = options.descriptionText;
1227
+ wrapper.appendChild(messageElement);
1228
+ return wrapper;
1229
+ }
1230
+ }
1231
+
1232
+ /* eslint-disable @typescript-eslint/no-explicit-any */
1233
+ const LOG_TAG = 'VizbeeHomeSSOManager';
1234
+ /**
1235
+ * Manages Single Sign-On (SSO) functionality between mobile and TV devices in the Vizbee ecosystem.
1236
+ * Implements singleton pattern for global state management.
1237
+ *
1238
+ * @remarks
1239
+ * This class serves as the central manager for SSO operations, handling:
1240
+ * - Communication between mobile and TV devices
1241
+ * - Sign-in status management and updates
1242
+ * - UI state management
1243
+ * - Analytics and metrics tracking
1244
+ *
1245
+ * @class VizbeeHomeSSOManager
1246
+ * @public
1247
+ */
1248
+ class VizbeeHomeSSOManager {
1249
+ /**
1250
+ * Private constructor to enforce singleton pattern
1251
+ * Initializes necessary components and sets up default handlers
1252
+ *
1253
+ * @internal
1254
+ */
1255
+ constructor() {
1256
+ /** @internal List of sign-in information for different services */
1257
+ this.signInInfoList = [];
1258
+ /** @internal Tracks if remote device is signed in */
1259
+ this.isRemoteSignedIn = false;
1260
+ /** @internal Tracks if screen device is signed in */
1261
+ this.isScreenSignedIn = false;
1262
+ /** @internal Tracks if sign-in process is currently active */
1263
+ this.isSignInInProgress = false;
1264
+ /** @internal Information about the sender device */
1265
+ this.senderInfo = null;
1266
+ /**
1267
+ * Modal display preferences for the SSO UI
1268
+ * @public
1269
+ */
1270
+ this.modalPreferences = {};
1271
+ this.vizbeeHomeSSOUIManager = VizbeeHomeSSOUIManager.getInstance();
1272
+ this.snackbar = new VizbeeSnackbar();
1273
+ this.vizbeeMetricsManager = new VizbeeMetricsManager();
1274
+ }
1275
+ /**
1276
+ * Gets the singleton instance of VizbeeHomeSSOManager
1277
+ * Creates a new instance if one doesn't exist
1278
+ *
1279
+ * @returns The singleton instance of the SSO manager
1280
+ * @public
1281
+ */
1282
+ static getInstance() {
1283
+ if (!VizbeeHomeSSOManager.instance) {
1284
+ VizbeeHomeSSOManager.instance = new VizbeeHomeSSOManager();
1285
+ }
1286
+ return VizbeeHomeSSOManager.instance;
1287
+ }
1288
+ init() {
1289
+ this.initializeVizbeeSession();
1290
+ }
1291
+ /**
1292
+ * Sets up a handler for processing sign-in events from mobile devices
1293
+ *
1294
+ * @param handler - Callback function to process sign-in information and provide status updates
1295
+ * @public
1296
+ */
1297
+ setSignInHandler(handler) {
1298
+ logger.debug(`[${LOG_TAG}][setSignInHandler] - setSignInHandler called`);
1299
+ if (!handler) {
1300
+ logger.error(`[${LOG_TAG}][setSignInHandler] - Error: Sign-in handler is missing`);
1301
+ return;
1302
+ }
1303
+ if (typeof handler !== 'function') {
1304
+ logger.error(`[${LOG_TAG}][setSignInHandler] - Error: Sign-in handler is not a function`);
1305
+ return;
1306
+ }
1307
+ logger.info(`[${LOG_TAG}][setSignInHandler] - Setting sign-in handler`);
1308
+ this.signInHandler = handler;
1309
+ }
1310
+ /**
1311
+ * Sets the callback for retrieving sign-in information
1312
+ *
1313
+ * @param getSignInInfo - Async callback that provides the list of sign-in information
1314
+ * @public
1315
+ */
1316
+ setSignInInfoGetter(getSignInInfo) {
1317
+ if (!getSignInInfo) {
1318
+ logger.error(`[${LOG_TAG}][setSignInInfoGetter] - Error: GetSignInInfo callback is missing`);
1319
+ return;
1320
+ }
1321
+ if (typeof getSignInInfo !== 'function') {
1322
+ logger.error(`[${LOG_TAG}][setSignInInfoGetter] - Error: GetSignInInfo is not a function`);
1323
+ return;
1324
+ }
1325
+ if (!this.vizbeeMetricsManager) {
1326
+ logger.error(`[${LOG_TAG}][setSignInInfoGetter] - Error: Metrics manager is missing`);
1327
+ return;
1328
+ }
1329
+ if (!this.vizbeeMetricsManager.getSignInInfo) {
1330
+ logger.error(`[${LOG_TAG}][setSignInInfoGetter] - Error: GetAttributes callback is missing`);
1331
+ return;
1332
+ }
1333
+ this.vizbeeMetricsManager.getSignInInfo = getSignInInfo;
1334
+ }
1335
+ /**
1336
+ * Handles sign-in progress updates
1337
+ * Updates UI, sends status to mobile device, and logs metrics
1338
+ *
1339
+ * @param progressStatus - Current progress status of the sign-in process
1340
+ * @public
1341
+ */
1342
+ onProgress(progressStatus) {
1343
+ logger.info(`[${LOG_TAG}][onProgress] - OnProgress is invoked`);
1344
+ this.isSignInInProgress = true;
1345
+ this.sendStatusToSender(progressStatus);
1346
+ this.updateProgressUI();
1347
+ this.vizbeeMetricsManager.log(VizbeeMetricsConstants.METRICS_EVENT_SCREEN_HOMESSO_SIGNIN_STATUS, {
1348
+ isScreenSignedIn: false,
1349
+ isRemoteSignedIn: this.isRemoteSignedIn,
1350
+ signInState: progressStatus.getState(),
1351
+ userId: null,
1352
+ signInType: progressStatus.signInType,
1353
+ });
1354
+ }
1355
+ /**
1356
+ * Handles successful sign-in completion
1357
+ * Updates UI, sends success status to mobile device, and logs metrics
1358
+ *
1359
+ * @param successStatus - Success status details
1360
+ * @public
1361
+ */
1362
+ onSuccess(successStatus) {
1363
+ logger.info(`[${LOG_TAG}][onSuccess] - OnSuccess is invoked`);
1364
+ this.isSignInInProgress = false;
1365
+ this.isRemoteSignedIn = true;
1366
+ this.sendStatusToSender(successStatus);
1367
+ this.updateSuccessUI();
1368
+ this.vizbeeMetricsManager.log(VizbeeMetricsConstants.METRICS_EVENT_SCREEN_HOMESSO_SIGNIN_STATUS, {
1369
+ isScreenSignedIn: true,
1370
+ isRemoteSignedIn: this.isRemoteSignedIn,
1371
+ signInState: successStatus.getState(),
1372
+ userId: successStatus.userId,
1373
+ signInType: successStatus.signInType,
1374
+ });
1375
+ }
1376
+ /**
1377
+ * Handles sign-in failures
1378
+ * Updates UI and sends failure status to mobile device
1379
+ *
1380
+ * @param failureStatus - Failure status details
1381
+ * @public
1382
+ */
1383
+ onFailure(failureStatus) {
1384
+ logger.info(`[${LOG_TAG}][onFailure] - OnFailure is invoked`);
1385
+ this.isSignInInProgress = false;
1386
+ this.sendStatusToSender(failureStatus);
1387
+ this.updateFailureUI();
1388
+ this.vizbeeMetricsManager.log(VizbeeMetricsConstants.METRICS_EVENT_SCREEN_HOMESSO_SIGNIN_STATUS, {
1389
+ isScreenSignedIn: false,
1390
+ isRemoteSignedIn: this.isRemoteSignedIn,
1391
+ signInState: failureStatus.getState(),
1392
+ userId: null,
1393
+ signInType: failureStatus.signInType,
1394
+ });
1395
+ }
1396
+ /**
1397
+ * Adds custom attributes for metrics tracking
1398
+ *
1399
+ * @param customEventAttributes - Dictionary of custom attributes to track
1400
+ * @public
1401
+ */
1402
+ addCustomEventAttributes(customEventAttributes) {
1403
+ var _a;
1404
+ if (customEventAttributes) {
1405
+ (_a = this.vizbeeMetricsManager) === null || _a === void 0 ? void 0 : _a.setCustomAttributes(customEventAttributes);
1406
+ }
1407
+ }
1408
+ /**
1409
+ * Initializes Vizbee session and messaging client
1410
+ *
1411
+ * @throws Error if initialization fails
1412
+ * @internal
1413
+ */
1414
+ initializeVizbeeSession() {
1415
+ var _a, _b;
1416
+ try {
1417
+ logger.info(`[${LOG_TAG}][initializeVizbeeSession] - Initializing Vizbee session`);
1418
+ // Check if vizbee and continuity exist before accessing xmessages
1419
+ if (!((_b = (_a = window.vizbee) === null || _a === void 0 ? void 0 : _a.continuity) === null || _b === void 0 ? void 0 : _b.xmessages)) {
1420
+ throw new Error('Vizbee continuity or xmessages not initialized');
1421
+ }
1422
+ // Access VizbeeBicastSessionManager directly from the existing object
1423
+ const sessionManager = new window.vizbee.continuity.xmessages.VizbeeBicastSessionManager();
1424
+ if (!sessionManager) {
1425
+ throw new Error('Session manager initialization failed');
1426
+ }
1427
+ // add sessionStateListener
1428
+ logger.debug(`[${LOG_TAG}]initializeVizbeeSession - Adding session state listener`);
1429
+ sessionManager.addSessionStateListener({
1430
+ onSessionStateChanged: (state) => {
1431
+ logger.info(`[${LOG_TAG}][onSessionStateChanged] - Session state changed:`, state);
1432
+ if (state === 3) {
1433
+ this.vizbeeSession = sessionManager.getSession();
1434
+ this.vizbeeMessagingClient =
1435
+ this.vizbeeSession.getMessagingClient();
1436
+ if (this.signInHandler) {
1437
+ logger.info(`[${LOG_TAG}][onSessionStateChanged] - Adding sign-in request receiver`);
1438
+ this.vizbeeMessagingClient.addReceiver(VizbeeConstants.EVENT_SSO_NAME, (payload, namespace, device) => __awaiter(this, void 0, void 0, function* () {
1439
+ logger.debug(`[${LOG_TAG}][onSessionStateChanged] - Received sign-in request on namespace:`, namespace);
1440
+ this.senderInfo = device;
1441
+ yield this.handleSignInRequest(payload, this.signInHandler);
1442
+ }));
1443
+ }
1444
+ else {
1445
+ logger.warn(`[${LOG_TAG}][onSessionStateChanged] - Error: Sign-in handler is missing`);
1446
+ }
1447
+ }
1448
+ },
1449
+ });
1450
+ }
1451
+ catch (error) {
1452
+ logger.warn(`[${LOG_TAG}][onSessionStateChanged] - Error initializing Vizbee session:`, error);
1453
+ throw error;
1454
+ }
1455
+ }
1456
+ /**
1457
+ * Processes incoming sign-in requests
1458
+ * Validates request and triggers appropriate handler
1459
+ *
1460
+ * @param payload - Sign-in request payload
1461
+ * @param handler - Callback to handle the sign-in request
1462
+ * @internal
1463
+ */
1464
+ handleSignInRequest(payload, handler) {
1465
+ return __awaiter(this, void 0, void 0, function* () {
1466
+ var _a, _b;
1467
+ const senderSignInInfo = payload[VizbeeConstants.KEY_START_SIGN_IN_INFO];
1468
+ if (!senderSignInInfo) {
1469
+ logger.warn(`[${LOG_TAG}][handleSignInRequest] - Error: Sender info is missing`);
1470
+ return;
1471
+ }
1472
+ const signInType = senderSignInInfo[VizbeeConstants.KEY_SIGN_IN_TYPE];
1473
+ this.isScreenSignedIn = yield this.isUserAlreadySignedIn(signInType);
1474
+ this.isRemoteSignedIn = payload[VizbeeConstants.KEY_START_SIGN_IN_INFO][VizbeeConstants.KEY_IS_SIGNED_IN];
1475
+ this.vizbeeMetricsManager.log(VizbeeMetricsConstants.METRICS_EVENT_SCREEN_HOMESSO_SIGNIN_RECEIVED, {
1476
+ isScreenSignedIn: this.isScreenSignedIn,
1477
+ isRemoteSignedIn: this.isRemoteSignedIn,
1478
+ signInType: signInType,
1479
+ senderInfo: this.senderInfo,
1480
+ });
1481
+ if (yield this.shouldIgnoreSignInRequest()) {
1482
+ return;
1483
+ }
1484
+ const signInInfo = {
1485
+ isSignedIn: this.isRemoteSignedIn,
1486
+ signInType: signInType,
1487
+ deviceId: (_a = this.senderInfo) === null || _a === void 0 ? void 0 : _a.deviceId,
1488
+ deviceType: (_b = this.senderInfo) === null || _b === void 0 ? void 0 : _b.deviceType,
1489
+ customData: {},
1490
+ };
1491
+ handler(signInInfo, this.handleSignInStatus.bind(this));
1492
+ });
1493
+ }
1494
+ /**
1495
+ * Determines if a sign-in request should be ignored
1496
+ * Checks various conditions like existing sign-in state
1497
+ *
1498
+ * @returns Promise<boolean> indicating if request should be ignored
1499
+ * @internal
1500
+ */
1501
+ shouldIgnoreSignInRequest() {
1502
+ return __awaiter(this, void 0, void 0, function* () {
1503
+ if (this.isScreenSignedIn) {
1504
+ logger.info(`[${LOG_TAG}][shouldIgnoreSignInRequest] - User is already signed in`);
1505
+ return true;
1506
+ }
1507
+ return false;
1508
+ });
1509
+ }
1510
+ /**
1511
+ * Checks if user is already signed in for a specific sign-in type
1512
+ *
1513
+ * @param signInType - Type of sign-in to check
1514
+ * @returns Promise<boolean> indicating if user is signed in
1515
+ * @internal
1516
+ */
1517
+ isUserAlreadySignedIn(signInType) {
1518
+ return __awaiter(this, void 0, void 0, function* () {
1519
+ var _a, _b;
1520
+ try {
1521
+ const attributes = yield ((_b = (_a = this.vizbeeMetricsManager) === null || _a === void 0 ? void 0 : _a.getAttributes) === null || _b === void 0 ? void 0 : _b.call(_a));
1522
+ const signInInfoList = attributes === null || attributes === void 0 ? void 0 : attributes['SCREEN_HOMESSO_USER_INFO'];
1523
+ logger.info(`[${LOG_TAG}][isUserAlreadySignedIn] - signInInfoList`, signInInfoList);
1524
+ const tvSignInInfo = signInInfoList.find((info) => info.user_login_type === signInType);
1525
+ logger.debug(`[${LOG_TAG}][isUserAlreadySignedIn] - TV sign in status fetched:`, tvSignInInfo);
1526
+ return tvSignInInfo === null || tvSignInInfo === void 0 ? void 0 : tvSignInInfo.user_is_signed_in;
1527
+ }
1528
+ catch (error) {
1529
+ logger.warn(`[${LOG_TAG}][isUserAlreadySignedIn] - Error checking sign-in status:`, error);
1530
+ return false;
1531
+ }
1532
+ });
1533
+ }
1534
+ /**
1535
+ * Handles sign-in status updates
1536
+ * Routes status updates to appropriate handlers
1537
+ *
1538
+ * @param status - Current status of the sign-in process
1539
+ * @internal
1540
+ */
1541
+ handleSignInStatus(status) {
1542
+ var _a, _b;
1543
+ if (status instanceof ProgressStatus) {
1544
+ const regcode = (_a = status.customData) === null || _a === void 0 ? void 0 : _a.regcode;
1545
+ if (regcode) {
1546
+ this.onProgress(status);
1547
+ }
1548
+ }
1549
+ else if (status instanceof SuccessStatus) {
1550
+ const userEmail = (_b = status.customData) === null || _b === void 0 ? void 0 : _b.email;
1551
+ if (userEmail) {
1552
+ this.onSuccess(status);
1553
+ }
1554
+ }
1555
+ else if (status instanceof FailureStatus) {
1556
+ this.onFailure(status);
1557
+ }
1558
+ }
1559
+ /**
1560
+ * Sends status updates to mobile device
1561
+ *
1562
+ * @param status - Status to send to mobile device
1563
+ * @internal
1564
+ */
1565
+ sendStatusToSender(status) {
1566
+ const signInStatus = this.serializeStatus(status);
1567
+ const data = {
1568
+ [VizbeeConstants.KEY_SUB_TYPE]: VizbeeConstants.EVENT_SUBTYPE_SIGN_IN_STATUS,
1569
+ [VizbeeConstants.KEY_SIGN_IN_STATUS]: signInStatus,
1570
+ };
1571
+ this.vizbeeMessagingClient.send(data, VizbeeConstants.EVENT_SSO_NAME);
1572
+ }
1573
+ /**
1574
+ * Serializes status objects for transmission to mobile device
1575
+ *
1576
+ * @param status - Status object to serialize
1577
+ * @returns Serialized status object or null if invalid status type
1578
+ * @internal
1579
+ */
1580
+ serializeStatus(status) {
1581
+ if (status instanceof ProgressStatus) {
1582
+ return status.serialize();
1583
+ }
1584
+ else if (status instanceof SuccessStatus) {
1585
+ return status.serialize();
1586
+ }
1587
+ else if (status instanceof FailureStatus) {
1588
+ return status.serialize();
1589
+ }
1590
+ return null;
1591
+ }
1592
+ /**
1593
+ * Updates UI for sign-in progress state
1594
+ * Shows appropriate modal based on remote sign-in status
1595
+ *
1596
+ * @internal
1597
+ */
1598
+ updateProgressUI() {
1599
+ if (!this.isRemoteSignedIn) {
1600
+ const modalOptions = this.vizbeeHomeSSOUIManager.getInformationalSignInModalConfig();
1601
+ this.snackbar.show(modalOptions);
1602
+ }
1603
+ else {
1604
+ const modalOptions = this.vizbeeHomeSSOUIManager.getProgressSignInModalConfig();
1605
+ this.snackbar.show(Object.assign(Object.assign({}, modalOptions), { shouldAnimateIcon: true }));
1606
+ }
1607
+ }
1608
+ /**
1609
+ * Updates UI for successful sign-in
1610
+ * Shows success modal with appropriate message
1611
+ *
1612
+ * @internal
1613
+ */
1614
+ updateSuccessUI() {
1615
+ // Enforce only the success duration; leave title/description to the
1616
+ // integrator's config (or the defaults) so the success toast can be
1617
+ // themed/localized like the informational and progress modals.
1618
+ this.vizbeeHomeSSOUIManager.setSuccessSignInModalConfig({ duration: 10000 });
1619
+ const modalOptions = this.vizbeeHomeSSOUIManager.getSuccessSignInModalConfig();
1620
+ this.snackbar.show(modalOptions);
1621
+ }
1622
+ /**
1623
+ * Updates UI for failed sign-in
1624
+ * Hides any active modals
1625
+ *
1626
+ * @internal
1627
+ */
1628
+ updateFailureUI() {
1629
+ this.snackbar.hide();
1630
+ }
1631
+ }
1632
+ /** @internal Singleton instance of the manager */
1633
+ VizbeeHomeSSOManager.instance = null;
1634
+
1635
+ const UNKNOWN_VALUE = 'UNKNOWN';
1636
+
1637
+ /**
1638
+ * @class HomeSSOContext
1639
+ * @description Context provider for Vizbee Home SSO functionality
1640
+ */
1641
+ class HomeSSOContext {
1642
+ constructor() {
1643
+ this.homeSSOUIManager = null;
1644
+ }
1645
+ /**
1646
+ * Gets the singleton instance of HomeSSOContext
1647
+ * @returns The singleton instance of HomeSSOContext
1648
+ */
1649
+ static getInstance() {
1650
+ if (!HomeSSOContext.instance) {
1651
+ HomeSSOContext.instance = new HomeSSOContext();
1652
+ }
1653
+ return HomeSSOContext.instance;
1654
+ }
1655
+ /**
1656
+ * Gets the HomeSSOManager instance
1657
+ * @returns The singleton instance of VizbeeHomeSSOManager
1658
+ */
1659
+ getHomeSSOManager() {
1660
+ return VizbeeHomeSSOManager.getInstance();
1661
+ }
1662
+ /**
1663
+ * Gets the HomeSSOUIManager instance
1664
+ * @param config Optional UI configuration including theme settings
1665
+ * @returns The singleton instance of VizbeeHomeSSOUIManager
1666
+ */
1667
+ getHomeSSOUIManager() {
1668
+ return VizbeeHomeSSOUIManager.getInstance();
1669
+ }
1670
+ enableLogger(enable) {
1671
+ logger.setConfig({
1672
+ enabled: enable,
1673
+ });
1674
+ }
1675
+ setLoggerLevel(level) {
1676
+ logger.setConfig({
1677
+ enabled: true,
1678
+ level: level,
1679
+ });
1680
+ }
1681
+ }
1682
+ HomeSSOContext.instance = null;
1683
+ const init = () => {
1684
+ // Initialize the global namespace
1685
+ if (typeof window !== 'undefined') {
1686
+ if (!window.vizbee) {
1687
+ window.addEventListener('VIZBEE_SDK_READY', () => {
1688
+ if (window.vizbee) {
1689
+ setupHomeSSO();
1690
+ }
1691
+ });
1692
+ }
1693
+ else {
1694
+ setupHomeSSO();
1695
+ }
1696
+ }
1697
+ };
1698
+ const setupHomeSSO = () => {
1699
+ window.vizbee.homesso = {
1700
+ HomeSSOContext: HomeSSOContext,
1701
+ messages: {
1702
+ ProgressStatus,
1703
+ SuccessStatus,
1704
+ FailureStatus,
1705
+ },
1706
+ LoggerLevel: exports.LogLevel,
1707
+ // Replaced at build time with package.json's version by
1708
+ // @rollup/plugin-replace (same token the metrics manager uses), so
1709
+ // integrators can read the loaded SDK version off the namespace.
1710
+ VERSION: '1.0.1',
1711
+ };
1712
+ window.dispatchEvent(new Event('VIZBEE_HOMESSO_READY'));
1713
+ };
1714
+ init();
1715
+
1716
+ exports.FailureStatus = FailureStatus;
1717
+ exports.HomeSSOContext = HomeSSOContext;
1718
+ exports.ProgressStatus = ProgressStatus;
1719
+ exports.SuccessStatus = SuccessStatus;
1720
+ exports.UNKNOWN_VALUE = UNKNOWN_VALUE;
1721
+ exports.VizbeeHomeSSOManager = VizbeeHomeSSOManager;
1722
+ exports.VizbeeHomeSSOUIManager = VizbeeHomeSSOUIManager;