
Security News
Attackers Are Hunting High-Impact Node.js Maintainers in a Coordinated Social Engineering Campaign
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.
@computerwwwizards/version-inferer
Advanced tools
A flexible, source-agnostic library for inferring and resolving configuration values from multiple sources with configurable precedence and conflict handling strategies
A flexible, source-agnostic library for inferring and resolving configuration values from multiple sources with configurable precedence and conflict handling strategies.
This library solves the common problem of determining which version or configuration value to use when multiple sources provide conflicting information. Originally designed for Node.js version inference, it has evolved into a generic resolution system applicable to any scenario requiring multi-source orchestration.
.nvmrc, package.json, or CI/CD workflowspnpm install @computerwwwizards/version-inferer
import inferNodeVersion from '@computerwwwizards/version-inferer';
// Infer Node.js version from project files
const result = await inferNodeVersion();
console.log(`Use Node.js ${result.version}`);
Automatically detects Node version from .nvmrc or package.json:
import inferNodeVersion from '@computerwwwizards/version-inferer';
const result = await inferNodeVersion({
rootPath: '/path/to/project'
});
if (result.version) {
console.log(`✅ Node version: ${result.version}`);
} else {
console.log('❌ No version found');
}
// Result includes all checked sources
console.log('Checked sources:', result.data);
// { nvmrc: '20.0.0', 'package.json': null }
Check GitHub Actions workflow files for Node version:
import inferNodeVersion from '@computerwwwizards/version-inferer';
const result = await inferNodeVersion({
workflowFilePath: '.github/workflows/ci.yml',
workflowOption: ['jobs', 'test', 'steps', '0', 'with', 'node-version'],
rootPath: process.cwd()
});
console.log('Version from CI:', result.version);
Prioritize specific sources over others:
import inferNodeVersion, { ConflictStrategy } from '@computerwwwizards/version-inferer';
const result = await inferNodeVersion({
workflowFilePath: '.github/workflows/deploy.yml',
workflowOption: ['jobs', 'deploy', 'with', 'node-version'],
// Prioritize workflow, then package.json, then .nvmrc
order: ['workflow', 'package.json', 'nvmrc'],
conflictStrategy: ConflictStrategy.STOP_ON_FIRST
});
console.log(`Using: ${result.version}`);
Different strategies for handling conflicting versions:
import inferNodeVersion, { ConflictStrategy } from '@computerwwwizards/version-inferer';
// Strategy 1: Report conflicts but continue
const result1 = await inferNodeVersion({
conflictStrategy: ConflictStrategy.REPORT
});
if (result1.conflicts.length > 0) {
console.log('⚠️ Version conflicts detected:');
result1.conflicts.forEach(conflict => {
console.log(` ${conflict.sources.join(' vs ')}: ${conflict.values.join(' vs ')}`);
});
}
// Strategy 2: Throw error on conflict
try {
const result2 = await inferNodeVersion({
conflictStrategy: ConflictStrategy.ERROR
});
} catch (error) {
console.error('Version conflict error:', error.message);
}
// Strategy 3: Stop at first valid version (default)
const result3 = await inferNodeVersion({
conflictStrategy: ConflictStrategy.STOP_ON_FIRST
});
console.log('First valid version:', result3.version);
Build your own resolver with custom sources:
import VersionPrecedenceResolver from '@computerwwwizards/version-inferer';
const resolver = new VersionPrecedenceResolver();
// Add custom sources
resolver
.registerSource('envVar', async () => process.env.NODE_VERSION || null)
.registerSource('defaultConfig', async () => '18.0.0')
.registerSource('userPreference', {
getVersion: async () => {
// Read from database, API, etc.
return '20.0.0';
}
});
const result = await resolver.resolveVersion({
order: ['userPreference', 'envVar', 'defaultConfig']
});
console.log('Resolved version:', result.version);
Create a script to ensure environment matches CI:
#!/usr/bin/env node
import inferNodeVersion from '@computerwwwizards/version-inferer';
import { execSync } from 'child_process';
async function ensureNodeVersion() {
const result = await inferNodeVersion({
workflowFilePath: '.github/workflows/ci.yml',
workflowOption: ['jobs', 'test', 'strategy', 'matrix', 'node-version', '0'],
order: ['workflow', 'nvmrc', 'package.json']
});
if (!result.version) {
console.error('❌ No Node version specified');
process.exit(1);
}
const currentVersion = execSync('node -v').toString().trim();
const requiredVersion = `v${result.version}`;
if (currentVersion !== requiredVersion) {
console.log(`⚠️ Version mismatch: ${currentVersion} !== ${requiredVersion}`);
console.log(`Run: nvm use ${result.version}`);
process.exit(1);
}
console.log(`✅ Using correct Node version: ${currentVersion}`);
}
ensureNodeVersion();
.nvmrc filesengines.node from package.json| Strategy | Behavior |
|---|---|
STOP_ON_FIRST | Returns first non-null value (default) |
REPORT | Collects conflicts but continues resolution |
ERROR | Throws error if conflicts detected |
All sources use a factory pattern to ensure proper resource management:
import { createReadStream } from 'fs';
import { NvmrcStreamSource } from '@computerwwwizards/version-inferer';
// ✅ Good: Stream created on-demand and auto-cleaned
const source = new NvmrcStreamSource(() => createReadStream('.nvmrc'));
// ❌ Bad: Pre-created stream may leak or lock
const stream = createReadStream('.nvmrc');
const source = new NvmrcStreamSource(stream); // Old API
This library is evolving toward:
Install dependencies:
pnpm install
pnpm build
pnpm dev
pnpm test
pnpm format
inferNodeVersion(options?)Main function for Node.js version inference.
Options:
{
workflowFilePath?: string; // Path to CI/CD workflow file
workflowOption?: string[]; // YAML path to version field
rootPath?: string; // Project root (default: process.cwd())
order?: string[]; // Source precedence order
conflictStrategy?: ConflictStrategy; // How to handle conflicts
}
Returns: Promise<ResolveResult>
{
version: string | null; // Resolved version
data: Record<string, string | null>; // All source values
conflicts: Conflict[]; // Detected conflicts
}
VersionPrecedenceResolverGeneric resolver class for custom implementations.
See Precedence Resolver Documentation for detailed architecture and design decisions.
MIT License - see the LICENSE file for details.
Copyright (c) 2025 ComputerWWWizards
Contributions welcome! Please read our contributing guidelines before submitting PRs.
FAQs
A flexible, source-agnostic library for inferring and resolving configuration values from multiple sources with configurable precedence and conflict handling strategies
We found that @computerwwwizards/version-inferer demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.