or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/npm-scarf--scarf

Analytics package that collects installation statistics for npm packages to help open-source maintainers understand usage patterns.

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/@scarf/scarf@1.4.x

To install, run

npx @tessl/cli install tessl/npm-scarf--scarf@1.4.0

index.mddocs/

Scarf Analytics

Scarf is an analytics package that automatically collects installation statistics for npm packages, helping open-source maintainers understand how their packages are used and by which organizations. It operates transparently during package installation via postinstall hooks and provides configurable opt-in/opt-out mechanisms.

Package Information

  • Package Name: @scarf/scarf
  • Package Type: npm
  • Language: JavaScript (Node.js)
  • Installation: npm install @scarf/scarf

Core Imports

const scarf = require('@scarf/scarf');

For ES modules:

import * as scarf from '@scarf/scarf';

Basic Usage

Scarf is primarily designed to work automatically through npm postinstall hooks:

{
  "name": "your-package",
  "scripts": {
    "postinstall": "node ./node_modules/@scarf/scarf"
  },
  "dependencies": {
    "@scarf/scarf": "^1.4.0"
  }
}

The package automatically reports analytics when installed as a dependency. No additional code is required for basic functionality.

Architecture

Scarf operates through several key components:

  • Automatic Execution: Runs via npm postinstall hooks during package installation
  • Dependency Analysis: Traverses npm dependency trees to understand package relationships
  • Privacy Protection: Hashes sensitive package information before transmission
  • User Consent Management: Respects user preferences and environment-based opt-out settings
  • Rate Limiting: Prevents spam messaging to users across multiple installations

Configuration

Environment Variables

Control Scarf behavior through environment variables:

  • SCARF_ANALYTICS=false - Disables analytics collection
  • SCARF_NO_ANALYTICS=true - Legacy disable flag
  • DO_NOT_TRACK=1 - Respects Console Do Not Track standard
  • SCARF_VERBOSE=true - Enables verbose logging output
  • SCARF_API_TOKEN - API authentication token for custom endpoints

Package.json Configuration

Configure Scarf behavior in your package.json:

{
  "scarfSettings": {
    "enabled": true,
    "defaultOptIn": true,
    "allowTopLevel": false,
    "skipTraversal": false
  }
}

Capabilities

Analytics Reporting

Main function that collects and sends installation analytics to Scarf servers.

/**
 * Collect and report installation analytics
 * @returns {Promise<void>} Promise that resolves when reporting completes
 * @throws {Error} When analytics are disabled or reporting fails
 */
function reportPostInstall(): Promise<void>;

Dependency Analysis

Analyzes npm dependency tree to understand package relationships and configuration.

/**
 * Analyze npm dependency tree to find package relationships
 * @param {string} [packageJSONOverride] - Optional path to package.json for testing
 * @returns {Promise<DependencyInfo>} Dependency information object
 */
function getDependencyInfo(packageJSONOverride?: string): Promise<DependencyInfo>;

/**
 * Find all paths to @scarf/scarf in dependency tree
 * @param {Object} tree - npm ls dependency tree object
 * @returns {Array<Array<Object>>} Array of dependency chain arrays
 */
function findScarfInFullDependencyTree(tree: Object): Array<Array<Object>>;

Privacy Protection

Functions that handle sensitive data redaction and hashing before transmission.

/**
 * Remove sensitive information from dependency data
 * @param {DependencyInfo} dependencyInfo - Dependency information object
 * @returns {DependencyInfo} Sanitized dependency info object
 */
function redactSensitivePackageInfo(dependencyInfo: DependencyInfo): DependencyInfo;

/**
 * Create SHA256 hash of input string with fallback value
 * @param {string} toHash - String to hash
 * @param {string} defaultReturn - Fallback value if hashing fails
 * @returns {string} Hash or default value
 */
function hashWithDefault(toHash: string, defaultReturn: string): string;

Git Integration

Retrieves Git commit information for enhanced analytics when available.

/**
 * Retrieve Git commit SHA from current repository
 * @returns {Promise<string|undefined>} Git SHA or undefined if unavailable
 */
function getGitShaFromRootPath(): Promise<string | undefined>;

Rate Limiting

Prevents spam messaging to users during multiple package installations.

/**
 * Log messages to users with rate limiting
 * @param {string} rateLimitKey - Unique key for rate limiting
 * @param {string} toLog - Message to log
 */
function rateLimitedUserLog(rateLimitKey: string, toLog: string): void;

/**
 * Check if rate limit has been exceeded for a given key
 * @param {string} rateLimitKey - Rate limit key to check
 * @param {Object} history - Rate limit history object
 * @returns {boolean} True if rate limit has been hit
 */
function hasHitRateLimit(rateLimitKey: string, history: Object): boolean;

/**
 * Retrieve rate limiting history from temporary file
 * @returns {Object} Rate limit history data
 */
function getRateLimitedLogHistory(): Object;

Environment Utilities

Utility functions for environment detection and path management.

/**
 * Generate temporary file name for rate limiting history
 * @returns {string} Temporary file path
 */
function tmpFileName(): string;

/**
 * Get current directory name (testable __dirname wrapper)
 * @returns {string} Current directory path
 */
function dirName(): string;

/**
 * Get npm executable path from environment
 * @returns {string} npm executable path
 */
function npmExecPath(): string;

Internal Processing

Callback factory functions for processing command output (primarily for testing).

/**
 * Create callback function for processing npm ls command output
 * @param {Function} resolve - Promise resolve callback
 * @param {Function} reject - Promise reject callback
 * @returns {Function} Callback function for processing npm ls output
 */
function processDependencyTreeOutput(resolve: Function, reject: Function): Function;

/**
 * Create callback function for processing git rev-parse command output
 * @param {Function} resolve - Promise resolve callback
 * @param {Function} reject - Promise reject callback
 * @returns {Function} Callback function for processing git output
 */
function processGitRevParseOutput(resolve: Function, reject: Function): Function;

Types

DependencyInfo

Complete dependency relationship information for analytics reporting.

interface DependencyInfo {
  scarf: {
    name: string;
    version: string;
    path?: string;
  };
  parent: {
    name: string;
    version: string;
    scarfSettings?: ScarfSettings;
    path?: string;
    gitSha?: string;
  };
  grandparent?: {
    name: string;
    version: string;
    path?: string;
    nameHash?: string;
    versionHash?: string;
  };
  rootPackage: {
    name: string;
    version: string;
    packageJsonPath: string;
    path?: string;
    nameHash?: string;
    versionHash?: string;
  };
  anyInChainDisabled: boolean;
  skippedTraversal?: boolean;
}

ScarfSettings

Configuration options for Scarf behavior in package.json.

interface ScarfSettings {
  /** Enable or disable Scarf for this package */
  enabled?: boolean;
  /** Whether users are opted into analytics by default */
  defaultOptIn?: boolean;
  /** Allow analytics when package is installed at root level */
  allowTopLevel?: boolean;
  /** Skip dependency tree traversal for large projects */
  skipTraversal?: boolean;
}

Analytics Payload

Data structure sent to Scarf analytics endpoint.

interface AnalyticsPayload {
  libraryType: 'npm';
  rawPlatform: string;
  rawArch: string;
  nodeVersion: string;
  dependencyInfo: DependencyInfo;
}

Usage Examples

Programmatic Usage

While primarily automatic, functions can be called programmatically for testing or advanced use cases:

const scarf = require('@scarf/scarf');

// Manually trigger analytics reporting
try {
  await scarf.reportPostInstall();
  console.log('Analytics reported successfully');
} catch (error) {
  console.log('Analytics disabled or failed:', error.message);
}

// Analyze dependency information
const depInfo = await scarf.getDependencyInfo();
console.log('Package relationships:', depInfo);

// Check rate limiting status
const history = scarf.getRateLimitedLogHistory();
const hitLimit = scarf.hasHitRateLimit('test-key', history);
console.log('Rate limit hit:', hitLimit);

Configuration Examples

Opt-out by default with manual opt-in:

{
  "scarfSettings": {
    "defaultOptIn": false
  }
}

Enable for top-level installations:

{
  "scarfSettings": {
    "allowTopLevel": true
  }
}

Skip dependency traversal for large projects:

{
  "scarfSettings": {
    "skipTraversal": true
  }
}

Complete configuration:

{
  "scarfSettings": {
    "enabled": true,
    "defaultOptIn": true,
    "allowTopLevel": true,
    "skipTraversal": false
  }
}