@drivemetadata-ai/sdk 0.1.1-beta.4 → 0.1.1
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 +152 -21
- package/dist/angular/index.cjs +173 -8
- package/dist/angular/index.cjs.map +1 -1
- package/dist/angular/index.js +173 -8
- package/dist/angular/index.js.map +1 -1
- package/dist/browser/index.cjs +173 -8
- package/dist/browser/index.cjs.map +1 -1
- package/dist/browser/index.js +173 -8
- package/dist/browser/index.js.map +1 -1
- package/dist/next/index.cjs +173 -8
- package/dist/next/index.cjs.map +1 -1
- package/dist/next/index.js +173 -8
- package/dist/next/index.js.map +1 -1
- package/dist/react/index.cjs +173 -8
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.js +173 -8
- package/dist/react/index.js.map +1 -1
- package/docs/integration.md +177 -5
- package/package.json +2 -1
package/dist/angular/index.js
CHANGED
|
@@ -239,6 +239,15 @@ var sensitiveKeys = /* @__PURE__ */ new Set([
|
|
|
239
239
|
"session",
|
|
240
240
|
"cookie"
|
|
241
241
|
]);
|
|
242
|
+
function redactUrl(url, allowQueryKeys = ["utm_source", "utm_medium", "utm_campaign", "utm_term", "utm_content"]) {
|
|
243
|
+
const parsed = new URL(url, "https://placeholder.local");
|
|
244
|
+
for (const key of Array.from(parsed.searchParams.keys())) {
|
|
245
|
+
if (!allowQueryKeys.includes(key)) {
|
|
246
|
+
parsed.searchParams.set(key, "[REDACTED]");
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
return url.startsWith("http") ? parsed.toString() : `${parsed.pathname}${parsed.search}`;
|
|
250
|
+
}
|
|
242
251
|
function sanitizeValue(value, allow, path = []) {
|
|
243
252
|
if (Array.isArray(value)) {
|
|
244
253
|
return value.map((item) => sanitizeValue(item, allow, path));
|
|
@@ -260,6 +269,127 @@ function sanitizeProperties(input, allowRawKeys = []) {
|
|
|
260
269
|
return sanitizeValue(input, allow);
|
|
261
270
|
}
|
|
262
271
|
|
|
272
|
+
// src/browser/core/attribute-persistence.ts
|
|
273
|
+
var DMD_ATTRIBUTES_STORAGE_KEY = "dmd_attributes";
|
|
274
|
+
var SESSION_STORAGE_KEY = "sessionData";
|
|
275
|
+
var SESSION_ID_KEY = "sessionId";
|
|
276
|
+
var SESSION_TIMESTAMP_KEY = "timestamp";
|
|
277
|
+
function isBlankValue(value) {
|
|
278
|
+
return value === null || value === void 0 || typeof value === "string" && value.trim() === "";
|
|
279
|
+
}
|
|
280
|
+
function readAttributes(base) {
|
|
281
|
+
const raw = base.getItem(DMD_ATTRIBUTES_STORAGE_KEY);
|
|
282
|
+
if (!raw) return {};
|
|
283
|
+
try {
|
|
284
|
+
const parsed = JSON.parse(raw);
|
|
285
|
+
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {};
|
|
286
|
+
} catch {
|
|
287
|
+
base.removeItem(DMD_ATTRIBUTES_STORAGE_KEY);
|
|
288
|
+
return {};
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
function sanitizeAttributes(attributes) {
|
|
292
|
+
return Object.fromEntries(Object.entries(attributes).filter(([, value]) => !isBlankValue(value)));
|
|
293
|
+
}
|
|
294
|
+
function writeAttributes(base, attributes) {
|
|
295
|
+
const sanitized = sanitizeAttributes(attributes);
|
|
296
|
+
if (Object.keys(sanitized).length === 0) {
|
|
297
|
+
base.removeItem(DMD_ATTRIBUTES_STORAGE_KEY);
|
|
298
|
+
return;
|
|
299
|
+
}
|
|
300
|
+
base.setItem(DMD_ATTRIBUTES_STORAGE_KEY, JSON.stringify(sanitized));
|
|
301
|
+
}
|
|
302
|
+
function parseSessionData(value) {
|
|
303
|
+
try {
|
|
304
|
+
const parsed = JSON.parse(value);
|
|
305
|
+
const sessionData = {};
|
|
306
|
+
const sessionId = typeof parsed.sessionId === "string" && parsed.sessionId.trim() !== "" ? parsed.sessionId : void 0;
|
|
307
|
+
const timestamp = typeof parsed.timestamp === "number" ? parsed.timestamp : void 0;
|
|
308
|
+
if (sessionId !== void 0) sessionData.sessionId = sessionId;
|
|
309
|
+
if (timestamp !== void 0) sessionData.timestamp = timestamp;
|
|
310
|
+
return sessionData;
|
|
311
|
+
} catch {
|
|
312
|
+
return {};
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
function getAggregateValue(attributes, key) {
|
|
316
|
+
if (key === SESSION_STORAGE_KEY) {
|
|
317
|
+
const sessionId = attributes[SESSION_ID_KEY];
|
|
318
|
+
const timestamp = attributes[SESSION_TIMESTAMP_KEY];
|
|
319
|
+
if (typeof sessionId === "string" && !isBlankValue(sessionId) && typeof timestamp === "number") {
|
|
320
|
+
return JSON.stringify({ sessionId, timestamp });
|
|
321
|
+
}
|
|
322
|
+
return null;
|
|
323
|
+
}
|
|
324
|
+
const value = attributes[key];
|
|
325
|
+
if (isBlankValue(value)) return null;
|
|
326
|
+
return typeof value === "string" ? value : JSON.stringify(value);
|
|
327
|
+
}
|
|
328
|
+
function setAggregateValue(attributes, key, value) {
|
|
329
|
+
if (key === SESSION_STORAGE_KEY) {
|
|
330
|
+
const sessionData = parseSessionData(value);
|
|
331
|
+
if (sessionData.sessionId === void 0 || sessionData.timestamp === void 0) {
|
|
332
|
+
delete attributes[SESSION_ID_KEY];
|
|
333
|
+
delete attributes[SESSION_TIMESTAMP_KEY];
|
|
334
|
+
return;
|
|
335
|
+
}
|
|
336
|
+
attributes[SESSION_ID_KEY] = sessionData.sessionId;
|
|
337
|
+
attributes[SESSION_TIMESTAMP_KEY] = sessionData.timestamp;
|
|
338
|
+
return;
|
|
339
|
+
}
|
|
340
|
+
attributes[key] = value;
|
|
341
|
+
}
|
|
342
|
+
function removeAggregateValue(attributes, key) {
|
|
343
|
+
if (key === SESSION_STORAGE_KEY) {
|
|
344
|
+
delete attributes[SESSION_ID_KEY];
|
|
345
|
+
delete attributes[SESSION_TIMESTAMP_KEY];
|
|
346
|
+
return;
|
|
347
|
+
}
|
|
348
|
+
delete attributes[key];
|
|
349
|
+
}
|
|
350
|
+
function createDmdAttributesPersistence(base) {
|
|
351
|
+
return {
|
|
352
|
+
getItem(key) {
|
|
353
|
+
if (key === DMD_ATTRIBUTES_STORAGE_KEY) return base.getItem(key);
|
|
354
|
+
const attributes = readAttributes(base);
|
|
355
|
+
const aggregateValue = getAggregateValue(attributes, key);
|
|
356
|
+
if (aggregateValue !== null) return aggregateValue;
|
|
357
|
+
const legacyValue = base.getItem(key);
|
|
358
|
+
if (isBlankValue(legacyValue)) return null;
|
|
359
|
+
setAggregateValue(attributes, key, String(legacyValue));
|
|
360
|
+
writeAttributes(base, attributes);
|
|
361
|
+
return legacyValue;
|
|
362
|
+
},
|
|
363
|
+
setItem(key, value) {
|
|
364
|
+
if (key === DMD_ATTRIBUTES_STORAGE_KEY) return base.setItem(key, value);
|
|
365
|
+
const attributes = readAttributes(base);
|
|
366
|
+
if (isBlankValue(value)) {
|
|
367
|
+
removeAggregateValue(attributes, key);
|
|
368
|
+
writeAttributes(base, attributes);
|
|
369
|
+
base.removeItem(key);
|
|
370
|
+
return true;
|
|
371
|
+
}
|
|
372
|
+
setAggregateValue(attributes, key, value);
|
|
373
|
+
writeAttributes(base, attributes);
|
|
374
|
+
base.setItem(key, value);
|
|
375
|
+
return true;
|
|
376
|
+
},
|
|
377
|
+
removeItem(key) {
|
|
378
|
+
if (key === DMD_ATTRIBUTES_STORAGE_KEY) {
|
|
379
|
+
base.removeItem(key);
|
|
380
|
+
return;
|
|
381
|
+
}
|
|
382
|
+
const attributes = readAttributes(base);
|
|
383
|
+
removeAggregateValue(attributes, key);
|
|
384
|
+
writeAttributes(base, attributes);
|
|
385
|
+
base.removeItem(key);
|
|
386
|
+
},
|
|
387
|
+
getHealth() {
|
|
388
|
+
return base.getHealth();
|
|
389
|
+
}
|
|
390
|
+
};
|
|
391
|
+
}
|
|
392
|
+
|
|
263
393
|
// src/core/attribution.ts
|
|
264
394
|
var dmdUtmKeys = [
|
|
265
395
|
"utm_source",
|
|
@@ -296,6 +426,10 @@ function mergeAttributionRecords(explicitProperties, stored) {
|
|
|
296
426
|
}
|
|
297
427
|
|
|
298
428
|
// src/browser/core/attribution.ts
|
|
429
|
+
var DMD_CLICK_ID_QUERY_KEY = "click_id";
|
|
430
|
+
var DMD_CLICK_ID_LEGACY_QUERY_KEY = "dmd_click_id";
|
|
431
|
+
var DMD_CLICK_ID_STORAGE_KEY = "dmd_click_id";
|
|
432
|
+
var DMD_CLICK_ID_ATTRIBUTE_KEY = "click_id";
|
|
299
433
|
function getCurrentUrl() {
|
|
300
434
|
return getBrowserWindow()?.location?.href;
|
|
301
435
|
}
|
|
@@ -314,6 +448,9 @@ function setIfPresent(persistence, key, value) {
|
|
|
314
448
|
persistence.setItem(key, value);
|
|
315
449
|
}
|
|
316
450
|
}
|
|
451
|
+
function getClickIdParam(params) {
|
|
452
|
+
return params.get(DMD_CLICK_ID_LEGACY_QUERY_KEY) || params.get(DMD_CLICK_ID_QUERY_KEY);
|
|
453
|
+
}
|
|
317
454
|
function getStoredString(persistence, key) {
|
|
318
455
|
const value = persistence.getItem(key);
|
|
319
456
|
return value === null || value === "" ? void 0 : value;
|
|
@@ -333,6 +470,9 @@ function captureAttributionFromUrl(persistence, url = getCurrentUrl()) {
|
|
|
333
470
|
for (const key of dmdCampaignKeys) {
|
|
334
471
|
setIfPresent(persistence, key, params.get(key));
|
|
335
472
|
}
|
|
473
|
+
const clickId = getClickIdParam(params);
|
|
474
|
+
setIfPresent(persistence, DMD_CLICK_ID_ATTRIBUTE_KEY, clickId);
|
|
475
|
+
setIfPresent(persistence, DMD_CLICK_ID_STORAGE_KEY, clickId);
|
|
336
476
|
for (const [param, sdkPubId] of dmdClickIdSources) {
|
|
337
477
|
const value = params.get(param);
|
|
338
478
|
if (value) {
|
|
@@ -348,7 +488,8 @@ function getStoredAttributionData(persistence) {
|
|
|
348
488
|
fbc: getStoredString(persistence, "fbc") ?? getCookie("_fbc"),
|
|
349
489
|
fbp: getStoredString(persistence, "fbp") ?? getCookie("_fbp"),
|
|
350
490
|
campaign_id: getStoredString(persistence, "campaign_id"),
|
|
351
|
-
ad_id: getStoredString(persistence, "ad_id")
|
|
491
|
+
ad_id: getStoredString(persistence, "ad_id"),
|
|
492
|
+
click_id: getStoredString(persistence, DMD_CLICK_ID_STORAGE_KEY) ?? getStoredString(persistence, DMD_CLICK_ID_ATTRIBUTE_KEY)
|
|
352
493
|
});
|
|
353
494
|
}
|
|
354
495
|
function getStoredUtmParameter(persistence) {
|
|
@@ -867,6 +1008,24 @@ function resetAnonymousId(persistence) {
|
|
|
867
1008
|
return anonymousId;
|
|
868
1009
|
}
|
|
869
1010
|
|
|
1011
|
+
// src/browser/core/page-context.ts
|
|
1012
|
+
function redactSearch(search) {
|
|
1013
|
+
const redacted = redactUrl(search);
|
|
1014
|
+
return redacted.startsWith("/?") ? redacted.slice(1) : redacted;
|
|
1015
|
+
}
|
|
1016
|
+
function getBrowserPageContext() {
|
|
1017
|
+
const browserWindow = getBrowserWindow();
|
|
1018
|
+
const documentRef = browserWindow?.document ?? globalThis.document;
|
|
1019
|
+
const location = browserWindow?.location;
|
|
1020
|
+
const page2 = {};
|
|
1021
|
+
if (location?.href) page2.url = location.href;
|
|
1022
|
+
if (location?.pathname) page2.path = location.pathname;
|
|
1023
|
+
if (location?.search) page2.search = redactSearch(location.search);
|
|
1024
|
+
if (documentRef?.title) page2.title = documentRef.title;
|
|
1025
|
+
if (documentRef?.referrer) page2.referrer = redactUrl(documentRef.referrer);
|
|
1026
|
+
return page2;
|
|
1027
|
+
}
|
|
1028
|
+
|
|
870
1029
|
// src/browser/core/persistence.ts
|
|
871
1030
|
function createPersistenceHealth(requested) {
|
|
872
1031
|
return {
|
|
@@ -1033,7 +1192,7 @@ function createBrowserPersistence(mode = "localStorage+cookie") {
|
|
|
1033
1192
|
}
|
|
1034
1193
|
|
|
1035
1194
|
// src/browser/core/session.ts
|
|
1036
|
-
var
|
|
1195
|
+
var SESSION_STORAGE_KEY2 = "sessionData";
|
|
1037
1196
|
function getUrlParam2(name) {
|
|
1038
1197
|
const href = getBrowserWindow()?.location?.href;
|
|
1039
1198
|
if (!href) return null;
|
|
@@ -1044,7 +1203,7 @@ function getUrlParam2(name) {
|
|
|
1044
1203
|
}
|
|
1045
1204
|
}
|
|
1046
1205
|
function readStoredSession(persistence) {
|
|
1047
|
-
const rawSession = persistence.getItem(
|
|
1206
|
+
const rawSession = persistence.getItem(SESSION_STORAGE_KEY2);
|
|
1048
1207
|
if (!rawSession) return void 0;
|
|
1049
1208
|
try {
|
|
1050
1209
|
const parsed = JSON.parse(rawSession);
|
|
@@ -1055,12 +1214,12 @@ function readStoredSession(persistence) {
|
|
|
1055
1214
|
};
|
|
1056
1215
|
}
|
|
1057
1216
|
} catch {
|
|
1058
|
-
persistence.removeItem(
|
|
1217
|
+
persistence.removeItem(SESSION_STORAGE_KEY2);
|
|
1059
1218
|
}
|
|
1060
1219
|
return void 0;
|
|
1061
1220
|
}
|
|
1062
1221
|
function writeStoredSession(persistence, sessionId, timestamp) {
|
|
1063
|
-
persistence.setItem(
|
|
1222
|
+
persistence.setItem(SESSION_STORAGE_KEY2, JSON.stringify({ sessionId, timestamp }));
|
|
1064
1223
|
}
|
|
1065
1224
|
function createSessionManager(persistence, idleTimeoutSeconds = 30 * 60) {
|
|
1066
1225
|
function resolveSessionId() {
|
|
@@ -1114,11 +1273,12 @@ var DriveMetaDataSDK = class {
|
|
|
1114
1273
|
requireConfigString(config.writeKey || config.token, "writeKey or token");
|
|
1115
1274
|
this.config = config;
|
|
1116
1275
|
this.endpoint = endpointFromConfig(config);
|
|
1117
|
-
|
|
1276
|
+
const storagePersistence = createBrowserPersistence(config.persistence);
|
|
1277
|
+
this.persistence = createDmdAttributesPersistence(storagePersistence);
|
|
1118
1278
|
this.session = createSessionManager(this.persistence, config.sessionIdleTimeoutSeconds);
|
|
1119
1279
|
const deliveryConfig = {
|
|
1120
1280
|
endpoint: this.endpoint,
|
|
1121
|
-
storage:
|
|
1281
|
+
storage: storagePersistence
|
|
1122
1282
|
};
|
|
1123
1283
|
if (config.delivery?.maxQueueSize !== void 0) deliveryConfig.maxQueueSize = config.delivery.maxQueueSize;
|
|
1124
1284
|
if (config.delivery?.queueTtlMs !== void 0) deliveryConfig.queueTtlMs = config.delivery.queueTtlMs;
|
|
@@ -1363,6 +1523,7 @@ var DriveMetaDataSDK = class {
|
|
|
1363
1523
|
}
|
|
1364
1524
|
toCollectorPayload(prepared) {
|
|
1365
1525
|
const browserWindow = getBrowserWindow();
|
|
1526
|
+
const pageContext = getBrowserPageContext();
|
|
1366
1527
|
return createBackendCollectorPayload({
|
|
1367
1528
|
requestId: prepared.messageId,
|
|
1368
1529
|
timestamp: prepared.timestamp,
|
|
@@ -1374,9 +1535,13 @@ var DriveMetaDataSDK = class {
|
|
|
1374
1535
|
sessionId: prepared.sessionId,
|
|
1375
1536
|
ua: browserWindow?.navigator?.userAgent,
|
|
1376
1537
|
appId: prepared.appId,
|
|
1377
|
-
pageUrl: browserWindow?.location?.href,
|
|
1538
|
+
pageUrl: pageContext.url ?? browserWindow?.location?.href,
|
|
1378
1539
|
eventData: mergeStoredAttribution({
|
|
1379
1540
|
...prepared.properties,
|
|
1541
|
+
page: {
|
|
1542
|
+
...pageContext,
|
|
1543
|
+
...prepared.properties.page && typeof prepared.properties.page === "object" ? prepared.properties.page : {}
|
|
1544
|
+
},
|
|
1380
1545
|
anonymousId: prepared.anonymousId,
|
|
1381
1546
|
sessionId: prepared.sessionId,
|
|
1382
1547
|
timestamp: prepared.timestamp,
|