@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/package.json CHANGED
@@ -1,13 +1,14 @@
1
1
  {
2
2
  "name": "@brainfish-ai/web-tracker",
3
- "version": "0.0.4-alpha.8",
4
- "module": "index.ts",
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
- "build": "vite build",
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.2",
26
+ "@brainfish-ai/tracker-sdk": "0.0.1-alpha.3",
26
27
  "html-to-image": "^1.11.11",
27
- "redact-pii": "^3.4.0",
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 './utils/snapshot';
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: __PACKAGE_VERSION__,
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
- ? anchor
138
- : null;
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
- screenshot: snapshot,
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;