@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/next/index.js
CHANGED
|
@@ -229,6 +229,15 @@ var sensitiveKeys = /* @__PURE__ */ new Set([
|
|
|
229
229
|
"session",
|
|
230
230
|
"cookie"
|
|
231
231
|
]);
|
|
232
|
+
function redactUrl(url, allowQueryKeys = ["utm_source", "utm_medium", "utm_campaign", "utm_term", "utm_content"]) {
|
|
233
|
+
const parsed = new URL(url, "https://placeholder.local");
|
|
234
|
+
for (const key of Array.from(parsed.searchParams.keys())) {
|
|
235
|
+
if (!allowQueryKeys.includes(key)) {
|
|
236
|
+
parsed.searchParams.set(key, "[REDACTED]");
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
return url.startsWith("http") ? parsed.toString() : `${parsed.pathname}${parsed.search}`;
|
|
240
|
+
}
|
|
232
241
|
function sanitizeValue(value, allow, path = []) {
|
|
233
242
|
if (Array.isArray(value)) {
|
|
234
243
|
return value.map((item) => sanitizeValue(item, allow, path));
|
|
@@ -250,6 +259,127 @@ function sanitizeProperties(input, allowRawKeys = []) {
|
|
|
250
259
|
return sanitizeValue(input, allow);
|
|
251
260
|
}
|
|
252
261
|
|
|
262
|
+
// src/browser/core/attribute-persistence.ts
|
|
263
|
+
var DMD_ATTRIBUTES_STORAGE_KEY = "dmd_attributes";
|
|
264
|
+
var SESSION_STORAGE_KEY = "sessionData";
|
|
265
|
+
var SESSION_ID_KEY = "sessionId";
|
|
266
|
+
var SESSION_TIMESTAMP_KEY = "timestamp";
|
|
267
|
+
function isBlankValue(value) {
|
|
268
|
+
return value === null || value === void 0 || typeof value === "string" && value.trim() === "";
|
|
269
|
+
}
|
|
270
|
+
function readAttributes(base) {
|
|
271
|
+
const raw = base.getItem(DMD_ATTRIBUTES_STORAGE_KEY);
|
|
272
|
+
if (!raw) return {};
|
|
273
|
+
try {
|
|
274
|
+
const parsed = JSON.parse(raw);
|
|
275
|
+
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {};
|
|
276
|
+
} catch {
|
|
277
|
+
base.removeItem(DMD_ATTRIBUTES_STORAGE_KEY);
|
|
278
|
+
return {};
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
function sanitizeAttributes(attributes) {
|
|
282
|
+
return Object.fromEntries(Object.entries(attributes).filter(([, value]) => !isBlankValue(value)));
|
|
283
|
+
}
|
|
284
|
+
function writeAttributes(base, attributes) {
|
|
285
|
+
const sanitized = sanitizeAttributes(attributes);
|
|
286
|
+
if (Object.keys(sanitized).length === 0) {
|
|
287
|
+
base.removeItem(DMD_ATTRIBUTES_STORAGE_KEY);
|
|
288
|
+
return;
|
|
289
|
+
}
|
|
290
|
+
base.setItem(DMD_ATTRIBUTES_STORAGE_KEY, JSON.stringify(sanitized));
|
|
291
|
+
}
|
|
292
|
+
function parseSessionData(value) {
|
|
293
|
+
try {
|
|
294
|
+
const parsed = JSON.parse(value);
|
|
295
|
+
const sessionData = {};
|
|
296
|
+
const sessionId = typeof parsed.sessionId === "string" && parsed.sessionId.trim() !== "" ? parsed.sessionId : void 0;
|
|
297
|
+
const timestamp = typeof parsed.timestamp === "number" ? parsed.timestamp : void 0;
|
|
298
|
+
if (sessionId !== void 0) sessionData.sessionId = sessionId;
|
|
299
|
+
if (timestamp !== void 0) sessionData.timestamp = timestamp;
|
|
300
|
+
return sessionData;
|
|
301
|
+
} catch {
|
|
302
|
+
return {};
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
function getAggregateValue(attributes, key) {
|
|
306
|
+
if (key === SESSION_STORAGE_KEY) {
|
|
307
|
+
const sessionId = attributes[SESSION_ID_KEY];
|
|
308
|
+
const timestamp = attributes[SESSION_TIMESTAMP_KEY];
|
|
309
|
+
if (typeof sessionId === "string" && !isBlankValue(sessionId) && typeof timestamp === "number") {
|
|
310
|
+
return JSON.stringify({ sessionId, timestamp });
|
|
311
|
+
}
|
|
312
|
+
return null;
|
|
313
|
+
}
|
|
314
|
+
const value = attributes[key];
|
|
315
|
+
if (isBlankValue(value)) return null;
|
|
316
|
+
return typeof value === "string" ? value : JSON.stringify(value);
|
|
317
|
+
}
|
|
318
|
+
function setAggregateValue(attributes, key, value) {
|
|
319
|
+
if (key === SESSION_STORAGE_KEY) {
|
|
320
|
+
const sessionData = parseSessionData(value);
|
|
321
|
+
if (sessionData.sessionId === void 0 || sessionData.timestamp === void 0) {
|
|
322
|
+
delete attributes[SESSION_ID_KEY];
|
|
323
|
+
delete attributes[SESSION_TIMESTAMP_KEY];
|
|
324
|
+
return;
|
|
325
|
+
}
|
|
326
|
+
attributes[SESSION_ID_KEY] = sessionData.sessionId;
|
|
327
|
+
attributes[SESSION_TIMESTAMP_KEY] = sessionData.timestamp;
|
|
328
|
+
return;
|
|
329
|
+
}
|
|
330
|
+
attributes[key] = value;
|
|
331
|
+
}
|
|
332
|
+
function removeAggregateValue(attributes, key) {
|
|
333
|
+
if (key === SESSION_STORAGE_KEY) {
|
|
334
|
+
delete attributes[SESSION_ID_KEY];
|
|
335
|
+
delete attributes[SESSION_TIMESTAMP_KEY];
|
|
336
|
+
return;
|
|
337
|
+
}
|
|
338
|
+
delete attributes[key];
|
|
339
|
+
}
|
|
340
|
+
function createDmdAttributesPersistence(base) {
|
|
341
|
+
return {
|
|
342
|
+
getItem(key) {
|
|
343
|
+
if (key === DMD_ATTRIBUTES_STORAGE_KEY) return base.getItem(key);
|
|
344
|
+
const attributes = readAttributes(base);
|
|
345
|
+
const aggregateValue = getAggregateValue(attributes, key);
|
|
346
|
+
if (aggregateValue !== null) return aggregateValue;
|
|
347
|
+
const legacyValue = base.getItem(key);
|
|
348
|
+
if (isBlankValue(legacyValue)) return null;
|
|
349
|
+
setAggregateValue(attributes, key, String(legacyValue));
|
|
350
|
+
writeAttributes(base, attributes);
|
|
351
|
+
return legacyValue;
|
|
352
|
+
},
|
|
353
|
+
setItem(key, value) {
|
|
354
|
+
if (key === DMD_ATTRIBUTES_STORAGE_KEY) return base.setItem(key, value);
|
|
355
|
+
const attributes = readAttributes(base);
|
|
356
|
+
if (isBlankValue(value)) {
|
|
357
|
+
removeAggregateValue(attributes, key);
|
|
358
|
+
writeAttributes(base, attributes);
|
|
359
|
+
base.removeItem(key);
|
|
360
|
+
return true;
|
|
361
|
+
}
|
|
362
|
+
setAggregateValue(attributes, key, value);
|
|
363
|
+
writeAttributes(base, attributes);
|
|
364
|
+
base.setItem(key, value);
|
|
365
|
+
return true;
|
|
366
|
+
},
|
|
367
|
+
removeItem(key) {
|
|
368
|
+
if (key === DMD_ATTRIBUTES_STORAGE_KEY) {
|
|
369
|
+
base.removeItem(key);
|
|
370
|
+
return;
|
|
371
|
+
}
|
|
372
|
+
const attributes = readAttributes(base);
|
|
373
|
+
removeAggregateValue(attributes, key);
|
|
374
|
+
writeAttributes(base, attributes);
|
|
375
|
+
base.removeItem(key);
|
|
376
|
+
},
|
|
377
|
+
getHealth() {
|
|
378
|
+
return base.getHealth();
|
|
379
|
+
}
|
|
380
|
+
};
|
|
381
|
+
}
|
|
382
|
+
|
|
253
383
|
// src/core/attribution.ts
|
|
254
384
|
var dmdUtmKeys = [
|
|
255
385
|
"utm_source",
|
|
@@ -286,6 +416,10 @@ function mergeAttributionRecords(explicitProperties, stored) {
|
|
|
286
416
|
}
|
|
287
417
|
|
|
288
418
|
// src/browser/core/attribution.ts
|
|
419
|
+
var DMD_CLICK_ID_QUERY_KEY = "click_id";
|
|
420
|
+
var DMD_CLICK_ID_LEGACY_QUERY_KEY = "dmd_click_id";
|
|
421
|
+
var DMD_CLICK_ID_STORAGE_KEY = "dmd_click_id";
|
|
422
|
+
var DMD_CLICK_ID_ATTRIBUTE_KEY = "click_id";
|
|
289
423
|
function getCurrentUrl() {
|
|
290
424
|
return getBrowserWindow()?.location?.href;
|
|
291
425
|
}
|
|
@@ -304,6 +438,9 @@ function setIfPresent(persistence, key, value) {
|
|
|
304
438
|
persistence.setItem(key, value);
|
|
305
439
|
}
|
|
306
440
|
}
|
|
441
|
+
function getClickIdParam(params) {
|
|
442
|
+
return params.get(DMD_CLICK_ID_LEGACY_QUERY_KEY) || params.get(DMD_CLICK_ID_QUERY_KEY);
|
|
443
|
+
}
|
|
307
444
|
function getStoredString(persistence, key) {
|
|
308
445
|
const value = persistence.getItem(key);
|
|
309
446
|
return value === null || value === "" ? void 0 : value;
|
|
@@ -323,6 +460,9 @@ function captureAttributionFromUrl(persistence, url = getCurrentUrl()) {
|
|
|
323
460
|
for (const key of dmdCampaignKeys) {
|
|
324
461
|
setIfPresent(persistence, key, params.get(key));
|
|
325
462
|
}
|
|
463
|
+
const clickId = getClickIdParam(params);
|
|
464
|
+
setIfPresent(persistence, DMD_CLICK_ID_ATTRIBUTE_KEY, clickId);
|
|
465
|
+
setIfPresent(persistence, DMD_CLICK_ID_STORAGE_KEY, clickId);
|
|
326
466
|
for (const [param, sdkPubId] of dmdClickIdSources) {
|
|
327
467
|
const value = params.get(param);
|
|
328
468
|
if (value) {
|
|
@@ -338,7 +478,8 @@ function getStoredAttributionData(persistence) {
|
|
|
338
478
|
fbc: getStoredString(persistence, "fbc") ?? getCookie("_fbc"),
|
|
339
479
|
fbp: getStoredString(persistence, "fbp") ?? getCookie("_fbp"),
|
|
340
480
|
campaign_id: getStoredString(persistence, "campaign_id"),
|
|
341
|
-
ad_id: getStoredString(persistence, "ad_id")
|
|
481
|
+
ad_id: getStoredString(persistence, "ad_id"),
|
|
482
|
+
click_id: getStoredString(persistence, DMD_CLICK_ID_STORAGE_KEY) ?? getStoredString(persistence, DMD_CLICK_ID_ATTRIBUTE_KEY)
|
|
342
483
|
});
|
|
343
484
|
}
|
|
344
485
|
function getStoredUtmParameter(persistence) {
|
|
@@ -857,6 +998,24 @@ function resetAnonymousId(persistence) {
|
|
|
857
998
|
return anonymousId;
|
|
858
999
|
}
|
|
859
1000
|
|
|
1001
|
+
// src/browser/core/page-context.ts
|
|
1002
|
+
function redactSearch(search) {
|
|
1003
|
+
const redacted = redactUrl(search);
|
|
1004
|
+
return redacted.startsWith("/?") ? redacted.slice(1) : redacted;
|
|
1005
|
+
}
|
|
1006
|
+
function getBrowserPageContext() {
|
|
1007
|
+
const browserWindow = getBrowserWindow();
|
|
1008
|
+
const documentRef = browserWindow?.document ?? globalThis.document;
|
|
1009
|
+
const location = browserWindow?.location;
|
|
1010
|
+
const page2 = {};
|
|
1011
|
+
if (location?.href) page2.url = location.href;
|
|
1012
|
+
if (location?.pathname) page2.path = location.pathname;
|
|
1013
|
+
if (location?.search) page2.search = redactSearch(location.search);
|
|
1014
|
+
if (documentRef?.title) page2.title = documentRef.title;
|
|
1015
|
+
if (documentRef?.referrer) page2.referrer = redactUrl(documentRef.referrer);
|
|
1016
|
+
return page2;
|
|
1017
|
+
}
|
|
1018
|
+
|
|
860
1019
|
// src/browser/core/persistence.ts
|
|
861
1020
|
function createPersistenceHealth(requested) {
|
|
862
1021
|
return {
|
|
@@ -1023,7 +1182,7 @@ function createBrowserPersistence(mode = "localStorage+cookie") {
|
|
|
1023
1182
|
}
|
|
1024
1183
|
|
|
1025
1184
|
// src/browser/core/session.ts
|
|
1026
|
-
var
|
|
1185
|
+
var SESSION_STORAGE_KEY2 = "sessionData";
|
|
1027
1186
|
function getUrlParam2(name) {
|
|
1028
1187
|
const href = getBrowserWindow()?.location?.href;
|
|
1029
1188
|
if (!href) return null;
|
|
@@ -1034,7 +1193,7 @@ function getUrlParam2(name) {
|
|
|
1034
1193
|
}
|
|
1035
1194
|
}
|
|
1036
1195
|
function readStoredSession(persistence) {
|
|
1037
|
-
const rawSession = persistence.getItem(
|
|
1196
|
+
const rawSession = persistence.getItem(SESSION_STORAGE_KEY2);
|
|
1038
1197
|
if (!rawSession) return void 0;
|
|
1039
1198
|
try {
|
|
1040
1199
|
const parsed = JSON.parse(rawSession);
|
|
@@ -1045,12 +1204,12 @@ function readStoredSession(persistence) {
|
|
|
1045
1204
|
};
|
|
1046
1205
|
}
|
|
1047
1206
|
} catch {
|
|
1048
|
-
persistence.removeItem(
|
|
1207
|
+
persistence.removeItem(SESSION_STORAGE_KEY2);
|
|
1049
1208
|
}
|
|
1050
1209
|
return void 0;
|
|
1051
1210
|
}
|
|
1052
1211
|
function writeStoredSession(persistence, sessionId, timestamp) {
|
|
1053
|
-
persistence.setItem(
|
|
1212
|
+
persistence.setItem(SESSION_STORAGE_KEY2, JSON.stringify({ sessionId, timestamp }));
|
|
1054
1213
|
}
|
|
1055
1214
|
function createSessionManager(persistence, idleTimeoutSeconds = 30 * 60) {
|
|
1056
1215
|
function resolveSessionId() {
|
|
@@ -1104,11 +1263,12 @@ var DriveMetaDataSDK = class {
|
|
|
1104
1263
|
requireConfigString(config.writeKey || config.token, "writeKey or token");
|
|
1105
1264
|
this.config = config;
|
|
1106
1265
|
this.endpoint = endpointFromConfig(config);
|
|
1107
|
-
|
|
1266
|
+
const storagePersistence = createBrowserPersistence(config.persistence);
|
|
1267
|
+
this.persistence = createDmdAttributesPersistence(storagePersistence);
|
|
1108
1268
|
this.session = createSessionManager(this.persistence, config.sessionIdleTimeoutSeconds);
|
|
1109
1269
|
const deliveryConfig = {
|
|
1110
1270
|
endpoint: this.endpoint,
|
|
1111
|
-
storage:
|
|
1271
|
+
storage: storagePersistence
|
|
1112
1272
|
};
|
|
1113
1273
|
if (config.delivery?.maxQueueSize !== void 0) deliveryConfig.maxQueueSize = config.delivery.maxQueueSize;
|
|
1114
1274
|
if (config.delivery?.queueTtlMs !== void 0) deliveryConfig.queueTtlMs = config.delivery.queueTtlMs;
|
|
@@ -1353,6 +1513,7 @@ var DriveMetaDataSDK = class {
|
|
|
1353
1513
|
}
|
|
1354
1514
|
toCollectorPayload(prepared) {
|
|
1355
1515
|
const browserWindow = getBrowserWindow();
|
|
1516
|
+
const pageContext = getBrowserPageContext();
|
|
1356
1517
|
return createBackendCollectorPayload({
|
|
1357
1518
|
requestId: prepared.messageId,
|
|
1358
1519
|
timestamp: prepared.timestamp,
|
|
@@ -1364,9 +1525,13 @@ var DriveMetaDataSDK = class {
|
|
|
1364
1525
|
sessionId: prepared.sessionId,
|
|
1365
1526
|
ua: browserWindow?.navigator?.userAgent,
|
|
1366
1527
|
appId: prepared.appId,
|
|
1367
|
-
pageUrl: browserWindow?.location?.href,
|
|
1528
|
+
pageUrl: pageContext.url ?? browserWindow?.location?.href,
|
|
1368
1529
|
eventData: mergeStoredAttribution({
|
|
1369
1530
|
...prepared.properties,
|
|
1531
|
+
page: {
|
|
1532
|
+
...pageContext,
|
|
1533
|
+
...prepared.properties.page && typeof prepared.properties.page === "object" ? prepared.properties.page : {}
|
|
1534
|
+
},
|
|
1370
1535
|
anonymousId: prepared.anonymousId,
|
|
1371
1536
|
sessionId: prepared.sessionId,
|
|
1372
1537
|
timestamp: prepared.timestamp,
|