// Test-side helpers: load the seed artifact, build SDK clients against prod, and // reach the admin API for wallet grants / player inspection. import { RudderClient } from '../../../src/client/RudderClient.js'; import type { RemoteConfigShape } from '../../../src/state/RemoteConfigState.js'; import type { TokenStore } from '../../../src/token/TokenStore.js'; import { createAdminClient, type AdminClient } from './adminClient.js'; import { readArtifact } from './artifact.js'; import type { SeedArtifact } from './types.js'; type RuntimeOptions = { loginEvent?: string | null; }; /** Loads the seed artifact; RUDDER_E2E_* env vars override file values. */ export function loadArtifact(): SeedArtifact { const file = readArtifact(); if (!file) { throw new Error( 'No seed artifact (.e2e-prod.local.json). Run `npm run test:e2e-prod` (globalSetup seeds automatically).', ); } return { ...file, baseUrl: process.env.RUDDER_E2E_BASE_URL ?? file.baseUrl, projectKey: process.env.RUDDER_E2E_PROJECT_KEY ?? file.projectKey, }; } export function createInMemoryTokenStore(): TokenStore { let access: string | null = null; let refresh: string | null = null; return { getAccessToken: () => access, getRefreshToken: () => refresh, saveTokens: (a, r) => { access = a; refresh = r; }, clear: () => { access = null; refresh = null; }, }; } /** A client with no auth yet (in-memory tokens, no IndexedDB persistence). */ export function makeProdClient( artifact: SeedArtifact = loadArtifact(), runtime: RuntimeOptions = { loginEvent: null }, ): RudderClient { return new RudderClient({ baseUrl: artifact.baseUrl, projectKey: artifact.projectKey, tokenStore: createInMemoryTokenStore(), runtime, }); } /** A device-authenticated client. In Node each call mints a fresh player (ephemeral device id). */ export async function freshPlayer( artifact: SeedArtifact = loadArtifact(), runtime?: RuntimeOptions, ): Promise> { const client = makeProdClient(artifact, runtime); await client.auth.loginWithDevice({ region: 'en', language: 'en' }); return client; } /** Admin (operator) API client authenticated with the seeded operator token. */ export function adminApi(artifact: SeedArtifact = loadArtifact()): AdminClient { const api = createAdminClient(artifact.baseUrl); api.setToken(artifact.adminToken); return api; } const sleep = (ms: number) => new Promise((r) => setTimeout(r, ms)); /** Retries a read until ok(result) holds — absorbs release/cache reload lag. */ export async function withReadRetry( fn: () => Promise, ok: (value: T) => boolean, tries = 8, gapMs = 1500, ): Promise { let last = await fn(); if (ok(last)) return last; for (let i = 1; i < tries; i++) { await sleep(gapMs); last = await fn(); if (ok(last)) return last; } return last; }