Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions jest.config.base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,15 @@ const config: JestConfigWithTsJest = {
],

// A map from regular expressions to module names or to arrays of module names that allow to stub out resources with a single module
// moduleNameMapper: {},
// moduleNameMapper: {
// '^@metamask/sdk$': '<rootDir>/packages/sdk/src/index.ts',
// '^@metamask/sdk-communication-layer$': '<rootDir>/packages/sdk-communication-layer/src/index.ts',
// '^@metamask/analytics-client$': '<rootDir>/packages/analytics-client/src/index.ts',
// '^@metamask/sdk-types$': '<rootDir>/packages/sdk-types/src/index.ts',
// '^@metamask/sdk-install-modal-web$': '<rootDir>/packages/sdk-install-modal-web/src/index.ts',
// '^@metamask/sdk-react$': '<rootDir>/packages/sdk-react/src/index.ts',
// // Add react-native if needed
// },

// An array of regexp pattern strings, matched against all module paths before considered 'visible' to the module loader
// modulePathIgnorePatterns: [],
Expand Down Expand Up @@ -176,7 +184,7 @@ const config: JestConfigWithTsJest = {
},

// An array of regexp pattern strings that are matched against all source file paths, matched files will skip transformation
transformIgnorePatterns: ['/node_modules/', '\\.pnp\\.[^\\/]+$'],
transformIgnorePatterns: ['/node_modules/', '\\\\.pnp\\\\.[^\\\\/]+$'],

// An array of regexp pattern strings that are matched against all modules before the module loader will automatically return a mock for them
// unmockedModulePathPatterns: undefined,
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"packages/sdk-react-native",
"packages/sdk-react-ui",
"packages/sdk-ui",
"packages/sdk-types",
"packages/sdk-lab",
"packages/devsocket",
"packages/devreact",
Expand Down
34 changes: 34 additions & 0 deletions packages/analytics-client/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
const path = require('path');

/**
* @type {import('eslint').Linter.Config}
*/
module.exports = {
extends: ['@metamask/eslint-config-typescript', '../../.eslintrc.js'],
root: true,
parser: '@typescript-eslint/parser',
parserOptions: {
project: [path.resolve(__dirname, 'tsconfig.eslint.json')],
},

ignorePatterns: [
'.prettierrc.js',
'**/.eslintrc.js',
'**/jest.config.ts',
'**/dist*/',
],

overrides: [
{
files: ['**/*.ts'],
rules: {
// Add any specific rule overrides for analytics-client here if needed
// Example:
// '@typescript-eslint/consistent-type-definitions': [
// 'error',
// 'interface',
// ],
},
},
],
};
84 changes: 60 additions & 24 deletions packages/analytics-client/package.json
Original file line number Diff line number Diff line change
@@ -1,27 +1,63 @@
{
"name": "@metamask/sdk-analytics-client",
"packageManager": "yarn@3.5.1",
"name": "@metamask/analytics-client",
"version": "0.1.0",
"description": "Client library for sending analytics events for MetaMask SDK",
"homepage": "https://github.com/MetaMask/metamask-sdk#readme",
"bugs": {
"url": "https://github.com/MetaMask/metamask-sdk/issues"
},
"repository": {
"type": "git",
"url": "https://github.com/MetaMask/metamask-sdk.git",
"directory": "packages/analytics-client"
},
"license": "MIT",
"author": "MetaMask",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"files": [
"/dist"
],
"scripts": {
"build": "echo 'Na'",
"build:dev": "echo 'Na'",
"dev": "echo 'Na'",
"build:post-tsc": "echo 'Na'",
"build:pre-tsc": "echo 'Na'",
"size": "echo 'Na'",
"clean": "echo 'Na'",
"lint": "echo 'Na'",
"lint:changelog": "echo 'Na'",
"lint:eslint": "echo 'Na'",
"lint:fix": "echo 'Na'",
"lint:misc": "echo 'Na'",
"publish:preview": "echo 'Na'",
"prepack": "echo 'Na'",
"reset": "echo 'Na'",
"test": "echo 'Na'",
"test:e2e": "echo 'Na'",
"test:coverage": "echo 'Na'",
"test:ci": "echo 'Na'",
"test:dev": "echo 'Na'",
"watch": "echo 'Na'"
}
"build": "yarn build:clean && tsc --project tsconfig.json",
"build:types": "tsc --project tsconfig.json --emitDeclarationOnly --outDir dist/types",
"build:clean": "rimraf ./dist && rimraf tsconfig.tsbuildinfo",
"clean": "rimraf ./dist && rimraf tsconfig.tsbuildinfo",
"test": "echo N/A",
"test:unit": "echo N/A",
"test:ci": "echo N/A",
"allow-scripts": "echo N/a",
"lint": "yarn lint:eslint && yarn lint:misc --check",
"lint:eslint": "eslint . --cache --ext js,ts",
"lint:changelog": "echo na",
"lint:fix": "yarn lint:eslint --fix && yarn lint:misc --write",
"lint:misc": "prettier '**/*.json' '**/*.md' '!CHANGELOG.md' --ignore-path ../../.gitignore",
"typecheck": "tsc --noEmit"
},
"dependencies": {
"@metamask/sdk-types": "workspace:^",
"cross-fetch": "^4.0.0"
},
"devDependencies": {
"@lavamoat/allow-scripts": "^2.3.1",
"@types/analytics-node": "^3.1.13",
"@types/body-parser": "^1.19.4",
"@types/cors": "^2.8.15",
"@types/express": "^4.17.20",
"@types/node": "^20.4.1",
"@typescript-eslint/eslint-plugin": "^4.20.0",
"@typescript-eslint/parser": "^4.20.0",
"eslint": "^7.30.0",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-prettier": "^3.4.0",
"prettier": "^2.8.8",
"rimraf": "^6.0.1",
"ts-node": "^10.9.1",
"typescript": "^4.3.5"
},
"publishConfig": {
"access": "public",
"registry": "https://registry.npmjs.org/"
},
"packageManager": "yarn@3.5.1"
}
Original file line number Diff line number Diff line change
@@ -1,19 +1,17 @@
import crossFetch from 'cross-fetch';
import { CommunicationLayerPreference } from './types/CommunicationLayerPreference';
import { OriginatorInfo } from './types/OriginatorInfo';
import { TrackingEvents } from './types/TrackingEvent';
import { logger } from './utils/logger';
import { type OriginatorInfo, TrackingEvent } from '@metamask/sdk-types'; // Use types package

export interface AnalyticsProps {
// Changed to type as per lint rule
export type AnalyticsProps = {
id: string;
event: TrackingEvents;
originatorInfo?: OriginatorInfo;
commLayer?: CommunicationLayerPreference;
event: TrackingEvent; // Reverted back to enum type
originatorInfo?: OriginatorInfo; // Now uses local type
// commLayer?: CommunicationLayerPreference; // Removed prop
sdkVersion?: string;
commLayerVersion?: string;
walletVersion?: string;
params?: Record<string, unknown>;
}
};

// Buffer for storing events
let analyticsBuffer: AnalyticsProps[] = [];
Expand Down Expand Up @@ -63,10 +61,6 @@ async function sendBufferedEvents(parameters: AnalyticsProps) {

const body = JSON.stringify(flatParams);

logger.RemoteCommunication(
`[sendBufferedEvents] Sending ${analyticsBuffer.length} analytics events to ${serverUrl}`,
);

try {
const response = await crossFetch(serverUrl, {
method: 'POST',
Expand All @@ -77,14 +71,22 @@ async function sendBufferedEvents(parameters: AnalyticsProps) {
body,
});

const text = await response.text();
logger.RemoteCommunication(`[sendBufferedEvents] Response: ${text}`);
// Check if the request was successful before clearing the buffer
if (!response.ok) {
// Log a warning if the request failed
console.warn(
`[Analytics] Failed to send analytics event: ${response.status} ${response.statusText}`,
);
// Optionally, handle the error differently, e.g., retry or log more details
// For now, we proceed to clear the buffer even on failure to prevent buildup
}

// Clear the processed buffer --- operation is atomic and no race condition can happen since we use a separate buffer
// eslint-disable-next-line require-atomic-updates
analyticsBuffer.length = 0;
} catch (error) {
console.warn(`Error sending analytics`, error);
// console.warn is kept as a basic logging mechanism for now
console.warn(`[Analytics] Error sending analytics`, error);
}
}

Expand Down
9 changes: 9 additions & 0 deletions packages/analytics-client/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export { SendAnalytics } from './Analytics';
export type { AnalyticsProps } from './Analytics';

// Removed re-exports from communication-layer
// export type {
// TrackingEvents,
// OriginatorInfo,
// CommunicationLayerPreference,
// } from '@metamask/sdk-communication-layer';
12 changes: 12 additions & 0 deletions packages/analytics-client/tsconfig.eslint.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"extends": "./tsconfig.json",
"include": [
"src/**/*.ts",
"*.js"
// Include test files if applicable and not covered by the main tsconfig
// "test/**/*.ts"
],
"compilerOptions": {
"noEmit": true // Important: ESLint only needs parsing, not compilation output
}
}
20 changes: 20 additions & 0 deletions packages/analytics-client/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"outDir": "./dist",
"rootDir": "./src",
"composite": true
// Override or add any specific compiler options for this package if needed
// e.g., "lib": ["es2020", "dom"]
},
"include": ["src/**/*"],
"exclude": [
"node_modules",
"dist",
"**/*.test.ts" // Exclude tests from main build if separate test command used
],
"references": [
// Add references to other workspace packages this package depends on
{ "path": "../sdk-types" } // Added reference to sdk-types
]
}
37 changes: 24 additions & 13 deletions packages/analytics-server/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,30 @@
const path = require('path');

/**
* @type {import('eslint').Linter.Config}
*/
module.exports = {
root: true,
parser: '@typescript-eslint/parser',
plugins: ['@typescript-eslint'],
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
'prettier',
'@metamask/eslint-config-nodejs', // Use nodejs config for server
'@metamask/eslint-config-typescript',
'../../.eslintrc.js' // Extend the root config
],
env: {
node: true,
es6: true,
root: true,
parser: '@typescript-eslint/parser',
parserOptions: {
project: [path.resolve(__dirname, 'tsconfig.eslint.json')], // Point to eslint tsconfig
},

ignorePatterns: [
'.prettierrc.js',
'**/.eslintrc.js',
'**/jest.config.ts',
'**/dist*/',
],

// Remove env and basic rules as they are likely handled by extended configs
// Keep specific overrides if necessary
rules: {
'@typescript-eslint/explicit-module-boundary-types': 'off',
'@typescript-eslint/no-explicit-any': 'warn',
'@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }],
},
'node/no-process-env': 'off',
}
};
Loading