Skip to content

Commit

Permalink
add(n4s): isURL builtin enforce plugin (#1046)
Browse files Browse the repository at this point in the history
Co-authored-by: Almog Haimovitch <[email protected]>
  • Loading branch information
almoghaimo and Almog Haimovitch authored Aug 10, 2023
1 parent bcfb703 commit 9b2cbb1
Show file tree
Hide file tree
Showing 6 changed files with 158 additions and 0 deletions.
1 change: 1 addition & 0 deletions packages/n4s/.npmignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ src
!dist/
tsconfig.json
!schema/
!isURL/
!email/
!date/
!compounds/
Expand Down
30 changes: 30 additions & 0 deletions packages/n4s/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,36 @@
"module": "./dist/es/schema.production.js",
"default": "./dist/cjs/schema.production.js"
},
"./isURL": {
"production": {
"types": "./types/isURL.d.ts",
"browser": "./dist/es/isURL.production.js",
"umd": "./dist/umd/isURL.production.js",
"import": "./dist/es/isURL.production.js",
"require": "./dist/cjs/isURL.production.js",
"node": "./dist/cjs/isURL.production.js",
"module": "./dist/es/isURL.production.js",
"default": "./dist/cjs/isURL.production.js"
},
"development": {
"types": "./types/isURL.d.ts",
"browser": "./dist/es/isURL.development.js",
"umd": "./dist/umd/isURL.development.js",
"import": "./dist/es/isURL.development.js",
"require": "./dist/cjs/isURL.development.js",
"node": "./dist/cjs/isURL.development.js",
"module": "./dist/es/isURL.development.js",
"default": "./dist/cjs/isURL.development.js"
},
"types": "./types/isURL.d.ts",
"browser": "./dist/es/isURL.production.js",
"umd": "./dist/umd/isURL.production.js",
"import": "./dist/es/isURL.production.js",
"require": "./dist/cjs/isURL.production.js",
"node": "./dist/cjs/isURL.production.js",
"module": "./dist/es/isURL.production.js",
"default": "./dist/cjs/isURL.production.js"
},
"./email": {
"production": {
"types": "./types/email.d.ts",
Expand Down
51 changes: 51 additions & 0 deletions packages/n4s/src/exports/__tests__/isUrl.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { enforce } from 'n4s';
import 'isURL';

describe('isURL', () => {
it('Should pass for valid URLs', () => {
expect(() => enforce('http://www.google.com').isURL()).not.toThrow();
expect(() => enforce('https://google.com').isURL()).not.toThrow();
expect(() => enforce('google.com').isURL()).not.toThrow();
expect(() => enforce('https://www.wikipedia.org/wiki/Main_Page').isURL()).not.toThrow();
expect(() => enforce('ftp://myserver.net').isURL()).not.toThrow();
expect(() => enforce('https://www.example.com/query?search=AI').isURL()).not.toThrow();
expect(() => enforce('https://username:[email protected]:8080').isURL()).not.toThrow();
expect(() => enforce('http://233.233.233.233').isURL()).not.toThrow();
expect(() => enforce('https://www.example.com/foo/?bar=baz&inga=42&quux').isURL()).not.toThrow();
expect(() => enforce('http://www.example.com/index.html#section1').isURL()).not.toThrow();
});

it('Should fail for invalid URLs', () => {
expect(() => enforce('').isURL()).toThrow();
expect(() => enforce('google').isURL()).toThrow();
expect(() => enforce('http://').isURL()).toThrow();
expect(() => enforce('https://').isURL()).toThrow();
expect(() => enforce('www.google.').isURL()).toThrow();
expect(() => enforce('http://google').isURL()).toThrow();
expect(() => enforce('https://google').isURL()).toThrow();
expect(() => enforce('http:///www.google.com').isURL()).toThrow();
expect(() => enforce('https:///www.google.com').isURL()).toThrow();
expect(() => enforce('http://www.goo gle.com').isURL()).toThrow();
expect(() => enforce('://www.google.com').isURL()).toThrow();
expect(() => enforce('http://localhost').isURL()).toThrow();
expect(() => enforce('www.com').isURL({ require_host: false })).not.toThrow();
})

describe('With options', () => {
it('should pass for valid URLs', () => {
expect(() => enforce('myprotocol://customdomain.com').isURL({ protocols: ['myprotocol'] })).not.toThrow();
expect(() => enforce('http://localhost:8080').isURL({ require_tld: false })).not.toThrow();
expect(() => enforce('invalid://www.google.com').isURL({ require_valid_protocol: false })).not.toThrow();
expect(() => enforce('http://my_server.com').isURL({ allow_underscores: true })).not.toThrow();
});

it('should fail for invalid URLs', () => {
expect(() => enforce('myprotocol://customdomain.com').isURL({ protocols: ['http'] })).toThrow();
expect(() => enforce('http://localhost:8080').isURL({ require_tld: true })).toThrow();
expect(() => enforce('invalid://www.google.com').isURL({ require_valid_protocol: true })).toThrow();
expect(() => enforce('http://my_server.com').isURL({ allow_underscores: false })).toThrow();
expect(() => enforce('http://www.example.com/index.html#section1').isURL({ allow_fragments: false })).toThrow();
});
});

});
15 changes: 15 additions & 0 deletions packages/n4s/src/exports/isUrl.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { enforce } from 'n4s';
import isURL from 'validator/es/lib/isURL';

import { EnforceCustomMatcher } from 'enforceUtilityTypes';

enforce.extend({ isURL });

/* eslint-disable @typescript-eslint/no-namespace */
declare global {
namespace n4s {
interface EnforceCustomMatchers<R> {
isURL: EnforceCustomMatcher<typeof isURL, R>;
}
}
}
1 change: 1 addition & 0 deletions packages/n4s/tsconfig.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

60 changes: 60 additions & 0 deletions website/docs/enforce/builtin-enforce-plugins/isUrl.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
---
sidebar_position: 4
title: isURL enforce Rule
description: isURL enforce rule for validating url addresses.
keywords: [Vest, enforce, plugin, isURL, n4s, url]
---

# isURL Enforce Rule

## Description

The isURL enforce rule provides functionality to validate URL values. This documentation covers the `isUrl` rule, along with its options and configurations.

These rule exposes the [`validator.js`](https://www.npmjs.com/package/validator) isURL rule, and accepts the same options.

## isURL Rule

The `isURL` rule checks whether a given value is a valid URL. It accepts various options to customize the validation behavior.

```javascript
enforce(value).isURL(options);
```

### Options

The isURL rule accepts an optional options object to customize the validation behavior. The available options are as follows:

The `isUrl` rule accepts an optional `options` object to customize the validation behavior. The available options are as follows:

| Option | Default Value | Description |
| ----------------------------- | ------------- | --------------------------------------------------------------------------------------------------------------------- |
| `require_protocol` | `false` | Requires the URL to include a protocol (e.g., `http://` or `https://`). |
| `require_host` | `true` | Requires the URL to include a host (e.g., `www.example.com`). |
| `require_valid_protocol` | `true` | Requires the URL's protocol to be in the list of valid protocols (`http`, `https`, `ftp`). |
| `allow_underscores` | `false` | Allows underscores in the host name. |
| `allow_trailing_dot` | `false` | Allows a trailing dot in the host name. |
| `allow_protocol_relative_urls`| `false` | Allows protocol-relative URLs (e.g., `//www.example.com`). |
| `allow_fragments` | `true` | Allows URL fragments (e.g., `#section`). |
| `allow_query_components` | `true` | Allows query components in the URL (e.g., `?query=value`). |
| `validate_length` | `true` | Validates that the URL length does not exceed the maximum allowed length (2083 characters). |

### Usage Example

```javascript
// Usage with options
enforce(url).isURL({
protocols: ['http', 'https', 'ftp'],
require_tld: true,
require_protocol: false,
require_host: true,
require_port: false,
require_valid_protocol: true,
allow_underscores: false,
allow_trailing_dot: false,
allow_protocol_relative_urls: false,
allow_fragments: true,
allow_query_components: true,
validate_length: true
});
```

2 comments on commit 9b2cbb1

@vercel
Copy link

@vercel vercel bot commented on 9b2cbb1 Aug 10, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

vest – ./website

vest-git-latest-ealush.vercel.app
vest.vercel.app
vest-ealush.vercel.app
vestjs.dev
www.vestjs.dev

@vercel
Copy link

@vercel vercel bot commented on 9b2cbb1 Aug 10, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

vest-next – ./website

vest-next-git-latest-ealush.vercel.app
vest-next.vercel.app
vest-next-ealush.vercel.app
vest-website.vercel.app

Please sign in to comment.