@brainfish-ai/web-tracker 0.0.4-alpha.8 → 0.0.4-aplha.19
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/index.js +1944 -0
- package/package.json +6 -7
- package/set-version.js +13 -0
- package/src/index.ts +9 -8
- package/src/redact/built-ins/NameRedactor.ts +41 -0
- package/src/redact/built-ins/SimpleRegexpRedactor.ts +22 -0
- package/src/redact/built-ins/simple-regexp-patterns.ts +20 -0
- package/src/redact/built-ins/well-known-names.ts +11543 -0
- package/src/redact/composition.ts +54 -0
- package/src/redact/index.ts +21 -0
- package/src/redact/types.ts +34 -0
- package/src/redact/utils.ts +15 -0
- package/src/{utils → screenshot}/redact.ts +1 -1
- package/src/tracker.ts +5 -5
- package/src/vite-env.d.ts +7 -1
- package/tsconfig.json +3 -2
- package/vite.config.ts +13 -17
- /package/src/{utils → screenshot}/capture.test.ts +0 -0
- /package/src/{utils → screenshot}/capture.ts +0 -0
- /package/src/{utils → screenshot}/redact.test.ts +0 -0
- /package/src/{utils → screenshot}/snapshot.ts +0 -0
package/package.json
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@brainfish-ai/web-tracker",
|
|
3
|
-
"version": "0.0.4-
|
|
4
|
-
"
|
|
3
|
+
"version": "0.0.4-aplha.19",
|
|
4
|
+
"main": "dist/index.js",
|
|
5
5
|
"description": "Brainfish Tracker for Web",
|
|
6
6
|
"private": false,
|
|
7
7
|
"scripts": {
|
|
8
8
|
"start": "vite",
|
|
9
9
|
"dev": "vite",
|
|
10
|
-
"
|
|
10
|
+
"set-version": "node set-version.js",
|
|
11
|
+
"build": "npm run set-version && vite build",
|
|
11
12
|
"serve": "vite preview --port 6006",
|
|
12
13
|
"test": "vitest"
|
|
13
14
|
},
|
|
@@ -22,11 +23,9 @@
|
|
|
22
23
|
"vite-tsconfig-paths": "^4.2.0"
|
|
23
24
|
},
|
|
24
25
|
"dependencies": {
|
|
25
|
-
"@brainfish-ai/tracker-sdk": "0.0.1-alpha.
|
|
26
|
+
"@brainfish-ai/tracker-sdk": "0.0.1-alpha.3",
|
|
26
27
|
"html-to-image": "^1.11.11",
|
|
27
|
-
"
|
|
28
|
-
"rrweb": "^2.0.0-alpha.4",
|
|
29
|
-
"vite-plugin-replace": "^0.1.1"
|
|
28
|
+
"rrweb": "^2.0.0-alpha.4"
|
|
30
29
|
},
|
|
31
30
|
"keywords": [
|
|
32
31
|
"typescript",
|
package/set-version.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const packageJson = require('./package.json');
|
|
3
|
+
|
|
4
|
+
// Get the version from package.json
|
|
5
|
+
const version = packageJson.version;
|
|
6
|
+
|
|
7
|
+
// Prepare the .env content
|
|
8
|
+
const envContent = `PACKAGE_VERSION=${version}\n`;
|
|
9
|
+
|
|
10
|
+
// Write the version to .env file
|
|
11
|
+
fs.writeFileSync('.env', envContent);
|
|
12
|
+
|
|
13
|
+
console.log(`Set PACKAGE_VERSION to ${version} in .env file`);
|
package/src/index.ts
CHANGED
|
@@ -5,7 +5,7 @@ import type {
|
|
|
5
5
|
TrackProperties,
|
|
6
6
|
} from '@brainfish-ai/tracker-sdk';
|
|
7
7
|
import { TrackerSdk } from '@brainfish-ai/tracker-sdk';
|
|
8
|
-
import { screenshot } from './
|
|
8
|
+
import { screenshot } from './screenshot/snapshot';
|
|
9
9
|
|
|
10
10
|
export type * from '@brainfish-ai/tracker-sdk';
|
|
11
11
|
|
|
@@ -18,19 +18,20 @@ export type TrackerOptions = TrackerSdkOptions & {
|
|
|
18
18
|
|
|
19
19
|
function toCamelCase(str: string) {
|
|
20
20
|
return str.replace(/([-_][a-z])/gi, ($1) =>
|
|
21
|
-
$1.toUpperCase().replace('-', '').replace('_', '')
|
|
21
|
+
$1.toUpperCase().replace('-', '').replace('_', '')
|
|
22
22
|
);
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
+
export const VERSION = import.meta.env.PACKAGE_VERSION as string;
|
|
26
|
+
|
|
25
27
|
export class Tracker extends TrackerSdk {
|
|
26
28
|
private lastPath = '';
|
|
27
29
|
private debounceTimer: ReturnType<typeof setTimeout> | null = null;
|
|
28
|
-
static mock: any;
|
|
29
30
|
|
|
30
31
|
constructor(public options: TrackerOptions) {
|
|
31
32
|
super({
|
|
32
33
|
sdk: 'web',
|
|
33
|
-
sdkVersion:
|
|
34
|
+
sdkVersion: VERSION,
|
|
34
35
|
...options,
|
|
35
36
|
});
|
|
36
37
|
|
|
@@ -134,8 +135,8 @@ export class Tracker extends TrackerSdk {
|
|
|
134
135
|
const element = btn?.getAttribute('data-track')
|
|
135
136
|
? btn
|
|
136
137
|
: anchor?.getAttribute('data-track')
|
|
137
|
-
|
|
138
|
-
|
|
138
|
+
? anchor
|
|
139
|
+
: null;
|
|
139
140
|
if (element) {
|
|
140
141
|
const properties: Record<string, unknown> = {};
|
|
141
142
|
for (const attr of element.attributes) {
|
|
@@ -156,7 +157,7 @@ export class Tracker extends TrackerSdk {
|
|
|
156
157
|
async screenView(path: string, properties?: TrackProperties): Promise<void>;
|
|
157
158
|
async screenView(
|
|
158
159
|
pathOrProperties?: string | TrackProperties,
|
|
159
|
-
propertiesOrUndefined?: TrackProperties
|
|
160
|
+
propertiesOrUndefined?: TrackProperties
|
|
160
161
|
): Promise<void> {
|
|
161
162
|
if (this.isServer()) {
|
|
162
163
|
return;
|
|
@@ -183,7 +184,7 @@ export class Tracker extends TrackerSdk {
|
|
|
183
184
|
this.lastPath = path;
|
|
184
185
|
super.track('screen_view', {
|
|
185
186
|
...(properties ?? {}),
|
|
186
|
-
|
|
187
|
+
__screenshot: snapshot,
|
|
187
188
|
__path: path,
|
|
188
189
|
__title: document.title,
|
|
189
190
|
});
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { ISyncRedactor } from '../types';
|
|
2
|
+
import _wellKnownNames from './well-known-names';
|
|
3
|
+
|
|
4
|
+
const greetingRegex = /(^|\.\s+)(dear|hi|hello|greetings|hey|hey there)/gi;
|
|
5
|
+
const closingRegex =
|
|
6
|
+
/(thx|thanks|thank you|regards|best|[a-z]+ly|[a-z]+ regards|all the best|happy [a-z]+ing|take care|have a [a-z]+ (weekend|night|day))/gi;
|
|
7
|
+
|
|
8
|
+
const greetingOrClosing = new RegExp(
|
|
9
|
+
'(((' + greetingRegex.source + ')|(' + closingRegex.source + '\\s*[,.!]*))[\\s-]*)',
|
|
10
|
+
'gi'
|
|
11
|
+
);
|
|
12
|
+
const genericName = new RegExp('( ?(([A-Z][a-z]+)|([A-Z]\\.)))+([,.]|[,.]?$)', 'gm');
|
|
13
|
+
|
|
14
|
+
const wellKnownNames = new RegExp('\\b(\\s*)(\\s*(' + _wellKnownNames.join('|') + '))+\\b', 'gim');
|
|
15
|
+
|
|
16
|
+
export class NameRedactor implements ISyncRedactor {
|
|
17
|
+
constructor(private replaceWith = 'PERSON_NAME') {}
|
|
18
|
+
|
|
19
|
+
redact(textToRedact: string) {
|
|
20
|
+
greetingOrClosing.lastIndex = 0;
|
|
21
|
+
genericName.lastIndex = 0;
|
|
22
|
+
let greetingOrClosingMatch = greetingOrClosing.exec(textToRedact);
|
|
23
|
+
while (greetingOrClosingMatch !== null) {
|
|
24
|
+
genericName.lastIndex = greetingOrClosing.lastIndex;
|
|
25
|
+
let genericNameMatch = genericName.exec(textToRedact);
|
|
26
|
+
if (genericNameMatch !== null && genericNameMatch.index === greetingOrClosing.lastIndex) {
|
|
27
|
+
let suffix = genericNameMatch[5] === null ? '' : genericNameMatch[5];
|
|
28
|
+
textToRedact =
|
|
29
|
+
textToRedact.slice(0, genericNameMatch.index) +
|
|
30
|
+
this.replaceWith +
|
|
31
|
+
suffix +
|
|
32
|
+
textToRedact.slice(genericNameMatch.index + genericNameMatch[0].length);
|
|
33
|
+
}
|
|
34
|
+
greetingOrClosingMatch = greetingOrClosing.exec(textToRedact);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
textToRedact = textToRedact.replace(wellKnownNames, '$1' + this.replaceWith);
|
|
38
|
+
|
|
39
|
+
return textToRedact;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { ISyncRedactor } from '../types';
|
|
2
|
+
import { snakeCase } from '../utils';
|
|
3
|
+
|
|
4
|
+
export class SimpleRegexpRedactor implements ISyncRedactor {
|
|
5
|
+
regexpMatcher: RegExp;
|
|
6
|
+
replaceWith: string;
|
|
7
|
+
|
|
8
|
+
constructor({
|
|
9
|
+
replaceWith = snakeCase('default').toUpperCase(),
|
|
10
|
+
regexpPattern: regexpMatcher,
|
|
11
|
+
}: {
|
|
12
|
+
replaceWith: string;
|
|
13
|
+
regexpPattern: RegExp;
|
|
14
|
+
}) {
|
|
15
|
+
this.replaceWith = replaceWith;
|
|
16
|
+
this.regexpMatcher = regexpMatcher;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
redact(textToRedact: string) {
|
|
20
|
+
return textToRedact.replace(this.regexpMatcher, this.replaceWith);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
const aptRegex = /(apt|bldg|dept|fl|hngr|lot|pier|rm|ste|slip|trlr|unit|#)\.? *[a-z0-9-]+\b/gi;
|
|
2
|
+
const poBoxRegex = /P\.? ?O\.? *Box +\d+/gi;
|
|
3
|
+
const roadRegex = /(street|st|road|rd|avenue|ave|drive|dr|loop|court|ct|circle|cir|lane|ln|boulevard|blvd|way)\.?\b/gi;
|
|
4
|
+
|
|
5
|
+
export const creditCardNumber = /\d{4}[ -]?\d{4}[ -]?\d{4}[ -]?\d{4}|\d{4}[ -]?\d{6}[ -]?\d{4}\d?/g;
|
|
6
|
+
export const streetAddress = new RegExp(
|
|
7
|
+
'(\\d+\\s*(\\w+ ){1,2}' + roadRegex.source + '(\\s+' + aptRegex.source + ')?)|(' + poBoxRegex.source + ')',
|
|
8
|
+
'gi'
|
|
9
|
+
);
|
|
10
|
+
export const zipcode = /\b\d{5}\b(-\d{4})?\b/g;
|
|
11
|
+
export const phoneNumber =
|
|
12
|
+
/(\(?\+?[0-9]{1,2}\)?[-. ]?)?(\(?[0-9]{3}\)?|[0-9]{3})[-. ]?([0-9]{3}[-. ]?[0-9]{4}|\b[A-Z0-9]{7}\b)/g;
|
|
13
|
+
export const ipAddress = /(\d{1,3}(\.\d{1,3}){3}|[0-9A-F]{4}(:[0-9A-F]{4}){5}(::|(:0000)+))/gi;
|
|
14
|
+
export const usSocialSecurityNumber = /\b\d{3}[ -.]\d{2}[ -.]\d{4}\b/g;
|
|
15
|
+
export const emailAddress = /([a-z0-9_\-.+]+)@\w+(\.\w+)*/gi;
|
|
16
|
+
export const username = /(user( ?name)?|login): \S+/gi;
|
|
17
|
+
export const password = /(pass(word|phrase)?|secret): \S+/gi;
|
|
18
|
+
export const credentials = /(login( cred(ential)?s| info(rmation)?)?|cred(ential)?s) ?:\s*\S+\s+\/?\s*\S+/gi;
|
|
19
|
+
export const digits = /\b\d{4,}\b/g;
|
|
20
|
+
export const url = /([^\s:/?#]+):\/\/([^/?#\s]*)([^?#\s]*)(\?([^#\s]*))?(#([^\s]*))?/g;
|