
Research
Malicious npm Packages Impersonate Flashbots SDKs, Targeting Ethereum Wallet Credentials
Four npm packages disguised as cryptographic tools steal developer credentials and send them to attacker-controlled Telegram infrastructure.
@reliverse/bleump
Advanced tools
@reliverse/bleump is a powerful version bump tool for javascript and typescript
Need a hassle-free way to bump versions across your JS/TS project?
@reliverse/bleump
has got you covered! It's available both as a CLI tool and a library.
sponsor — discord — repo — npm — docs
# bun — pnpm — yarn — npm
bun add -D @reliverse/bleump
Just run:
bun bleump
That's it! Follow the prompts to:
import { bumpVersionWithAnalysis } from "@reliverse/bleump";
// 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 reliverse.ts
);
// Manual version with customVersion
await bumpVersionWithAnalysis(
"manual", // bumpType
["package.json"], // files to bump
{
dryRun: false,
customVersion: "1.2.3" // overrides bumpSet if provided
},
);
# Basic usage examples
bun bleump --bumpType patch --files package.json src/version.ts
bun bleump --bumpType minor --dryRun # Preview changes
bun bleump --bumpType major --mainFile package.json
bun bleump --bumpType auto --mainFile package.json --files package.json reliverse.ts
bun bleump --bumpType manual --customVersion 2.0.0 --mainFile package.json
# Advanced usage
bun bleump \
--bumpType manual \
--customVersion 1.0.1 \
--dryRun \
--mainFile package.json \
--verbose \
--files "package.json reliverse.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:
reliverse.ts
Bump Handler: Advanced version bumping with:
Bump Disable Management:
import {
bumpVersionWithAnalysis,
analyzeFiles,
getCurrentVersion,
type BumpMode,
type FileAnalysis
} from "@reliverse/bleump";
// First analyze files
const currentVersion = await getCurrentVersion("package.json");
const fileAnalysis = await analyzeFiles(
[
"package.json",
"src/version.ts",
"reliverse.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 reliverse.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
reliverse.ts
Create a reliverse.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 "@reliverse/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: "bleump",
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 reliverse.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
@reliverse/bleump is a powerful version bump tool for javascript and typescript
The npm package @reliverse/bleump receives a total of 218 weekly downloads. As such, @reliverse/bleump popularity was classified as not popular.
We found that @reliverse/bleump 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.
Research
Four npm packages disguised as cryptographic tools steal developer credentials and send them to attacker-controlled Telegram infrastructure.
Security News
Ruby maintainers from Bundler and rbenv teams are building rv to bring Python uv's speed and unified tooling approach to Ruby development.
Security News
Following last week’s supply chain attack, Nx published findings on the GitHub Actions exploit and moved npm publishing to Trusted Publishers.