humanbehavior-js 0.4.19 → 0.4.21
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/cjs/angular/index.cjs +799 -13
- package/dist/cjs/angular/index.cjs.map +1 -1
- package/dist/cjs/index.cjs +815 -13
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/install-wizard.cjs +56 -10
- package/dist/cjs/install-wizard.cjs.map +1 -1
- package/dist/cjs/react/index.cjs +800 -14
- package/dist/cjs/react/index.cjs.map +1 -1
- package/dist/cjs/remix/index.cjs +800 -14
- package/dist/cjs/remix/index.cjs.map +1 -1
- package/dist/cjs/svelte/index.cjs +799 -13
- package/dist/cjs/svelte/index.cjs.map +1 -1
- package/dist/cjs/vue/index.cjs +799 -13
- package/dist/cjs/vue/index.cjs.map +1 -1
- package/dist/cjs/wizard/index.cjs +56 -10
- package/dist/cjs/wizard/index.cjs.map +1 -1
- package/dist/cli/ai-auto-install.js +56 -10
- package/dist/cli/ai-auto-install.js.map +1 -1
- package/dist/cli/auto-install.js +56 -10
- package/dist/cli/auto-install.js.map +1 -1
- package/dist/esm/angular/index.js +799 -13
- package/dist/esm/angular/index.js.map +1 -1
- package/dist/esm/index.js +807 -14
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/install-wizard.js +56 -10
- package/dist/esm/install-wizard.js.map +1 -1
- package/dist/esm/react/index.js +800 -14
- package/dist/esm/react/index.js.map +1 -1
- package/dist/esm/remix/index.js +800 -14
- package/dist/esm/remix/index.js.map +1 -1
- package/dist/esm/svelte/index.js +799 -13
- package/dist/esm/svelte/index.js.map +1 -1
- package/dist/esm/vue/index.js +799 -13
- package/dist/esm/vue/index.js.map +1 -1
- package/dist/esm/wizard/index.js +56 -10
- package/dist/esm/wizard/index.js.map +1 -1
- package/dist/index.min.js +1 -1
- package/dist/index.min.js.map +1 -1
- package/dist/types/angular/index.d.ts +60 -1
- package/dist/types/index.d.ts +258 -3
- package/dist/types/react/index.d.ts +60 -1
- package/dist/types/remix/index.d.ts +60 -1
- package/dist/types/svelte/index.d.ts +60 -1
- package/package/canvas-recording-demo.html +1 -1
- package/package/simple-spa.html +1 -1
- package/package/src/angular/index.ts +3 -3
- package/package/src/react/index.tsx +2 -2
- package/package/src/svelte/index.ts +1 -1
- package/package/src/tracker.ts +2 -2
- package/package/src/vue/index.ts +1 -1
- package/package.json +1 -1
- package/simple-spa.html +164 -2
- package/src/angular/index.ts +3 -3
- package/src/api.ts +40 -0
- package/src/index.ts +7 -0
- package/src/react/index.tsx +2 -2
- package/src/svelte/index.ts +1 -1
- package/src/tracker.ts +175 -11
- package/src/utils/ip-detector.ts +158 -0
- package/src/utils/property-detector.ts +345 -0
- package/src/utils/property-manager.ts +274 -0
- package/src/vue/index.ts +1 -1
- package/src/wizard/core/install-wizard.ts +60 -10
- package/canvas-recording-demo.html +0 -143
- package/clean-console-demo.html +0 -39
- package/simple-demo.html +0 -26
|
@@ -698,8 +698,17 @@ export default defineNuxtPlugin(() => {
|
|
|
698
698
|
});
|
|
699
699
|
}
|
|
700
700
|
|
|
701
|
-
// Handle Angular environment
|
|
701
|
+
// Handle Angular environment files (proper Angular way)
|
|
702
702
|
const envFile = path.join(this.projectRoot, 'src', 'environments', 'environment.ts');
|
|
703
|
+
const envProdFile = path.join(this.projectRoot, 'src', 'environments', 'environment.prod.ts');
|
|
704
|
+
|
|
705
|
+
// Create environments directory if it doesn't exist
|
|
706
|
+
const envDir = path.dirname(envFile);
|
|
707
|
+
if (!fs.existsSync(envDir)) {
|
|
708
|
+
fs.mkdirSync(envDir, { recursive: true });
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
// Create or update development environment
|
|
703
712
|
if (fs.existsSync(envFile)) {
|
|
704
713
|
const content = fs.readFileSync(envFile, 'utf8');
|
|
705
714
|
if (!content.includes('humanBehaviorApiKey')) {
|
|
@@ -707,20 +716,62 @@ export default defineNuxtPlugin(() => {
|
|
|
707
716
|
/export const environment = {([\s\S]*?)};/,
|
|
708
717
|
`export const environment = {
|
|
709
718
|
$1,
|
|
710
|
-
humanBehaviorApiKey:
|
|
719
|
+
humanBehaviorApiKey: '${this.apiKey}'
|
|
711
720
|
};`
|
|
712
721
|
);
|
|
713
722
|
modifications.push({
|
|
714
723
|
filePath: envFile,
|
|
715
724
|
action: 'modify',
|
|
716
725
|
content: modifiedContent,
|
|
717
|
-
description: 'Added API key to Angular environment'
|
|
726
|
+
description: 'Added API key to Angular development environment'
|
|
727
|
+
});
|
|
728
|
+
}
|
|
729
|
+
} else {
|
|
730
|
+
// Create new development environment file
|
|
731
|
+
modifications.push({
|
|
732
|
+
filePath: envFile,
|
|
733
|
+
action: 'create',
|
|
734
|
+
content: `export const environment = {
|
|
735
|
+
production: false,
|
|
736
|
+
humanBehaviorApiKey: '${this.apiKey}'
|
|
737
|
+
};`,
|
|
738
|
+
description: 'Created Angular development environment file'
|
|
739
|
+
});
|
|
740
|
+
}
|
|
741
|
+
|
|
742
|
+
// Create or update production environment
|
|
743
|
+
if (fs.existsSync(envProdFile)) {
|
|
744
|
+
const content = fs.readFileSync(envProdFile, 'utf8');
|
|
745
|
+
if (!content.includes('humanBehaviorApiKey')) {
|
|
746
|
+
const modifiedContent = content.replace(
|
|
747
|
+
/export const environment = {([\s\S]*?)};/,
|
|
748
|
+
`export const environment = {
|
|
749
|
+
$1,
|
|
750
|
+
humanBehaviorApiKey: '${this.apiKey}'
|
|
751
|
+
};`
|
|
752
|
+
);
|
|
753
|
+
modifications.push({
|
|
754
|
+
filePath: envProdFile,
|
|
755
|
+
action: 'modify',
|
|
756
|
+
content: modifiedContent,
|
|
757
|
+
description: 'Added API key to Angular production environment'
|
|
718
758
|
});
|
|
719
759
|
}
|
|
760
|
+
} else {
|
|
761
|
+
// Create new production environment file
|
|
762
|
+
modifications.push({
|
|
763
|
+
filePath: envProdFile,
|
|
764
|
+
action: 'create',
|
|
765
|
+
content: `export const environment = {
|
|
766
|
+
production: true,
|
|
767
|
+
humanBehaviorApiKey: '${this.apiKey}'
|
|
768
|
+
};`,
|
|
769
|
+
description: 'Created Angular production environment file'
|
|
770
|
+
});
|
|
720
771
|
}
|
|
721
772
|
|
|
722
|
-
//
|
|
723
|
-
|
|
773
|
+
// For Angular, we don't need .env files since we use environment.ts
|
|
774
|
+
// The environment files are already created above
|
|
724
775
|
|
|
725
776
|
return modifications;
|
|
726
777
|
}
|
|
@@ -1255,11 +1306,12 @@ export default function App()`
|
|
|
1255
1306
|
}
|
|
1256
1307
|
|
|
1257
1308
|
const importStatement = `import { initializeHumanBehavior } from 'humanbehavior-js/angular';`;
|
|
1309
|
+
const environmentImport = `import { environment } from './environments/environment';`;
|
|
1258
1310
|
|
|
1259
|
-
// Add
|
|
1311
|
+
// Add imports at the top
|
|
1260
1312
|
let modifiedContent = content.replace(
|
|
1261
1313
|
/import.*from.*['"]@angular/,
|
|
1262
|
-
`${importStatement}\n$&`
|
|
1314
|
+
`${importStatement}\n${environmentImport}\n$&`
|
|
1263
1315
|
);
|
|
1264
1316
|
|
|
1265
1317
|
// Add initialization after bootstrapApplication
|
|
@@ -1269,9 +1321,7 @@ export default function App()`
|
|
|
1269
1321
|
|
|
1270
1322
|
// Initialize HumanBehavior SDK (client-side only)
|
|
1271
1323
|
if (typeof window !== 'undefined') {
|
|
1272
|
-
const tracker = initializeHumanBehavior(
|
|
1273
|
-
'${this.apiKey}'
|
|
1274
|
-
);
|
|
1324
|
+
const tracker = initializeHumanBehavior(environment.humanBehaviorApiKey);
|
|
1275
1325
|
}`
|
|
1276
1326
|
);
|
|
1277
1327
|
|
|
@@ -1,143 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="UTF-8">
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
-
<title>HumanBehavior Canvas Recording Demo</title>
|
|
7
|
-
<style>
|
|
8
|
-
body { font-family: Arial, sans-serif; margin: 20px; }
|
|
9
|
-
.demo-section { margin: 20px 0; padding: 20px; border: 1px solid #ccc; }
|
|
10
|
-
canvas { border: 2px solid #333; margin: 10px; }
|
|
11
|
-
button { padding: 10px 20px; margin: 5px; }
|
|
12
|
-
.info { background: #f0f0f0; padding: 10px; border-radius: 5px; }
|
|
13
|
-
</style>
|
|
14
|
-
</head>
|
|
15
|
-
<body>
|
|
16
|
-
<h1>HumanBehavior Canvas Recording Demo</h1>
|
|
17
|
-
|
|
18
|
-
<div class="info">
|
|
19
|
-
<h3>PostHog-Style Canvas Protection</h3>
|
|
20
|
-
<ul>
|
|
21
|
-
<li><strong>4 FPS Throttling:</strong> Prevents canvas overwhelm (vs 60 FPS default)</li>
|
|
22
|
-
<li><strong>40% Quality:</strong> WebP format with compression</li>
|
|
23
|
-
<li><strong>Opt-in Only:</strong> Disabled by default for safety</li>
|
|
24
|
-
<li><strong>Smart Sampling:</strong> Only captures when canvas changes</li>
|
|
25
|
-
</ul>
|
|
26
|
-
</div>
|
|
27
|
-
|
|
28
|
-
<div class="demo-section">
|
|
29
|
-
<h3>Canvas Drawing Demo</h3>
|
|
30
|
-
<canvas id="demoCanvas" width="400" height="300"></canvas>
|
|
31
|
-
<br>
|
|
32
|
-
<button onclick="drawRandom()">Draw Random Shape</button>
|
|
33
|
-
<button onclick="clearCanvas()">Clear Canvas</button>
|
|
34
|
-
<button onclick="animate()">Start Animation</button>
|
|
35
|
-
</div>
|
|
36
|
-
|
|
37
|
-
<div class="demo-section">
|
|
38
|
-
<h3>Canvas Recording Options</h3>
|
|
39
|
-
<button onclick="enableCanvasRecording()">Enable Canvas Recording</button>
|
|
40
|
-
<button onclick="disableCanvasRecording()">Disable Canvas Recording</button>
|
|
41
|
-
<p id="status">Canvas recording: <strong>Disabled</strong></p>
|
|
42
|
-
</div>
|
|
43
|
-
|
|
44
|
-
<script src="./dist/index.min.js"></script>
|
|
45
|
-
<script>
|
|
46
|
-
let tracker;
|
|
47
|
-
let canvas = document.getElementById('demoCanvas');
|
|
48
|
-
let ctx = canvas.getContext('2d');
|
|
49
|
-
let animationId;
|
|
50
|
-
|
|
51
|
-
// Initialize tracker without canvas recording
|
|
52
|
-
function initTracker(enableCanvas = false) {
|
|
53
|
-
tracker = HumanBehaviorTracker.init('13c3e029-ca45-4a3c-a33b-f5dcb297e31c', {
|
|
54
|
-
logLevel: 'warn',
|
|
55
|
-
suppressConsoleErrors: true,
|
|
56
|
-
recordCanvas: enableCanvas // PostHog-style protection
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
updateStatus();
|
|
60
|
-
console.log('✅ Tracker initialized with canvas recording:', enableCanvas);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
function updateStatus() {
|
|
64
|
-
const status = document.getElementById('status');
|
|
65
|
-
status.innerHTML = `Canvas recording: <strong>${tracker.recordCanvas ? 'Enabled' : 'Disabled'}</strong>`;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
function enableCanvasRecording() {
|
|
69
|
-
if (tracker) {
|
|
70
|
-
tracker.stop();
|
|
71
|
-
}
|
|
72
|
-
initTracker(true);
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
function disableCanvasRecording() {
|
|
76
|
-
if (tracker) {
|
|
77
|
-
tracker.stop();
|
|
78
|
-
}
|
|
79
|
-
initTracker(false);
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
function drawRandom() {
|
|
83
|
-
const colors = ['#FF6B6B', '#4ECDC4', '#45B7D1', '#96CEB4', '#FFEAA7'];
|
|
84
|
-
const color = colors[Math.floor(Math.random() * colors.length)];
|
|
85
|
-
|
|
86
|
-
ctx.fillStyle = color;
|
|
87
|
-
ctx.beginPath();
|
|
88
|
-
ctx.arc(
|
|
89
|
-
Math.random() * canvas.width,
|
|
90
|
-
Math.random() * canvas.height,
|
|
91
|
-
Math.random() * 50 + 10,
|
|
92
|
-
0,
|
|
93
|
-
2 * Math.PI
|
|
94
|
-
);
|
|
95
|
-
ctx.fill();
|
|
96
|
-
|
|
97
|
-
// Track the drawing event
|
|
98
|
-
if (tracker) {
|
|
99
|
-
tracker.customEvent('canvas_draw', {
|
|
100
|
-
color: color,
|
|
101
|
-
timestamp: Date.now()
|
|
102
|
-
});
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
function clearCanvas() {
|
|
107
|
-
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
|
108
|
-
|
|
109
|
-
if (tracker) {
|
|
110
|
-
tracker.customEvent('canvas_clear', {
|
|
111
|
-
timestamp: Date.now()
|
|
112
|
-
});
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
function animate() {
|
|
117
|
-
let angle = 0;
|
|
118
|
-
|
|
119
|
-
function animateFrame() {
|
|
120
|
-
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
|
121
|
-
|
|
122
|
-
// Draw rotating rectangle
|
|
123
|
-
ctx.save();
|
|
124
|
-
ctx.translate(canvas.width / 2, canvas.height / 2);
|
|
125
|
-
ctx.rotate(angle);
|
|
126
|
-
ctx.fillStyle = '#FF6B6B';
|
|
127
|
-
ctx.fillRect(-25, -25, 50, 50);
|
|
128
|
-
ctx.restore();
|
|
129
|
-
|
|
130
|
-
angle += 0.02;
|
|
131
|
-
animationId = requestAnimationFrame(animateFrame);
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
animateFrame();
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
// Initialize tracker on page load
|
|
138
|
-
initTracker(false);
|
|
139
|
-
|
|
140
|
-
console.log('🎨 Canvas demo ready! Try drawing or enabling canvas recording.');
|
|
141
|
-
</script>
|
|
142
|
-
</body>
|
|
143
|
-
</html>
|
package/clean-console-demo.html
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="UTF-8">
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
-
<title>HumanBehavior Clean Console Demo</title>
|
|
7
|
-
</head>
|
|
8
|
-
<body>
|
|
9
|
-
<h1>HumanBehavior Clean Console Demo</h1>
|
|
10
|
-
<p>This demo shows how to suppress common rrweb errors for a clean console.</p>
|
|
11
|
-
|
|
12
|
-
<!-- External images that would normally cause CORS errors -->
|
|
13
|
-
<img src="https://img.lumas.com/showimg_rwt01_search.jpg" alt="External image 1" style="width: 100px; height: 100px;">
|
|
14
|
-
<img src="https://media.lumas.de/homepage/2024/magazine-kachel-300x400.webp" alt="External image 2" style="width: 100px; height: 100px;">
|
|
15
|
-
|
|
16
|
-
<button>Click me to test recording</button>
|
|
17
|
-
<input type="text" placeholder="Type something">
|
|
18
|
-
<input type="password" placeholder="Password (will be redacted)">
|
|
19
|
-
|
|
20
|
-
<script src="./dist/index.min.js"></script>
|
|
21
|
-
<script>
|
|
22
|
-
// Initialize the tracker with error suppression enabled (default)
|
|
23
|
-
const tracker = HumanBehaviorTracker.init('13c3e029-ca45-4a3c-a33b-f5dcb297e31c', {
|
|
24
|
-
redactFields: ['input[type="password"]'],
|
|
25
|
-
suppressConsoleErrors: true, // Enable error suppression (default)
|
|
26
|
-
logLevel: 'warn' // Only show warnings and errors
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
console.log('✅ HumanBehavior tracker initialized with clean console mode');
|
|
30
|
-
console.log('✅ Canvas security errors and CORS issues will be suppressed');
|
|
31
|
-
|
|
32
|
-
// Test that core functionality still works
|
|
33
|
-
tracker.customEvent('demo_started', {
|
|
34
|
-
feature: 'clean_console',
|
|
35
|
-
timestamp: Date.now()
|
|
36
|
-
});
|
|
37
|
-
</script>
|
|
38
|
-
</body>
|
|
39
|
-
</html>
|
package/simple-demo.html
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="UTF-8">
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
-
<title>HumanBehavior Simple Demo</title>
|
|
7
|
-
</head>
|
|
8
|
-
<body>
|
|
9
|
-
<h1>HumanBehavior Tracker Demo</h1>
|
|
10
|
-
<p>This page initializes the HumanBehavior tracker. Check the console for status.</p>
|
|
11
|
-
|
|
12
|
-
<button>Click me to test recording</button>
|
|
13
|
-
<input type="text" placeholder="Type something">
|
|
14
|
-
<input type="password" placeholder="Password (will be redacted)">
|
|
15
|
-
|
|
16
|
-
<script src="./dist/index.min.js"></script>
|
|
17
|
-
<script>
|
|
18
|
-
// Initialize the tracker
|
|
19
|
-
const tracker = HumanBehaviorTracker.init('13c3e029-ca45-4a3c-a33b-f5dcb297e31c', {
|
|
20
|
-
redactFields: ['input[type="password"]']
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
console.log('HumanBehavior tracker initialized:', tracker);
|
|
24
|
-
</script>
|
|
25
|
-
</body>
|
|
26
|
-
</html>
|