@tolinku/web-sdk 0.1.0
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/LICENSE +21 -0
- package/README.md +198 -0
- package/dist/index.d.mts +298 -0
- package/dist/index.d.ts +298 -0
- package/dist/index.js +913 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +910 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +56 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/client.ts","../src/analytics.ts","../src/referrals.ts","../src/deferred.ts","../src/storage.ts","../src/sanitize.ts","../src/banners.ts","../src/messages.ts","../src/index.ts"],"names":["isSafeUrl"],"mappings":"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","file":"index.js","sourcesContent":["import type { TolinkuConfig } from './types.js';\n\nconst MAX_RETRIES = 3;\nconst BASE_DELAY_MS = 500;\nconst MAX_JITTER_MS = 250;\n\nexport class HttpClient {\n private _baseUrl: string;\n private apiKey: string;\n private abortController: AbortController | null = null;\n\n constructor(config: Required<TolinkuConfig>) {\n this._baseUrl = config.baseUrl.replace(/\\/+$/, '');\n this.apiKey = config.apiKey;\n }\n\n /** Abort all in-flight requests (called by Tolinku.destroy()) */\n abort(): void {\n if (this.abortController) {\n this.abortController.abort();\n this.abortController = null;\n }\n }\n\n /** Get a signal for the current request batch, creating a controller if needed */\n private get signal(): AbortSignal {\n if (!this.abortController) {\n this.abortController = new AbortController();\n }\n return this.abortController.signal;\n }\n\n /** Public accessor for the base URL */\n get baseUrl(): string {\n return this._baseUrl;\n }\n\n /** Public accessor for the API key (used by sendBeacon which cannot set custom headers) */\n get key(): string {\n return this.apiKey;\n }\n\n async get<T>(path: string, params?: Record<string, string>): Promise<T> {\n let url = this._baseUrl + path;\n if (params) {\n const qs = new URLSearchParams(params).toString();\n if (qs) url += '?' + qs;\n }\n\n const res = await this.fetchWithRetry(url, {\n method: 'GET',\n headers: this.headers(),\n signal: this.signal,\n });\n\n if (!res.ok) {\n const body = await res.json().catch(() => ({ error: res.statusText }));\n throw new TolinkuError(body.error || res.statusText, res.status, body.code);\n }\n\n return this.parseJson<T>(res);\n }\n\n async post<T>(path: string, body?: Record<string, unknown>): Promise<T> {\n const res = await this.fetchWithRetry(this._baseUrl + path, {\n method: 'POST',\n headers: {\n ...this.headers(),\n 'Content-Type': 'application/json',\n },\n body: body ? JSON.stringify(body) : undefined,\n signal: this.signal,\n });\n\n if (!res.ok) {\n const data = await res.json().catch(() => ({ error: res.statusText }));\n throw new TolinkuError(data.error || res.statusText, res.status, data.code);\n }\n\n return this.parseJson<T>(res);\n }\n\n /** GET without API key auth (for public endpoints like banner config) */\n async getPublic<T>(path: string, params?: Record<string, string>): Promise<T> {\n let url = this._baseUrl + path;\n if (params) {\n const qs = new URLSearchParams(params).toString();\n if (qs) url += '?' + qs;\n }\n\n const res = await this.fetchWithRetry(url, {\n method: 'GET',\n signal: this.signal,\n });\n\n if (!res.ok) {\n const body = await res.json().catch(() => ({ error: res.statusText }));\n throw new TolinkuError(body.error || res.statusText, res.status, body.code);\n }\n\n return this.parseJson<T>(res);\n }\n\n /** POST without API key auth (for public endpoints like deferred claim) */\n async postPublic<T>(path: string, body?: Record<string, unknown>): Promise<T> {\n const res = await this.fetchWithRetry(this._baseUrl + path, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: body ? JSON.stringify(body) : undefined,\n signal: this.signal,\n });\n\n if (!res.ok) {\n const data = await res.json().catch(() => ({ error: res.statusText }));\n throw new TolinkuError(data.error || res.statusText, res.status, data.code);\n }\n\n return this.parseJson<T>(res);\n }\n\n /**\n * Fetch with retry logic. Retries on network errors, HTTP 429, and 5xx responses.\n * Uses exponential backoff: BASE_DELAY_MS * 2^attempt + random jitter.\n * Respects Retry-After header on 429 responses.\n * Does NOT retry on 4xx errors (except 429) or successful responses.\n */\n private async fetchWithRetry(url: string, init: RequestInit): Promise<Response> {\n let lastError: unknown;\n\n for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {\n try {\n const res = await fetch(url, init);\n\n // Successful or non-retryable 4xx: return immediately\n if (res.ok || (res.status >= 400 && res.status < 500 && res.status !== 429)) {\n return res;\n }\n\n // Retryable status (429 or 5xx): retry if attempts remain\n if (attempt < MAX_RETRIES) {\n const delay = this.computeDelay(attempt, res);\n await this.sleep(delay, init.signal as AbortSignal | undefined);\n continue;\n }\n\n // Out of retries: return the last response so the caller can handle the error\n return res;\n } catch (err) {\n // If the request was aborted, do not retry\n if (err instanceof DOMException && err.name === 'AbortError') {\n throw err;\n }\n\n lastError = err;\n\n // Network error: retry if attempts remain\n if (attempt < MAX_RETRIES) {\n const delay = this.computeDelay(attempt);\n await this.sleep(delay, init.signal as AbortSignal | undefined);\n continue;\n }\n }\n }\n\n // All retries exhausted due to network errors\n throw lastError;\n }\n\n /** Compute backoff delay: BASE_DELAY_MS * 2^attempt + random jitter (0 to MAX_JITTER_MS) */\n private computeDelay(attempt: number, res?: Response): number {\n // Respect Retry-After header on 429 responses\n if (res && res.status === 429) {\n const retryAfter = res.headers.get('Retry-After');\n if (retryAfter) {\n const seconds = Number(retryAfter);\n if (!isNaN(seconds) && seconds > 0) {\n return seconds * 1000;\n }\n }\n }\n\n const exponential = BASE_DELAY_MS * Math.pow(2, attempt);\n const jitter = Math.random() * MAX_JITTER_MS;\n return exponential + jitter;\n }\n\n /** Sleep for a given duration, but throw if the signal is aborted */\n private sleep(ms: number, signal?: AbortSignal): Promise<void> {\n return new Promise((resolve, reject) => {\n if (signal?.aborted) {\n reject(new DOMException('The operation was aborted.', 'AbortError'));\n return;\n }\n\n const timer = setTimeout(resolve, ms);\n\n signal?.addEventListener('abort', () => {\n clearTimeout(timer);\n reject(new DOMException('The operation was aborted.', 'AbortError'));\n }, { once: true });\n });\n }\n\n /** Safely parse JSON from a response, handling non-JSON 200s */\n private async parseJson<T>(res: Response): Promise<T> {\n try {\n return await res.json() as T;\n } catch {\n throw new TolinkuError('Invalid JSON in response body', res.status);\n }\n }\n\n private headers(): Record<string, string> {\n return {\n 'X-API-Key': this.apiKey,\n };\n }\n}\n\nexport class TolinkuError extends Error {\n status: number;\n code: string | undefined;\n\n constructor(message: string, status: number, code?: string) {\n super(message);\n this.name = 'TolinkuError';\n this.status = status;\n this.code = code;\n }\n}\n","import type { HttpClient } from './client.js';\nimport type { TrackProperties } from './types.js';\n\nconst BATCH_SIZE = 10;\nconst FLUSH_INTERVAL_MS = 5000;\nconst MAX_QUEUE_SIZE = 1000;\n\ninterface QueuedEvent {\n event_type: string;\n properties: TrackProperties;\n}\n\nexport class Analytics {\n private queue: QueuedEvent[] = [];\n private flushTimer: ReturnType<typeof setTimeout> | null = null;\n private unloadHandler: (() => void) | null = null;\n\n constructor(private client: HttpClient) {\n // Listen for page unload to send remaining events via sendBeacon\n if (typeof window !== 'undefined') {\n this.unloadHandler = () => this.flushBeacon();\n window.addEventListener('beforeunload', this.unloadHandler);\n }\n }\n\n /**\n * Track a custom event. Event type must start with \"custom.\" and match\n * the pattern custom.[a-z0-9_]+\n *\n * Events are queued and sent in batches for efficiency.\n */\n async track(eventType: string, properties?: TrackProperties): Promise<void> {\n if (typeof eventType !== 'string' || eventType.trim().length === 0) {\n throw new Error('Tolinku: event name must be a non-empty string');\n }\n\n if (!eventType.startsWith('custom.')) {\n eventType = 'custom.' + eventType;\n }\n\n // Validate the full event name matches the required pattern\n const eventNameRegex = /^custom\\.[a-z0-9_]+$/;\n if (!eventNameRegex.test(eventType)) {\n throw new Error(\n `Tolinku: event name \"${eventType}\" is invalid. Event names must match the pattern \"custom.[a-z0-9_]+\" (lowercase letters, numbers, and underscores only after \"custom.\")`\n );\n }\n\n this.queue.push({\n event_type: eventType,\n properties: properties || {},\n });\n\n // Start the flush timer if this is the first queued event\n if (this.queue.length === 1 && !this.flushTimer) {\n this.flushTimer = setTimeout(() => {\n this.flushTimer = null;\n this.flush();\n }, FLUSH_INTERVAL_MS);\n }\n\n // Flush immediately if the batch is full\n if (this.queue.length >= BATCH_SIZE) {\n await this.flush();\n }\n }\n\n /** Send all queued events to the server */\n async flush(): Promise<void> {\n if (this.flushTimer) {\n clearTimeout(this.flushTimer);\n this.flushTimer = null;\n }\n\n if (this.queue.length === 0) return;\n\n // Drain the queue before sending (so new events during the request are not lost)\n const events = this.queue.splice(0);\n\n try {\n const result = await this.client.post<{ ok: boolean; accepted?: number; errors?: string[] }>('/v1/api/analytics/batch', { events });\n if (result.errors && result.errors.length > 0) {\n console.warn('[TolinkuSDK] Batch partial failure:', result.errors);\n }\n } catch {\n // If sending fails, re-queue the events at the front so they can be retried\n this.queue.unshift(...events);\n\n // Drop the oldest events if the queue exceeds the max size to prevent memory leaks\n if (this.queue.length > MAX_QUEUE_SIZE) {\n this.queue.splice(0, this.queue.length - MAX_QUEUE_SIZE);\n }\n }\n }\n\n /**\n * Flush remaining events using navigator.sendBeacon (best-effort).\n * Called on page unload when a normal fetch may not complete.\n */\n private flushBeacon(): void {\n if (this.queue.length === 0) return;\n\n const events = this.queue.splice(0);\n const url = this.client.baseUrl + '/v1/api/analytics/batch';\n const body = JSON.stringify({ events, apiKey: this.client.key });\n\n if (typeof navigator !== 'undefined' && typeof navigator.sendBeacon === 'function') {\n navigator.sendBeacon(url, new Blob([body], { type: 'application/json' }));\n }\n }\n\n /** Clean up timers and event listeners. Called by Tolinku.destroy(). */\n destroy(): void {\n // Flush remaining events (best-effort via beacon since destroy may be called during teardown)\n this.flushBeacon();\n\n if (this.flushTimer) {\n clearTimeout(this.flushTimer);\n this.flushTimer = null;\n }\n\n if (typeof window !== 'undefined' && this.unloadHandler) {\n window.removeEventListener('beforeunload', this.unloadHandler);\n this.unloadHandler = null;\n }\n }\n}\n","import type { HttpClient } from './client.js';\nimport type {\n CreateReferralOptions,\n CreateReferralResult,\n CompleteReferralOptions,\n CompleteReferralResult,\n MilestoneOptions,\n MilestoneResult,\n ReferralInfo,\n LeaderboardEntry,\n} from './types.js';\n\nexport class Referrals {\n constructor(private client: HttpClient) {}\n\n /** Create a new referral for a user */\n async create(options: CreateReferralOptions): Promise<CreateReferralResult> {\n return this.client.post('/v1/api/referral/create', {\n user_id: options.userId,\n metadata: options.metadata,\n user_name: options.userName,\n });\n }\n\n /** Get referral info by code */\n async get(code: string): Promise<ReferralInfo> {\n return this.client.get(`/v1/api/referral/${encodeURIComponent(code)}`);\n }\n\n /** Complete a referral (mark as converted) */\n async complete(options: CompleteReferralOptions): Promise<CompleteReferralResult> {\n return this.client.post('/v1/api/referral/complete', {\n referral_code: options.code,\n referred_user_id: options.referredUserId,\n milestone: options.milestone,\n referred_user_name: options.referredUserName,\n });\n }\n\n /** Update a referral milestone */\n async milestone(options: MilestoneOptions): Promise<MilestoneResult> {\n return this.client.post('/v1/api/referral/milestone', {\n referral_code: options.code,\n milestone: options.milestone,\n });\n }\n\n /** Claim a referral reward */\n async claimReward(code: string): Promise<{ success: boolean; referral_code: string; reward_claimed: boolean }> {\n return this.client.post('/v1/api/referral/claim-reward', {\n referral_code: code,\n });\n }\n\n /** Get the referral leaderboard */\n async leaderboard(limit: number = 25): Promise<{ leaderboard: LeaderboardEntry[] }> {\n return this.client.get('/v1/api/referral/leaderboard', {\n limit: String(limit),\n });\n }\n}\n","import type { HttpClient } from './client.js';\nimport type { DeferredLink, ClaimBySignalsOptions } from './types.js';\n\nexport class Deferred {\n constructor(private client: HttpClient) {}\n\n /** Claim a deferred deep link by referrer token (from Play Store referrer or clipboard) */\n async claimByToken(token: string): Promise<DeferredLink | null> {\n try {\n return await this.client.getPublic<DeferredLink>('/v1/api/deferred/claim', { token });\n } catch (err) {\n console.warn('[Tolinku] Failed to claim deferred link by token:', err);\n return null;\n }\n }\n\n /** Claim a deferred deep link by device signal matching */\n async claimBySignals(options: ClaimBySignalsOptions): Promise<DeferredLink | null> {\n try {\n return await this.client.postPublic<DeferredLink>('/v1/api/deferred/claim-by-signals', {\n appspace_id: options.appspaceId,\n timezone: options.timezone || Intl.DateTimeFormat().resolvedOptions().timeZone,\n language: options.language || navigator.language,\n screen_width: options.screenWidth || window.screen.width,\n screen_height: options.screenHeight || window.screen.height,\n });\n } catch (err) {\n console.warn('[Tolinku] Failed to claim deferred link by signals:', err);\n return null;\n }\n }\n}\n","const BANNER_KEY = 'tolinku_banner_dismissed';\nconst MESSAGE_KEY = 'tolinku_message_dismissed';\nconst MESSAGE_IMPRESSIONS_KEY = 'tolinku_message_impressions';\nconst MESSAGE_LAST_SHOWN_KEY = 'tolinku_message_last_shown';\n\nfunction getStore(key: string): Record<string, string> {\n try {\n return JSON.parse(localStorage.getItem(key) || '{}');\n } catch {\n return {};\n }\n}\n\nfunction setStore(key: string, data: Record<string, string>): void {\n try {\n localStorage.setItem(key, JSON.stringify(data));\n } catch {\n // Storage full or unavailable\n }\n}\n\n/**\n * Check if a banner was recently dismissed. When dismissDays is 0,\n * the banner is never considered dismissed (i.e. it shows on every\n * page load with no persistence).\n */\nexport function isBannerDismissed(bannerId: string, dismissDays: number | null): boolean {\n // dismissDays: 0 means \"show every page load\" (no persistence)\n if (!dismissDays || dismissDays <= 0) return false;\n const data = getStore(BANNER_KEY);\n const entry = data[bannerId];\n if (!entry) return false;\n const dismissedAt = new Date(entry).getTime();\n return (Date.now() - dismissedAt) < (dismissDays * 86400000);\n}\n\nexport function saveBannerDismissal(bannerId: string): void {\n const data = getStore(BANNER_KEY);\n data[bannerId] = new Date().toISOString();\n setStore(BANNER_KEY, data);\n}\n\n/**\n * Check if a message was recently dismissed. When dismissDays is 0,\n * the message is never considered dismissed (i.e. it shows on every\n * page load with no persistence).\n */\nexport function isMessageDismissed(messageId: string, dismissDays: number | null): boolean {\n // dismissDays: 0 means \"show every page load\" (no persistence)\n if (!dismissDays || dismissDays <= 0) return false;\n const data = getStore(MESSAGE_KEY);\n const entry = data[messageId];\n if (!entry) return false;\n const dismissedAt = new Date(entry).getTime();\n return (Date.now() - dismissedAt) < (dismissDays * 86400000);\n}\n\nexport function saveMessageDismissal(messageId: string): void {\n const data = getStore(MESSAGE_KEY);\n data[messageId] = new Date().toISOString();\n setStore(MESSAGE_KEY, data);\n}\n\n/**\n * Check if a message should be suppressed based on max_impressions\n * or min_interval_hours. Returns true if the message should NOT be shown.\n */\nexport function isMessageSuppressed(\n messageId: string,\n maxImpressions: number | null,\n minIntervalHours: number | null,\n): boolean {\n // Check max impressions\n if (maxImpressions !== null && maxImpressions > 0) {\n const impressions = getStore(MESSAGE_IMPRESSIONS_KEY);\n const count = parseInt(impressions[messageId] || '0', 10);\n if (count >= maxImpressions) return true;\n }\n\n // Check min interval\n if (minIntervalHours !== null && minIntervalHours > 0) {\n const lastShown = getStore(MESSAGE_LAST_SHOWN_KEY);\n const entry = lastShown[messageId];\n if (entry) {\n const lastShownAt = new Date(entry).getTime();\n const intervalMs = minIntervalHours * 3600000;\n if ((Date.now() - lastShownAt) < intervalMs) return true;\n }\n }\n\n return false;\n}\n\n/** Record that a message was shown (increment impression count and update last-shown time). */\nexport function recordMessageImpression(messageId: string): void {\n // Increment impression count\n const impressions = getStore(MESSAGE_IMPRESSIONS_KEY);\n const count = parseInt(impressions[messageId] || '0', 10);\n impressions[messageId] = String(count + 1);\n setStore(MESSAGE_IMPRESSIONS_KEY, impressions);\n\n // Update last-shown timestamp\n const lastShown = getStore(MESSAGE_LAST_SHOWN_KEY);\n lastShown[messageId] = new Date().toISOString();\n setStore(MESSAGE_LAST_SHOWN_KEY, lastShown);\n}\n","/**\n * Sanitize a CSS color value. Allows hex colors, rgb(), rgba(), hsl(), hsla(),\n * and named CSS colors. Strips anything containing ; or { or } to prevent\n * CSS injection.\n */\nexport function sanitizeCssColor(value: string | undefined): string | null {\n if (!value) return null;\n const trimmed = value.trim();\n // Block dangerous characters that could escape the CSS property\n if (/[;{}]/.test(trimmed)) return null;\n // Allow hex colors\n if (/^#([0-9a-fA-F]{3}|[0-9a-fA-F]{4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/.test(trimmed)) return trimmed;\n // Allow rgb/rgba/hsl/hsla functions (only digits, commas, spaces, dots, percentages, slashes)\n if (/^(rgb|rgba|hsl|hsla)\\([0-9a-zA-Z,.%\\s/]+\\)$/.test(trimmed)) return trimmed;\n // Allow named CSS colors (letters and hyphens only, reasonable length)\n if (/^[a-zA-Z-]{1,30}$/.test(trimmed)) return trimmed;\n return null;\n}\n","import type { HttpClient } from './client.js';\nimport type { BannerConfig, BannerItem, ShowBannerOptions } from './types.js';\nimport { isBannerDismissed, saveBannerDismissal } from './storage.js';\nimport { sanitizeCssColor } from './sanitize.js';\n\nexport class Banners {\n private container: HTMLDivElement | null = null;\n private styleEl: HTMLStyleElement | null = null;\n\n constructor(private client: HttpClient) {}\n\n /** Fetch banner config and show the highest-priority banner */\n async show(options: ShowBannerOptions = {}, userId?: string | null): Promise<void> {\n const params: Record<string, string> = {};\n if (userId) params.user_id = userId;\n const config = await this.client.getPublic<BannerConfig>('/v1/api/banner/config', params);\n if (!config.enabled || !config.banners || config.banners.length === 0) return;\n\n // Sort by priority descending (server may not guarantee ordering)\n config.banners.sort((a, b) => b.priority - a.priority);\n\n let banner: BannerItem | null = null;\n for (const b of config.banners) {\n if (options.label && b.label !== options.label) continue;\n if (!isBannerDismissed(b.id, b.dismiss_days)) {\n banner = b;\n break;\n }\n }\n if (!banner) return;\n\n this.render(config, banner, options);\n }\n\n /** Remove the banner from the DOM */\n dismiss(): void {\n if (this.container) {\n this.container.classList.remove('tolk-visible');\n const pos = this.container.dataset.position || 'top';\n document.body.style.removeProperty(pos === 'top' ? 'padding-top' : 'padding-bottom');\n setTimeout(() => {\n this.container?.remove();\n this.styleEl?.remove();\n this.container = null;\n this.styleEl = null;\n }, 400);\n }\n }\n\n private render(config: BannerConfig, banner: BannerItem, options: ShowBannerOptions): void {\n // Remove existing banner if any\n if (this.container) {\n this.container.remove();\n this.styleEl?.remove();\n }\n\n const position = options.position || banner.position || 'top';\n const bgColor = sanitizeCssColor(banner.background_color) || '#ffffff';\n const textColor = sanitizeCssColor(banner.text_color) || '#000000';\n const ctaText = banner.cta_text || 'Open';\n const baseUrl = this.client.baseUrl;\n // Use the per-banner action_url if available, fall back to install_url\n const installUrl = banner.action_url || (baseUrl + (config.install_url || '/install'));\n\n const safeTop = position === 'top' ? 'padding-top: env(safe-area-inset-top, 0px);' : '';\n const safeBottom = position === 'bottom' ? 'padding-bottom: env(safe-area-inset-bottom, 0px);' : '';\n\n const container = document.createElement('div');\n container.id = 'tolinku-banner';\n container.setAttribute('role', 'banner');\n container.setAttribute('aria-live', 'polite');\n container.dataset.position = position;\n\n const style = document.createElement('style');\n style.textContent = `\n #tolinku-banner {\n position: fixed;\n ${position}: 0;\n left: 0; right: 0;\n z-index: 999999;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n transform: translateY(${position === 'top' ? '-100%' : '100%'});\n transition: transform 0.35s ease;\n ${safeTop}${safeBottom}\n }\n #tolinku-banner.tolk-visible { transform: translateY(0); }\n #tolinku-banner .tolk-inner {\n display: flex; align-items: center; gap: 10px;\n padding: 10px 14px;\n background: ${bgColor}; color: ${textColor};\n box-shadow: 0 2px 8px rgba(0,0,0,0.15);\n }\n #tolinku-banner .tolk-close {\n background: none; border: none; font-size: 20px; line-height: 1;\n cursor: pointer; color: ${textColor}; opacity: 0.6; padding: 0 4px; flex-shrink: 0;\n }\n #tolinku-banner .tolk-close:hover { opacity: 1; }\n #tolinku-banner .tolk-icon {\n width: 40px; height: 40px; border-radius: 10px; flex-shrink: 0; object-fit: cover;\n }\n #tolinku-banner .tolk-text { flex: 1; min-width: 0; }\n #tolinku-banner .tolk-title {\n font-size: 14px; font-weight: 600; margin: 0;\n white-space: nowrap; overflow: hidden; text-overflow: ellipsis;\n }\n #tolinku-banner .tolk-body {\n font-size: 12px; margin: 0; opacity: 0.75;\n white-space: nowrap; overflow: hidden; text-overflow: ellipsis;\n }\n #tolinku-banner .tolk-cta {\n display: inline-block; padding: 6px 16px; border-radius: 100px;\n font-size: 13px; font-weight: 600; text-decoration: none;\n background: ${textColor}; color: ${bgColor}; flex-shrink: 0; text-align: center;\n }\n `;\n\n const inner = document.createElement('div');\n inner.className = 'tolk-inner';\n\n // Close button\n const closeBtn = document.createElement('button');\n closeBtn.className = 'tolk-close';\n closeBtn.setAttribute('aria-label', 'Dismiss banner');\n closeBtn.textContent = '\\u00d7';\n closeBtn.addEventListener('click', () => {\n saveBannerDismissal(banner.id);\n this.dismiss();\n });\n inner.appendChild(closeBtn);\n\n // App icon\n if (config.app_icon && isSafeUrl(config.app_icon)) {\n const icon = document.createElement('img');\n icon.className = 'tolk-icon';\n icon.src = config.app_icon;\n icon.alt = config.app_name || 'App';\n inner.appendChild(icon);\n }\n\n // Text\n const textWrap = document.createElement('div');\n textWrap.className = 'tolk-text';\n const titleEl = document.createElement('p');\n titleEl.className = 'tolk-title';\n titleEl.textContent = banner.title || config.app_name || 'Get the App';\n textWrap.appendChild(titleEl);\n if (banner.body) {\n const bodyEl = document.createElement('p');\n bodyEl.className = 'tolk-body';\n bodyEl.textContent = banner.body;\n textWrap.appendChild(bodyEl);\n }\n inner.appendChild(textWrap);\n\n // CTA\n const cta = document.createElement('a');\n cta.className = 'tolk-cta';\n cta.href = isSafeUrl(installUrl) ? installUrl : '#';\n cta.textContent = ctaText;\n inner.appendChild(cta);\n\n container.appendChild(inner);\n document.head.appendChild(style);\n document.body.appendChild(container);\n\n this.container = container;\n this.styleEl = style;\n\n // Animate in and add body padding\n requestAnimationFrame(() => {\n requestAnimationFrame(() => {\n container.classList.add('tolk-visible');\n const bannerHeight = container.offsetHeight + 'px';\n if (position === 'top') {\n document.body.style.paddingTop = bannerHeight;\n } else {\n document.body.style.paddingBottom = bannerHeight;\n }\n });\n });\n }\n}\n\n/** Only allow http: and https: protocols to prevent javascript: XSS */\nfunction isSafeUrl(url: string): boolean {\n try {\n const parsed = new URL(url, window.location.href);\n return parsed.protocol === 'http:' || parsed.protocol === 'https:';\n } catch {\n return false;\n }\n}\n\n","import type { HttpClient } from './client.js';\nimport type { Message, MessageComponent, ShowMessageOptions } from './types.js';\nimport { isMessageDismissed, saveMessageDismissal, isMessageSuppressed, recordMessageImpression } from './storage.js';\nimport { sanitizeCssColor } from './sanitize.js';\n\nexport class Messages {\n private overlay: HTMLDivElement | null = null;\n private styleEl: HTMLStyleElement | null = null;\n\n constructor(private client: HttpClient) {}\n\n /** Fetch messages and show the highest-priority non-dismissed one */\n async show(options: ShowMessageOptions = {}, userId?: string | null): Promise<void> {\n const params: Record<string, string> = {};\n if (options.trigger) params.trigger = options.trigger;\n if (userId) params.user_id = userId;\n\n const data = await this.client.get<{ messages: Message[] }>('/v1/api/messages', params);\n if (!data.messages || data.messages.length === 0) return;\n\n // Filter dismissed, filter by triggerValue (server only filters by trigger), and sort by priority\n const candidates = data.messages\n .filter(m => !isMessageDismissed(m.id, m.dismiss_days))\n .filter(m => !isMessageSuppressed(m.id, m.max_impressions, m.min_interval_hours))\n .filter(m => !options.triggerValue || m.trigger_value === options.triggerValue)\n .sort((a, b) => b.priority - a.priority);\n\n if (candidates.length === 0) return;\n\n const message = candidates[0];\n recordMessageImpression(message.id);\n this.render(message, options);\n }\n\n /** Remove the message overlay */\n dismiss(): void {\n if (this.overlay) {\n this.overlay.style.opacity = '0';\n setTimeout(() => {\n this.overlay?.remove();\n this.styleEl?.remove();\n this.overlay = null;\n this.styleEl = null;\n }, 300);\n }\n }\n\n private render(message: Message, options: ShowMessageOptions): void {\n if (this.overlay) {\n this.overlay.remove();\n this.styleEl?.remove();\n }\n\n const style = document.createElement('style');\n style.textContent = `\n .tolk-msg-overlay {\n position: fixed; top: 0; right: 0; bottom: 0; left: 0; z-index: 1000000;\n display: flex; align-items: center; justify-content: center;\n background: rgba(0,0,0,0.5);\n opacity: 0; transition: opacity 0.3s ease;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n }\n .tolk-msg-overlay.tolk-visible { opacity: 1; }\n .tolk-msg-card {\n position: relative; max-width: 375px; width: 90%;\n max-height: 80vh; overflow-y: auto;\n border-radius: 16px; padding: 24px;\n box-shadow: 0 20px 60px rgba(0,0,0,0.3);\n }\n .tolk-msg-close {\n position: absolute; top: 12px; right: 12px;\n background: rgba(0,0,0,0.1); border: none; border-radius: 50%;\n width: 28px; height: 28px; font-size: 16px; line-height: 1;\n cursor: pointer; display: flex; align-items: center; justify-content: center;\n color: inherit; opacity: 0.6;\n }\n .tolk-msg-close:hover { opacity: 1; }\n `;\n\n const overlay = document.createElement('div');\n overlay.className = 'tolk-msg-overlay';\n overlay.addEventListener('click', (e) => {\n if (e.target === overlay) {\n saveMessageDismissal(message.id);\n options.onDismiss?.(message.id);\n this.dismiss();\n }\n });\n\n const card = document.createElement('div');\n card.className = 'tolk-msg-card';\n card.style.background = sanitizeCssColor(message.background_color) || '#ffffff';\n\n // Close button\n const closeBtn = document.createElement('button');\n closeBtn.className = 'tolk-msg-close';\n closeBtn.setAttribute('aria-label', 'Close message');\n closeBtn.textContent = '\\u00d7';\n closeBtn.addEventListener('click', () => {\n saveMessageDismissal(message.id);\n options.onDismiss?.(message.id);\n this.dismiss();\n });\n card.appendChild(closeBtn);\n\n // Render Puck content tree\n if (message.content && message.content.content) {\n for (const component of message.content.content) {\n const el = this.renderComponent(component, message.id, options);\n if (el) card.appendChild(el);\n }\n }\n\n overlay.appendChild(card);\n document.head.appendChild(style);\n document.body.appendChild(overlay);\n\n this.overlay = overlay;\n this.styleEl = style;\n\n requestAnimationFrame(() => {\n requestAnimationFrame(() => {\n overlay.classList.add('tolk-visible');\n });\n });\n }\n\n private renderComponent(\n component: MessageComponent,\n messageId: string,\n options: ShowMessageOptions,\n ): HTMLElement | null {\n const props = component.props;\n\n switch (component.type) {\n case 'Heading': {\n const el = document.createElement('h2');\n el.textContent = (props.text as string) || '';\n el.style.fontSize = (props.fontSize as number || 28) + 'px';\n el.style.fontWeight = '700';\n el.style.color = sanitizeCssColor(props.color as string) || '#1B1B1B';\n el.style.textAlign = sanitizeTextAlign(props.alignment as string);\n el.style.lineHeight = '1.2';\n el.style.margin = '0 0 8px 0';\n return el;\n }\n\n case 'TextBlock': {\n const el = document.createElement('p');\n el.textContent = (props.content as string) || '';\n el.style.fontSize = (props.fontSize as number || 15) + 'px';\n el.style.color = sanitizeCssColor(props.color as string) || '#555555';\n el.style.textAlign = sanitizeTextAlign(props.alignment as string);\n el.style.lineHeight = '1.5';\n el.style.margin = '0 0 8px 0';\n return el;\n }\n\n case 'Image': {\n const url = (props.url as string) || '';\n if (!isSafeUrl(url)) return null;\n const el = document.createElement('img');\n el.src = url;\n el.alt = (props.alt as string) || '';\n const width = (props.width as string) || '100%';\n el.style.width = width.endsWith('px') || width.endsWith('%') ? width : width + 'px';\n el.style.borderRadius = (props.borderRadius as number || 8) + 'px';\n el.style.display = 'block';\n el.style.margin = '0 auto 8px auto';\n return el;\n }\n\n case 'Button': {\n const el = document.createElement('button');\n el.textContent = (props.label as string) || 'Click';\n el.style.backgroundColor = sanitizeCssColor(props.bgColor as string) || '#1B1B1B';\n el.style.color = sanitizeCssColor(props.textColor as string) || '#ffffff';\n el.style.fontSize = (props.fontSize as number || 16) + 'px';\n el.style.borderRadius = (props.borderRadius as number || 8) + 'px';\n el.style.border = 'none';\n el.style.padding = '10px 20px';\n el.style.cursor = 'pointer';\n el.style.fontWeight = '600';\n el.style.margin = '8px 0';\n if (props.fullWidth) {\n el.style.width = '100%';\n }\n el.addEventListener('click', () => {\n const action = (props.action as string) || '';\n if (options.onButtonPress) {\n options.onButtonPress(action, messageId);\n } else if (action) {\n // Only allow http: and https: URLs to prevent javascript: XSS\n if (isSafeUrl(action)) {\n window.location.href = action;\n }\n }\n });\n return el;\n }\n\n case 'Section': {\n const el = document.createElement('div');\n if (props.bgColor) el.style.backgroundColor = sanitizeCssColor(props.bgColor as string) || '';\n el.style.padding = (props.padding as number || 16) + 'px';\n el.style.borderRadius = (props.borderRadius as number || 0) + 'px';\n el.style.margin = '8px 0';\n if (props.bgImage) {\n const sanitizedUrl = sanitizeCssUrl(props.bgImage as string);\n if (sanitizedUrl) {\n el.style.backgroundImage = `url(\"${sanitizedUrl}\")`;\n el.style.backgroundSize = sanitizeBackgroundSize(props.bgSize as string);\n el.style.backgroundPosition = 'center';\n }\n }\n // Render children if present\n const children = (props.children as MessageComponent[]) || [];\n for (const child of children) {\n const childEl = this.renderComponent(child, messageId, options);\n if (childEl) el.appendChild(childEl);\n }\n return el;\n }\n\n case 'Spacer': {\n const el = document.createElement('div');\n el.style.height = (props.height as number || 24) + 'px';\n return el;\n }\n\n case 'Divider': {\n const el = document.createElement('hr');\n el.style.border = 'none';\n el.style.borderTop = `${props.thickness || 1}px solid ${sanitizeCssColor(props.color as string) || '#e5e5e5'}`;\n el.style.margin = '8px 0';\n return el;\n }\n\n default:\n return null;\n }\n }\n}\n\n/** Only allow http: and https: protocols to prevent javascript: XSS */\nfunction isSafeUrl(url: string): boolean {\n try {\n const parsed = new URL(url, window.location.href);\n return parsed.protocol === 'http:' || parsed.protocol === 'https:';\n } catch {\n return false;\n }\n}\n\n/** Sanitize a URL for use in CSS url() values (escape quotes and backslashes, block dangerous schemes) */\nfunction sanitizeCssUrl(url: string): string | null {\n if (!isSafeUrl(url)) return null;\n // Escape characters that could break out of a quoted CSS url()\n return url.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"').replace(/\\n/g, '').replace(/\\r/g, '');\n}\n\n/** Sanitize text-align value to prevent CSS injection */\nfunction sanitizeTextAlign(value: string | undefined): string {\n const allowed = ['left', 'center', 'right', 'justify'];\n if (value && allowed.includes(value)) {\n return value;\n }\n return 'left';\n}\n\n/** Sanitize background-size value to prevent CSS injection */\nfunction sanitizeBackgroundSize(value: string | undefined): string {\n if (!value) return 'cover';\n\n const allowed = ['cover', 'contain', 'auto'];\n if (allowed.includes(value)) {\n return value;\n }\n\n // Allow valid CSS length patterns (e.g., \"100px\", \"50%\", \"10rem\", \"100px 50px\")\n const lengthPattern = /^(\\d+(\\.\\d+)?(px|%|em|rem|vh|vw)(\\s+\\d+(\\.\\d+)?(px|%|em|rem|vh|vw))?)$/;\n if (lengthPattern.test(value)) {\n return value;\n }\n\n return 'cover';\n}\n","import { HttpClient, TolinkuError } from './client.js';\nimport { Analytics } from './analytics.js';\nimport { Referrals } from './referrals.js';\nimport { Deferred } from './deferred.js';\nimport { Banners } from './banners.js';\nimport { Messages } from './messages.js';\nimport type {\n TolinkuConfig,\n TrackProperties,\n ShowBannerOptions,\n ShowMessageOptions,\n} from './types.js';\n\nexport class Tolinku {\n private client: HttpClient;\n\n /** Analytics: track custom events */\n readonly analytics: Analytics;\n /** Referrals: create, complete, milestone, leaderboard */\n readonly referrals: Referrals;\n /** Deferred deep links: claim by token or signals */\n readonly deferred: Deferred;\n\n private banners: Banners;\n private messages: Messages;\n\n /** The current user ID, used for segment targeting and analytics. */\n private _userId: string | null = null;\n\n constructor(config: TolinkuConfig) {\n if (!config.apiKey || typeof config.apiKey !== 'string') {\n throw new Error('Tolinku: apiKey is required and must be a non-empty string');\n }\n const resolvedConfig = {\n ...config,\n baseUrl: config.baseUrl || 'https://api.tolinku.com',\n };\n\n // Validate baseUrl is a proper URL\n try {\n const parsed = new URL(resolvedConfig.baseUrl);\n if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') {\n throw new Error('Tolinku: baseUrl must use http: or https: protocol');\n }\n } catch (e) {\n if (e instanceof Error && e.message.startsWith('Tolinku:')) throw e;\n throw new Error('Tolinku: baseUrl must be a valid URL (e.g. https://api.tolinku.com)');\n }\n\n this.client = new HttpClient(resolvedConfig);\n this.analytics = new Analytics(this.client);\n this.referrals = new Referrals(this.client);\n this.deferred = new Deferred(this.client);\n this.banners = new Banners(this.client);\n this.messages = new Messages(this.client);\n }\n\n /**\n * Set the user ID for segment targeting and analytics attribution.\n * Pass null to clear the user ID.\n */\n setUserId(userId: string | null): void {\n this._userId = userId;\n }\n\n /**\n * Track a custom event (shorthand for analytics.track).\n * Event type is auto-prefixed with \"custom.\" if not already.\n * If a userId has been set, it is automatically injected into event properties.\n */\n async track(eventType: string, properties?: TrackProperties): Promise<void> {\n const mergedProps = this._userId\n ? { user_id: this._userId, ...properties }\n : properties;\n return this.analytics.track(eventType, mergedProps);\n }\n\n /** Show a smart banner at the top or bottom of the page */\n async showBanner(options?: ShowBannerOptions): Promise<void> {\n return this.banners.show(options, this._userId);\n }\n\n /** Dismiss the currently visible smart banner */\n dismissBanner(): void {\n this.banners.dismiss();\n }\n\n /** Show an in-app message as a modal overlay */\n async showMessage(options?: ShowMessageOptions): Promise<void> {\n return this.messages.show(options, this._userId);\n }\n\n /** Dismiss the currently visible in-app message */\n dismissMessage(): void {\n this.messages.dismiss();\n }\n\n /** Flush any queued analytics events immediately */\n async flush(): Promise<void> {\n return this.analytics.flush();\n }\n\n /** Clean up all DOM elements, flush events, and cancel in-flight requests (e.g. before unmounting in SPAs) */\n destroy(): void {\n this.analytics.destroy();\n this.client.abort();\n this.banners.dismiss();\n this.messages.dismiss();\n }\n}\n\n// Re-export types and error class\nexport { TolinkuError } from './client.js';\nexport type {\n TolinkuConfig,\n TrackProperties,\n CreateReferralOptions,\n CreateReferralResult,\n CompleteReferralOptions,\n CompleteReferralResult,\n MilestoneOptions,\n MilestoneResult,\n ReferralInfo,\n LeaderboardEntry,\n DeferredLink,\n ClaimBySignalsOptions,\n BannerConfig,\n BannerItem,\n ShowBannerOptions,\n Message,\n MessageContent,\n MessageComponent,\n ShowMessageOptions,\n} from './types.js';\n"]}
|