# @helpers4/version

> Tree-shakable TypeScript utility functions for the `version` domain.
> Package: `@helpers4/version` — Version: 2.0.0
> License: LGPL-3.0-or-later

## Installation

```sh
npm install @helpers4/version
# or
pnpm add @helpers4/version
```

## Usage

```typescript
import { compare, increment, isPrerelease, ... } from '@helpers4/version';
```

## Functions

| Function | Description |
|---|---|
| `compare` | Compares two semantic version strings according to SemVer 2.0.0 specification  Supports: - Core vers |
| `increment` | Increments a semantic version |
| `isPrerelease` | Returns `true` when the version string has a prerelease suffix (i.e. contains a `-` after the core ` |
| `parse` | Parses a semantic version string into its components according to SemVer 2.0.0 specification  Suppor |
| `satisfiesRange` | Checks if a version satisfies a range (simple implementation) |
| `stringify` | Reconstruct a semantic version string from a ParsedVersion object.  This is the inverse of parse: `s |
| `stripV` | Strip the leading "v" from a version string if it exists. |

---

## API Reference

### `compare`

Compares two semantic version strings according to SemVer 2.0.0 specification

Supports:
- Core version: MAJOR.MINOR.PATCH
- Pre-release: -alpha, -beta.1, -rc.1, etc.
- Build metadata: +build, +sha.abc123 (ignored in comparison per spec)
- Optional 'v' prefix

```typescript
import { compare } from '@helpers4/version';

compare(version1: string, version2: string): number
```

**Parameters:**

- `version1: string` — First version string
- `version2: string` — Second version string

**Returns:** `number` — -1 if version1 < version2, 0 if equal, 1 if version1 > version2

**Examples:**

*Compare two semver versions*

Returns -1, 0, or 1 based on SemVer ordering.

```typescript
compare('1.0.0', '2.0.0') // => -1
compare('1.0.0', '1.0.0') // => 0
compare('2.0.0', '1.0.0') // => 1
```

*Prerelease is lower than release*

A prerelease version is always less than the release.

```typescript
compare('1.0.0-alpha', '1.0.0')
// => -1
```

---

### `increment`

Increments a semantic version

```typescript
import { increment } from '@helpers4/version';

increment(version: string, type: "major" | "minor" | "patch"): string
```

**Parameters:**

- `version: string` — The version to increment
- `type: "major" | "minor" | "patch"` — The increment type ('major', 'minor', 'patch')

**Returns:** `string` — Incremented version string

```typescript
import { increment } from '@helpers4/version';

increment(version: undefined, type: "major" | "minor" | "patch"): undefined
```

**Parameters:**

- `version: undefined` — The version to increment
- `type: "major" | "minor" | "patch"` — The increment type ('major', 'minor', 'patch')

**Returns:** `undefined` — Incremented version string

```typescript
import { increment } from '@helpers4/version';

increment(version: null, type: "major" | "minor" | "patch"): null
```

**Parameters:**

- `version: null` — The version to increment
- `type: "major" | "minor" | "patch"` — The increment type ('major', 'minor', 'patch')

**Returns:** `null` — Incremented version string

**Examples:**

*Increment the patch version*

Bumps the patch number while keeping major and minor.

```typescript
increment('1.2.3', 'patch')
// => '1.2.4'
```

*Increment the minor version*

Bumps the minor number and resets patch to 0.

```typescript
increment('1.2.3', 'minor')
// => '1.3.0'
```

*Preserve the v prefix*

The v prefix is preserved if present in the input.

```typescript
increment('v1.0.0', 'major')
// => 'v2.0.0'
```

---

### `isPrerelease`

Returns `true` when the version string has a prerelease suffix
(i.e. contains a `-` after the core `MAJOR.MINOR.PATCH`).

```typescript
import { isPrerelease } from '@helpers4/version';

isPrerelease(version: string): boolean
```

**Parameters:**

- `version: string` — A semantic version string (e.g. `'2.0.0-alpha.1'`, `'1.0.0'`).

**Returns:** `boolean` — `true` if the version is a prerelease, `false` otherwise.

```typescript
import { isPrerelease } from '@helpers4/version';

isPrerelease(version: ParsedVersion): boolean
```

**Parameters:**

- `version: ParsedVersion` — A ParsedVersion object (as returned by parse).

**Returns:** `boolean` — `true` if `version.prerelease` is non-empty, `false` otherwise.

```typescript
import { isPrerelease } from '@helpers4/version';

isPrerelease(version: undefined): undefined
```

**Parameters:**

- `version: undefined` — A semantic version string (e.g. `'2.0.0-alpha.1'`, `'1.0.0'`).

**Returns:** `undefined` — `true` if the version is a prerelease, `false` otherwise.

```typescript
import { isPrerelease } from '@helpers4/version';

isPrerelease(version: null): null
```

**Parameters:**

- `version: null` — A semantic version string (e.g. `'2.0.0-alpha.1'`, `'1.0.0'`).

**Returns:** `null` — `true` if the version is a prerelease, `false` otherwise.

**Examples:**

*Detect a prerelease version*

Returns true for any version string that contains a prerelease suffix.

```typescript
isPrerelease('2.0.0-alpha.1') // true
isPrerelease('1.0.0-rc.0')   // true
```

*Stable versions return false*

Returns false when the version has no prerelease suffix.

```typescript
isPrerelease('1.0.0') // false
isPrerelease('2.1.3') // false
```

*Accept a ParsedVersion object*

Works with the result of parse() — checks the prerelease array instead of string matching.

```typescript
isPrerelease(parse('2.0.0-alpha.1')) // true
isPrerelease(parse('1.0.0'))         // false
```

---

### `parse`

Parses a semantic version string into its components according to SemVer 2.0.0 specification

Supports:
- Core version: MAJOR.MINOR.PATCH
- Pre-release: -alpha, -beta.1, -rc.1, -0.3.7, -x.7.z.92
- Build metadata: +build, +sha.abc123, +20130313144700
- Optional 'v' prefix (commonly used in git tags)

```typescript
import { parse } from '@helpers4/version';

parse(version: string): ParsedVersion
```

**Parameters:**

- `version: string` — Version string to parse

**Returns:** `ParsedVersion` — Parsed version object with major, minor, patch, prerelease, and build

```typescript
import { parse } from '@helpers4/version';

parse(version: undefined): undefined
```

**Parameters:**

- `version: undefined` — Version string to parse

**Returns:** `undefined` — Parsed version object with major, minor, patch, prerelease, and build

```typescript
import { parse } from '@helpers4/version';

parse(version: null): null
```

**Parameters:**

- `version: null` — Version string to parse

**Returns:** `null` — Parsed version object with major, minor, patch, prerelease, and build

**Examples:**

*Parse a semver string*

Breaks a semantic version string into its components.

```typescript
parse('1.2.3')
// => { major: 1, minor: 2, patch: 3, prerelease: [], build: [] }
```

*Parse a prerelease version*

Handles prerelease identifiers and optional v prefix.

```typescript
parse('v2.0.0-alpha.1')
// => { major: 2, minor: 0, patch: 0, prerelease: ['alpha', '1'], build: [] }
```

---

### `satisfiesRange`

Checks if a version satisfies a range (simple implementation)

```typescript
import { satisfiesRange } from '@helpers4/version';

satisfiesRange(version: string, range: string): boolean
```

**Parameters:**

- `version: string` — Version to check
- `range: string` — Range pattern (e.g., ">=1.0.0", "~1.2.0", "^1.0.0")

**Returns:** `boolean` — True if version satisfies the range

**Examples:**

*Check caret range*

Caret (^) allows patch and minor updates within the same major.

```typescript
satisfiesRange('1.2.3', '^1.0.0')
// => true
```

*Check greater-than-or-equal range*

The >= operator checks if the version is at least the specified value.

```typescript
satisfiesRange('2.0.0', '>=1.5.0')
// => true
```

*Out of range*

Returns false when the version does not satisfy the range.

```typescript
satisfiesRange('0.9.0', '>=1.0.0')
// => false
```

---

### `stringify`

Reconstruct a semantic version string from a ParsedVersion object.

This is the inverse of parse:
`stringify(parse(v)) === stripV(v)` for any valid SemVer string `v`.

```typescript
import { stringify } from '@helpers4/version';

stringify(parsed: ParsedVersion): string
```

**Parameters:**

- `parsed: ParsedVersion` — A parsed semantic version object.

**Returns:** `string` — The reconstructed version string (without leading `v`).

```typescript
import { stringify } from '@helpers4/version';

stringify(parsed: undefined): undefined
```

**Parameters:**

- `parsed: undefined` — A parsed semantic version object.

**Returns:** `undefined` — The reconstructed version string (without leading `v`).

```typescript
import { stringify } from '@helpers4/version';

stringify(parsed: null): null
```

**Parameters:**

- `parsed: null` — A parsed semantic version object.

**Returns:** `null` — The reconstructed version string (without leading `v`).

**Examples:**

*Reconstruct a stable version*

Converts a ParsedVersion object back to a version string.

```typescript
stringify({ major: 1, minor: 2, patch: 3, prerelease: [], build: [] })
// => '1.2.3'
```

*Round-trip with parse*

stringify(parse(v)) returns the original version string (without leading v).

```typescript
stringify(parse('2.0.0-alpha.1'))
// => '2.0.0-alpha.1'

stringify(parse('1.0.0-beta+exp.sha.5114f85'))
// => '1.0.0-beta+exp.sha.5114f85'
```

---

### `stripV`

Strip the leading "v" from a version string if it exists.

```typescript
import { stripV } from '@helpers4/version';

stripV(version: string): string
```

**Parameters:**

- `version: string` — The version string to process

**Returns:** `string` — The version string without leading "v", or the original value if it's not a string or doesn't start with "v"

```typescript
import { stripV } from '@helpers4/version';

stripV(version: null): null
```

**Parameters:**

- `version: null` — The version string to process

**Returns:** `null` — The version string without leading "v", or the original value if it's not a string or doesn't start with "v"

```typescript
import { stripV } from '@helpers4/version';

stripV(version: undefined): undefined
```

**Parameters:**

- `version: undefined` — The version string to process

**Returns:** `undefined` — The version string without leading "v", or the original value if it's not a string or doesn't start with "v"

**Examples:**

*Remove v prefix from a version string*

Strips the leading "v" from a git tag-style version string.

```typescript
stripV('v1.2.3')
// => '1.2.3'
```

*No-op when there is no v prefix*

Returns the string unchanged when it does not start with "v".

```typescript
stripV('1.2.3')
// => '1.2.3'
```

---
