diff --git a/README.md b/README.md index 4333a92..b366e18 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ to _your_ definition of valid. See [how to use it](#usage). - [`parsers.integer(value: string): number`](#parsersintegervalue-string-number) - [`parsers.float(value: string): number`](#parsersfloatvalue-string-number) - [`parsers.email(value: string): string`](#parsersemailvalue-string-string) - - [`parsers.url(value: string): string`](#parsersurlvalue-string-string) + - [`parsers.url(value: string, opts?: any): string`](#parsersurlvalue-string-string) - [`parsers.ipAddress(value: string): string`](#parsersipaddressvalue-string-string) - [`parsers.port(value: string): number`](#parsersportvalue-string-number) - [`parsers.whitelist(whitelistedValues: string[]): Parser`](#parserswhitelistwhitelistedvalues-string-parserstring) @@ -177,10 +177,14 @@ Ensures the value is a float. Ensures the value is an email. -#### `parsers.url(value: string): string` +#### `parsers.url(value: string, opts: any): string` Ensures the value is a url. +You can also pass the optional second argument `opts` which allows you to customise the validation rules. + +See the `isURL` method of validator.js for a list of the options: https://github.com/validatorjs/validator.js + #### `parsers.ipAddress(value: string): string` Ensures the value is an IP address. diff --git a/src/parsers.test.ts b/src/parsers.test.ts index cdf3009..e0cc4c4 100644 --- a/src/parsers.test.ts +++ b/src/parsers.test.ts @@ -87,18 +87,33 @@ describe('parsers.email', () => { }); describe('parsers.url', () => { - test('parses a url', () => { - const serializedValue = 'https://example.com'; - const expectedValue = serializedValue; - - expect(parsers.url(serializedValue)).toEqual(expectedValue); - }); - - test('throws when serialized value is not an email', () => { - const serializedValue = 'not_an_email'; - - expect(() => parsers.url(serializedValue)).toThrow(); - }); + test.each([ + 'https://example.com', + 'https://withsubdomain.example.com', + 'http://non-secure.example.com', + 'https://withport.example.com:123', + ])('successfully parses the url: "%p"', (theUrl: string) => { + expect(parsers.url(theUrl)).toEqual(theUrl); + }); + + test.each([ + // eslint-disable-next-line @typescript-eslint/naming-convention + ['https://nodot', { require_tld: false }], + // eslint-disable-next-line @typescript-eslint/naming-convention + ['notaproto://example.com', { require_valid_protocol: false }], + ])( + 'successfully parses urls with different options: "%p", options: %j', + (theUrl: string, opts) => { + expect(parsers.url(theUrl, opts)).toEqual(theUrl); + }, + ); + + test.each(['not_a_url', 'https://nodot', 'notaproto://example.com'])( + 'throws when serialized value is not a url: "%p"', + (theUrl: string) => { + expect(() => parsers.url(theUrl)).toThrow(`value is not an URL`); + }, + ); }); describe('parsers.ipAddress', () => { diff --git a/src/parsers.ts b/src/parsers.ts index 9ac65a8..1215d61 100644 --- a/src/parsers.ts +++ b/src/parsers.ts @@ -2,7 +2,10 @@ import validator from 'validator'; import EnvironmentVariableError from './EnvironmentVariableError'; -export type Parser = (serializedValue: string) => TReturn; +export type Parser = ( + serializedValue: string, + opts?: any, +) => TReturn; /** * Parses a string. @@ -77,10 +80,10 @@ export const email: Parser = (serializedValue) => { /** * Parses a URL. */ -export const url: Parser = (serializedValue) => { +export const url: Parser = (serializedValue: string, opts?: any) => { const value = serializedValue; - if (!validator.isURL(value)) { + if (!validator.isURL(value, opts)) { throw new EnvironmentVariableError('value is not an URL'); }