@atlasauth/js 0.13.0 → 0.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -4,28 +4,51 @@
4
4
  * whoever referred them.
5
5
  *
6
6
  * What is captured, when the instance has referrals on (`referrals` in
7
- * `GET /v1/client/environment`):
8
- * - the referral code from the page URL — the instance's URL parameters
9
- * (default `ref`, `via`, `aff`) on the current page, the page the SDK first
10
- * loaded on, and the `redirect_url` / `after_url` query of either;
11
- * - with consent, the referral platform's first-party tracking cookie (the
12
- * instance's `context_cookie`): JSON or URL-encoded JSON
13
- * `{code?, clickId?, anonId?}`, or a plain click id. A URL code wins over the
14
- * cookie's code.
7
+ * `GET /v1/client/environment`): ONE source, in precedence order, never
8
+ * mixing fields across sources:
9
+ * 1. the app's own reader (`referralSource`), for any referral program;
10
+ * 2. a referral program's script on the page, among the instance's
11
+ * `browser_sources` (Referally's `aff.getReferral()`, Rewardful, Tolt,
12
+ * PromoteKit; see ./referral-detect);
13
+ * 3. explicit `ref_*` parameters (`ref`, `ref_click_id`, `ref_anon_id`,
14
+ * `ref_consent`, `ref_captured_at`) on the page URL;
15
+ * 4. the referral code from the page URL — the instance's URL parameters
16
+ * (default `ref`, `via`, `aff`) on the current page, the page the SDK first
17
+ * loaded on, and the `redirect_url` / `after_url` query of either;
18
+ * 5. the instance's tracking cookie (`context_cookie`): JSON or URL-encoded
19
+ * JSON `{code?, clickId?, anonId?, ts?, exp?}`, or a plain click id. An
20
+ * expired cookie is ignored;
21
+ * 6. a referral program's own cookies, among `browser_sources`
22
+ * (FirstPromoter, PartnerStack, Dub).
23
+ * Click and anonymous ids are sent only with consent; without it only the
24
+ * code goes. The capture says where it came from (`source`) and who decided
25
+ * consent (`consent_by`), for the delivery log.
15
26
  *
16
- * Consent: when Cookie Munch is on the page (`window.CookieMunch`), the cookie
17
- * is read only when the instance's consent category is granted (else its
18
- * fallback category). Without a consent manager the cookie is read only when
19
- * the app says its own consent manager allowed it (`referralConsent:
20
- * 'granted'`). Otherwise the URL code alone is sent. The SDK never writes the
27
+ * Consent: the consent manager on the page decides (the instance's
28
+ * `consent_provider`: `auto` finds Cookie Munch, OneTrust, Cookiebot, Didomi,
29
+ * Usercentrics, Osano, CookieYes, Complianz, Klaro, any IAB TCF v2 manager or
30
+ * Google Consent Mode), for the instance's consent category, else its fallback
31
+ * category. With no manager on the page, or `consent_provider: 'app'`, the
32
+ * app's own decision (`referralConsent`) applies. Otherwise only the code is
33
+ * sent. The SDK never writes a
21
34
  * cookie. Nothing captured is trusted: the server re-validates every field.
22
35
  *
23
36
  * Opt out with `referral: false` (per client, or page-wide with
24
- * {@link configureReferralCapture}).
37
+ * {@link configureReferralCapture}). `'auto'` is the default.
38
+ *
39
+ * Redirects to a hosted page or `/oauth2/authorize` carry the same referral as
40
+ * `ref_*` query parameters: {@link signIn} / {@link signUp},
41
+ * {@link withReferralParams} and {@link referralParams}.
25
42
  */
43
+ import { type ReferralSourceReader } from './referral-detect';
44
+ export type { ReferralSourceReader } from './referral-detect';
26
45
  /** The instance's public referral settings, camelCased. */
27
46
  export interface ReferralConfig {
28
47
  enabled: boolean;
48
+ /** The referral programs' scripts and cookies to read (`browser_sources`), in order. */
49
+ sources: string[];
50
+ /** Which consent manager decides: `auto`, a manager id, or `app` (only the app's `referralConsent`). */
51
+ consentProvider: string;
29
52
  /** URL query parameters that carry a code, in priority order. */
30
53
  urlParams: string[];
31
54
  /** The tracking cookie to read under consent; null = never read a cookie. */
@@ -34,6 +57,10 @@ export interface ReferralConfig {
34
57
  consentFallbackCategory: string | null;
35
58
  /** `always`: a sign-up carrying a referral code must pass the bot challenge. */
36
59
  challengeReferredSignups: 'always' | 'inherit';
60
+ /** Public "Invited by" lookup URL template with `{code}`, or null. See {@link lookupReferralCode}. */
61
+ codeLookupUrl: string | null;
62
+ /** The instance shows an optional "Referral code" field on sign-up. */
63
+ signupCodeField: boolean;
37
64
  }
38
65
  /** The `referral` object a sign-in / sign-up request carries (snake_case, as the API takes it). */
39
66
  export interface ReferralCapture {
@@ -43,6 +70,10 @@ export interface ReferralCapture {
43
70
  consent: 'granted' | 'not_required';
44
71
  /** ISO 8601. */
45
72
  captured_at: string;
73
+ /** Where it came from: `custom`, a program id (e.g. `rewardful`), `url` or `cookie`. */
74
+ source?: string;
75
+ /** Who decided consent for the ids: `app`, `url`, a consent manager id, or `none`. */
76
+ consent_by?: string;
46
77
  }
47
78
  /**
48
79
  * The app's own consent decision for the referral cookie, used only when no
@@ -52,10 +83,15 @@ export interface ReferralCapture {
52
83
  export type ReferralConsent = 'granted' | 'denied' | boolean | (() => 'granted' | 'denied' | boolean | null | undefined);
53
84
  /** The referral options a FAPI client and the prebuilt components take. */
54
85
  export interface ReferralCaptureOptions {
55
- /** `false` turns referral capture off. */
56
- referral?: false | undefined;
86
+ /** `false` turns referral capture off; `'auto'` (the default) captures when the instance has referrals on. */
87
+ referral?: false | 'auto' | undefined;
57
88
  /** See {@link ReferralConsent}. */
58
89
  referralConsent?: ReferralConsent;
90
+ /**
91
+ * Your own reader, for a referral program the SDK doesn't know: return
92
+ * `{code, clickId, anonId}` (any of them) or null. Tried before everything else.
93
+ */
94
+ referralSource?: ReferralSourceReader;
59
95
  }
60
96
  export declare const DISABLED_REFERRAL_CONFIG: Readonly<ReferralConfig>;
61
97
  /** A well-formed code / click id / anonymous id, or null. */
@@ -69,21 +105,31 @@ export declare function referralConfigFrom(body: unknown): ReferralConfig;
69
105
  export declare function referralCodeFromSearch(search: string | null | undefined, params: readonly string[]): string | null;
70
106
  /** The query strings a code may be in: each search, plus its `redirect_url` / `after_url` targets' queries. */
71
107
  export declare function referralSearches(searches: readonly string[], base?: string): string[];
72
- /**
73
- * Parse a tracking-cookie value: JSON or URL-encoded JSON `{code?, clickId?,
74
- * anonId?}` (snake_case accepted too); a plain value is a click id.
75
- */
76
- export declare function parseReferralCookie(value: string | null | undefined): {
108
+ /** An ISO time from an ISO string or unix seconds / milliseconds, or null. */
109
+ export declare function referralTime(value: unknown): string | null;
110
+ /** One referral source's raw fields. */
111
+ export interface ReferralSourceFields {
77
112
  code: string | null;
78
113
  clickId: string | null;
79
114
  anonId: string | null;
80
- } | null;
115
+ /** ISO 8601, when the source says when it captured the referral. */
116
+ capturedAt?: string;
117
+ }
118
+ /**
119
+ * Parse a tracking-cookie value: JSON or URL-encoded JSON `{code?, clickId?,
120
+ * anonId?, ts?, exp?}` (snake_case accepted too); a plain value is a click id.
121
+ * `ts` (unix seconds or ms) becomes `capturedAt`; a cookie past its `exp` is
122
+ * ignored.
123
+ */
124
+ export declare function parseReferralCookie(value: string | null | undefined, now?: number): ReferralSourceFields | null;
81
125
  /** A cookie's value from a `document.cookie` string, or null. */
82
126
  export declare function readCookieValue(cookies: string | null | undefined, name: string): string | null;
83
127
  /**
84
- * Whether the referral cookie may be read. Cookie Munch on the page decides
85
- * when present (the instance's category, else its fallback category); else
86
- * the app's own `referralConsent`.
128
+ * Whether the referral cookie may be read, with only Cookie Munch to ask (the
129
+ * shape before consent managers were detected generally). Cookie Munch on the
130
+ * page decides when present (the instance's category, else its fallback
131
+ * category); else the app's own `referralConsent`. See {@link detectConsent}
132
+ * for every manager.
87
133
  */
88
134
  export declare function referralConsentGranted(config: Pick<ReferralConfig, 'consentCategory' | 'consentFallbackCategory'>, cookieMunch: unknown, appConsent: ReferralConsent | undefined): boolean;
89
135
  /** Everything {@link captureReferral} reads from the page. */
@@ -92,15 +138,31 @@ export interface ReferralPage {
92
138
  searches: readonly string[];
93
139
  /** `document.cookie`. */
94
140
  cookies?: string | null;
95
- /** `window.CookieMunch`, if any. */
141
+ /** `window`: its referral scripts and consent manager are read. */
142
+ win?: unknown;
143
+ /** `window.CookieMunch`, when no `win` is given (older callers). */
96
144
  cookieMunch?: unknown;
145
+ /** `window.aff`, when no `win` is given (older callers). */
146
+ aff?: unknown;
97
147
  /** Base for resolving a relative redirect_url. */
98
148
  base?: string;
99
149
  /** ISO time of capture. */
100
150
  capturedAt?: string;
101
151
  }
102
- /** Capture the referral for a request, or null when there is nothing to send. Pure. */
103
- export declare function captureReferral(config: ReferralConfig, page: ReferralPage, appConsent?: ReferralConsent): ReferralCapture | null;
152
+ /** What the page's referral script (`window.aff.getReferral()`) holds, or null. Never throws. */
153
+ export declare function referralFromScript(aff: unknown): ReferralSourceFields | null;
154
+ /** The explicit `ref_*` referral in a query string, or null. `consent` is whether ids may be kept. */
155
+ export declare function explicitReferralFromSearch(search: string | null | undefined): (ReferralSourceFields & {
156
+ consentGranted: boolean;
157
+ }) | null;
158
+ /**
159
+ * Capture the referral for a request, or null when there is nothing to send.
160
+ * Pure. One source wins, in the order described at the top of this module;
161
+ * fields are never mixed across sources. Ids need consent: the app's
162
+ * `referralConsent`, `ref_consent=granted` on an explicit URL, or the consent
163
+ * manager on the page.
164
+ */
165
+ export declare function captureReferral(config: ReferralConfig, page: ReferralPage, appConsent?: ReferralConsent, customSource?: ReferralSourceReader): ReferralCapture | null;
104
166
  /** Whether a FAPI POST path starts or continues a sign-in / sign-up (and so takes `referral`). */
105
167
  export declare function acceptsReferral(path: string): boolean;
106
168
  /**
@@ -147,3 +209,74 @@ export declare function currentReferral(client: ReferralClient): Promise<Referra
147
209
  * sign-ups (even with the captcha otherwise off).
148
210
  */
149
211
  export declare function referralChallengeRequired(client: ReferralClient): Promise<boolean>;
212
+ /** Options for {@link referralParams}, {@link withReferralParams}, {@link signIn} and {@link signUp}. */
213
+ export interface ReferralRedirectOptions {
214
+ /** `false`: add nothing. `'auto'` (default): capture as described above. */
215
+ referral?: false | 'auto';
216
+ /**
217
+ * The app's consent for referral tracking (click and anonymous ids). When
218
+ * omitted, the page-wide `referralConsent` applies, else the consent manager
219
+ * on the page (`referrals`, else `marketing`), else no consent (code only).
220
+ */
221
+ consent?: ReferralConsent;
222
+ /** Your own reader for a referral program the SDK doesn't know (see {@link ReferralCaptureOptions.referralSource}). */
223
+ source?: ReferralSourceReader;
224
+ /**
225
+ * The instance's config, when the app has it. Defaults: `ref` / `via` /
226
+ * `aff`, no tracking cookie, every known referral script and cookie, and
227
+ * any consent manager.
228
+ */
229
+ config?: ReferralConfig;
230
+ }
231
+ /**
232
+ * The referral this page would send, as `ref_*` query parameters (`[]` when
233
+ * there is none). Synchronous: it uses the instance config when one was
234
+ * loaded on this page (or passed), else the default URL parameters. Consent
235
+ * comes from `consent`, else Cookie Munch on the page.
236
+ */
237
+ export declare function referralParams(options?: ReferralRedirectOptions): Array<[string, string]>;
238
+ /** `url` with the page's referral added as `ref_*` parameters (existing ones are kept, never replaced). */
239
+ export declare function withReferralParams(url: string, options?: ReferralRedirectOptions): string;
240
+ /** Where {@link signIn} / {@link signUp} go. */
241
+ export interface HostedRedirectOptions extends ReferralRedirectOptions {
242
+ /**
243
+ * A full URL to go to: a hosted page, `/oauth2/authorize?...`, or your own
244
+ * login route. Wins over `frontendApi`.
245
+ */
246
+ url?: string;
247
+ /** The instance's Frontend API host or origin (e.g. `accounts.example.com`), for its hosted page. */
248
+ frontendApi?: string;
249
+ /** Where the hosted page sends the user afterwards (`redirect_url`). */
250
+ redirectUrl?: string;
251
+ /** `false`: return the URL without navigating. Default true. */
252
+ navigate?: boolean;
253
+ }
254
+ /**
255
+ * Send the visitor to the hosted sign-in page (or `url`), carrying the
256
+ * referral they arrived with as `ref_*` parameters (`referral: 'auto'`, the
257
+ * default). Returns the URL it went to.
258
+ *
259
+ * ```ts
260
+ * signIn({ frontendApi: 'accounts.example.com', redirectUrl: location.href, consent: () => cmp.granted('referrals') });
261
+ * ```
262
+ */
263
+ export declare function signIn(options: HostedRedirectOptions): string;
264
+ /** {@link signIn} for the hosted sign-up page. */
265
+ export declare function signUp(options: HostedRedirectOptions): string;
266
+ /** What a code lookup answers. */
267
+ export interface ReferralCodeLookup {
268
+ valid: boolean;
269
+ partnerDisplayName?: string;
270
+ /** Platform-defined; a string or an object with a `description`. */
271
+ refereeReward?: unknown;
272
+ }
273
+ /**
274
+ * Ask the instance's public code lookup (`code_lookup_url`) about a code, for
275
+ * an "X invited you" line. No credentials, `timeoutMs` (default 3000). Null
276
+ * when there is no lookup, the code is malformed, or the lookup fails: never
277
+ * block a sign-up on it.
278
+ */
279
+ export declare function lookupReferralCode(config: Pick<ReferralConfig, 'codeLookupUrl'> | string | null | undefined, code: string, options?: {
280
+ fetchImpl?: typeof fetch;
281
+ timeoutMs?: number;
282
+ }): Promise<ReferralCodeLookup | null>;