
Security News
Axios Maintainer Confirms Social Engineering Attack Behind npm Compromise
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.
@reliverse/bump
Advanced tools
@reliverse/bump is a powerful version bumping tool for javascript and typescript libraries.
sponsor — discord — repo — npm — docs
# bun — pnpm — yarn — npm
bun add -D @reliverse/bump
Just run:
bun rse bump
That's it! Follow the prompts to:
import { bumpVersionWithAnalysis } from "@reliverse/bump";
// Patch bump
await bumpVersionWithAnalysis(
"patch", // bumpType: "patch" | "minor" | "major" | "auto" | "manual"
["package.json"], // files to bump
{ dryRun: false }, // options
);
// Manual version with bumpSet from config
await bumpVersionWithAnalysis(
"manual", // bumpType
["package.json"], // files to bump
{ dryRun: false }, // options
"1.2.3", // bumpSet from dler.ts
);
// Manual version with customVersion
await bumpVersionWithAnalysis(
"manual", // bumpType
["package.json"], // files to bump
{
dryRun: false,
customVersion: "1.2.3" // overrides bumpSet if provided
},
);
CLI is available via Dler CLI by Reliverse.
# Basic usage examples
bun rse bump --bumpType patch --files package.json src/version.ts
bun rse bump --bumpType minor --dryRun # Preview changes
bun rse bump --bumpType major --mainFile package.json
bun rse bump --bumpType auto --mainFile package.json --files package.json dler.ts
bun rse bump --bumpType manual --customVersion 2.0.0 --mainFile package.json
# Advanced usage
bun rse bump \
--bumpType manual \
--customVersion 1.0.1 \
--dryRun \
--mainFile package.json \
--verbose \
--files "package.json dler.ts"
# Available options
--dev # Run in dev mode
--bumpType # Type of bump: patch|minor|major|auto|manual
--customVersion # Set specific version (with manual mode)
--dryRun # Preview changes without applying
--mainFile # Version source file (default: package.json)
--verbose # Show detailed logs
--files # Files to bump (space or comma-separated)
--disableBump # Disable bumping (useful for CI)
The tool performs deep analysis of your files to:
dler.tsBump Handler: Advanced version bumping with:
Bump Disable Management:
import {
bumpVersionWithAnalysis,
analyzeFiles,
getCurrentVersion,
type BumpMode,
type FileAnalysis
} from "@reliverse/bump";
// First analyze files
const currentVersion = await getCurrentVersion("package.json");
const fileAnalysis = await analyzeFiles(
[
"package.json",
"src/version.ts",
"dler.ts"
],
currentVersion
);
// Filter supported files
const supportedFiles = fileAnalysis
.filter(f => f.supported)
.map(f => f.file);
// Then bump versions
await bumpVersionWithAnalysis(
"patch", // bumpType
supportedFiles, // only supported files
{
dryRun: true, // preview only
verbose: true, // show detailed logs
}
);
type BumpMode = "patch" | "minor" | "major" | "auto" | "manual";
type BumpOptions = {
dryRun?: boolean;
verbose?: boolean;
customVersion?: string;
};
type FileAnalysis = {
file: string;
supported: boolean;
detectedVersion: string | null;
versionMismatch: boolean;
reason: string;
fileType: "package.json" | "typescript" | "unknown";
};
// Check if version bumping is currently disabled
await isBumpDisabled(): Promise<boolean>
// Set bumpDisable flag to a specific value
await setBumpDisabledValueTo(value: boolean): Promise<void>
// Update any field in dler.ts
await updateDlerConfig(field: string, value: any): Promise<void>
// Get current version from a file
await getCurrentVersion(filePath?: string, field?: string): Promise<string>
// Get package name from a file
await getPackageName(filePath?: string, field?: string): Promise<string>
// Get package author from a file
await getPackageAuthor(filePath?: string, field?: string): Promise<string>
// Compare two versions
compareVersions(version1: string, version2: string): number
// Get latest version from an array of versions
getLatestVersion(versions: string[]): string | null
// Check if a version is a prerelease
isPrerelease(version: string): boolean
// Check if a version satisfies a range
satisfiesRange(version: string, range: string): boolean
// Parse semver into components
parseSemver(version: string): [number, number, number]
// Validate semver format
isValidSemver(version: string): boolean
Options:
--bumpMode <mode> Mode: patch, minor, major, auto, manual
--customVersion <ver> Set specific version (with manual mode)
--mainFile <file> Version source file (default: package.json)
--dryRun Preview changes without applying
--disableBump Disable bumping (useful for CI)
--dev Run in dev mode
dler.tsCreate a dler.ts to configure default behavior:
import { defineConfig } from "@reliverse/dler";
export default defineConfig({
bumpFilter: [
"package.json",
"src/version.ts",
],
bumpMode: "patch",
bumpDisable: false,
});
// src/cli.ts
import { relinka } from "@reliverse/relinka";
import {
runMain,
defineCommand,
defineArgs,
selectPrompt,
inputPrompt,
startPrompt,
endPrompt,
} from "rempts";
import path from "node:path";
import semver from "semver";
import {
bumpVersionWithAnalysis,
getCurrentVersion,
getFilesFromConfigOrDefault,
getConfigFromDler,
type BumpMode,
validateBumpConfig,
getDefaultBumpMode,
handleNonInteractiveSession,
handleInteractiveSession,
type SessionConfig,
} from "./mod.js";
const bumpTypes: BumpMode[] = ["patch", "minor", "major", "auto", "manual"];
const main = defineCommand({
meta: {
name: "bump",
description:
"Allows you to bump the version of your project interactively.",
},
args: defineArgs({
dev: {
type: "boolean",
description: "Runs the CLI in dev mode",
},
bumpType: {
type: "string",
description: "The type of version bump to perform",
allowed: bumpTypes,
},
customVersion: {
type: "string",
description: "Custom version to set (only used with manual bump type)",
},
disableBump: {
type: "boolean",
description: "Disables the bump (this is useful for CI)",
},
files: {
type: "string",
description:
'Files to bump (comma or space-separated, or quoted: "package.json dler.ts")',
default: "",
},
dryRun: {
type: "boolean",
description: "Preview changes without writing files",
},
mainFile: {
type: "string",
description:
"The file to use as version source (defaults to package.json)",
default: "package.json",
},
verbose: {
type: "boolean",
description: "Enable verbose output",
},
}),
async run({ args }) {
const isCI = process.env.CI === "true";
const isNonInteractive = !process.stdout.isTTY;
const dryRun = !!args.dryRun;
const verbose = !!args.verbose;
const mainFile = args.mainFile;
const customVersion = args.customVersion;
// Read current versions
let bleumpVersion = "unknown";
let projectVersion = "unknown";
try {
const bleumpPkg = await import("../package.json", {
assert: { type: "json" },
});
bleumpVersion = bleumpPkg.default.version || "unknown";
projectVersion = await getCurrentVersion(mainFile);
} catch (e) {
relinka("warn", `Could not read package versions: ${e}`);
}
await showStartPrompt(args.dev, bleumpVersion);
// Get files to bump - handle multiple parsing scenarios
let filesToBumpArr: string[] = [];
// Handle files from --files flag with improved parsing
if (args.files) {
// handle both comma and space separation, plus remaining CLI args
const filesFromFlag = args.files
.split(/[,\s]+/) // split on comma or whitespace
.map((f) => f.trim())
.filter(Boolean);
// also check if there are additional file arguments after known flags
const remainingArgs = process.argv.slice(2);
const knownFlags = [
"--dev",
"--bumpType",
"--customVersion",
"--disableBump",
"--files",
"--dryRun",
"--mainFile",
"--verbose",
];
// find files that appear after --files but aren't flags
const filesIndex = remainingArgs.findIndex((arg) => arg === "--files");
if (filesIndex !== -1) {
for (let i = filesIndex + 2; i < remainingArgs.length; i++) {
const arg = remainingArgs[i];
if (arg.startsWith("--") || knownFlags.includes(arg)) break;
if (!filesFromFlag.includes(arg)) {
filesFromFlag.push(arg);
}
}
}
filesToBumpArr = filesFromFlag;
}
// If no files specified, use defaults
if (filesToBumpArr.length === 0) {
filesToBumpArr = await getFilesFromConfigOrDefault();
}
// Ensure mainFile is in the list (using absolute path)
if (!filesToBumpArr.includes(mainFile)) {
filesToBumpArr.unshift(mainFile);
}
// Remove duplicates while preserving order
filesToBumpArr = [...new Set(filesToBumpArr)];
// Get bump type and other settings from config
const dlerConfig = await getConfigFromDler();
let effectiveBumpMode = args.bumpType as BumpMode;
// Apply config settings if not overridden by CLI args
if (!effectiveBumpMode && dlerConfig.bumpMode) {
effectiveBumpMode = dlerConfig.bumpMode;
}
if (!effectiveBumpMode) {
effectiveBumpMode = getDefaultBumpMode(isCI, isNonInteractive);
}
// Override disableBump from config if not set via CLI
if (!args.disableBump && dlerConfig.bumpDisable) {
args.disableBump = true;
}
const sessionConfig: SessionConfig = {
isCI,
isNonInteractive,
mainFile,
filesToBump: filesToBumpArr,
options: { dryRun, verbose, customVersion },
bumpType: effectiveBumpMode,
};
if (verbose) {
relinka("info", "Configuration:");
relinka("log", ` Bump Type: ${effectiveBumpMode}`);
relinka("log", ` Custom Version: ${customVersion || "none"}`);
relinka("log", ` Dry Run: ${dryRun}`);
relinka("log", ` Main File: ${mainFile}`);
relinka("log", ` Files to Bump (${filesToBumpArr.length}):`);
for (const file of filesToBumpArr) {
relinka("log", ` ${file}`);
}
relinka("log", ` Current Version: ${projectVersion}`);
}
if (args.disableBump) {
relinka(
"log",
"Bump disabled (--disableBump flag set or configured in dler.ts)",
);
process.exit(0);
}
try {
if (isCI || isNonInteractive) {
await handleNonInteractiveSession(sessionConfig);
} else {
await handleInteractiveSession(sessionConfig, projectVersion);
// Get bump type from user if not provided
if (!args.bumpType) {
effectiveBumpMode = (await selectPrompt({
title: `Select a bump type (current: ${projectVersion} from ${path.relative(process.cwd(), mainFile)})`,
options: [
{
value: "patch",
label: `patch (${projectVersion} → ${semver.inc(projectVersion, "patch")})`,
},
{
value: "minor",
label: `minor (${projectVersion} → ${semver.inc(projectVersion, "minor")})`,
},
{
value: "major",
label: `major (${projectVersion} → ${semver.inc(projectVersion, "major")})`,
},
{
value: "auto",
label: "auto (automatically determine bump type)",
},
{
value: "manual",
label: "manual (enter your own version)",
},
],
})) as BumpMode;
// If manual selected, prompt for the version
if (effectiveBumpMode === "manual") {
const newCustomVersion = await inputPrompt({
title: "Enter the version number",
content: "Must be a valid semver (e.g., 1.2.3)",
defaultValue: projectVersion,
validate: (input: string) => {
if (!semver.valid(input)) {
return "Please enter a valid semver version (e.g., 1.2.3)";
}
return true;
},
});
sessionConfig.options.customVersion = newCustomVersion;
}
}
sessionConfig.bumpType = effectiveBumpMode;
validateBumpConfig(
effectiveBumpMode,
sessionConfig.options.customVersion,
);
await bumpVersionWithAnalysis(
effectiveBumpMode,
filesToBumpArr,
sessionConfig.options,
dlerConfig.bumpSet,
);
}
} catch (error) {
relinka("error", error instanceof Error ? error.message : String(error));
process.exit(1);
}
relinka("log", " ");
await showEndPrompt();
},
});
await runMain(main);
async function showStartPrompt(isDev: boolean, currentVersion: string) {
await startPrompt({
titleColor: "inverse",
clearConsole: false,
packageName: "bleump",
packageVersion: currentVersion,
isDev,
});
}
async function showEndPrompt() {
await endPrompt({
title:
"❤️ Please support bleump: https://github.com/sponsors/blefnk\n│ 📝 Feedback: https://github.com/blefnk/bleump/issues",
titleColor: "dim",
});
}
Got ideas? Found a bug? We'd love your help! Check out our issues or submit a PR.
FAQs
Bump utils for Reliverse ecosystem
We found that @reliverse/bump 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
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.

Security News
The Axios compromise shows how time-dependent dependency resolution makes exposure harder to detect and contain.