Skip to content

@trackbridge/core

The shared kernel: type definitions, normalization rules for enhanced-conversion fields, and the SHA-256 helper used identically on browser and server. Both @trackbridge/browser and @trackbridge/server depend on this package.

You’ll rarely import from @trackbridge/core yourself. The cases where you might:

  • You’re building tooling that needs to inspect what the SDK will send to Google before it sends it (for testing or auditing).
  • You’re hashing identity fields somewhere outside the conversion path and want to use the same normalization as the SDK so values match.
  • You’re extending Trackbridge with a new transport (CAPI, TikTok, etc.) and want to reuse the normalization layer.

Outside those cases, prefer the browser/server packages.

import {
hashSha256,
hashUserData,
normalizeAddress,
normalizeEmail,
normalizeName,
normalizePhone,
} from '@trackbridge/core';
import type {
Address,
HashedAddress,
HashedUserData,
UserData,
} from '@trackbridge/core';

hashSha256(input: string): Promise<string>

Section titled “hashSha256(input: string): Promise<string>”
function hashSha256(input: string): Promise<string>;

Computes the SHA-256 hash of input’s UTF-8 byte representation. Returns 64 lowercase hex characters. The encoding is fixed to UTF-8 internally so browser and server cannot disagree on bytes.

The caller is responsible for normalizing the string first — hashSha256 does no transformation.

await hashSha256('hello'); // → '2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824'

hashUserData(input: UserData): Promise<HashedUserData>

Section titled “hashUserData(input: UserData): Promise<HashedUserData>”
function hashUserData(input: UserData): Promise<HashedUserData>;

Normalizes and SHA-256-hashes every field of a UserData object that Google expects hashed (email, phone, firstName, lastName, address.street). Address-locality fields (city, region, postalCode, country) are normalized but not hashed — Google requires them in plaintext.

Fields that are absent on input or normalize to an empty string are omitted from the result. The address key is omitted entirely when no sub-field survives normalization.

await hashUserData({
email: ' Alice@Example.COM ',
address: { country: 'us' },
});
// → {
// email: 'd9f...64-hex...',
// address: { country: 'US' }, // normalized to ISO-3166 alpha-2 uppercase, not hashed
// }
function normalizeEmail(input: string): string;

Trim → lowercase → Unicode NFC. Returns '' for input that trims to empty.

function normalizePhone(input: string): string;

Strips whitespace and non-digit characters; preserves a leading + if present. Does not infer a country code (which would depend on runtime locale and would silently diverge between client and server). Returns digits only when no + is present, or +<digits> when one is.

normalizePhone(' (555) 123-4567 '); // → '5551234567'
normalizePhone('+1 (555) 123-4567'); // → '+15551234567'
function normalizeName(input: string): string;

Trim → lowercase → NFC. Preserves hyphens, apostrophes, internal spaces, and diacritics in their NFC form.

function normalizeAddress(input: Address): Address;

Field-by-field normalization:

FieldRule
street, city, regiontrim → lowercase → NFC
postalCodetrim → lowercase. Internal spaces preserved (UK SW1A 1AA stays as written).
countrytrim → uppercase → NFC. Convention: ISO 3166-1 alpha-2 (US, GB, DE).

Undefined input fields are omitted from the result. Fields present but normalizing to an empty string are kept as empty.

type UserData = {
email?: string;
phone?: string;
firstName?: string;
lastName?: string;
address?: Address;
};
type Address = {
street?: string;
city?: string;
region?: string;
postalCode?: string;
country?: string;
};
type HashedUserData = {
email?: string;
phone?: string;
firstName?: string;
lastName?: string;
address?: HashedAddress;
};
type HashedAddress = {
street?: string;
city?: string;
region?: string;
postalCode?: string;
country?: string;
};

HashedUserData and HashedAddress are structurally identical to their unhashed counterparts. The string fields hold lowercase hex SHA-256 digests instead of plaintext.