Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 0 additions & 15 deletions packages/audience/core/src/config.test.ts

This file was deleted.

8 changes: 1 addition & 7 deletions packages/audience/core/src/config.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const TEST_KEY_PREFIX = 'pk_imapik-test-';
export const BASE_URL = 'https://api.immutable.com';

export const INGEST_PATH = '/v1/audience/messages';
export const CONSENT_PATH = '/v1/audience/tracking-consent';
Expand All @@ -13,9 +13,3 @@ export const SESSION_MAX_AGE = 30 * 60; // 30 minutes in seconds

export const SESSION_START = 'session_start';
export const SESSION_END = 'session_end';

export const getBaseUrl = (publishableKey: string): string => (
publishableKey.startsWith(TEST_KEY_PREFIX)
? 'https://api.sandbox.immutable.com'
: 'https://api.immutable.com'
);
6 changes: 3 additions & 3 deletions packages/audience/core/src/consent.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ describe('createConsentManager', () => {
manager.setLevel('anonymous');

expect(send).toHaveBeenCalledWith(
'https://api.sandbox.immutable.com/v1/audience/tracking-consent',
'https://api.immutable.com/v1/audience/tracking-consent',
'pk_imapik-test-local',
{ anonymousId: 'anon-1', status: 'anonymous', source: 'pixel' },
{ method: 'PUT', keepalive: true },
Expand Down Expand Up @@ -146,7 +146,7 @@ describe('createConsentManager', () => {
ok: false,
error: new TransportError({
status: 503,
endpoint: 'https://api.sandbox.immutable.com/v1/audience/tracking-consent',
endpoint: 'https://api.immutable.com/v1/audience/tracking-consent',
body: { code: 'SERVICE_UNAVAILABLE' },
}),
});
Expand All @@ -172,7 +172,7 @@ describe('createConsentManager', () => {
ok: false,
error: new TransportError({
status: 0,
endpoint: 'https://api.sandbox.immutable.com/v1/audience/tracking-consent',
endpoint: 'https://api.immutable.com/v1/audience/tracking-consent',
cause: new TypeError('Failed to fetch'),
}),
});
Expand Down
4 changes: 2 additions & 2 deletions packages/audience/core/src/consent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import type {
import type { MessageQueue } from './queue';
import type { HttpSend } from './transport';
import { type AudienceError, invokeOnError, toAudienceError } from './errors';
import { CONSENT_PATH, getBaseUrl } from './config';
import { BASE_URL, CONSENT_PATH } from './config';

export interface ConsentManager {
level: ConsentLevel;
Expand Down Expand Up @@ -59,7 +59,7 @@ export function createConsentManager(
const LEVELS: Record<ConsentLevel, number> = { none: 0, anonymous: 1, full: 2 };

function notifyBackend(level: ConsentLevel): void {
const url = `${baseUrl ?? getBaseUrl(publishableKey)}${CONSENT_PATH}`;
const url = `${baseUrl ?? BASE_URL}${CONSENT_PATH}`;
Comment thread
cursor[bot] marked this conversation as resolved.
const payload: ConsentUpdatePayload = { anonymousId, status: level, source };
// Fire-and-forget. HttpSend never rejects, so the floating chain is safe.
send(url, publishableKey, payload, { method: 'PUT', keepalive: true })
Expand Down
10 changes: 5 additions & 5 deletions packages/audience/core/src/queue.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ describe('MessageQueue', () => {
const send = jest.fn<ReturnType<HttpSend>, Parameters<HttpSend>>().mockResolvedValue({
ok: false,
error: new TransportError({
status: 500, endpoint: 'https://api.sandbox.immutable.com/v1/audience/messages', body: null,
status: 500, endpoint: 'https://api.immutable.com/v1/audience/messages', body: null,
}),
});
const queue = createQueue(send, { onError });
Expand All @@ -228,7 +228,7 @@ describe('MessageQueue', () => {
ok: false,
error: new TransportError({
status: 0,
endpoint: 'https://api.sandbox.immutable.com/v1/audience/messages',
endpoint: 'https://api.immutable.com/v1/audience/messages',
cause: new TypeError('Failed to fetch'),
}),
});
Expand Down Expand Up @@ -278,7 +278,7 @@ describe('MessageQueue', () => {
ok: false,
error: new TransportError({
status: 200,
endpoint: 'https://api.sandbox.immutable.com/v1/audience/messages',
endpoint: 'https://api.immutable.com/v1/audience/messages',
body: { accepted: 1, rejected: 1 },
}),
});
Expand Down Expand Up @@ -342,7 +342,7 @@ describe('page-unload flush (keepalive)', () => {
document.dispatchEvent(new Event('visibilitychange'));

expect(send).toHaveBeenCalledWith(
'https://api.sandbox.immutable.com/v1/audience/messages',
'https://api.immutable.com/v1/audience/messages',
'pk_imapik-test-local',
expect.objectContaining({ messages: expect.any(Array) }),
{ keepalive: true },
Expand All @@ -366,7 +366,7 @@ describe('page-unload flush (keepalive)', () => {
window.dispatchEvent(new Event('pagehide'));

expect(send).toHaveBeenCalledWith(
'https://api.sandbox.immutable.com/v1/audience/messages',
'https://api.immutable.com/v1/audience/messages',
'pk_imapik-test-local',
expect.objectContaining({ messages: expect.any(Array) }),
{ keepalive: true },
Expand Down
4 changes: 2 additions & 2 deletions packages/audience/core/src/queue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type { Message, BatchPayload } from './types';
import type { HttpSend } from './transport';
import { type AudienceError, invokeOnError, toAudienceError } from './errors';
import {
getBaseUrl, INGEST_PATH, FLUSH_INTERVAL_MS, FLUSH_SIZE,
BASE_URL, INGEST_PATH, FLUSH_INTERVAL_MS, FLUSH_SIZE,
} from './config';
import * as storage from './storage';
import { isBrowser } from './utils';
Expand Down Expand Up @@ -87,7 +87,7 @@ export class MessageQueue {
private readonly publishableKey: string,
options?: MessageQueueOptions,
) {
this.endpointUrl = `${options?.baseUrl ?? getBaseUrl(publishableKey)}${INGEST_PATH}`;
this.endpointUrl = `${options?.baseUrl ?? BASE_URL}${INGEST_PATH}`;
this.flushIntervalMs = options?.flushIntervalMs ?? FLUSH_INTERVAL_MS;
this.flushSize = options?.flushSize ?? FLUSH_SIZE;
this.onFlush = options?.onFlush;
Expand Down
2 changes: 2 additions & 0 deletions packages/audience/core/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ interface BaseMessage {
anonymousId: string;
surface: Surface;
context: EventContext;
/** Present when the SDK/pixel is initialised with testMode: true. */
test?: true;
}

export interface TrackMessage extends BaseMessage {
Expand Down
7 changes: 6 additions & 1 deletion packages/audience/pixel/src/pixel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ export interface PixelInitOptions {
autocapture?: AutocaptureOptions;
/** Override the default API base URL. */
baseUrl?: string;
/** When true, all events are marked test: true and can be filtered from production analytics. */
testMode?: boolean;
}

export class Pixel {
Expand All @@ -55,6 +57,8 @@ export class Pixel {

private domain: string | undefined;

private testMode = false;

private initialized = false;

private unloadHandler?: () => void;
Expand All @@ -80,6 +84,7 @@ export class Pixel {

this.publishableKey = key;
this.domain = domain;
this.testMode = options.testMode ?? false;

this.queue = new MessageQueue(
httpSend,
Expand Down Expand Up @@ -320,14 +325,14 @@ export class Pixel {

// -- Helpers ------------------------------------------------------------

// eslint-disable-next-line class-methods-use-this
private buildBase() {
return {
messageId: generateId(),
eventTimestamp: getTimestamp(),
anonymousId: this.anonymousId,
surface: 'pixel' as const,
context: collectContext('@imtbl/pixel', PIXEL_VERSION),
...(this.testMode && { test: true as const }),
};
}

Expand Down
4 changes: 4 additions & 0 deletions packages/audience/sdk/src/sdk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ export class Audience {

private readonly cookieDomain?: string;

private readonly testMode: boolean;

private anonymousId: string;

private sessionId: string | undefined;
Expand All @@ -81,6 +83,7 @@ export class Audience {
const consentSource = DEFAULT_CONSENT_SOURCE;

this.cookieDomain = cookieDomain;
this.testMode = config.testMode ?? false;
this.debug = new DebugLogger(config.debug ?? false);

let isNewSession = false;
Expand Down Expand Up @@ -173,6 +176,7 @@ export class Audience {
anonymousId: this.anonymousId,
surface: 'web' as const,
context: collectContext(LIBRARY_NAME, LIBRARY_VERSION),
...(this.testMode && { test: true as const }),
};
}

Expand Down
2 changes: 2 additions & 0 deletions packages/audience/sdk/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ export interface AudienceConfig {
flushSize?: number;
/** Override the default API base URL. */
baseUrl?: string;
/** When true, all events are marked test: true and can be filtered from production analytics. */
testMode?: boolean;
/**
* Called when the SDK fails to reach the backend. Receives a structured
* {@link AudienceError} with a machine-readable `code` so studios can
Expand Down
Loading