This commit is contained in:
Yamozha
2021-04-02 02:24:13 +03:00
parent c23950b545
commit 7256d79e2c
31493 changed files with 3036630 additions and 0 deletions

17
node_modules/@hapi/address/.travis.yml generated vendored Normal file
View File

@ -0,0 +1,17 @@
language: node_js
node_js:
- "8"
- "10"
- "12"
- "node"
sudo: false
install:
- "npm install"
os:
- "linux"
- "osx"
- "windows"

49
node_modules/@hapi/address/API.md generated vendored Executable file
View File

@ -0,0 +1,49 @@
## Methods
### `domain.analyze(domain, [options])`
Analyzes a string to verify it is a valid domain name where:
- `domain` - the domain name string being verified.
- `options` - optional settings:
- `allowUnicode` - if `false`, Unicode characters are not allowd in domain names. Defaults to `true`.
- `minDomainSegments` - the minimum number of domain segments (e.g. `x.y.z` has 3 segments) required. Defaults to `2`.
- `tlds` - options to validate the top-level-domain segment (e.g. `com` in `example.com`). Can be set to one of:
- `false` - disable TLD validation.
- `true` - validate the TLD using the official list of [registered names](http://data.iana.org/TLD/tlds-alpha-by-domain.txt). This is the default setting.
- an object with one (and only one) of:
- `deny` - a `Set` with strings matching forbidden TLD values (all non-matching values are allowed).
- `allow` - a `Set` with strings matching the only allowed TLD values. Can also be set to `true` which defaults to the official list of [registered names](http://data.iana.org/TLD/tlds-alpha-by-domain.txt).
If the `domain` is valid, no return value. If the `domain` is invalid, an object is returned with:
- `error` - a string containing the reason the domain is invalid.
### `domain.isValid(domain, [options])`
Validates a string to verify it is a valid domain name where:
- `domain` - the domain name string being verified.
- `options` - same options as [`domain.analyze()`](#domainanalyzedomain-options).
### `email.analyze(email, [options])`
Analyzes a string to verify it is a valid email address where:
- `email` - the email address string being verified.
- `options` - optional settings:
- `allowUnicode` - if `false`, Unicode characters are not allowd in the email address local and domain parts. Defaults to `true`.
- `ignoreLength` - if `true`, the standards email maximum length limit is ignored. Defaults to `true`.
- `minDomainSegments` - the minimum number of domain segments (e.g. `x.y.z` has 3 segments) required in the domain part. Defaults to `2`.
- `tlds` - options to validate the top-level-domain segment (e.g. `com` in `example.com`) of the domain part. Can be set to one of:
- `false` - disable TLD validation.
- `true` - validate the TLD using the official list of [registered names](http://data.iana.org/TLD/tlds-alpha-by-domain.txt). This is the default setting.
- an object with one (and only one) of:
- `deny` - a `Set` with strings matching forbidden TLD values (all non-matching values are allowed).
- `allow` - a `Set` with strings matching the only allowed TLD values. Can also be set to `true` which defaults to the official list of [registered names](http://data.iana.org/TLD/tlds-alpha-by-domain.txt).
If the `email` is valid, no return value. If the `email` is invalid, an object is returned with:
- `error` - a string containing the reason the email is invalid.
### `email.isValid(email, [options])`
Validates a string to verify it is a valid email address where:
- `email` - the email address string being verified.
- `options` - same options as [`email.analyze()`](#emailanalyzeemail-options).

3
node_modules/@hapi/address/CHANGELOG.md generated vendored Normal file
View File

@ -0,0 +1,3 @@
Breaking changes are documented using GitHub issues, see [issues labeled "release notes"](https://github.com/hapijs/address/issues?q=is%3Aissue+label%3A%22release+notes%22).
If you want changes of a specific minor or patch release, you can browse the [GitHub milestones](https://github.com/hapijs/address/milestones?state=closed&direction=asc&sort=due_date).

9
node_modules/@hapi/address/LICENSE.md generated vendored Normal file
View File

@ -0,0 +1,9 @@
Copyright (c) 2019, Project contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
* The names of any contributors may not be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

16
node_modules/@hapi/address/README.md generated vendored Executable file
View File

@ -0,0 +1,16 @@
<a href="https://hapi.dev"><img src="https://raw.githubusercontent.com/hapijs/assets/master/images/family.png" width="180px" align="right" /></a>
# @hapi/address
#### Validate email address and domain.
**address** is part of the **hapi** ecosystem and was designed to work seamlessly with the [hapi web framework](https://hapi.dev) and its other components (but works great on its own or with other frameworks). If you are using a different web framework and find this module useful, check out [hapi](https://hapi.dev) <20> they work even better together.
### Visit the [hapi.dev](https://hapi.dev) Developer Portal for tutorials, documentation, and support
## Useful resources
- [Documentation and API](https://hapi.dev/family/address/)
- [Versions status](https://hapi.dev/resources/status/#address)
- [Project policies](https://hapi.dev/policies/)
- [Free and commercial support options](https://hapi.dev/support/)

238
node_modules/@hapi/address/bench/test.js generated vendored Executable file
View File

@ -0,0 +1,238 @@
'use strict';
const Bench = require('bench');
const Address = require('../');
const Isemail = require('isemail');
const tests = [
['', false],
['\r', false],
['test', false],
['@', false],
['test@', false],
['test@io', false],
['test@io', true, { minDomainSegments: 1 }],
['@io', false],
['@iana.org', false],
['test@iana.org', true],
['test@nominet.org.uk', true],
['test@about.museum', true],
['a@iana.org', true],
['êjness@iana.org', true],
['ñoñó1234@iana.org', true],
['ñoñó1234@something.com', true],
['伊昭傑@郵件.商務', true],
['\ud801\udc37\ud852\udf62@iana.org', true],
['test.test@iana.org', true],
['.test@iana.org', false],
['test.@iana.org', false],
['test..iana.org', false],
['test_exa-mple.com', false],
['!#$%&`*+/=?^`{|}~@iana.org', true],
['test\\@test@iana.org', false],
['123@iana.org', true],
['test@123.com', true],
['test@iana.123', false],
['test@255.255.255.255', false],
['abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghiklm@iana.org', true],
['abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghiklmn@iana.org', false],
['\ud83d\ude06\ud83d\ude06\ud83d\ude06\ud83d\ude06\ud83d\ude06\ud83d\ude06\ud83d\ude06\ud83d\ude06\ud83d\ude06\ud83d\ude06\ud83d\ude06\ud83d\ude06\ud83d\ude06\ud83d\ude06\ud83d\ude06\ud83d\ude06\ud83d\ude06@iana.org', false],
['test@abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghiklm', false],
['test@\ud83d\ude06\ud83d\ude06\ud83d\ude06\ud83d\ude06\ud83d\ude06\ud83d\ude06\ud83d\ude06\ud83d\ude06\ud83d\ude06\ud83d\ude06\ud83d\ude06\ud83d\ude06\ud83d\ude06\ud83d\ude06\ud83d\ude06\ud83d\ude06\ud83d\ude06.org', true],
['test@abcdefghijklmnopqrstuvwxyzabcdefghijklmno\ud83d\ude06\ud83d\ude06\ud83d\ude06\ud83d\ude06\ud83d\ude06\ud83d\ude06\ud83d\ude06\ud83d\ude06\ud83d\ude06\ud83d\ude06\ud83d\ude06\ud83d\ude06\ud83d\ude06\ud83d\ude06\ud83d\ude06\ud83d\ude06\ud83d\ude06.org', false],
['test@abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghiklm.com', false],
['test@mason-dixon.com', true],
['test@-iana.org', false],
['test@iana-.com', false],
['test@.iana.org', false],
['test@iana.org.', false],
['test@iana..com', false],
['abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghiklm@abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefg.abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefg.abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefg.abcdefghijklmno', false],
['abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghiklm@abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefg.abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefg.abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefg.\ud83d\ude06\ud83d\ude06\ud83d\ude06\ud83d\ude06', false],
['abcdef@abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefg.abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefg.abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefg.abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdef.hijklmnopqrstuv', false],
['abcdef@abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefg.abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefg.abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefg.abcdefghi.abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcd\ud83d\ude06', false],
['abcdef@abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefg.abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefg.abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefg.abcdefghi.abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz\ud83d\ude06', false],
['a@abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefg.abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefg.abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefg.abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefg.abcdefghijkl.hijk', false],
['a@abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefg.abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefg.abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefg.abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefg.abcdefghijkl.\ud83d\ude06', false],
['\"\r', false],
['\"test\"@iana.org', false],
['\"\"@iana.org', false],
['\"\"\"@iana.org', false],
['\"\\a\"@iana.org', false],
['\"\\\"\"@iana.org', false],
['\"\\\"@iana.org', false],
['\"\\\\\"@iana.org', false],
['test\"@iana.org', false],
['\"test@iana.org', false],
['\"test\"test@iana.org', false],
['test\"text\"@iana.org', false],
['\"test\"\"test\"@iana.org', false],
['\"test\".\"test\"@iana.org', false],
['\"test\\ test\"@iana.org', false],
['\"test\".test@iana.org', false],
['\"test\u0000\"@iana.org', false],
['\"test\\\u0000\"@iana.org', false],
['\"test\r\n test\"@iana.org', false],
['\"abcdefghijklmnopqrstuvwxyz abcdefghijklmnopqrstuvwxyz abcdefghj\"@iana.org', false],
['\"abcdefghijklmnopqrstuvwxyz abcdefghijklmnopqrstuvwxyz abcdefg\\h\"@iana.org', false],
['test@[255.255.255.255]', false],
['test@a[255.255.255.255]', false],
['test@[255.255.255]', false],
['test@[255.255.255.255.255]', false],
['test@[255.255.255.256]', false],
['test@[1111:2222:3333:4444:5555:6666:7777:8888]', false],
['test@[IPv6:1111:2222:3333:4444:5555:6666:7777]', false],
['test@[IPv6:1111:2222:3333:4444:5555:6666:7777:8888]', false],
['test@[IPv6:1111:2222:3333:4444:5555:6666:7777:8888:9999]', false],
['test@[IPv6:1111:2222:3333:4444:5555:6666:7777:888G]', false],
['test@[IPv6:1111:2222:3333:4444:5555:6666::8888]', false],
['test@[IPv6:1111:2222:3333:4444:5555::8888]', false],
['test@[IPv6:1111:2222:3333:4444:5555:6666::7777:8888]', false],
['test@[IPv6::3333:4444:5555:6666:7777:8888]', false],
['test@[IPv6:::3333:4444:5555:6666:7777:8888]', false],
['test@[IPv6:1111::4444:5555::8888]', false],
['test@[IPv6:::]', false],
['test@[IPv6:1111:2222:3333:4444:5555:255.255.255.255]', false],
['test@[IPv6:1111:2222:3333:4444:5555:6666:255.255.255.255]', false],
['test@[IPv6:1111:2222:3333:4444:5555:6666:7777:255.255.255.255]', false],
['test@[IPv6:1111:2222:3333:4444::255.255.255.255]', false],
['test@[IPv6:1111:2222:3333:4444:5555:6666::255.255.255.255]', false],
['test@[IPv6:1111:2222:3333:4444:::255.255.255.255]', false],
['test@[IPv6::255.255.255.255]', false],
['test@[255.255.255.255].local', false],
['test@local.[255.255.255.255]', false],
['test@local.[255.255.255.255].local', false],
['test@local.(comment)[255.255.255.255].local', false],
['test@local. [255.255.255.255].local', false],
['test@local.[255.255.255.255](comment).local', false],
['test@local.[255.255.255.255] .local', false],
[' test @iana.org', false],
['test@ iana .com', false],
['test . test@iana.org', false],
['\r\n test@iana.org', false],
['\r\n \r\n test@iana.org', false],
['(\r', false],
['(comment)test@iana.org', false],
['((comment)test@iana.org', false],
['(comment(comment))test@iana.org', false],
['test@(comment)iana.org', false],
['test(comment)@iana.org', false],
['test(comment)test@iana.org', false],
['test@(comment)[255.255.255.255]', false],
['(comment)abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghiklm@iana.org', false],
['test@(comment)abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefg.com', false],
['(comment)test@abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefg.abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefg.abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefg.abcdefghijklmnopqrstuvwxyzabcdefghijk.abcdefghijklmnopqrst', false],
['test@iana.org\n', false],
['xn--test@iana.org', true],
['test@iana.org-', false],
['\"test@iana.org', false],
['(test@iana.org', false],
['test@(iana.org', false],
['test@[1.2.3.4', false],
['\"test\\\"@iana.org', false],
['(comment\\)test@iana.org', false],
['test@iana.org(comment\\)', false],
['test@iana.org(comment\\', false],
['test@[RFC-5322-domain-literal]', false],
['test@[RFC-5322-郵件ñó-domain-literal]', false],
['test@[RFC-5322]-domain-literal]', false],
['test@[RFC-5322].domain-literal]', false],
['test@[RFC-5322-[domain-literal]', false],
['test@[€', false],
['test@[\u0007]', false],
['test@[RFC-5322-\\\u0007-domain-literal]', false],
['test@[RFC-5322-\\\t-domain-literal]', false],
['test@[RFC-5322-\\]-domain-literal]', false],
['test@[RFC-5322-\\郵-no-domain-literal]', false],
['test@[RFC-5322--domain-literal]', false],
['test@[RFC-5322-domain-literal\\]', false],
['test@[RFC-5322-domain-literal\\', false],
['test@[RFC 5322 domain literal]', false],
['test@[RFC-5322-domain-literal] (comment)', false],
['@iana.org', false],
['test@.org', false],
['\"\"@iana.org', false],
['\"€\"@iana.org', false],
['\"\\\"@iana.org', false],
['()test@iana.org', false],
['(€)test@iana.org', false],
['test@iana.org\r', false],
['\rtest@iana.org', false],
['\"\rtest\"@iana.org', false],
['(\r)test@iana.org', false],
['test@iana.org(\r)', false],
['test@<iana>.org', false],
['\ntest@iana.org', false],
['\"\n\"@iana.org', false],
['\"\\\n\"@iana.org', false],
['(\n)test@iana.org', false],
['\u0007@iana.org', false],
['test@\u0007.org', false],
['\"\u0007\"@iana.org', false],
['\"\\\u0007\"@iana.org', false],
['(\u0007)test@iana.org', false],
['\r\ntest@iana.org', false],
['\r\n \r\ntest@iana.org', false],
[' \r\ntest@iana.org', false],
[' \r\n test@iana.org', false],
[' \r\n \r\ntest@iana.org', false],
[' \r\n\r\ntest@iana.org', false],
[' \r\n\r\n test@iana.org', false],
['test@iana.org\r\n ', false],
['test@iana.org\r\n \r\n ', false],
['test@iana.org\r\n', false],
['test@iana.org \r', false],
['test@iana.org\r\n \r\n', false],
['test@iana.org \r\n', false],
['test@iana.org \r\n ', false],
['test@iana.org \r\n \r\n', false],
['test@iana.org \r\n\r\n', false],
['test@iana.org \r\n\r\n ', false],
['test@iana. org', false],
['test@[\r', false],
['test@[\r\n', false],
[' test@iana.org', false],
['test@iana.org ', false],
['test@[IPv6:1::2:]', false],
['\"test\\\u0094\"@iana.org', false],
['test@iana/icann.org', false],
['test@iana!icann.org', false],
['test@iana?icann.org', false],
['test@iana^icann.org', false],
['test@iana{icann}.org', false],
['test.(comment)test@iana.org', false],
['test@iana.(comment)org', false],
['test@iana(comment)iana.org', false],
['(comment\r\n comment)test@iana.org', false],
['test@org', true, { minDomainSegments: 1 }],
['test\ud800@invalid', false],
['\"\ud800\"@invalid', false],
['\"\\\ud800\"@invalid', false],
['(\ud800)thing@invalid', false],
['\"\\\ud800\"@invalid', false],
['test@\ud800\udfffñoñó郵件ñoñó郵件.郵件ñoñó郵件ñoñó郵件.ñoñó郵件ñoñó郵件.ñoñó郵件ñoñó郵件.ñoñó郵件ñoñó郵件.ñoñó郵件ñoñó郵件.ñoñó郵件ñoñó郵件.noñó郵件.商務', true],
['test@\ud800\udfffñoñó郵件ñoñó郵件.郵件ñoñó郵件ñoñó郵件.ñoñó郵件ñoñó郵件.ñoñó郵件ñoñó郵件.ñoñó郵件ñoñó郵件.ñoñó郵件ñoñó郵件.ñoñó郵件ñoñó郵件.noñó郵件ñoñó郵.商務', false],
['test@\ud800\udfffñoñó郵件ñoñó郵件.郵件ñoñó郵件ñoñó郵件.ñoñó郵件ñoñó郵件ñoñó郵件.ñoñó郵件ñoñó郵件.ñoñó郵件ñoñó郵件.ñoñó郵件ñoñó郵件.ñoñó郵件ñoñó郵件.ñoñó郵件ñoñó郵件.oñó郵件ñoñó郵件ñoñó郵件.商務', false],
['test@ñoñoñó郵件\ud83d\ude06ñoñ.oñó郵件\uc138ñoñ.oñó郵件\u0644\u4eec\u010dñoñoñó郵件\u05dcño.ñoñó郵件\u092f\u672cñoñoñó郵件\uc138añoñ.oñó郵件\ud83d\ude06bc\uc138郵\ud83d\ude06ño.ñoñó郵件ñoñoñó郵件\ud83d\ude06ñoñoñó郵件\uc138ñoñ.oñó郵件\u0644\u4eecñoñoñó.郵件\ud83d\ude06ñoñoñó郵件郵\uc138ñoñoñó郵件\u0644\u4eecñoñoñó郵件.\ud83d\ude06ñoñoñó郵件郵\uc138\u0644\u4eec.郵件\ud83d\ude06ñoñoñó郵.件郵\uc138\u4eec\ud83d\ude06ñoñoñó件郵\uc138ñoñoñó郵件', false],
['test@ñoñó郵件ñoñó郵件ñoñó郵件ñoñoñó郵件ñoñó郵件ñoñó郵件ñoñó郵件ñoñó郵件ñoñó郵件ñoñó郵件ñoñó郵件ñoñó郵件ñoñó郵件ñoñó郵件ñoñó郵件ñoñó郵件ñoñó郵件ñoñó郵件ñoñó郵件ñoñó郵件ñoñó郵件ñoñó郵件ñoñó郵件ñoñó郵件ñoñó郵件ñoñó郵件ñoñó郵件ñoñó郵件ñoñó郵件ñoñó郵件ñoñó郵件ñoñó郵件ñoñó郵件ñoñó郵件ñoñó郵件ñoñó郵件ñoñó郵件ñoñó郵件ñoñó郵件ñoñó郵件ñoñó郵件ñoñó郵件ñoñó郵件.商務', false],
['\ud83d\ude06ñoñó郵件ñoñó郵件ñoñó\ud83d\ude06郵件ñoñoñó郵@\ud83d\ude06郵件ñoñó郵件ñoñó.\ud83d\ude06郵件ñoñó郵件ñoñó.\ud83d\ude06郵件ñoñó郵件ñoñó.郵件ñoñó郵件ñoñó\ud83d\ude06.郵件ñoñó郵件ñoñó.郵件ñoñó郵件.ñoñó郵件ñoñó.郵件ñoñó郵件.\ud83d\ude06郵件ñoñó郵件ñoñó.\ud83d\ude06郵件ñoñó郵件ñoñó.\ud83d\ude06商務.郵件ñoñó郵件ñoñó郵件.\ud83d\ude06商務.\ud83d\ude06商務.\ud83d\ude06商務', false]
];
exports.compare = {
address: function () {
for (const test of tests) {
Address.email.isValid(test[0]);
}
},
isemail: function () {
for (const test of tests) {
Isemail.validate(test[0]);
}
}
};
Bench.runMain();

103
node_modules/@hapi/address/lib/domain.js generated vendored Executable file
View File

@ -0,0 +1,103 @@
'use strict';
const Url = require('url');
const internals = {
minDomainSegments: 2,
nonAsciiRx: /[^\x00-\x7f]/,
domainControlRx: /[\x00-\x20@\:\/]/, // Control + space + separators
tldSegmentRx: /^[a-zA-Z](?:[a-zA-Z0-9\-]*[a-zA-Z0-9])?$/,
domainSegmentRx: /^[a-zA-Z0-9](?:[a-zA-Z0-9\-]*[a-zA-Z0-9])?$/,
URL: Url.URL || URL // $lab:coverage:ignore$
};
exports.analyze = function (domain, options = {}) {
if (typeof domain !== 'string') {
throw new Error('Invalid input: domain must be a string');
}
if (!domain) {
return { error: 'Domain must be a non-empty string' };
}
if (domain.length > 256) {
return { error: 'Domain too long' };
}
const ascii = !internals.nonAsciiRx.test(domain);
if (!ascii) {
if (options.allowUnicode === false) { // Defaults to true
return { error: 'Domain contains forbidden Unicode characters' };
}
domain = domain.normalize('NFC');
}
if (internals.domainControlRx.test(domain)) {
return { error: 'Domain contains invalid character' };
}
domain = internals.punycode(domain);
// https://tools.ietf.org/html/rfc1035 section 2.3.1
const minDomainSegments = options.minDomainSegments || internals.minDomainSegments;
const segments = domain.split('.');
if (segments.length < minDomainSegments) {
return { error: 'Domain lacks the minimum required number of segments' };
}
const tlds = options.tlds;
if (tlds) {
const tld = segments[segments.length - 1].toLowerCase();
if (tlds.deny && tlds.deny.has(tld) ||
tlds.allow && !tlds.allow.has(tld)) {
return { error: 'Domain uses forbidden TLD' };
}
}
for (let i = 0; i < segments.length; ++i) {
const segment = segments[i];
if (!segment.length) {
return { error: 'Domain contains empty dot-separated segment' };
}
if (segment.length > 63) {
return { error: 'Domain contains dot-separated segment that is too long' };
}
if (i < segments.length - 1) {
if (!internals.domainSegmentRx.test(segment)) {
return { error: 'Domain contains invalid character' };
}
}
else {
if (!internals.tldSegmentRx.test(segment)) {
return { error: 'Domain contains invalid tld character' };
}
}
}
};
exports.isValid = function (domain, options) {
return !exports.analyze(domain, options);
};
internals.punycode = function (domain) {
try {
return new internals.URL(`http://${domain}`).host;
}
catch (err) {
return domain;
}
};

169
node_modules/@hapi/address/lib/email.js generated vendored Executable file
View File

@ -0,0 +1,169 @@
'use strict';
const Util = require('util');
const Domain = require('./domain');
const internals = {
nonAsciiRx: /[^\x00-\x7f]/,
encoder: new (Util.TextEncoder || TextEncoder)() // $lab:coverage:ignore$
};
exports.analyze = function (email, options) {
return internals.email(email, options);
};
exports.isValid = function (email, options) {
return !internals.email(email, options);
};
internals.email = function (email, options = {}) {
if (typeof email !== 'string') {
throw new Error('Invalid input: email must be a string');
}
if (!email) {
return { error: 'Address must be a non-empty string' };
}
// Unicode
const ascii = !internals.nonAsciiRx.test(email);
if (!ascii) {
if (options.allowUnicode === false) { // Defaults to true
return { error: 'Address contains forbidden Unicode characters' };
}
email = email.normalize('NFC');
}
// Basic structure
const parts = email.split('@');
if (parts.length !== 2) {
return { error: parts.length > 2 ? 'Address cannot contain more than one @ character' : 'Address must contain one @ character' };
}
const [local, domain] = parts;
if (!local) {
return { error: 'Address local part cannot be empty' };
}
if (!options.ignoreLength) {
if (email.length > 254) { // http://tools.ietf.org/html/rfc5321#section-4.5.3.1.3
return { error: 'Address too long' };
}
if (internals.encoder.encode(local).length > 64) { // http://tools.ietf.org/html/rfc5321#section-4.5.3.1.1
return { error: 'Address local part too long' };
}
}
// Validate parts
return internals.local(local, ascii) || Domain.analyze(domain, options);
};
internals.local = function (local, ascii) {
const segments = local.split('.');
for (const segment of segments) {
if (!segment.length) {
return { error: 'Address local part contains empty dot-separated segment' };
}
if (ascii) {
if (!internals.atextRx.test(segment)) {
return { error: 'Address local part contains invalid character' };
}
continue;
}
for (const char of segment) {
if (internals.atextRx.test(char)) {
continue;
}
const binary = internals.binary(char);
if (!internals.atomRx.test(binary)) {
return { error: 'Address local part contains invalid character' };
}
}
}
};
internals.binary = function (char) {
return Array.from(internals.encoder.encode(char)).map((v) => String.fromCharCode(v)).join('');
};
/*
From RFC 5321:
Mailbox = Local-part "@" ( Domain / address-literal )
Local-part = Dot-string / Quoted-string
Dot-string = Atom *("." Atom)
Atom = 1*atext
atext = ALPHA / DIGIT / "!" / "#" / "$" / "%" / "&" / "'" / "*" / "+" / "-" / "/" / "=" / "?" / "^" / "_" / "`" / "{" / "|" / "}" / "~"
Domain = sub-domain *("." sub-domain)
sub-domain = Let-dig [Ldh-str]
Let-dig = ALPHA / DIGIT
Ldh-str = *( ALPHA / DIGIT / "-" ) Let-dig
ALPHA = %x41-5A / %x61-7A ; a-z, A-Z
DIGIT = %x30-39 ; 0-9
From RFC 6531:
sub-domain =/ U-label
atext =/ UTF8-non-ascii
UTF8-non-ascii = UTF8-2 / UTF8-3 / UTF8-4
UTF8-2 = %xC2-DF UTF8-tail
UTF8-3 = %xE0 %xA0-BF UTF8-tail /
%xE1-EC 2( UTF8-tail ) /
%xED %x80-9F UTF8-tail /
%xEE-EF 2( UTF8-tail )
UTF8-4 = %xF0 %x90-BF 2( UTF8-tail ) /
%xF1-F3 3( UTF8-tail ) /
%xF4 %x80-8F 2( UTF8-tail )
UTF8-tail = %x80-BF
Note: The following are not supported:
RFC 5321: address-literal, Quoted-string
RFC 5322: obs-*, CFWS
*/
internals.atextRx = /^[\w!#\$%&'\*\+\-/=\?\^`\{\|\}~]+$/; // _ included in \w
internals.atomRx = new RegExp([
// %xC2-DF UTF8-tail
'(?:[\\xc2-\\xdf][\\x80-\\xbf])',
// %xE0 %xA0-BF UTF8-tail %xE1-EC 2( UTF8-tail ) %xED %x80-9F UTF8-tail %xEE-EF 2( UTF8-tail )
'(?:\\xe0[\\xa0-\\xbf][\\x80-\\xbf])|(?:[\\xe1-\\xec][\\x80-\\xbf]{2})|(?:\\xed[\\x80-\\x9f][\\x80-\\xbf])|(?:[\\xee-\\xef][\\x80-\\xbf]{2})',
// %xF0 %x90-BF 2( UTF8-tail ) %xF1-F3 3( UTF8-tail ) %xF4 %x80-8F 2( UTF8-tail )
'(?:\\xf0[\\x90-\\xbf][\\x80-\\xbf]{2})|(?:[\\xf1-\\xf3][\\x80-\\xbf]{3})|(?:\\xf4[\\x80-\\x8f][\\x80-\\xbf]{2})'
].join('|'));

84
node_modules/@hapi/address/lib/index.js generated vendored Executable file
View File

@ -0,0 +1,84 @@
'use strict';
const Domain = require('./domain');
const Email = require('./email');
const Tlds = require('./tlds');
const internals = {
defaultTlds: { allow: Tlds, deny: null }
};
module.exports = {
domain: {
analyze(domain, options) {
options = internals.options(options);
return Domain.analyze(domain, options);
},
isValid(domain, options) {
options = internals.options(options);
return Domain.isValid(domain, options);
}
},
email: {
analyze(email, options) {
options = internals.options(options);
return Email.analyze(email, options);
},
isValid(email, options) {
options = internals.options(options);
return Email.isValid(email, options);
}
}
};
internals.options = function (options) {
if (!options) {
return { tlds: internals.defaultTlds };
}
if (options.tlds === false) { // Defaults to true
return options;
}
if (!options.tlds ||
options.tlds === true) {
return Object.assign({}, options, { tlds: internals.defaultTlds });
}
if (typeof options.tlds !== 'object') {
throw new Error('Invalid options: tlds must be a boolean or an object');
}
if (options.tlds.deny) {
if (options.tlds.deny instanceof Set === false) {
throw new Error('Invalid options: tlds.deny must be a Set object');
}
if (options.tlds.allow) {
throw new Error('Invalid options: cannot specify both tlds.allow and tlds.deny lists');
}
return options;
}
if (options.tlds.allow === true) {
return Object.assign({}, options, { tlds: internals.defaultTlds });
}
if (options.tlds.allow instanceof Set === false) {
throw new Error('Invalid options: tlds.allow must be a Set object or true');
}
return options;
};

1542
node_modules/@hapi/address/lib/tlds.js generated vendored Executable file

File diff suppressed because it is too large Load Diff

23
node_modules/@hapi/address/package.json generated vendored Normal file
View File

@ -0,0 +1,23 @@
{
"name": "@hapi/address",
"description": "Email address and domain validation",
"version": "2.1.4",
"repository": "git://github.com/hapijs/address",
"main": "lib/index.js",
"keywords": [
"email",
"domain",
"address",
"validation"
],
"dependencies": {},
"devDependencies": {
"@hapi/code": "6.x.x",
"@hapi/lab": "20.x.x"
},
"scripts": {
"test": "lab -a @hapi/code -t 100 -L",
"test-cov-html": "lab -a @hapi/code -t 100 -L -r html -o coverage.html"
},
"license": "BSD-3-Clause"
}

451
node_modules/@hapi/address/test/index.js generated vendored Executable file
View File

@ -0,0 +1,451 @@
'use strict';
const Punycode = require('punycode');
const Code = require('@hapi/code');
const Address = require('..');
const Lab = require('@hapi/lab');
const internals = {};
const { describe, it } = exports.lab = Lab.script();
const expect = Code.expect;
describe('email', () => {
it('available as direct require', () => {
expect(require('../lib/email').isValid('test@example.com')).to.be.true();
});
describe('analyze()', () => {
it('identifies error', () => {
const tests = [
['', 'Address must be a non-empty string'],
['êjness@iana.org', 'Address contains forbidden Unicode characters', { allowUnicode: false }],
['test@test@test', 'Address cannot contain more than one @ character'],
['test', 'Address must contain one @ character'],
['@example.com', 'Address local part cannot be empty'],
['test@', 'Domain must be a non-empty string'],
['1234567890@abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz.com', 'Address too long'],
['1234567890123456789012345678901234567890123456789012345678901234567890@example.com', 'Address local part too long'],
['x..y@example.com', 'Address local part contains empty dot-separated segment'],
['x:y@example.com', 'Address local part contains invalid character'],
['ê:y@example.com', 'Address local part contains invalid character'],
['test@com', 'Domain lacks the minimum required number of segments'],
['test@x.no-such-tld', 'Domain uses forbidden TLD'],
['test@example..com', 'Domain contains empty dot-separated segment'],
['test@1234567890123456789012345678901234567890123456789012345678901234567890.com', 'Domain contains dot-separated segment that is too long'],
['test@example+.com', 'Domain contains invalid character', { tlds: false }],
['test@example.com_', 'Domain contains invalid tld character', { tlds: false }]
];
for (let i = 0; i < tests.length; ++i) {
const email = tests[i];
const output = Address.email.analyze(email[0], email[2]);
const result = email[1];
if (!output ||
output.error !== result) {
console.log(i, email[0]);
}
expect(output.error).to.equal(result);
}
});
it('validates options', () => {
const tests = [
['test@example.com', 'Invalid options: tlds must be a boolean or an object', { tlds: 1 }],
['test@example.com', 'Invalid options: tlds.allow must be a Set object or true', { tlds: { allow: ['test'] } }],
['test@example.com', 'Invalid options: tlds.deny must be a Set object', { tlds: { deny: ['test'] } }],
['test@example.com', 'Invalid options: cannot specify both tlds.allow and tlds.deny lists', { tlds: { allow: new Set(), deny: new Set() } }],
[1, 'Invalid input: email must be a string']
];
for (let i = 0; i < tests.length; ++i) {
const email = tests[i];
expect(() => Address.email.analyze(email[0], email[2])).to.throw(email[1]);
}
});
describe('validated TLD', () => {
it('applies built-in list', () => {
expect(Address.email.analyze('test@example.com')).to.not.exist();
expect(Address.email.analyze('test@example.com', { tlds: true })).to.not.exist();
expect(Address.email.analyze('test@example.com', { tlds: { allow: true } })).to.not.exist();
});
it('ignores built-in list', () => {
expect(Address.email.analyze('test@example.invalid-top', { tlds: false })).to.not.exist();
});
it('denies listed tls', () => {
expect(Address.email.analyze('test@example.com', { tlds: { deny: new Set(['test']) } })).to.not.exist();
expect(Address.email.analyze('test@example.com', { tlds: { deny: new Set(['com']) } })).to.equal({ error: 'Domain uses forbidden TLD' });
});
});
});
describe('isValid()', () => {
it('validates email', () => {
// Tests adapted from https://github.com/skeggse/isemail
// Copyright (c) 2008-2019, Eli Skeggs, Dominic Sayers, GlobeSherpa
const tests = [
['\r', false],
['test', false],
['@', false],
['test@', false],
['test@io', false],
['test@io', true, { minDomainSegments: 1 }],
['@io', false],
['@iana.org', false],
['test@iana.org', true],
['test@nominet.org.uk', true],
['test@about.museum', true],
['a@iana.org', true],
['êjness@iana.org', true],
['ñoñó1234@iana.org', true],
['ñoñó1234@something.com', true],
['伊昭傑@郵件.商務', true, { tlds: { allow: new Set([Punycode.toASCII('商務')]) } }],
['\ud801\udc37\ud852\udf62@iana.org', true],
['test.test@iana.org', true],
['.test@iana.org', false],
['test.@iana.org', false],
['test..iana.org', false],
['test_exa-mple.com', false],
['!#$%&`*+/=?^`{|}~@iana.org', true],
['test\\@test@iana.org', false],
['123@iana.org', true],
['test@123.com', true],
['test@iana.123', false],
['test@255.255.255.255', false],
['abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghiklm@iana.org', true],
['abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghiklmn@iana.org', false],
['\ud83d\ude06\ud83d\ude06\ud83d\ude06\ud83d\ude06\ud83d\ude06\ud83d\ude06\ud83d\ude06\ud83d\ude06\ud83d\ude06\ud83d\ude06\ud83d\ude06\ud83d\ude06\ud83d\ude06\ud83d\ude06\ud83d\ude06\ud83d\ude06\ud83d\ude06@iana.org', false],
['test@abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghiklm', false],
['test@\ud83d\ude06\ud83d\ude06\ud83d\ude06\ud83d\ude06\ud83d\ude06\ud83d\ude06\ud83d\ude06\ud83d\ude06\ud83d\ude06\ud83d\ude06\ud83d\ude06\ud83d\ude06\ud83d\ude06\ud83d\ude06\ud83d\ude06\ud83d\ude06\ud83d\ude06.org', true],
['test@abcdefghijklmnopqrstuvwxyzabcdefghijklmno\ud83d\ude06\ud83d\ude06\ud83d\ude06\ud83d\ude06\ud83d\ude06\ud83d\ude06\ud83d\ude06\ud83d\ude06\ud83d\ude06\ud83d\ude06\ud83d\ude06\ud83d\ude06\ud83d\ude06\ud83d\ude06\ud83d\ude06\ud83d\ude06\ud83d\ude06.org', false],
['test@abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghiklm.com', false],
['test@mason-dixon.com', true],
['test@-iana.org', false],
['test@iana-.com', false],
['test@.iana.org', false],
['test@iana.org.', false],
['test@iana..com', false],
['abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghiklm@abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefg.abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefg.abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefg.abcdefghijklmno', false],
['abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghiklm@abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefg.abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefg.abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefg.\ud83d\ude06\ud83d\ude06\ud83d\ude06\ud83d\ude06', false],
['abcdef@abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefg.abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefg.abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefg.abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdef.hijklmnopqrstuv', false],
['abcdef@abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefg.abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefg.abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefg.abcdefghi.abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcd\ud83d\ude06', false],
['abcdef@abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefg.abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefg.abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefg.abcdefghi.abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz\ud83d\ude06', false],
['a@abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefg.abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefg.abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefg.abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefg.abcdefghijkl.hijk', false],
['a@abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefg.abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefg.abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefg.abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefg.abcdefghijkl.\ud83d\ude06', false],
['\"\r', false],
['\"test\"@iana.org', false],
['\"\"@iana.org', false],
['\"\"\"@iana.org', false],
['\"\\a\"@iana.org', false],
['\"\\\"\"@iana.org', false],
['\"\\\"@iana.org', false],
['\"\\\\\"@iana.org', false],
['test\"@iana.org', false],
['\"test@iana.org', false],
['\"test\"test@iana.org', false],
['test\"text\"@iana.org', false],
['\"test\"\"test\"@iana.org', false],
['\"test\".\"test\"@iana.org', false],
['\"test\\ test\"@iana.org', false],
['\"test\".test@iana.org', false],
['\"test\u0000\"@iana.org', false],
['\"test\\\u0000\"@iana.org', false],
['\"test\r\n test\"@iana.org', false],
['\"abcdefghijklmnopqrstuvwxyz abcdefghijklmnopqrstuvwxyz abcdefghj\"@iana.org', false],
['\"abcdefghijklmnopqrstuvwxyz abcdefghijklmnopqrstuvwxyz abcdefg\\h\"@iana.org', false],
['test@[255.255.255.255]', false],
['test@a[255.255.255.255]', false],
['test@[255.255.255]', false],
['test@[255.255.255.255.255]', false],
['test@[255.255.255.256]', false],
['test@[1111:2222:3333:4444:5555:6666:7777:8888]', false],
['test@[IPv6:1111:2222:3333:4444:5555:6666:7777]', false],
['test@[IPv6:1111:2222:3333:4444:5555:6666:7777:8888]', false],
['test@[IPv6:1111:2222:3333:4444:5555:6666:7777:8888:9999]', false],
['test@[IPv6:1111:2222:3333:4444:5555:6666:7777:888G]', false],
['test@[IPv6:1111:2222:3333:4444:5555:6666::8888]', false],
['test@[IPv6:1111:2222:3333:4444:5555::8888]', false],
['test@[IPv6:1111:2222:3333:4444:5555:6666::7777:8888]', false],
['test@[IPv6::3333:4444:5555:6666:7777:8888]', false],
['test@[IPv6:::3333:4444:5555:6666:7777:8888]', false],
['test@[IPv6:1111::4444:5555::8888]', false],
['test@[IPv6:::]', false],
['test@[IPv6:1111:2222:3333:4444:5555:255.255.255.255]', false],
['test@[IPv6:1111:2222:3333:4444:5555:6666:255.255.255.255]', false],
['test@[IPv6:1111:2222:3333:4444:5555:6666:7777:255.255.255.255]', false],
['test@[IPv6:1111:2222:3333:4444::255.255.255.255]', false],
['test@[IPv6:1111:2222:3333:4444:5555:6666::255.255.255.255]', false],
['test@[IPv6:1111:2222:3333:4444:::255.255.255.255]', false],
['test@[IPv6::255.255.255.255]', false],
['test@[255.255.255.255].local', false],
['test@local.[255.255.255.255]', false],
['test@local.[255.255.255.255].local', false],
['test@local.(comment)[255.255.255.255].local', false],
['test@local. [255.255.255.255].local', false],
['test@local.[255.255.255.255](comment).local', false],
['test@local.[255.255.255.255] .local', false],
[' test @iana.org', false],
['test@ iana .com', false],
['test . test@iana.org', false],
['\r\n test@iana.org', false],
['\r\n \r\n test@iana.org', false],
['(\r', false],
['(comment)test@iana.org', false],
['((comment)test@iana.org', false],
['(comment(comment))test@iana.org', false],
['test@(comment)iana.org', false],
['test(comment)@iana.org', false],
['test(comment)test@iana.org', false],
['test@(comment)[255.255.255.255]', false],
['(comment)abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghiklm@iana.org', false],
['test@(comment)abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefg.com', false],
['(comment)test@abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefg.abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefg.abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefg.abcdefghijklmnopqrstuvwxyzabcdefghijk.abcdefghijklmnopqrst', false],
['test@iana.org\n', false],
['xn--test@iana.org', true],
['test@iana.org-', false],
['\"test@iana.org', false],
['(test@iana.org', false],
['test@(iana.org', false],
['test@[1.2.3.4', false],
['\"test\\\"@iana.org', false],
['(comment\\)test@iana.org', false],
['test@iana.org(comment\\)', false],
['test@iana.org(comment\\', false],
['test@[RFC-5322-domain-literal]', false],
['test@[RFC-5322-郵件ñó-domain-literal]', false],
['test@[RFC-5322]-domain-literal]', false],
['test@[RFC-5322].domain-literal]', false],
['test@[RFC-5322-[domain-literal]', false],
['test@[€', false],
['test@[\u0007]', false],
['test@[RFC-5322-\\\u0007-domain-literal]', false],
['test@[RFC-5322-\\\t-domain-literal]', false],
['test@[RFC-5322-\\]-domain-literal]', false],
['test@[RFC-5322-\\郵-no-domain-literal]', false],
['test@[RFC-5322--domain-literal]', false],
['test@[RFC-5322-domain-literal\\]', false],
['test@[RFC-5322-domain-literal\\', false],
['test@[RFC 5322 domain literal]', false],
['test@[RFC-5322-domain-literal] (comment)', false],
['@iana.org', false],
['test@.org', false],
['\"\"@iana.org', false],
['\"€\"@iana.org', false],
['\"\\\"@iana.org', false],
['()test@iana.org', false],
['(€)test@iana.org', false],
['test@iana.org\r', false],
['\rtest@iana.org', false],
['\"\rtest\"@iana.org', false],
['(\r)test@iana.org', false],
['test@iana.org(\r)', false],
['test@<iana>.org', false],
['\ntest@iana.org', false],
['\"\n\"@iana.org', false],
['\"\\\n\"@iana.org', false],
['(\n)test@iana.org', false],
['\u0007@iana.org', false],
['test@\u0007.org', false],
['\"\u0007\"@iana.org', false],
['\"\\\u0007\"@iana.org', false],
['(\u0007)test@iana.org', false],
['\r\ntest@iana.org', false],
['\r\n \r\ntest@iana.org', false],
[' \r\ntest@iana.org', false],
[' \r\n test@iana.org', false],
[' \r\n \r\ntest@iana.org', false],
[' \r\n\r\ntest@iana.org', false],
[' \r\n\r\n test@iana.org', false],
['test@iana.org\r\n ', false],
['test@iana.org\r\n \r\n ', false],
['test@iana.org\r\n', false],
['test@iana.org \r', false],
['test@iana.org\r\n \r\n', false],
['test@iana.org \r\n', false],
['test@iana.org \r\n ', false],
['test@iana.org \r\n \r\n', false],
['test@iana.org \r\n\r\n', false],
['test@iana.org \r\n\r\n ', false],
['test@iana. org', false],
['test@[\r', false],
['test@[\r\n', false],
[' test@iana.org', false],
['test@iana.org ', false],
['test@[IPv6:1::2:]', false],
['\"test\\\u0094\"@iana.org', false],
['test@iana/icann.org', false],
['test@iana!icann.org', false],
['test@iana?icann.org', false],
['test@iana^icann.org', false],
['test@iana{icann}.org', false],
['test.(comment)test@iana.org', false],
['test@iana.(comment)org', false],
['test@iana(comment)iana.org', false],
['(comment\r\n comment)test@iana.org', false],
['test@org', true, { minDomainSegments: 1 }],
['test\ud800@invalid', false],
['\"\ud800\"@invalid', false],
['\"\\\ud800\"@invalid', false],
['(\ud800)thing@invalid', false],
['\"\\\ud800\"@invalid', false],
['test@\ud800\udfffñoñó郵件ñoñó郵件.郵件ñoñó郵件ñoñó郵件.ñoñó郵件ñoñó郵件.ñoñó郵件ñoñó郵件.ñoñó郵件ñoñó郵件.ñoñó郵件ñoñó郵件.ñoñó郵件ñoñó郵件.noñó郵件ñoñó郵.商務', false, { tlds: { allow: new Set([Punycode.toASCII('商務')]) } }],
['test@\ud800\udfffñoñó郵件ñoñó郵件.郵件ñoñó郵件ñoñó郵件.ñoñó郵件ñoñó郵件ñoñó郵件.ñoñó郵件ñoñó郵件.ñoñó郵件ñoñó郵件.ñoñó郵件ñoñó郵件.ñoñó郵件ñoñó郵件.ñoñó郵件ñoñó郵件.oñó郵件ñoñó郵件ñoñó郵件.商務', false, { tlds: { allow: new Set([Punycode.toASCII('商務')]) } }],
['test@ñoñoñó郵件\ud83d\ude06ñoñ.oñó郵件\uc138ñoñ.oñó郵件\u0644\u4eec\u010dñoñoñó郵件\u05dcño.ñoñó郵件\u092f\u672cñoñoñó郵件\uc138añoñ.oñó郵件\ud83d\ude06bc\uc138郵\ud83d\ude06ño.ñoñó郵件ñoñoñó郵件\ud83d\ude06ñoñoñó郵件\uc138ñoñ.oñó郵件\u0644\u4eecñoñoñó.郵件\ud83d\ude06ñoñoñó郵件郵\uc138ñoñoñó郵件\u0644\u4eecñoñoñó郵件.\ud83d\ude06ñoñoñó郵件郵\uc138\u0644\u4eec.郵件\ud83d\ude06ñoñoñó郵.件郵\uc138\u4eec\ud83d\ude06ñoñoñó件郵\uc138ñoñoñó郵件', false, { tlds: { allow: new Set([Punycode.toASCII('商務')]) } }],
['test@ñoñó郵件ñoñó郵件ñoñó郵件ñoñoñó郵件ñoñó郵件ñoñó郵件ñoñó郵件ñoñó郵件ñoñó郵件ñoñó郵件ñoñó郵件ñoñó郵件ñoñó郵件ñoñó郵件ñoñó郵件ñoñó郵件ñoñó郵件ñoñó郵件ñoñó郵件ñoñó郵件ñoñó郵件ñoñó郵件ñoñó郵件ñoñó郵件ñoñó郵件ñoñó郵件ñoñó郵件ñoñó郵件ñoñó郵件ñoñó郵件ñoñó郵件ñoñó郵件ñoñó郵件ñoñó郵件ñoñó郵件ñoñó郵件ñoñó郵件ñoñó郵件ñoñó郵件ñoñó郵件ñoñó郵件ñoñó郵件ñoñó郵件.商務', false, { tlds: { allow: new Set([Punycode.toASCII('商務')]) } }],
['\ud83d\ude06ñoñó郵件ñoñó郵件ñoñó\ud83d\ude06郵件ñoñoñó郵@\ud83d\ude06郵件ñoñó郵件ñoñó.\ud83d\ude06郵件ñoñó郵件ñoñó.\ud83d\ude06郵件ñoñó郵件ñoñó.郵件ñoñó郵件ñoñó\ud83d\ude06.郵件ñoñó郵件ñoñó.郵件ñoñó郵件.ñoñó郵件ñoñó.郵件ñoñó郵件.\ud83d\ude06郵件ñoñó郵件ñoñó.\ud83d\ude06郵件ñoñó郵件ñoñó.\ud83d\ude06商務.郵件ñoñó郵件ñoñó郵件.\ud83d\ude06商務.\ud83d\ude06商務.\ud83d\ude06商務', false, { tlds: { allow: new Set([Punycode.toASCII('商務')]) } }],
['test@[\0', false],
['(\0)test@example.com', false],
['shouldbe@invalid', false],
['shouldbe@INVALID', false],
['shouldbe@example.com', true],
['shouldbe@example.COM', true],
['apple-touch-icon-60x60@2x.png', false],
['shouldbe@XN--UNUP4Y', true, { minDomainSegments: 1 }],
['shouldbe@xn--unup4y', true, { minDomainSegments: 1 }],
['shouldbe@\u6e38\u620f', true, { minDomainSegments: 1 }],
['æøå', false],
['1234567890abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw@xyz.com', true, { ignoreLength: true }],
['test@example.com@example.com', false],
['test@example.com/path', false],
['test@example.com:123', false]
];
for (let i = 0; i < tests.length; ++i) {
const email = tests[i];
const valid = Address.email.isValid(email[0], email[2]);
const result = email[1];
if (valid !== result) {
const outcome = Address.email.analyze(email[0], email[2]);
if (outcome) {
console.log(i, email[0], outcome.error);
}
else {
console.log(i, email[0]);
}
}
expect(valid).to.equal(result);
}
});
});
});
describe('domain', () => {
it('available as direct require', () => {
expect(require('../lib/domain').isValid('example.com')).to.be.true();
});
describe('analyze()', () => {
it('identifies error', () => {
const tests = [
['', 'Domain must be a non-empty string'],
['êiana.org', 'Domain contains forbidden Unicode characters', { allowUnicode: false }],
['abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz.com', 'Domain too long'],
['com', 'Domain lacks the minimum required number of segments'],
['x.no-such-tld', 'Domain uses forbidden TLD'],
['example..com', 'Domain contains empty dot-separated segment'],
['1234567890123456789012345678901234567890123456789012345678901234567890.com', 'Domain contains dot-separated segment that is too long'],
['example+.com', 'Domain contains invalid character', { tlds: false }],
['example.com_', 'Domain contains invalid tld character', { tlds: false }]
];
for (let i = 0; i < tests.length; ++i) {
const domain = tests[i];
const output = Address.domain.analyze(domain[0], domain[2]);
const result = domain[1];
if (!output ||
output.error !== result) {
console.log(i, domain[0]);
}
expect(output.error).to.equal(result);
}
});
it('validates options', () => {
const tests = [
['example.com', 'Invalid options: tlds must be a boolean or an object', { tlds: 1 }],
['example.com', 'Invalid options: tlds.allow must be a Set object or true', { tlds: { allow: ['test'] } }],
['example.com', 'Invalid options: tlds.deny must be a Set object', { tlds: { deny: ['test'] } }],
['example.com', 'Invalid options: cannot specify both tlds.allow and tlds.deny lists', { tlds: { allow: new Set(), deny: new Set() } }],
[1, 'Invalid input: domain must be a string']
];
for (let i = 0; i < tests.length; ++i) {
const domain = tests[i];
expect(() => Address.domain.analyze(domain[0], domain[2])).to.throw(domain[1]);
}
});
});
describe('isValid()', () => {
it('validates domain', () => {
const tests = [
['\r', false],
['test', false],
['@', false],
['iana.org', true],
['nominet.org.uk', true],
['about.museum', true],
['x.商務', true, { tlds: { allow: new Set([Punycode.toASCII('商務')]) } }],
['iana.123', false],
['255.255.255.255', false],
['XN--UNUP4Y', true, { minDomainSegments: 1 }],
['test@example.com', false],
['test:example.com', false],
['example.com:123', false],
['example.com/path', false]
];
for (let i = 0; i < tests.length; ++i) {
const domain = tests[i];
const valid = Address.domain.isValid(domain[0], domain[2]);
const result = domain[1];
if (valid !== result) {
const outcome = Address.domain.analyze(domain[0], domain[2]);
if (outcome) {
console.log(i, domain[0], outcome.error);
}
else {
console.log(i, domain[0]);
}
}
expect(valid).to.equal(result);
}
});
});
});