Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(url): 6 new URL helpers in new section #328

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions benchmarks/url/cleanPath.bench.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { cleanPath } from 'radashi'

describe('cleanPath', () => {
bench('with no input', () => {
cleanPath(undefined)
})
bench('with empty string', () => {
cleanPath('')
})
bench('with correct path', () => {
cleanPath('/some/path')
})
bench('with multiple slashes in path', () => {
cleanPath('/some//path')
})
bench('with protocol, path, query, and fragment', () => {
cleanPath('https://server//some//path?query=thing#fragment')
})
})
22 changes: 22 additions & 0 deletions benchmarks/url/onlyPath.bench.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { onlyPath } from 'radashi'

describe('onlyPath', () => {
bench('with no input', () => {
onlyPath(undefined)
})
bench('with empty string', () => {
onlyPath('')
})
bench('with path only', () => {
onlyPath('/some/path')
})
bench('with path and query', () => {
onlyPath('/some/path?query=thing')
})
bench('with path and fragment', () => {
onlyPath('/some/path#fragment')
})
bench('with path, query, and fragment', () => {
onlyPath('/some/path?query=thing#fragment')
})
})
16 changes: 16 additions & 0 deletions benchmarks/url/withLeadingSlash.bench.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { withLeadingSlash } from 'radashi'

describe('withLeadingSlash', () => {
bench('with no input', () => {
withLeadingSlash(undefined)
})
bench('with empty string', () => {
withLeadingSlash('')
})
bench('with missing leading slash', () => {
withLeadingSlash('some/path')
})
bench('with leading slash', () => {
withLeadingSlash('/some/path')
})
})
16 changes: 16 additions & 0 deletions benchmarks/url/withTrailingSlash.bench.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { withTrailingSlash } from 'radashi'

describe('withTrailingSlash', () => {
bench('with no input', () => {
withTrailingSlash(undefined)
})
bench('with empty string', () => {
withTrailingSlash('')
})
bench('with missing trailing slash', () => {
withTrailingSlash('some/path')
})
bench('with trailing slash', () => {
withTrailingSlash('some/path/')
})
})
16 changes: 16 additions & 0 deletions benchmarks/url/withoutLeadingSlash.bench.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { withoutLeadingSlash } from 'radashi'

describe('withoutLeadingSlash', () => {
bench('with no input', () => {
withoutLeadingSlash(undefined)
})
bench('with empty string', () => {
withoutLeadingSlash('')
})
bench('with leading slash', () => {
withoutLeadingSlash('/some/path')
})
bench('without leading slash', () => {
withoutLeadingSlash('some/path')
})
})
16 changes: 16 additions & 0 deletions benchmarks/url/withoutTrailingSlash.bench.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { withoutTrailingSlash } from 'radashi'

describe('withoutTrailingSlash', () => {
bench('with no input', () => {
withoutTrailingSlash(undefined)
})
bench('with empty string', () => {
withoutTrailingSlash('')
})
bench('with trailing slash', () => {
withoutTrailingSlash('some/path/')
})
bench('without trailing slash', () => {
withoutTrailingSlash('some/path')
})
})
18 changes: 18 additions & 0 deletions docs/url/cleanPath.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
title: cleanPath
description: Clean a path
---

### Usage

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

```ts
import { cleanPath } from 'radashi'

cleanPath('/path//to///resource') // => '/path/to/resource'
cleanPath('http://example.com//path//to///resource') // => 'http://example.com/path/to/resource'
cleanPath(undefined) // => undefined
cleanPath(null) // => null
```
26 changes: 26 additions & 0 deletions docs/url/onlyPath.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
---
title: onlyPath
description: Extract only the path
---

### Usage

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`

```ts
import { onlyPath } from 'radashi'

onlyPath('/path') // => '/path'
onlyPath('/path?query=thing') // => '/path'
onlyPath('/path#fragment') // => '/path'
onlyPath('/path?query=thing#fragment') // => '/path'
onlyPath(undefined) // => undefined
onlyPath(null) // => null
```
22 changes: 22 additions & 0 deletions docs/url/withLeadingSlash.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
---
title: withLeadingSlash
description: Adds a leading slash
---

### Usage

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.

```ts
import { withLeadingSlash } from 'radashi'

withLeadingSlash('') // => '/'
withLeadingSlash('no/slash') // => '/no/slash'
withLeadingSlash('/already/has/slash') // => '/already/has/slash'
withLeadingSlash(undefined) // => undefined
withLeadingSlash(null) // => null
```
22 changes: 22 additions & 0 deletions docs/url/withTrailingSlash.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
---
title: withTrailingSlash
description: Adds a trailing slash
---

### Usage

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.

```ts
import { withTrailingSlash } from 'radashi'

withTrailingSlash('') // => '/'
withTrailingSlash('no/slash') // => 'no/slash/'
withTrailingSlash('already/has/slash/') // => 'already/has/slash/'
withTrailingSlash(undefined) // => undefined
withTrailingSlash(null) // => null
```
22 changes: 22 additions & 0 deletions docs/url/withoutLeadingSlash.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
---
title: withoutLeadingSlash
description: Removes the leading slash
---

### Usage

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.

```ts
import { withoutLeadingSlash } from 'radashi'

withoutLeadingSlash('') // => ''
withoutLeadingSlash('/no/slash') // => 'no/slash'
withoutLeadingSlash('already/has/slash') // => 'already/has/slash'
withoutLeadingSlash(undefined) // => undefined
withoutLeadingSlash(null) // => null
```
22 changes: 22 additions & 0 deletions docs/url/withoutTrailingSlash.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
---
title: withoutTrailingSlash
description: Removes the trailing slash
---

### Usage

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.

```ts
import { withoutTrailingSlash } from 'radashi'

withoutTrailingSlash('') // => ''
withoutTrailingSlash('no/slash/') // => 'no/slash'
withoutTrailingSlash('already/has/slash') // => 'already/has/slash'
withoutTrailingSlash(undefined) // => undefined
withoutTrailingSlash(null) // => null
```
7 changes: 7 additions & 0 deletions src/mod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,4 +142,11 @@ export * from './typed/isUndefined.ts'
export * from './typed/isWeakMap.ts'
export * from './typed/isWeakSet.ts'

export * from './url/cleanPath.ts'
export * from './url/onlyPath.ts'
export * from './url/withLeadingSlash.ts'
export * from './url/withoutLeadingSlash.ts'
export * from './url/withoutTrailingSlash.ts'
export * from './url/withTrailingSlash.ts'

export * from './types.ts'
23 changes: 23 additions & 0 deletions src/url/cleanPath.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/**
* Clean an URL by removing duplicate slashes.
* The protocol part of the URL is not modified.
*
* @param url - The URL string to be processed. Can be `string`, `undefined`, or `null`.
* @returns The cleaned URL string, or `undefined` if the input is `undefined`, or `null` if the input is `null`.
*
* @example
* ```ts
* cleanPath('/path//to///resource') // => '/path/to/resource'
* cleanPath('http://example.com//path//to///resource') // => 'http://example.com/path/to/resource'
* cleanPath(undefined) // => undefined
* cleanPath(null) // => null
* ```
*/
export function cleanPath(
url: string | undefined | null,
): string | undefined | null {
if (url === undefined || url === null) {
return url
}
return url.replace(/([^:]\/)\/+/g, '$1')
}
103 changes: 103 additions & 0 deletions src/url/onlyPath.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
/**
* 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`
*
* @param url - The URL string to be processed. Can be `string`, `undefined`, or `null`.
* @returns The URL string without query and fragment, or `undefined` if the input is `undefined`, or `null` if the input is `null`.
*
* @example
* ```ts
* onlyPath('/path') // => '/path'
* onlyPath('/path?query=thing') // => '/path'
* onlyPath('/path#fragment') // => '/path'
* onlyPath('/path?query=thing#fragment') // => '/path'
* onlyPath(undefined) // => undefined
* onlyPath(null) // => null
* ```
*/
export function onlyPath(url: string): string

/**
* 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`
*
* @param url - The URL string to be processed. Can be `string`, `undefined`, or `null`.
* @returns The URL string without query and fragment, or `undefined` if the input is `undefined`, or `null` if the input is `null`.
*
* @example
* ```ts
* onlyPath('/path') // => '/path'
* onlyPath('/path?query=thing') // => '/path'
* onlyPath('/path#fragment') // => '/path'
* onlyPath('/path?query=thing#fragment') // => '/path'
* onlyPath(undefined) // => undefined
* onlyPath(null) // => null
* ```
*/
export function onlyPath(url: null): null

/**
* 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`
*
* @param url - The URL string to be processed. Can be `string`, `undefined`, or `null`.
* @returns The URL string without query and fragment, or `undefined` if the input is `undefined`, or `null` if the input is `null`.
*
* @example
* ```ts
* onlyPath('/path') // => '/path'
* onlyPath('/path?query=thing') // => '/path'
* onlyPath('/path#fragment') // => '/path'
* onlyPath('/path?query=thing#fragment') // => '/path'
* onlyPath(undefined) // => undefined
* onlyPath(null) // => null
* ```
*/
export function onlyPath(url: undefined): undefined

/**
* 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`
*
* @param url - The URL string to be processed. Can be `string`, `undefined`, or `null`.
* @returns The URL string without query and fragment, or `undefined` if the input is `undefined`, or `null` if the input is `null`.
*
* @example
* ```ts
* onlyPath('/path') // => '/path'
* onlyPath('/path?query=thing') // => '/path'
* onlyPath('/path#fragment') // => '/path'
* onlyPath('/path?query=thing#fragment') // => '/path'
* onlyPath(undefined) // => undefined
* onlyPath(null) // => null
* ```
*/
export function onlyPath(
url: string | undefined | null,
): string | undefined | null {
if (url === undefined || url === null) {
return url
}
const [path] = url.split(/[?#]/)
return path
}
Loading
Loading