default

Nagare (流れ) is a comprehensive release management library for JavaScript/TypeScript projects that automates version bumping, changelog generation, and GitHub releases using conventional commits and semantic versioning.

Examples

Initialize Nagare in your project

deno run -A jsr:@rick/nagare/cli init

Basic programmatic usage

import { ReleaseManager } from "jsr:@rick/nagare";

const config = {
  project: {
    name: "My App",
    repository: "https://github.com/user/my-app"
  },
  versionFile: {
    path: "./version.ts",
    template: "typescript"
  }
};

const releaseManager = new ReleaseManager(config);
const result = await releaseManager.release();

if (result.success) {
  console.log(`Released version ${result.version}`);
}

Architecture Overview

Nagare follows a layered architecture with clear separation of concerns:

┌─────────────────────────────────────────┐
│            CLI Interface                │  ← User entry point
├─────────────────────────────────────────┤
│          Manager Layer                  │  ← Orchestration
│  ReleaseManager  │  RollbackManager     │
├─────────────────────────────────────────┤
│        Integration Layer                │  ← External systems
│ GitOperations │ GitHubIntegration │ ... │
├─────────────────────────────────────────┤
│        Processing Layer                 │  ← Data transformation
│ TemplateProcessor │ ChangelogGen │ ...  │
├─────────────────────────────────────────┤
│       Infrastructure Layer              │  ← Foundation
│    Logger    │   Config   │   Types    │
└─────────────────────────────────────────┘

Intelligent File Handlers (v1.1.0+)

Nagare includes built-in handlers that automatically detect and update common file types:

Simple file updates with built-in handlers

updateFiles: [
  { path: "./deno.json" },     // Automatically handled
  { path: "./package.json" },  // Automatically handled
  { path: "./README.md" },     // Updates badges and version references
  { path: "./jsr.json" }       // Automatically handled
]

Conventional Commits

Nagare analyzes commit messages to determine version bumps:

  • feat: → Minor version bump (1.0.0 → 1.1.0)
  • fix: → Patch version bump (1.0.0 → 1.0.1)
  • feat!: or BREAKING CHANGE: → Major version bump (1.0.0 → 2.0.0)
  • Other types → Patch version bump

Extensible Version Files (v1.8.0+)

Add custom exports to generated version files without writing full templates:

Additional exports configuration

versionFile: {
  path: "./version.ts",
  template: "typescript",

  // Add custom exports
  additionalExports: [
    {
      name: "API_CONFIG",
      type: "const",
      value: { baseUrl: "https://api.example.com", timeout: 5000 },
      description: "API configuration",
      asConst: true
    },
    {
      name: "Utils",
      type: "class",
      content: `
  static formatVersion(): string {
    return \`v\${VERSION}\`;
  }`
    }
  ],

  // Or add raw content
  extend: {
    prepend: "// Auto-generated file\\n\\n",
    append: "\\n// End of generated content"
  }
}

Advanced Usage

Custom file handler

import { FileHandlerManager } from "jsr:@rick/nagare";

const fileHandler = new FileHandlerManager();
fileHandler.registerHandler({
  id: "custom-config",
  name: "Custom Config Handler",
  detector: (filepath) => filepath.endsWith(".custom"),
  patterns: {
    version: /version:\s*"([^"]+)"/
  }
});

Custom version template

versionFile: {
  path: "./version.ts",
  template: "custom",
  customTemplate: `
export const VERSION = "{{version}}";
export const BUILD_DATE = "{{buildDate}}";
export const FEATURES = {{metadata.features | jsonStringify}};
`
}

Custom updateFn for complex replacements

// For files with special formatting like markdown tables
updateFiles: [{
  path: "./mod.ts",
  patterns: {
    version: /(\| Version \| )([^\s]+)( \|)/,
  },
  updateFn: (content: string, data: TemplateData) => {
    // Preserve table structure while updating only the version
    return content.replace(
      /(\| Version \| )([^\s]+)( \|)/,
      `$1${data.version}$3`
    );
  },
}]

Migration from Other Tools

From semantic-release

  • Nagare uses similar conventional commit analysis
  • Configuration is TypeScript-based instead of JSON
  • Built-in file update patterns instead of plugins

From standard-version

  • Similar changelog generation following Keep a Changelog
  • More flexible file update system
  • Better TypeScript and Deno support

Classes

c
DocGenerator(config: NagareConfig)

DocGenerator - Documentation generation using deno doc

c
ErrorFactory

Factory class for creating common Nagare errors with consistent formatting

c
FileHandlerManager()

Manages built-in and custom file handlers, providing automatic detection and updating of version strings in project files.

c
GitOperations(config: NagareConfig)

Provides a comprehensive interface for git operations needed during the release process. Handles commit parsing, tag management, and repository state validation.

c
PatternBuilder

Provides factory methods for creating common, safe regex patterns for version matching in various file formats.

c
ReleaseManager(
config: NagareConfig,
deps?: ReleaseManagerDeps
)

The ReleaseManager orchestrates all aspects of the release process including:

c
TemplateProcessor(config: NagareConfig)

Template processing and file generation using Vento.

Enums

E
BumpType

Bump types for version increments

E
LogLevel

Log levels

E
TemplateFormat

Template formats supported by Nagare's built-in templates. All built-in templates now use Vento syntax for robust processing.

Interfaces

I
AdditionalExport

Define additional constants, classes, functions, or types to be included in generated version files. Supports various export types with TypeScript compatibility.

I
CommitTypeMapping

Commit type to changelog section mapping

I
ConventionalCommit

Conventional commit structure

I
FileChangePreview

Preview of changes that would be made to a file

I
FileHandler

File handler definition for intelligent file updates

I
FileUpdatePattern

Defines how additional files are updated during the release process. Can use either regex patterns for find/replace or a custom update function.

I
FileUpdateResult

Result of a file update operation

I
GitHubConfig

GitHub integration configuration

I
NagareConfig

Main configuration interface for Nagare

I
ReleaseNotes

Release notes structure

I
ReleaseResult

Detailed result information from release operations including success status, version changes, generated artifacts, and error details.

I
TemplateData

Comprehensive data object passed to Vento templates during processing. Contains version information, build metadata, release notes, and custom data. Enhanced with computed properties for easier template access.

I
VersionFile

Defines how version files are generated using either built-in templates (TypeScript, JSON, YAML) or custom Vento templates.

Type Aliases

T
T
TranslationKey =
"errors.gitNotInitialized"
| "errors.gitNotRepo"
| "errors.gitNotClean"
| "errors.gitUncommittedChanges"
| "errors.gitUserNotConfigured"
| "errors.gitNoCommits"
| "errors.gitTagExists"
| "errors.gitRemoteError"
| "errors.configNotFound"
| "errors.configInvalid"
| "errors.configMissingRequired"
| "errors.versionNotFound"
| "errors.versionInvalidFormat"
| "errors.versionFileNotFound"
| "errors.versionBumpInvalid"
| "errors.fileNotFound"
| "errors.fileUpdateFailed"
| "errors.filePatternNoMatch"
| "errors.fileHandlerNotFound"
| "errors.fileJsonInvalid"
| "errors.githubCliNotFound"
| "errors.githubAuthFailed"
| "errors.githubReleaseFailed"
| "errors.templateInvalid"
| "errors.templateProcessingFailed"
| "errors.templateSecurityViolation"
| "errors.securityInvalidGitRef"
| "errors.securityEmptyGitRef"
| "errors.securityInvalidGitRefChars"
| "errors.securityInvalidGitRefPattern"
| "errors.securityGitTagTooLong"
| "errors.securityInvalidCommitHash"
| "errors.securityInvalidFilePath"
| "errors.securityPathTraversal"
| "errors.securityPathEscape"
| "errors.securityInvalidVersion"
| "errors.securityInvalidSemverFormat"
| "errors.securityInvalidCliArgType"
| "errors.securityShellInjection"
| "errors.securityNullByteInjection"
| "errors.securityInvalidPath"
| "errors.securityPathNotAbsolute"
| "errors.securityForbiddenChars"
| "errors.dependencyNotFound"
| "errors.permissionDenied"
| "errors.operationCancelled"
| "errors.unknownError"
| "errors.invalidBumpType"
| "errors.breakingRequiresMajor"
| "errors.commandFailed"
| "errors.noCommits"
| "errors.tagExists"
| "errors.rollbackFailed"
| "errors.templateError"
| "cli.release.description"
| "cli.release.calculating"
| "cli.release.currentVersion"
| "cli.release.newVersion"
| "cli.release.updating"
| "cli.release.committing"
| "cli.release.pushing"
| "cli.release.creatingGithub"
| "cli.release.success"
| "cli.release.dryRun"
| "cli.release.noChanges"
| "cli.rollback.description"
| "cli.rollback.confirm"
| "cli.rollback.rollingBack"
| "cli.rollback.restoringFiles"
| "cli.rollback.removingTag"
| "cli.rollback.success"
| "cli.rollback.cancelled"
| "cli.init.description"
| "cli.init.creating"
| "cli.init.success"
| "cli.init.exists"
| "cli.init.initializing"
| "cli.init.createdLauncher"
| "cli.init.failedLauncher"
| "cli.init.foundConfig"
| "cli.init.creatingConfig"
| "cli.init.createdConfig"
| "cli.init.failedConfig"
| "cli.init.checkingDeno"
| "cli.init.foundTasks"
| "cli.init.addTasks"
| "cli.init.noDeno"
| "cli.init.complete"
| "cli.init.nextSteps"
| "cli.init.nextStep1"
| "cli.init.nextStep2"
| "cli.init.nextStep3"
| "cli.init.moreInfo"
| "cli.commands.patch"
| "cli.commands.minor"
| "cli.commands.major"
| "cli.commands.auto"
| "cli.options.dryRun"
| "cli.options.skipConfirmation"
| "cli.options.skipGithub"
| "cli.options.skipDocs"
| "cli.options.verbose"
| "cli.options.quiet"
| "cli.help.title"
| "cli.help.usage"
| "cli.help.usageLine1"
| "cli.help.usageLine2"
| "cli.help.usageLine3"
| "cli.help.commands"
| "cli.help.commandRelease"
| "cli.help.commandRollback"
| "cli.help.commandInit"
| "cli.help.bumpTypes"
| "cli.help.bumpMajor"
| "cli.help.bumpMinor"
| "cli.help.bumpPatch"
| "cli.help.options"
| "cli.help.optionConfig"
| "cli.help.optionDryRun"
| "cli.help.optionSkipConfirm"
| "cli.help.optionLogLevel"
| "cli.help.optionHelp"
| "cli.help.optionVersion"
| "cli.help.optionVersionDetailed"
| "cli.help.optionVersionJson"
| "cli.help.examples"
| "cli.help.exampleInit"
| "cli.help.exampleRelease"
| "cli.help.exampleReleaseMinor"
| "cli.help.exampleDryRun"
| "cli.help.exampleRollback"
| "cli.help.exampleRollbackVersion"
| "cli.help.exampleConfig"
| "cli.help.exampleVersionDetailed"
| "cli.help.exampleVersionJson"
| "cli.help.configuration"
| "cli.help.configIntro"
| "cli.help.safePatterns"
| "cli.help.safePatternsIntro"
| "cli.help.safeExample"
| "cli.help.unsafeExample"
| "cli.help.safePatternsNote"
| "cli.help.safePatternsWarning"
| "cli.help.moreInfo"
| "cli.version.description"
| "cli.version.repository"
| "cli.version.license"
| "cli.version.buildInfo"
| "cli.version.buildDate"
| "cli.version.gitCommit"
| "cli.version.environment"
| "cli.version.releaseNotes"
| "cli.version.added"
| "cli.version.changed"
| "cli.version.fixed"
| "cli.version.deprecated"
| "cli.version.removed"
| "cli.version.security"
| "cli.version.runtimeInfo"
| "cli.version.deno"
| "cli.version.v8"
| "cli.version.typescript"
| "log.release.starting"
| "log.release.noFiles"
| "log.release.fileUpdatePreview"
| "log.release.filePreview"
| "log.release.usingHandler"
| "log.release.customFunction"
| "log.release.noChanges"
| "log.release.foundMatch"
| "log.release.noMatches"
| "log.release.suggestions"
| "log.release.suggestBuiltin"
| "log.release.currentVersion"
| "log.release.noCommits"
| "log.release.commitsFound"
| "log.release.newVersion"
| "log.release.releaseNotes"
| "log.release.dryRunMode"
| "log.release.dryRunInfo"
| "log.release.updatingFiles"
| "log.release.generatingChangelog"
| "log.release.committingChanges"
| "log.release.pushingToRemote"
| "log.release.creatingGitHub"
| "log.release.gitHubSuccess"
| "log.release.generatingDocs"
| "log.release.releaseSuccess"
| "log.release.releaseUrl"
| "log.release.noFilesToUpdate"
| "log.release.processingFiles"
| "log.rollback.starting"
| "log.rollback.noReleaseTags"
| "log.rollback.availableTags"
| "log.rollback.targetNotFound"
| "log.rollback.rollingBack"
| "log.rollback.restoringFiles"
| "log.rollback.removingTag"
| "log.rollback.removingGitHub"
| "log.rollback.success"
| "log.error"
| "log.warn"
| "log.info"
| "log.debug"
| "prompts.confirm"
| "prompts.yes"
| "prompts.no"
| "prompts.proceedRelease"
| "prompts.releaseCancelled"
| "prompts.undoRollback"
| "prompts.rollbackCancelled"
| "prompts.deleteRemoteTag"
| "suggestions.checkPath"
| "suggestions.verifyPermissions"
| "suggestions.runGitInit"
| "suggestions.navigateToRepo"
| "suggestions.checkProjectDir"
| "suggestions.commitChanges"
| "suggestions.stashChanges"
| "suggestions.discardChanges"
| "suggestions.viewChanges"
| "suggestions.runNagareInit"
| "suggestions.createConfigManually"
| "suggestions.specifyConfigPath"
| "suggestions.addVersionPattern"
| "suggestions.configureCustomPattern"
| "suggestions.ensureFileReadable"
| "suggestions.addCustomUpdateFn"
| "suggestions.useBuiltInHandler"
| "suggestions.defineCustomPatterns"
| "suggestions.checkJsonSyntax"
| "suggestions.validateJson"
| "suggestions.checkJsonCommas"
| "suggestions.revertRecentChanges"
| "suggestions.installGitHubCli"
| "suggestions.installGitHubCliMac"
| "suggestions.installGitHubCliWindows"
| "suggestions.disableGitHubReleases"
| "suggestions.useValidType"
| "suggestions.checkGitHub"
| "suggestions.checkConfig"
| "suggestions.provideValidString"
| "suggestions.checkNotNull"
| "suggestions.ensureNotNumberOrObject"
| "suggestions.provideNonEmpty"
| "suggestions.checkWhitespace"
| "suggestions.useSimpleNames"
| "suggestions.useOnlyAlphanumeric"
| "suggestions.avoidSpecialChars"
| "suggestions.checkGitDocs"
| "suggestions.followGitNaming"
| "suggestions.useShorterName"
| "suggestions.provideFullHash"
| "suggestions.checkGitLog"
| "suggestions.useAbsolutePath"
| "suggestions.removeTraversal"
| "suggestions.stayWithinProject"
| "suggestions.useForwardSlashes"
| "suggestions.checkPathExists"
| "suggestions.provideSemver"
| "suggestions.checkVersionFormat"
| "suggestions.removeInvalidChars"
| "suggestions.provideValidGitRef"
| "suggestions.checkNotNullOrUndefined"
| "suggestions.ensureStringType"
| "suggestions.removeSpecialChars"
| "suggestions.useAlphanumeric"
| "suggestions.noStartWithHyphen"
| "suggestions.removeDoubleDots"
| "suggestions.noEndWithDotOrLock"
| "suggestions.removeAtBraces"
| "suggestions.useConciseNaming"
| "suggestions.useAbbreviatedVersions"
| "suggestions.checkForNullUndefined"
| "suggestions.checkInputSource"
| "suggestions.convertNumbersToStrings"
| "suggestions.ensureStringArgs"
| "suggestions.escapeSpecialChars"
| "suggestions.forbiddenChars"
| "suggestions.provideValidPath"
| "suggestions.removeNullBytes"
| "suggestions.removeShellMetachars"
| "suggestions.checkSemverDocs"
| "suggestions.checkSymbolicLinks"
| "suggestions.useGitRevParse"
| "suggestions.useParamSubstitution"
| "suggestions.useRelativePaths"
| "suggestions.useSemverFormat"
| "suggestions.validateEncoding"
| "suggestions.validSemverExamples"
| "changelog.title"
| "changelog.unreleased"
| "changelog.added"
| "changelog.changed"
| "changelog.deprecated"
| "changelog.removed"
| "changelog.fixed"
| "changelog.security"
| "changelog.breakingChanges"
| "commitTypes.feat"
| "commitTypes.fix"
| "commitTypes.docs"
| "commitTypes.style"
| "commitTypes.refactor"
| "commitTypes.perf"
| "commitTypes.test"
| "commitTypes.build"
| "commitTypes.ci"
| "commitTypes.chore"
| "commitTypes.revert"
| "fileHandlers.updating"
| "fileHandlers.skipping"
| "fileHandlers.preview"
| "fileHandlers.pattern"
| "fileHandlers.customHandler"
| "version.current"
| "version.previous"
| "version.bump"
| "git.status"
| "git.clean"
| "git.uncommitted"
| "git.tag"
| "git.commit"
| "git.push"
| "time.just_now"
| "time.seconds_ago"
| "time.minutes_ago"
| "time.hours_ago"
| "time.days_ago"

All available translation keys as string literals

Variables

v
BUILT_IN_HANDLERS: Record<string, FileHandler>

Contains pre-configured handlers for:

v
DEFAULT_CONFIG: Partial<NagareConfig>

Default configuration - UPDATED with safer patterns

v
ErrorCodes: { GIT_NOT_INITIALIZED: string; GIT_UNCOMMITTED_CHANGES: string; GIT_USER_NOT_CONFIGURED: string; GIT_NO_COMMITS: string; GIT_TAG_EXISTS: string; GIT_REMOTE_ERROR: string; CONFIG_NOT_FOUND: string; CONFIG_INVALID: string; CONFIG_MISSING_REQUIRED: string; VERSION_NOT_FOUND: string; VERSION_INVALID_FORMAT: string; VERSION_FILE_NOT_FOUND: string; VERSION_BUMP_INVALID: string; FILE_NOT_FOUND: string; FILE_UPDATE_FAILED: string; FILE_PATTERN_NO_MATCH: string; FILE_HANDLER_NOT_FOUND: string; FILE_JSON_INVALID: string; GITHUB_CLI_NOT_FOUND: string; GITHUB_AUTH_FAILED: string; GITHUB_RELEASE_FAILED: string; TEMPLATE_INVALID: string; TEMPLATE_PROCESSING_FAILED: string; TEMPLATE_SECURITY_VIOLATION: string; SECURITY_INVALID_GIT_REF: string; SECURITY_EMPTY_GIT_REF: string; SECURITY_INVALID_GIT_REF_CHARS: string; SECURITY_INVALID_GIT_REF_PATTERN: string; SECURITY_GIT_TAG_TOO_LONG: string; SECURITY_INVALID_COMMIT_HASH: string; SECURITY_INVALID_FILE_PATH: string; SECURITY_PATH_TRAVERSAL: string; SECURITY_PATH_ESCAPE: string; SECURITY_INVALID_VERSION: string; SECURITY_INVALID_SEMVER_FORMAT: string; SECURITY_INVALID_CLI_ARG_TYPE: string; SECURITY_SHELL_INJECTION: string; SECURITY_NULL_BYTE_INJECTION: string; DEPENDENCY_NOT_FOUND: string; PERMISSION_DENIED: string; OPERATION_CANCELLED: string; RELEASE_FAILED: string; UNKNOWN_ERROR: string; }

Standard error codes for common Nagare errors