oss-maintainance-cost-analyser 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/DEVELOPMENT.md +282 -0
- package/QUICKSTART.md +198 -0
- package/README.md +502 -0
- package/docs/README.md +148 -0
- package/docs/index.html +634 -0
- package/docs/script.js +201 -0
- package/docs/styles.css +1359 -0
- package/package.json +37 -0
- package/src/analyzer.js +391 -0
- package/src/api/depsDev.js +295 -0
- package/src/api/osv.js +213 -0
- package/src/cli.js +151 -0
- package/src/scoring/calculator.js +195 -0
- package/src/utils/formatter.js +156 -0
- package/src/utils/version.js +26 -0
- package/tests/analyzer.test.js +124 -0
- package/tests/api/depsDev.test.js +229 -0
- package/tests/api/osv.test.js +215 -0
- package/tests/scoring/calculator.test.js +152 -0
- package/tests/utils/version.test.js +66 -0
- package/vitest.config.js +7 -0
package/DEVELOPMENT.md
ADDED
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
# Development Guide
|
|
2
|
+
|
|
3
|
+
## Project Structure
|
|
4
|
+
|
|
5
|
+
```
|
|
6
|
+
oss-maintainance-cost-analyser/
|
|
7
|
+
├── src/
|
|
8
|
+
│ ├── api/ # API clients for external services
|
|
9
|
+
│ │ ├── osv.js # OSV.dev API client (CVE data)
|
|
10
|
+
│ │ └── depsDev.js # deps.dev API client (package metadata)
|
|
11
|
+
│ ├── scoring/ # Scoring logic
|
|
12
|
+
│ │ └── calculator.js # Composite score calculation
|
|
13
|
+
│ ├── utils/ # Utility functions
|
|
14
|
+
│ │ └── formatter.js # Console output formatting
|
|
15
|
+
│ ├── analyzer.js # Main analysis orchestration
|
|
16
|
+
│ └── cli.js # CLI interface (entry point)
|
|
17
|
+
├── package.json
|
|
18
|
+
├── README.md
|
|
19
|
+
├── QUICKSTART.md
|
|
20
|
+
└── DEVELOPMENT.md (this file)
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Architecture
|
|
24
|
+
|
|
25
|
+
### Data Flow
|
|
26
|
+
|
|
27
|
+
```
|
|
28
|
+
CLI (cli.js)
|
|
29
|
+
↓
|
|
30
|
+
Analyzer (analyzer.js)
|
|
31
|
+
↓
|
|
32
|
+
├─→ OSV.dev API (osv.js) → CVE metrics
|
|
33
|
+
└─→ deps.dev API (depsDev.js) → Package metadata
|
|
34
|
+
↓
|
|
35
|
+
Scoring Calculator (calculator.js) → Composite score
|
|
36
|
+
↓
|
|
37
|
+
Formatter (formatter.js) → Console output
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Key Components
|
|
41
|
+
|
|
42
|
+
#### 1. API Clients (`src/api/`)
|
|
43
|
+
|
|
44
|
+
**osv.js** - Queries OSV.dev for vulnerability data
|
|
45
|
+
- `queryVulnerabilities(packageName)` - Fetch CVEs for a package
|
|
46
|
+
- `calculateCVEMetrics(vulnerabilities)` - Calculate frequency metrics
|
|
47
|
+
- `getPackageVulnerabilityMetrics(packageName)` - High-level interface
|
|
48
|
+
|
|
49
|
+
**depsDev.js** - Queries deps.dev for package metadata
|
|
50
|
+
- `getPackageInfo(packageName)` - Fetch package info
|
|
51
|
+
- `getVersionInfo(packageName, version)` - Fetch version-specific info
|
|
52
|
+
- `calculateMaintenanceMetrics(packageInfo)` - Calculate maintenance score
|
|
53
|
+
- `calculateComplexityMetrics(versionInfo)` - Calculate complexity score
|
|
54
|
+
|
|
55
|
+
#### 2. Scoring Engine (`src/scoring/calculator.js`)
|
|
56
|
+
|
|
57
|
+
Combines metrics into a composite score (0-100):
|
|
58
|
+
|
|
59
|
+
- **Weights**: Configurable in `WEIGHTS` constant
|
|
60
|
+
- **CVE Score**: Based on historical vulnerability frequency
|
|
61
|
+
- **Technical Lag Score**: Based on package age and unpatched CVEs
|
|
62
|
+
- **Composite Score**: Weighted average of all metrics
|
|
63
|
+
- **Maintenance Hours**: Estimates annual effort
|
|
64
|
+
- **Risk Level**: Categorizes score into LOW/MEDIUM/ELEVATED/HIGH/CRITICAL
|
|
65
|
+
|
|
66
|
+
#### 3. Analyzer (`src/analyzer.js`)
|
|
67
|
+
|
|
68
|
+
Orchestrates the analysis workflow:
|
|
69
|
+
|
|
70
|
+
- `readPackageJson(filePath)` - Parse package.json
|
|
71
|
+
- `extractDependencies(packageJson, includeDev)` - Get dependency list
|
|
72
|
+
- `analyzePackage(packageName, version)` - Analyze single package
|
|
73
|
+
- `analyzeProject(packageJsonPath, options)` - Analyze all dependencies
|
|
74
|
+
- `calculateProjectSummary(packages)` - Generate summary stats
|
|
75
|
+
|
|
76
|
+
#### 4. Formatter (`src/utils/formatter.js`)
|
|
77
|
+
|
|
78
|
+
Handles console output formatting:
|
|
79
|
+
|
|
80
|
+
- `formatScore(score)` - Color-coded score display
|
|
81
|
+
- `formatRisk(risk)` - Color-coded risk level
|
|
82
|
+
- `formatPackageResult(result)` - Detailed package report
|
|
83
|
+
- `formatProjectSummary(summary)` - Project summary report
|
|
84
|
+
- `formatQuickSummary(result)` - One-line package summary
|
|
85
|
+
|
|
86
|
+
#### 5. CLI (`src/cli.js`)
|
|
87
|
+
|
|
88
|
+
Command-line interface using Commander.js:
|
|
89
|
+
|
|
90
|
+
- `analyze` command - Analyze project dependencies
|
|
91
|
+
- `check` command - Check single package
|
|
92
|
+
- Exit codes based on risk levels
|
|
93
|
+
|
|
94
|
+
## Adding New Features
|
|
95
|
+
|
|
96
|
+
### Example: Add GitHub Stars to Community Signals
|
|
97
|
+
|
|
98
|
+
1. **Create GitHub API client** (`src/api/github.js`):
|
|
99
|
+
```javascript
|
|
100
|
+
export async function getRepoStars(packageName) {
|
|
101
|
+
// Query GitHub API
|
|
102
|
+
// Return star count
|
|
103
|
+
}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
2. **Update scoring calculator** (`src/scoring/calculator.js`):
|
|
107
|
+
```javascript
|
|
108
|
+
export function calculateCommunityScore(githubData) {
|
|
109
|
+
let score = 50;
|
|
110
|
+
if (githubData.stars > 10000) score += 20;
|
|
111
|
+
// ... more logic
|
|
112
|
+
return score;
|
|
113
|
+
}
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
3. **Integrate in analyzer** (`src/analyzer.js`):
|
|
117
|
+
```javascript
|
|
118
|
+
const githubData = await getGithubMetrics(packageName);
|
|
119
|
+
const communityScore = calculateCommunityScore(githubData);
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
4. **Update formatter** for display
|
|
123
|
+
|
|
124
|
+
### Example: Add Custom Weights Configuration
|
|
125
|
+
|
|
126
|
+
1. **Create config file** (`.ossbudgetrc`):
|
|
127
|
+
```json
|
|
128
|
+
{
|
|
129
|
+
"weights": {
|
|
130
|
+
"historicalCVEs": 0.40,
|
|
131
|
+
"maintenance": 0.30,
|
|
132
|
+
"complexity": 0.15,
|
|
133
|
+
"technicalLag": 0.10,
|
|
134
|
+
"communitySignals": 0.05
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
2. **Update calculator** to read config:
|
|
140
|
+
```javascript
|
|
141
|
+
import { readConfig } from './utils/config.js';
|
|
142
|
+
const WEIGHTS = readConfig() || DEFAULT_WEIGHTS;
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
## Testing
|
|
146
|
+
|
|
147
|
+
The project uses **Vitest** for testing with full ES module support.
|
|
148
|
+
|
|
149
|
+
### Running Tests
|
|
150
|
+
|
|
151
|
+
```bash
|
|
152
|
+
# Run all tests
|
|
153
|
+
npm test
|
|
154
|
+
|
|
155
|
+
# Watch mode (for development)
|
|
156
|
+
npm run test:watch
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### Test Structure
|
|
160
|
+
|
|
161
|
+
```
|
|
162
|
+
tests/
|
|
163
|
+
├── api/
|
|
164
|
+
│ ├── osv.test.js - OSV API and CVE metrics
|
|
165
|
+
│ ├── depsDev.test.js - deps.dev API and package metrics
|
|
166
|
+
├── scoring/
|
|
167
|
+
│ └── calculator.test.js - Composite score calculation
|
|
168
|
+
├── utils/
|
|
169
|
+
│ └── version.test.js - Version resolution
|
|
170
|
+
└── analyzer.test.js - Main analyzer orchestration
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### Manual Testing
|
|
174
|
+
|
|
175
|
+
```bash
|
|
176
|
+
# Test single package check with transitive analysis
|
|
177
|
+
npm start -- check express
|
|
178
|
+
|
|
179
|
+
# Test shallow (direct-only) analysis
|
|
180
|
+
npm start -- check express --shallow
|
|
181
|
+
|
|
182
|
+
# Test with example file
|
|
183
|
+
npm start -- analyze --path example-package.json --verbose
|
|
184
|
+
|
|
185
|
+
# Test with your own project
|
|
186
|
+
npm start -- analyze --path /path/to/real/package.json
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
## API Rate Limiting
|
|
190
|
+
|
|
191
|
+
Both APIs are free and public, but have rate limits:
|
|
192
|
+
|
|
193
|
+
**OSV.dev**: No documented limit, but be respectful
|
|
194
|
+
**deps.dev**: No authentication required, generous limits
|
|
195
|
+
|
|
196
|
+
To avoid issues:
|
|
197
|
+
- Default concurrency is 5 (adjustable via `--concurrency`)
|
|
198
|
+
- Add delays between batches if needed
|
|
199
|
+
- Cache results when possible
|
|
200
|
+
|
|
201
|
+
### Adding Caching
|
|
202
|
+
|
|
203
|
+
```javascript
|
|
204
|
+
// src/utils/cache.js
|
|
205
|
+
const cache = new Map();
|
|
206
|
+
|
|
207
|
+
export function getCached(key, ttl = 3600000) {
|
|
208
|
+
const cached = cache.get(key);
|
|
209
|
+
if (cached && Date.now() - cached.timestamp < ttl) {
|
|
210
|
+
return cached.value;
|
|
211
|
+
}
|
|
212
|
+
return null;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
export function setCache(key, value) {
|
|
216
|
+
cache.set(key, { value, timestamp: Date.now() });
|
|
217
|
+
}
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
## Debugging
|
|
221
|
+
|
|
222
|
+
Enable verbose logging:
|
|
223
|
+
|
|
224
|
+
```javascript
|
|
225
|
+
// In any file
|
|
226
|
+
const DEBUG = process.env.DEBUG === 'true';
|
|
227
|
+
if (DEBUG) console.log('Debug info:', data);
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
Run with:
|
|
231
|
+
```bash
|
|
232
|
+
DEBUG=true npm start -- analyze
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
## Code Style
|
|
236
|
+
|
|
237
|
+
- ES6 modules (`import`/`export`)
|
|
238
|
+
- Async/await for asynchronous operations
|
|
239
|
+
- JSDoc comments for public functions
|
|
240
|
+
- Descriptive variable names
|
|
241
|
+
- Keep functions small and focused
|
|
242
|
+
|
|
243
|
+
## Dependencies
|
|
244
|
+
|
|
245
|
+
Minimal dependencies to keep the tool lightweight:
|
|
246
|
+
|
|
247
|
+
**Runtime:**
|
|
248
|
+
- **chalk** - Terminal color output
|
|
249
|
+
- **commander** - CLI argument parsing
|
|
250
|
+
- **semver** - Version range resolution for dependency trees
|
|
251
|
+
|
|
252
|
+
**Development:**
|
|
253
|
+
- **vitest** - Testing framework with ES module support
|
|
254
|
+
|
|
255
|
+
No runtime dependencies on security scanners or heavy libraries.
|
|
256
|
+
|
|
257
|
+
## Future Enhancements
|
|
258
|
+
|
|
259
|
+
See README.md for planned features. Priority order:
|
|
260
|
+
|
|
261
|
+
1. **Community signals** - GitHub integration
|
|
262
|
+
2. **Configuration file** - Custom weights/thresholds
|
|
263
|
+
3. ~~**Transitive deps**~~ - ✅ Completed (full dependency tree analysis)
|
|
264
|
+
4. **HTML reports** - Visual dashboards
|
|
265
|
+
5. **CI/CD integration** - GitHub Actions plugin
|
|
266
|
+
6. **Historical tracking** - Store results over time
|
|
267
|
+
7. **Socket.dev integration** - Behavioral analysis
|
|
268
|
+
|
|
269
|
+
## Contributing
|
|
270
|
+
|
|
271
|
+
Internal tool - contact the security team for access or questions.
|
|
272
|
+
|
|
273
|
+
### Making Changes
|
|
274
|
+
|
|
275
|
+
1. Create a feature branch
|
|
276
|
+
2. Test thoroughly with real package.json files
|
|
277
|
+
3. Update documentation (README, QUICKSTART, this file)
|
|
278
|
+
4. Submit for review
|
|
279
|
+
|
|
280
|
+
---
|
|
281
|
+
|
|
282
|
+
**Questions?** Contact the development team.
|
package/QUICKSTART.md
ADDED
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
# Quick Start Guide
|
|
2
|
+
|
|
3
|
+
## Installation
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
cd /Users/nheal/dev/nickheal/oss-maintainance-cost-analyser
|
|
7
|
+
npm install
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
## The Core Idea: Set an OSS Maintenance Budget
|
|
11
|
+
|
|
12
|
+
**OSS packages aren't free.** Every dependency requires time for:
|
|
13
|
+
- Security patches
|
|
14
|
+
- Version updates
|
|
15
|
+
- Investigating CVEs
|
|
16
|
+
- Dealing with breaking changes
|
|
17
|
+
|
|
18
|
+
**More packages = less time for features.**
|
|
19
|
+
|
|
20
|
+
### What to Do
|
|
21
|
+
|
|
22
|
+
1. **Set a budget** - e.g., "40 hours/year for our team of 5"
|
|
23
|
+
2. **Measure your baseline** - Run this tool against your current repos
|
|
24
|
+
3. **Track regularly** - Monthly or quarterly checks
|
|
25
|
+
4. **Evaluate before adding** - Will this push you over budget?
|
|
26
|
+
5. **Remove unused packages** - Keep your dependency tree lean
|
|
27
|
+
6. **Choose wisely** - Use maintenance cost when selecting between libraries
|
|
28
|
+
|
|
29
|
+
**Important:** This measures ONLY OSS maintenance cost - a specific slice of overall maintenance, not all technical debt.
|
|
30
|
+
|
|
31
|
+
See the full README for detailed philosophy and workflow examples.
|
|
32
|
+
|
|
33
|
+
## Test with Example Package
|
|
34
|
+
|
|
35
|
+
Check a single package to see how it works:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
npm start -- check lodash
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
This will analyze the `lodash` package and show:
|
|
42
|
+
- Overall score (0-100)
|
|
43
|
+
- Risk level (LOW/MEDIUM/ELEVATED/HIGH/CRITICAL)
|
|
44
|
+
- Historical CVE frequency
|
|
45
|
+
- Maintenance health
|
|
46
|
+
- Dependency complexity
|
|
47
|
+
- Estimated annual maintenance hours
|
|
48
|
+
|
|
49
|
+
## Analyze a Project
|
|
50
|
+
|
|
51
|
+
To test with the example project:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
npm start -- analyze --path example-package.json --verbose
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
To analyze your own project:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
# In your project directory
|
|
61
|
+
cd /path/to/your/project
|
|
62
|
+
/Users/nheal/dev/nickheal/oss-maintainance-cost-analyser/src/cli.js analyze
|
|
63
|
+
|
|
64
|
+
# Or from the analyzer directory
|
|
65
|
+
npm start -- analyze --path /path/to/your/project/package.json
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Common Commands
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
# Quick analysis (summary only)
|
|
72
|
+
npm start -- analyze
|
|
73
|
+
|
|
74
|
+
# Detailed analysis (all packages)
|
|
75
|
+
npm start -- analyze --verbose
|
|
76
|
+
|
|
77
|
+
# Include dev dependencies
|
|
78
|
+
npm start -- analyze --dev
|
|
79
|
+
|
|
80
|
+
# Save results to file
|
|
81
|
+
npm start -- analyze --output results.json
|
|
82
|
+
|
|
83
|
+
# Check single package (includes full dependency tree)
|
|
84
|
+
npm start -- check express
|
|
85
|
+
npm start -- check react --version 18.2.0
|
|
86
|
+
|
|
87
|
+
# Check only direct package without transitive dependencies
|
|
88
|
+
npm start -- check express --shallow
|
|
89
|
+
|
|
90
|
+
# Adjust concurrency (for rate limiting)
|
|
91
|
+
npm start -- analyze --concurrency 3
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Understanding the Output
|
|
95
|
+
|
|
96
|
+
### Score Interpretation
|
|
97
|
+
|
|
98
|
+
- **80-100 (LOW risk)**: Safe to use, well-maintained
|
|
99
|
+
- **60-79 (MEDIUM risk)**: Acceptable, monitor regularly
|
|
100
|
+
- **40-59 (ELEVATED risk)**: Consider alternatives
|
|
101
|
+
- **20-39 (HIGH risk)**: Avoid if possible
|
|
102
|
+
- **0-19 (CRITICAL risk)**: Do not use
|
|
103
|
+
|
|
104
|
+
### Maintenance Hours
|
|
105
|
+
|
|
106
|
+
This estimates how many hours per year you'll spend:
|
|
107
|
+
- Updating the package when new versions release
|
|
108
|
+
- Investigating and patching vulnerabilities
|
|
109
|
+
- Dealing with breaking changes
|
|
110
|
+
- Debugging issues caused by poor maintenance
|
|
111
|
+
|
|
112
|
+
### Risk Factors
|
|
113
|
+
|
|
114
|
+
Pay attention to:
|
|
115
|
+
- **High CVE frequency** (>2 per year) = package or its dependencies are often vulnerable
|
|
116
|
+
- **Abandoned packages** (no releases in 1+ years) = won't get security fixes
|
|
117
|
+
- **High complexity** (>200 total dependencies in tree) = more attack surface
|
|
118
|
+
- **Critical CVEs** (even 1 per year) = serious security issues
|
|
119
|
+
|
|
120
|
+
**Note**: CVE metrics now include the full transitive dependency tree. If a package has many dependencies, expect higher CVE counts even if the package itself is secure.
|
|
121
|
+
|
|
122
|
+
## Integration Examples
|
|
123
|
+
|
|
124
|
+
### CI/CD Pipeline
|
|
125
|
+
|
|
126
|
+
Add to your GitHub Actions:
|
|
127
|
+
|
|
128
|
+
```yaml
|
|
129
|
+
- name: Check dependency risk
|
|
130
|
+
run: |
|
|
131
|
+
npx /Users/nheal/dev/nickheal/oss-maintainance-cost-analyser/src/cli.js analyze
|
|
132
|
+
# Fails if critical/high risk packages detected
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### Pre-commit Hook
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
#!/bin/bash
|
|
139
|
+
# .git/hooks/pre-commit
|
|
140
|
+
if git diff --cached --name-only | grep -q "package.json"; then
|
|
141
|
+
echo "Checking dependency security..."
|
|
142
|
+
/Users/nheal/dev/nickheal/oss-maintainance-cost-analyser/src/cli.js analyze
|
|
143
|
+
fi
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### Package Review Process
|
|
147
|
+
|
|
148
|
+
Before adding a new dependency:
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
# Check the package first
|
|
152
|
+
npm start -- check new-package-name
|
|
153
|
+
|
|
154
|
+
# If score > 60, approve it
|
|
155
|
+
# If score < 60, find an alternative
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
## Troubleshooting
|
|
159
|
+
|
|
160
|
+
### Rate Limiting
|
|
161
|
+
|
|
162
|
+
If you get rate limit errors, reduce concurrency:
|
|
163
|
+
|
|
164
|
+
```bash
|
|
165
|
+
npm start -- analyze --concurrency 2
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
Or add delays between batches in `src/analyzer.js`.
|
|
169
|
+
|
|
170
|
+
### Package Not Found
|
|
171
|
+
|
|
172
|
+
Some packages may not be in deps.dev. This is normal for:
|
|
173
|
+
- Very new packages (published recently)
|
|
174
|
+
- Private packages
|
|
175
|
+
- Packages removed from npm
|
|
176
|
+
|
|
177
|
+
The tool will still show CVE data from OSV.dev.
|
|
178
|
+
|
|
179
|
+
### No CVE Data
|
|
180
|
+
|
|
181
|
+
If a package shows 0 CVEs, it could mean:
|
|
182
|
+
- Genuinely no vulnerabilities found (good!)
|
|
183
|
+
- Package is too new to have been audited
|
|
184
|
+
- Package is unpopular and not scrutinized
|
|
185
|
+
|
|
186
|
+
Check the package's age and popularity before assuming it's safe.
|
|
187
|
+
|
|
188
|
+
## Next Steps
|
|
189
|
+
|
|
190
|
+
1. **Analyze your current projects** to establish a baseline
|
|
191
|
+
2. **Set score thresholds** for your team (e.g., "no packages below 50")
|
|
192
|
+
3. **Create a budget** based on total maintenance hours
|
|
193
|
+
4. **Review quarterly** to track trends
|
|
194
|
+
5. **Integrate into CI/CD** to prevent risky packages from being added
|
|
195
|
+
|
|
196
|
+
---
|
|
197
|
+
|
|
198
|
+
**Need help?** Check the full README.md for detailed documentation.
|