or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

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

0

# Scarf Analytics

1

2

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.

3

4

## Package Information

5

6

- **Package Name**: @scarf/scarf

7

- **Package Type**: npm

8

- **Language**: JavaScript (Node.js)

9

- **Installation**: `npm install @scarf/scarf`

10

11

## Core Imports

12

13

```javascript

14

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

15

```

16

17

For ES modules:

18

19

```javascript

20

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

21

```

22

23

## Basic Usage

24

25

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

26

27

```json

28

{

29

"name": "your-package",

30

"scripts": {

31

"postinstall": "node ./node_modules/@scarf/scarf"

32

},

33

"dependencies": {

34

"@scarf/scarf": "^1.4.0"

35

}

36

}

37

```

38

39

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

40

41

## Architecture

42

43

Scarf operates through several key components:

44

45

- **Automatic Execution**: Runs via npm postinstall hooks during package installation

46

- **Dependency Analysis**: Traverses npm dependency trees to understand package relationships

47

- **Privacy Protection**: Hashes sensitive package information before transmission

48

- **User Consent Management**: Respects user preferences and environment-based opt-out settings

49

- **Rate Limiting**: Prevents spam messaging to users across multiple installations

50

51

## Configuration

52

53

### Environment Variables

54

55

Control Scarf behavior through environment variables:

56

57

- `SCARF_ANALYTICS=false` - Disables analytics collection

58

- `SCARF_NO_ANALYTICS=true` - Legacy disable flag

59

- `DO_NOT_TRACK=1` - Respects Console Do Not Track standard

60

- `SCARF_VERBOSE=true` - Enables verbose logging output

61

- `SCARF_API_TOKEN` - API authentication token for custom endpoints

62

63

### Package.json Configuration

64

65

Configure Scarf behavior in your package.json:

66

67

```json

68

{

69

"scarfSettings": {

70

"enabled": true,

71

"defaultOptIn": true,

72

"allowTopLevel": false,

73

"skipTraversal": false

74

}

75

}

76

```

77

78

## Capabilities

79

80

### Analytics Reporting

81

82

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

83

84

```javascript { .api }

85

/**

86

* Collect and report installation analytics

87

* @returns {Promise<void>} Promise that resolves when reporting completes

88

* @throws {Error} When analytics are disabled or reporting fails

89

*/

90

function reportPostInstall(): Promise<void>;

91

```

92

93

### Dependency Analysis

94

95

Analyzes npm dependency tree to understand package relationships and configuration.

96

97

```javascript { .api }

98

/**

99

* Analyze npm dependency tree to find package relationships

100

* @param {string} [packageJSONOverride] - Optional path to package.json for testing

101

* @returns {Promise<DependencyInfo>} Dependency information object

102

*/

103

function getDependencyInfo(packageJSONOverride?: string): Promise<DependencyInfo>;

104

105

/**

106

* Find all paths to @scarf/scarf in dependency tree

107

* @param {Object} tree - npm ls dependency tree object

108

* @returns {Array<Array<Object>>} Array of dependency chain arrays

109

*/

110

function findScarfInFullDependencyTree(tree: Object): Array<Array<Object>>;

111

```

112

113

### Privacy Protection

114

115

Functions that handle sensitive data redaction and hashing before transmission.

116

117

```javascript { .api }

118

/**

119

* Remove sensitive information from dependency data

120

* @param {DependencyInfo} dependencyInfo - Dependency information object

121

* @returns {DependencyInfo} Sanitized dependency info object

122

*/

123

function redactSensitivePackageInfo(dependencyInfo: DependencyInfo): DependencyInfo;

124

125

/**

126

* Create SHA256 hash of input string with fallback value

127

* @param {string} toHash - String to hash

128

* @param {string} defaultReturn - Fallback value if hashing fails

129

* @returns {string} Hash or default value

130

*/

131

function hashWithDefault(toHash: string, defaultReturn: string): string;

132

```

133

134

### Git Integration

135

136

Retrieves Git commit information for enhanced analytics when available.

137

138

```javascript { .api }

139

/**

140

* Retrieve Git commit SHA from current repository

141

* @returns {Promise<string|undefined>} Git SHA or undefined if unavailable

142

*/

143

function getGitShaFromRootPath(): Promise<string | undefined>;

144

```

145

146

### Rate Limiting

147

148

Prevents spam messaging to users during multiple package installations.

149

150

```javascript { .api }

151

/**

152

* Log messages to users with rate limiting

153

* @param {string} rateLimitKey - Unique key for rate limiting

154

* @param {string} toLog - Message to log

155

*/

156

function rateLimitedUserLog(rateLimitKey: string, toLog: string): void;

157

158

/**

159

* Check if rate limit has been exceeded for a given key

160

* @param {string} rateLimitKey - Rate limit key to check

161

* @param {Object} history - Rate limit history object

162

* @returns {boolean} True if rate limit has been hit

163

*/

164

function hasHitRateLimit(rateLimitKey: string, history: Object): boolean;

165

166

/**

167

* Retrieve rate limiting history from temporary file

168

* @returns {Object} Rate limit history data

169

*/

170

function getRateLimitedLogHistory(): Object;

171

```

172

173

### Environment Utilities

174

175

Utility functions for environment detection and path management.

176

177

```javascript { .api }

178

/**

179

* Generate temporary file name for rate limiting history

180

* @returns {string} Temporary file path

181

*/

182

function tmpFileName(): string;

183

184

/**

185

* Get current directory name (testable __dirname wrapper)

186

* @returns {string} Current directory path

187

*/

188

function dirName(): string;

189

190

/**

191

* Get npm executable path from environment

192

* @returns {string} npm executable path

193

*/

194

function npmExecPath(): string;

195

```

196

197

### Internal Processing

198

199

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

200

201

```javascript { .api }

202

/**

203

* Create callback function for processing npm ls command output

204

* @param {Function} resolve - Promise resolve callback

205

* @param {Function} reject - Promise reject callback

206

* @returns {Function} Callback function for processing npm ls output

207

*/

208

function processDependencyTreeOutput(resolve: Function, reject: Function): Function;

209

210

/**

211

* Create callback function for processing git rev-parse command output

212

* @param {Function} resolve - Promise resolve callback

213

* @param {Function} reject - Promise reject callback

214

* @returns {Function} Callback function for processing git output

215

*/

216

function processGitRevParseOutput(resolve: Function, reject: Function): Function;

217

```

218

219

## Types

220

221

### DependencyInfo

222

223

Complete dependency relationship information for analytics reporting.

224

225

```javascript { .api }

226

interface DependencyInfo {

227

scarf: {

228

name: string;

229

version: string;

230

path?: string;

231

};

232

parent: {

233

name: string;

234

version: string;

235

scarfSettings?: ScarfSettings;

236

path?: string;

237

gitSha?: string;

238

};

239

grandparent?: {

240

name: string;

241

version: string;

242

path?: string;

243

nameHash?: string;

244

versionHash?: string;

245

};

246

rootPackage: {

247

name: string;

248

version: string;

249

packageJsonPath: string;

250

path?: string;

251

nameHash?: string;

252

versionHash?: string;

253

};

254

anyInChainDisabled: boolean;

255

skippedTraversal?: boolean;

256

}

257

```

258

259

### ScarfSettings

260

261

Configuration options for Scarf behavior in package.json.

262

263

```javascript { .api }

264

interface ScarfSettings {

265

/** Enable or disable Scarf for this package */

266

enabled?: boolean;

267

/** Whether users are opted into analytics by default */

268

defaultOptIn?: boolean;

269

/** Allow analytics when package is installed at root level */

270

allowTopLevel?: boolean;

271

/** Skip dependency tree traversal for large projects */

272

skipTraversal?: boolean;

273

}

274

```

275

276

### Analytics Payload

277

278

Data structure sent to Scarf analytics endpoint.

279

280

```javascript { .api }

281

interface AnalyticsPayload {

282

libraryType: 'npm';

283

rawPlatform: string;

284

rawArch: string;

285

nodeVersion: string;

286

dependencyInfo: DependencyInfo;

287

}

288

```

289

290

## Usage Examples

291

292

### Programmatic Usage

293

294

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

295

296

```javascript

297

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

298

299

// Manually trigger analytics reporting

300

try {

301

await scarf.reportPostInstall();

302

console.log('Analytics reported successfully');

303

} catch (error) {

304

console.log('Analytics disabled or failed:', error.message);

305

}

306

307

// Analyze dependency information

308

const depInfo = await scarf.getDependencyInfo();

309

console.log('Package relationships:', depInfo);

310

311

// Check rate limiting status

312

const history = scarf.getRateLimitedLogHistory();

313

const hitLimit = scarf.hasHitRateLimit('test-key', history);

314

console.log('Rate limit hit:', hitLimit);

315

```

316

317

### Configuration Examples

318

319

**Opt-out by default with manual opt-in:**

320

321

```json

322

{

323

"scarfSettings": {

324

"defaultOptIn": false

325

}

326

}

327

```

328

329

**Enable for top-level installations:**

330

331

```json

332

{

333

"scarfSettings": {

334

"allowTopLevel": true

335

}

336

}

337

```

338

339

**Skip dependency traversal for large projects:**

340

341

```json

342

{

343

"scarfSettings": {

344

"skipTraversal": true

345

}

346

}

347

```

348

349

**Complete configuration:**

350

351

```json

352

{

353

"scarfSettings": {

354

"enabled": true,

355

"defaultOptIn": true,

356

"allowTopLevel": true,

357

"skipTraversal": false

358

}

359

}

360

```