# @helpers4/url

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

## Installation

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

## Usage

```typescript
import { cleanPath, extractPureURI, onlyPath, ... } from '@helpers4/url';
```

## Functions

| Function | Description |
|---|---|
| `cleanPath` | Clean an URL by removing duplicate slashes. The protocol part of the URL is not modified. |
| `extractPureURI` | Extracts the pure URI from a URL by removing query parameters and fragments. |
| `onlyPath` | Extract only the path from an URI with optional query and fragments.  For example, all these paramet |
| `parsePackageRepository` | Parse the `repository` field from `package.json` into a structured object.  Supports all npm-specifi |
| `relativeURLToAbsolute` | Converts a relative URL to an absolute URL using the current document base URI. |
| `withLeadingSlash` | Adds a leading slash `/` to the given URL if it is not already present.  This function is useful for |
| `withoutLeadingSlash` | Removes the leading slash `/` from the given URL if it is present.  This function is useful for ensu |
| `withoutTrailingSlash` | Removes the trailing slash `/` from the given URL if it is present.  This function is useful for ens |
| `withTrailingSlash` | Adds a trailing slash `/` to the given URL if it is not already present.  This function is useful fo |

---

## API Reference

### `cleanPath`

Clean an URL by removing duplicate slashes.
The protocol part of the URL is not modified.

```typescript
import { cleanPath } from '@helpers4/url';

cleanPath(url: string | null | undefined): string | null | undefined
```

**Parameters:**

- `url: string | null | undefined` — The URL string to be processed. Can be `string`, `undefined`, or `null`.

**Returns:** `string | null | undefined` — The cleaned URL string, or `undefined` if the input is `undefined`, or `null` if the input is `null`.

**Examples:**

*Remove duplicate slashes*

Cleans an URL by removing duplicate slashes while preserving the protocol.

```typescript
cleanPath('/path//to///resource')
// => '/path/to/resource'
```

*Preserve protocol*

The double slash after the protocol (http://) is not modified.

```typescript
cleanPath('http://example.com//path')
// => 'http://example.com/path'
```

*Handle null and undefined*

Returns null for null input and undefined for undefined input.

```typescript
cleanPath(null)      // => null
cleanPath(undefined) // => undefined
```

---

### `extractPureURI`

Extracts the pure URI from a URL by removing query parameters and fragments.

```typescript
import { extractPureURI } from '@helpers4/url';

extractPureURI(url: string): string
```

**Parameters:**

- `url: string` — The URL string to process

**Returns:** `string` — The URI without query parameters and fragments, or the original value if undefined/null

```typescript
import { extractPureURI } from '@helpers4/url';

extractPureURI(url: undefined): undefined
```

**Parameters:**

- `url: undefined` — The URL string to process

**Returns:** `undefined` — The URI without query parameters and fragments, or the original value if undefined/null

```typescript
import { extractPureURI } from '@helpers4/url';

extractPureURI(url: null): null
```

**Parameters:**

- `url: null` — The URL string to process

**Returns:** `null` — The URI without query parameters and fragments, or the original value if undefined/null

**Examples:**

*Remove query parameters and fragments*

Strips everything after ? or # from the URL.

```typescript
extractPureURI('https://example.com/path?query=1#section')
// => 'https://example.com/path'
```

---

### `onlyPath`

Extract only the path from an URI with optional query and fragments.

For example, all these parameters will return `/path`:
 - `/path`
 - `/path?query=thing`
 - `/path#fragment`
 - `/path?query=thing#fragment`

```typescript
import { onlyPath } from '@helpers4/url';

onlyPath(url: string): string
```

**Parameters:**

- `url: string` — The URL string to be processed. Can be `string`, `undefined`, or `null`.

**Returns:** `string` — The URL string without query and fragment, or `undefined` if the input is `undefined`, or `null` if the input is `null`.

```typescript
import { onlyPath } from '@helpers4/url';

onlyPath(url: null): null
```

**Parameters:**

- `url: null` — The URL string to be processed. Can be `string`, `undefined`, or `null`.

**Returns:** `null` — The URL string without query and fragment, or `undefined` if the input is `undefined`, or `null` if the input is `null`.

```typescript
import { onlyPath } from '@helpers4/url';

onlyPath(url: undefined): undefined
```

**Parameters:**

- `url: undefined` — The URL string to be processed. Can be `string`, `undefined`, or `null`.

**Returns:** `undefined` — The URL string without query and fragment, or `undefined` if the input is `undefined`, or `null` if the input is `null`.

**Examples:**

*Extract the path from a URL*

Strips query parameters and fragments from a URL path.

```typescript
onlyPath('/path?query=thing#fragment')
// => '/path'
```

---

### `parsePackageRepository`

Parse the `repository` field from `package.json` into a structured object.

Supports all npm-specified formats:
- **Object form**: `{ "type": "git", "url": "...", "directory": "..." }`
- **GitHub shorthand**: `"owner/repo"` or `"github:owner/repo"`
- **Platform shorthands**: `"gitlab:owner/repo"`, `"bitbucket:owner/repo"`
- **Gist shorthand**: `"gist:<id>"`
- **URL forms**: `git+https://`, `https://`, `git://`, `git@` SSH, `git+ssh://`

Returns `undefined` for `null`, `undefined`, arrays, or values that cannot
be matched to any recognised format.

```typescript
import { parsePackageRepository } from '@helpers4/url';

parsePackageRepository(repository: unknown): PackageRepository | undefined
```

**Parameters:**

- `repository: unknown` — The `repository` field value from `package.json`.

**Returns:** `PackageRepository | undefined` — A parsed PackageRepository object, or `undefined` if the
  input cannot be parsed.

**Examples:**

*Parse the npm canonical object form*

Parses the full object form written by npm publish.

```typescript
parsePackageRepository({ type: 'git', url: 'git+https://github.com/helpers4/typescript.git' })
// => { type: 'git', host: 'github', slug: 'helpers4/typescript',
//      owner: 'helpers4', repo: 'typescript', gistId: undefined, directory: undefined }
```

*Parse npm shorthand forms*

npm accepts "owner/repo", "github:owner/repo", "gitlab:owner/repo" etc. as shorthand.

```typescript
parsePackageRepository('helpers4/typescript')
// => { host: 'github', slug: 'helpers4/typescript', owner: 'helpers4', repo: 'typescript', ... }

parsePackageRepository('gitlab:myorg/myproject')
// => { host: 'gitlab', slug: 'myorg/myproject', owner: 'myorg', repo: 'myproject', ... }

parsePackageRepository('gist:11081aaa281')
// => { host: 'gist', gistId: '11081aaa281', slug: undefined, owner: undefined, ... }
```

---

### `relativeURLToAbsolute`

Converts a relative URL to an absolute URL using the current document base URI.

```typescript
import { relativeURLToAbsolute } from '@helpers4/url';

relativeURLToAbsolute(relativeUrl: string): string
```

**Parameters:**

- `relativeUrl: string` — The relative URL to convert

**Returns:** `string` — The absolute URL

**Examples:**

*Convert a relative URL to absolute*

Prepends the base URI to a relative path, cleaning duplicate slashes.

```typescript
relativeURLToAbsolute('/api/data')
// => 'http://localhost/api/data' (depends on document.baseURI)
```

---

### `withLeadingSlash`

Adds a leading slash `/` to the given URL if it is not already present.

This function is useful for ensuring that URLs are properly formatted
with a leading slash, which is often required in web development for
consistency and to avoid issues with relative paths.

```typescript
import { withLeadingSlash } from '@helpers4/url';

withLeadingSlash(url: string): string
```

**Parameters:**

- `url: string` — The URL string to be processed. Can be `string`, `undefined`, or `null`.

**Returns:** `string` — The URL string with a leading slash, or `undefined` if the input is `undefined`, or `null` if the input is `null`.

```typescript
import { withLeadingSlash } from '@helpers4/url';

withLeadingSlash(url: undefined): undefined
```

**Parameters:**

- `url: undefined` — The URL string to be processed. Can be `string`, `undefined`, or `null`.

**Returns:** `undefined` — The URL string with a leading slash, or `undefined` if the input is `undefined`, or `null` if the input is `null`.

```typescript
import { withLeadingSlash } from '@helpers4/url';

withLeadingSlash(url: null): null
```

**Parameters:**

- `url: null` — The URL string to be processed. Can be `string`, `undefined`, or `null`.

**Returns:** `null` — The URL string with a leading slash, or `undefined` if the input is `undefined`, or `null` if the input is `null`.

**Examples:**

*Add a leading slash*

Ensures the URL starts with a forward slash.

```typescript
withLeadingSlash('path/to/resource')
// => '/path/to/resource'
```

*Already has leading slash*

Does not add a duplicate slash.

```typescript
withLeadingSlash('/already/has/slash')
// => '/already/has/slash'
```

---

### `withoutLeadingSlash`

Removes the leading slash `/` from the given URL if it is present.

This function is useful for ensuring that URLs are properly formatted
without a leading slash, which is often required in web development for
consistency and to avoid issues with relative paths.

```typescript
import { withoutLeadingSlash } from '@helpers4/url';

withoutLeadingSlash(url: string): string
```

**Parameters:**

- `url: string` — The URL string to be processed. Can be `string`, `undefined`, or `null`.

**Returns:** `string` — The URL string without a leading slash, or `undefined` if the input is `undefined`, or `null` if the input is `null`.

```typescript
import { withoutLeadingSlash } from '@helpers4/url';

withoutLeadingSlash(url: undefined): undefined
```

**Parameters:**

- `url: undefined` — The URL string to be processed. Can be `string`, `undefined`, or `null`.

**Returns:** `undefined` — The URL string without a leading slash, or `undefined` if the input is `undefined`, or `null` if the input is `null`.

```typescript
import { withoutLeadingSlash } from '@helpers4/url';

withoutLeadingSlash(url: null): null
```

**Parameters:**

- `url: null` — The URL string to be processed. Can be `string`, `undefined`, or `null`.

**Returns:** `null` — The URL string without a leading slash, or `undefined` if the input is `undefined`, or `null` if the input is `null`.

**Examples:**

*Remove leading slash*

Strips the leading slash from a URL path.

```typescript
withoutLeadingSlash('/path/to/resource')
// => 'path/to/resource'
```

---

### `withoutTrailingSlash`

Removes the trailing slash `/` from the given URL if it is present.

This function is useful for ensuring that URLs are properly formatted
without a trailing slash, which is often required in web development for
consistency and to avoid issues with relative paths.

```typescript
import { withoutTrailingSlash } from '@helpers4/url';

withoutTrailingSlash(url: string): string
```

**Parameters:**

- `url: string` — The URL string to be processed. Can be `string`, `undefined`, or `null`.

**Returns:** `string` — The URL string without a trailing slash, or `undefined` if the input is `undefined`, or `null` if the input is `null`.

```typescript
import { withoutTrailingSlash } from '@helpers4/url';

withoutTrailingSlash(url: undefined): undefined
```

**Parameters:**

- `url: undefined` — The URL string to be processed. Can be `string`, `undefined`, or `null`.

**Returns:** `undefined` — The URL string without a trailing slash, or `undefined` if the input is `undefined`, or `null` if the input is `null`.

```typescript
import { withoutTrailingSlash } from '@helpers4/url';

withoutTrailingSlash(url: null): null
```

**Parameters:**

- `url: null` — The URL string to be processed. Can be `string`, `undefined`, or `null`.

**Returns:** `null` — The URL string without a trailing slash, or `undefined` if the input is `undefined`, or `null` if the input is `null`.

**Examples:**

*Remove trailing slash*

Strips the trailing slash from a URL path.

```typescript
withoutTrailingSlash('path/to/resource/')
// => 'path/to/resource'
```

---

### `withTrailingSlash`

Adds a trailing slash `/` to the given URL if it is not already present.

This function is useful for ensuring that URLs are properly formatted
with a trailing slash, which is often required in web development for
consistency and to avoid issues with relative paths.

```typescript
import { withTrailingSlash } from '@helpers4/url';

withTrailingSlash(url: string): string
```

**Parameters:**

- `url: string` — The URL string to be processed. Can be `string`, `undefined`, or `null`.

**Returns:** `string` — The URL string with a trailing slash, or `undefined` if the input is `undefined`, or `null` if the input is `null`.

```typescript
import { withTrailingSlash } from '@helpers4/url';

withTrailingSlash(url: undefined): undefined
```

**Parameters:**

- `url: undefined` — The URL string to be processed. Can be `string`, `undefined`, or `null`.

**Returns:** `undefined` — The URL string with a trailing slash, or `undefined` if the input is `undefined`, or `null` if the input is `null`.

```typescript
import { withTrailingSlash } from '@helpers4/url';

withTrailingSlash(url: null): null
```

**Parameters:**

- `url: null` — The URL string to be processed. Can be `string`, `undefined`, or `null`.

**Returns:** `null` — The URL string with a trailing slash, or `undefined` if the input is `undefined`, or `null` if the input is `null`.

**Examples:**

*Add a trailing slash*

Ensures the URL ends with a forward slash.

```typescript
withTrailingSlash('path/to/resource')
// => 'path/to/resource/'
```

---
