diff --git a/README.md b/README.md index 362eee6..50faa45 100644 --- a/README.md +++ b/README.md @@ -158,6 +158,42 @@ Check if a path starts with `./` or `../`. isRelative('./foo') ``` +### `withHttp` + +Ensures url protocol is `http` + +```ts +// Result: http://example.com +withHttp('https://example.com') +``` + +### `withHttps` + +Ensures url protocol is `https` + +```ts +// Result: https://example.com +withHttps('http://example.com') +``` + +### `withProtocol` + +Changes url protocol passed as second argument + +```ts +// Result: ftp://example.com +withProtocol('http://example.com', 'ftp:') +``` + +### `withoutProtocol` + +Removes url protocol + +```ts +// Result: example.com +withoutProtocol('http://example.com') +``` + ## License [MIT](./LICENSE) diff --git a/src/parse.ts b/src/parse.ts index c5bb710..86c00be 100644 --- a/src/parse.ts +++ b/src/parse.ts @@ -64,10 +64,10 @@ export function parseHost (input: string = ''): ParsedHost { } } -export function stringifyParsedURL (parsed: ParsedURL) { +export function stringifyParsedURL (parsed: ParsedURL, withoutProtocol: boolean = false) { const fullpath = parsed.pathname + (parsed.search ? (parsed.search.startsWith('?') ? '' : '?') + parsed.search : '') + parsed.hash - if (!parsed.protocol) { + if (!parsed.protocol && !withoutProtocol) { return fullpath } - return parsed.protocol + '//' + (parsed.auth ? parsed.auth + '@' : '') + parsed.host + fullpath + return (withoutProtocol ? '' : parsed.protocol + '//') + (parsed.auth ? parsed.auth + '@' : '') + parsed.host + fullpath } diff --git a/src/utils.ts b/src/utils.ts index 2fd9c25..04bcc3c 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -109,6 +109,26 @@ export function joinURL (base: string, ...input: string[]): string { return url } +export function withHttp (input: string): string { + return withProtocol(input, 'http:') +} + +export function withHttps (input: string): string { + return withProtocol(input, 'https:') +} + +export function withoutProtocol (input: string): string { + const parsed = parseURL(input) + parsed.protocol = '' + return stringifyParsedURL(parsed, true) +} + +export function withProtocol (input: string, protocol?: string): string { + const parsed = parseURL(input) + parsed.protocol = protocol + return stringifyParsedURL(parsed) +} + // $URL based utils export function createURL (input: string): $URL { diff --git a/test/utilities.test.ts b/test/utilities.test.ts index e1f5f4d..8d73f1e 100644 --- a/test/utilities.test.ts +++ b/test/utilities.test.ts @@ -1,5 +1,14 @@ import { describe, expect, test } from 'vitest' -import { hasProtocol, isRelative, parsePath, stringifyParsedURL } from '../src' +import { + hasProtocol, + isRelative, + parsePath, + stringifyParsedURL, + withHttp, + withHttps, + withoutProtocol, + withProtocol +} from '../src' describe('hasProtocol', () => { const tests = [ @@ -60,3 +69,65 @@ describe('stringifyParsedURL', () => { }) } }) + +describe('withHttp', () => { + const tests = [ + { input: 'https://example.com', out: 'http://example.com' }, + { input: 'ftp://example.com/test?foo', out: 'http://example.com/test?foo' }, + { input: 'https://foo.com/test?query=123#hash', out: 'http://foo.com/test?query=123#hash' }, + { input: 'file:///home/user', out: 'http:///home/user' } + ] + + for (const t of tests) { + test(t.input.toString(), () => { + expect(withHttp(t.input)).toBe(t.out) + }) + } +}) + +describe('withHttps', () => { + const tests = [ + { input: 'http://example.com', out: 'https://example.com' }, + { input: 'ftp://example.com/test?foo', out: 'https://example.com/test?foo' }, + { input: 'http://foo.com/test?query=123#hash', out: 'https://foo.com/test?query=123#hash' }, + { input: 'file:///home/user', out: 'https:///home/user' } + ] + + for (const t of tests) { + test(t.input.toString(), () => { + expect(withHttps(t.input)).toBe(t.out) + }) + } +}) + +describe('withProtocol', () => { + const tests = [ + { input: 'http://example.com', protocol: 'https:', out: 'https://example.com' }, + { input: 'https://example.com', protocol: 'http:', out: 'http://example.com' }, + { input: 'ftp://example.com/test?foo', protocol: 'http:', out: 'http://example.com/test?foo' }, + { input: 'http://foo.com/test?query=123#hash', protocol: 'ftp:', out: 'ftp://foo.com/test?query=123#hash' }, + { input: 'file:///home/user', protocol: 'https:', out: 'https:///home/user' } + ] + + for (const t of tests) { + test(t.input.toString(), () => { + expect(withProtocol(t.input, t.protocol)).toBe(t.out) + }) + } +}) + +describe('withoutProtocol', () => { + const tests = [ + { input: 'http://example.com', out: 'example.com' }, + { input: 'https://example.com', out: 'example.com' }, + { input: 'ftp://example.com/test?foo', out: 'example.com/test?foo' }, + { input: 'http://foo.com/test?query=123#hash', out: 'foo.com/test?query=123#hash' }, + { input: 'file:///home/user', out: '/home/user' } + ] + + for (const t of tests) { + test(t.input.toString(), () => { + expect(withoutProtocol(t.input)).toBe(t.out) + }) + } +})