@proveanything/smartlinks 1.8.0 → 1.8.2
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/dist/api/ai.js +3 -99
- package/dist/api/analytics.d.ts +3 -3
- package/dist/api/analytics.js +48 -11
- package/dist/docs/API_SUMMARY.md +50 -8
- package/dist/docs/analytics-metadata-conventions.md +18 -14
- package/dist/docs/analytics.md +14 -17
- package/dist/docs/iframe-streaming-parent-changes.md +308 -0
- package/dist/http.d.ts +9 -0
- package/dist/http.js +236 -0
- package/dist/iframeResponder.d.ts +4 -0
- package/dist/iframeResponder.js +152 -0
- package/dist/openapi.yaml +68 -5
- package/dist/types/analytics.d.ts +10 -9
- package/dist/types/iframeResponder.d.ts +20 -0
- package/docs/API_SUMMARY.md +50 -8
- package/docs/analytics-metadata-conventions.md +18 -14
- package/docs/analytics.md +14 -17
- package/docs/iframe-streaming-parent-changes.md +308 -0
- package/openapi.yaml +68 -5
- package/package.json +1 -1
package/dist/iframeResponder.js
CHANGED
|
@@ -35,6 +35,7 @@ export class IframeResponder {
|
|
|
35
35
|
constructor(options) {
|
|
36
36
|
this.iframe = null;
|
|
37
37
|
this.uploads = new Map();
|
|
38
|
+
this.activeStreams = new Map();
|
|
38
39
|
this.isInitialLoad = true;
|
|
39
40
|
this.messageHandler = null;
|
|
40
41
|
this.resizeHandler = null;
|
|
@@ -97,6 +98,8 @@ export class IframeResponder {
|
|
|
97
98
|
this.resizeHandler = null;
|
|
98
99
|
}
|
|
99
100
|
this.uploads.clear();
|
|
101
|
+
this.activeStreams.forEach(controller => controller.abort());
|
|
102
|
+
this.activeStreams.clear();
|
|
100
103
|
this.iframe = null;
|
|
101
104
|
}
|
|
102
105
|
// ===========================================================================
|
|
@@ -263,6 +266,16 @@ export class IframeResponder {
|
|
|
263
266
|
await this.handleUpload(data, event);
|
|
264
267
|
return;
|
|
265
268
|
}
|
|
269
|
+
// Stream proxy aborts
|
|
270
|
+
if (data._smartlinksProxyStreamAbort) {
|
|
271
|
+
this.handleProxyStreamAbort(data);
|
|
272
|
+
return;
|
|
273
|
+
}
|
|
274
|
+
// Stream proxy requests
|
|
275
|
+
if (data._smartlinksProxyStreamRequest) {
|
|
276
|
+
await this.handleProxyStreamRequest(data, event);
|
|
277
|
+
return;
|
|
278
|
+
}
|
|
266
279
|
// API proxy requests
|
|
267
280
|
if (data._smartlinksProxyRequest || data._smartlinksCustomProxyRequest) {
|
|
268
281
|
await this.handleProxyRequest(data, event);
|
|
@@ -426,6 +439,145 @@ export class IframeResponder {
|
|
|
426
439
|
}
|
|
427
440
|
this.sendResponse(event, response);
|
|
428
441
|
}
|
|
442
|
+
handleProxyStreamAbort(data) {
|
|
443
|
+
const controller = this.activeStreams.get(data.id);
|
|
444
|
+
if (!controller) {
|
|
445
|
+
return;
|
|
446
|
+
}
|
|
447
|
+
controller.abort();
|
|
448
|
+
this.activeStreams.delete(data.id);
|
|
449
|
+
}
|
|
450
|
+
async handleProxyStreamRequest(data, event) {
|
|
451
|
+
var _a, _b, _c;
|
|
452
|
+
const controller = new AbortController();
|
|
453
|
+
this.activeStreams.set(data.id, controller);
|
|
454
|
+
try {
|
|
455
|
+
const path = data.path.startsWith('/') ? data.path.slice(1) : data.path;
|
|
456
|
+
const baseUrl = getBaseURL();
|
|
457
|
+
if (!baseUrl) {
|
|
458
|
+
throw new Error('SDK not initialized - call initializeApi() first');
|
|
459
|
+
}
|
|
460
|
+
const fetchOptions = {
|
|
461
|
+
method: data.method,
|
|
462
|
+
headers: data.headers,
|
|
463
|
+
signal: controller.signal,
|
|
464
|
+
};
|
|
465
|
+
if (data.body && data.method !== 'GET') {
|
|
466
|
+
fetchOptions.body = JSON.stringify(data.body);
|
|
467
|
+
fetchOptions.headers = Object.assign(Object.assign({}, fetchOptions.headers), { 'Content-Type': 'application/json' });
|
|
468
|
+
}
|
|
469
|
+
const response = await fetch(`${baseUrl}/${path}`, fetchOptions);
|
|
470
|
+
if (!response.ok) {
|
|
471
|
+
let responseBody = null;
|
|
472
|
+
try {
|
|
473
|
+
responseBody = await response.json();
|
|
474
|
+
}
|
|
475
|
+
catch (_d) {
|
|
476
|
+
responseBody = null;
|
|
477
|
+
}
|
|
478
|
+
const message = (responseBody === null || responseBody === void 0 ? void 0 : responseBody.message) || ((_a = responseBody === null || responseBody === void 0 ? void 0 : responseBody.error) === null || _a === void 0 ? void 0 : _a.message) || `Request failed with status ${response.status}`;
|
|
479
|
+
this.sendResponse(event, {
|
|
480
|
+
_smartlinksProxyStream: true,
|
|
481
|
+
id: data.id,
|
|
482
|
+
phase: 'error',
|
|
483
|
+
status: response.status,
|
|
484
|
+
error: message,
|
|
485
|
+
});
|
|
486
|
+
return;
|
|
487
|
+
}
|
|
488
|
+
if (!response.body) {
|
|
489
|
+
throw new Error('Streaming response body is unavailable in this environment');
|
|
490
|
+
}
|
|
491
|
+
this.sendResponse(event, {
|
|
492
|
+
_smartlinksProxyStream: true,
|
|
493
|
+
id: data.id,
|
|
494
|
+
phase: 'open',
|
|
495
|
+
});
|
|
496
|
+
await this.forwardProxyStream(data.id, response.body, event);
|
|
497
|
+
this.sendResponse(event, {
|
|
498
|
+
_smartlinksProxyStream: true,
|
|
499
|
+
id: data.id,
|
|
500
|
+
phase: 'end',
|
|
501
|
+
});
|
|
502
|
+
}
|
|
503
|
+
catch (err) {
|
|
504
|
+
if ((err === null || err === void 0 ? void 0 : err.name) === 'AbortError') {
|
|
505
|
+
return;
|
|
506
|
+
}
|
|
507
|
+
console.error('[IframeResponder] Proxy stream error:', err);
|
|
508
|
+
this.sendResponse(event, {
|
|
509
|
+
_smartlinksProxyStream: true,
|
|
510
|
+
id: data.id,
|
|
511
|
+
phase: 'error',
|
|
512
|
+
error: (err === null || err === void 0 ? void 0 : err.message) || 'Unknown streaming error',
|
|
513
|
+
});
|
|
514
|
+
(_c = (_b = this.options).onError) === null || _c === void 0 ? void 0 : _c.call(_b, err);
|
|
515
|
+
}
|
|
516
|
+
finally {
|
|
517
|
+
this.activeStreams.delete(data.id);
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
async forwardProxyStream(id, stream, event) {
|
|
521
|
+
const reader = stream.getReader();
|
|
522
|
+
const decoder = new TextDecoder();
|
|
523
|
+
let buffer = '';
|
|
524
|
+
let dataLines = [];
|
|
525
|
+
while (true) {
|
|
526
|
+
const { done, value } = await reader.read();
|
|
527
|
+
if (done) {
|
|
528
|
+
break;
|
|
529
|
+
}
|
|
530
|
+
buffer += decoder.decode(value, { stream: true });
|
|
531
|
+
const lines = buffer.split(/\r?\n/);
|
|
532
|
+
buffer = lines.pop() || '';
|
|
533
|
+
for (const rawLine of lines) {
|
|
534
|
+
const line = rawLine.trimEnd();
|
|
535
|
+
if (!line) {
|
|
536
|
+
if (!dataLines.length) {
|
|
537
|
+
continue;
|
|
538
|
+
}
|
|
539
|
+
const payload = dataLines.join('\n');
|
|
540
|
+
dataLines = [];
|
|
541
|
+
if (payload === '[DONE]') {
|
|
542
|
+
return;
|
|
543
|
+
}
|
|
544
|
+
try {
|
|
545
|
+
const parsed = JSON.parse(payload);
|
|
546
|
+
this.sendResponse(event, {
|
|
547
|
+
_smartlinksProxyStream: true,
|
|
548
|
+
id,
|
|
549
|
+
phase: 'event',
|
|
550
|
+
data: parsed,
|
|
551
|
+
});
|
|
552
|
+
}
|
|
553
|
+
catch (_a) {
|
|
554
|
+
// Ignore malformed event chunks
|
|
555
|
+
}
|
|
556
|
+
continue;
|
|
557
|
+
}
|
|
558
|
+
if (line.startsWith('data:')) {
|
|
559
|
+
dataLines.push(line.slice(5).trimStart());
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
if (dataLines.length) {
|
|
564
|
+
const payload = dataLines.join('\n');
|
|
565
|
+
if (payload !== '[DONE]') {
|
|
566
|
+
try {
|
|
567
|
+
const parsed = JSON.parse(payload);
|
|
568
|
+
this.sendResponse(event, {
|
|
569
|
+
_smartlinksProxyStream: true,
|
|
570
|
+
id,
|
|
571
|
+
phase: 'event',
|
|
572
|
+
data: parsed,
|
|
573
|
+
});
|
|
574
|
+
}
|
|
575
|
+
catch (_b) {
|
|
576
|
+
// Ignore malformed trailing event chunk
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
}
|
|
429
581
|
getCachedResponse(path) {
|
|
430
582
|
// App data endpoints should NOT be cached - they need fresh data from API
|
|
431
583
|
// These are the new separated app config endpoints
|
package/dist/openapi.yaml
CHANGED
|
@@ -10782,7 +10782,7 @@ components:
|
|
|
10782
10782
|
type: number
|
|
10783
10783
|
area:
|
|
10784
10784
|
type: number
|
|
10785
|
-
|
|
10785
|
+
AnalyticsStandardEventFields:
|
|
10786
10786
|
type: object
|
|
10787
10787
|
properties:
|
|
10788
10788
|
visitorId:
|
|
@@ -10834,7 +10834,7 @@ components:
|
|
|
10834
10834
|
type: object
|
|
10835
10835
|
properties:
|
|
10836
10836
|
sessionId:
|
|
10837
|
-
|
|
10837
|
+
$ref: "#/components/schemas/AnalyticsSessionId"
|
|
10838
10838
|
eventType:
|
|
10839
10839
|
$ref: "#/components/schemas/AnalyticsEventType"
|
|
10840
10840
|
collectionId:
|
|
@@ -10873,7 +10873,7 @@ components:
|
|
|
10873
10873
|
type: object
|
|
10874
10874
|
properties:
|
|
10875
10875
|
sessionId:
|
|
10876
|
-
|
|
10876
|
+
$ref: "#/components/schemas/AnalyticsSessionId"
|
|
10877
10877
|
eventType:
|
|
10878
10878
|
$ref: "#/components/schemas/AnalyticsEventType"
|
|
10879
10879
|
collectionId:
|
|
@@ -11048,11 +11048,11 @@ components:
|
|
|
11048
11048
|
items:
|
|
11049
11049
|
type: string
|
|
11050
11050
|
sessionId:
|
|
11051
|
-
|
|
11051
|
+
$ref: "#/components/schemas/AnalyticsSessionId"
|
|
11052
11052
|
sessionIds:
|
|
11053
11053
|
type: array
|
|
11054
11054
|
items:
|
|
11055
|
-
|
|
11055
|
+
$ref: "#/components/schemas/AnalyticsSessionId"
|
|
11056
11056
|
country:
|
|
11057
11057
|
type: string
|
|
11058
11058
|
countries:
|
|
@@ -15478,6 +15478,69 @@ components:
|
|
|
15478
15478
|
required:
|
|
15479
15479
|
- _smartlinksProxyResponse
|
|
15480
15480
|
- id
|
|
15481
|
+
ProxyStreamRequest:
|
|
15482
|
+
type: object
|
|
15483
|
+
properties:
|
|
15484
|
+
_smartlinksProxyStreamRequest:
|
|
15485
|
+
type: object
|
|
15486
|
+
additionalProperties: true
|
|
15487
|
+
id:
|
|
15488
|
+
type: string
|
|
15489
|
+
method:
|
|
15490
|
+
type: string
|
|
15491
|
+
enum:
|
|
15492
|
+
- GET
|
|
15493
|
+
- POST
|
|
15494
|
+
- PUT
|
|
15495
|
+
- PATCH
|
|
15496
|
+
- DELETE
|
|
15497
|
+
path:
|
|
15498
|
+
type: string
|
|
15499
|
+
body: {}
|
|
15500
|
+
headers:
|
|
15501
|
+
type: object
|
|
15502
|
+
additionalProperties:
|
|
15503
|
+
type: string
|
|
15504
|
+
required:
|
|
15505
|
+
- _smartlinksProxyStreamRequest
|
|
15506
|
+
- id
|
|
15507
|
+
- method
|
|
15508
|
+
- path
|
|
15509
|
+
ProxyStreamAbortMessage:
|
|
15510
|
+
type: object
|
|
15511
|
+
properties:
|
|
15512
|
+
_smartlinksProxyStreamAbort:
|
|
15513
|
+
type: object
|
|
15514
|
+
additionalProperties: true
|
|
15515
|
+
id:
|
|
15516
|
+
type: string
|
|
15517
|
+
required:
|
|
15518
|
+
- _smartlinksProxyStreamAbort
|
|
15519
|
+
- id
|
|
15520
|
+
ProxyStreamMessage:
|
|
15521
|
+
type: object
|
|
15522
|
+
properties:
|
|
15523
|
+
_smartlinksProxyStream:
|
|
15524
|
+
type: object
|
|
15525
|
+
additionalProperties: true
|
|
15526
|
+
id:
|
|
15527
|
+
type: string
|
|
15528
|
+
phase:
|
|
15529
|
+
type: string
|
|
15530
|
+
enum:
|
|
15531
|
+
- open
|
|
15532
|
+
- event
|
|
15533
|
+
- end
|
|
15534
|
+
- error
|
|
15535
|
+
data: {}
|
|
15536
|
+
error:
|
|
15537
|
+
type: string
|
|
15538
|
+
status:
|
|
15539
|
+
type: number
|
|
15540
|
+
required:
|
|
15541
|
+
- _smartlinksProxyStream
|
|
15542
|
+
- id
|
|
15543
|
+
- phase
|
|
15481
15544
|
UploadStartMessage:
|
|
15482
15545
|
type: object
|
|
15483
15546
|
properties:
|
|
@@ -11,6 +11,7 @@ export type AnalyticsMetric = 'count' | 'uniqueSessions' | 'uniqueVisitors';
|
|
|
11
11
|
export type AnalyticsSortOrder = 'asc' | 'desc';
|
|
12
12
|
export type AnalyticsDeviceType = 'mobile' | 'tablet' | 'desktop' | 'unknown';
|
|
13
13
|
export type AnalyticsStorageMode = 'local' | 'session' | false;
|
|
14
|
+
export type AnalyticsSessionId = number;
|
|
14
15
|
export interface AnalyticsLocation {
|
|
15
16
|
country?: string;
|
|
16
17
|
latitude?: number;
|
|
@@ -18,7 +19,7 @@ export interface AnalyticsLocation {
|
|
|
18
19
|
area?: number;
|
|
19
20
|
[key: string]: any;
|
|
20
21
|
}
|
|
21
|
-
export interface
|
|
22
|
+
export interface AnalyticsStandardEventFields {
|
|
22
23
|
visitorId?: string;
|
|
23
24
|
referrer?: string;
|
|
24
25
|
referrerHost?: string;
|
|
@@ -42,8 +43,8 @@ export interface AnalyticsStandardMetadataFields {
|
|
|
42
43
|
qrCodeId?: string;
|
|
43
44
|
scanMethod?: string;
|
|
44
45
|
}
|
|
45
|
-
export interface CollectionAnalyticsEvent extends
|
|
46
|
-
sessionId?:
|
|
46
|
+
export interface CollectionAnalyticsEvent extends AnalyticsStandardEventFields {
|
|
47
|
+
sessionId?: AnalyticsSessionId;
|
|
47
48
|
eventType: AnalyticsEventType;
|
|
48
49
|
collectionId: string;
|
|
49
50
|
productId?: string;
|
|
@@ -60,8 +61,8 @@ export interface CollectionAnalyticsEvent extends AnalyticsStandardMetadataField
|
|
|
60
61
|
location?: AnalyticsLocation;
|
|
61
62
|
metadata?: Record<string, any>;
|
|
62
63
|
}
|
|
63
|
-
export interface TagAnalyticsEvent extends
|
|
64
|
-
sessionId?:
|
|
64
|
+
export interface TagAnalyticsEvent extends AnalyticsStandardEventFields {
|
|
65
|
+
sessionId?: AnalyticsSessionId;
|
|
65
66
|
eventType: AnalyticsEventType;
|
|
66
67
|
collectionId: string;
|
|
67
68
|
productId?: string;
|
|
@@ -81,13 +82,13 @@ export interface AnalyticsTrackOptions {
|
|
|
81
82
|
}
|
|
82
83
|
export interface AnalyticsBrowserConfig {
|
|
83
84
|
sessionStorageKey?: string;
|
|
84
|
-
sessionIdFactory?: () =>
|
|
85
|
+
sessionIdFactory?: () => AnalyticsSessionId;
|
|
85
86
|
visitorId?: string;
|
|
86
87
|
visitorStorage?: AnalyticsStorageMode;
|
|
87
88
|
visitorStorageKey?: string;
|
|
88
89
|
visitorIdFactory?: () => string;
|
|
89
90
|
autoCaptureCampaignParams?: boolean;
|
|
90
|
-
campaignParamMap?: Partial<Record<keyof
|
|
91
|
+
campaignParamMap?: Partial<Record<keyof AnalyticsStandardEventFields, string | string[]>>;
|
|
91
92
|
defaultCollectionEvent?: Partial<CollectionAnalyticsEvent>;
|
|
92
93
|
defaultTagEvent?: Partial<TagAnalyticsEvent>;
|
|
93
94
|
getCollectionDefaults?: () => Partial<CollectionAnalyticsEvent> | undefined;
|
|
@@ -148,8 +149,8 @@ export interface AnalyticsFilterRequest {
|
|
|
148
149
|
batchIds?: string[];
|
|
149
150
|
variantId?: string;
|
|
150
151
|
variantIds?: string[];
|
|
151
|
-
sessionId?:
|
|
152
|
-
sessionIds?:
|
|
152
|
+
sessionId?: AnalyticsSessionId;
|
|
153
|
+
sessionIds?: AnalyticsSessionId[];
|
|
153
154
|
country?: string;
|
|
154
155
|
countries?: string[];
|
|
155
156
|
metadata?: Record<string, any>;
|
|
@@ -68,6 +68,26 @@ export interface ProxyResponse {
|
|
|
68
68
|
data?: any;
|
|
69
69
|
error?: string;
|
|
70
70
|
}
|
|
71
|
+
export interface ProxyStreamRequest {
|
|
72
|
+
_smartlinksProxyStreamRequest: true;
|
|
73
|
+
id: string;
|
|
74
|
+
method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
|
|
75
|
+
path: string;
|
|
76
|
+
body?: any;
|
|
77
|
+
headers?: Record<string, string>;
|
|
78
|
+
}
|
|
79
|
+
export interface ProxyStreamAbortMessage {
|
|
80
|
+
_smartlinksProxyStreamAbort: true;
|
|
81
|
+
id: string;
|
|
82
|
+
}
|
|
83
|
+
export interface ProxyStreamMessage {
|
|
84
|
+
_smartlinksProxyStream: true;
|
|
85
|
+
id: string;
|
|
86
|
+
phase: 'open' | 'event' | 'end' | 'error';
|
|
87
|
+
data?: any;
|
|
88
|
+
error?: string;
|
|
89
|
+
status?: number;
|
|
90
|
+
}
|
|
71
91
|
export interface UploadStartMessage {
|
|
72
92
|
_smartlinksProxyUpload: true;
|
|
73
93
|
phase: 'start';
|
package/docs/API_SUMMARY.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Smartlinks API Summary
|
|
2
2
|
|
|
3
|
-
Version: 1.8.
|
|
3
|
+
Version: 1.8.2 | Generated: 2026-03-14T10:21:47.666Z
|
|
4
4
|
|
|
5
5
|
This is a concise summary of all available API functions and types.
|
|
6
6
|
|
|
@@ -166,6 +166,14 @@ Internal helper that performs a PATCH request to `${baseURL}${path}`, injecting
|
|
|
166
166
|
options: RequestInit) → `Promise<T>`
|
|
167
167
|
Internal helper that performs a request to `${baseURL}${path}` with custom options, injecting headers for apiKey or bearerToken if present. Returns the parsed JSON as T, or throws an Error.
|
|
168
168
|
|
|
169
|
+
**requestStream**(path: string,
|
|
170
|
+
options?: {
|
|
171
|
+
method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE'
|
|
172
|
+
body?: any
|
|
173
|
+
headers?: Record<string, string>
|
|
174
|
+
}) → `Promise<AsyncIterable<T>>`
|
|
175
|
+
Internal helper that performs a streaming request using the shared auth and proxy transport. The response is expected to be `text/event-stream` with JSON payloads in `data:` frames.
|
|
176
|
+
|
|
169
177
|
**del**(path: string,
|
|
170
178
|
extraHeaders?: Record<string, string>) → `Promise<T>`
|
|
171
179
|
Internal helper that performs a DELETE request to `${baseURL}${path}`, injecting headers for apiKey or bearerToken if present. Returns the parsed JSON as T, or throws an Error.
|
|
@@ -938,9 +946,9 @@ interface AnalyticsLocation {
|
|
|
938
946
|
}
|
|
939
947
|
```
|
|
940
948
|
|
|
941
|
-
**
|
|
949
|
+
**AnalyticsStandardEventFields** (interface)
|
|
942
950
|
```typescript
|
|
943
|
-
interface
|
|
951
|
+
interface AnalyticsStandardEventFields {
|
|
944
952
|
visitorId?: string
|
|
945
953
|
referrer?: string
|
|
946
954
|
referrerHost?: string
|
|
@@ -977,13 +985,13 @@ interface AnalyticsTrackOptions {
|
|
|
977
985
|
```typescript
|
|
978
986
|
interface AnalyticsBrowserConfig {
|
|
979
987
|
sessionStorageKey?: string
|
|
980
|
-
sessionIdFactory?: () =>
|
|
988
|
+
sessionIdFactory?: () => AnalyticsSessionId
|
|
981
989
|
visitorId?: string
|
|
982
990
|
visitorStorage?: AnalyticsStorageMode
|
|
983
991
|
visitorStorageKey?: string
|
|
984
992
|
visitorIdFactory?: () => string
|
|
985
993
|
autoCaptureCampaignParams?: boolean
|
|
986
|
-
campaignParamMap?: Partial<Record<keyof
|
|
994
|
+
campaignParamMap?: Partial<Record<keyof AnalyticsStandardEventFields, string | string[]>>
|
|
987
995
|
defaultCollectionEvent?: Partial<CollectionAnalyticsEvent>
|
|
988
996
|
defaultTagEvent?: Partial<TagAnalyticsEvent>
|
|
989
997
|
getCollectionDefaults?: () => Partial<CollectionAnalyticsEvent> | undefined
|
|
@@ -1048,8 +1056,8 @@ interface AnalyticsFilterRequest {
|
|
|
1048
1056
|
batchIds?: string[]
|
|
1049
1057
|
variantId?: string
|
|
1050
1058
|
variantIds?: string[]
|
|
1051
|
-
sessionId?:
|
|
1052
|
-
sessionIds?:
|
|
1059
|
+
sessionId?: AnalyticsSessionId
|
|
1060
|
+
sessionIds?: AnalyticsSessionId[]
|
|
1053
1061
|
country?: string
|
|
1054
1062
|
countries?: string[]
|
|
1055
1063
|
metadata?: Record<string, any>
|
|
@@ -1256,6 +1264,8 @@ interface AnalyticsTagsResponse {
|
|
|
1256
1264
|
|
|
1257
1265
|
**AnalyticsStorageMode** = `'local' | 'session' | false`
|
|
1258
1266
|
|
|
1267
|
+
**AnalyticsSessionId** = `number`
|
|
1268
|
+
|
|
1259
1269
|
**EventAnalyticsDimension** = ``
|
|
1260
1270
|
|
|
1261
1271
|
**TagAnalyticsDimension** = ``
|
|
@@ -4203,6 +4213,38 @@ interface ProxyResponse {
|
|
|
4203
4213
|
}
|
|
4204
4214
|
```
|
|
4205
4215
|
|
|
4216
|
+
**ProxyStreamRequest** (interface)
|
|
4217
|
+
```typescript
|
|
4218
|
+
interface ProxyStreamRequest {
|
|
4219
|
+
_smartlinksProxyStreamRequest: true;
|
|
4220
|
+
id: string;
|
|
4221
|
+
method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
|
|
4222
|
+
path: string;
|
|
4223
|
+
body?: any;
|
|
4224
|
+
headers?: Record<string, string>;
|
|
4225
|
+
}
|
|
4226
|
+
```
|
|
4227
|
+
|
|
4228
|
+
**ProxyStreamAbortMessage** (interface)
|
|
4229
|
+
```typescript
|
|
4230
|
+
interface ProxyStreamAbortMessage {
|
|
4231
|
+
_smartlinksProxyStreamAbort: true;
|
|
4232
|
+
id: string;
|
|
4233
|
+
}
|
|
4234
|
+
```
|
|
4235
|
+
|
|
4236
|
+
**ProxyStreamMessage** (interface)
|
|
4237
|
+
```typescript
|
|
4238
|
+
interface ProxyStreamMessage {
|
|
4239
|
+
_smartlinksProxyStream: true;
|
|
4240
|
+
id: string;
|
|
4241
|
+
phase: 'open' | 'event' | 'end' | 'error';
|
|
4242
|
+
data?: any;
|
|
4243
|
+
error?: string;
|
|
4244
|
+
status?: number;
|
|
4245
|
+
}
|
|
4246
|
+
```
|
|
4247
|
+
|
|
4206
4248
|
**UploadStartMessage** (interface)
|
|
4207
4249
|
```typescript
|
|
4208
4250
|
interface UploadStartMessage {
|
|
@@ -5789,7 +5831,7 @@ Fire-and-forget tag analytics event. Uses `navigator.sendBeacon()` when availabl
|
|
|
5789
5831
|
**configure**(config: AnalyticsBrowserConfig) → `void`
|
|
5790
5832
|
Fire-and-forget tag analytics event. Uses `navigator.sendBeacon()` when available, falling back to `fetch(..., { keepalive: true })`.
|
|
5791
5833
|
|
|
5792
|
-
**getSessionId**() → `
|
|
5834
|
+
**getSessionId**() → `AnalyticsSessionId | undefined`
|
|
5793
5835
|
Fire-and-forget tag analytics event. Uses `navigator.sendBeacon()` when available, falling back to `fetch(..., { keepalive: true })`.
|
|
5794
5836
|
|
|
5795
5837
|
**getVisitorId**() → `string | undefined`
|
|
@@ -1,26 +1,31 @@
|
|
|
1
1
|
# Analytics Metadata Conventions
|
|
2
2
|
|
|
3
|
-
Use these as the recommended standard
|
|
3
|
+
Use these as the recommended standard analytics keys.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Some of these are now promoted top-level analytics fields. Others remain good metadata keys for custom dimensions.
|
|
6
6
|
|
|
7
7
|
---
|
|
8
8
|
|
|
9
9
|
## Recommended Keys
|
|
10
10
|
|
|
11
|
-
###
|
|
11
|
+
### Promoted top-level fields
|
|
12
12
|
|
|
13
|
-
- `
|
|
13
|
+
- `visitorId`
|
|
14
14
|
- `referrerHost`
|
|
15
|
+
- `entryType`
|
|
16
|
+
- `pageId`
|
|
17
|
+
- `scanMethod`
|
|
18
|
+
|
|
19
|
+
These should be sent as top-level analytics fields, not inside `metadata`.
|
|
20
|
+
|
|
21
|
+
### Metadata-friendly keys
|
|
22
|
+
|
|
23
|
+
- `referrer`
|
|
15
24
|
- `utmSource`
|
|
16
25
|
- `utmMedium`
|
|
17
26
|
- `utmCampaign`
|
|
18
27
|
- `utmContent`
|
|
19
28
|
- `utmTerm`
|
|
20
|
-
- `entryType` — for example `direct`, `qr`, `nfc`, `social`, `email`, `paid`, or `organic`
|
|
21
|
-
|
|
22
|
-
### Link-tree and page analytics
|
|
23
|
-
|
|
24
29
|
- `group`
|
|
25
30
|
- `tag`
|
|
26
31
|
- `campaign`
|
|
@@ -31,13 +36,8 @@ You can put them in `metadata` directly today. The public analytics ingestion en
|
|
|
31
36
|
- `linkTitle`
|
|
32
37
|
- `destinationDomain`
|
|
33
38
|
- `pagePath`
|
|
34
|
-
- `pageId`
|
|
35
39
|
- `qrCodeId`
|
|
36
40
|
|
|
37
|
-
### Physical scan analytics
|
|
38
|
-
|
|
39
|
-
- `scanMethod` — for example `nfc` or `qr`
|
|
40
|
-
|
|
41
41
|
---
|
|
42
42
|
|
|
43
43
|
## Why These Matter
|
|
@@ -56,6 +56,7 @@ These keys give teams a shared vocabulary for:
|
|
|
56
56
|
|
|
57
57
|
- Treat these as reserved standard keys.
|
|
58
58
|
- Prefer these names before inventing custom alternatives.
|
|
59
|
+
- Send promoted fields at top level.
|
|
59
60
|
- Keep values flat and scalar where possible so they are easier to filter and break down later.
|
|
60
61
|
- Promote a field to a first-class backend column only when it becomes a hot platform-wide dimension.
|
|
61
62
|
|
|
@@ -65,14 +66,17 @@ These keys give teams a shared vocabulary for:
|
|
|
65
66
|
|
|
66
67
|
```typescript
|
|
67
68
|
analytics.collection.track({
|
|
68
|
-
sessionId:
|
|
69
|
+
sessionId: 1234567890,
|
|
69
70
|
eventType: 'click_link',
|
|
70
71
|
collectionId: 'demo-collection',
|
|
72
|
+
visitorId: 'visitor_123',
|
|
71
73
|
linkId: 'hero-cta',
|
|
72
74
|
href: 'https://example.com/buy',
|
|
75
|
+
referrerHost: 'instagram.com',
|
|
73
76
|
placement: 'hero',
|
|
74
77
|
campaign: 'summer-launch',
|
|
75
78
|
utmSource: 'email',
|
|
79
|
+
pageId: 'QR123',
|
|
76
80
|
metadata: {
|
|
77
81
|
pagePath: '/c/demo-collection',
|
|
78
82
|
},
|