@drivemetadata-ai/sdk 0.1.1-beta.1 → 0.1.1-beta.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/README.md +18 -15
- package/dist/angular/index.cjs +118 -115
- package/dist/angular/index.cjs.map +1 -1
- package/dist/angular/index.d.cts +2 -2
- package/dist/angular/index.d.ts +2 -2
- package/dist/angular/index.js +118 -115
- package/dist/angular/index.js.map +1 -1
- package/dist/browser/index.cjs +119 -116
- package/dist/browser/index.cjs.map +1 -1
- package/dist/browser/index.d.cts +5 -68
- package/dist/browser/index.d.ts +5 -68
- package/dist/browser/index.js +119 -116
- package/dist/browser/index.js.map +1 -1
- package/dist/next/index.cjs +119 -115
- package/dist/next/index.cjs.map +1 -1
- package/dist/next/index.d.cts +1 -1
- package/dist/next/index.d.ts +1 -1
- package/dist/next/index.js +119 -115
- package/dist/next/index.js.map +1 -1
- package/dist/node/index.cjs +80 -7
- package/dist/node/index.cjs.map +1 -1
- package/dist/node/index.d.cts +7 -1
- package/dist/node/index.d.ts +7 -1
- package/dist/node/index.js +80 -7
- package/dist/node/index.js.map +1 -1
- package/dist/react/index.cjs +119 -115
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.cts +2 -2
- package/dist/react/index.d.ts +2 -2
- package/dist/react/index.js +119 -115
- package/dist/react/index.js.map +1 -1
- package/dist/{types-BwtS0ZDu.d.cts → types--V8TVIqT.d.cts} +7 -3
- package/dist/{types-BwtS0ZDu.d.ts → types--V8TVIqT.d.ts} +7 -3
- package/docs/angular-integration.md +6 -6
- package/docs/index.md +4 -6
- package/docs/integration.md +322 -0
- package/docs/node-server-integration.md +16 -7
- package/docs/npm-browser-sdk.md +4 -8
- package/docs/react-next-integration.md +9 -9
- package/docs/security-privacy.md +11 -11
- package/package.json +4 -5
- package/docs/migration-cdn-to-npm.md +0 -99
package/dist/react/index.js
CHANGED
|
@@ -1,53 +1,62 @@
|
|
|
1
1
|
// src/react/DmdProvider.tsx
|
|
2
2
|
import React from "react";
|
|
3
3
|
|
|
4
|
-
// src/core/
|
|
5
|
-
function
|
|
6
|
-
if (typeof value !== "string"
|
|
7
|
-
|
|
4
|
+
// src/core/backend-payload.ts
|
|
5
|
+
function formatUtcTimestamp(value) {
|
|
6
|
+
if (typeof value !== "string") return (/* @__PURE__ */ new Date()).toISOString().replace("T", " ").slice(0, 19);
|
|
7
|
+
const date = new Date(value);
|
|
8
|
+
if (Number.isNaN(date.getTime())) return value;
|
|
9
|
+
return date.toISOString().replace("T", " ").slice(0, 19);
|
|
10
|
+
}
|
|
11
|
+
function cleanObject(value) {
|
|
12
|
+
if (Array.isArray(value)) {
|
|
13
|
+
const cleaned = value.map((item) => cleanObject(item)).filter((item) => item !== null && item !== void 0 && item !== "");
|
|
14
|
+
return cleaned.length > 0 ? cleaned : void 0;
|
|
15
|
+
}
|
|
16
|
+
if (value && typeof value === "object") {
|
|
17
|
+
const cleaned = Object.fromEntries(
|
|
18
|
+
Object.entries(value).map(([key, item]) => [key, cleanObject(item)]).filter(([, item]) => {
|
|
19
|
+
if (item === null || item === void 0 || item === "") return false;
|
|
20
|
+
if (typeof item === "object" && !Array.isArray(item) && Object.keys(item).length === 0) return false;
|
|
21
|
+
return true;
|
|
22
|
+
})
|
|
23
|
+
);
|
|
24
|
+
return Object.keys(cleaned).length > 0 ? cleaned : void 0;
|
|
8
25
|
}
|
|
9
26
|
return value;
|
|
10
27
|
}
|
|
11
|
-
function
|
|
12
|
-
const
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
28
|
+
function createBackendCollectorPayload(input) {
|
|
29
|
+
const eventData = input.eventData && typeof input.eventData === "object" ? input.eventData : {};
|
|
30
|
+
const page2 = eventData.page && typeof eventData.page === "object" ? eventData.page : {};
|
|
31
|
+
const timestamp = formatUtcTimestamp(eventData.timestamp ?? input.timestamp);
|
|
32
|
+
const normalizedEventData = {
|
|
33
|
+
...eventData,
|
|
34
|
+
timestamp,
|
|
35
|
+
requestSentAt: formatUtcTimestamp(eventData.requestSentAt ?? input.requestSentAt ?? timestamp),
|
|
36
|
+
requestReceivedAt: formatUtcTimestamp(eventData.requestReceivedAt ?? input.requestReceivedAt ?? timestamp)
|
|
37
|
+
};
|
|
38
|
+
const metaData = {
|
|
39
|
+
...normalizedEventData,
|
|
40
|
+
requestId: input.requestId,
|
|
41
|
+
timestamp,
|
|
42
|
+
eventType: input.eventType,
|
|
43
|
+
requestFrom: input.requestFrom ?? "3",
|
|
44
|
+
clientId: input.clientId,
|
|
45
|
+
workspaceId: input.workspaceId,
|
|
46
|
+
token: input.token,
|
|
47
|
+
anonymousId: eventData.anonymousId ?? input.anonymousId,
|
|
48
|
+
sessionId: eventData.sessionId ?? input.sessionId,
|
|
49
|
+
ua: input.ua,
|
|
50
|
+
appDetails: { app_id: input.appId },
|
|
51
|
+
page: { ...page2, url: page2.url ?? input.pageUrl },
|
|
52
|
+
requestSentAt: normalizedEventData.requestSentAt,
|
|
53
|
+
requestReceivedAt: normalizedEventData.requestReceivedAt
|
|
18
54
|
};
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
if (config.deeplink !== void 0) legacyConfig.deeplink = config.deeplink;
|
|
22
|
-
if (config.debug !== void 0) legacyConfig.debug = config.debug;
|
|
23
|
-
if (config.consent !== void 0) legacyConfig.consent = config.consent;
|
|
24
|
-
if (config.gdprConsent !== void 0) legacyConfig.gdprConsent = config.gdprConsent;
|
|
25
|
-
if (config.autocapture !== void 0) legacyConfig.autocapture = config.autocapture;
|
|
26
|
-
if (config.capturePageview !== void 0) legacyConfig.capture_pageview = config.capturePageview;
|
|
27
|
-
if (config.capturePageleave !== void 0) legacyConfig.capture_pageleave = config.capturePageleave;
|
|
28
|
-
if (config.captureDeadClicks !== void 0) legacyConfig.capture_dead_clicks = config.captureDeadClicks;
|
|
29
|
-
if (config.crossSubdomainCookie !== void 0) legacyConfig.cross_subdomain_cookie = config.crossSubdomainCookie;
|
|
30
|
-
if (config.disablePersistence !== void 0) legacyConfig.disable_persistence = config.disablePersistence;
|
|
31
|
-
if (config.disableSurveys !== void 0) legacyConfig.disable_surveys = config.disableSurveys;
|
|
32
|
-
if (config.disableSessionRecording !== void 0) legacyConfig.disable_session_recording = config.disableSessionRecording;
|
|
33
|
-
if (config.enableHeatmaps !== void 0) legacyConfig.enable_heatmaps = config.enableHeatmaps;
|
|
34
|
-
if (config.maskAllText !== void 0) legacyConfig.mask_all_text = config.maskAllText;
|
|
35
|
-
if (config.maskAllElementAttributes !== void 0) {
|
|
36
|
-
legacyConfig.mask_all_element_attributes = config.maskAllElementAttributes;
|
|
37
|
-
}
|
|
38
|
-
if (config.persistence !== void 0) legacyConfig.persistence = config.persistence;
|
|
39
|
-
if (config.propertyDenylist !== void 0) legacyConfig.property_denylist = config.propertyDenylist;
|
|
40
|
-
if (config.sessionIdleTimeoutSeconds !== void 0) {
|
|
41
|
-
legacyConfig.session_idle_timeout_seconds = config.sessionIdleTimeoutSeconds;
|
|
42
|
-
}
|
|
43
|
-
if (config.beforeSend !== void 0) legacyConfig.before_send = config.beforeSend;
|
|
44
|
-
return legacyConfig;
|
|
55
|
+
const payload = { metaData };
|
|
56
|
+
return cleanObject(payload);
|
|
45
57
|
}
|
|
46
58
|
|
|
47
59
|
// src/core/environment.ts
|
|
48
|
-
function isBrowserRuntime() {
|
|
49
|
-
return typeof window !== "undefined" && typeof document !== "undefined";
|
|
50
|
-
}
|
|
51
60
|
function getBrowserWindow() {
|
|
52
61
|
return typeof window === "undefined" ? void 0 : window;
|
|
53
62
|
}
|
|
@@ -107,8 +116,9 @@ function stableStringify(value) {
|
|
|
107
116
|
);
|
|
108
117
|
}
|
|
109
118
|
function createIdempotencyKey(payload, messageId) {
|
|
110
|
-
const
|
|
111
|
-
const
|
|
119
|
+
const metaData = payload.metaData;
|
|
120
|
+
const event = String(metaData?.eventType ?? payload.event ?? payload.type ?? "event");
|
|
121
|
+
const properties = metaData ?? payload.properties;
|
|
112
122
|
const orderId = properties?.orderId ?? properties?.order_id ?? properties?.transaction_id;
|
|
113
123
|
if (orderId !== void 0) return `${event}:${String(orderId)}`;
|
|
114
124
|
return `${event}:${stableStringify(properties ?? {}) || messageId}`;
|
|
@@ -209,7 +219,17 @@ function createDeliveryManager(config) {
|
|
|
209
219
|
persistQueue();
|
|
210
220
|
}
|
|
211
221
|
function withEnvelope(payload) {
|
|
212
|
-
const
|
|
222
|
+
const metaData = payload.metaData;
|
|
223
|
+
const messageId = String(metaData?.requestId ?? payload.messageId ?? createId("msg"));
|
|
224
|
+
if (metaData) {
|
|
225
|
+
return {
|
|
226
|
+
...payload,
|
|
227
|
+
metaData: {
|
|
228
|
+
...metaData,
|
|
229
|
+
requestId: messageId
|
|
230
|
+
}
|
|
231
|
+
};
|
|
232
|
+
}
|
|
213
233
|
return {
|
|
214
234
|
...payload,
|
|
215
235
|
messageId,
|
|
@@ -235,7 +255,7 @@ function createDeliveryManager(config) {
|
|
|
235
255
|
const body = withEnvelope(payload);
|
|
236
256
|
if (payloadByteLength(body) > maxPayloadBytes) {
|
|
237
257
|
recordDrop({
|
|
238
|
-
messageId: String(body.messageId),
|
|
258
|
+
messageId: String(body.metaData?.requestId ?? body.messageId),
|
|
239
259
|
reason: "payload_too_large",
|
|
240
260
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
241
261
|
});
|
|
@@ -248,7 +268,7 @@ function createDeliveryManager(config) {
|
|
|
248
268
|
const deliveryError = error instanceof Error ? error : new Error(String(error));
|
|
249
269
|
recordError(deliveryError);
|
|
250
270
|
enqueue({
|
|
251
|
-
messageId: String(body.messageId),
|
|
271
|
+
messageId: String(body.metaData?.requestId ?? body.messageId),
|
|
252
272
|
savedAt: Date.now(),
|
|
253
273
|
attempts: 1,
|
|
254
274
|
lastError: deliveryError.message,
|
|
@@ -423,6 +443,12 @@ function endpointFromConfig(config) {
|
|
|
423
443
|
const host = config.apiHost ?? "https://sdk.drivemetadata.com/v2";
|
|
424
444
|
return `${host.replace(/\/$/, "")}/data-collector`;
|
|
425
445
|
}
|
|
446
|
+
function requireConfigString(value, field) {
|
|
447
|
+
if (typeof value !== "string" || value.trim() === "") {
|
|
448
|
+
throw new Error(`DMD SDK config ${field} is required`);
|
|
449
|
+
}
|
|
450
|
+
return value;
|
|
451
|
+
}
|
|
426
452
|
function getBrowserStorage() {
|
|
427
453
|
const browserWindow = getBrowserWindow();
|
|
428
454
|
try {
|
|
@@ -437,6 +463,10 @@ var DriveMetaDataSDK = class {
|
|
|
437
463
|
this.queue = [];
|
|
438
464
|
this.offline = false;
|
|
439
465
|
this.droppedEvents = 0;
|
|
466
|
+
requireConfigString(config.clientId, "clientId");
|
|
467
|
+
requireConfigString(config.workspaceId, "workspaceId");
|
|
468
|
+
requireConfigString(config.appId, "appId");
|
|
469
|
+
requireConfigString(config.writeKey || config.token, "writeKey or token");
|
|
440
470
|
this.config = config;
|
|
441
471
|
this.endpoint = endpointFromConfig(config);
|
|
442
472
|
const storage = getBrowserStorage();
|
|
@@ -460,6 +490,7 @@ var DriveMetaDataSDK = class {
|
|
|
460
490
|
this.maxRetryDelayMs = config.delivery?.maxRetryDelayMs ?? 3e4;
|
|
461
491
|
this.writeKey = config.writeKey || config.token || "";
|
|
462
492
|
this.identity = { anonymousId: createId2("anon") };
|
|
493
|
+
this.sessionId = createId2("session");
|
|
463
494
|
this.consentState = normalizeConsent(config.gdprConsent ?? config.consent);
|
|
464
495
|
this.gdprConsent = this.consentState.analytics;
|
|
465
496
|
if (!config.delivery?.disableLifecycleFlush) {
|
|
@@ -605,7 +636,8 @@ var DriveMetaDataSDK = class {
|
|
|
605
636
|
workspaceId: this.config.workspaceId,
|
|
606
637
|
appId: this.config.appId,
|
|
607
638
|
writeKey: this.writeKey,
|
|
608
|
-
consent: this.consentState
|
|
639
|
+
consent: this.consentState,
|
|
640
|
+
sessionId: this.sessionId
|
|
609
641
|
};
|
|
610
642
|
if (this.identity.userId !== void 0) prepared.userId = this.identity.userId;
|
|
611
643
|
if (this.identity.groupId !== void 0) prepared.groupId = this.identity.groupId;
|
|
@@ -629,7 +661,31 @@ var DriveMetaDataSDK = class {
|
|
|
629
661
|
if (!validation.ok) {
|
|
630
662
|
this.lastError = `DMD SDK schema warning: ${validation.errors.join(", ")}`;
|
|
631
663
|
}
|
|
632
|
-
this.sendEvent(prepared);
|
|
664
|
+
this.sendEvent(this.toCollectorPayload(prepared));
|
|
665
|
+
}
|
|
666
|
+
toCollectorPayload(prepared) {
|
|
667
|
+
const browserWindow = getBrowserWindow();
|
|
668
|
+
return createBackendCollectorPayload({
|
|
669
|
+
requestId: prepared.messageId,
|
|
670
|
+
timestamp: prepared.timestamp,
|
|
671
|
+
eventType: prepared.event,
|
|
672
|
+
clientId: prepared.clientId,
|
|
673
|
+
workspaceId: prepared.workspaceId,
|
|
674
|
+
token: prepared.writeKey,
|
|
675
|
+
anonymousId: prepared.anonymousId,
|
|
676
|
+
sessionId: prepared.sessionId,
|
|
677
|
+
ua: browserWindow?.navigator?.userAgent,
|
|
678
|
+
appId: prepared.appId,
|
|
679
|
+
pageUrl: browserWindow?.location?.href,
|
|
680
|
+
eventData: {
|
|
681
|
+
...prepared.properties,
|
|
682
|
+
anonymousId: prepared.anonymousId,
|
|
683
|
+
sessionId: prepared.sessionId,
|
|
684
|
+
timestamp: prepared.timestamp,
|
|
685
|
+
requestSentAt: prepared.timestamp,
|
|
686
|
+
requestReceivedAt: prepared.timestamp
|
|
687
|
+
}
|
|
688
|
+
});
|
|
633
689
|
}
|
|
634
690
|
recordDrop(type, reason, event) {
|
|
635
691
|
this.droppedEvents += 1;
|
|
@@ -643,22 +699,6 @@ var DriveMetaDataSDK = class {
|
|
|
643
699
|
}
|
|
644
700
|
};
|
|
645
701
|
|
|
646
|
-
// src/browser/legacy-loader.ts
|
|
647
|
-
function getLegacySdkInstanceFromWindow() {
|
|
648
|
-
const browserWindow = getBrowserWindow();
|
|
649
|
-
return browserWindow?.__DriveMetaDataSDKInstance;
|
|
650
|
-
}
|
|
651
|
-
function ensureLegacySdkLoaded() {
|
|
652
|
-
if (!isBrowserRuntime()) {
|
|
653
|
-
throw new Error("DMD legacy SDK is only available in a browser runtime");
|
|
654
|
-
}
|
|
655
|
-
const browserWindow = getBrowserWindow();
|
|
656
|
-
if (!browserWindow?.DriveMetaDataSDK) {
|
|
657
|
-
throw new Error("DMD legacy SDK constructor is missing from window.DriveMetaDataSDK");
|
|
658
|
-
}
|
|
659
|
-
return browserWindow.DriveMetaDataSDK;
|
|
660
|
-
}
|
|
661
|
-
|
|
662
702
|
// src/browser/client.ts
|
|
663
703
|
var singleton;
|
|
664
704
|
var publicSingleton;
|
|
@@ -667,56 +707,34 @@ var lastError;
|
|
|
667
707
|
var lastDroppedEvent;
|
|
668
708
|
function createPublicClient(instance) {
|
|
669
709
|
return {
|
|
670
|
-
__legacy: instance,
|
|
671
710
|
track(event, properties, options) {
|
|
672
|
-
|
|
673
|
-
instance.trackEvent(event, properties, options);
|
|
674
|
-
return;
|
|
675
|
-
}
|
|
676
|
-
instance.sendEvent?.({ eventName: event, event, properties, options });
|
|
711
|
+
instance.trackEvent(event, properties, options);
|
|
677
712
|
},
|
|
678
713
|
identify(userId, traits, options) {
|
|
679
|
-
|
|
680
|
-
instance.identify(userId, traits, options);
|
|
681
|
-
return;
|
|
682
|
-
}
|
|
683
|
-
instance.identifyUser?.(userId, traits);
|
|
714
|
+
instance.identify(userId, traits, options);
|
|
684
715
|
},
|
|
685
716
|
page(name, properties, options) {
|
|
686
|
-
|
|
687
|
-
instance.page(name, properties, options);
|
|
688
|
-
return;
|
|
689
|
-
}
|
|
690
|
-
instance.trackPageview?.();
|
|
717
|
+
instance.page(name, properties, options);
|
|
691
718
|
},
|
|
692
719
|
group(groupId, traits, options) {
|
|
693
|
-
instance.group
|
|
720
|
+
instance.group(groupId, traits, options);
|
|
694
721
|
},
|
|
695
722
|
alias(previousId, userId, options) {
|
|
696
|
-
instance.alias
|
|
723
|
+
instance.alias(previousId, userId, options);
|
|
697
724
|
},
|
|
698
725
|
async flush() {
|
|
699
|
-
await instance.flush
|
|
726
|
+
await instance.flush();
|
|
700
727
|
},
|
|
701
728
|
reset() {
|
|
702
|
-
instance.reset
|
|
729
|
+
instance.reset();
|
|
703
730
|
singleton = void 0;
|
|
704
731
|
publicSingleton = void 0;
|
|
705
732
|
},
|
|
706
733
|
setConsent(consent) {
|
|
707
|
-
|
|
708
|
-
instance.setConsent(consent);
|
|
709
|
-
return;
|
|
710
|
-
}
|
|
711
|
-
if (typeof consent === "string") {
|
|
712
|
-
instance.gdprConsent = consent;
|
|
713
|
-
}
|
|
734
|
+
instance.setConsent(consent);
|
|
714
735
|
},
|
|
715
736
|
getHealth() {
|
|
716
|
-
|
|
717
|
-
return instance.getHealth();
|
|
718
|
-
}
|
|
719
|
-
return getDmdHealth();
|
|
737
|
+
return instance.getHealth();
|
|
720
738
|
}
|
|
721
739
|
};
|
|
722
740
|
}
|
|
@@ -741,23 +759,8 @@ function initDmdSDK(config) {
|
|
|
741
759
|
if (publicSingleton) {
|
|
742
760
|
return publicSingleton;
|
|
743
761
|
}
|
|
744
|
-
const legacyConfig = normalizeBrowserConfig(config);
|
|
745
|
-
const existingInstance = getLegacySdkInstanceFromWindow();
|
|
746
|
-
if (existingInstance) {
|
|
747
|
-
return setSingleton(existingInstance);
|
|
748
|
-
}
|
|
749
762
|
try {
|
|
750
|
-
|
|
751
|
-
try {
|
|
752
|
-
const LegacySdk = ensureLegacySdkLoaded();
|
|
753
|
-
instance = new LegacySdk(legacyConfig);
|
|
754
|
-
} catch (error) {
|
|
755
|
-
if (error instanceof Error && error.message.includes("constructor is missing")) {
|
|
756
|
-
instance = new DriveMetaDataSDK(config);
|
|
757
|
-
} else {
|
|
758
|
-
throw error;
|
|
759
|
-
}
|
|
760
|
-
}
|
|
763
|
+
const instance = new DriveMetaDataSDK(config);
|
|
761
764
|
return setSingleton(instance);
|
|
762
765
|
} catch (error) {
|
|
763
766
|
lastError = error instanceof Error ? error.message : String(error);
|
|
@@ -824,14 +827,14 @@ function setConsent(consent) {
|
|
|
824
827
|
getDmdSDK()?.setConsent(consent);
|
|
825
828
|
}
|
|
826
829
|
function getDmdHealth() {
|
|
827
|
-
if (singleton
|
|
830
|
+
if (singleton) {
|
|
828
831
|
return singleton.getHealth();
|
|
829
832
|
}
|
|
830
833
|
const health = {
|
|
831
|
-
initialized:
|
|
832
|
-
consent:
|
|
833
|
-
queueSize:
|
|
834
|
-
offline:
|
|
834
|
+
initialized: false,
|
|
835
|
+
consent: "pending",
|
|
836
|
+
queueSize: 0,
|
|
837
|
+
offline: false,
|
|
835
838
|
droppedEvents
|
|
836
839
|
};
|
|
837
840
|
if (lastError !== void 0) {
|
|
@@ -874,6 +877,7 @@ function DmdProvider({
|
|
|
874
877
|
config.workspaceId,
|
|
875
878
|
config.appId,
|
|
876
879
|
config.writeKey,
|
|
880
|
+
config.token,
|
|
877
881
|
config.apiHost,
|
|
878
882
|
config.consent,
|
|
879
883
|
config.gdprConsent,
|