@alessiofrittoli/url-utils
Version:
TypeScript URL utility library
748 lines (472 loc) • 16 kB
Markdown
# URL utils 🔗
[![NPM Latest Version][version-badge]][npm-url] [![Coverage Status][coverage-badge]][coverage-url] [![Socket Status][socket-badge]][socket-url] [![NPM Monthly Downloads][downloads-badge]][npm-url] [![Dependencies][deps-badge]][deps-url]
[![GitHub Sponsor][sponsor-badge]][sponsor-url]
[version-badge]: https://img.shields.io/npm/v/%40alessiofrittoli%2Furl-utils
[npm-url]: https://npmjs.org/package/%40alessiofrittoli%2Furl-utils
[coverage-badge]: https://coveralls.io/repos/github/alessiofrittoli/url-utils/badge.svg
[coverage-url]: https://coveralls.io/github/alessiofrittoli/url-utils
[socket-badge]: https://socket.dev/api/badge/npm/package/@alessiofrittoli/url-utils
[socket-url]: https://socket.dev/npm/package/@alessiofrittoli/url-utils/overview
[downloads-badge]: https://img.shields.io/npm/dm/%40alessiofrittoli%2Furl-utils.svg
[deps-badge]: https://img.shields.io/librariesio/release/npm/%40alessiofrittoli%2Furl-utils
[deps-url]: https://libraries.io/npm/%40alessiofrittoli%2Furl-utils
[sponsor-badge]: https://img.shields.io/static/v1?label=Fund%20this%20package&message=%E2%9D%A4&logo=GitHub&color=%23DB61A2
[sponsor-url]: https://github.com/sponsors/alessiofrittoli
## TypeScript URL utility library
### Table of Contents
- [Getting started](#getting-started)
- [What's Changed](#whats-changed)
- [API Reference](#api-reference)
- [Url utility Class](#url-utility-class)
- [Check functions](#check-functions)
- [Various functions](#various-functions)
- [Parse functions](#parse-functions)
- [Slash functions](#slash-functions)
- [Development](#development)
- [Install depenendencies](#install-depenendencies)
- [Build the source code](#build-the-source-code)
- [ESLint](#eslint)
- [Jest](#jest)
- [Contributing](#contributing)
- [Security](#security)
- [Credits](#made-with-)
### Getting started
Run the following command to start using `url-utils` in your projects:
```bash
npm i @alessiofrittoli/url-utils
```
or using `pnpm`
```bash
pnpm i @alessiofrittoli/url-utils
```
### What's Changed
#### Updates in the latest release 🎉
- Add [`getCurrentLocationURL`](#getcurrentlocationurl) utility function.
### API Reference
#### Url utility Class
The `Url` utility class provides methods for parsing and formatting URLs. It supports multiple input types, ensuring flexibility in handling URL manipulation.
##### Type Definitions
###### `UrlInput`
The Url parse/format accepted input.
| Type | Description |
|-------------|------------------------------------------------------------------------|
| `string` | A URL string. |
| `URL` | An instance of the `URL` class. |
| `Location` | An instance of the `Location` class. |
| `UrlObject` | An object containing URL properties, similar to `node:url` structures. |
##### Methods
###### `Url.parse()`
Parses a given URL input into a `URL` instance. If the `host` is not provided, it defaults to `unresolved`.
<details>
<summary>Parameters</summary>
| Parameter | Type | Default | Description |
|-----------|------------|---------|-------------|
| `url` | `UrlInput` | - | The URL string, `URL` instance, `Location` instance or UrlObject to parse. |
| `params` | `boolean` | `true` | Whether to keep search parameters or not. |
</details>
<details>
<summary>Returns</summary>
Type: `URL`
A new instance of `URL`.
</details>
###### `Url.format()`
Formats a given URL input into a URL string. If the `hostname` is `unresolved`, it returns a relative URL string.
<details>
<summary>Parameters</summary>
| Parameter | Type | Default | Description |
|-----------|------------|---------|-------------|
| `url` | `UrlInput` | - | The URL string, `URL` instance, `Location` instance or UrlObject to format. |
| `params` | `boolean` | `true` | Whether to keep search parameters or not. |
</details>
<details>
<summary>Returns</summary>
Type: `string`
The formatted URL string.
</details>
#### Check functions
##### Importing functions
```ts
import { ... } from '@alessiofrittoli/url-utils/check'
```
##### `isExternalUrl`
Determines if a given URL is external compared to a provided or default location.
<details>
<summary>Parameters</summary>
| Parameter | Type | Default | Description |
|------------|-----------------|---------|-------------|
| `url` | `UrlInput` | - | A URL `string`, `URL` instance, `Location` instance or `UrlObject` representing the URL to be checked. |
| `location` | `UrlInput` | `window.location` | A URL `string`, `URL` instance, `Location` instance or `UrlObject` representing the current location. Defaults to `window.location` if available in the browser environment. |
</details>
<details>
<summary>Returns</summary>
Type: `boolean`
- `true` if the URL is external.
- `false` otherwise.
</details>
<details>
<summary>Example usage</summary>
```ts
// External URL check
const result1 = isExternalUrl( 'https://example.com', 'https://mywebsite.com' )
console.log( result1 ) // true
// Internal URL check
const result2 = isExternalUrl( '/about', 'https://mywebsite.com' )
console.log( result2 ) // false
```
</details>
##### `isAbsoluteUrl`
Checks if a given URL is absolute.
<details>
<summary>Parameters</summary>
| Parameter | Type | Description |
|------------|------------------------------|-------------|
| `url` | `UrlInput` | A URL `string`, `URL` instance, `Location` instance or `UrlObject` representing the URL to be checked. |
</details>
<details>
<summary>Returns</summary>
Type: `boolean`
- `true` if the URL is absolute.
- `false` otherwise.
</details>
<details>
<summary>Example usage</summary>
```ts
// Absolute URL check
const result1 = isAbsoluteUrl( 'https://example.com' )
console.log( result1 ) // true
// Relative URL check
const result2 = isAbsoluteUrl( '/about' )
console.log( result2 ) // false
```
</details>
#### Various functions
##### Importing functions
```ts
import { ... } from '@alessiofrittoli/url-utils/lib'
```
##### `getCurrentLocationURL`
Get current Window Location URL.
<details>
<summary style="cursor:pointer">Returns</summary>
Type: `URL | null`
The current Window Location URL, `null` if Window object is not defined.
</details>
<details>
<summary style="cursor:pointer">Usage</summary>
```ts
const currentPathname = getCurrentLocationURL()?.pathname
```
</details>
#### Parse functions
##### Importing functions
```ts
import { ... } from '@alessiofrittoli/url-utils/parse'
```
##### `slugify`
Converts a given string into a URL-friendly slug.
<details>
<summary>Parameters</summary>
| Parameter | Type | Default | Description |
|-------------|-----------|---------|-------------|
| `text` | `string` | - | A `string` to be converted into a slug. |
| `trim` | `boolean` | `true` | A `boolean` indicating whether to trim whitespace from both ends of the string. This options is pretty usefull when using `slugify` to transform user input while typing. |
| `keepSlash` | `boolean` | `false` | A `boolean` indicating whether to retain slashes (/) in the string. |
</details>
<details>
<summary>Returns</summary>
Type: `string`
A `string` representing the slugified version of the input text.
</details>
<details>
<summary>Example usage</summary>
###### Basic usage
```ts
const slug = slugify( 'Hello World! Let\'s Code.' )
console.log( slug ) // Outputs: 'hello-world-lets-code'
```
###### Transforming user input
```ts
input.addEventListener( 'input', event => {
const input = event.target
// setting `trim` to false will allow the user to type whitespace characters that will be converted to hyphen characters, improving typing experience.
input.value = slugify( input.value, false )
} )
```
</details>
##### `getDomain`
Extracts the domain name from a given URL.
<details>
<summary>Parameters</summary>
| Parameter | Type | Default | Description |
|-------------|------------|---------|-------------|
| `url` | `UrlInput` | - | A URL `string`, `URL` instance, `Location` instance or `UrlObject` representing the URL. |
| `subdomain` | `boolean` | `true` | A `boolean` indicating whether to include subdomains in the result. |
</details>
<details>
<summary>Returns</summary>
Type: `string`
A `string` representing the domain name.
</details>
<details>
<summary>Example usage</summary>
###### Basic usage
```ts
const domain = getDomain( 'https://www.sub.example.com/path' )
console.log( domain ) // 'sub.example.com'
```
###### Getting 1st level domain name
```ts
const domain = getDomain( 'https://www.sub.example.com/path', false )
console.log( domain ) // 'example.com'
```
</details>
#### Slash functions
##### Importing functions
```ts
import { ... } from '@alessiofrittoli/url-utils/slash'
```
##### `backToForwardSlashes`
Converts all backslashes (`\`) in a string to forward slashes (`/`).
<details>
<summary>Parameters</summary>
| Parameter | Type | Description |
|-----------|----------|------------------------|
| `input` | `string` | A `string` to process. |
</details>
<details>
<summary>Returns</summary>
Type: `string`
A `string` with all backslashes replaced by forward slashes.
</details>
<details>
<summary>Example usage</summary>
```ts
console.log( backToForwardSlashes( 'path\\to\\file' ) ) // Outputs: 'path/to/file'
```
</details>
##### `forwardToBackSlashes`
Converts all forward slashes (`/`) in a string to backslashes (`\`).
<details>
<summary>Parameters</summary>
| Parameter | Type | Description |
|-----------|----------|------------------------|
| `input` | `string` | A `string` to process. |
</details>
<details>
<summary>Returns</summary>
Type: `string`
A `string` with all forward slashes replaced by backslashes.
</details>
<details>
<summary>Example usage</summary>
```ts
console.log( forwardToBackSlashes( 'path/to/file' ) ) // Outputs: 'path\to\file'
```
</details>
##### `addLeadingSlash`
Adds a leading slash (`/` or `\`) to a `string` if it doesn’t already have one.
<details>
<summary>Parameters</summary>
| Parameter | Type | Default | Description |
|-----------|----------|---------|----------------------------------------|
| `input` | `string` | - | A `string` to process. |
| `slash` | `/ \| \` | `/` | The type of slash to add (`/` or `\`). |
</details>
<details>
<summary>Returns</summary>
Type: `string`
A `string` with the specified leading slash.
</details>
<details>
<summary>Example usage</summary>
```ts
console.log( addLeadingSlash( 'path/to/file' ) ) // Outputs: '/path/to/file'
console.log( addLeadingSlash( 'path\\to\\file', '\\' ) ) // Outputs: '\path\to\file'
```
</details>
##### `removeLeadingSlash`
Removes any leading slashes (`/` or `\`) from a string.
<details>
<summary>Parameters</summary>
| Parameter | Type | Description |
|-----------|----------|------------------------|
| `input` | `string` | A `string` to process. |
</details>
<details>
<summary>Returns</summary>
Type: `string`
A `string` without leading slashes.
</details>
<details>
<summary>Example usage</summary>
```ts
console.log( removeLeadingSlash( '/path/to/file' ) ) // Outputs: 'path/to/file'
console.log( removeLeadingSlash( '\\path\\to\\file' ) ) // Outputs: 'path\to\file'
```
</details>
##### `addTrailingSlash`
Adds a trailing slash (`/` or `\`) to a `string` if it doesn’t already have one.
<details>
<summary>Parameters</summary>
| Parameter | Type | Default | Description |
|-----------|----------|---------|----------------------------------------|
| `input` | `string` | - | A `string` to process. |
| `slash` | `/ \| \` | `/` | The type of slash to add (`/` or `\`). |
</details>
<details>
<summary>Returns</summary>
Type: `string`
A `string` with the specified trailing slash.
</details>
<details>
<summary>Example usage</summary>
```ts
console.log( addTrailingSlash( 'path/to/file' ) ) // Outputs: 'path/to/file/'
console.log( addTrailingSlash( 'path\\to\\file', '\\' ) ) // Outputs: 'path\to\file\'
```
</details>
##### `removeTrailingSlash`
Removes any trailing slashes (`/` or `\`) from a string.
<details>
<summary>Parameters</summary>
| Parameter | Type | Description |
|-----------|----------|------------------------|
| `input` | `string` | A `string` to process. |
</details>
<details>
<summary>Returns</summary>
Type: `string`
A `string` without trailing slashes.
</details>
<details>
<summary>Example usage</summary>
```ts
console.log( removeTrailingSlash( 'path/to/file/' ) ) // Outputs: 'path/to/file'
console.log( removeTrailingSlash( 'path\\to\\file\\' ) ) // Outputs: 'path\\to\\file'
```
</details>
### Development
#### Install depenendencies
```bash
npm install
```
or using `pnpm`
```bash
pnpm i
```
#### Build the source code
Run the following command to test and build code for distribution.
```bash
pnpm build
```
#### [ESLint](https://www.npmjs.com/package/eslint)
warnings / errors check.
```bash
pnpm lint
```
#### [Jest](https://npmjs.com/package/jest)
Run all the defined test suites by running the following:
```bash
# Run tests and watch file changes.
pnpm test:watch
# Run tests and watch file changes with jest-environment-jsdom.
pnpm test:jsdom
# Run tests in a CI environment.
pnpm test:ci
# Run tests in a CI environment with jest-environment-jsdom.
pnpm test:ci:jsdom
```
You can eventually run specific suits like so:
- See [`package.json`](./package.json) file scripts for more info.
```bash
pnpm test:jest
pnpm test:jest:jsdom
```
Run tests with coverage.
An HTTP server is then started to serve coverage files from `./coverage` folder.
⚠️ You may see a blank page the first time you run this command. Simply refresh the browser to see the updates.
```bash
test:coverage:serve
```
### Contributing
Contributions are truly welcome!
Please refer to the [Contributing Doc](./CONTRIBUTING.md) for more information on how to start contributing to this project.
Help keep this project up to date with [GitHub Sponsor][sponsor-url].
[![GitHub Sponsor][sponsor-badge]][sponsor-url]
### Security
If you believe you have found a security vulnerability, we encourage you to **_responsibly disclose this and NOT open a public issue_**. We will investigate all legitimate reports. Email `security@alessiofrittoli.it` to disclose any security vulnerabilities.
### Made with ☕
<table style='display:flex;gap:20px;'>
<tbody>
<tr>
<td>
<img alt="avatar" src='https://avatars.githubusercontent.com/u/35973186' style='width:60px;border-radius:50%;object-fit:contain;'>
</td>
<td>
<table style='display:flex;gap:2px;flex-direction:column;'>
<tbody>
<tr>
<td>
<a href='https://github.com/alessiofrittoli' target='_blank' rel='noopener'>Alessio Frittoli</a>
</td>
</tr>
<tr>
<td>
<small>
<a href='https://alessiofrittoli.it' target='_blank' rel='noopener'>https://alessiofrittoli.it</a> |
<a href='mailto:info@alessiofrittoli.it' target='_blank' rel='noopener'>info@alessiofrittoli.it</a>
</small>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>