bleurgh
v1.2.0
Published
CLI tool for purging Fastly cache by surrogate keys across multiple environments
Readme
Bleurgh
A powerful command-line tool for purging Fastly cache by surrogate keys across multiple environments and services.
Features
- 🚀 Multi-environment support: dev, test, prod
- 🔧 Dynamic service discovery: Multiple environment variable patterns supported
- �️ Friendly service names: Optional display names for better logging and team clarity
- �🎯 Direct service override: Use
--servicesto specify service IDs directly - 📝 Multiple key support: Purge multiple cache keys in a single command
- 🔄 Batch purging: Purge multiple services simultaneously
- � Complete purge: Use
--allflag to purge entire cache for services - �🧪 Dry run mode: Preview operations without making changes
- 📝 Verbose logging: Detailed operation feedback
- ⚡ Fast execution: Concurrent API calls with proper error handling
- 🛡️ Error resilience: Continues operation even if some services fail
Quick Start
First-Time Setup
Install the CLI:
npm install -g bleurghGet your Fastly API token from here
Set up environment variables:
export FASTLY_TOKEN="your-fastly-api-token" export FASTLY_DEV_SERVICE_IDS="dev-service-1,dev-service-2"Test it works:
bleurgh user-123 --dry-run
Team Setup (Administrators)
Generate setup strings for your team using the built-in generator:
# First, set your environment variables (examples below)
export FASTLY_DEV_SERVICE_IDS="dev-svc-1,dev-svc-2"
export FASTLY_TEST_SERVICE_IDS="test-svc-1,test-svc-2"
export FASTLY_PROD_SERVICE_IDS="prod-svc-1,prod-svc-2"
export FASTLY_DEFAULT_KEYS="global,always"
# Optionally add friendly names for your ids
export FASTLY_DEV_SERVICE_NAMES="www-dev,backend-dev"
export FASTLY_TEST_SERVICE_NAMES="www-test,backend-test"
export FASTLY_PROD_SERVICE_NAMES="www,backend"
# Generate setup string from your current environment
node -e "
const { generateSetupString } = require('./dist/setup.js');
// Generate setup with all currently set FASTLY_* environment variables
generateSetupString();
// Or specify which environment variables to export
// generateSetupString(['FASTLY_DEV_SERVICE_IDS', 'FASTLY_TEST_SERVICE_IDS']);
// Or include custom environment variable names (any keys)
// generateSetupString(['FASTLY_STAGE_SERVICE_IDS', 'FASTLY_QA_SERVICE_IDS']);
"
**Security Note**: The `generateSetupString()` function **never** includes `FASTLY_TOKEN` in setup strings for security. Recipients must set their own tokens separately.
Share the generated base64 string with your team:
```bash
# Team members run this:
bleurgh --setup <base64-string>
# Team members also need to set their own token:
export FASTLY_TOKEN="their-individual-token"
# Or for automatic setup:
bleurgh --setup <base64-string> --allow-executionInstallation Options
Global Installation (Recommended)
npm install -g bleurghNPX Usage (No Installation Required)
npx bleurgh <key> [options]Local Development
git clone <your-repo-url>
cd bleurgh
npm install
npm run buildRunning Locally
After building the project, you can run it locally in several ways:
# Option 1: Run the compiled JavaScript directly
./dist/index.js user-123 --env dev
# Option 2: Use npm run dev (with ts-node, no build required)
npm run dev user-123 --env dev
# Option 3: Use node directly
node dist/index.js user-123 --env dev
# Option 4: Create a symlink for global-like usage (optional)
npm link
bleurgh user-123 --env devNote: Make sure you have the required environment variables set up before running locally:
export FASTLY_TOKEN="your-fastly-api-token"
export FASTLY_DEV_SERVICE_IDS="dev-service-1,dev-service-2"
#optional friendly name for ids
export FASTLY_DEV_SERVICE_NAMES="www, backend"Basic Usage
# Purge cache for user-123 in dev environment (default)
bleurgh user-123
# Purge multiple keys at once
bleurgh user-123 product-456 article-789
# Purge specific URL (global across all services)
bleurgh https://example.com/page
# Purge ALL cache for services (ignores keys and defaults)
bleurgh --all
# Purge cache in production environment
bleurgh product-456 --env prod
# Dry run to see what would be purged
bleurgh user-123 --dry-run
# Override service IDs directly
bleurgh user-123 --services svc-1,svc-2,svc-3Configuration
Required
FASTLY_TOKEN: Your Fastly API token (Get one here)
Optional
FASTLY_DEV_SERVICE_IDS: Development service IDs (comma-separated)FASTLY_TEST_SERVICE_IDS: Test service IDsFASTLY_PROD_SERVICE_IDS: Production service IDsFASTLY_DEV_SERVICE_NAMES: Development service friendly names (comma-separated, optional)FASTLY_TEST_SERVICE_NAMES: Test service friendly names (comma-separated, optional)FASTLY_PROD_SERVICE_NAMES: Production service friendly names (comma-separated, optional)FASTLY_DEFAULT_KEYS: Global default cache keys (comma-separated, optional)FASTLY_{ENV}_DEFAULT_KEYS: Environment-specific default keys (optional, overrides global)
Alternative patterns supported: DEV_SERVICE_IDS, SERVICE_IDS_DEV, FASTLY_SERVICES_DEV
Service names patterns: DEV_SERVICE_NAMES, SERVICE_NAMES_DEV, FASTLY_SERVICES_DEV_NAMES
# Example setup
export FASTLY_TOKEN="your-fastly-api-token"
export FASTLY_DEV_SERVICE_IDS="dev-service-1,dev-service-2"
export FASTLY_DEV_SERVICE_NAMES="Dev Frontend,Dev API"
export FASTLY_DEFAULT_KEYS="global,always"
# Environment-specific default keys (optional)
export FASTLY_DEV_DEFAULT_KEYS="dev-global,dev-cache"
export FASTLY_PROD_DEFAULT_KEYS="prod-global,prod-cache,critical"Advanced Usage
# Dry run with multiple keys
bleurgh user-123 product-456 article-789 --dry-run
# Purge ALL cache for services
bleurgh --all --env prod
# Verbose output for debugging
bleurgh user-123 --verbose
# Combine options
bleurgh key1 key2 key3 --env prod --dry-run --verbose
# Emergency complete cache purge
bleurgh --all --services emergency-svc --verboseCommand Options
| Option | Alias | Description | Default |
|--------|-------|-------------|---------|
| --all | | Purge ALL cache for services (ignores keys and defaults) | false |
| --env | -e | Target environment (dev|test|prod) | dev |
| --services | -s | Comma-separated service IDs (overrides environment) | |
| --verbose | -v | Enable verbose logging | false |
| --dry-run | -d | Preview operation without purging | false |
| --help | -h | Show help information | |
| --version | | Show version number | |
Detailed Documentation
Environment Variable Patterns
Bleurgh supports multiple environment variable patterns for maximum flexibility:
Primary patterns:
FASTLY_{ENV}_SERVICE_IDS: Standard pattern (e.g.,FASTLY_DEV_SERVICE_IDS){ENV}_SERVICE_IDS: Simplified pattern (e.g.,DEV_SERVICE_IDS)SERVICE_IDS_{ENV}: Reverse pattern (e.g.,SERVICE_IDS_DEV)FASTLY_SERVICES_{ENV}: Alternative pattern (e.g.,FASTLY_SERVICES_DEV)
Service names patterns (optional):
FASTLY_{ENV}_SERVICE_NAMES: Standard pattern (e.g.,FASTLY_DEV_SERVICE_NAMES){ENV}_SERVICE_NAMES: Simplified pattern (e.g.,DEV_SERVICE_NAMES)SERVICE_NAMES_{ENV}: Reverse pattern (e.g.,SERVICE_NAMES_DEV)FASTLY_SERVICES_{ENV}_NAMES: Alternative pattern (e.g.,FASTLY_SERVICES_DEV_NAMES)
Service Names (Optional)
Bleurgh supports friendly service names that are displayed in logs alongside service IDs. This makes it easier to identify which services are being purged, especially in team environments.
# Service IDs are required for API calls
export FASTLY_DEV_SERVICE_IDS="svc-abc123,svc-def456,svc-ghi789"
# Service names are optional and used for display only
export FASTLY_DEV_SERVICE_NAMES="Frontend Service,API Service,Worker Service"Important notes about service names:
- Service names are purely cosmetic and used only for logging
- They should match the order of service IDs (1st name = 1st ID, etc.)
- If names and IDs don't match up perfectly, the tool gracefully handles mismatches
- Missing names will fall back to showing just the service ID
- Extra names beyond the number of IDs are ignored
- The app will never crash due to name/ID mismatches
Complete Configuration Example
export FASTLY_TOKEN="your-fastly-api-token"
# Choose any of these patterns that works best for you:
export FASTLY_DEV_SERVICE_IDS="dev-service-1,dev-service-2"
export TEST_SERVICE_IDS="test-service-1,test-service-2"
export SERVICE_IDS_PROD="prod-service-1,prod-service-2"
# Optional - Service names for friendly display
export FASTLY_DEV_SERVICE_NAMES="Dev Frontend,Dev API"
export TEST_SERVICE_NAMES="Test Frontend,Test API"
export SERVICE_NAMES_PROD="Prod Frontend,Prod API"
# Optional - Default keys
export FASTLY_DEFAULT_KEYS="global,always,common"- Key Assembly: Combines default keys with your specified key(s):
- Environment-specific keys:
FASTLY_{ENV}_DEFAULT_KEYS(e.g.,FASTLY_DEV_DEFAULT_KEYS) - Falls back to global keys:
FASTLY_DEFAULT_KEYS - Finally your specified keys
- Environment-specific keys:
- Service Discovery: Uses flexible environment variable patterns or
--servicesoverride - Concurrent Purging: Makes parallel API calls to all services
- Result Reporting: Shows success/failure status for each service
Service ID Resolution Priority
- Direct override:
--servicesparameter (highest priority) - Environment variables: Multiple patterns supported
- No fallback: If no service IDs are configured, the tool will show setup instructions
Purge Keys
The tool automatically includes default keys plus your specified key(s):
Global defaults (always used unless environment-specific ones are set):
export FASTLY_DEFAULT_KEYS="global,always"
bleurgh user-123 # Purges: ["global", "always", "user-123"]Environment-specific defaults (override global defaults):
export FASTLY_DEFAULT_KEYS="global,always"
export FASTLY_DEV_DEFAULT_KEYS="dev-global,dev-always"
export FASTLY_PROD_DEFAULT_KEYS="prod-global,prod-critical"
bleurgh user-123 --env dev # Purges: ["dev-global", "dev-always", "user-123"]
bleurgh user-123 --env prod # Purges: ["prod-global", "prod-critical", "user-123"]
bleurgh user-123 --env test # Purges: ["global", "always", "user-123"] (fallback)Key assembly examples:
- With defaults:
bleurgh user-123→["global", "always", "user-123"] - Without defaults:
bleurgh user-123→["user-123"] - Multiple keys:
bleurgh key1 key2 key3→["global", "always", "key1", "key2", "key3"]
URL Purging
When the first argument starts with https://, bleurgh automatically switches to URL purge mode:
- Global purging: URLs are purged globally across Fastly's network (not per-service)
- Single API call: Only one purge request is made regardless of configured services
- Extra keys ignored: Additional arguments after the URL are ignored with a warning
- Environment independent: URL purges work the same across all environments
Examples:
# Purge a specific page globally
bleurgh https://example.com/page
# URL with query parameters (automatically encoded)
bleurgh "https://example.com/api/data?id=123&type=json"
# Multiple arguments - extra keys are ignored with warning
bleurgh https://example.com/page extra-key another-key
# ⚠️ Warning: URL detected: https://example.com/page - ignoring additional keys: extra-key, another-keyDevelopment Workflow
# Preview changes in dev
bleurgh feature-xyz --dry-run --verbose
# Actually purge dev cache
bleurgh feature-xyz
# Purge multiple related features at once
bleurgh feature-xyz feature-abc component-123 --env dev
# Purge numerical content IDs (e.g., from CMS)
bleurgh 123456 789012 999 --dry-run
# Deploy to test and purge
bleurgh feature-xyz --env test
# Production deployment with specific services
bleurgh feature-xyz --services prod-svc-1,prod-svc-2
# Emergency complete cache clear
bleurgh --all --services emergency-svc --verbose
# Emergency purge with specific keys
bleurgh critical-fix urgent-update hotfix-123 --services emergency-svc --verbose
# Complete cache refresh for maintenance
bleurgh --all --env prod --dry-run
# Mixed keys - user IDs, content IDs, and feature flags
bleurgh user-123 456789 feature-new-ui product-abc --env prod
# Release purge - clear multiple cache keys for a release
bleurgh release-v2.1.0 api-v2 frontend-v2 --env prod --verboseCI/CD Integration
# GitHub Actions example
- name: Purge Fastly Cache
run: |
npx bleurgh ${{ github.sha }} --env prod
env:
FASTLY_TOKEN: ${{ secrets.FASTLY_TOKEN }}
FASTLY_PROD_SERVICE_IDS: ${{ secrets.FASTLY_PROD_SERVICE_IDS }}
# Alternative with direct service specification
- name: Purge Specific Services
run: |
npx bleurgh ${{ github.sha }} --services ${{ secrets.PROD_SERVICES }}
env:
FASTLY_TOKEN: ${{ secrets.FASTLY_TOKEN }}
# Purge multiple keys for a release
- name: Purge Release Cache
run: |
npx bleurgh release-${{ github.ref_name }} api-cache frontend-cache --env prod
env:
FASTLY_TOKEN: ${{ secrets.FASTLY_TOKEN }}
FASTLY_PROD_SERVICE_IDS: ${{ secrets.FASTLY_PROD_SERVICE_IDS }}
# Complete cache flush for major deployments
- name: Complete Cache Flush
run: |
npx bleurgh --all --env prod
env:
FASTLY_TOKEN: ${{ secrets.FASTLY_TOKEN }}
FASTLY_PROD_SERVICE_IDS: ${{ secrets.FASTLY_PROD_SERVICE_IDS }}Docker Usage
FROM node:18-alpine
RUN npm install -g bleurgh
ENTRYPOINT ["bleurgh"]docker run --rm \
-e FASTLY_TOKEN="your-token" \
-e PROD_SERVICE_IDS="service1,service2" \
your-image user-123 --env prod
# Or with direct service specification
docker run --rm \
-e FASTLY_TOKEN="your-token" \
your-image user-123 --services service1,service2
# Complete cache purge
docker run --rm \
-e FASTLY_TOKEN="your-token" \
-e PROD_SERVICE_IDS="service1,service2" \
your-image --all --env prodError Handling
The tool provides detailed error messages and exit codes:
- Exit Code 0: All operations successful
- Exit Code 1: One or more operations failed
Example error scenarios:
- Missing
FASTLY_TOKEN - Invalid service IDs
- Network connectivity issues
- Insufficient API permissions
Development & Contributing
Development Setup
git clone <repo-url>
cd bleurgh
npm install
npm run build
npm testAvailable Scripts
npm run build # Compile TypeScript
npm run dev # Run with ts-node
npm test # Run comprehensive test suite
npm run test:watch # Run tests in watch mode
npm run test:coverage # Run tests with coverage reportContributing
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests if applicable
- Submit a pull request
Technical Reference
Bleurgh includes a comprehensive test suite with excellent coverage:
- Core Logic Tests (
test/core.test.ts): Unit tests for all core functions - End-to-End Tests (
test/e2e.test.ts): Integration tests for real-world scenarios - CLI Tests (
test/cli.test.ts): CLI integration tests (currently skipped in automated runs)
Test Coverage:
- 98.7% Statement Coverage
- 96.42% Branch Coverage
- 100% Function Coverage
- 98.61% Line Coverage
# Run all tests
npm test
# Run tests with coverage report
npm run test:coverage
# Run tests in watch mode during development
npm run test:watchThe test suite includes:
- Core Logic Tests (
test/core.test.ts): Unit tests for service ID resolution, key handling, and error scenarios - End-to-End Integration Tests (
test/e2e.test.ts): Real-world workflow testing and edge cases - All business logic is thoroughly tested; CLI layer is a thin wrapper around tested core functions
├── src/
│ ├── index.ts # Main CLI implementation
│ ├── core.ts # Core business logic
│ ├── cli-help.ts # Contextual help system
│ └── setup.ts # Setup and configuration
├── test/ # Test suites
├── scripts/ # Utility scripts
├── dist/ # Compiled JavaScript (auto-generated)
├── package.json # Package configuration
├── tsconfig.json # TypeScript configuration
└── README.md # This fileFastly Purge API
This tool uses the Fastly Purge API:
POST https://api.fastly.com/service/{service_id}/purgeFor the --all flag, it uses the purge all endpoint:
POST https://api.fastly.com/service/{service_id}/purge_allEnvironment Variables
| Variable | Required | Description | Example |
|----------|----------|-------------|---------|
| FASTLY_TOKEN | ✅ | Fastly API token | abc123... |
| FASTLY_DEV_SERVICE_IDS | ❌ | Dev service IDs (primary pattern) | svc1,svc2 |
| DEV_SERVICE_IDS | ❌ | Dev service IDs (alternative pattern) | svc1,svc2 |
| SERVICE_IDS_DEV | ❌ | Dev service IDs (reverse pattern) | svc1,svc2 |
| FASTLY_SERVICES_DEV | ❌ | Dev service IDs (alternative pattern) | svc1,svc2 |
| FASTLY_DEV_SERVICE_NAMES | ❌ | Dev service friendly names (optional) | Frontend,API |
| DEV_SERVICE_NAMES | ❌ | Dev service names (alternative pattern) | Frontend,API |
| SERVICE_NAMES_DEV | ❌ | Dev service names (reverse pattern) | Frontend,API |
| FASTLY_SERVICES_DEV_NAMES | ❌ | Dev service names (alternative pattern) | Frontend,API |
| FASTLY_DEFAULT_KEYS | ❌ | Global default purge keys (comma-separated) | global,always |
| FASTLY_{ENV}_DEFAULT_KEYS | ❌ | Environment-specific default keys (overrides global) | dev-global,dev-cache |
Note: Similar patterns work for TEST and PROD environments
The bleurgh CLI includes robust security validation to prevent command injection and protect your environment:
Setup Security Features
- Input Validation: All configuration values are validated for dangerous patterns, shell metacharacters, and suspicious keywords
- Shell Injection Protection: Uses the
shescapelibrary to detect values that could be exploited in shell environments - Command Structure Validation: Export commands are validated to ensure they follow safe patterns
- Environment Variable Allowlist: Only approved Fastly-related environment variables can be set
- Base64 Configuration: Setup strings are base64-encoded to prevent accidental exposure in logs
Security Patterns Detected
The CLI automatically detects and prevents:
- Command injection attempts (
; rm -rf /,$(whoami), etc.) - Shell metacharacters that could be exploited
- Path traversal attempts (
../) - Control characters and null bytes
- Suspicious keywords (curl, wget, eval, etc.)
- Invalid environment variable names
Best Practices
- Always verify setup configuration strings from trusted sources
- Use the
--dry-runflag to preview operations before execution - Regularly rotate your Fastly API tokens
- Keep your CLI updated to get the latest security improvements
Support & Community
Getting Help
Need assistance running bleurgh?
- 📖 Check out
.ai-instructions.md- comprehensive guide for AI assistants helping with setup and troubleshooting - 🚀 Quick start: See the "Quick Start" section above for step-by-step setup
- ❓ Common issues: Most problems are related to missing
FASTLY_TOKENor service ID configuration
For developers and contributors:
License
MIT
Changelog
v1.3.0
- NEW: URL purge support - automatically detects URLs starting with
https://and purges them globally - IMPROVED: URL purging is now global across Fastly's network, not per-service, for better efficiency
- IMPROVED: Enhanced logging for URL purges to clarify global scope
- IMPROVED: Better validation and warnings when URL is mixed with other keys (ignores extra keys)
- TECHNICAL: Optimized URL purge operations to make only one API call regardless of configured services
- TECHNICAL: Added comprehensive test coverage for URL purge functionality
- UPDATED: CLI help and documentation to clarify URL purge behavior
v1.2.0
- NEW: Complete cache purge with
--allflag - purges entire cache for services without requiring specific keys - NEW: Enhanced CLI validation - prevents using
--allwith specific keys for safety - NEW: Updated help documentation to include complete cache purge examples
- IMPROVED: Better error messages for invalid flag combinations
- IMPROVED: Enhanced logging to differentiate between key-specific and complete purges
- TECHNICAL: Added comprehensive test coverage for new
--allfunctionality - TECHNICAL: Refactored core purge logic for better maintainability and reduced complexity
v1.1.0
- NEW: Multiple keys support - purge multiple cache keys in a single command
- NEW: Friendly service names support via
*_SERVICE_NAMESenvironment variables for better logging - NEW: Team setup feature with base64-encoded configuration and selective export options
- NEW: Contextual help system - shows setup instructions or quick start based on configuration
- NEW: Comprehensive test suite with 98%+ coverage (Jest-based unit and integration tests)
- NEW: Automated testing in CI/CD pipeline
- FIXED: Support for numerical cache keys (e.g.,
123456,0,-123,3.14) - Enhanced CLI with flexible positional arguments and setup options
- Improved error handling and logging with colorized output
- Updated examples and documentation
- Improved logging to show user keys separately from all keys
- Core logic extracted to separate modules for better testability
- Removed all hardcoded fallback values for better user experience
- Service names feature gracefully handles mismatches between IDs and names without crashing
v1.0.0
- Initial release
- Multi-environment support
- Dynamic service discovery with multiple environment variable patterns
- Direct service override with --services parameter
- Configurable service IDs
- Dry run mode
- Verbose logging
- Concurrent purging
