diff --git a/INSTALLATION.md b/INSTALLATION.md index 458945f..639b73f 100644 --- a/INSTALLATION.md +++ b/INSTALLATION.md @@ -10,7 +10,13 @@ Add this to your GitHub Actions workflow: - name: Usage Statistics Tracker uses: LukeHagar/usage-statistics@v1 with: - config: 'production' + npm-packages: 'lodash,axios' + github-repositories: 'microsoft/vscode,facebook/react' + pypi-packages: 'requests,numpy' + homebrew-formulas: 'git,node' + powershell-modules: 'PowerShellGet,PSReadLine' + postman-collections: '12345,67890' + go-modules: 'github.com/gin-gonic/gin,github.com/go-chi/chi' json-output-path: 'stats.json' update-readme: 'true' github-token: ${{ secrets.GITHUB_TOKEN }} @@ -37,7 +43,13 @@ jobs: - name: Usage Statistics Tracker uses: LukeHagar/usage-statistics@v1 with: - config: 'production' + npm-packages: 'lodash,axios' + github-repositories: 'microsoft/vscode,facebook/react' + pypi-packages: 'requests,numpy' + homebrew-formulas: 'git,node' + powershell-modules: 'PowerShellGet,PSReadLine' + postman-collections: '12345,67890' + go-modules: 'github.com/gin-gonic/gin,github.com/go-chi/chi' json-output-path: 'stats.json' csv-output-path: 'stats.csv' report-output-path: 'docs/usage-report.md' @@ -68,19 +80,17 @@ Last updated: 2025-07-29T18:53:52.619Z - **Unique Packages**: 8 - **Platforms Tracked**: npm, pypi, homebrew, go +### Platform Totals +- **HOMEBREW**: 380,163 downloads (2 packages) +- **NPM**: 34,311 downloads (2 packages) +- **GO**: 33 downloads (2 packages) + ### Top Packages 1. **node** (homebrew) - 226,882 downloads 2. **git** (homebrew) - 153,281 downloads 3. **axios** (npm) - 18,397 downloads 4. **lodash** (npm) - 15,914 downloads 5. **github.com/go-chi/chi** (go) - 33 downloads - -### Recent Activity -- **node** (homebrew) - 226,882 downloads on 7/29/2025 -- **git** (homebrew) - 153,281 downloads on 7/29/2025 -- **axios** (npm) - 722 downloads on 7/29/2025 -- **lodash** (npm) - 857 downloads on 7/29/2025 -- **axios** (npm) - 936 downloads on 7/28/2025 ``` diff --git a/README.md b/README.md index 1d286a0..40edb95 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,13 @@ A comprehensive GitHub Action for tracking download statistics across multiple p - name: Usage Statistics Tracker uses: LukeHagar/usage-statistics@v1 with: - config: 'production' + npm-packages: 'lodash,axios' + github-repositories: 'microsoft/vscode,facebook/react' + pypi-packages: 'requests,numpy' + homebrew-formulas: 'git,node' + powershell-modules: 'PowerShellGet,PSReadLine' + postman-collections: '12345,67890' + go-modules: 'github.com/gin-gonic/gin,github.com/go-chi/chi' json-output-path: 'stats.json' csv-output-path: 'stats.csv' report-output-path: 'report.md' @@ -50,7 +56,13 @@ bun test | Parameter | Description | Required | Default | |-----------|-------------|----------|---------| -| `config` | Configuration mode or JSON | No | `production` | +| `npm-packages` | Comma-separated list of NPM packages | No | (empty) | +| `github-repositories` | Comma-separated list of GitHub repos (owner/repo) | No | (empty) | +| `pypi-packages` | Comma-separated list of PyPI packages | No | (empty) | +| `homebrew-formulas` | Comma-separated list of Homebrew formulas | No | (empty) | +| `powershell-modules` | Comma-separated list of PowerShell modules | No | (empty) | +| `postman-collections` | Comma-separated list of Postman collection IDs | No | (empty) | +| `go-modules` | Comma-separated list of Go modules | No | (empty) | | `json-output-path` | Path for JSON output | No | `stats.json` | | `csv-output-path` | Path for CSV output | No | (empty) | | `report-output-path` | Path for human-readable report | No | (empty) | @@ -61,30 +73,36 @@ bun test | `commit-message` | Commit message for changes | No | `chore: update usage statistics [skip ci]` | | `preview-mode` | Run with mock data | No | `false` | -### Configuration Modes +### Configuration Examples -#### Production Mode +#### NPM Packages Only ```yaml - name: Usage Statistics Tracker uses: LukeHagar/usage-statistics@v1 with: - config: 'production' + npm-packages: 'lodash,axios,react' ``` -#### Development Mode +#### GitHub Repositories Only ```yaml - name: Usage Statistics Tracker uses: LukeHagar/usage-statistics@v1 with: - config: 'development' + github-repositories: 'microsoft/vscode,facebook/react,vercel/next.js' ``` -#### Custom JSON Configuration +#### Mixed Platform Configuration ```yaml - name: Usage Statistics Tracker uses: LukeHagar/usage-statistics@v1 with: - config: '{"npmPackages": ["lodash", "axios"], "githubRepositories": ["microsoft/vscode"]}' + npm-packages: 'lodash,axios' + github-repositories: 'microsoft/vscode,facebook/react' + pypi-packages: 'requests,numpy' + homebrew-formulas: 'git,node' + powershell-modules: 'PowerShellGet,PSReadLine' + postman-collections: '12345,67890' + go-modules: 'github.com/gin-gonic/gin,github.com/go-chi/chi' ``` ### Outputs @@ -121,7 +139,13 @@ jobs: - name: Usage Statistics Tracker uses: LukeHagar/usage-statistics@v1 with: - config: 'production' + npm-packages: 'lodash,axios' + github-repositories: 'microsoft/vscode,facebook/react' + pypi-packages: 'requests,numpy' + homebrew-formulas: 'git,node' + powershell-modules: 'PowerShellGet,PSReadLine' + postman-collections: '12345,67890' + go-modules: 'github.com/gin-gonic/gin,github.com/go-chi/chi' json-output-path: 'stats.json' update-readme: 'true' github-token: ${{ secrets.GITHUB_TOKEN }} @@ -141,7 +165,13 @@ jobs: - name: Usage Statistics Tracker uses: LukeHagar/usage-statistics@v1 with: - config: 'production' + npm-packages: 'lodash,axios,react' + github-repositories: 'microsoft/vscode,facebook/react' + pypi-packages: 'requests,numpy' + homebrew-formulas: 'git,node' + powershell-modules: 'PowerShellGet,PSReadLine' + postman-collections: '12345,67890' + go-modules: 'github.com/gin-gonic/gin,github.com/go-chi/chi' json-output-path: 'data/stats.json' csv-output-path: 'data/stats.csv' report-output-path: 'docs/usage-report.md' @@ -172,7 +202,11 @@ jobs: id: stats uses: LukeHagar/usage-statistics@v1 with: - config: 'production' + npm-packages: 'lodash,axios' + github-repositories: 'microsoft/vscode,facebook/react' + powershell-modules: 'PowerShellGet' + postman-collections: '12345' + go-modules: 'github.com/gin-gonic/gin' json-output-path: 'stats.json' - name: Use Statistics Data @@ -198,19 +232,17 @@ Last updated: 2025-07-29T18:53:52.619Z - **Unique Packages**: 8 - **Platforms Tracked**: npm, pypi, homebrew, go +### Platform Totals +- **HOMEBREW**: 380,163 downloads (2 packages) +- **NPM**: 34,311 downloads (2 packages) +- **GO**: 33 downloads (2 packages) + ### Top Packages 1. **node** (homebrew) - 226,882 downloads 2. **git** (homebrew) - 153,281 downloads 3. **axios** (npm) - 18,397 downloads 4. **lodash** (npm) - 15,914 downloads 5. **github.com/go-chi/chi** (go) - 33 downloads - -### Recent Activity -- **node** (homebrew) - 226,882 downloads on 7/29/2025 -- **git** (homebrew) - 153,281 downloads on 7/29/2025 -- **axios** (npm) - 722 downloads on 7/29/2025 -- **lodash** (npm) - 857 downloads on 7/29/2025 -- **axios** (npm) - 936 downloads on 7/28/2025 ``` @@ -246,7 +278,6 @@ usage-statistics/ ├── src/ │ ├── index.ts # Main library entry point │ ├── action.ts # GitHub Action entry point -│ ├── config.ts # Configuration management │ ├── aggregator.ts # Statistics aggregation │ ├── types/ # TypeScript type definitions │ ├── trackers/ # Platform-specific trackers diff --git a/action.yml b/action.yml index 646d30b..7755a2b 100644 --- a/action.yml +++ b/action.yml @@ -3,11 +3,47 @@ description: 'Track download statistics across multiple platforms (NPM, GitHub, author: 'LukeHagar' inputs: - # Configuration - config: - description: 'Configuration for tracking (development, production, test, or custom JSON)' + # NPM Configuration + npm-packages: + description: 'Comma-separated list of NPM packages to track' required: false - default: 'production' + default: '' + + # GitHub Configuration + github-repositories: + description: 'Comma-separated list of GitHub repositories (format: owner/repo)' + required: false + default: '' + + # PyPI Configuration + pypi-packages: + description: 'Comma-separated list of PyPI packages to track' + required: false + default: '' + + # Homebrew Configuration + homebrew-formulas: + description: 'Comma-separated list of Homebrew formulas to track' + required: false + default: '' + + # PowerShell Configuration + powershell-modules: + description: 'Comma-separated list of PowerShell modules to track' + required: false + default: '' + + # Postman Configuration + postman-collections: + description: 'Comma-separated list of Postman collection IDs to track' + required: false + default: '' + + # Go Configuration + go-modules: + description: 'Comma-separated list of Go modules to track' + required: false + default: '' # Output paths json-output-path: @@ -80,4 +116,4 @@ outputs: runs: using: 'node20' - main: 'dist/index.js' \ No newline at end of file + main: 'dist/action.js' \ No newline at end of file diff --git a/examples/basic-usage.yml b/examples/basic-usage.yml index bd877ee..2258134 100644 --- a/examples/basic-usage.yml +++ b/examples/basic-usage.yml @@ -16,7 +16,13 @@ jobs: - name: Usage Statistics Tracker uses: LukeHagar/usage-statistics@v1 with: - config: 'production' + npm-packages: 'lodash,axios' + github-repositories: 'microsoft/vscode,facebook/react' + pypi-packages: 'requests,numpy' + homebrew-formulas: 'git,node' + powershell-modules: 'PowerShellGet,PSReadLine' + postman-collections: '12345,67890' + go-modules: 'github.com/gin-gonic/gin,github.com/go-chi/chi' json-output-path: 'stats.json' csv-output-path: 'stats.csv' report-output-path: 'docs/usage-report.md' diff --git a/examples/input-based-config.yml b/examples/input-based-config.yml new file mode 100644 index 0000000..e1892b6 --- /dev/null +++ b/examples/input-based-config.yml @@ -0,0 +1,59 @@ +name: Usage Statistics with Input-Based Configuration + +on: + schedule: + - cron: '0 0 * * *' # Daily at midnight + workflow_dispatch: + +jobs: + update-stats: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Usage Statistics Tracker + uses: LukeHagar/usage-statistics@v1 + with: + # NPM packages to track + npm-packages: 'lodash,axios,react,vue' + + # GitHub repositories to track + github-repositories: 'microsoft/vscode,facebook/react,vercel/next.js' + + # PyPI packages to track + pypi-packages: 'requests,numpy,pandas' + + # Homebrew formulas to track + homebrew-formulas: 'git,node,postgresql' + + # PowerShell modules to track + powershell-modules: 'PowerShellGet,PSReadLine' + + # Go modules to track + go-modules: 'github.com/gin-gonic/gin,github.com/go-chi/chi' + + # Output configuration + json-output-path: 'data/stats.json' + csv-output-path: 'data/stats.csv' + report-output-path: 'docs/usage-report.md' + + # README integration + update-readme: 'true' + readme-path: 'README.md' + + # API tokens + github-token: ${{ secrets.GITHUB_TOKEN }} + postman-api-key: ${{ secrets.POSTMAN_API_KEY }} + + # Commit settings + commit-message: 'feat: update usage statistics with detailed report' + + - name: Commit and push changes + run: | + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + git add data/stats.json data/stats.csv docs/usage-report.md README.md + git commit -m "chore: update usage statistics [skip ci]" || echo "No changes to commit" + git push \ No newline at end of file diff --git a/src/action.ts b/src/action.ts index fdb9177..3960f7a 100644 --- a/src/action.ts +++ b/src/action.ts @@ -3,12 +3,19 @@ import * as core from '@actions/core'; import * as fs from 'fs/promises'; import * as path from 'path'; import { UsageStatisticsManager } from './index'; -import { getConfig, validateConfig } from './config'; +import type { TrackingConfig } from './types'; async function run() { try { // Get inputs - const configInput = core.getInput('config'); + const npmPackages = core.getInput('npm-packages'); + const githubRepositories = core.getInput('github-repositories'); + const pypiPackages = core.getInput('pypi-packages'); + const homebrewFormulas = core.getInput('homebrew-formulas'); + const powershellModules = core.getInput('powershell-modules'); + const postmanCollections = core.getInput('postman-collections'); + const goModules = core.getInput('go-modules'); + const jsonOutputPath = core.getInput('json-output-path'); const csvOutputPath = core.getInput('csv-output-path'); const reportOutputPath = core.getInput('report-output-path'); @@ -27,31 +34,35 @@ async function run() { process.env.POSTMAN_API_KEY = postmanApiKey; } - // Get configuration - let trackingConfig; - if (configInput === 'development' || configInput === 'production' || configInput === 'test') { - trackingConfig = getConfig(configInput as 'development' | 'production' | 'test'); - } else { - // Try to parse as JSON - try { - trackingConfig = JSON.parse(configInput); - } catch (error) { - core.setFailed(`Invalid config input: ${configInput}. Must be 'development', 'production', 'test', or valid JSON.`); - return; - } - } + // Build configuration from inputs + const trackingConfig: TrackingConfig = { + enableLogging: true, + updateInterval: 60 * 60 * 1000, // 1 hour + npmPackages: npmPackages ? npmPackages.split(',').map(p => p.trim()).filter(p => p) : [], + githubRepos: githubRepositories ? githubRepositories.split(',').map(r => r.trim()).filter(r => r) : [], + pythonPackages: pypiPackages ? pypiPackages.split(',').map(p => p.trim()).filter(p => p) : [], + homebrewPackages: homebrewFormulas ? homebrewFormulas.split(',').map(f => f.trim()).filter(f => f) : [], + powershellModules: powershellModules ? powershellModules.split(',').map(m => m.trim()).filter(m => m) : [], + postmanCollections: postmanCollections ? postmanCollections.split(',').map(c => c.trim()).filter(c => c) : [], + goModules: goModules ? goModules.split(',').map(m => m.trim()).filter(m => m) : [] + }; - // Validate configuration - try { - validateConfig(trackingConfig); - } catch (error) { - core.setFailed(`Configuration validation failed: ${error}`); - return; + // Validate that at least one platform has packages configured + const totalPackages = (trackingConfig.npmPackages?.length || 0) + + (trackingConfig.githubRepos?.length || 0) + + (trackingConfig.pythonPackages?.length || 0) + + (trackingConfig.homebrewPackages?.length || 0) + + (trackingConfig.powershellModules?.length || 0) + + (trackingConfig.postmanCollections?.length || 0) + + (trackingConfig.goModules?.length || 0); + + if (totalPackages === 0 && !previewMode) { + core.warning('No packages configured for tracking. Consider adding packages to track or enabling preview mode.'); } // Create manager const manager = new UsageStatisticsManager(trackingConfig); - + // Generate report let report; if (previewMode) { @@ -61,10 +72,10 @@ async function run() { core.info('📊 Generating comprehensive usage statistics report...'); report = await manager.generateComprehensiveReport(); } - + // Display report await manager.displayReport(report); - + // Write JSON output if (jsonOutputPath) { const jsonContent = JSON.stringify(report, null, 2); @@ -112,36 +123,28 @@ async function run() { } async function generateHumanReadableReport(report: any): Promise { - let content = '# Usage Statistics Report\n\n'; + let content = '# Usage Statistics Summary\n\n'; content += `Generated on: ${new Date().toISOString()}\n\n`; - // Summary - content += '## Summary\n\n'; + // Overall Summary + content += '## Overall Summary\n\n'; content += `- **Total Downloads**: ${report.totalDownloads.toLocaleString()}\n`; content += `- **Unique Packages**: ${report.uniquePackages}\n`; content += `- **Platforms Tracked**: ${report.platforms.join(', ')}\n\n`; - // Platform Breakdown - content += '## Platform Breakdown\n\n'; + // Platform Totals + content += '## Platform Totals\n\n'; for (const [platform, data] of Object.entries(report.platformBreakdown)) { content += `### ${platform.toUpperCase()}\n`; - content += `- Downloads: ${data.totalDownloads.toLocaleString()}\n`; - content += `- Packages: ${data.uniquePackages}\n`; - content += `- Package List: ${data.packages.join(', ')}\n\n`; + content += `- **Downloads**: ${data.totalDownloads.toLocaleString()}\n`; + content += `- **Packages**: ${data.uniquePackages}\n\n`; } - // Top Packages - content += '## Top Packages\n\n'; - report.topPackages.slice(0, 10).forEach((pkg: any, index: number) => { + // Package Rankings + content += '## Package Rankings\n\n'; + report.topPackages.forEach((pkg: any, index: number) => { content += `${index + 1}. **${pkg.name}** (${pkg.platform}) - ${pkg.downloads.toLocaleString()} downloads\n`; }); - content += '\n'; - - // Recent Activity - content += '## Recent Activity\n\n'; - report.recentActivity.slice(0, 5).forEach((activity: any) => { - content += `- **${activity.packageName}** (${activity.platform}) - ${activity.downloads.toLocaleString()} downloads on ${activity.timestamp.toLocaleDateString()}\n`; - }); return content; } @@ -163,14 +166,14 @@ Last updated: ${new Date().toISOString()} - **Unique Packages**: ${report.uniquePackages} - **Platforms Tracked**: ${report.platforms.join(', ')} -### Top Packages -${report.topPackages.slice(0, 10).map((pkg: any, index: number) => - `${index + 1}. **${pkg.name}** (${pkg.platform}) - ${pkg.downloads.toLocaleString()} downloads` +### Platform Totals +${Object.entries(report.platformBreakdown).map(([platform, data]: [string, any]) => + `- **${platform.toUpperCase()}**: ${data.totalDownloads.toLocaleString()} downloads (${data.uniquePackages} packages)` ).join('\n')} -### Recent Activity -${report.recentActivity.slice(0, 5).map((activity: any) => - `- **${activity.packageName}** (${activity.platform}) - ${activity.downloads.toLocaleString()} downloads on ${activity.timestamp.toLocaleDateString()}` +### Top Packages +${report.topPackages.map((pkg: any, index: number) => + `${index + 1}. **${pkg.name}** (${pkg.platform}) - ${pkg.downloads.toLocaleString()} downloads` ).join('\n')} `; diff --git a/src/aggregator.ts b/src/aggregator.ts index 448f7b4..c8a16ec 100644 --- a/src/aggregator.ts +++ b/src/aggregator.ts @@ -17,7 +17,6 @@ export interface AggregatedStats { totalDownloads: number; uniquePackages: number; platforms: string[]; - timeRange: { start: Date; end: Date } | null; platformBreakdown: Record; - recentActivity: Array<{ - packageName: string; - platform: string; - downloads: number; - timestamp: Date; - }>; } export class DownloadStatsAggregator implements DownloadStatsAggregator { @@ -64,17 +57,10 @@ export class DownloadStatsAggregator implements DownloadStatsAggregator { }> = {}; const packageMap = new Map(); - const recentActivity: Array<{ - packageName: string; - platform: string; - downloads: number; - timestamp: Date; - }> = []; let totalDownloads = 0; let uniquePackages = 0; const platforms = new Set(); - const timeRange = { start: new Date(), end: new Date(0) }; // Process each stat for (const stat of stats) { @@ -104,27 +90,8 @@ export class DownloadStatsAggregator implements DownloadStatsAggregator { platformBreakdown[stat.platform].packages.push(stat.packageName); platformBreakdown[stat.platform].uniquePackages++; } - - // Track recent activity - recentActivity.push({ - packageName: stat.packageName, - platform: stat.platform, - downloads: stat.downloadCount, - timestamp: stat.timestamp - }); - - // Update time range - if (stat.timestamp < timeRange.start) { - timeRange.start = stat.timestamp; - } - if (stat.timestamp > timeRange.end) { - timeRange.end = stat.timestamp; - } } - // Sort recent activity by timestamp - recentActivity.sort((a, b) => b.timestamp.getTime() - a.timestamp.getTime()); - // Get top packages const topPackages = Array.from(packageMap.entries()) .map(([key, data]) => ({ @@ -132,17 +99,14 @@ export class DownloadStatsAggregator implements DownloadStatsAggregator { platform: data.platform, downloads: data.downloads })) - .sort((a, b) => b.downloads - a.downloads) - .slice(0, 10); + .sort((a, b) => b.downloads - a.downloads); return { totalDownloads, uniquePackages, platforms: Array.from(platforms), - timeRange: timeRange.start < timeRange.end ? timeRange : null, platformBreakdown, - topPackages, - recentActivity: recentActivity.slice(0, 20) + topPackages }; } diff --git a/src/config.ts b/src/config.ts deleted file mode 100644 index 219b79e..0000000 --- a/src/config.ts +++ /dev/null @@ -1,112 +0,0 @@ -/** - * Configuration for usage statistics tracking - * Customize this file to track your specific packages and tools - */ - -import type { TrackingConfig } from './types'; - -export const defaultConfig: TrackingConfig = { - // NPM packages - Add your NPM package names here - npmPackages: [ - 'lodash', - 'axios' - ], - - // GitHub repositories - Format: 'owner/repo' - githubRepos: [ - 'microsoft/vscode', - 'facebook/react' - ], - - // PyPI packages - Add your Python package names here - pythonPackages: [ - 'requests', - 'numpy' - ], - - // Homebrew formulae - Add your Homebrew package names here - homebrewPackages: [ - 'git', - 'node' - ], - - // PowerShell modules - Add your PowerShell module names here - powershellModules: [ - 'PowerShellGet' - ], - - // Postman collections - Add your Postman collection IDs here - postmanCollections: [ - // Note: These are example IDs - replace with real collection IDs - // For testing, we'll leave these empty to avoid errors - ], - - // Go modules - Add your Go module paths here - goModules: [ - 'github.com/gin-gonic/gin', - 'github.com/go-chi/chi' - ], - - // Update interval in milliseconds (default: 1 hour) - updateInterval: 60 * 60 * 1000, - - // Enable detailed logging - enableLogging: true -}; - -// Test configuration with minimal packages -export const testConfig: TrackingConfig = { - npmPackages: ['lodash'], - githubRepos: [], - pythonPackages: ['requests'], - homebrewPackages: ['git'], - powershellModules: [], - postmanCollections: [], - goModules: [], - updateInterval: 60 * 60 * 1000, - enableLogging: false -}; - -// Environment-specific configurations -export const developmentConfig: TrackingConfig = { - ...defaultConfig, - enableLogging: true, - updateInterval: 5 * 60 * 1000, // 5 minutes for development -}; - -export const productionConfig: TrackingConfig = { - ...defaultConfig, - enableLogging: false, - updateInterval: 60 * 60 * 1000, // 1 hour for production -}; - -// Helper function to get configuration based on environment -export function getConfig(environment: 'development' | 'production' | 'default' | 'test' = 'default'): TrackingConfig { - switch (environment) { - case 'development': - return developmentConfig; - case 'production': - return productionConfig; - case 'test': - return testConfig; - default: - return defaultConfig; - } -} - -// Helper function to validate configuration -export function validateConfig(config: TrackingConfig): string[] { - const errors: string[] = []; - - if (!config.npmPackages && !config.githubRepos && !config.pythonPackages && - !config.homebrewPackages && !config.powershellModules && - !config.postmanCollections && !config.goModules) { - errors.push('No packages configured for tracking. Please add packages to at least one platform.'); - } - - if (config.updateInterval && config.updateInterval < 60000) { - errors.push('Update interval should be at least 60 seconds to avoid rate limiting.'); - } - - return errors; -} \ No newline at end of file diff --git a/src/index.test.ts b/src/index.test.ts index 38bd939..a7111a1 100644 --- a/src/index.test.ts +++ b/src/index.test.ts @@ -1,12 +1,22 @@ import { describe, it, expect, beforeEach } from "bun:test"; import { UsageStatisticsManager } from "./index"; -import { getConfig } from "./config"; +import type { TrackingConfig } from "./types"; describe("UsageStatisticsManager", () => { let manager: UsageStatisticsManager; beforeEach(() => { - const config = getConfig('test'); + const config: TrackingConfig = { + enableLogging: true, + updateInterval: 60 * 60 * 1000, + npmPackages: ['lodash', 'axios'], + githubRepos: ['microsoft/vscode', 'facebook/react'], + pythonPackages: ['requests', 'numpy'], + homebrewPackages: ['git', 'node'], + powershellModules: ['PowerShellGet'], + postmanCollections: [], + goModules: ['github.com/gin-gonic/gin', 'github.com/go-chi/chi'] + }; manager = new UsageStatisticsManager(config); }); @@ -19,7 +29,7 @@ describe("UsageStatisticsManager", () => { expect(report.uniquePackages).toBeGreaterThanOrEqual(0); expect(Array.isArray(report.platforms)).toBe(true); expect(Array.isArray(report.topPackages)).toBe(true); - expect(Array.isArray(report.recentActivity)).toBe(true); + expect(report.topPackages.length).toBeGreaterThan(0); expect(typeof report.platformBreakdown).toBe('object'); }, 30000); // 30 second timeout }); @@ -72,27 +82,23 @@ describe("UsageStatisticsManager", () => { }); describe("Configuration", () => { - it("should load development config", () => { - const config = getConfig('development'); - - expect(config).toBeDefined(); - expect(config.enableLogging).toBe(true); - expect(config.updateInterval).toBe(5 * 60 * 1000); // 5 minutes - }); - - it("should load production config", () => { - const config = getConfig('production'); - - expect(config).toBeDefined(); - expect(config.enableLogging).toBe(false); - expect(config.updateInterval).toBe(60 * 60 * 1000); // 1 hour - }); - - it("should load default config", () => { - const config = getConfig('default'); + it("should create valid config", () => { + const config: TrackingConfig = { + enableLogging: true, + updateInterval: 60 * 60 * 1000, + npmPackages: ['lodash', 'axios'], + githubRepos: ['microsoft/vscode'], + pythonPackages: ['requests'], + homebrewPackages: ['git'], + powershellModules: ['PowerShellGet'], + postmanCollections: [], + goModules: ['github.com/gin-gonic/gin'] + }; expect(config).toBeDefined(); expect(config.enableLogging).toBe(true); expect(config.updateInterval).toBe(60 * 60 * 1000); // 1 hour + expect(config.npmPackages).toContain('lodash'); + expect(config.githubRepos).toContain('microsoft/vscode'); }); }); \ No newline at end of file diff --git a/src/index.ts b/src/index.ts index a92dcc8..138288f 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,7 +2,6 @@ import type { TrackingConfig } from './types'; import { DownloadStatsAggregator } from './aggregator'; import type { AggregatedStats } from './aggregator'; -import { getConfig, validateConfig } from './config'; import { promises as fs } from 'fs'; import path from 'path'; import { execSync } from 'node:child_process'; @@ -45,14 +44,9 @@ Last updated: ${new Date().toISOString()} - **Platforms Tracked**: ${stats.platforms.join(', ')} ### Top Packages -${stats.topPackages.slice(0, 10).map((pkg, index) => +${stats.topPackages.map((pkg, index) => `${index + 1}. **${pkg.name}** (${pkg.platform}) - ${pkg.downloads.toLocaleString()} downloads` ).join('\n')} - -### Recent Activity -${stats.recentActivity.slice(0, 5).map(activity => - `- **${activity.packageName}** (${activity.platform}) - ${activity.downloads.toLocaleString()} downloads on ${activity.timestamp.toLocaleDateString()}` -).join('\n')} `; const startMarker = readmeContent.indexOf(STATS_MARKER_START); @@ -80,8 +74,6 @@ async function gitCommitAndPush(files: string[], message: string) { execSync(`git push`); } -const trackingConfig: TrackingConfig = getConfig(process.env.NODE_ENV as 'development' | 'production' || 'default'); - class UsageStatisticsManager { private aggregator: DownloadStatsAggregator; private lastUpdateTime: Date | null = null; @@ -110,9 +102,9 @@ class UsageStatisticsManager { const report = await this.generateComprehensiveReport(); if (format === 'csv') { - const csvHeader = 'Platform,Package,Downloads,Last Updated\n'; + const csvHeader = 'Platform,Package,Downloads\n'; const csvRows = report.topPackages.map(pkg => - `${pkg.platform},${pkg.name},${pkg.downloads},${new Date().toISOString()}` + `${pkg.platform},${pkg.name},${pkg.downloads}` ).join('\n'); return csvHeader + csvRows; } @@ -125,36 +117,27 @@ class UsageStatisticsManager { } async displayReport(report: AggregatedStats) { - console.log('🚀 Usage Statistics Report'); + console.log('📊 Usage Statistics Summary'); console.log('==================================================\n'); - console.log('📈 Summary:'); + // Overall Summary + console.log('📈 Overall Summary:'); console.log(`Total Downloads: ${report.totalDownloads.toLocaleString()}`); console.log(`Unique Packages: ${report.uniquePackages}`); - console.log(`Platforms Tracked: ${report.platforms.join(', ')}`); - if (report.timeRange) { - console.log(`Time Range: ${report.timeRange.start.toLocaleDateString()} to ${report.timeRange.end.toLocaleDateString()}\n`); - } + console.log(`Platforms Tracked: ${report.platforms.join(', ')}\n`); - console.log('🏗️ Platform Breakdown:'); + // Platform Totals + console.log('🏗️ Platform Totals:'); for (const [platform, data] of Object.entries(report.platformBreakdown)) { - console.log(` ${platform.toUpperCase()}:`); - console.log(` Downloads: ${data.totalDownloads.toLocaleString()}`); - console.log(` Packages: ${data.uniquePackages}`); - console.log(` Package List: ${data.packages.join(', ')}`); + console.log(` ${platform.toUpperCase()}: ${data.totalDownloads.toLocaleString()} downloads (${data.uniquePackages} packages)`); } - console.log(); + console.log(''); - console.log('🏆 Top Packages:'); - report.topPackages.slice(0, 10).forEach((pkg, index) => { + // Package Rankings + console.log('🏆 Package Rankings:'); + report.topPackages.forEach((pkg, index) => { console.log(` ${index + 1}. ${pkg.name} (${pkg.platform}) - ${pkg.downloads.toLocaleString()} downloads`); }); - console.log(); - - console.log('🕒 Recent Activity:'); - report.recentActivity.slice(0, 5).forEach(activity => { - console.log(` ${activity.packageName} (${activity.platform}) - ${activity.downloads.toLocaleString()} downloads on ${activity.timestamp.toLocaleDateString()}`); - }); console.log('=================================================='); } @@ -167,41 +150,49 @@ class UsageStatisticsManager { platform: 'npm', packageName: 'lodash', downloadCount: 1500000, - timestamp: new Date(), - period: 'total' as const, metadata: { version: '4.17.21' } }, { platform: 'npm', packageName: 'axios', downloadCount: 800000, - timestamp: new Date(), - period: 'total' as const, metadata: { version: '1.6.0' } }, { platform: 'github', packageName: 'microsoft/vscode', downloadCount: 500000, - timestamp: new Date(), - period: 'total' as const, metadata: { release: 'v1.85.0' } }, { platform: 'pypi', packageName: 'requests', downloadCount: 300000, - timestamp: new Date(), - period: 'total' as const, metadata: { version: '2.31.0' } }, { platform: 'homebrew', packageName: 'git', downloadCount: 250000, - timestamp: new Date(), - period: 'total' as const, metadata: { version: '2.43.0' } + }, + { + platform: 'powershell', + packageName: 'PowerShellGet', + downloadCount: 120000, + metadata: { version: '2.2.5' } + }, + { + platform: 'postman', + packageName: 'Postman Collection', + downloadCount: 75000, + metadata: { collectionId: '12345' } + }, + { + platform: 'go', + packageName: 'github.com/gin-gonic/gin', + downloadCount: 45000, + metadata: { version: 'v1.9.1' } } ]; @@ -214,15 +205,20 @@ class UsageStatisticsManager { async function main() { console.log('🚀 Usage Statistics Tracker Starting...\n'); - // Validate configuration - try { - validateConfig(trackingConfig); - } catch (error) { - console.error('❌ Configuration validation failed:', error); - process.exit(1); - } + // Create a default configuration for CLI usage + const defaultConfig: TrackingConfig = { + enableLogging: true, + updateInterval: 60 * 60 * 1000, // 1 hour + npmPackages: ['lodash', 'axios'], + githubRepos: ['microsoft/vscode', 'facebook/react'], + pythonPackages: ['requests', 'numpy'], + homebrewPackages: ['git', 'node'], + powershellModules: ['PowerShellGet'], + postmanCollections: [], + goModules: ['github.com/gin-gonic/gin', 'github.com/go-chi/chi'] + }; - const manager = new UsageStatisticsManager(trackingConfig); + const manager = new UsageStatisticsManager(defaultConfig); try { // Check for preview mode @@ -263,4 +259,4 @@ if (import.meta.main) { main(); } -export { UsageStatisticsManager, trackingConfig }; \ No newline at end of file +export { UsageStatisticsManager }; \ No newline at end of file diff --git a/src/types/index.ts b/src/types/index.ts index 4dde74d..44763ec 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -7,8 +7,6 @@ export interface BaseDownloadStats { packageName: string; version?: string; downloadCount: number; - timestamp: Date; - period?: 'daily' | 'weekly' | 'monthly' | 'total'; metadata?: Record; } @@ -24,7 +22,6 @@ export interface DownloadStatsAggregator { totalDownloads: number; uniquePackages: number; platforms: string[]; - timeRange: { start: Date; end: Date } | null; }; }