diff --git a/packages/audience/sdk-sample-app/README.md b/packages/audience/sdk-sample-app/README.md new file mode 100644 index 0000000000..176895533d --- /dev/null +++ b/packages/audience/sdk-sample-app/README.md @@ -0,0 +1,178 @@ +# @imtbl/audience-sdk-sample-app + +Interactive sample app for `@imtbl/audience`. Every public method, every +typed `track()` event, and every reachable `AudienceErrorCode` has a +dedicated UI control so you can sanity-check SDK changes end-to-end +against the real sandbox backend and copy working call sites. + +> **Pre-release.** Depends on `@imtbl/audience@0.0.0`. The SDK API is +> stabilising but breaking changes may still land before the first +> published release. + +## Why vanilla JavaScript? + +Every other sample app in this monorepo (`packages/passport/sdk-sample-app`, +`packages/checkout/sdk-sample-app`, `packages/internal/dex/sdk-sample-app`, +`packages/internal/bridge/bridge-sample-app`) is React + Next.js with the +`@biom3` design system. This one is plain ES2020 served by a ~90-line Node +stdlib HTTP server. Intentional: the whole point is to demonstrate how +`@imtbl/audience` loads via a plain ` + + + diff --git a/packages/audience/sdk-sample-app/package.json b/packages/audience/sdk-sample-app/package.json new file mode 100644 index 0000000000..d8172d57bd --- /dev/null +++ b/packages/audience/sdk-sample-app/package.json @@ -0,0 +1,17 @@ +{ + "name": "@imtbl/audience-sdk-sample-app", + "description": "Interactive sample app for @imtbl/audience. Exercises every public method on the Audience class, every typed track() event, and every reachable AudienceErrorCode against the sandbox backend.", + "version": "0.0.0", + "author": "Immutable", + "private": true, + "engines": { + "node": ">=20.11.0" + }, + "devDependencies": { + "@imtbl/audience": "workspace:*" + }, + "scripts": { + "dev": "pnpm --filter @imtbl/audience run build && node ./serve.mjs", + "start": "pnpm dev" + } +} diff --git a/packages/audience/sdk-sample-app/sample-app.css b/packages/audience/sdk-sample-app/sample-app.css new file mode 100644 index 0000000000..a44b95caaf --- /dev/null +++ b/packages/audience/sdk-sample-app/sample-app.css @@ -0,0 +1,668 @@ +:root { + --bg: #f7f8fa; + --panel-bg: #ffffff; + --panel-border: #e6e8ec; + --text: #131313; + --text-muted: #868686; + --text-dim: #a8a8a8; + --accent: #131313; + --ok: #148530; + --warn: #a07a00; + --err: #bb3049; + --debug: #6366f1; + --chip-bg: #eef0f3; + --mono: 'Roboto Mono', ui-monospace, 'SF Mono', Menlo, Monaco, Consolas, monospace; + --sans: 'Roboto', -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif; + + --shadow-panel: 0 1px 3px rgba(17, 24, 39, 0.06), 0 1px 2px rgba(17, 24, 39, 0.04); + --shadow-button: 0 1px 2px rgba(17, 24, 39, 0.06); + --shadow-button-hover: 0 2px 6px rgba(17, 24, 39, 0.1); + --shadow-input-inset: inset 0 1px 2px rgba(17, 24, 39, 0.03); +} + +* { box-sizing: border-box; } + +.surface { + background: var(--panel-bg); + border: 1px solid var(--panel-border); + border-radius: 8px; + box-shadow: var(--shadow-panel); +} + +html, body { + margin: 0; + padding: 0; + background: var(--bg); + color: var(--text); + font-family: var(--sans); + font-size: 14px; + line-height: 1.5; +} + +main { + max-width: 1100px; + margin: 0 auto; + padding: 24px 16px 64px; +} + +header { + margin-bottom: 16px; +} + +h1 { + font-size: 28px; + font-weight: 700; + letter-spacing: -0.01em; + margin: 0 0 6px; +} + +.status-bar { + padding: 16px 20px; + margin-bottom: 16px; + display: flex; + flex-wrap: wrap; + gap: 20px; + font-size: 13px; + font-family: var(--mono); +} + +.status-group > div, +.status-cookies > div { + display: flex; + gap: 6px; + align-items: center; +} + +.status-group { + display: flex; + gap: 32px; + align-items: center; + flex-wrap: wrap; +} + +.status-group + .status-group { + padding-left: 20px; + border-left: 1px solid var(--panel-border); +} + +.status-cookies { + width: 100%; + display: flex; + gap: 20px; + align-items: center; + flex-wrap: wrap; + padding-top: 12px; + margin-top: -4px; + border-top: 1px dashed var(--panel-border); +} + +/* Shared eyebrow label style. */ +.status-label, +.panel-title, +.section-label, +.accordion-title, +.field label { + font-family: var(--sans); + font-size: 11px; + font-weight: 700; + text-transform: uppercase; + letter-spacing: 0.06em; + color: var(--text-muted); +} + +.section-label { + margin: 16px 0 8px; + padding-top: 16px; + border-top: 1px solid var(--panel-border); +} + +/* Kill top margin + border when section-label is the first visible element. */ +.panel > .section-label:first-child { + margin-top: 0; + padding-top: 0; + border-top: none; +} + +.status-value { + color: var(--text); + word-break: break-all; + cursor: pointer; +} + +.status-value.dim { + color: var(--text-dim); +} + +.status-value.copied { + color: var(--ok); +} + +.panel { + padding: 16px 20px; + margin-bottom: 16px; +} + +.field { + display: flex; + flex-direction: column; + gap: 4px; + margin-bottom: 8px; +} + +.field input[type="text"], +.field input[type="number"], +.field textarea, +.field select { + background: var(--panel-bg); + border: 1px solid #d4d7dd; + color: var(--text); + padding: 7px 10px; + border-radius: 8px; + font-family: var(--mono); + font-size: 12px; + box-shadow: var(--shadow-input-inset); + transition: border-color 0.15s ease, box-shadow 0.15s ease; +} + +.field input[type="text"]:focus, +.field input[type="number"]:focus, +.field textarea:focus, +.field select:focus { + outline: none; + border-color: var(--accent); + box-shadow: 0 0 0 3px rgba(19, 19, 19, 0.1); +} + +.field select { + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + padding-right: 32px; + background-image: url("data:image/svg+xml;utf8,"); + background-repeat: no-repeat; + background-position: right 12px center; + cursor: pointer; +} + +.field textarea { + min-height: 64px; + resize: vertical; +} + +.actions { + display: flex; + gap: 8px; + flex-wrap: wrap; + margin-top: 16px; + margin-bottom: 16px; +} + +.actions:last-child { + margin-bottom: 0; +} + +button { + background: var(--accent); + color: #ffffff; + border: none; + padding: 7px 14px; + border-radius: 8px; + font-family: var(--sans); + font-size: 12px; + font-weight: 600; + cursor: pointer; + box-shadow: var(--shadow-button); + transition: background 0.15s ease, box-shadow 0.15s ease; +} + +button:hover:not(:disabled) { + background: #2a2a2a; + box-shadow: var(--shadow-button-hover); +} + +button:disabled { + background: var(--panel-border); + color: var(--text-dim); + cursor: not-allowed; + box-shadow: none; +} + +button:focus-visible { + outline: 2px solid var(--debug); + outline-offset: 2px; +} + +button.secondary { + background: var(--panel-bg); + border: 1px solid var(--panel-border); + color: var(--text); +} + +button.secondary:hover:not(:disabled) { + background: #f3f4f6; + border-color: #d4d7dd; + box-shadow: var(--shadow-button-hover); +} + +button.active { + background: #000; + box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.25) inset, var(--shadow-button); +} + +button .btn-sig { + display: block; + font-family: var(--mono); + font-size: 10px; + font-weight: 400; + margin-top: 2px; +} + +.log { + font-family: var(--mono); + font-size: 12px; + height: 360px; + min-height: 120px; + overflow: auto; + padding: 16px 20px; + resize: vertical; +} + +.log-row { + display: flex; + flex-direction: column; + gap: 4px; + margin-bottom: 8px; + padding-bottom: 8px; + border-bottom: 1px dashed var(--panel-border); + overflow-wrap: anywhere; +} + +.log-row:last-child { + margin-bottom: 0; + padding-bottom: 0; + border-bottom: none; +} + +.log-row-head { + display: flex; + flex-wrap: wrap; + align-items: baseline; + gap: 8px; +} + +.log-copy-btn { + margin-left: auto; + padding: 2px 4px; + opacity: 0; + transition: opacity 0.15s ease; +} + +.log-row:hover .log-copy-btn, +.log-copy-btn:focus-visible { + opacity: 1; +} + +.log-copy-btn svg { + display: block; + width: 12px; + height: 12px; +} + +.log-ts { + color: var(--text-dim); + font-size: 11px; +} + +.log-badge { + display: inline-block; + padding: 1px 7px; + border-radius: 999px; + font-size: 9px; + font-weight: 700; + text-transform: uppercase; + letter-spacing: 0.05em; + vertical-align: middle; +} + +.log-badge.badge-app { + color: var(--text); + background: var(--chip-bg); +} + +.log-badge.badge-sdk { + color: #fff; + background: var(--debug); +} + +.log-label { + font-weight: 600; +} + +.log-body { + margin: 0; + font-size: 11px; + white-space: pre-wrap; + overflow-wrap: anywhere; + padding-left: 2px; +} + +.log-row.log-ok .log-label { color: var(--ok); } +.log-row.log-warn .log-label { color: var(--warn); } +.log-row.log-err .log-label { color: var(--err); } +.log-row.log-info .log-label { color: var(--text-muted); } +.log-row.log-debug .log-label { color: var(--debug); font-style: italic; } + +.log-count { + display: inline-block; + background: var(--chip-bg); + color: var(--text-muted); + font-size: 10px; + font-weight: 400; + font-family: var(--mono); + padding: 2px 10px; + border-radius: 999px; + margin-left: 6px; + vertical-align: middle; +} + +.log-row.collapsible .log-row-head { + cursor: pointer; +} +.log-row.collapsible .log-row-head::before { + content: "▾"; + color: var(--text-muted); + font-size: 10px; + margin-right: 2px; +} +.log-row.collapsible.collapsed .log-row-head::before { + content: "▸"; +} +.log-row.collapsed .log-body { + display: none; +} + +/* min-height MUST match .tab-bar (both 38px). */ +.log-header { + display: flex; + align-items: baseline; + justify-content: space-between; + min-height: 38px; + margin-bottom: 16px; + border-bottom: 1px solid var(--panel-border); +} + +.log-actions { + display: flex; + gap: 8px; +} + +@media (min-width: 1024px) { + main { + max-width: min(95vw, 1800px); + } + + .sample-app-grid { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 16px; + align-items: start; + } + + .controls > .panel:last-child { + margin-bottom: 0; + } + + .log-pane { + position: sticky; + top: 120px; + max-height: calc(100vh - 136px); + } + + .log-pane .log { + height: calc(100vh - 220px); + max-height: calc(100vh - 80px); + resize: vertical; + } +} + +.sdk-version { + font-family: var(--mono); + font-size: 14px; + font-weight: 400; + color: var(--text-muted); + margin-left: 10px; + vertical-align: middle; + padding: 3px 8px; + border: 1px solid var(--panel-border); + border-radius: 999px; + background: var(--panel-bg); +} + +.identity-state-list { + margin: 0 0 16px; + display: flex; + flex-direction: column; + gap: 4px; +} + +.identity-state-row { + display: grid; + grid-template-columns: 100px 1fr; + gap: 8px; + font-family: var(--mono); + padding: 4px 0; +} + +.identity-state-row dt { + margin: 0; + color: var(--text-muted); + text-transform: uppercase; + letter-spacing: 0.06em; + font-size: 10px; + align-self: center; +} + +.identity-state-row dd { + margin: 0; + font-size: 11px; + color: var(--text); + word-break: break-all; + white-space: pre-wrap; +} + +.advanced-grid { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 12px; + margin-bottom: 8px; +} + +.advanced-grid .field { + margin-bottom: 0; +} + +.accordion-item { + border: 1px solid var(--panel-border); + border-radius: 8px; + background: var(--panel-bg); + margin-bottom: 8px; + overflow: hidden; +} + +.accordion-header { + display: flex; + align-items: center; + justify-content: space-between; + padding: 12px 16px; + cursor: pointer; + list-style: none; + user-select: none; +} + +.accordion-header::-webkit-details-marker { display: none; } + +.accordion-item[open] .accordion-title { + color: var(--text); +} + +.accordion-header::after { + content: "▸"; + color: var(--text-muted); +} + +.accordion-item[open] .accordion-header::after { + content: "▾"; + color: var(--text); +} + +.accordion-content { + padding: 4px 16px 16px 16px; +} + +.accordion-content > .helper-text:first-child { + margin-bottom: 12px; +} + +.alias-grid { + display: grid; + grid-template-columns: 1fr auto 1fr; + align-items: center; + gap: 16px; +} + +.alias-side { display: flex; flex-direction: column; gap: 8px; } + +.alias-arrow { + font-size: 24px; + color: var(--text-muted); + font-weight: 300; + padding: 0 4px; +} + +.consent-grid { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 12px; +} + +.consent-choice { + display: flex; + flex-direction: column; + gap: 8px; +} + +.consent-choice button { + width: 100%; +} + +.helper-text { + margin: 0; + color: var(--text-muted); + font-size: 11px; + line-height: 1.4; +} + +.panel code { + font-family: var(--mono); + font-size: 11px; + background: var(--chip-bg); + padding: 1px 6px; + border-radius: 4px; +} + +@media (max-width: 720px) { + .alias-grid { grid-template-columns: 1fr; } + .alias-arrow { transform: rotate(90deg); text-align: center; } + .consent-grid { grid-template-columns: 1fr; } +} + +.status-value.state-ok { color: var(--ok); } +.status-value.state-warn { color: var(--warn); } +.status-value.state-err { color: var(--err); } + +.prod-warning { + position: sticky; + top: 0; + z-index: 20; + padding: 14px 16px; + background: #dc2626; + color: #fff; + font-family: var(--sans); + font-size: 16px; + font-weight: 800; + text-align: center; + text-transform: uppercase; + letter-spacing: 0.06em; +} + +/* --- Tabbed panel interface --- */ + +.sticky-top { + position: sticky; + top: 0; + z-index: 10; + background: var(--bg); + box-shadow: 0 2px 4px rgba(17, 24, 39, 0.04); +} + +.tab-bar { + display: flex; + flex-wrap: nowrap; + overflow-x: auto; + gap: 2px; + min-height: 38px; + margin-bottom: 16px; + border-bottom: 1px solid var(--panel-border); + scrollbar-width: thin; + scrollbar-color: var(--panel-border) transparent; +} + +.tab-bar::-webkit-scrollbar { + height: 4px; +} +.tab-bar::-webkit-scrollbar-thumb { + background: var(--panel-border); + border-radius: 2px; +} +/* .tab-bar .tab specificity (0,2,0) beats base button rules. */ +.tab-bar .tab { + padding: 8px 14px; + background: transparent; + border: 1px solid transparent; + border-bottom: 2px solid transparent; + border-radius: 8px 8px 0 0; + box-shadow: none; + cursor: pointer; + font-family: var(--sans); + font-size: 12px; + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.06em; + color: var(--text); + white-space: nowrap; +} + +.tab-bar .tab:hover:not(.active):not(:disabled) { + background: transparent; + border-bottom-color: var(--text-dim); + box-shadow: none; +} + +.tab-bar .tab.active, +.tab-bar .tab.active:hover { + background: var(--panel-bg); + color: var(--text); + font-weight: 700; + border-color: var(--panel-border); + border-bottom-color: var(--accent); + box-shadow: var(--shadow-button); +} + +.controls .panel { + display: none; +} + +.controls .panel.active { + display: block; +} + diff --git a/packages/audience/sdk-sample-app/sample-app.js b/packages/audience/sdk-sample-app/sample-app.js new file mode 100644 index 0000000000..0d36c0731d --- /dev/null +++ b/packages/audience/sdk-sample-app/sample-app.js @@ -0,0 +1,880 @@ +// Sample app for @imtbl/audience. +// Vanilla ES2020, no build step. Reads the CDN bundle's window.ImmutableAudience. + +(function () { + 'use strict'; + + if (!window.ImmutableAudience) { + document.body.textContent = 'ERROR: window.ImmutableAudience is undefined. The CDN bundle did not load.'; + return; + } + + var audienceInit = window.ImmutableAudience.init; + var IdentityType = window.ImmutableAudience.IdentityType; + var SdkAudienceEvents = window.ImmutableAudience.AudienceEvents; + var canIdentify = window.ImmutableAudience.canIdentify; + var SDK_VERSION = window.ImmutableAudience.version || 'unknown'; + + // Field shapes for typed events accordion. Cross-checked against AudienceEvents at bootstrap. + var AUDIENCE_EVENTS = [ + { name: 'sign_up', fields: [{ key: 'method', type: 'string', optional: true }] }, + { name: 'sign_in', fields: [{ key: 'method', type: 'string', optional: true }] }, + { name: 'email_acquired', fields: [{ key: 'source', type: 'string', optional: true }] }, + { name: 'wishlist_add', fields: [ + { key: 'gameId', type: 'string' }, + { key: 'source', type: 'string', optional: true }, + { key: 'platform', type: 'string', optional: true }, + ] }, + { name: 'wishlist_remove', fields: [{ key: 'gameId', type: 'string' }] }, + { name: 'purchase', fields: [ + { key: 'currency', type: 'string' }, + { key: 'value', type: 'number' }, + { key: 'itemId', type: 'string', optional: true }, + { key: 'itemName', type: 'string', optional: true }, + { key: 'quantity', type: 'number', optional: true }, + { key: 'transactionId', type: 'string', optional: true }, + ] }, + { name: 'game_launch', fields: [ + { key: 'platform', type: 'string', optional: true }, + { key: 'version', type: 'string', optional: true }, + { key: 'buildId', type: 'string', optional: true }, + ] }, + { name: 'progression', fields: [ + { key: 'status', type: 'enum', values: ['start', 'complete', 'fail'] }, + { key: 'world', type: 'string', optional: true }, + { key: 'level', type: 'string', optional: true }, + { key: 'stage', type: 'string', optional: true }, + { key: 'score', type: 'number', optional: true }, + { key: 'durationSec', type: 'number', optional: true }, + ] }, + { name: 'resource', fields: [ + { key: 'flow', type: 'enum', values: ['sink', 'source'] }, + { key: 'currency', type: 'string' }, + { key: 'amount', type: 'number' }, + { key: 'itemType', type: 'string', optional: true }, + { key: 'itemId', type: 'string', optional: true }, + ] }, + { name: 'game_page_viewed', fields: [ + { key: 'gameId', type: 'string' }, + { key: 'gameName', type: 'string', optional: true }, + { key: 'slug', type: 'string', optional: true }, + ] }, + { name: 'link_clicked', fields: [ + { key: 'url', type: 'string' }, + { key: 'label', type: 'string', optional: true }, + { key: 'source', type: 'string', optional: true }, + { key: 'gameId', type: 'string', optional: true }, + ] }, + ]; + + var audience = null; + var currentConsent = null; + var currentUserId = null; + + var identityMirror = emptyIdentity(); + var logEntries = []; + var logAutoScroll = true; + var MAX_LOG_ENTRIES = 500; + var LOG_BOTTOM_THRESHOLD = 20; + + // SDK-writable first-party cookies (shared with @imtbl/pixel). + var ANON_COOKIE_NAME = 'imtbl_anon_id'; + + function readCookie(name) { + var pattern = new RegExp('(?:^|;\\s*)' + name + '=([^;]+)'); + var match = document.cookie.match(pattern); + return match ? decodeURIComponent(match[1]) : null; + } + + // DOM helpers + function $(id) { return document.getElementById(id); } + function text(el, val) { el.textContent = val; } + function errMsg(err) { return String(err && err.message || err); } + function create(tag, className) { + var el = document.createElement(tag); + if (className) el.className = className; + return el; + } + function addOption(select, value, label) { + var opt = create('option'); + opt.value = value; + text(opt, label); + select.appendChild(opt); + } + function emptyIdentity() { return { userId: null, identityType: null, traits: null, aliases: [] }; } + + // --- Event log (source: 'app' | 'sdk') --- + + function log(label, payload, level, source) { + var entry = { + ts: new Date().toISOString(), + label: label, + payload: payload, + level: level || 'info', + source: source || 'app', + }; + logEntries.push(entry); + if (logEntries.length > MAX_LOG_ENTRIES) { + logEntries.shift(); + var logEl = $('log'); + if (logEl.firstChild) logEl.removeChild(logEl.firstChild); + } + renderLogEntry(entry); + updateLogCount(); + } + + function formatLogBody(payload) { + if (payload == null) return ''; + if (typeof payload === 'string') return payload; + try { return JSON.stringify(payload, null, 2); } + catch (err) { return String(payload); } + } + + function renderLogEntry(entry) { + var row = create('div', 'log-row log-' + entry.level); + var head = create('div', 'log-row-head'); + var bodyText = formatLogBody(entry.payload); + + var ts = create('span', 'log-ts'); + text(ts, entry.ts.slice(11, 23)); + + var badge = create('span', 'log-badge ' + (entry.source === 'sdk' ? 'badge-sdk' : 'badge-app')); + text(badge, entry.source === 'sdk' ? 'SDK' : 'APP'); + + var label = create('span', 'log-label'); + text(label, entry.label); + + var copyBtn = create('button', 'secondary log-copy-btn'); + copyBtn.type = 'button'; + copyBtn.innerHTML = COPY_ICON_HTML; + copyBtn.setAttribute('aria-label', 'Copy log entry'); + copyBtn.addEventListener('click', function (e) { + e.stopPropagation(); + copyToClipboard(bodyText, copyBtn, true); + }); + + head.appendChild(ts); + head.appendChild(badge); + head.appendChild(label); + head.appendChild(copyBtn); + row.appendChild(head); + + if (bodyText) { + var body = create('pre', 'log-body'); + text(body, bodyText); + row.appendChild(body); + // Click or Enter/Space on the row head toggles collapse/expand. + var isCollapsed = bodyText.length > 240; + row.classList.add('collapsible'); + head.setAttribute('tabindex', '0'); + head.setAttribute('role', 'button'); + head.setAttribute('aria-expanded', String(!isCollapsed)); + function toggleCollapse() { + row.classList.toggle('collapsed'); + head.setAttribute('aria-expanded', String(!row.classList.contains('collapsed'))); + } + head.addEventListener('click', toggleCollapse); + head.addEventListener('keydown', function (e) { + if (e.key === 'Enter' || e.key === ' ') { + e.preventDefault(); + toggleCollapse(); + } + }); + // Long bodies default-collapsed so the log doesn't bloat. + if (isCollapsed) row.classList.add('collapsed'); + } + + $('log').appendChild(row); + if (logAutoScroll) $('log').scrollTop = $('log').scrollHeight; + } + + function clearLog() { logEntries.length = 0; $('log').textContent = ''; updateLogCount(); } + + function updateLogCount() { text($('log-count'), String(logEntries.length)); } + + var COPY_ICON_HTML = ''; + var COPY_CHECK_ICON_HTML = ''; + + function copyToClipboard(str, btn, isIcon) { + navigator.clipboard.writeText(str).then(function () { + flashCopied(btn, isIcon); + }).catch(function () {}); + } + + function flashCopied(el, isIcon) { + if (el.dataset.copyTimer) clearTimeout(Number(el.dataset.copyTimer)); + if (isIcon) el.innerHTML = COPY_CHECK_ICON_HTML; + else el.textContent = 'Copied'; + var timerId = setTimeout(function () { + if (isIcon) el.innerHTML = COPY_ICON_HTML; + else el.textContent = 'Copy'; + delete el.dataset.copyTimer; + }, 1200); + el.dataset.copyTimer = String(timerId); + } + + var activeTabId = 'panel-setup'; + + // --- UI state persistence (localStorage, dev-only) --- + + var UI_STATE_KEY = 'imtbl_audience_sample_app_ui_v1'; + + var UI_FIELDS = [ + ['pk', 'value', 'pk'], + ['initial-consent', 'value', 'initialConsent'], + ['debug', 'checked', 'debug'], + ['cookie-domain', 'value', 'cookieDomain'], + ['flush-interval', 'value', 'flushInterval'], + ['flush-size', 'value', 'flushSize'], + ['environment', 'value', 'environment'], + ]; + + function saveUiState() { + try { + var state = { activeTab: activeTabId }; + UI_FIELDS.forEach(function (f) { state[f[2]] = $(f[0])[f[1]]; }); + localStorage.setItem(UI_STATE_KEY, JSON.stringify(state)); + } catch (err) { /* storage unavailable */ } + } + + function restoreUiState() { + try { + var raw = localStorage.getItem(UI_STATE_KEY); + if (!raw) return; + var state = JSON.parse(raw); + UI_FIELDS.forEach(function (f) { if (state[f[2]] !== undefined) $(f[0])[f[1]] = state[f[2]]; }); + if ($('environment').selectedIndex === -1) $('environment').selectedIndex = 0; + return state; + } catch (err) { /* ignore */ } + } + + // --- SDK debug console mirror --- + // Wraps console.log/warn to mirror [audience]-prefixed messages into + // the in-page event log. Original console methods stay active. + + // Harvested from the debug mirror (reliable) or cookies (fallback). + var currentAnonId = null; + var currentSessionId = null; + var pendingQueueCount = 0; + + function installConsoleMirror() { + var originalLog = console.log.bind(console); + var originalWarn = console.warn.bind(console); + + function harvestIds(payload) { + if (!payload || typeof payload !== 'object') return; + var changed = false; + if (typeof payload.anonymousId === 'string' && payload.anonymousId && currentAnonId !== payload.anonymousId) { + currentAnonId = payload.anonymousId; + changed = true; + } + var sid = payload.properties && payload.properties.sessionId; + if (typeof sid === 'string' && sid && currentSessionId !== sid) { + currentSessionId = sid; + changed = true; + } + if (changed) updateStatus(); + } + + function tryMirror(args, level) { + if (args.length === 0 || typeof args[0] !== 'string') return; + if (args[0].indexOf('[audience] ') !== 0) return; + var msg = args[0].slice(11); + var payload = args.length > 1 ? args[1] : undefined; + harvestIds(payload); + // Promote flush outcomes to ok/err so they stand out in the log. + var flushMatch = msg.match(/^flush (ok|failed)/); + if (flushMatch && flushMatch[1] === 'ok') { pendingQueueCount = 0; updateStatus(); } + var effectiveLevel = flushMatch ? (flushMatch[1] === 'ok' ? 'ok' : 'err') : level; + log(msg, payload, effectiveLevel, 'sdk'); + } + + console.log = function () { + originalLog.apply(null, arguments); + tryMirror(arguments, 'debug'); + }; + console.warn = function () { + originalWarn.apply(null, arguments); + tryMirror(arguments, 'warn'); + }; + } + + function isTestKey(key) { return key.indexOf('pk_imapik-test') === 0; } + + var DEV_URL = 'https://api.dev.immutable.com'; + var PROD_URL = 'https://api.immutable.com'; + + var lastKeyType = null; // 'test' | 'prod' | null + function syncEnvironment() { + var key = $('pk').value.trim(); + if (!key) { lastKeyType = null; return; } + var type = isTestKey(key) ? 'test' : 'prod'; + if (type === lastKeyType) return; + lastKeyType = type; + $('environment').value = type === 'test' ? DEV_URL : PROD_URL; + } + + function handleError(err) { + var info = {}; + ['name', 'code', 'status', 'endpoint', 'message', 'responseBody'].forEach(function (k) { + if (err && err[k] !== undefined) info[k] = err[k]; + }); + log('onError', info, 'err'); + } + + function readConfig() { + var config = { + publishableKey: $('pk').value.trim(), + consent: $('initial-consent').value, + debug: $('debug').checked, + onError: handleError, + }; + var cd = $('cookie-domain').value.trim(); if (cd) config.cookieDomain = cd; + config.baseUrl = $('environment').value; + var fi = parseInt($('flush-interval').value, 10); if (!Number.isNaN(fi)) config.flushInterval = fi; + var fs = parseInt($('flush-size').value, 10); if (!Number.isNaN(fs)) config.flushSize = fs; + return config; + } + + // --- Init button gating --- + + function syncInitEnabled() { + $('btn-init').disabled = $('pk').value.trim() === '' || audience !== null; + } + + var SDK_BUTTONS = [ + 'btn-page', 'btn-flush', 'btn-reset', 'btn-shutdown', + 'btn-consent-none', 'btn-consent-anon', 'btn-consent-full', + 'btn-custom-event', + 'btn-identify', 'btn-identify-traits', + ]; + + function setInitState(on) { + $('btn-init').disabled = on; + SDK_BUTTONS.forEach(function (id) { + var el = $(id); + if (el) el.disabled = !on; + }); + var typedButtons = document.querySelectorAll('#typed-events-accordion .accordion-item button'); + for (var i = 0; i < typedButtons.length; i++) typedButtons[i].disabled = !on; + $('btn-alias').disabled = true; + if (on) syncAliasButton(); + } + + var CONSENT_BUTTONS = { none: 'btn-consent-none', anonymous: 'btn-consent-anon', full: 'btn-consent-full' }; + function syncConsentPills() { + Object.keys(CONSENT_BUTTONS).forEach(function (level) { + $(CONSENT_BUTTONS[level]).classList.toggle('active', currentConsent === level); + }); + } + + function updateStatus() { + syncConsentPills(); + var anonId = null; + if (audience) { + anonId = currentAnonId || readCookie(ANON_COOKIE_NAME); + } + + // Pre-init: mirror the form's Initial consent value. + var displayConsent = currentConsent; + if (!audience) { + var initialConsent = $('initial-consent').value; + if (initialConsent) displayConsent = initialConsent; + } + + var ep = $('environment').value; + var isProd = ep === PROD_URL; + var consentTint = { none: ' state-err', anonymous: ' state-warn', full: ' state-ok' }[displayConsent] || ''; + var endpointTint = isProd ? ' state-warn' : ' state-ok'; + $('prod-warning').hidden = !isProd; + var anonCookie = readCookie(ANON_COOKIE_NAME); + var sidCookie = readCookie('_imtbl_sid'); + + [ + ['status-endpoint', ep, endpointTint], + ['status-consent', displayConsent || '—', consentTint], + ['status-anon', anonId || '—', anonId ? '' : ' dim'], + ['status-user', currentUserId || '—', currentUserId ? '' : ' dim'], + ['status-session', currentSessionId || '—', currentSessionId ? '' : ' dim'], + ['status-queue', audience ? String(pendingQueueCount) : '—', audience ? '' : ' dim'], + ['status-cookie-anon', anonCookie || '—', anonCookie ? '' : ' dim'], + ['status-cookie-sid', sidCookie || '—', sidCookie ? '' : ' dim'], + ].forEach(function (c) { + var el = $(c[0]); + text(el, c[1]); + el.className = 'status-value' + c[2]; + }); + } + + // --- Setup panel: Init --- + + function onInit() { + try { + var config = readConfig(); + audience = audienceInit(config); + setInitState(true); + currentConsent = config.consent; + log('INIT', { + consent: config.consent, + debug: config.debug, + cookieDomain: config.cookieDomain, + flushInterval: config.flushInterval, + flushSize: config.flushSize, + baseUrl: config.baseUrl, + }, 'ok'); + updateStatus(); + } catch (err) { + log('INIT', errMsg(err), 'err'); + } + } + + function clearSdkCookies() { + var expired = '; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/'; + [ANON_COOKIE_NAME, '_imtbl_sid'].forEach(function (name) { + document.cookie = name + '=' + expired; + }); + updateStatus(); + log('cookies', 'Cleared SDK cookies', 'info', 'app'); + } + + // --- Identity state mirror --- + + function resetLocalState() { + currentUserId = null; + currentAnonId = null; + currentSessionId = null; + pendingQueueCount = 0; + identityMirror = emptyIdentity(); + renderIdentityState(); + } + + function setIdentityRow(key, value) { + var dd = document.querySelector('.identity-state-row[data-key="' + key + '"] dd'); + if (dd) text(dd, value || '—'); + } + + function renderIdentityState() { + setIdentityRow('userId', identityMirror.userId); + setIdentityRow('identityType', identityMirror.identityType); + setIdentityRow('traits', identityMirror.traits ? JSON.stringify(identityMirror.traits) : null); + setIdentityRow('aliases', identityMirror.aliases.length + ? identityMirror.aliases.map(function (a) { + return a.from.identityType + ':' + a.from.id + ' \u2192 ' + a.to.identityType + ':' + a.to.id; + }).join('\n') + : null); + } + + // --- Event catalogue drift check --- + // Warn if local AUDIENCE_EVENTS diverges from the SDK's AudienceEvents. + + function validateEventCatalogue() { + if (!SdkAudienceEvents) return; + var sdkNames = Object.values(SdkAudienceEvents); + var localNames = AUDIENCE_EVENTS.map(function (e) { return e.name; }); + var missing = sdkNames.filter(function (n) { return localNames.indexOf(n) === -1; }); + var extra = localNames.filter(function (n) { return sdkNames.indexOf(n) === -1; }); + if (missing.length || extra.length) { + log('drift', { sdkHasButSampleAppMissing: missing, sampleAppHasButSdkMissing: extra }, 'warn'); + } + } + + // --- Tab switching --- + + function installTabSwitching() { + var tabs = Array.prototype.slice.call(document.querySelectorAll('.tab-bar .tab')); + if (!tabs.length) return; + + function activate(targetPanelId, moveFocus) { + activeTabId = targetPanelId; + saveUiState(); + for (var i = 0; i < tabs.length; i++) { + var isActive = tabs[i].getAttribute('data-panel') === targetPanelId; + tabs[i].classList.toggle('active', isActive); + tabs[i].setAttribute('aria-selected', String(isActive)); + tabs[i].setAttribute('tabindex', isActive ? '0' : '-1'); + if (isActive && moveFocus) tabs[i].focus(); + } + var panels = document.querySelectorAll('.controls .panel'); + for (var j = 0; j < panels.length; j++) { + panels[j].classList.toggle('active', panels[j].id === targetPanelId); + } + } + + tabs.forEach(function (tab) { + tab.addEventListener('click', function () { activate(tab.getAttribute('data-panel')); }); + }); + + // ARIA tablist keyboard navigation. + document.querySelector('.tab-bar').addEventListener('keydown', function (e) { + var current = tabs.indexOf(document.activeElement); + if (current === -1) return; + var next; + if (e.key === 'ArrowRight' || e.key === 'ArrowDown') { + next = (current + 1) % tabs.length; + } else if (e.key === 'ArrowLeft' || e.key === 'ArrowUp') { + next = (current - 1 + tabs.length) % tabs.length; + } else if (e.key === 'Home') { + next = 0; + } else if (e.key === 'End') { + next = tabs.length - 1; + } else { + return; + } + e.preventDefault(); + activate(tabs[next].getAttribute('data-panel'), true); + }); + } + + // --- Bootstrap --- + + function bootstrap() { + installConsoleMirror(); + validateEventCatalogue(); + installTabSwitching(); + var restored = restoreUiState(); + var restoredKey = $('pk').value.trim(); + if (restoredKey) lastKeyType = isTestKey(restoredKey) ? 'test' : 'prod'; + + var identityTypes = Object.values(IdentityType || {}); + ['id-type', 'alias-from-type', 'alias-to-type'].forEach(function (id) { + identityTypes.forEach(function (val) { addOption($(id), val, val); }); + }); + + $('pk').addEventListener('input', function () { + syncEnvironment(); syncInitEnabled(); updateStatus(); saveUiState(); + }); + $('environment').addEventListener('change', function () { updateStatus(); saveUiState(); }); + $('initial-consent').addEventListener('change', function () { saveUiState(); updateStatus(); }); + ['debug', 'cookie-domain', 'flush-interval', 'flush-size'].forEach(function (id) { + var el = $(id); + if (!el) return; + el.addEventListener('input', saveUiState); + }); + $('btn-init').addEventListener('click', onInit); + $('btn-page').addEventListener('click', onPage); + $('btn-flush').addEventListener('click', onFlush); + $('btn-reset').addEventListener('click', onReset); + $('btn-shutdown').addEventListener('click', onShutdown); + $('btn-consent-none').addEventListener('click', function () { onSetConsent('none'); }); + $('btn-consent-anon').addEventListener('click', function () { onSetConsent('anonymous'); }); + $('btn-consent-full').addEventListener('click', function () { onSetConsent('full'); }); + $('btn-identify').addEventListener('click', onIdentify); + $('btn-identify-traits').addEventListener('click', onIdentifyTraits); + $('btn-alias').addEventListener('click', onAlias); + ['alias-from-id', 'alias-to-id', 'alias-from-type', 'alias-to-type'].forEach(function (id) { + $(id).addEventListener('input', syncAliasButton); + }); + $('btn-clear-cookies').addEventListener('click', clearSdkCookies); + document.querySelector('.status-bar').addEventListener('click', function (e) { + var val = e.target.closest('.status-value'); + if (!val || val.textContent === '—') return; + var original = val.textContent; + navigator.clipboard.writeText(original).then(function () { + val.textContent = 'Copied'; + val.classList.add('copied'); + setTimeout(function () { val.textContent = original; val.classList.remove('copied'); }, 800); + }).catch(function () {}); + }); + + $('btn-copy-log').addEventListener('click', function () { + var s = logEntries.map(function (e) { + return e.ts + ' [' + (e.source === 'sdk' ? 'SDK' : 'APP') + '] ' + + e.label + ' ' + (typeof e.payload === 'string' ? e.payload : JSON.stringify(e.payload)); + }).join('\n'); + copyToClipboard(s, $('btn-copy-log')); + }); + $('btn-clear-log').addEventListener('click', clearLog); + $('log').addEventListener('scroll', function () { + var el = $('log'); + logAutoScroll = (el.scrollHeight - el.scrollTop - el.clientHeight) < LOG_BOTTOM_THRESHOLD; + }); + + var typedContainer = $('typed-events-accordion'); + typedContainer.textContent = ''; + AUDIENCE_EVENTS.forEach(function (event) { renderTypedEventRow(event, typedContainer); }); + $('btn-custom-event').addEventListener('click', onCustomEvent); + + syncInitEnabled(); + updateStatus(); + text($('sdk-version'), 'v' + SDK_VERSION); + renderIdentityState(); + + if (restored && restored.activeTab && restored.activeTab !== 'panel-setup') { + var tabBtn = document.querySelector('.tab-bar .tab[data-panel="' + restored.activeTab + '"]'); + if (tabBtn) tabBtn.click(); + } + + log('READY', 'Sample app loaded. Paste a publishable key and click Init.', 'info'); + } + + if (document.readyState === 'loading') { + document.addEventListener('DOMContentLoaded', bootstrap); + } else { + bootstrap(); + } + + // --- Queue count (app-level tracking, works without debug mode) --- + + function enqueued() { + pendingQueueCount += 1; + updateStatus(); + } + + // --- SDK lifecycle --- + + function onPage() { + if (!audience) return; + try { + var props = { path: window.location.pathname }; + audience.page(props); + enqueued(); + log('page()', props, 'ok'); + } catch (err) { + log('page()', errMsg(err), 'err'); + } + } + + function onFlush() { + if (!audience) return; + audience.flush().then(function () { + pendingQueueCount = 0; + updateStatus(); + log('flush()', 'queue flushed', 'ok'); + }).catch(function (err) { + log('flush()', errMsg(err), 'err'); + }); + } + + function onReset() { + if (!audience) return; + log('reset()', { clearing: { anonId: currentAnonId, userId: currentUserId, sessionId: currentSessionId } }, 'info'); + audience.reset(); + resetLocalState(); + log('reset()', 'anonymous ID regenerated, queue cleared', 'ok'); + updateStatus(); + } + + function onShutdown() { + if (!audience) return; + log('shutdown()', { clearing: { anonId: currentAnonId, userId: currentUserId, sessionId: currentSessionId, consent: currentConsent } }, 'info'); + audience.shutdown(); + audience = null; + currentConsent = null; + resetLocalState(); + setInitState(false); + syncInitEnabled(); + updateStatus(); + log('shutdown()', 'SDK stopped', 'ok'); + } + + // --- Consent panel --- + + function onSetConsent(level) { + if (!audience) return; + var previous = currentConsent; + try { + audience.setConsent(level); + currentConsent = level; + // Log observable side effects of the transition. + var effects = []; + if (previous === 'none' && level !== 'none') effects.push('queue started, session created'); + if (level === 'none') effects.push('queue purged, cookies deleted'); + if (!canIdentify(level)) { + currentUserId = null; + identityMirror = emptyIdentity(); + renderIdentityState(); + if (canIdentify(previous)) effects.push('userId cleared'); + } + log('setConsent()', { from: previous, to: level, effects: effects.length ? effects : undefined }, 'ok'); + updateStatus(); + } catch (err) { + log('setConsent()', errMsg(err), 'err'); + } + } + + function renderTypedEventRow(event, container) { + var row = create('details', 'accordion-item'); + var summary = create('summary', 'accordion-header'); + var title = create('span', 'accordion-title'); + text(title, event.name); + summary.appendChild(title); + row.appendChild(summary); + + var content = create('div', 'accordion-content'); + row.appendChild(content); + + var inputsByKey = {}; + event.fields.forEach(function (field) { + var fieldEl = create('div', 'field'); + var inputId = 'te-' + event.name + '-' + field.key; + var label = create('label'); + label.setAttribute('for', inputId); + text(label, field.key + (field.optional ? '?' : '') + ': ' + (field.values ? field.values.join(' | ') : field.type)); + fieldEl.appendChild(label); + + var input; + if (field.type === 'enum') { + input = create('select'); + if (field.optional) addOption(input, '', '(not set)'); + field.values.forEach(function (v) { addOption(input, v, v); }); + } else { + input = create('input'); + input.type = field.type === 'number' ? 'number' : 'text'; + } + input.id = inputId; + fieldEl.appendChild(input); + content.appendChild(fieldEl); + inputsByKey[field.key] = { input: input, field: field }; + }); + + var actions = create('div', 'actions'); + var btn = create('button'); + text(btn, 'Send'); + btn.disabled = true; + actions.appendChild(btn); + content.appendChild(actions); + + function collectProps() { + var props = {}; + Object.keys(inputsByKey).forEach(function (key) { + var entry = inputsByKey[key]; + var raw = entry.input.value; + if (raw === '') return; + if (entry.field.type === 'number') { + var n = Number(raw); + if (Number.isNaN(n)) return; + props[key] = n; + } else { + props[key] = raw; + } + }); + return props; + } + + btn.addEventListener('click', function () { + if (!audience) return; + var props = collectProps(); + try { + audience.track(event.name, props); + enqueued(); + log('track()', { event: event.name, properties: props }, 'ok'); + } catch (err) { + log('track()', errMsg(err), 'err'); + } + }); + + container.appendChild(row); + } + + function onCustomEvent() { + if (!audience) return; + var name = $('custom-event-name').value.trim(); + if (!name) { log('track()', 'event name required', 'err'); return; } + try { + var propsText = $('custom-event-props').value.trim(); + var props = propsText ? JSON.parse(propsText) : undefined; + audience.track(name, props); + enqueued(); + log('track()', { event: name, properties: props }, 'ok'); + } catch (err) { + log('track()', errMsg(err), 'err'); + } + } + + // --- Identity panel --- + + function requiresFullConsent(label) { + if (canIdentify(currentConsent)) return true; + log(label, 'skipped — canIdentify(' + currentConsent + ') is false; requires consent: full', 'info'); + return false; + } + + function parseTraits(raw) { + var trimmed = (raw || '').trim(); + if (!trimmed) return undefined; + return JSON.parse(trimmed); + } + + function onIdentify() { + if (!audience) return; + if (!requiresFullConsent('identify()')) return; + var id = $('id-id').value.trim(); + var type = $('id-type').value; + if (!id) { + log('identify()', 'id required', 'err'); + return; + } + var traits; + try { traits = parseTraits($('id-traits').value); } + catch (err) { log('identify()', 'invalid traits JSON: ' + err.message, 'err'); return; } + try { + audience.identify(id, type, traits); + enqueued(); + currentUserId = id; + identityMirror.userId = id; + identityMirror.identityType = type; + identityMirror.traits = traits || null; + renderIdentityState(); + log('identify()', { id: id, identityType: type, traits: traits }, 'ok'); + updateStatus(); + } catch (err) { + log('identify()', errMsg(err), 'err'); + } + } + + function onIdentifyTraits() { + if (!audience) return; + if (!requiresFullConsent('identify()')) return; + var traits; + try { traits = parseTraits($('traits-json').value); } + catch (err) { log('identify()', 'invalid JSON: ' + err.message, 'err'); return; } + if (!traits) { + log('identify()', 'traits required', 'err'); + return; + } + try { + audience.identify(traits); + enqueued(); + identityMirror.traits = traits; + renderIdentityState(); + log('identify(traits)', traits, 'ok'); + } catch (err) { + log('identify(traits)', errMsg(err), 'err'); + } + } + + function onAlias() { + if (!audience) return; + if (!requiresFullConsent('alias()')) return; + var fromId = $('alias-from-id').value.trim(); + var fromType = $('alias-from-type').value; + var toId = $('alias-to-id').value.trim(); + var toType = $('alias-to-type').value; + if (!fromId || !toId || (fromId === toId && fromType === toType)) { + log('alias()', 'from and to must both be set and differ', 'err'); + return; + } + var from = { id: fromId, identityType: fromType }; + var to = { id: toId, identityType: toType }; + try { + audience.alias(from, to); + enqueued(); + identityMirror.aliases.push({ from: from, to: to }); + renderIdentityState(); + log('alias()', { from: from, to: to }, 'ok'); + } catch (err) { + log('alias()', errMsg(err), 'err'); + } + } + + function syncAliasButton() { + var btn = $('btn-alias'); + if (!audience) { btn.disabled = true; return; } + var fromId = $('alias-from-id').value.trim(); + var fromType = $('alias-from-type').value; + var toId = $('alias-to-id').value.trim(); + var toType = $('alias-to-type').value; + btn.disabled = !fromId || !toId || (fromId === toId && fromType === toType); + } + +}()); diff --git a/packages/audience/sdk-sample-app/serve.mjs b/packages/audience/sdk-sample-app/serve.mjs new file mode 100644 index 0000000000..905333c2ce --- /dev/null +++ b/packages/audience/sdk-sample-app/serve.mjs @@ -0,0 +1,82 @@ +#!/usr/bin/env node +// Static file server for the @imtbl/audience sample app. +// +// Mounts the sample-app's own files under / and the sibling SDK's CDN +// build output under /vendor/. The HTML + +``` + +The CDN bundle attaches `init` (the same static factory ESM consumers +call as `Audience.init({...})`) alongside `AudienceError`, +`AudienceEvents`, `IdentityType`, `canTrack`, `canIdentify`, and +`version`, so every runtime helper an ESM consumer needs is reachable +from the CDN global too. + +## Error handling + +`AudienceError.code` is a closed union — `'FLUSH_FAILED'`, +`'CONSENT_SYNC_FAILED'`, `'NETWORK_ERROR'`, `'VALIDATION_REJECTED'` — +so you can branch on the failure mode: + +```ts +Audience.init({ + publishableKey: 'pk_imapik-test-...', + onError: (err) => { + switch (err.code) { + case 'VALIDATION_REJECTED': + // Terminal: messages were dropped. Inspect err.responseBody + // for per-message detail when the backend provides it. + break; + default: + // Transient: the queue will retry automatically. + break; + } + telemetry.captureException(err); + }, +}); +``` + +Exceptions thrown from `onError` are swallowed by the SDK so a +bad handler can't wedge the queue. + +## Interactive sample app + +For a live harness that exercises every public method, every typed +`track()` event, and every reachable `AudienceErrorCode` against the +real sandbox backend, see [`packages/audience/sdk-sample-app`](https://github.com/immutable/ts-immutable-sdk/tree/main/packages/audience/sdk-sample-app) +in the `ts-immutable-sdk` monorepo. + +## License + +See [LICENSE.md](../../../LICENSE.md) at the repo root. diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 31dab14f00..1dcc87db71 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -120,13 +120,13 @@ importers: version: 29.7.0 jest: specifier: ^29.7.0 - version: 29.7.0(@types/node@22.19.7)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@swc/core@1.15.3(@swc/helpers@0.5.15))(@types/node@22.19.7)(typescript@5.6.2)) + version: 29.7.0(@types/node@20.14.13)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@swc/core@1.15.3(@swc/helpers@0.5.15))(@types/node@20.14.13)(typescript@5.6.2)) ts-jest: specifier: ^29.2.5 - version: 29.2.5(@babel/core@7.26.10)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.26.10))(esbuild@0.23.1)(jest@29.7.0(@types/node@22.19.7)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@swc/core@1.15.3(@swc/helpers@0.5.15))(@types/node@22.19.7)(typescript@5.6.2)))(typescript@5.6.2) + version: 29.2.5(@babel/core@7.26.10)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.26.10))(esbuild@0.23.1)(jest@29.7.0(@types/node@20.14.13)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@swc/core@1.15.3(@swc/helpers@0.5.15))(@types/node@20.14.13)(typescript@5.6.2)))(typescript@5.6.2) ts-node: specifier: ^10.9.2 - version: 10.9.2(@swc/core@1.15.3(@swc/helpers@0.5.15))(@types/node@22.19.7)(typescript@5.6.2) + version: 10.9.2(@swc/core@1.15.3(@swc/helpers@0.5.15))(@types/node@20.14.13)(typescript@5.6.2) typescript: specifier: ^5 version: 5.6.2 @@ -138,7 +138,7 @@ importers: version: 0.25.21(@emotion/react@11.11.3(@types/react@18.3.12)(react@18.3.1))(@rive-app/react-canvas-lite@4.9.0(react@18.3.1))(embla-carousel-react@8.1.5(react@18.3.1))(framer-motion@11.18.2(@emotion/is-prop-valid@0.8.8)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@imtbl/sdk': specifier: latest - version: 2.14.3(bufferutil@4.0.8)(hardhat@2.22.6(bufferutil@4.0.8)(ts-node@10.9.2(@swc/core@1.15.3(@swc/helpers@0.5.15))(@types/node@20.14.13)(typescript@5.6.2))(typescript@5.6.2)(utf-8-validate@5.0.10))(next-auth@5.0.0-beta.30(next@14.2.25(@babel/core@7.26.10)(@playwright/test@1.45.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1))(next@14.2.25(@babel/core@7.26.10)(@playwright/test@1.45.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(utf-8-validate@5.0.10) + version: 2.14.3(bufferutil@4.0.8)(next-auth@5.0.0-beta.30(next@14.2.25(@babel/core@7.26.10)(@playwright/test@1.45.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1))(next@14.2.25(@babel/core@7.26.10)(@playwright/test@1.45.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(utf-8-validate@5.0.10) next: specifier: 14.2.25 version: 14.2.25(@babel/core@7.26.10)(@playwright/test@1.45.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -940,7 +940,7 @@ importers: version: 8.57.0 jest: specifier: ^29.7.0 - version: 29.7.0(@types/node@22.19.7)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@swc/core@1.15.3(@swc/helpers@0.5.15))(@types/node@22.19.7)(typescript@5.6.2)) + version: 29.7.0(@types/node@22.19.7)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2) jest-environment-jsdom: specifier: ^29.4.3 version: 29.6.1(bufferutil@4.0.8)(utf-8-validate@5.0.10) @@ -971,7 +971,7 @@ importers: version: 8.57.0 jest: specifier: ^29.7.0 - version: 29.7.0(@types/node@22.19.7)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@swc/core@1.15.3(@swc/helpers@0.5.15))(@types/node@22.19.7)(typescript@5.6.2)) + version: 29.7.0(@types/node@22.19.7)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2) jest-environment-jsdom: specifier: ^29.4.3 version: 29.6.1(bufferutil@4.0.8)(utf-8-validate@5.0.10) @@ -1011,7 +1011,7 @@ importers: version: 8.57.0 jest: specifier: ^29.7.0 - version: 29.7.0(@types/node@22.19.7)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@swc/core@1.15.3(@swc/helpers@0.5.15))(@types/node@22.19.7)(typescript@5.6.2)) + version: 29.7.0(@types/node@22.19.7)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2) jest-environment-jsdom: specifier: ^29.4.3 version: 29.6.1(bufferutil@4.0.8)(utf-8-validate@5.0.10) @@ -1023,7 +1023,7 @@ importers: version: 6.4.1(rollup@4.28.0)(typescript@5.6.2) ts-jest: specifier: ^29.1.0 - version: 29.2.5(@babel/core@7.26.10)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.26.10))(esbuild@0.23.1)(jest@29.7.0(@types/node@22.19.7)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@swc/core@1.15.3(@swc/helpers@0.5.15))(@types/node@22.19.7)(typescript@5.6.2)))(typescript@5.6.2) + version: 29.2.5(@babel/core@7.26.10)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.26.10))(esbuild@0.23.1)(jest@29.7.0(@types/node@22.19.7)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2))(typescript@5.6.2) tsup: specifier: ^8.3.0 version: 8.3.0(@swc/core@1.15.3(@swc/helpers@0.5.15))(jiti@1.21.0)(postcss@8.4.49)(typescript@5.6.2)(yaml@2.5.0) @@ -1031,6 +1031,12 @@ importers: specifier: ^5.6.2 version: 5.6.2 + packages/audience/sdk-sample-app: + devDependencies: + '@imtbl/audience': + specifier: workspace:* + version: link:../sdk + packages/auth: dependencies: '@imtbl/generated-clients': @@ -1112,13 +1118,13 @@ importers: version: 8.57.0 jest: specifier: ^29.7.0 - version: 29.7.0(@types/node@22.19.7)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@swc/core@1.15.3(@swc/helpers@0.5.15))(@types/node@22.19.7)(typescript@5.6.2)) + version: 29.7.0(@types/node@22.19.7)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2) next: specifier: ^15.2.6 version: 15.5.10(@babel/core@7.26.10)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) next-auth: specifier: ^5.0.0-beta.30 - version: 5.0.0-beta.30(next@15.5.10(@babel/core@7.26.10)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) + version: 5.0.0-beta.30(next@15.5.10(@babel/core@7.26.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) react: specifier: ^18.2.0 version: 18.3.1 @@ -1148,7 +1154,7 @@ importers: version: 8.57.0 jest: specifier: ^29.7.0 - version: 29.7.0(@types/node@22.19.7)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@swc/core@1.15.3(@swc/helpers@0.5.15))(@types/node@22.19.7)(typescript@5.6.2)) + version: 29.7.0(@types/node@22.19.7)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2) next: specifier: ^15.2.6 version: 15.5.10(@babel/core@7.26.10)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@19.0.0-rc-66855b96-20241106))(react@19.0.0-rc-66855b96-20241106) @@ -1188,7 +1194,7 @@ importers: version: 8.57.0 jest: specifier: ^29.7.0 - version: 29.7.0(@types/node@22.19.7)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@swc/core@1.15.3(@swc/helpers@0.5.15))(@types/node@22.19.7)(typescript@5.6.2)) + version: 29.7.0(@types/node@22.19.7)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2) jest-environment-jsdom: specifier: ^29.4.3 version: 29.6.1(bufferutil@4.0.8)(utf-8-validate@5.0.10) @@ -1267,7 +1273,7 @@ importers: version: 8.57.0 jest: specifier: ^29.7.0 - version: 29.7.0(@types/node@22.19.7)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@swc/core@1.15.3(@swc/helpers@0.5.15))(@types/node@22.19.7)(typescript@5.6.2)) + version: 29.7.0(@types/node@22.19.7)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2) jest-environment-jsdom: specifier: ^29.4.3 version: 29.6.1(bufferutil@4.0.8)(utf-8-validate@5.0.10) @@ -1967,7 +1973,7 @@ importers: version: 22.19.7 jest: specifier: ^29.7.0 - version: 29.7.0(@types/node@22.19.7)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@swc/core@1.15.3(@swc/helpers@0.5.15))(@types/node@22.19.7)(typescript@5.6.2)) + version: 29.7.0(@types/node@22.19.7)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2) rimraf: specifier: ^6.0.1 version: 6.0.1 @@ -2004,13 +2010,13 @@ importers: version: 8.57.0 jest: specifier: ^29.7.0 - version: 29.7.0(@types/node@22.19.7)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@swc/core@1.15.3(@swc/helpers@0.5.15))(@types/node@22.19.7)(typescript@5.6.2)) + version: 29.7.0(@types/node@22.19.7)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2) jest-environment-jsdom: specifier: ^29.4.3 version: 29.6.1(bufferutil@4.0.8)(utf-8-validate@5.0.10) ts-jest: specifier: ^29.1.0 - version: 29.2.5(@babel/core@7.26.10)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.26.10))(esbuild@0.23.1)(jest@29.7.0(@types/node@22.19.7)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@swc/core@1.15.3(@swc/helpers@0.5.15))(@types/node@22.19.7)(typescript@5.6.2)))(typescript@5.6.2) + version: 29.2.5(@babel/core@7.26.10)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.26.10))(esbuild@0.23.1)(jest@29.7.0(@types/node@22.19.7)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2))(typescript@5.6.2) tsup: specifier: ^8.3.0 version: 8.3.0(@swc/core@1.15.3(@swc/helpers@0.5.15))(jiti@1.21.0)(postcss@8.4.49)(typescript@5.6.2)(yaml@2.5.0) @@ -2142,7 +2148,7 @@ importers: version: 8.57.0 jest: specifier: ^29.7.0 - version: 29.7.0(@types/node@22.19.7)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@swc/core@1.15.3(@swc/helpers@0.5.15))(@types/node@22.19.7)(typescript@5.6.2)) + version: 29.7.0(@types/node@22.19.7)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2) jest-environment-jsdom: specifier: ^29.4.3 version: 29.6.1(bufferutil@4.0.8)(utf-8-validate@5.0.10) @@ -2200,7 +2206,7 @@ importers: version: 8.57.0 jest: specifier: ^29.7.0 - version: 29.7.0(@types/node@22.19.7)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@swc/core@1.15.3(@swc/helpers@0.5.15))(@types/node@22.19.7)(typescript@5.6.2)) + version: 29.7.0(@types/node@22.19.7)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2) jest-environment-jsdom: specifier: ^29.4.3 version: 29.6.1(bufferutil@4.0.8)(utf-8-validate@5.0.10) @@ -2483,7 +2489,7 @@ importers: version: 8.57.0 jest: specifier: ^29.7.0 - version: 29.7.0(@types/node@22.19.7)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@swc/core@1.15.3(@swc/helpers@0.5.15))(@types/node@22.19.7)(typescript@5.6.2)) + version: 29.7.0(@types/node@22.19.7)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2) jest-environment-jsdom: specifier: ^29.4.3 version: 29.6.1(bufferutil@4.0.8)(utf-8-validate@5.0.10) @@ -20408,12 +20414,12 @@ snapshots: - supports-color - utf-8-validate - '@imtbl/checkout-sdk@2.14.3(bufferutil@4.0.8)(hardhat@2.22.6(bufferutil@4.0.8)(ts-node@10.9.2(@swc/core@1.15.3(@swc/helpers@0.5.15))(@types/node@20.14.13)(typescript@5.6.2))(typescript@5.6.2)(utf-8-validate@5.0.10))(typescript@5.6.2)(utf-8-validate@5.0.10)': + '@imtbl/checkout-sdk@2.14.3(bufferutil@4.0.8)(typescript@5.6.2)(utf-8-validate@5.0.10)': dependencies: '@imtbl/blockchain-data': 2.14.3 '@imtbl/bridge-sdk': 2.14.3(bufferutil@4.0.8)(utf-8-validate@5.0.10) '@imtbl/config': 2.14.3 - '@imtbl/dex-sdk': 2.14.3(bufferutil@4.0.8)(hardhat@2.22.6(bufferutil@4.0.8)(ts-node@10.9.2(@swc/core@1.15.3(@swc/helpers@0.5.15))(@types/node@20.14.13)(typescript@5.6.2))(typescript@5.6.2)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) + '@imtbl/dex-sdk': 2.14.3(bufferutil@4.0.8)(utf-8-validate@5.0.10) '@imtbl/generated-clients': 2.14.3 '@imtbl/metrics': 2.14.3 '@imtbl/orderbook': 2.14.3(bufferutil@4.0.8)(utf-8-validate@5.0.10) @@ -20479,12 +20485,12 @@ snapshots: - typescript - utf-8-validate - '@imtbl/dex-sdk@2.14.3(bufferutil@4.0.8)(hardhat@2.22.6(bufferutil@4.0.8)(ts-node@10.9.2(@swc/core@1.15.3(@swc/helpers@0.5.15))(@types/node@20.14.13)(typescript@5.6.2))(typescript@5.6.2)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10)': + '@imtbl/dex-sdk@2.14.3(bufferutil@4.0.8)(utf-8-validate@5.0.10)': dependencies: '@imtbl/config': 2.14.3 '@uniswap/sdk-core': 3.2.3 - '@uniswap/swap-router-contracts': 1.3.1(hardhat@2.22.6(bufferutil@4.0.8)(ts-node@10.9.2(@swc/core@1.15.3(@swc/helpers@0.5.15))(@types/node@20.14.13)(typescript@5.6.2))(typescript@5.6.2)(utf-8-validate@5.0.10)) - '@uniswap/v3-sdk': 3.10.0(hardhat@2.22.6(bufferutil@4.0.8)(ts-node@10.9.2(@swc/core@1.15.3(@swc/helpers@0.5.15))(@types/node@20.14.13)(typescript@5.6.2))(typescript@5.6.2)(utf-8-validate@5.0.10)) + '@uniswap/swap-router-contracts': 1.3.1(hardhat@2.22.6(bufferutil@4.0.8)(ts-node@10.9.2(@swc/core@1.15.3(@swc/helpers@0.5.15))(@types/node@22.19.7)(typescript@5.6.2))(typescript@5.6.2)(utf-8-validate@5.0.10)) + '@uniswap/v3-sdk': 3.10.0(hardhat@2.22.6(bufferutil@4.0.8)(ts-node@10.9.2(@swc/core@1.15.3(@swc/helpers@0.5.15))(@types/node@22.19.7)(typescript@5.6.2))(typescript@5.6.2)(utf-8-validate@5.0.10)) ethers: 6.13.5(bufferutil@4.0.8)(utf-8-validate@5.0.10) transitivePeerDependencies: - bufferutil @@ -20563,13 +20569,13 @@ snapshots: - encoding - supports-color - '@imtbl/sdk@2.14.3(bufferutil@4.0.8)(hardhat@2.22.6(bufferutil@4.0.8)(ts-node@10.9.2(@swc/core@1.15.3(@swc/helpers@0.5.15))(@types/node@20.14.13)(typescript@5.6.2))(typescript@5.6.2)(utf-8-validate@5.0.10))(next-auth@5.0.0-beta.30(next@14.2.25(@babel/core@7.26.10)(@playwright/test@1.45.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1))(next@14.2.25(@babel/core@7.26.10)(@playwright/test@1.45.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(utf-8-validate@5.0.10)': + '@imtbl/sdk@2.14.3(bufferutil@4.0.8)(next-auth@5.0.0-beta.30(next@14.2.25(@babel/core@7.26.10)(@playwright/test@1.45.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1))(next@14.2.25(@babel/core@7.26.10)(@playwright/test@1.45.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(typescript@5.6.2)(utf-8-validate@5.0.10)': dependencies: '@imtbl/auth': 2.14.3 '@imtbl/auth-next-client': 2.14.3(next-auth@5.0.0-beta.30(next@14.2.25(@babel/core@7.26.10)(@playwright/test@1.45.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1))(next@14.2.25(@babel/core@7.26.10)(@playwright/test@1.45.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) '@imtbl/auth-next-server': 2.14.3(next-auth@5.0.0-beta.30(next@14.2.25(@babel/core@7.26.10)(@playwright/test@1.45.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1))(next@14.2.25(@babel/core@7.26.10)(@playwright/test@1.45.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) '@imtbl/blockchain-data': 2.14.3 - '@imtbl/checkout-sdk': 2.14.3(bufferutil@4.0.8)(hardhat@2.22.6(bufferutil@4.0.8)(ts-node@10.9.2(@swc/core@1.15.3(@swc/helpers@0.5.15))(@types/node@20.14.13)(typescript@5.6.2))(typescript@5.6.2)(utf-8-validate@5.0.10))(typescript@5.6.2)(utf-8-validate@5.0.10) + '@imtbl/checkout-sdk': 2.14.3(bufferutil@4.0.8)(typescript@5.6.2)(utf-8-validate@5.0.10) '@imtbl/config': 2.14.3 '@imtbl/minting-backend': 2.14.3 '@imtbl/orderbook': 2.14.3(bufferutil@4.0.8)(utf-8-validate@5.0.10) @@ -25218,17 +25224,6 @@ snapshots: tiny-invariant: 1.3.1 toformat: 2.0.0 - '@uniswap/swap-router-contracts@1.3.1(hardhat@2.22.6(bufferutil@4.0.8)(ts-node@10.9.2(@swc/core@1.15.3(@swc/helpers@0.5.15))(@types/node@20.14.13)(typescript@5.6.2))(typescript@5.6.2)(utf-8-validate@5.0.10))': - dependencies: - '@openzeppelin/contracts': 3.4.2 - '@uniswap/v2-core': 1.0.1 - '@uniswap/v3-core': 1.0.0 - '@uniswap/v3-periphery': 1.4.4 - dotenv: 14.3.2 - hardhat-watcher: 2.5.0(hardhat@2.22.6(bufferutil@4.0.8)(ts-node@10.9.2(@swc/core@1.15.3(@swc/helpers@0.5.15))(@types/node@20.14.13)(typescript@5.6.2))(typescript@5.6.2)(utf-8-validate@5.0.10)) - transitivePeerDependencies: - - hardhat - '@uniswap/swap-router-contracts@1.3.1(hardhat@2.22.6(bufferutil@4.0.8)(ts-node@10.9.2(@swc/core@1.15.3(@swc/helpers@0.5.15))(@types/node@22.19.7)(typescript@5.6.2))(typescript@5.6.2)(utf-8-validate@5.0.10))': dependencies: '@openzeppelin/contracts': 3.4.2 @@ -25260,19 +25255,6 @@ snapshots: '@uniswap/v3-core': 1.0.0 base64-sol: 1.0.1 - '@uniswap/v3-sdk@3.10.0(hardhat@2.22.6(bufferutil@4.0.8)(ts-node@10.9.2(@swc/core@1.15.3(@swc/helpers@0.5.15))(@types/node@20.14.13)(typescript@5.6.2))(typescript@5.6.2)(utf-8-validate@5.0.10))': - dependencies: - '@ethersproject/abi': 5.7.0 - '@ethersproject/solidity': 5.7.0 - '@uniswap/sdk-core': 4.0.6 - '@uniswap/swap-router-contracts': 1.3.1(hardhat@2.22.6(bufferutil@4.0.8)(ts-node@10.9.2(@swc/core@1.15.3(@swc/helpers@0.5.15))(@types/node@20.14.13)(typescript@5.6.2))(typescript@5.6.2)(utf-8-validate@5.0.10)) - '@uniswap/v3-periphery': 1.4.3 - '@uniswap/v3-staker': 1.0.0 - tiny-invariant: 1.3.1 - tiny-warning: 1.0.3 - transitivePeerDependencies: - - hardhat - '@uniswap/v3-sdk@3.10.0(hardhat@2.22.6(bufferutil@4.0.8)(ts-node@10.9.2(@swc/core@1.15.3(@swc/helpers@0.5.15))(@types/node@22.19.7)(typescript@5.6.2))(typescript@5.6.2)(utf-8-validate@5.0.10))': dependencies: '@ethersproject/abi': 5.7.0 @@ -28386,7 +28368,7 @@ snapshots: dependencies: confusing-browser-globals: 1.0.11 eslint: 8.57.0 - eslint-plugin-import: 2.29.1(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.6.2))(eslint@8.57.0) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-typescript@3.5.5(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.6.2))(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0) object.assign: 4.1.5 object.entries: 1.1.8 semver: 6.3.1 @@ -28397,13 +28379,13 @@ snapshots: '@typescript-eslint/parser': 5.62.0(eslint@8.57.0)(typescript@5.6.2) eslint: 8.57.0 eslint-config-airbnb-base: 15.0.0(eslint-plugin-import@2.29.1(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.6.2))(eslint@8.57.0))(eslint@8.57.0) - eslint-plugin-import: 2.29.1(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.6.2))(eslint@8.57.0) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-typescript@3.5.5(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.6.2))(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0) eslint-config-airbnb@19.0.4(eslint-plugin-import@2.29.1(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.6.2))(eslint@8.57.0))(eslint-plugin-jsx-a11y@6.9.0(eslint@8.57.0))(eslint-plugin-react-hooks@5.0.0(eslint@8.57.0))(eslint-plugin-react@7.35.0(eslint@8.57.0))(eslint@8.57.0): dependencies: eslint: 8.57.0 eslint-config-airbnb-base: 15.0.0(eslint-plugin-import@2.29.1(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.6.2))(eslint@8.57.0))(eslint@8.57.0) - eslint-plugin-import: 2.29.1(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.6.2))(eslint@8.57.0) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-typescript@3.5.5(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.6.2))(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0) eslint-plugin-jsx-a11y: 6.9.0(eslint@8.57.0) eslint-plugin-react: 7.35.0(eslint@8.57.0) eslint-plugin-react-hooks: 5.0.0(eslint@8.57.0) @@ -28417,8 +28399,8 @@ snapshots: '@typescript-eslint/parser': 5.62.0(eslint@8.57.0)(typescript@5.6.2) eslint: 8.57.0 eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.5.5(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.6.2))(eslint@8.57.0))(eslint@8.57.0) - eslint-plugin-import: 2.29.1(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-typescript@3.5.5)(eslint@8.57.0) + eslint-import-resolver-typescript: 3.5.5(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.57.0) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-typescript@3.5.5(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.6.2))(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0) eslint-plugin-jsx-a11y: 6.9.0(eslint@8.57.0) eslint-plugin-react: 7.35.0(eslint@8.57.0) eslint-plugin-react-hooks: 4.6.0(eslint@8.57.0) @@ -28437,7 +28419,7 @@ snapshots: eslint: 8.57.0 eslint-import-resolver-node: 0.3.9 eslint-import-resolver-typescript: 3.5.5(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.6.2))(eslint@8.57.0))(eslint@8.57.0) - eslint-plugin-import: 2.29.1(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-typescript@3.5.5)(eslint@8.57.0) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-typescript@3.5.5(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.6.2))(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0) eslint-plugin-jsx-a11y: 6.9.0(eslint@8.57.0) eslint-plugin-react: 7.35.0(eslint@8.57.0) eslint-plugin-react-hooks: 5.0.0-canary-7118f5dd7-20230705(eslint@8.57.0) @@ -28454,8 +28436,8 @@ snapshots: '@typescript-eslint/parser': 5.62.0(eslint@8.57.0)(typescript@5.6.2) eslint: 8.57.0 eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.5.5(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.6.2))(eslint@8.57.0))(eslint@8.57.0) - eslint-plugin-import: 2.29.1(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-typescript@3.5.5)(eslint@8.57.0) + eslint-import-resolver-typescript: 3.5.5(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.57.0) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-typescript@3.5.5(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.6.2))(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0) eslint-plugin-jsx-a11y: 6.9.0(eslint@8.57.0) eslint-plugin-react: 7.35.0(eslint@8.57.0) eslint-plugin-react-hooks: 5.0.0-canary-7118f5dd7-20230705(eslint@8.57.0) @@ -28472,8 +28454,8 @@ snapshots: '@typescript-eslint/parser': 5.62.0(eslint@8.57.0)(typescript@5.6.2) eslint: 8.57.0 eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.5.5(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.6.2))(eslint@8.57.0))(eslint@8.57.0) - eslint-plugin-import: 2.29.1(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-typescript@3.5.5)(eslint@8.57.0) + eslint-import-resolver-typescript: 3.5.5(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.57.0) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-typescript@3.5.5(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.6.2))(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0) eslint-plugin-jsx-a11y: 6.9.0(eslint@8.57.0) eslint-plugin-react: 7.35.0(eslint@8.57.0) eslint-plugin-react-hooks: 5.0.0-canary-7118f5dd7-20230705(eslint@8.57.0) @@ -28521,7 +28503,7 @@ snapshots: confusing-browser-globals: 1.0.11 eslint: 8.57.0 eslint-plugin-flowtype: 8.0.3(@babel/plugin-syntax-flow@7.24.7(@babel/core@7.26.9))(@babel/plugin-transform-react-jsx@7.25.9(@babel/core@7.26.9))(eslint@8.57.0) - eslint-plugin-import: 2.29.1(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.6.2))(eslint@8.57.0) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-typescript@3.5.5(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.6.2))(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0) eslint-plugin-jest: 25.7.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.6.2))(eslint@8.57.0)(typescript@5.6.2))(eslint@8.57.0)(jest@27.5.1(bufferutil@4.0.8)(node-notifier@8.0.2)(ts-node@10.9.2(@swc/core@1.15.3(@swc/helpers@0.5.15))(@types/node@22.19.7)(typescript@5.6.2))(utf-8-validate@5.0.10))(typescript@5.6.2) eslint-plugin-jsx-a11y: 6.9.0(eslint@8.57.0) eslint-plugin-react: 7.35.0(eslint@8.57.0) @@ -28551,7 +28533,25 @@ snapshots: enhanced-resolve: 5.15.0 eslint: 8.57.0 eslint-module-utils: 2.8.1(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.5.5(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.6.2))(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0) - eslint-plugin-import: 2.29.1(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-typescript@3.5.5)(eslint@8.57.0) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-typescript@3.5.5(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.6.2))(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0) + get-tsconfig: 4.6.2 + globby: 13.2.2 + is-core-module: 2.15.0 + is-glob: 4.0.3 + synckit: 0.8.5 + transitivePeerDependencies: + - '@typescript-eslint/parser' + - eslint-import-resolver-node + - eslint-import-resolver-webpack + - supports-color + + eslint-import-resolver-typescript@3.5.5(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.57.0): + dependencies: + debug: 4.3.7(supports-color@8.1.1) + enhanced-resolve: 5.15.0 + eslint: 8.57.0 + eslint-module-utils: 2.8.1(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.5.5)(eslint@8.57.0) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-typescript@3.5.5(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.6.2))(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0) get-tsconfig: 4.6.2 globby: 13.2.2 is-core-module: 2.15.0 @@ -28574,6 +28574,17 @@ snapshots: transitivePeerDependencies: - supports-color + eslint-module-utils@2.8.1(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.5.5)(eslint@8.57.0): + dependencies: + debug: 3.2.7 + optionalDependencies: + '@typescript-eslint/parser': 5.62.0(eslint@8.57.0)(typescript@5.6.2) + eslint: 8.57.0 + eslint-import-resolver-node: 0.3.9 + eslint-import-resolver-typescript: 3.5.5(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.57.0) + transitivePeerDependencies: + - supports-color + eslint-module-utils@2.8.1(@typescript-eslint/parser@5.62.0(eslint@9.16.0(jiti@1.21.0))(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint@9.16.0(jiti@1.21.0)): dependencies: debug: 3.2.7 @@ -28600,34 +28611,7 @@ snapshots: lodash: 4.17.21 string-natural-compare: 3.0.1 - eslint-plugin-import@2.29.1(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-typescript@3.5.5)(eslint@8.57.0): - dependencies: - array-includes: 3.1.8 - array.prototype.findlastindex: 1.2.5 - array.prototype.flat: 1.3.2 - array.prototype.flatmap: 1.3.2 - debug: 3.2.7 - doctrine: 2.1.0 - eslint: 8.57.0 - eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.8.1(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.5.5(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.6.2))(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0) - hasown: 2.0.2 - is-core-module: 2.15.0 - is-glob: 4.0.3 - minimatch: 3.1.2 - object.fromentries: 2.0.8 - object.groupby: 1.0.3 - object.values: 1.2.0 - semver: 6.3.1 - tsconfig-paths: 3.15.0 - optionalDependencies: - '@typescript-eslint/parser': 5.62.0(eslint@8.57.0)(typescript@5.6.2) - transitivePeerDependencies: - - eslint-import-resolver-typescript - - eslint-import-resolver-webpack - - supports-color - - eslint-plugin-import@2.29.1(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.6.2))(eslint@8.57.0): + eslint-plugin-import@2.29.1(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-typescript@3.5.5(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.6.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(@typescript-eslint/parser@5.62.0(eslint@8.57.0)(typescript@5.6.2))(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0): dependencies: array-includes: 3.1.8 array.prototype.findlastindex: 1.2.5 @@ -30038,11 +30022,6 @@ snapshots: - debug - utf-8-validate - hardhat-watcher@2.5.0(hardhat@2.22.6(bufferutil@4.0.8)(ts-node@10.9.2(@swc/core@1.15.3(@swc/helpers@0.5.15))(@types/node@20.14.13)(typescript@5.6.2))(typescript@5.6.2)(utf-8-validate@5.0.10)): - dependencies: - chokidar: 3.6.0 - hardhat: 2.22.6(bufferutil@4.0.8)(ts-node@10.9.2(@swc/core@1.15.3(@swc/helpers@0.5.15))(@types/node@20.14.13)(typescript@5.6.2))(typescript@5.6.2)(utf-8-validate@5.0.10) - hardhat-watcher@2.5.0(hardhat@2.22.6(bufferutil@4.0.8)(ts-node@10.9.2(@swc/core@1.15.3(@swc/helpers@0.5.15))(@types/node@22.19.7)(typescript@5.6.2))(typescript@5.6.2)(utf-8-validate@5.0.10)): dependencies: chokidar: 3.6.0 @@ -31043,6 +31022,27 @@ snapshots: - supports-color - ts-node + jest-cli@29.7.0(@types/node@22.19.7)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2): + dependencies: + '@jest/core': 29.7.0(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@swc/core@1.15.3(@swc/helpers@0.5.15))(@types/node@20.14.13)(typescript@5.6.2)) + '@jest/test-result': 29.7.0 + '@jest/types': 29.6.3 + chalk: 4.1.2 + create-jest: 29.7.0(@types/node@22.19.7)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.3(@swc/helpers@0.5.15))(@types/node@22.19.7)(typescript@5.6.2)) + exit: 0.1.2 + import-local: 3.1.0 + jest-config: 29.7.0(@types/node@22.19.7)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.15.3(@swc/helpers@0.5.15))(@types/node@22.19.7)(typescript@5.6.2)) + jest-util: 29.7.0 + jest-validate: 29.7.0 + yargs: 17.7.2 + optionalDependencies: + node-notifier: 8.0.2 + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - supports-color + - ts-node + jest-cli@29.7.0(@types/node@22.19.7)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@swc/core@1.15.3(@swc/helpers@0.5.15))(@types/node@22.19.7)(typescript@5.6.2)): dependencies: '@jest/core': 29.7.0(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@swc/core@1.15.3(@swc/helpers@0.5.15))(@types/node@22.19.7)(typescript@5.6.2)) @@ -32090,6 +32090,20 @@ snapshots: - supports-color - ts-node + jest@29.7.0(@types/node@22.19.7)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2): + dependencies: + '@jest/core': 29.7.0(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@swc/core@1.15.3(@swc/helpers@0.5.15))(@types/node@20.14.13)(typescript@5.6.2)) + '@jest/types': 29.6.3 + import-local: 3.1.0 + jest-cli: 29.7.0(@types/node@22.19.7)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2) + optionalDependencies: + node-notifier: 8.0.2 + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - supports-color + - ts-node + jest@29.7.0(@types/node@22.19.7)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@swc/core@1.15.3(@swc/helpers@0.5.15))(@types/node@22.19.7)(typescript@5.6.2)): dependencies: '@jest/core': 29.7.0(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@swc/core@1.15.3(@swc/helpers@0.5.15))(@types/node@22.19.7)(typescript@5.6.2)) @@ -33238,12 +33252,6 @@ snapshots: react: 18.3.1 optional: true - next-auth@5.0.0-beta.30(next@15.5.10(@babel/core@7.26.10)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1): - dependencies: - '@auth/core': 0.41.0 - next: 15.5.10(@babel/core@7.26.10)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - react: 18.3.1 - next-auth@5.0.0-beta.30(next@15.5.10(@babel/core@7.26.10)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@19.0.0-rc-66855b96-20241106))(react@19.0.0-rc-66855b96-20241106))(react@19.0.0-rc-66855b96-20241106): dependencies: '@auth/core': 0.41.0 @@ -33253,7 +33261,7 @@ snapshots: next-auth@5.0.0-beta.30(next@15.5.10(@babel/core@7.26.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1): dependencies: '@auth/core': 0.41.0 - next: 15.5.10(@babel/core@7.26.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + next: 15.5.10(@babel/core@7.26.10)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 next@14.2.25(@babel/core@7.26.10)(@playwright/test@1.45.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): @@ -33328,29 +33336,6 @@ snapshots: - '@babel/core' - babel-plugin-macros - next@15.5.10(@babel/core@7.26.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): - dependencies: - '@next/env': 15.5.10 - '@swc/helpers': 0.5.15 - caniuse-lite: 1.0.30001760 - postcss: 8.4.31 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - styled-jsx: 5.1.6(@babel/core@7.26.10)(babel-plugin-macros@3.1.0)(react@18.3.1) - optionalDependencies: - '@next/swc-darwin-arm64': 15.5.7 - '@next/swc-darwin-x64': 15.5.7 - '@next/swc-linux-arm64-gnu': 15.5.7 - '@next/swc-linux-arm64-musl': 15.5.7 - '@next/swc-linux-x64-gnu': 15.5.7 - '@next/swc-linux-x64-musl': 15.5.7 - '@next/swc-win32-arm64-msvc': 15.5.7 - '@next/swc-win32-x64-msvc': 15.5.7 - sharp: 0.34.5 - transitivePeerDependencies: - - '@babel/core' - - babel-plugin-macros - nice-napi@1.0.2: dependencies: node-addon-api: 3.2.1 @@ -37134,6 +37119,26 @@ snapshots: babel-jest: 29.7.0(@babel/core@7.26.10) esbuild: 0.23.1 + ts-jest@29.2.5(@babel/core@7.26.10)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.26.10))(esbuild@0.23.1)(jest@29.7.0(@types/node@22.19.7)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2))(typescript@5.6.2): + dependencies: + bs-logger: 0.2.6 + ejs: 3.1.10 + fast-json-stable-stringify: 2.1.0 + jest: 29.7.0(@types/node@22.19.7)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2) + jest-util: 29.7.0 + json5: 2.2.3 + lodash.memoize: 4.1.2 + make-error: 1.3.6 + semver: 7.6.3 + typescript: 5.6.2 + yargs-parser: 21.1.1 + optionalDependencies: + '@babel/core': 7.26.10 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + babel-jest: 29.7.0(@babel/core@7.26.10) + esbuild: 0.23.1 + ts-jest@29.2.5(@babel/core@7.26.9)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.26.9))(esbuild@0.23.1)(jest@29.7.0(@types/node@22.19.7)(babel-plugin-macros@3.1.0)(node-notifier@8.0.2)(ts-node@10.9.2(@swc/core@1.15.3(@swc/helpers@0.5.15))(@types/node@22.19.7)(typescript@5.6.2)))(typescript@5.6.2): dependencies: bs-logger: 0.2.6 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 09f5e8fee2..7ae4680e8e 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -24,6 +24,7 @@ packages: - "packages/audience/core" - "packages/audience/pixel" - "packages/audience/sdk" + - "packages/audience/sdk-sample-app" - "packages/game-bridge" - "packages/webhook/sdk" - "packages/minting-backend/sdk"