@xenia-martech/sdk-js 1.0.0-dev.25 → 1.0.0-dev.27
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.
- package/README.md +31 -45
- package/dist/{actions-DfuHrjUL.d.cts → actions-CkiSdvSa.d.cts} +73 -11
- package/dist/{actions-DfuHrjUL.d.ts → actions-CkiSdvSa.d.ts} +73 -11
- package/dist/{chunk-PTYUK4P3.js → chunk-7D2HJMW6.js} +33 -4
- package/dist/chunk-7D2HJMW6.js.map +1 -0
- package/dist/{chunk-JEFNAD5J.cjs → chunk-UOW3GK4I.cjs} +34 -3
- package/dist/chunk-UOW3GK4I.cjs.map +1 -0
- package/dist/client/index.cjs +75 -9
- package/dist/client/index.cjs.map +1 -1
- package/dist/client/index.d.cts +2 -2
- package/dist/client/index.d.ts +2 -2
- package/dist/client/index.js +75 -9
- package/dist/client/index.js.map +1 -1
- package/dist/client/react/index.cjs +75 -9
- package/dist/client/react/index.cjs.map +1 -1
- package/dist/client/react/index.d.cts +3 -3
- package/dist/client/react/index.d.ts +3 -3
- package/dist/client/react/index.js +75 -9
- package/dist/client/react/index.js.map +1 -1
- package/dist/{cookie-names-BQ-L04A8.d.cts → cookie-names-C3LKDhsg.d.cts} +42 -6
- package/dist/{cookie-names-BQ-L04A8.d.ts → cookie-names-C3LKDhsg.d.ts} +42 -6
- package/dist/index.cjs +23 -19
- package/dist/index.d.cts +25 -4
- package/dist/index.d.ts +25 -4
- package/dist/index.js +1 -1
- package/dist/server/index.cjs +53 -22
- package/dist/server/index.cjs.map +1 -1
- package/dist/server/index.d.cts +37 -14
- package/dist/server/index.d.ts +37 -14
- package/dist/server/index.js +43 -12
- package/dist/server/index.js.map +1 -1
- package/dist/xenia-sdk.iife.js +3 -3
- package/dist/xenia-sdk.iife.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-JEFNAD5J.cjs.map +0 -1
- package/dist/chunk-PTYUK4P3.js.map +0 -1
|
@@ -46,15 +46,16 @@ interface RetryConfig {
|
|
|
46
46
|
/**
|
|
47
47
|
* Root configuration shared by client and server runtimes.
|
|
48
48
|
*
|
|
49
|
-
* Developers supply the minimum:
|
|
50
|
-
*
|
|
49
|
+
* Developers supply the minimum: tenant scope. Everything else (identity,
|
|
50
|
+
* UTM, journey attribution, device id) is handled by the SDK.
|
|
51
51
|
*/
|
|
52
52
|
interface XeniaConfig {
|
|
53
53
|
/**
|
|
54
|
-
* Base URL of the Xenia backend
|
|
55
|
-
*
|
|
54
|
+
* Base URL of the Xenia backend. Defaults to the hosted engine,
|
|
55
|
+
* `https://engine.xeniamartech.com/xenia` — omit this unless you're
|
|
56
|
+
* pointing at a self-hosted or non-default environment.
|
|
56
57
|
*/
|
|
57
|
-
baseUrl
|
|
58
|
+
baseUrl?: string;
|
|
58
59
|
/** Tenant id — sent as `X-Tenant-Id` on header-scoped endpoints. */
|
|
59
60
|
tenantId: string;
|
|
60
61
|
/** Environment key — sent as `X-Environment` on header-scoped endpoints. */
|
|
@@ -85,6 +86,23 @@ interface XeniaConfig {
|
|
|
85
86
|
* cookie read via `getVisitorId()`.
|
|
86
87
|
*/
|
|
87
88
|
visitorId?: string;
|
|
89
|
+
/**
|
|
90
|
+
* The ambient request context for a **server** client — the SDK-provided page/campaign fields
|
|
91
|
+
* (`path`, `query`, `url`, `referrer`, `utmSource`/`utmMedium`/`utmCampaign`/`utmContent`/`utmId`)
|
|
92
|
+
* that get attached to EVERY `resolve()`/`resolveBatch()`/`webhook()` made with this client, so
|
|
93
|
+
* journey rules can gate on `query.<name>` or `path` without any per-call wiring.
|
|
94
|
+
*
|
|
95
|
+
* The browser client needs nothing here — it reads these off `window.location` itself. A server
|
|
96
|
+
* runtime has no ambient request, so bind it once when constructing the per-request client:
|
|
97
|
+
*
|
|
98
|
+
* ```ts
|
|
99
|
+
* createXeniaServer({ …, context: contextFromUrl(currentUrl, referrer) })
|
|
100
|
+
* ```
|
|
101
|
+
*
|
|
102
|
+
* Lowest precedence: a per-call `context`/`identity` overrides it, and the SDK-owned `visitorId`
|
|
103
|
+
* still wins over everything.
|
|
104
|
+
*/
|
|
105
|
+
context?: EventContext;
|
|
88
106
|
/**
|
|
89
107
|
* Persist the SDK visitor id to a first-party `xenia_vid` cookie so your
|
|
90
108
|
* **same-origin** server can read it (`getVisitorId(cookieHeader)`) and bind
|
|
@@ -303,6 +321,23 @@ interface ResolveOptions {
|
|
|
303
321
|
locale?: string;
|
|
304
322
|
/** When true, ask the server to splice and return `content`. */
|
|
305
323
|
merge?: boolean;
|
|
324
|
+
/**
|
|
325
|
+
* Caller-supplied identity fields (`deviceId`/`visitorId`/`customerId`/
|
|
326
|
+
* `email`), merged into `data` the same way `ServerWebhookOptions.identity`
|
|
327
|
+
* is merged for `webhook()`. Only relevant server-side — the browser client
|
|
328
|
+
* collects these ambiently instead and ignores this field. The SDK-owned
|
|
329
|
+
* `visitorId` (from `config.visitorId`) still wins over a value supplied
|
|
330
|
+
* here, same precedence as `webhook()`.
|
|
331
|
+
*/
|
|
332
|
+
identity?: EventIdentity;
|
|
333
|
+
/**
|
|
334
|
+
* Caller-supplied page context (`path`/`query`/`url`/`referrer`/`utm*`),
|
|
335
|
+
* merged into `data` the same way `ServerWebhookOptions.context` is merged
|
|
336
|
+
* for `webhook()`. There's no ambient `window`/`document` server-side, so a
|
|
337
|
+
* server caller who wants these SDK-provided fields on a resolve() call
|
|
338
|
+
* must pass them explicitly (e.g. from the current request's headers).
|
|
339
|
+
*/
|
|
340
|
+
context?: EventContext;
|
|
306
341
|
}
|
|
307
342
|
/** Body posted to `POST /api/events/v1/identify` — binds visitor to a known user. */
|
|
308
343
|
interface IdentifyRequest {
|
|
@@ -389,7 +424,8 @@ type XeniaAction = {
|
|
|
389
424
|
/**
|
|
390
425
|
* Low-level, isomorphic Xenia API client. Wraps the raw endpoints; identity,
|
|
391
426
|
* UTM capture, and action rendering are layered on top by the client runtime.
|
|
392
|
-
* All paths are relative to `baseUrl
|
|
427
|
+
* All paths are relative to `baseUrl`, which defaults to the hosted engine
|
|
428
|
+
* (`https://engine.xeniamartech.com/xenia`) when omitted from config.
|
|
393
429
|
*/
|
|
394
430
|
declare class XeniaApi {
|
|
395
431
|
private readonly http;
|
|
@@ -46,15 +46,16 @@ interface RetryConfig {
|
|
|
46
46
|
/**
|
|
47
47
|
* Root configuration shared by client and server runtimes.
|
|
48
48
|
*
|
|
49
|
-
* Developers supply the minimum:
|
|
50
|
-
*
|
|
49
|
+
* Developers supply the minimum: tenant scope. Everything else (identity,
|
|
50
|
+
* UTM, journey attribution, device id) is handled by the SDK.
|
|
51
51
|
*/
|
|
52
52
|
interface XeniaConfig {
|
|
53
53
|
/**
|
|
54
|
-
* Base URL of the Xenia backend
|
|
55
|
-
*
|
|
54
|
+
* Base URL of the Xenia backend. Defaults to the hosted engine,
|
|
55
|
+
* `https://engine.xeniamartech.com/xenia` — omit this unless you're
|
|
56
|
+
* pointing at a self-hosted or non-default environment.
|
|
56
57
|
*/
|
|
57
|
-
baseUrl
|
|
58
|
+
baseUrl?: string;
|
|
58
59
|
/** Tenant id — sent as `X-Tenant-Id` on header-scoped endpoints. */
|
|
59
60
|
tenantId: string;
|
|
60
61
|
/** Environment key — sent as `X-Environment` on header-scoped endpoints. */
|
|
@@ -85,6 +86,23 @@ interface XeniaConfig {
|
|
|
85
86
|
* cookie read via `getVisitorId()`.
|
|
86
87
|
*/
|
|
87
88
|
visitorId?: string;
|
|
89
|
+
/**
|
|
90
|
+
* The ambient request context for a **server** client — the SDK-provided page/campaign fields
|
|
91
|
+
* (`path`, `query`, `url`, `referrer`, `utmSource`/`utmMedium`/`utmCampaign`/`utmContent`/`utmId`)
|
|
92
|
+
* that get attached to EVERY `resolve()`/`resolveBatch()`/`webhook()` made with this client, so
|
|
93
|
+
* journey rules can gate on `query.<name>` or `path` without any per-call wiring.
|
|
94
|
+
*
|
|
95
|
+
* The browser client needs nothing here — it reads these off `window.location` itself. A server
|
|
96
|
+
* runtime has no ambient request, so bind it once when constructing the per-request client:
|
|
97
|
+
*
|
|
98
|
+
* ```ts
|
|
99
|
+
* createXeniaServer({ …, context: contextFromUrl(currentUrl, referrer) })
|
|
100
|
+
* ```
|
|
101
|
+
*
|
|
102
|
+
* Lowest precedence: a per-call `context`/`identity` overrides it, and the SDK-owned `visitorId`
|
|
103
|
+
* still wins over everything.
|
|
104
|
+
*/
|
|
105
|
+
context?: EventContext;
|
|
88
106
|
/**
|
|
89
107
|
* Persist the SDK visitor id to a first-party `xenia_vid` cookie so your
|
|
90
108
|
* **same-origin** server can read it (`getVisitorId(cookieHeader)`) and bind
|
|
@@ -303,6 +321,23 @@ interface ResolveOptions {
|
|
|
303
321
|
locale?: string;
|
|
304
322
|
/** When true, ask the server to splice and return `content`. */
|
|
305
323
|
merge?: boolean;
|
|
324
|
+
/**
|
|
325
|
+
* Caller-supplied identity fields (`deviceId`/`visitorId`/`customerId`/
|
|
326
|
+
* `email`), merged into `data` the same way `ServerWebhookOptions.identity`
|
|
327
|
+
* is merged for `webhook()`. Only relevant server-side — the browser client
|
|
328
|
+
* collects these ambiently instead and ignores this field. The SDK-owned
|
|
329
|
+
* `visitorId` (from `config.visitorId`) still wins over a value supplied
|
|
330
|
+
* here, same precedence as `webhook()`.
|
|
331
|
+
*/
|
|
332
|
+
identity?: EventIdentity;
|
|
333
|
+
/**
|
|
334
|
+
* Caller-supplied page context (`path`/`query`/`url`/`referrer`/`utm*`),
|
|
335
|
+
* merged into `data` the same way `ServerWebhookOptions.context` is merged
|
|
336
|
+
* for `webhook()`. There's no ambient `window`/`document` server-side, so a
|
|
337
|
+
* server caller who wants these SDK-provided fields on a resolve() call
|
|
338
|
+
* must pass them explicitly (e.g. from the current request's headers).
|
|
339
|
+
*/
|
|
340
|
+
context?: EventContext;
|
|
306
341
|
}
|
|
307
342
|
/** Body posted to `POST /api/events/v1/identify` — binds visitor to a known user. */
|
|
308
343
|
interface IdentifyRequest {
|
|
@@ -389,7 +424,8 @@ type XeniaAction = {
|
|
|
389
424
|
/**
|
|
390
425
|
* Low-level, isomorphic Xenia API client. Wraps the raw endpoints; identity,
|
|
391
426
|
* UTM capture, and action rendering are layered on top by the client runtime.
|
|
392
|
-
* All paths are relative to `baseUrl
|
|
427
|
+
* All paths are relative to `baseUrl`, which defaults to the hosted engine
|
|
428
|
+
* (`https://engine.xeniamartech.com/xenia`) when omitted from config.
|
|
393
429
|
*/
|
|
394
430
|
declare class XeniaApi {
|
|
395
431
|
private readonly http;
|
package/dist/index.cjs
CHANGED
|
@@ -1,80 +1,84 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkUOW3GK4I_cjs = require('./chunk-UOW3GK4I.cjs');
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
Object.defineProperty(exports, "CONSENT_COOKIE", {
|
|
8
8
|
enumerable: true,
|
|
9
|
-
get: function () { return
|
|
9
|
+
get: function () { return chunkUOW3GK4I_cjs.CONSENT_COOKIE; }
|
|
10
10
|
});
|
|
11
11
|
Object.defineProperty(exports, "DEFAULT_PREFIX", {
|
|
12
12
|
enumerable: true,
|
|
13
|
-
get: function () { return
|
|
13
|
+
get: function () { return chunkUOW3GK4I_cjs.DEFAULT_PREFIX; }
|
|
14
14
|
});
|
|
15
15
|
Object.defineProperty(exports, "HttpClient", {
|
|
16
16
|
enumerable: true,
|
|
17
|
-
get: function () { return
|
|
17
|
+
get: function () { return chunkUOW3GK4I_cjs.HttpClient; }
|
|
18
18
|
});
|
|
19
19
|
Object.defineProperty(exports, "HttpError", {
|
|
20
20
|
enumerable: true,
|
|
21
|
-
get: function () { return
|
|
21
|
+
get: function () { return chunkUOW3GK4I_cjs.HttpError; }
|
|
22
22
|
});
|
|
23
23
|
Object.defineProperty(exports, "LocalStorageResponseStore", {
|
|
24
24
|
enumerable: true,
|
|
25
|
-
get: function () { return
|
|
25
|
+
get: function () { return chunkUOW3GK4I_cjs.LocalStorageResponseStore; }
|
|
26
26
|
});
|
|
27
27
|
Object.defineProperty(exports, "MAX_EVENT_ID_LENGTH", {
|
|
28
28
|
enumerable: true,
|
|
29
|
-
get: function () { return
|
|
29
|
+
get: function () { return chunkUOW3GK4I_cjs.MAX_EVENT_ID_LENGTH; }
|
|
30
30
|
});
|
|
31
31
|
Object.defineProperty(exports, "MemoryResponseStore", {
|
|
32
32
|
enumerable: true,
|
|
33
|
-
get: function () { return
|
|
33
|
+
get: function () { return chunkUOW3GK4I_cjs.MemoryResponseStore; }
|
|
34
34
|
});
|
|
35
35
|
Object.defineProperty(exports, "VISITOR_COOKIE", {
|
|
36
36
|
enumerable: true,
|
|
37
|
-
get: function () { return
|
|
37
|
+
get: function () { return chunkUOW3GK4I_cjs.VISITOR_COOKIE; }
|
|
38
38
|
});
|
|
39
39
|
Object.defineProperty(exports, "XeniaApi", {
|
|
40
40
|
enumerable: true,
|
|
41
|
-
get: function () { return
|
|
41
|
+
get: function () { return chunkUOW3GK4I_cjs.XeniaApi; }
|
|
42
42
|
});
|
|
43
43
|
Object.defineProperty(exports, "buildUrl", {
|
|
44
44
|
enumerable: true,
|
|
45
|
-
get: function () { return
|
|
45
|
+
get: function () { return chunkUOW3GK4I_cjs.buildUrl; }
|
|
46
46
|
});
|
|
47
47
|
Object.defineProperty(exports, "consentCookieName", {
|
|
48
48
|
enumerable: true,
|
|
49
|
-
get: function () { return
|
|
49
|
+
get: function () { return chunkUOW3GK4I_cjs.consentCookieName; }
|
|
50
|
+
});
|
|
51
|
+
Object.defineProperty(exports, "contextFromUrl", {
|
|
52
|
+
enumerable: true,
|
|
53
|
+
get: function () { return chunkUOW3GK4I_cjs.contextFromUrl; }
|
|
50
54
|
});
|
|
51
55
|
Object.defineProperty(exports, "extractContentSwaps", {
|
|
52
56
|
enumerable: true,
|
|
53
|
-
get: function () { return
|
|
57
|
+
get: function () { return chunkUOW3GK4I_cjs.extractContentSwaps; }
|
|
54
58
|
});
|
|
55
59
|
Object.defineProperty(exports, "generateUlid", {
|
|
56
60
|
enumerable: true,
|
|
57
|
-
get: function () { return
|
|
61
|
+
get: function () { return chunkUOW3GK4I_cjs.generateUlid; }
|
|
58
62
|
});
|
|
59
63
|
Object.defineProperty(exports, "isBrowser", {
|
|
60
64
|
enumerable: true,
|
|
61
|
-
get: function () { return
|
|
65
|
+
get: function () { return chunkUOW3GK4I_cjs.isBrowser; }
|
|
62
66
|
});
|
|
63
67
|
Object.defineProperty(exports, "parseActions", {
|
|
64
68
|
enumerable: true,
|
|
65
|
-
get: function () { return
|
|
69
|
+
get: function () { return chunkUOW3GK4I_cjs.parseActions; }
|
|
66
70
|
});
|
|
67
71
|
Object.defineProperty(exports, "spliceSlots", {
|
|
68
72
|
enumerable: true,
|
|
69
|
-
get: function () { return
|
|
73
|
+
get: function () { return chunkUOW3GK4I_cjs.spliceSlots; }
|
|
70
74
|
});
|
|
71
75
|
Object.defineProperty(exports, "toEventId", {
|
|
72
76
|
enumerable: true,
|
|
73
|
-
get: function () { return
|
|
77
|
+
get: function () { return chunkUOW3GK4I_cjs.toEventId; }
|
|
74
78
|
});
|
|
75
79
|
Object.defineProperty(exports, "visitorCookieName", {
|
|
76
80
|
enumerable: true,
|
|
77
|
-
get: function () { return
|
|
81
|
+
get: function () { return chunkUOW3GK4I_cjs.visitorCookieName; }
|
|
78
82
|
});
|
|
79
83
|
//# sourceMappingURL=index.cjs.map
|
|
80
84
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { R as RetryConfig, H as HttpMethod, J as JsonValue, W as WebhookResponse } from './cookie-names-
|
|
2
|
-
export { A as AnalyticsContext, a as AnalyticsEventName, b as AnalyticsIdentity, c as AnalyticsIngestResponse, C as CONSENT_COOKIE, d as ConsentState, D as DEFAULT_PREFIX,
|
|
1
|
+
import { R as RetryConfig, H as HttpMethod, J as JsonValue, E as EventContext, W as WebhookResponse } from './cookie-names-C3LKDhsg.cjs';
|
|
2
|
+
export { A as AnalyticsContext, a as AnalyticsEventName, b as AnalyticsIdentity, c as AnalyticsIngestResponse, C as CONSENT_COOKIE, d as ConsentState, D as DEFAULT_PREFIX, e as EventIdentity, I as IdentifyRequest, f as IdentifyResponse, g as InteractionType, h as JsonObject, M as MessageCta, i as MessagePlacement, P as PersonalizationSwap, j as ResolveBatchItem, k as ResolveBatchResult, l as ResolveOptions, m as ResolveResult, T as TrackOptions, V as VISITOR_COOKIE, X as XeniaAction, n as XeniaApi, o as XeniaConfig, p as XeniaEvent, q as consentCookieName, r as parseActions, v as visitorCookieName } from './cookie-names-C3LKDhsg.cjs';
|
|
3
3
|
|
|
4
4
|
/** Returns true when running in a browser environment (SSR-safe). */
|
|
5
5
|
declare function isBrowser(): boolean;
|
|
@@ -38,7 +38,8 @@ declare class HttpError extends Error {
|
|
|
38
38
|
constructor(status: number, data: JsonValue, message?: string);
|
|
39
39
|
}
|
|
40
40
|
interface HttpClientOptions {
|
|
41
|
-
|
|
41
|
+
/** Defaults to {@link DEFAULT_BASE_URL} when omitted. */
|
|
42
|
+
baseUrl?: string;
|
|
42
43
|
defaultHeaders?: Record<string, string>;
|
|
43
44
|
timeout?: number;
|
|
44
45
|
retry?: RetryConfig;
|
|
@@ -120,6 +121,26 @@ declare function spliceSlots(slots: Record<string, JsonValue>, swaps: ContentSwa
|
|
|
120
121
|
/** Extract `xeniaContentSwaps` from a webhook-response body, if present and well-formed. */
|
|
121
122
|
declare function extractContentSwaps(body: JsonValue): ContentSwap[] | undefined;
|
|
122
123
|
|
|
124
|
+
/**
|
|
125
|
+
* Derive the SDK-provided page/campaign fields from a URL — the server-side counterpart to the
|
|
126
|
+
* browser client's `Identity.collectContext()`, which reads the same fields off `window.location`.
|
|
127
|
+
*
|
|
128
|
+
* Exists because a server runtime has no ambient `window`: a Node client is constructed per request,
|
|
129
|
+
* so the one thing it needs handed over is the URL being served. Everything a journey rule can
|
|
130
|
+
* reference — `path`, `query.<name>`, `url`, `referrer`, `utmSource`/`utmMedium`/`utmCampaign`/
|
|
131
|
+
* `utmContent`/`utmId` — is derived here rather than by each app, so a server-rendered page gets the
|
|
132
|
+
* same field set a browser page does without hand-rolling UTM parsing at every call site.
|
|
133
|
+
*
|
|
134
|
+
* Field names and semantics deliberately mirror `collectContext()` exactly: `query` is the flattened
|
|
135
|
+
* search params, UTMs come from the standard `utm_*` params, and absent values are omitted rather
|
|
136
|
+
* than set to `""` (a blank string is a value a condition could accidentally match).
|
|
137
|
+
*
|
|
138
|
+
* @param url Absolute URL of the request being served (e.g. `https://shop.example/product/x?ref=a`).
|
|
139
|
+
* A relative or unparseable value yields an empty context rather than throwing.
|
|
140
|
+
* @param referrer Optional referring URL, typically the request's `Referer` header.
|
|
141
|
+
*/
|
|
142
|
+
declare function contextFromUrl(url: string | null | undefined, referrer?: string | null): EventContext;
|
|
143
|
+
|
|
123
144
|
/**
|
|
124
145
|
* Persists webhook responses the SDK receives, keyed by an arbitrary string
|
|
125
146
|
* (typically the eventId, triggerId, or journeyId). Lets the app read back the
|
|
@@ -154,4 +175,4 @@ declare class LocalStorageResponseStore implements ResponseStore {
|
|
|
154
175
|
clear(): void;
|
|
155
176
|
}
|
|
156
177
|
|
|
157
|
-
export { type ContentSwap, HttpClient, type HttpClientOptions, HttpError, HttpMethod, type HttpResult, JsonValue, LocalStorageResponseStore, MAX_EVENT_ID_LENGTH, MemoryResponseStore, type RequestOptions, type ResponseStore, RetryConfig, WebhookResponse, buildUrl, extractContentSwaps, generateUlid, isBrowser, spliceSlots, toEventId };
|
|
178
|
+
export { type ContentSwap, EventContext, HttpClient, type HttpClientOptions, HttpError, HttpMethod, type HttpResult, JsonValue, LocalStorageResponseStore, MAX_EVENT_ID_LENGTH, MemoryResponseStore, type RequestOptions, type ResponseStore, RetryConfig, WebhookResponse, buildUrl, contextFromUrl, extractContentSwaps, generateUlid, isBrowser, spliceSlots, toEventId };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { R as RetryConfig, H as HttpMethod, J as JsonValue, W as WebhookResponse } from './cookie-names-
|
|
2
|
-
export { A as AnalyticsContext, a as AnalyticsEventName, b as AnalyticsIdentity, c as AnalyticsIngestResponse, C as CONSENT_COOKIE, d as ConsentState, D as DEFAULT_PREFIX,
|
|
1
|
+
import { R as RetryConfig, H as HttpMethod, J as JsonValue, E as EventContext, W as WebhookResponse } from './cookie-names-C3LKDhsg.js';
|
|
2
|
+
export { A as AnalyticsContext, a as AnalyticsEventName, b as AnalyticsIdentity, c as AnalyticsIngestResponse, C as CONSENT_COOKIE, d as ConsentState, D as DEFAULT_PREFIX, e as EventIdentity, I as IdentifyRequest, f as IdentifyResponse, g as InteractionType, h as JsonObject, M as MessageCta, i as MessagePlacement, P as PersonalizationSwap, j as ResolveBatchItem, k as ResolveBatchResult, l as ResolveOptions, m as ResolveResult, T as TrackOptions, V as VISITOR_COOKIE, X as XeniaAction, n as XeniaApi, o as XeniaConfig, p as XeniaEvent, q as consentCookieName, r as parseActions, v as visitorCookieName } from './cookie-names-C3LKDhsg.js';
|
|
3
3
|
|
|
4
4
|
/** Returns true when running in a browser environment (SSR-safe). */
|
|
5
5
|
declare function isBrowser(): boolean;
|
|
@@ -38,7 +38,8 @@ declare class HttpError extends Error {
|
|
|
38
38
|
constructor(status: number, data: JsonValue, message?: string);
|
|
39
39
|
}
|
|
40
40
|
interface HttpClientOptions {
|
|
41
|
-
|
|
41
|
+
/** Defaults to {@link DEFAULT_BASE_URL} when omitted. */
|
|
42
|
+
baseUrl?: string;
|
|
42
43
|
defaultHeaders?: Record<string, string>;
|
|
43
44
|
timeout?: number;
|
|
44
45
|
retry?: RetryConfig;
|
|
@@ -120,6 +121,26 @@ declare function spliceSlots(slots: Record<string, JsonValue>, swaps: ContentSwa
|
|
|
120
121
|
/** Extract `xeniaContentSwaps` from a webhook-response body, if present and well-formed. */
|
|
121
122
|
declare function extractContentSwaps(body: JsonValue): ContentSwap[] | undefined;
|
|
122
123
|
|
|
124
|
+
/**
|
|
125
|
+
* Derive the SDK-provided page/campaign fields from a URL — the server-side counterpart to the
|
|
126
|
+
* browser client's `Identity.collectContext()`, which reads the same fields off `window.location`.
|
|
127
|
+
*
|
|
128
|
+
* Exists because a server runtime has no ambient `window`: a Node client is constructed per request,
|
|
129
|
+
* so the one thing it needs handed over is the URL being served. Everything a journey rule can
|
|
130
|
+
* reference — `path`, `query.<name>`, `url`, `referrer`, `utmSource`/`utmMedium`/`utmCampaign`/
|
|
131
|
+
* `utmContent`/`utmId` — is derived here rather than by each app, so a server-rendered page gets the
|
|
132
|
+
* same field set a browser page does without hand-rolling UTM parsing at every call site.
|
|
133
|
+
*
|
|
134
|
+
* Field names and semantics deliberately mirror `collectContext()` exactly: `query` is the flattened
|
|
135
|
+
* search params, UTMs come from the standard `utm_*` params, and absent values are omitted rather
|
|
136
|
+
* than set to `""` (a blank string is a value a condition could accidentally match).
|
|
137
|
+
*
|
|
138
|
+
* @param url Absolute URL of the request being served (e.g. `https://shop.example/product/x?ref=a`).
|
|
139
|
+
* A relative or unparseable value yields an empty context rather than throwing.
|
|
140
|
+
* @param referrer Optional referring URL, typically the request's `Referer` header.
|
|
141
|
+
*/
|
|
142
|
+
declare function contextFromUrl(url: string | null | undefined, referrer?: string | null): EventContext;
|
|
143
|
+
|
|
123
144
|
/**
|
|
124
145
|
* Persists webhook responses the SDK receives, keyed by an arbitrary string
|
|
125
146
|
* (typically the eventId, triggerId, or journeyId). Lets the app read back the
|
|
@@ -154,4 +175,4 @@ declare class LocalStorageResponseStore implements ResponseStore {
|
|
|
154
175
|
clear(): void;
|
|
155
176
|
}
|
|
156
177
|
|
|
157
|
-
export { type ContentSwap, HttpClient, type HttpClientOptions, HttpError, HttpMethod, type HttpResult, JsonValue, LocalStorageResponseStore, MAX_EVENT_ID_LENGTH, MemoryResponseStore, type RequestOptions, type ResponseStore, RetryConfig, WebhookResponse, buildUrl, extractContentSwaps, generateUlid, isBrowser, spliceSlots, toEventId };
|
|
178
|
+
export { type ContentSwap, EventContext, HttpClient, type HttpClientOptions, HttpError, HttpMethod, type HttpResult, JsonValue, LocalStorageResponseStore, MAX_EVENT_ID_LENGTH, MemoryResponseStore, type RequestOptions, type ResponseStore, RetryConfig, WebhookResponse, buildUrl, contextFromUrl, extractContentSwaps, generateUlid, isBrowser, spliceSlots, toEventId };
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { CONSENT_COOKIE, DEFAULT_PREFIX, HttpClient, HttpError, LocalStorageResponseStore, MAX_EVENT_ID_LENGTH, MemoryResponseStore, VISITOR_COOKIE, XeniaApi, buildUrl, consentCookieName, extractContentSwaps, generateUlid, isBrowser, parseActions, spliceSlots, toEventId, visitorCookieName } from './chunk-
|
|
1
|
+
export { CONSENT_COOKIE, DEFAULT_PREFIX, HttpClient, HttpError, LocalStorageResponseStore, MAX_EVENT_ID_LENGTH, MemoryResponseStore, VISITOR_COOKIE, XeniaApi, buildUrl, consentCookieName, contextFromUrl, extractContentSwaps, generateUlid, isBrowser, parseActions, spliceSlots, toEventId, visitorCookieName } from './chunk-7D2HJMW6.js';
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
|
3
3
|
//# sourceMappingURL=index.js.map
|
package/dist/server/index.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkUOW3GK4I_cjs = require('../chunk-UOW3GK4I.cjs');
|
|
4
4
|
|
|
5
5
|
// src/core/event-payload.ts
|
|
6
6
|
var RESERVED = /* @__PURE__ */ new Set([
|
|
@@ -21,7 +21,7 @@ var RESERVED = /* @__PURE__ */ new Set([
|
|
|
21
21
|
"path",
|
|
22
22
|
"query"
|
|
23
23
|
]);
|
|
24
|
-
function
|
|
24
|
+
function compact2(obj) {
|
|
25
25
|
const out = {};
|
|
26
26
|
for (const [k, v] of Object.entries(obj)) {
|
|
27
27
|
if (v !== void 0) out[k] = v;
|
|
@@ -45,8 +45,8 @@ function buildEventPayload(input) {
|
|
|
45
45
|
// what they reliably know (real page url, visitor/device id), so a stray prop
|
|
46
46
|
// can't override the true page context — see merge order below.
|
|
47
47
|
...reserved,
|
|
48
|
-
...
|
|
49
|
-
...
|
|
48
|
+
...compact2(input.context ?? {}),
|
|
49
|
+
...compact2(input.identity ?? {}),
|
|
50
50
|
eventId: input.eventId,
|
|
51
51
|
...input.eventType ? { eventType: input.eventType } : {},
|
|
52
52
|
...input.journeyId ? { journeyId: input.journeyId } : {}
|
|
@@ -59,9 +59,12 @@ var XeniaServer = class {
|
|
|
59
59
|
api;
|
|
60
60
|
/** SDK-owned visitor anchor for this (per-request) client — see {@link XeniaConfig.visitorId}. */
|
|
61
61
|
visitorId;
|
|
62
|
+
/** Ambient request context attached to every call — see {@link XeniaConfig.context}. */
|
|
63
|
+
context;
|
|
62
64
|
constructor(config) {
|
|
63
|
-
this.api = new
|
|
65
|
+
this.api = new chunkUOW3GK4I_cjs.XeniaApi(config);
|
|
64
66
|
this.visitorId = config.visitorId;
|
|
67
|
+
this.context = config.context;
|
|
65
68
|
}
|
|
66
69
|
/**
|
|
67
70
|
* Send a unified event server-side (`POST /api/events/v1`) and return the
|
|
@@ -72,7 +75,7 @@ var XeniaServer = class {
|
|
|
72
75
|
async track(eventName, opts = {}) {
|
|
73
76
|
const event = {
|
|
74
77
|
eventName,
|
|
75
|
-
eventId: opts.eventId ?
|
|
78
|
+
eventId: opts.eventId ? chunkUOW3GK4I_cjs.toEventId(opts.eventId) : chunkUOW3GK4I_cjs.generateUlid(),
|
|
76
79
|
eventVersion: opts.eventVersion ?? 1,
|
|
77
80
|
occurredAtMs: opts.occurredAtMs ?? Date.now(),
|
|
78
81
|
source: opts.source ?? "xenia-server-sdk",
|
|
@@ -103,7 +106,9 @@ var XeniaServer = class {
|
|
|
103
106
|
// cookie per request) is attached automatically. Falls back to a
|
|
104
107
|
// per-call visitorId only when none is bound.
|
|
105
108
|
identity: { ...opts.identity, visitorId: this.visitorId ?? opts.identity?.visitorId },
|
|
106
|
-
context
|
|
109
|
+
// Ambient request context (config.context, bound once per request) under a per-call
|
|
110
|
+
// override — same precedence resolve() uses, so both surfaces carry the same fields.
|
|
111
|
+
context: { ...this.context, ...opts.context },
|
|
107
112
|
props: data
|
|
108
113
|
});
|
|
109
114
|
return this.api.webhook(triggerId, payload, opts.method ?? "POST");
|
|
@@ -117,6 +122,13 @@ var XeniaServer = class {
|
|
|
117
122
|
* (`POST /api/personalization/resolve`). Requires a configured SDK token
|
|
118
123
|
* (`token`/`getToken`) — resolve is auth-required. With `merge: true` the
|
|
119
124
|
* returned `content` is server-spliced.
|
|
125
|
+
*
|
|
126
|
+
* Pass `opts.identity`/`opts.context` to attach the same SDK-provided
|
|
127
|
+
* fields (`deviceId`, `customerId`, `email`, `path`, `url`, `referrer`,
|
|
128
|
+
* `utm*`, …) the browser client collects ambiently — there's no ambient
|
|
129
|
+
* `window`/`document` server-side, so a server caller must supply whatever
|
|
130
|
+
* it knows (e.g. from the current request) explicitly. See
|
|
131
|
+
* {@link ResolveOptions}.
|
|
120
132
|
*/
|
|
121
133
|
async resolve(contentKey, opts) {
|
|
122
134
|
return this.api.resolve(contentKey, this.withVisitor(opts));
|
|
@@ -126,14 +138,33 @@ var XeniaServer = class {
|
|
|
126
138
|
return this.api.resolveBatch(items, this.withVisitor(opts));
|
|
127
139
|
}
|
|
128
140
|
/**
|
|
129
|
-
*
|
|
130
|
-
*
|
|
131
|
-
*
|
|
132
|
-
*
|
|
141
|
+
* Merge the ambient `config.context` and `opts.identity`/`opts.context` into
|
|
142
|
+
* the resolve `data`, then stamp the SDK-owned visitor id
|
|
143
|
+
* (`config.visitorId`) under both the reserved `_xenia_vid` key (read by the
|
|
144
|
+
* backend for holdout/exposure bucketing) and the flat `visitorId` field —
|
|
145
|
+
* mirrors `webhook()`'s merge order/precedence exactly: caller `data` <
|
|
146
|
+
* ambient `config.context` < caller `context`/`identity` < SDK-owned
|
|
147
|
+
* `visitorId`/`_xenia_vid`, set LAST so neither can be overridden per call.
|
|
148
|
+
*
|
|
149
|
+
* `config.context` is what makes the SDK-provided fields automatic on the
|
|
150
|
+
* server: bound once per request, every `resolve()` carries `path`/`query`/
|
|
151
|
+
* `url`/`referrer`/UTMs with no per-call wiring, matching what the browser
|
|
152
|
+
* client collects from `window` on its own. A no-op when nothing is bound and
|
|
153
|
+
* nothing was passed — preserving today's behavior for callers using neither.
|
|
133
154
|
*/
|
|
134
155
|
withVisitor(opts) {
|
|
135
|
-
|
|
136
|
-
|
|
156
|
+
const identity = chunkUOW3GK4I_cjs.compact({
|
|
157
|
+
...opts?.identity,
|
|
158
|
+
visitorId: this.visitorId ?? opts?.identity?.visitorId
|
|
159
|
+
});
|
|
160
|
+
const merged = {
|
|
161
|
+
...chunkUOW3GK4I_cjs.compact(this.context ?? {}),
|
|
162
|
+
...chunkUOW3GK4I_cjs.compact(opts?.context ?? {}),
|
|
163
|
+
...identity
|
|
164
|
+
};
|
|
165
|
+
if (Object.keys(merged).length === 0 && !this.visitorId) return opts;
|
|
166
|
+
if (this.visitorId) merged._xenia_vid = this.visitorId;
|
|
167
|
+
return { ...opts, data: { ...opts?.data ?? {}, ...merged } };
|
|
137
168
|
}
|
|
138
169
|
};
|
|
139
170
|
function createXeniaServer(config) {
|
|
@@ -142,7 +173,7 @@ function createXeniaServer(config) {
|
|
|
142
173
|
|
|
143
174
|
// src/server/token.ts
|
|
144
175
|
async function refreshSdkToken(opts) {
|
|
145
|
-
const http = new
|
|
176
|
+
const http = new chunkUOW3GK4I_cjs.HttpClient({ baseUrl: opts.baseUrl, timeout: opts.timeout });
|
|
146
177
|
const { data } = await http.request({
|
|
147
178
|
method: "POST",
|
|
148
179
|
path: "/api/personalization/token/refresh",
|
|
@@ -187,10 +218,10 @@ function parseCookies(header) {
|
|
|
187
218
|
return out;
|
|
188
219
|
}
|
|
189
220
|
function getVisitorId(cookieHeader, prefix) {
|
|
190
|
-
return parseCookies(cookieHeader)[
|
|
221
|
+
return parseCookies(cookieHeader)[chunkUOW3GK4I_cjs.visitorCookieName(prefix)] ?? null;
|
|
191
222
|
}
|
|
192
223
|
function getConsent(cookieHeader, prefix) {
|
|
193
|
-
const raw = parseCookies(cookieHeader)[
|
|
224
|
+
const raw = parseCookies(cookieHeader)[chunkUOW3GK4I_cjs.consentCookieName(prefix)];
|
|
194
225
|
if (!raw) return { analytics: false, marketing: false, personalization: false };
|
|
195
226
|
try {
|
|
196
227
|
const parsed = JSON.parse(raw);
|
|
@@ -207,27 +238,27 @@ function getConsent(cookieHeader, prefix) {
|
|
|
207
238
|
|
|
208
239
|
Object.defineProperty(exports, "CONSENT_COOKIE", {
|
|
209
240
|
enumerable: true,
|
|
210
|
-
get: function () { return
|
|
241
|
+
get: function () { return chunkUOW3GK4I_cjs.CONSENT_COOKIE; }
|
|
211
242
|
});
|
|
212
243
|
Object.defineProperty(exports, "VISITOR_COOKIE", {
|
|
213
244
|
enumerable: true,
|
|
214
|
-
get: function () { return
|
|
245
|
+
get: function () { return chunkUOW3GK4I_cjs.VISITOR_COOKIE; }
|
|
215
246
|
});
|
|
216
247
|
Object.defineProperty(exports, "XeniaApi", {
|
|
217
248
|
enumerable: true,
|
|
218
|
-
get: function () { return
|
|
249
|
+
get: function () { return chunkUOW3GK4I_cjs.XeniaApi; }
|
|
219
250
|
});
|
|
220
251
|
Object.defineProperty(exports, "consentCookieName", {
|
|
221
252
|
enumerable: true,
|
|
222
|
-
get: function () { return
|
|
253
|
+
get: function () { return chunkUOW3GK4I_cjs.consentCookieName; }
|
|
223
254
|
});
|
|
224
255
|
Object.defineProperty(exports, "parseActions", {
|
|
225
256
|
enumerable: true,
|
|
226
|
-
get: function () { return
|
|
257
|
+
get: function () { return chunkUOW3GK4I_cjs.parseActions; }
|
|
227
258
|
});
|
|
228
259
|
Object.defineProperty(exports, "visitorCookieName", {
|
|
229
260
|
enumerable: true,
|
|
230
|
-
get: function () { return
|
|
261
|
+
get: function () { return chunkUOW3GK4I_cjs.visitorCookieName; }
|
|
231
262
|
});
|
|
232
263
|
exports.XeniaServer = XeniaServer;
|
|
233
264
|
exports.createTokenRoute = createTokenRoute;
|