@flisk/analyze-tracking 0.2.0 → 0.2.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.
@@ -0,0 +1,17 @@
1
+ name: PR Tests
2
+
3
+ on:
4
+ pull_request_target:
5
+ branches:
6
+ - main
7
+
8
+ jobs:
9
+ test:
10
+ runs-on: ubuntu-latest
11
+ steps:
12
+ - uses: actions/checkout@v4
13
+ - uses: actions/setup-node@v4
14
+ with:
15
+ node-version: 20
16
+ - run: npm ci
17
+ - run: npm test
package/README.md CHANGED
@@ -98,6 +98,22 @@ posthog.capture('<event_name>', {
98
98
  ```
99
99
 
100
100
 
101
+ #### Pendo
102
+ ```js
103
+ pendo.track('<event_name>', {
104
+ <event_parameters>
105
+ });
106
+ ```
107
+
108
+
109
+ #### Heap
110
+ ```js
111
+ heap.track('<event_name>', {
112
+ <event_parameters>
113
+ });
114
+ ```
115
+
116
+
101
117
  #### Snowplow
102
118
  ```js
103
119
  snowplow('trackStructEvent', {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flisk/analyze-tracking",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "description": "Analyzes tracking code in a project and generates data schemas",
5
5
  "main": "src/index.js",
6
6
  "bin": {
@@ -22,6 +22,8 @@
22
22
  "dependencies": {
23
23
  "@typescript-eslint/parser": "^8.1.0",
24
24
  "acorn": "^8.12.1",
25
+ "acorn-jsx": "^5.3.2",
26
+ "acorn-jsx-walk": "^2.0.0",
25
27
  "acorn-walk": "^8.3.3",
26
28
  "command-line-args": "^6.0.0",
27
29
  "js-yaml": "^4.1.0",
package/schema.json CHANGED
@@ -64,6 +64,8 @@
64
64
  "rudderstack",
65
65
  "mparticle",
66
66
  "posthog",
67
+ "pendo",
68
+ "heap",
67
69
  "snowplow",
68
70
  "unknown"
69
71
  ],
@@ -1,11 +1,17 @@
1
1
  const fs = require('fs');
2
2
  const acorn = require('acorn');
3
+ const jsx = require('acorn-jsx');
3
4
  const walk = require('acorn-walk');
5
+ const { extend } = require('acorn-jsx-walk');
4
6
  const { detectSourceJs, findWrappingFunctionJs, extractJsProperties } = require('./helpers');
5
7
 
8
+ const parser = acorn.Parser.extend(jsx());
9
+ const parserOptions = { ecmaVersion: 'latest', sourceType: 'module', locations: true };
10
+ extend(walk.base);
11
+
6
12
  function analyzeJsFile(filePath) {
7
13
  const code = fs.readFileSync(filePath, 'utf8');
8
- const ast = acorn.parse(code, { ecmaVersion: 'latest', sourceType: 'module', locations: true });
14
+ const ast = parser.parse(code, parserOptions);
9
15
  const events = [];
10
16
 
11
17
  walk.ancestor(ast, {
@@ -15,6 +15,8 @@ function detectSourceJs(node) {
15
15
  if (objectName === 'rudderanalytics' && methodName === 'track') return 'rudderstack';
16
16
  if (objectName === 'mParticle' && methodName === 'logEvent') return 'mparticle';
17
17
  if (objectName === 'posthog' && methodName === 'capture') return 'posthog';
18
+ if (objectName === 'pendo' && methodName === 'track') return 'pendo';
19
+ if (objectName === 'heap' && methodName === 'track') return 'heap';
18
20
  } else if (node.callee.type === 'Identifier' && node.callee.name === 'snowplow') {
19
21
  return 'snowplow';
20
22
  }
@@ -37,6 +39,8 @@ function detectSourceTs(node) {
37
39
  if (objectName === 'rudderanalytics' && methodName === 'track') return 'rudderstack';
38
40
  if (objectName === 'mParticle' && methodName === 'logEvent') return 'mparticle';
39
41
  if (objectName === 'posthog' && methodName === 'capture') return 'posthog';
42
+ if (objectName === 'pendo' && methodName === 'track') return 'pendo';
43
+ if (objectName === 'heap' && methodName === 'track') return 'heap';
40
44
  } else if (ts.isIdentifier(node.expression) && node.expression.escapedText === 'snowplow') {
41
45
  return 'snowplow';
42
46
  }
@@ -8,14 +8,14 @@ function analyzeDirectory(dirPath) {
8
8
  const files = getAllFiles(dirPath);
9
9
  const allEvents = {};
10
10
 
11
- const tsFiles = files.filter(file => file.endsWith('.ts'));
11
+ const tsFiles = files.filter(file => /\.(tsx?)$/.test(file));
12
12
  const program = ts.createProgram(tsFiles, {
13
13
  target: ts.ScriptTarget.ESNext,
14
14
  module: ts.ModuleKind.CommonJS,
15
15
  });
16
16
 
17
17
  files.forEach((file) => {
18
- const isTsFile = file.endsWith('.ts');
18
+ const isTsFile = /\.(tsx?)$/.test(file);
19
19
  const events = isTsFile ? analyzeTsFile(file, program) : analyzeJsFile(file);
20
20
 
21
21
  events.forEach((event) => {
@@ -6,9 +6,24 @@ function getAllFiles(dirPath, arrayOfFiles = []) {
6
6
 
7
7
  files.forEach((file) => {
8
8
  const fullPath = path.join(dirPath, file);
9
- if (fs.statSync(fullPath).isDirectory()) {
9
+
10
+ let stats;
11
+ try {
12
+ stats = fs.statSync(fullPath);
13
+ } catch (error) {
14
+ if (error.code === 'ENOENT') {
15
+ return; // Skip this file or directory if it does not exist
16
+ } else {
17
+ throw error;
18
+ }
19
+ }
20
+
21
+ if (stats.isDirectory()) {
22
+ if (file === 'node_modules') {
23
+ return; // Ignore the node_modules directory
24
+ }
10
25
  arrayOfFiles = getAllFiles(fullPath, arrayOfFiles);
11
- } else if (file.endsWith('.js') || file.endsWith('.ts')) {
26
+ } else if (/\.((j|t)sx?)$/.test(file)) {
12
27
  arrayOfFiles.push(fullPath);
13
28
  }
14
29
  });