From 94f556c3d2a1c7b918cec457ff36b653e1a7074e Mon Sep 17 00:00:00 2001 From: Paul Boocock Date: Mon, 15 Mar 2021 22:15:33 +0000 Subject: [PATCH] Add debug mode (close #381) --- .browserslistrc | 2 +- .../feat-debugger_2021-03-15-22-16.json | 11 + .../feat-debugger_2021-03-15-22-16.json | 11 + .../feat-debugger_2021-03-15-22-16.json | 11 + .../feat-debugger_2021-03-15-22-16.json | 11 + .../feat-debugger_2021-03-15-22-16.json | 11 + common/config/rush/pnpm-lock.yaml | 268 ++++++++++-------- common/config/rush/repo-state.json | 2 +- .../browser-tracker-core/src/detectors.ts | 2 +- libraries/browser-tracker-core/src/helpers.ts | 11 +- .../browser-tracker-core/src/snowplow.ts | 14 +- libraries/browser-tracker-core/src/state.ts | 7 +- .../browser-tracker-core/src/tracker/index.ts | 15 +- .../src/tracker/out_queue.ts | 6 +- libraries/tracker-core/src/contexts.ts | 76 ++--- libraries/tracker-core/src/core.ts | 10 +- libraries/tracker-core/src/index.ts | 1 + libraries/tracker-core/src/logger.ts | 113 ++++++++ libraries/tracker-core/src/payload.ts | 34 ++- libraries/tracker-core/src/plugins.ts | 6 + libraries/tracker-core/test/contexts.ts | 25 +- plugins/browser-plugin-consent/src/index.ts | 67 +++-- plugins/browser-plugin-debugger/LICENSE | 29 ++ plugins/browser-plugin-debugger/README.md | 56 ++++ plugins/browser-plugin-debugger/package.json | 45 +++ .../browser-plugin-debugger/rollup.config.js | 67 +++++ plugins/browser-plugin-debugger/src/index.ts | 90 ++++++ plugins/browser-plugin-debugger/tsconfig.json | 3 + rush.json | 6 + trackers/javascript-tracker/src/in_queue.ts | 19 +- 30 files changed, 766 insertions(+), 263 deletions(-) create mode 100644 common/changes/@snowplow/browser-plugin-consent/feat-debugger_2021-03-15-22-16.json create mode 100644 common/changes/@snowplow/browser-plugin-debugger/feat-debugger_2021-03-15-22-16.json create mode 100644 common/changes/@snowplow/browser-tracker-core/feat-debugger_2021-03-15-22-16.json create mode 100644 common/changes/@snowplow/javascript-tracker/feat-debugger_2021-03-15-22-16.json create mode 100644 common/changes/@snowplow/tracker-core/feat-debugger_2021-03-15-22-16.json create mode 100644 libraries/tracker-core/src/logger.ts create mode 100644 plugins/browser-plugin-debugger/LICENSE create mode 100644 plugins/browser-plugin-debugger/README.md create mode 100644 plugins/browser-plugin-debugger/package.json create mode 100644 plugins/browser-plugin-debugger/rollup.config.js create mode 100644 plugins/browser-plugin-debugger/src/index.ts create mode 100644 plugins/browser-plugin-debugger/tsconfig.json diff --git a/.browserslistrc b/.browserslistrc index 0a4202b67..27001cf97 100644 --- a/.browserslistrc +++ b/.browserslistrc @@ -2,4 +2,4 @@ chrome >= 32, ie >= 9, edge >= 13, firefox >= 27, -safari >= 8, \ No newline at end of file +safari >= 8, diff --git a/common/changes/@snowplow/browser-plugin-consent/feat-debugger_2021-03-15-22-16.json b/common/changes/@snowplow/browser-plugin-consent/feat-debugger_2021-03-15-22-16.json new file mode 100644 index 000000000..fae914b4a --- /dev/null +++ b/common/changes/@snowplow/browser-plugin-consent/feat-debugger_2021-03-15-22-16.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "comment": "Add debug mode (#381)", + "type": "none", + "packageName": "@snowplow/browser-plugin-consent" + } + ], + "packageName": "@snowplow/browser-plugin-consent", + "email": "paul@snowplowanalytics.com" +} \ No newline at end of file diff --git a/common/changes/@snowplow/browser-plugin-debugger/feat-debugger_2021-03-15-22-16.json b/common/changes/@snowplow/browser-plugin-debugger/feat-debugger_2021-03-15-22-16.json new file mode 100644 index 000000000..3f9145db6 --- /dev/null +++ b/common/changes/@snowplow/browser-plugin-debugger/feat-debugger_2021-03-15-22-16.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "comment": "Add debug mode (#381)", + "type": "none", + "packageName": "@snowplow/browser-plugin-debugger" + } + ], + "packageName": "@snowplow/browser-plugin-debugger", + "email": "paul@snowplowanalytics.com" +} \ No newline at end of file diff --git a/common/changes/@snowplow/browser-tracker-core/feat-debugger_2021-03-15-22-16.json b/common/changes/@snowplow/browser-tracker-core/feat-debugger_2021-03-15-22-16.json new file mode 100644 index 000000000..0d252db83 --- /dev/null +++ b/common/changes/@snowplow/browser-tracker-core/feat-debugger_2021-03-15-22-16.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "comment": "Add debug mode (#381)", + "type": "none", + "packageName": "@snowplow/browser-tracker-core" + } + ], + "packageName": "@snowplow/browser-tracker-core", + "email": "paul@snowplowanalytics.com" +} \ No newline at end of file diff --git a/common/changes/@snowplow/javascript-tracker/feat-debugger_2021-03-15-22-16.json b/common/changes/@snowplow/javascript-tracker/feat-debugger_2021-03-15-22-16.json new file mode 100644 index 000000000..4218e5e97 --- /dev/null +++ b/common/changes/@snowplow/javascript-tracker/feat-debugger_2021-03-15-22-16.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "comment": "Add debug mode (#381)", + "type": "none", + "packageName": "@snowplow/javascript-tracker" + } + ], + "packageName": "@snowplow/javascript-tracker", + "email": "paul@snowplowanalytics.com" +} \ No newline at end of file diff --git a/common/changes/@snowplow/tracker-core/feat-debugger_2021-03-15-22-16.json b/common/changes/@snowplow/tracker-core/feat-debugger_2021-03-15-22-16.json new file mode 100644 index 000000000..0656b0e91 --- /dev/null +++ b/common/changes/@snowplow/tracker-core/feat-debugger_2021-03-15-22-16.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "comment": "Add debug mode (#381)", + "type": "none", + "packageName": "@snowplow/tracker-core" + } + ], + "packageName": "@snowplow/tracker-core", + "email": "paul@snowplowanalytics.com" +} \ No newline at end of file diff --git a/common/config/rush/pnpm-lock.yaml b/common/config/rush/pnpm-lock.yaml index 41ba73eb2..84672a433 100644 --- a/common/config/rush/pnpm-lock.yaml +++ b/common/config/rush/pnpm-lock.yaml @@ -3,7 +3,7 @@ importers: specifiers: {} ../../libraries/browser-tracker-core: dependencies: - '@snowplow/tracker-core': 'link:../tracker-core' + '@snowplow/tracker-core': link:../tracker-core sha1: 1.1.1 tslib: 2.1.0 uuid: 3.4.0 @@ -33,7 +33,7 @@ importers: '@ampproject/rollup-plugin-closure-compiler': ^0.26.0 '@rollup/plugin-commonjs': ^17.1.0 '@rollup/plugin-node-resolve': ^11.2.0 - '@snowplow/tracker-core': 'workspace:*' + '@snowplow/tracker-core': workspace:* '@types/jest': ^26.0.20 '@types/jsdom': ^16.2.6 '@types/sha1': ^1.1.2 @@ -97,8 +97,8 @@ importers: uuid: ^3.4.0 ../../plugins/browser-plugin-ad-tracking: dependencies: - '@snowplow/browser-tracker-core': 'link:../../libraries/browser-tracker-core' - '@snowplow/tracker-core': 'link:../../libraries/tracker-core' + '@snowplow/browser-tracker-core': link:../../libraries/browser-tracker-core + '@snowplow/tracker-core': link:../../libraries/tracker-core tslib: 2.1.0 devDependencies: '@rollup/plugin-commonjs': 17.1.0_rollup@2.41.1 @@ -119,8 +119,8 @@ importers: specifiers: '@rollup/plugin-commonjs': ^17.1.0 '@rollup/plugin-node-resolve': ^11.2.0 - '@snowplow/browser-tracker-core': 'workspace:*' - '@snowplow/tracker-core': 'workspace:*' + '@snowplow/browser-tracker-core': workspace:* + '@snowplow/tracker-core': workspace:* '@types/jest': ^26.0.20 '@typescript-eslint/eslint-plugin': ^4.9.0 '@typescript-eslint/parser': ^4.9.0 @@ -137,12 +137,12 @@ importers: typescript: ^4.2.3 ../../plugins/browser-plugin-browser-features: dependencies: - '@snowplow/browser-tracker-core': 'link:../../libraries/browser-tracker-core' + '@snowplow/browser-tracker-core': link:../../libraries/browser-tracker-core tslib: 2.1.0 devDependencies: '@rollup/plugin-commonjs': 17.1.0_rollup@2.41.1 '@rollup/plugin-node-resolve': 11.2.0_rollup@2.41.1 - '@snowplow/tracker-core': 'link:../../libraries/tracker-core' + '@snowplow/tracker-core': link:../../libraries/tracker-core '@types/jest': 26.0.20 '@types/jsdom': 16.2.6 '@typescript-eslint/eslint-plugin': 4.11.0_3261e8a6d4b016dd957834f001de0f18 @@ -162,8 +162,8 @@ importers: specifiers: '@rollup/plugin-commonjs': ^17.1.0 '@rollup/plugin-node-resolve': ^11.2.0 - '@snowplow/browser-tracker-core': 'workspace:*' - '@snowplow/tracker-core': 'workspace:*' + '@snowplow/browser-tracker-core': workspace:* + '@snowplow/tracker-core': workspace:* '@types/jest': ^26.0.20 '@types/jsdom': ^16.2.6 '@typescript-eslint/eslint-plugin': ^4.9.0 @@ -183,7 +183,7 @@ importers: typescript: ^4.2.3 ../../plugins/browser-plugin-client-hints: dependencies: - '@snowplow/browser-tracker-core': 'link:../../libraries/browser-tracker-core' + '@snowplow/browser-tracker-core': link:../../libraries/browser-tracker-core tslib: 2.1.0 devDependencies: '@rollup/plugin-commonjs': 17.1.0_rollup@2.41.1 @@ -204,7 +204,7 @@ importers: specifiers: '@rollup/plugin-commonjs': ^17.1.0 '@rollup/plugin-node-resolve': ^11.2.0 - '@snowplow/browser-tracker-core': 'workspace:*' + '@snowplow/browser-tracker-core': workspace:* '@types/jest': ^26.0.20 '@typescript-eslint/eslint-plugin': ^4.9.0 '@typescript-eslint/parser': ^4.9.0 @@ -221,8 +221,8 @@ importers: typescript: ^4.2.3 ../../plugins/browser-plugin-consent: dependencies: - '@snowplow/browser-tracker-core': 'link:../../libraries/browser-tracker-core' - '@snowplow/tracker-core': 'link:../../libraries/tracker-core' + '@snowplow/browser-tracker-core': link:../../libraries/browser-tracker-core + '@snowplow/tracker-core': link:../../libraries/tracker-core tslib: 2.1.0 devDependencies: '@rollup/plugin-commonjs': 17.1.0_rollup@2.41.1 @@ -243,8 +243,48 @@ importers: specifiers: '@rollup/plugin-commonjs': ^17.1.0 '@rollup/plugin-node-resolve': ^11.2.0 - '@snowplow/browser-tracker-core': 'workspace:*' - '@snowplow/tracker-core': 'workspace:*' + '@snowplow/browser-tracker-core': workspace:* + '@snowplow/tracker-core': workspace:* + '@types/jest': ^26.0.20 + '@typescript-eslint/eslint-plugin': ^4.9.0 + '@typescript-eslint/parser': ^4.9.0 + '@wessberg/rollup-plugin-ts': ^1.3.8 + eslint: ^7.7.0 + jest: ^26.6.3 + jest-standard-reporter: ^2.0.0 + rollup: ^2.41.1 + rollup-plugin-cleanup: ^3.2.1 + rollup-plugin-license: ^2.2.0 + rollup-plugin-terser: ^7.0.2 + ts-jest: ^26.5.0 + tslib: ^2.1.0 + typescript: ^4.2.3 + ../../plugins/browser-plugin-debugger: + dependencies: + '@snowplow/browser-tracker-core': link:../../libraries/browser-tracker-core + '@snowplow/tracker-core': link:../../libraries/tracker-core + tslib: 2.1.0 + devDependencies: + '@rollup/plugin-commonjs': 17.1.0_rollup@2.41.1 + '@rollup/plugin-node-resolve': 11.2.0_rollup@2.41.1 + '@types/jest': 26.0.20 + '@typescript-eslint/eslint-plugin': 4.11.0_3261e8a6d4b016dd957834f001de0f18 + '@typescript-eslint/parser': 4.11.0_eslint@7.16.0+typescript@4.2.3 + '@wessberg/rollup-plugin-ts': 1.3.8_rollup@2.41.1+typescript@4.2.3 + eslint: 7.16.0 + jest: 26.6.3 + jest-standard-reporter: 2.0.0 + rollup: 2.41.1 + rollup-plugin-cleanup: 3.2.1_rollup@2.41.1 + rollup-plugin-license: 2.2.0_rollup@2.41.1 + rollup-plugin-terser: 7.0.2_rollup@2.41.1 + ts-jest: 26.5.0_jest@26.6.3+typescript@4.2.3 + typescript: 4.2.3 + specifiers: + '@rollup/plugin-commonjs': ^17.1.0 + '@rollup/plugin-node-resolve': ^11.2.0 + '@snowplow/browser-tracker-core': workspace:* + '@snowplow/tracker-core': workspace:* '@types/jest': ^26.0.20 '@typescript-eslint/eslint-plugin': ^4.9.0 '@typescript-eslint/parser': ^4.9.0 @@ -261,8 +301,8 @@ importers: typescript: ^4.2.3 ../../plugins/browser-plugin-ecommerce: dependencies: - '@snowplow/browser-tracker-core': 'link:../../libraries/browser-tracker-core' - '@snowplow/tracker-core': 'link:../../libraries/tracker-core' + '@snowplow/browser-tracker-core': link:../../libraries/browser-tracker-core + '@snowplow/tracker-core': link:../../libraries/tracker-core tslib: 2.1.0 devDependencies: '@rollup/plugin-commonjs': 17.1.0_rollup@2.41.1 @@ -283,8 +323,8 @@ importers: specifiers: '@rollup/plugin-commonjs': ^17.1.0 '@rollup/plugin-node-resolve': ^11.2.0 - '@snowplow/browser-tracker-core': 'workspace:*' - '@snowplow/tracker-core': 'workspace:*' + '@snowplow/browser-tracker-core': workspace:* + '@snowplow/tracker-core': workspace:* '@types/jest': ^26.0.20 '@typescript-eslint/eslint-plugin': ^4.9.0 '@typescript-eslint/parser': ^4.9.0 @@ -301,8 +341,8 @@ importers: typescript: ^4.2.3 ../../plugins/browser-plugin-enhanced-ecommerce: dependencies: - '@snowplow/browser-tracker-core': 'link:../../libraries/browser-tracker-core' - '@snowplow/tracker-core': 'link:../../libraries/tracker-core' + '@snowplow/browser-tracker-core': link:../../libraries/browser-tracker-core + '@snowplow/tracker-core': link:../../libraries/tracker-core tslib: 2.1.0 devDependencies: '@rollup/plugin-commonjs': 17.1.0_rollup@2.41.1 @@ -325,8 +365,8 @@ importers: specifiers: '@rollup/plugin-commonjs': ^17.1.0 '@rollup/plugin-node-resolve': ^11.2.0 - '@snowplow/browser-tracker-core': 'workspace:*' - '@snowplow/tracker-core': 'workspace:*' + '@snowplow/browser-tracker-core': workspace:* + '@snowplow/tracker-core': workspace:* '@types/jest': ^26.0.20 '@types/lodash': ^4.14.168 '@typescript-eslint/eslint-plugin': ^4.9.0 @@ -345,8 +385,8 @@ importers: typescript: ^4.2.3 ../../plugins/browser-plugin-error-tracking: dependencies: - '@snowplow/browser-tracker-core': 'link:../../libraries/browser-tracker-core' - '@snowplow/tracker-core': 'link:../../libraries/tracker-core' + '@snowplow/browser-tracker-core': link:../../libraries/browser-tracker-core + '@snowplow/tracker-core': link:../../libraries/tracker-core tslib: 2.1.0 devDependencies: '@rollup/plugin-commonjs': 17.1.0_rollup@2.41.1 @@ -367,8 +407,8 @@ importers: specifiers: '@rollup/plugin-commonjs': ^17.1.0 '@rollup/plugin-node-resolve': ^11.2.0 - '@snowplow/browser-tracker-core': 'workspace:*' - '@snowplow/tracker-core': 'workspace:*' + '@snowplow/browser-tracker-core': workspace:* + '@snowplow/tracker-core': workspace:* '@types/jest': ^26.0.20 '@typescript-eslint/eslint-plugin': ^4.9.0 '@typescript-eslint/parser': ^4.9.0 @@ -385,8 +425,8 @@ importers: typescript: ^4.2.3 ../../plugins/browser-plugin-form-tracking: dependencies: - '@snowplow/browser-tracker-core': 'link:../../libraries/browser-tracker-core' - '@snowplow/tracker-core': 'link:../../libraries/tracker-core' + '@snowplow/browser-tracker-core': link:../../libraries/browser-tracker-core + '@snowplow/tracker-core': link:../../libraries/tracker-core tslib: 2.1.0 devDependencies: '@rollup/plugin-commonjs': 17.1.0_rollup@2.41.1 @@ -407,8 +447,8 @@ importers: specifiers: '@rollup/plugin-commonjs': ^17.1.0 '@rollup/plugin-node-resolve': ^11.2.0 - '@snowplow/browser-tracker-core': 'workspace:*' - '@snowplow/tracker-core': 'workspace:*' + '@snowplow/browser-tracker-core': workspace:* + '@snowplow/tracker-core': workspace:* '@types/jest': ^26.0.20 '@typescript-eslint/eslint-plugin': ^4.9.0 '@typescript-eslint/parser': ^4.9.0 @@ -425,8 +465,8 @@ importers: typescript: ^4.2.3 ../../plugins/browser-plugin-ga-cookies: dependencies: - '@snowplow/browser-tracker-core': 'link:../../libraries/browser-tracker-core' - '@snowplow/tracker-core': 'link:../../libraries/tracker-core' + '@snowplow/browser-tracker-core': link:../../libraries/browser-tracker-core + '@snowplow/tracker-core': link:../../libraries/tracker-core tslib: 2.1.0 devDependencies: '@rollup/plugin-commonjs': 17.1.0_rollup@2.41.1 @@ -447,8 +487,8 @@ importers: specifiers: '@rollup/plugin-commonjs': ^17.1.0 '@rollup/plugin-node-resolve': ^11.2.0 - '@snowplow/browser-tracker-core': 'workspace:*' - '@snowplow/tracker-core': 'workspace:*' + '@snowplow/browser-tracker-core': workspace:* + '@snowplow/tracker-core': workspace:* '@types/jest': ^26.0.20 '@typescript-eslint/eslint-plugin': ^4.9.0 '@typescript-eslint/parser': ^4.9.0 @@ -465,8 +505,8 @@ importers: typescript: ^4.2.3 ../../plugins/browser-plugin-geolocation: dependencies: - '@snowplow/browser-tracker-core': 'link:../../libraries/browser-tracker-core' - '@snowplow/tracker-core': 'link:../../libraries/tracker-core' + '@snowplow/browser-tracker-core': link:../../libraries/browser-tracker-core + '@snowplow/tracker-core': link:../../libraries/tracker-core tslib: 2.1.0 devDependencies: '@rollup/plugin-commonjs': 17.1.0_rollup@2.41.1 @@ -487,8 +527,8 @@ importers: specifiers: '@rollup/plugin-commonjs': ^17.1.0 '@rollup/plugin-node-resolve': ^11.2.0 - '@snowplow/browser-tracker-core': 'workspace:*' - '@snowplow/tracker-core': 'workspace:*' + '@snowplow/browser-tracker-core': workspace:* + '@snowplow/tracker-core': workspace:* '@types/jest': ^26.0.20 '@typescript-eslint/eslint-plugin': ^4.9.0 '@typescript-eslint/parser': ^4.9.0 @@ -505,8 +545,8 @@ importers: typescript: ^4.2.3 ../../plugins/browser-plugin-link-click-tracking: dependencies: - '@snowplow/browser-tracker-core': 'link:../../libraries/browser-tracker-core' - '@snowplow/tracker-core': 'link:../../libraries/tracker-core' + '@snowplow/browser-tracker-core': link:../../libraries/browser-tracker-core + '@snowplow/tracker-core': link:../../libraries/tracker-core tslib: 2.1.0 devDependencies: '@rollup/plugin-commonjs': 17.1.0_rollup@2.41.1 @@ -527,8 +567,8 @@ importers: specifiers: '@rollup/plugin-commonjs': ^17.1.0 '@rollup/plugin-node-resolve': ^11.2.0 - '@snowplow/browser-tracker-core': 'workspace:*' - '@snowplow/tracker-core': 'workspace:*' + '@snowplow/browser-tracker-core': workspace:* + '@snowplow/tracker-core': workspace:* '@types/jest': ^26.0.20 '@typescript-eslint/eslint-plugin': ^4.9.0 '@typescript-eslint/parser': ^4.9.0 @@ -545,8 +585,8 @@ importers: typescript: ^4.2.3 ../../plugins/browser-plugin-optimizely: dependencies: - '@snowplow/browser-tracker-core': 'link:../../libraries/browser-tracker-core' - '@snowplow/tracker-core': 'link:../../libraries/tracker-core' + '@snowplow/browser-tracker-core': link:../../libraries/browser-tracker-core + '@snowplow/tracker-core': link:../../libraries/tracker-core tslib: 2.1.0 devDependencies: '@rollup/plugin-commonjs': 17.1.0_rollup@2.41.1 @@ -567,8 +607,8 @@ importers: specifiers: '@rollup/plugin-commonjs': ^17.1.0 '@rollup/plugin-node-resolve': ^11.2.0 - '@snowplow/browser-tracker-core': 'workspace:*' - '@snowplow/tracker-core': 'workspace:*' + '@snowplow/browser-tracker-core': workspace:* + '@snowplow/tracker-core': workspace:* '@types/jest': ^26.0.20 '@typescript-eslint/eslint-plugin': ^4.9.0 '@typescript-eslint/parser': ^4.9.0 @@ -585,8 +625,8 @@ importers: typescript: ^4.2.3 ../../plugins/browser-plugin-optimizely-x: dependencies: - '@snowplow/browser-tracker-core': 'link:../../libraries/browser-tracker-core' - '@snowplow/tracker-core': 'link:../../libraries/tracker-core' + '@snowplow/browser-tracker-core': link:../../libraries/browser-tracker-core + '@snowplow/tracker-core': link:../../libraries/tracker-core tslib: 2.1.0 devDependencies: '@rollup/plugin-commonjs': 17.1.0_rollup@2.41.1 @@ -607,8 +647,8 @@ importers: specifiers: '@rollup/plugin-commonjs': ^17.1.0 '@rollup/plugin-node-resolve': ^11.2.0 - '@snowplow/browser-tracker-core': 'workspace:*' - '@snowplow/tracker-core': 'workspace:*' + '@snowplow/browser-tracker-core': workspace:* + '@snowplow/tracker-core': workspace:* '@types/jest': ^26.0.20 '@typescript-eslint/eslint-plugin': ^4.9.0 '@typescript-eslint/parser': ^4.9.0 @@ -625,7 +665,7 @@ importers: typescript: ^4.2.3 ../../plugins/browser-plugin-parrable: dependencies: - '@snowplow/browser-tracker-core': 'link:../../libraries/browser-tracker-core' + '@snowplow/browser-tracker-core': link:../../libraries/browser-tracker-core tslib: 2.1.0 devDependencies: '@rollup/plugin-commonjs': 17.1.0_rollup@2.41.1 @@ -646,7 +686,7 @@ importers: specifiers: '@rollup/plugin-commonjs': ^17.1.0 '@rollup/plugin-node-resolve': ^11.2.0 - '@snowplow/browser-tracker-core': 'workspace:*' + '@snowplow/browser-tracker-core': workspace:* '@types/jest': ^26.0.20 '@typescript-eslint/eslint-plugin': ^4.9.0 '@typescript-eslint/parser': ^4.9.0 @@ -663,8 +703,8 @@ importers: typescript: ^4.2.3 ../../plugins/browser-plugin-performance-timing: dependencies: - '@snowplow/browser-tracker-core': 'link:../../libraries/browser-tracker-core' - '@snowplow/tracker-core': 'link:../../libraries/tracker-core' + '@snowplow/browser-tracker-core': link:../../libraries/browser-tracker-core + '@snowplow/tracker-core': link:../../libraries/tracker-core tslib: 2.1.0 devDependencies: '@rollup/plugin-commonjs': 17.1.0_rollup@2.41.1 @@ -685,8 +725,8 @@ importers: specifiers: '@rollup/plugin-commonjs': ^17.1.0 '@rollup/plugin-node-resolve': ^11.2.0 - '@snowplow/browser-tracker-core': 'workspace:*' - '@snowplow/tracker-core': 'workspace:*' + '@snowplow/browser-tracker-core': workspace:* + '@snowplow/tracker-core': workspace:* '@types/jest': ^26.0.20 '@typescript-eslint/eslint-plugin': ^4.9.0 '@typescript-eslint/parser': ^4.9.0 @@ -703,8 +743,8 @@ importers: typescript: ^4.2.3 ../../plugins/browser-plugin-site-tracking: dependencies: - '@snowplow/browser-tracker-core': 'link:../../libraries/browser-tracker-core' - '@snowplow/tracker-core': 'link:../../libraries/tracker-core' + '@snowplow/browser-tracker-core': link:../../libraries/browser-tracker-core + '@snowplow/tracker-core': link:../../libraries/tracker-core tslib: 2.1.0 devDependencies: '@rollup/plugin-commonjs': 17.1.0_rollup@2.41.1 @@ -725,8 +765,8 @@ importers: specifiers: '@rollup/plugin-commonjs': ^17.1.0 '@rollup/plugin-node-resolve': ^11.2.0 - '@snowplow/browser-tracker-core': 'workspace:*' - '@snowplow/tracker-core': 'workspace:*' + '@snowplow/browser-tracker-core': workspace:* + '@snowplow/tracker-core': workspace:* '@types/jest': ^26.0.20 '@typescript-eslint/eslint-plugin': ^4.9.0 '@typescript-eslint/parser': ^4.9.0 @@ -743,8 +783,8 @@ importers: typescript: ^4.2.3 ../../plugins/browser-plugin-timezone: dependencies: - '@snowplow/browser-tracker-core': 'link:../../libraries/browser-tracker-core' - '@snowplow/tracker-core': 'link:../../libraries/tracker-core' + '@snowplow/browser-tracker-core': link:../../libraries/browser-tracker-core + '@snowplow/tracker-core': link:../../libraries/tracker-core jstimezonedetect: 1.0.7 tslib: 2.1.0 devDependencies: @@ -769,8 +809,8 @@ importers: specifiers: '@rollup/plugin-commonjs': ^17.1.0 '@rollup/plugin-node-resolve': ^11.2.0 - '@snowplow/browser-tracker-core': 'workspace:*' - '@snowplow/tracker-core': 'workspace:*' + '@snowplow/browser-tracker-core': workspace:* + '@snowplow/tracker-core': workspace:* '@types/jest': ^26.0.20 '@types/jsdom': ^16.2.6 '@types/jstimezonedetect': ~1.0.3 @@ -791,8 +831,8 @@ importers: typescript: ^4.2.3 ../../trackers/browser-tracker: dependencies: - '@snowplow/browser-tracker-core': 'link:../../libraries/browser-tracker-core' - '@snowplow/tracker-core': 'link:../../libraries/tracker-core' + '@snowplow/browser-tracker-core': link:../../libraries/browser-tracker-core + '@snowplow/tracker-core': link:../../libraries/tracker-core tslib: 2.1.0 devDependencies: '@ampproject/rollup-plugin-closure-compiler': 0.26.0_rollup@2.41.1 @@ -822,8 +862,8 @@ importers: '@rollup/plugin-commonjs': ^17.1.0 '@rollup/plugin-json': ^4.1.0 '@rollup/plugin-node-resolve': ^11.2.0 - '@snowplow/browser-tracker-core': 'workspace:*' - '@snowplow/tracker-core': 'workspace:*' + '@snowplow/browser-tracker-core': workspace:* + '@snowplow/tracker-core': workspace:* '@types/jest': ^26.0.20 '@types/jsdom': ^16.2.6 '@types/lodash': ^4.14.168 @@ -845,26 +885,26 @@ importers: typescript: ^4.2.3 ../../trackers/javascript-tracker: dependencies: - '@snowplow/browser-plugin-ad-tracking': 'link:../../plugins/browser-plugin-ad-tracking' - '@snowplow/browser-plugin-browser-features': 'link:../../plugins/browser-plugin-browser-features' - '@snowplow/browser-plugin-client-hints': 'link:../../plugins/browser-plugin-client-hints' - '@snowplow/browser-plugin-consent': 'link:../../plugins/browser-plugin-consent' - '@snowplow/browser-plugin-ecommerce': 'link:../../plugins/browser-plugin-ecommerce' - '@snowplow/browser-plugin-enhanced-ecommerce': 'link:../../plugins/browser-plugin-enhanced-ecommerce' - '@snowplow/browser-plugin-error-tracking': 'link:../../plugins/browser-plugin-error-tracking' - '@snowplow/browser-plugin-form-tracking': 'link:../../plugins/browser-plugin-form-tracking' - '@snowplow/browser-plugin-ga-cookies': 'link:../../plugins/browser-plugin-ga-cookies' - '@snowplow/browser-plugin-geolocation': 'link:../../plugins/browser-plugin-geolocation' - '@snowplow/browser-plugin-link-click-tracking': 'link:../../plugins/browser-plugin-link-click-tracking' - '@snowplow/browser-plugin-optimizely': 'link:../../plugins/browser-plugin-optimizely' - '@snowplow/browser-plugin-optimizely-x': 'link:../../plugins/browser-plugin-optimizely-x' - '@snowplow/browser-plugin-parrable': 'link:../../plugins/browser-plugin-parrable' - '@snowplow/browser-plugin-performance-timing': 'link:../../plugins/browser-plugin-performance-timing' - '@snowplow/browser-plugin-site-tracking': 'link:../../plugins/browser-plugin-site-tracking' - '@snowplow/browser-plugin-timezone': 'link:../../plugins/browser-plugin-timezone' - '@snowplow/browser-tracker': 'link:../browser-tracker' - '@snowplow/browser-tracker-core': 'link:../../libraries/browser-tracker-core' - '@snowplow/tracker-core': 'link:../../libraries/tracker-core' + '@snowplow/browser-plugin-ad-tracking': link:../../plugins/browser-plugin-ad-tracking + '@snowplow/browser-plugin-browser-features': link:../../plugins/browser-plugin-browser-features + '@snowplow/browser-plugin-client-hints': link:../../plugins/browser-plugin-client-hints + '@snowplow/browser-plugin-consent': link:../../plugins/browser-plugin-consent + '@snowplow/browser-plugin-ecommerce': link:../../plugins/browser-plugin-ecommerce + '@snowplow/browser-plugin-enhanced-ecommerce': link:../../plugins/browser-plugin-enhanced-ecommerce + '@snowplow/browser-plugin-error-tracking': link:../../plugins/browser-plugin-error-tracking + '@snowplow/browser-plugin-form-tracking': link:../../plugins/browser-plugin-form-tracking + '@snowplow/browser-plugin-ga-cookies': link:../../plugins/browser-plugin-ga-cookies + '@snowplow/browser-plugin-geolocation': link:../../plugins/browser-plugin-geolocation + '@snowplow/browser-plugin-link-click-tracking': link:../../plugins/browser-plugin-link-click-tracking + '@snowplow/browser-plugin-optimizely': link:../../plugins/browser-plugin-optimizely + '@snowplow/browser-plugin-optimizely-x': link:../../plugins/browser-plugin-optimizely-x + '@snowplow/browser-plugin-parrable': link:../../plugins/browser-plugin-parrable + '@snowplow/browser-plugin-performance-timing': link:../../plugins/browser-plugin-performance-timing + '@snowplow/browser-plugin-site-tracking': link:../../plugins/browser-plugin-site-tracking + '@snowplow/browser-plugin-timezone': link:../../plugins/browser-plugin-timezone + '@snowplow/browser-tracker': link:../browser-tracker + '@snowplow/browser-tracker-core': link:../../libraries/browser-tracker-core + '@snowplow/tracker-core': link:../../libraries/tracker-core tslib: 2.1.0 devDependencies: '@ampproject/rollup-plugin-closure-compiler': 0.26.0_rollup@2.41.1 @@ -908,26 +948,26 @@ importers: '@rollup/plugin-commonjs': ^17.1.0 '@rollup/plugin-json': ^4.1.0 '@rollup/plugin-node-resolve': ^11.2.0 - '@snowplow/browser-plugin-ad-tracking': 'workspace:*' - '@snowplow/browser-plugin-browser-features': 'workspace:*' - '@snowplow/browser-plugin-client-hints': 'workspace:*' - '@snowplow/browser-plugin-consent': 'workspace:*' - '@snowplow/browser-plugin-ecommerce': 'workspace:*' - '@snowplow/browser-plugin-enhanced-ecommerce': 'workspace:*' - '@snowplow/browser-plugin-error-tracking': 'workspace:*' - '@snowplow/browser-plugin-form-tracking': 'workspace:*' - '@snowplow/browser-plugin-ga-cookies': 'workspace:*' - '@snowplow/browser-plugin-geolocation': 'workspace:*' - '@snowplow/browser-plugin-link-click-tracking': 'workspace:*' - '@snowplow/browser-plugin-optimizely': 'workspace:*' - '@snowplow/browser-plugin-optimizely-x': 'workspace:*' - '@snowplow/browser-plugin-parrable': 'workspace:*' - '@snowplow/browser-plugin-performance-timing': 'workspace:*' - '@snowplow/browser-plugin-site-tracking': 'workspace:*' - '@snowplow/browser-plugin-timezone': 'workspace:*' - '@snowplow/browser-tracker': 'workspace:*' - '@snowplow/browser-tracker-core': 'workspace:*' - '@snowplow/tracker-core': 'workspace:*' + '@snowplow/browser-plugin-ad-tracking': workspace:* + '@snowplow/browser-plugin-browser-features': workspace:* + '@snowplow/browser-plugin-client-hints': workspace:* + '@snowplow/browser-plugin-consent': workspace:* + '@snowplow/browser-plugin-ecommerce': workspace:* + '@snowplow/browser-plugin-enhanced-ecommerce': workspace:* + '@snowplow/browser-plugin-error-tracking': workspace:* + '@snowplow/browser-plugin-form-tracking': workspace:* + '@snowplow/browser-plugin-ga-cookies': workspace:* + '@snowplow/browser-plugin-geolocation': workspace:* + '@snowplow/browser-plugin-link-click-tracking': workspace:* + '@snowplow/browser-plugin-optimizely': workspace:* + '@snowplow/browser-plugin-optimizely-x': workspace:* + '@snowplow/browser-plugin-parrable': workspace:* + '@snowplow/browser-plugin-performance-timing': workspace:* + '@snowplow/browser-plugin-site-tracking': workspace:* + '@snowplow/browser-plugin-timezone': workspace:* + '@snowplow/browser-tracker': workspace:* + '@snowplow/browser-tracker-core': workspace:* + '@snowplow/tracker-core': workspace:* '@types/dockerode': ^3.2.2 '@types/jest': ^26.0.20 '@types/lodash': ^4.14.168 @@ -10598,7 +10638,7 @@ packages: request-promise-core: 1.1.4_request@2.88.2 stealthy-require: 1.1.1 tough-cookie: 2.5.0 - deprecated: 'request-promise-native has been deprecated because it extends the now deprecated request package, see https://github.com/request/request/issues/3142' + deprecated: request-promise-native has been deprecated because it extends the now deprecated request package, see https://github.com/request/request/issues/3142 dev: true engines: node: '>=0.12.0' @@ -10628,7 +10668,7 @@ packages: tough-cookie: 2.5.0 tunnel-agent: 0.6.0 uuid: 3.4.0 - deprecated: 'request has been deprecated, see https://github.com/request/request/issues/3142' + deprecated: request has been deprecated, see https://github.com/request/request/issues/3142 dev: true engines: node: '>= 6' @@ -10690,7 +10730,7 @@ packages: resolution: integrity: sha1-MrueOcBtZzONyTeMDW1gdFZq0TE= /resolve-url/0.2.1: - deprecated: 'https://github.com/lydell/resolve-url#deprecated' + deprecated: https://github.com/lydell/resolve-url#deprecated dev: true resolution: integrity: sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= @@ -12301,7 +12341,7 @@ packages: resolution: integrity: sha512-B0yRTzYdUCCn9n+F4+Gh4yIDtMQcaJsmYBDsTSG8g/OejKBodLQ2IHfN3bM7jUsRXndopT7OIXWdYqc1fjmV6g== /urix/0.1.0: - deprecated: 'Please see https://github.com/lydell/urix#deprecated' + deprecated: Please see https://github.com/lydell/urix#deprecated dev: true resolution: integrity: sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= diff --git a/common/config/rush/repo-state.json b/common/config/rush/repo-state.json index 9e248b4a9..b2827b39c 100644 --- a/common/config/rush/repo-state.json +++ b/common/config/rush/repo-state.json @@ -1,5 +1,5 @@ // DO NOT MODIFY THIS FILE. It is generated and used by Rush. { - "pnpmShrinkwrapHash": "bc8149e6d9b4110937fd4ad8e5a494b2d1c45f70", + "pnpmShrinkwrapHash": "ce450bc326bcb592aa18c1aaa6a8184bf7de796d", "preferredVersionsHash": "bf21a9e8fbc5a3846fb05b4fa0859e0917b2202f" } diff --git a/libraries/browser-tracker-core/src/detectors.ts b/libraries/browser-tracker-core/src/detectors.ts index dfeadd05e..4f4496bcf 100644 --- a/libraries/browser-tracker-core/src/detectors.ts +++ b/libraries/browser-tracker-core/src/detectors.ts @@ -28,7 +28,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -var windowAlias = window, +const windowAlias = window, documentAlias = document; /* diff --git a/libraries/browser-tracker-core/src/helpers.ts b/libraries/browser-tracker-core/src/helpers.ts index d6645069b..b113c3613 100755 --- a/libraries/browser-tracker-core/src/helpers.ts +++ b/libraries/browser-tracker-core/src/helpers.ts @@ -34,7 +34,7 @@ declare global { } } -var windowAlias = window, +const windowAlias = window, documentAlias = document, localStorageAlias = window.localStorage, sessionStorageAlias = window.sessionStorage; @@ -200,15 +200,6 @@ export function fromQuerystring(field: string, url: string) { return decodeURIComponent(match[1].replace(/\+/g, ' ')); } -/** - * Only log deprecation warnings if they won't cause an error - */ -export function warn(message: string) { - if (typeof console !== 'undefined') { - console.warn('Snowplow: ' + message); - } -} - /** * Add a name-value pair to the querystring of a URL * diff --git a/libraries/browser-tracker-core/src/snowplow.ts b/libraries/browser-tracker-core/src/snowplow.ts index 0c36ef5ff..3de76756c 100644 --- a/libraries/browser-tracker-core/src/snowplow.ts +++ b/libraries/browser-tracker-core/src/snowplow.ts @@ -28,7 +28,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -import { warn } from './helpers'; +import { LOG } from '@snowplow/tracker-core'; import { SharedState } from './state'; import { Tracker } from './tracker'; import { BrowserTracker, TrackerConfiguration } from './tracker/types'; @@ -44,8 +44,8 @@ const namedTrackers: Record = {}; export function dispatchToTrackers(trackers: Array | undefined, fn: (t: BrowserTracker) => void) { try { getTrackers(trackers ?? allTrackerNames()).forEach(fn); - } catch { - warn('function failed'); + } catch (ex) { + LOG.error('Function failed', ex); } } @@ -63,8 +63,8 @@ export function dispatchToTrackersInCollection( ) { try { getTrackersFromCollection(trackers ?? Object.keys(trackerCollection), trackerCollection).forEach(fn); - } catch { - warn('function failed'); + } catch (ex) { + LOG.error('Function failed', ex); } } @@ -110,7 +110,7 @@ export function getTracker(trackerId: string) { return namedTrackers[trackerId]; } - warn(trackerId + ' not configured'); + LOG.warn(trackerId + ' not configured'); return null; } @@ -146,7 +146,7 @@ function getTrackersFromCollection( if (trackerCollection.hasOwnProperty(id)) { trackers.push(trackerCollection[id]); } else { - warn(id + ' not configured'); + LOG.warn(id + ' not configured'); } } return trackers; diff --git a/libraries/browser-tracker-core/src/state.ts b/libraries/browser-tracker-core/src/state.ts index 27c353074..b9c82be66 100644 --- a/libraries/browser-tracker-core/src/state.ts +++ b/libraries/browser-tracker-core/src/state.ts @@ -37,6 +37,9 @@ declare global { } } +const documentAlias = document, + windowAlias = window; + /** * A set of variables which are shared among all initialised trackers */ @@ -55,9 +58,7 @@ export class SharedState { } export function createSharedState(): SharedState { - const documentAlias = document, - windowAlias = window, - sharedState = new SharedState(); + const sharedState = new SharedState(); /* * Handle page visibility event diff --git a/libraries/browser-tracker-core/src/tracker/index.ts b/libraries/browser-tracker-core/src/tracker/index.ts index 96b060e55..69d960701 100755 --- a/libraries/browser-tracker-core/src/tracker/index.ts +++ b/libraries/browser-tracker-core/src/tracker/index.ts @@ -35,6 +35,7 @@ import { CommonEventProperties, PayloadBuilder, SelfDescribingJson, + LOG, } from '@snowplow/tracker-core'; import hash from 'sha1'; import { v4 as uuid } from 'uuid'; @@ -52,7 +53,6 @@ import { attemptDeleteLocalStorage, deleteCookie, fixupTitle, - warn, fromQuerystring, isInteger, } from '../helpers'; @@ -103,6 +103,11 @@ type ActivityTrackingConfig = { configurations: ActivityConfigurations; }; +const documentAlias = document, + windowAlias = window, + navigatorAlias = navigator, + screenAlias = screen; + /** * The Snowplow Tracker * @@ -168,10 +173,6 @@ export function Tracker( }, }), // Aliases - documentAlias = document, - windowAlias = window, - navigatorAlias = navigator, - screenAlias = screen, browserLanguage = (navigatorAlias as any).userLanguage || navigatorAlias.language, documentCharset = documentAlias.characterSet || documentAlias.charset, // Current URL and Referrer URL @@ -1027,7 +1028,9 @@ export function Tracker( }; } - warn('Activity tracking not enabled, please provide integer values for minimumVisitLength and heartbeatDelay.'); + LOG.warn( + 'Activity tracking not enabled, please provide integer values for minimumVisitLength and heartbeatDelay.' + ); return undefined; } diff --git a/libraries/browser-tracker-core/src/tracker/out_queue.ts b/libraries/browser-tracker-core/src/tracker/out_queue.ts index 34211c336..b0c030509 100644 --- a/libraries/browser-tracker-core/src/tracker/out_queue.ts +++ b/libraries/browser-tracker-core/src/tracker/out_queue.ts @@ -28,10 +28,10 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -import { warn, attemptWriteLocalStorage, isString } from '../helpers'; +import { attemptWriteLocalStorage, isString } from '../helpers'; import { SharedState } from '../state'; import { localStorageAccessible } from '../detectors'; -import { Payload } from '@snowplow/tracker-core'; +import { LOG, Payload } from '@snowplow/tracker-core'; export interface OutQueue { enqueueRequest: (request: Payload, url: string) => void; @@ -218,7 +218,7 @@ export function OutQueueManager( if (usePost) { const body = getBody(request); if (body.bytes >= maxPostBytes) { - warn('Event (' + body.bytes + 'B) too big, max is ' + maxPostBytes); + LOG.warn('Event (' + body.bytes + 'B) too big, max is ' + maxPostBytes); const xhr = initializeXMLHttpRequest(configCollectorUrl, true, false); xhr.send(encloseInPayloadDataEnvelope(attachStmToEvent([body.evt]))); return; diff --git a/libraries/tracker-core/src/contexts.ts b/libraries/tracker-core/src/contexts.ts index 91d44a451..59dfb61bc 100644 --- a/libraries/tracker-core/src/contexts.ts +++ b/libraries/tracker-core/src/contexts.ts @@ -30,8 +30,8 @@ import { PayloadBuilder, Payload, isNonEmptyJson } from './payload'; import { SelfDescribingJson } from './core'; -import { base64urldecode } from './base64'; import { CorePlugin } from './plugins'; +import { LOG } from './logger'; /** * Argument for {@link ContextGenerator} and {@link ContextFilter} callback @@ -148,7 +148,7 @@ export function globalContexts(): GlobalContexts { * @param event The event to check for applicable global contexts for * @returns An array of contexts */ - const assembleAllContexts = (event: Payload): Array => { + const assembleAllContexts = (event: PayloadBuilder): Array => { const eventSchema = getUsefulSchema(event); const eventType = getEventType(event); const contexts: Array = []; @@ -202,13 +202,7 @@ export function globalContexts(): GlobalContexts { }, getApplicableContexts(event: PayloadBuilder): Array { - const builtEvent = event.build(); - if (isEventJson(builtEvent)) { - const decodedEvent = getDecodedEvent(builtEvent); - return assembleAllContexts(decodedEvent); - } else { - return []; - } + return assembleAllContexts(event); }, }; } @@ -237,7 +231,7 @@ export function pluginContexts(plugins: Array): PluginContexts { combinedContexts.push(...plugin.contexts()); } } catch (ex) { - console.warn('Snowplow: error with plugin context', ex); + LOG.error('Error adding plugin contexts', ex); } }); @@ -394,17 +388,6 @@ export function isSelfDescribingJson(input: unknown): input is SelfDescribingJso return false; } -/** - * Check if a variable to is a valid, non-empty Payload event by looking for the 'e' parameter of a Payload - * @param input The variable to validate - * @returns True if a valid Payload - */ -export function isEventJson(input: unknown): input is Payload { - const payload = input as Payload; - if (isNonEmptyJson(payload) && 'e' in payload) return typeof payload.e === 'string'; - return false; -} - /** * Validates if the input object contains the expected properties of a ruleset * @param input The object containing a rule set @@ -568,38 +551,29 @@ function matchPart(rule: string, schema: string): boolean { } // Returns the "useful" schema, i.e. what would someone want to use to identify events. -// The idea being that you can determine the event type from 'e', so getting the schema from -// 'ue_px.schema'/'ue_pr.schema' would be redundant - it'll return the unstruct_event schema. -// Instead the schema nested inside the unstruct_event is more useful! -// This doesn't decode ue_px, it works because it's called by code that has already decoded it -function getUsefulSchema(sb: Payload): string { - if (typeof (sb['ue_px'] as SelfDescribingJson)?.['data']?.['schema'] === 'string') - return (sb['ue_px'] as SelfDescribingJson)?.['data']?.['schema']; - else if (typeof (sb['ue_pr'] as SelfDescribingJson)?.['data']?.['schema'] === 'string') - return (sb['ue_pr'] as SelfDescribingJson)?.['data']?.['schema']; - else if (typeof (sb as SelfDescribingJson)?.['schema'] === 'string') return (sb as SelfDescribingJson)?.['schema']; - return ''; -} - -function getDecodedEvent(sb: Payload): Payload { - const decodedEvent = { ...sb }; // spread operator, instantiates new object - try { - if (Object.prototype.hasOwnProperty.call(decodedEvent, 'ue_px')) { - decodedEvent['ue_px'] = JSON.parse(base64urldecode(decodedEvent['ue_px'] as string)); +// For some events this is the 'e' property but for unstructured events, this is the +// 'schema' from the 'ue_px' field. +function getUsefulSchema(sb: PayloadBuilder): string { + let eventJson = sb.getJson(); + for (const json of eventJson) { + if (json.length === 3 && json[0] === 'ue_px' && typeof json[2]['data'] === 'object') { + const schema = (json[2]['data'] as Record)['schema']; + if (typeof schema == 'string') { + return schema; + } } - return decodedEvent; - } catch (e) { - return decodedEvent; } + return ''; } -function getEventType(sb: Record): string { - return (sb?.['e'] ?? '') as string; +function getEventType(payloadBuilder: PayloadBuilder): string { + const eventType = payloadBuilder.getPayload()['e']; + return typeof eventType === 'string' ? eventType : ''; } function buildGenerator( generator: ContextGenerator, - event: Payload, + event: PayloadBuilder, eventType: string, eventSchema: string ): SelfDescribingJson | Array | undefined { @@ -607,7 +581,7 @@ function buildGenerator( try { // try to evaluate context generator const args = { - event: event, + event: event.getPayload(), eventType: eventType, eventSchema: eventSchema, }; @@ -635,7 +609,7 @@ function normalizeToArray(input: Array | T): Array { function generatePrimitives( contextPrimitives: Array | ContextPrimitive, - event: Payload, + event: PayloadBuilder, eventType: string, eventSchema: string ): Array { @@ -655,7 +629,7 @@ function generatePrimitives( function evaluatePrimitive( contextPrimitive: ContextPrimitive, - event: Payload, + event: PayloadBuilder, eventType: string, eventSchema: string ): Array | undefined { @@ -674,7 +648,7 @@ function evaluatePrimitive( function evaluateProvider( provider: ConditionalContextProvider, - event: Payload, + event: PayloadBuilder, eventType: string, eventSchema: string ): Array { @@ -683,7 +657,7 @@ function evaluateProvider( let filterResult = false; try { const args = { - event: event, + event: event.getPayload(), eventType: eventType, eventSchema: eventSchema, }; @@ -704,7 +678,7 @@ function evaluateProvider( function generateConditionals( providers: Array | ConditionalContextProvider, - event: Payload, + event: PayloadBuilder, eventType: string, eventSchema: string ): Array { diff --git a/libraries/tracker-core/src/core.ts b/libraries/tracker-core/src/core.ts index f7ef3a6cb..ceeffac8b 100644 --- a/libraries/tracker-core/src/core.ts +++ b/libraries/tracker-core/src/core.ts @@ -39,6 +39,7 @@ import { pluginContexts, } from './contexts'; import { CorePlugin } from './plugins'; +import { LOG } from './logger'; /** * export interface for any Self-Describing JSON such as context or Self Describing events @@ -285,6 +286,10 @@ export interface TrackerCore { */ removeGlobalContexts(contexts: Array): void; + /** + * Add a plugin into the plugin collection after Core has already been initialised + * @param plugin The plugin to add + */ addPlugin(plugin: CorePlugin): void; } @@ -381,7 +386,7 @@ export function trackerCore(configuration: CoreConfiguration = {}): TrackerCore plugin.beforeTrack(pb); } } catch (ex) { - console.warn('Snowplow: error with plugin beforeTrack', ex); + LOG.error('Plugin beforeTrack', ex); } }); @@ -397,7 +402,7 @@ export function trackerCore(configuration: CoreConfiguration = {}): TrackerCore plugin.afterTrack(finalPayload); } } catch (ex) { - console.warn('Snowplow: error with plugin ', ex); + LOG.error('Plugin afterTrack', ex); } }); @@ -515,6 +520,7 @@ export function trackerCore(configuration: CoreConfiguration = {}): TrackerCore }; plugins?.forEach((plugin) => { + plugin.logger?.(LOG); plugin.activateCorePlugin?.(core); }); diff --git a/libraries/tracker-core/src/index.ts b/libraries/tracker-core/src/index.ts index 51051606e..0797789ae 100644 --- a/libraries/tracker-core/src/index.ts +++ b/libraries/tracker-core/src/index.ts @@ -39,3 +39,4 @@ export * from './contexts'; export * from './plugins'; export * from './payload'; export * from './core'; +export { LOG, LOG_LEVEL, Logger } from './logger'; diff --git a/libraries/tracker-core/src/logger.ts b/libraries/tracker-core/src/logger.ts new file mode 100644 index 000000000..7f49cb9f9 --- /dev/null +++ b/libraries/tracker-core/src/logger.ts @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2021 Snowplow Analytics Ltd, 2010 Anthon Pang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +const label = 'Snowplow: '; + +export enum LOG_LEVEL { + none = 0, + error = 1, + warn = 2, + debug = 3, + info = 4, +} + +export interface Logger { + setLogLevel: (level: LOG_LEVEL) => void; + info: (message: string, ...extraParams: unknown[]) => void; + debug: (message: string, ...extraParams: unknown[]) => void; + warn: (message: string, error?: Error, ...extraParams: unknown[]) => void; + error: (message: string, error?: Error, ...extraParams: unknown[]) => void; +} + +export const LOG = logger(); + +function logger(logLevel: LOG_LEVEL = LOG_LEVEL.warn): Logger { + function setLogLevel(level: LOG_LEVEL) { + if (LOG_LEVEL[level]) { + logLevel = level; + } else { + logLevel = LOG_LEVEL.warn; + } + } + + /** + * Log errors, with or without error object + */ + function error(message: string, error?: Error, ...extraParams: unknown[]) { + if (logLevel >= LOG_LEVEL.error && typeof console !== 'undefined') { + const logMsg = label + message + '\n'; + if (error) { + console.error(logMsg + '\n', error, ...extraParams); + } else { + console.error(logMsg, ...extraParams); + } + } + } + + /** + * Log warnings, with or without error object + */ + function warn(message: string, error?: Error, ...extraParams: unknown[]) { + if (logLevel >= LOG_LEVEL.warn && typeof console !== 'undefined') { + if (typeof console !== 'undefined') { + const logMsg = label + message; + if (error) { + console.warn(logMsg + '\n', error, ...extraParams); + } else { + console.warn(logMsg, ...extraParams); + } + } + } + } + + /** + * Log debug messages + */ + function debug(message: string, ...extraParams: unknown[]) { + if (logLevel >= LOG_LEVEL.debug && typeof console !== 'undefined') { + if (typeof console !== 'undefined') { + console.warn(label + message, ...extraParams); + } + } + } + + /** + * Log info messages + */ + function info(message: string, ...extraParams: unknown[]) { + if (logLevel >= LOG_LEVEL.info && typeof console !== 'undefined') { + if (typeof console !== 'undefined') { + console.info(label + message, ...extraParams); + } + } + } + + return { setLogLevel, warn, error, debug, info }; +} diff --git a/libraries/tracker-core/src/payload.ts b/libraries/tracker-core/src/payload.ts index 0b4aea195..dfc0d1f73 100644 --- a/libraries/tracker-core/src/payload.ts +++ b/libraries/tracker-core/src/payload.ts @@ -36,14 +36,19 @@ import { base64urlencode } from './base64'; export type Payload = Record; /** - * An array of tuples which represented the unprocessed JSON to be added to the Payload + * A tuple which represents the unprocessed JSON to be added to the Payload */ -export type JsonForProcessing = Array<[keyIfEncoded: string, keyIfNotEncoded: string, json: Record]>; +export type EventJsonWithKeys = [keyIfEncoded: string, keyIfNotEncoded: string, json: Record]; + +/** + * An array of tuples which represents the unprocessed JSON to be added to the Payload + */ +export type EventJson = Array; /** * A function which will processor the Json onto the injected PayloadBuilder */ -export type JsonProcessor = (payloadBuilder: PayloadBuilder, jsonForProcessing: JsonForProcessing) => void; +export type JsonProcessor = (payloadBuilder: PayloadBuilder, jsonForProcessing: EventJson) => void; /** * Interface for mutable object encapsulating tracker payload @@ -70,6 +75,16 @@ export interface PayloadBuilder { */ addJson: (keyIfEncoded: string, keyIfNotEncoded: string, json: Record) => void; + /** + * Gets the current payload, before cached JSON is processed + */ + getPayload: () => Payload; + + /** + * Gets all JSON objects added to payload + */ + getJson: () => EventJson; + /** * Adds a function which will be executed when building * the payload to process the JSON which has been added to this payload @@ -79,14 +94,15 @@ export interface PayloadBuilder { /** * Builds and returns the Payload - * @param base64Encode configures if cached json should be encoded + * @param base64Encode configures if unprocessed, cached json should be encoded */ build: () => Payload; } export function payloadBuilder(): PayloadBuilder { const dict: Payload = {}, - jsonForProcessing: JsonForProcessing = []; + allJson: EventJson = [], + jsonForProcessing: EventJson = []; let processor: JsonProcessor | undefined; const add = (key: string, value: unknown): void => { @@ -106,7 +122,9 @@ export function payloadBuilder(): PayloadBuilder { const addJson = (keyIfEncoded: string, keyIfNotEncoded: string, json?: Record): void => { if (json && isNonEmptyJson(json)) { - jsonForProcessing.push([keyIfEncoded, keyIfNotEncoded, json]); + const jsonWithKeys: EventJsonWithKeys = [keyIfEncoded, keyIfNotEncoded, json]; + jsonForProcessing.push(jsonWithKeys); + allJson.push(jsonWithKeys); } }; @@ -114,6 +132,8 @@ export function payloadBuilder(): PayloadBuilder { add, addDict, addJson, + getPayload: () => dict, + getJson: () => allJson, withJsonProcessor: (jsonProcessor) => { processor = jsonProcessor; }, @@ -131,7 +151,7 @@ export function payloadBuilder(): PayloadBuilder { * @return The request builder, with add and build methods */ export function payloadJsonProcessor(encodeBase64: boolean): JsonProcessor { - return (payloadBuilder: PayloadBuilder, jsonForProcessing: JsonForProcessing) => { + return (payloadBuilder: PayloadBuilder, jsonForProcessing: EventJson) => { for (const json of jsonForProcessing) { const str = JSON.stringify(json[2]); if (encodeBase64) { diff --git a/libraries/tracker-core/src/plugins.ts b/libraries/tracker-core/src/plugins.ts index f23803d14..16499c342 100644 --- a/libraries/tracker-core/src/plugins.ts +++ b/libraries/tracker-core/src/plugins.ts @@ -29,6 +29,7 @@ */ import { TrackerCore, SelfDescribingJson } from './core'; +import { Logger } from './logger'; import { Payload, PayloadBuilder } from './payload'; /** @@ -57,4 +58,9 @@ export interface CorePlugin { * Useful for adding additional context to events */ contexts?: () => SelfDescribingJson[]; + /** + * Passed a logger instance which can be used to send log information + * to the active logger + */ + logger?: (logger: Logger) => void; } diff --git a/libraries/tracker-core/test/contexts.ts b/libraries/tracker-core/test/contexts.ts index 77ca1a292..c8fa7f4c2 100644 --- a/libraries/tracker-core/test/contexts.ts +++ b/libraries/tracker-core/test/contexts.ts @@ -30,7 +30,7 @@ import test from 'ava'; import * as contexts from '../src/contexts'; -import { payloadBuilder, Payload } from '../src/payload'; +import { payloadBuilder } from '../src/payload'; import { SelfDescribingJson } from '../src/core'; test('Identify context primitives', (t) => { @@ -334,24 +334,17 @@ test('Get applicable contexts', (t) => { [geolocationContext, eventTypeContextGenerator], ]; - const eventJson: Payload = { - e: 'ue', - ue_px: { - schema: 'iglu:com.snowplowanalytics.snowplow/unstruct_event/jsonschema/1-0-0', - data: { - schema: 'iglu:com.acme_company/some_event/jsonschema/1-0-0', - data: {}, - }, - }, - }; const contextArray = [filterProvider, ruleSetProvider, geolocationContext, eventTypeContextGenerator]; const globalContexts = contexts.globalContexts(); const event = payloadBuilder(); - for (const property in eventJson) { - if (Object.prototype.hasOwnProperty.call(eventJson, property)) { - event.add(property, eventJson[property]); - } - } + event.add('e', 'ue'); + event.addJson('ue_px', 'ue_pr', { + schema: 'iglu:com.snowplowanalytics.snowplow/unstruct_event/jsonschema/1-0-0', + data: { + schema: 'iglu:com.acme_company/some_event/jsonschema/1-0-0', + data: {}, + }, + }); globalContexts.addGlobalContexts(contextArray); t.is(globalContexts.getApplicableContexts(event).length, 6); diff --git a/plugins/browser-plugin-consent/src/index.ts b/plugins/browser-plugin-consent/src/index.ts index f288b533a..c570c5441 100644 --- a/plugins/browser-plugin-consent/src/index.ts +++ b/plugins/browser-plugin-consent/src/index.ts @@ -28,13 +28,14 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -import { BrowserPlugin, BrowserTracker, dispatchToTrackersInCollection, warn } from '@snowplow/browser-tracker-core'; +import { BrowserPlugin, BrowserTracker, dispatchToTrackersInCollection } from '@snowplow/browser-tracker-core'; import { buildConsentGranted, buildConsentWithdrawn, CommonEventProperties, ConsentGrantedEvent, ConsentWithdrawnEvent, + Logger, } from '@snowplow/tracker-core'; import { Gdpr } from './contexts'; @@ -65,6 +66,39 @@ export interface GdprContextConfiguration { const _trackers: Record = {}; const _context: Record = {}; +let LOG: Logger; + +/** + * The Consent Plugin + * + * Adds Consent Granted and Withdrawn events + * and the ability to add the GDPR context to events + */ +export function ConsentPlugin(): BrowserPlugin { + let trackerId: string; + + return { + activateBrowserPlugin: (tracker) => { + trackerId = tracker.id; + _trackers[tracker.id] = tracker; + }, + contexts: () => { + if (_context[trackerId]) { + return [ + { + schema: 'iglu:com.snowplowanalytics.snowplow/gdpr/jsonschema/1-0-0', + data: _context[trackerId], + }, + ]; + } + + return []; + }, + logger: (logger) => { + LOG = logger; + }, + }; +} /** * Enable the GDPR context for each event @@ -79,7 +113,7 @@ export function enableGdprContext( let basis = gdprBasis[basisForProcessing]; if (!basis) { - warn( + LOG.warn( 'enableGdprContext: basisForProcessing must be one of: consent, contract, legalObligation, vitalInterests, publicTask, legitimateInterests' ); return; @@ -136,32 +170,3 @@ export function trackConsentWithdrawn( ); }); } - -/** - * The Consent Plugin - * - * Adds Consent Granted and Withdrawn events - * and the ability to add the GDPR context to events - */ -export function ConsentPlugin(): BrowserPlugin { - let trackerId: string; - - return { - activateBrowserPlugin: (tracker) => { - trackerId = tracker.id; - _trackers[tracker.id] = tracker; - }, - contexts: () => { - if (_context[trackerId]) { - return [ - { - schema: 'iglu:com.snowplowanalytics.snowplow/gdpr/jsonschema/1-0-0', - data: _context[trackerId], - }, - ]; - } - - return []; - }, - }; -} diff --git a/plugins/browser-plugin-debugger/LICENSE b/plugins/browser-plugin-debugger/LICENSE new file mode 100644 index 000000000..b7452e52b --- /dev/null +++ b/plugins/browser-plugin-debugger/LICENSE @@ -0,0 +1,29 @@ +BSD 3-Clause License + +Copyright (c) 2021 Snowplow Analytics Ltd, 2010 Anthon Pang +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/plugins/browser-plugin-debugger/README.md b/plugins/browser-plugin-debugger/README.md new file mode 100644 index 000000000..21c7bbcd7 --- /dev/null +++ b/plugins/browser-plugin-debugger/README.md @@ -0,0 +1,56 @@ +# Snowplow Advertising Tracking + +[![npm version][npm-image]][npm-url] +[![License][license-image]](LICENSE) + +Browser Plugin to be used with `@snowplow/browser-tracker`. + +Adds debugging to your Snowplow tracking. + +## Maintainer quick start + +Part of the Snowplow JavaScript Tracker monorepo. +Build with [Node](https://nodejs.org/en/) (10+) and [Rush](https://rushjs.io/). + +### Setup repository + +```bash +$ npm install -g @microsoft/rush +$ git clone https://github.com/snowplow/snowplow-javascript-tracker.git +$ rush update +``` + +## Package Installation + +With npm: + +```bash +npm install @snowplow/browser-plugin-debugger +``` + +## Usage + +Initialize your tracker with the DebuggerPlugin: + +```js +import { newTracker } from '@snowplow/browser-tracker'; +import { DebuggerPlugin } from '@snowplow/browser-plugin-debugger'; + +newTracker('sp1', '{{collector}}', { plugins: [ DebuggerPlugin() ] }); // Also stores reference at module level +``` + +Then additional debugging information will be available in your browsers Developer Tools. + +## Copyright and license + +Licensed and distributed under the [BSD 3-Clause License](LICENSE) ([An OSI Approved License][osi]). + +Copyright (c) 2021 Snowplow Analytics Ltd, 2010 Anthon Pang. + +All rights reserved. + +[npm-url]: https://www.npmjs.com/package/@snowplow/browser-plugin-ad-tracking +[npm-image]: https://img.shields.io/npm/v/@snowplow/browser-plugin-ad-tracking +[docs]: https://docs.snowplowanalytics.com/docs/collecting-data/collecting-from-own-applications/javascript-tracker/ +[osi]: https://opensource.org/licenses/BSD-3-Clause +[license-image]: https://img.shields.io/github/license/snowplow/snowplow-javascript-tracker diff --git a/plugins/browser-plugin-debugger/package.json b/plugins/browser-plugin-debugger/package.json new file mode 100644 index 000000000..47c06ce8e --- /dev/null +++ b/plugins/browser-plugin-debugger/package.json @@ -0,0 +1,45 @@ +{ + "name": "@snowplow/browser-plugin-debugger", + "version": "2.17.3", + "description": "Debugger for Snowplow", + "homepage": "http://bit.ly/sp-js", + "bugs": "https://github.com/snowplow/snowplow-javascript-tracker/issues", + "repository": { + "type": "git", + "url": "https://github.com/snowplow/snowplow-javascript-tracker.git" + }, + "license": "BSD-3-Clause", + "author": "Paul Boocock", + "main": "./dist/index.umd.js", + "module": "./dist/index.module.js", + "types": "./dist/index.module.d.ts", + "files": [ + "dist" + ], + "scripts": { + "build": "rollup -c --silent --failAfterWarnings", + "test": "" + }, + "dependencies": { + "@snowplow/browser-tracker-core": "workspace:*", + "@snowplow/tracker-core": "workspace:*", + "tslib": "^2.1.0" + }, + "devDependencies": { + "@rollup/plugin-commonjs": "^17.1.0", + "@rollup/plugin-node-resolve": "^11.2.0", + "@types/jest": "^26.0.20", + "@typescript-eslint/eslint-plugin": "^4.9.0", + "@typescript-eslint/parser": "^4.9.0", + "@wessberg/rollup-plugin-ts": "^1.3.8", + "eslint": "^7.7.0", + "jest": "^26.6.3", + "jest-standard-reporter": "^2.0.0", + "rollup": "^2.41.1", + "rollup-plugin-cleanup": "^3.2.1", + "rollup-plugin-license": "^2.2.0", + "rollup-plugin-terser": "^7.0.2", + "ts-jest": "^26.5.0", + "typescript": "^4.2.3" + } +} diff --git a/plugins/browser-plugin-debugger/rollup.config.js b/plugins/browser-plugin-debugger/rollup.config.js new file mode 100644 index 000000000..b8cb1a15b --- /dev/null +++ b/plugins/browser-plugin-debugger/rollup.config.js @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2021 Snowplow Analytics Ltd, 2010 Anthon Pang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +import { nodeResolve } from '@rollup/plugin-node-resolve'; +import commonjs from '@rollup/plugin-commonjs'; +import ts from '@wessberg/rollup-plugin-ts'; // Prefered over @rollup/plugin-typescript as it bundles .d.ts files +import { banner } from '../../banner'; +import compiler from '@ampproject/rollup-plugin-closure-compiler'; +import { terser } from 'rollup-plugin-terser'; +import cleanup from 'rollup-plugin-cleanup'; +import pkg from './package.json'; +import { builtinModules } from 'module'; + +const umdPlugins = [nodeResolve({ browser: true }), commonjs(), ts()]; +const umdName = 'snowplowAdTracking'; + +export default [ + // CommonJS (for Node) and ES module (for bundlers) build. + { + input: './src/index.ts', + plugins: [...umdPlugins, banner()], + treeshake: { moduleSideEffects: ['sha1'] }, + output: [{ file: pkg.main, format: 'umd', sourcemap: true, name: umdName }], + }, + { + input: './src/index.ts', + plugins: [...umdPlugins, compiler(), terser(), cleanup({ comments: 'none' }), banner()], + treeshake: { moduleSideEffects: ['sha1'] }, + output: [{ file: pkg.main.replace('.js', '.min.js'), format: 'umd', sourcemap: true, name: umdName }], + }, + { + input: './src/index.ts', + external: [...builtinModules, ...Object.keys(pkg.dependencies), ...Object.keys(pkg.devDependencies)], + plugins: [ + ts(), // so Rollup can convert TypeScript to JavaScript + banner(), + ], + output: [{ file: pkg.module, format: 'es', sourcemap: true }], + }, +]; diff --git a/plugins/browser-plugin-debugger/src/index.ts b/plugins/browser-plugin-debugger/src/index.ts new file mode 100644 index 000000000..b4cc90a1e --- /dev/null +++ b/plugins/browser-plugin-debugger/src/index.ts @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2021 Snowplow Analytics Ltd, 2010 Anthon Pang + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +import { BrowserPlugin, BrowserTracker } from '@snowplow/browser-tracker-core'; +import { + EventJson, + EventJsonWithKeys, + JsonProcessor, + Logger, + LOG_LEVEL, + Payload, + PayloadBuilder, + payloadJsonProcessor, +} from '@snowplow/tracker-core'; + +/** + * Adds advertisement tracking functions + */ +export function DebuggerPlugin(logLevel: LOG_LEVEL = LOG_LEVEL.debug): BrowserPlugin { + let LOG: Logger; + let tracker: BrowserTracker; + + function jsonInterceptor(encodeBase64: boolean): JsonProcessor { + return (payloadBuilder: PayloadBuilder, jsonForProcessing: EventJson) => { + if (jsonForProcessing.length) { + for (const json of jsonForProcessing) { + LOG.debug(`${tracker.id}: ${getJsonType(json)} JSON`, json[2]); + } + } + return payloadJsonProcessor(encodeBase64)(payloadBuilder, jsonForProcessing); + }; + } + + return { + logger: (logger) => { + LOG = logger; + LOG.setLogLevel(logLevel); + }, + activateBrowserPlugin: (t) => { + tracker = t; + LOG.debug(`${tracker.id}: Tracker Activated`); + }, + beforeTrack: (payloadBuilder: PayloadBuilder) => { + payloadBuilder.withJsonProcessor(jsonInterceptor(tracker.core.getBase64Encoding())); + const payload = payloadBuilder.build(); + LOG.debug(`${tracker.id}: Tracking event`, payload['e']); + }, + afterTrack: (payload: Payload) => { + LOG.debug(`${tracker.id}: Tracked event`, payload); + }, + }; +} + +function getJsonType(json: EventJsonWithKeys) { + switch (json[0]) { + case 'cx': + return 'Context'; + case 'ue_px': + return 'Unstructured event'; + default: + return `${json[0]}, ${json[1]}`; + } +} diff --git a/plugins/browser-plugin-debugger/tsconfig.json b/plugins/browser-plugin-debugger/tsconfig.json new file mode 100644 index 000000000..4082f16a5 --- /dev/null +++ b/plugins/browser-plugin-debugger/tsconfig.json @@ -0,0 +1,3 @@ +{ + "extends": "../../tsconfig.json" +} diff --git a/rush.json b/rush.json index 18df76aa2..9c9e7e647 100644 --- a/rush.json +++ b/rush.json @@ -514,6 +514,12 @@ "projectFolder": "plugins/browser-plugin-site-tracking", "reviewCategory": "plugins", "versionPolicyName": "tracker" + }, + { + "packageName": "@snowplow/browser-plugin-debugger", + "projectFolder": "plugins/browser-plugin-debugger", + "reviewCategory": "plugins", + "versionPolicyName": "tracker" } ] } diff --git a/trackers/javascript-tracker/src/in_queue.ts b/trackers/javascript-tracker/src/in_queue.ts index 87d916bcc..456e6d86f 100644 --- a/trackers/javascript-tracker/src/in_queue.ts +++ b/trackers/javascript-tracker/src/in_queue.ts @@ -28,9 +28,8 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -import { isStringArray } from '@snowplow/tracker-core'; +import { isStringArray, LOG } from '@snowplow/tracker-core'; import { - warn, isFunction, addTracker, createSharedState, @@ -100,11 +99,11 @@ export function InQueueManager(functionName: string, asyncQueue: Array) if (availableFunctions[f]) { try { availableFunctions[f].apply(null, parameters); - } catch { - warn(f + ' did not succeed'); + } catch (ex) { + LOG.error(f + ' failed', ex); } } else { - warn(f + ' is not an available function'); + LOG.warn(f + ' is not an available function'); } } @@ -141,7 +140,7 @@ export function InQueueManager(functionName: string, asyncQueue: Array) if (tracker) { availableTrackerIds.push(tracker.id); } else { - warn(parameterArray[0] + ' already exists'); + LOG.warn(parameterArray[0] + ' already exists'); return; } @@ -149,7 +148,7 @@ export function InQueueManager(functionName: string, asyncQueue: Array) updateAvailableFunctions(p[1]); }); } else { - warn('Invalid newTracker call'); + LOG.error('newTracker failed', new Error('Invalid parameters')); } } @@ -182,7 +181,7 @@ export function InQueueManager(functionName: string, asyncQueue: Array) 'error', () => { postScriptHandler(scriptSrc); - warn(`failed to load plugin ${constructorPath[0]} from ${scriptSrc}`); + LOG.warn(`failed to load plugin ${constructorPath[0]} from ${scriptSrc}`); }, true ); @@ -239,8 +238,8 @@ export function InQueueManager(functionName: string, asyncQueue: Array) fnTrackers[tracker.id.replace(`${functionName}_`, '')] = tracker; } input.apply(fnTrackers, parameterArray); - } catch (e) { - warn(`Custom callback error - ${e}`); + } catch (ex) { + LOG.error('Tracker callback failed', ex); } finally { continue; }