[6a3a178] | 1 | # psl (Public Suffix List)
|
---|
| 2 |
|
---|
| 3 | [![NPM](https://nodei.co/npm/psl.png?downloads=true&downloadRank=true)](https://nodei.co/npm/psl/)
|
---|
| 4 |
|
---|
| 5 | [![Greenkeeper badge](https://badges.greenkeeper.io/lupomontero/psl.svg)](https://greenkeeper.io/)
|
---|
| 6 | [![Build Status](https://travis-ci.org/lupomontero/psl.svg?branch=master)](https://travis-ci.org/lupomontero/psl)
|
---|
| 7 | [![devDependency Status](https://david-dm.org/lupomontero/psl/dev-status.png)](https://david-dm.org/lupomontero/psl#info=devDependencies)
|
---|
| 8 |
|
---|
| 9 | `psl` is a `JavaScript` domain name parser based on the
|
---|
| 10 | [Public Suffix List](https://publicsuffix.org/).
|
---|
| 11 |
|
---|
| 12 | This implementation is tested against the
|
---|
| 13 | [test data hosted by Mozilla](http://mxr.mozilla.org/mozilla-central/source/netwerk/test/unit/data/test_psl.txt?raw=1)
|
---|
| 14 | and kindly provided by [Comodo](https://www.comodo.com/).
|
---|
| 15 |
|
---|
| 16 | Cross browser testing provided by
|
---|
| 17 | [<img alt="BrowserStack" width="160" src="./browserstack-logo.svg" />](https://www.browserstack.com/)
|
---|
| 18 |
|
---|
| 19 | ## What is the Public Suffix List?
|
---|
| 20 |
|
---|
| 21 | The Public Suffix List is a cross-vendor initiative to provide an accurate list
|
---|
| 22 | of domain name suffixes.
|
---|
| 23 |
|
---|
| 24 | The Public Suffix List is an initiative of the Mozilla Project, but is
|
---|
| 25 | maintained as a community resource. It is available for use in any software,
|
---|
| 26 | but was originally created to meet the needs of browser manufacturers.
|
---|
| 27 |
|
---|
| 28 | A "public suffix" is one under which Internet users can directly register names.
|
---|
| 29 | Some examples of public suffixes are ".com", ".co.uk" and "pvt.k12.wy.us". The
|
---|
| 30 | Public Suffix List is a list of all known public suffixes.
|
---|
| 31 |
|
---|
| 32 | Source: http://publicsuffix.org
|
---|
| 33 |
|
---|
| 34 |
|
---|
| 35 | ## Installation
|
---|
| 36 |
|
---|
| 37 | ### Node.js
|
---|
| 38 |
|
---|
| 39 | ```sh
|
---|
| 40 | npm install --save psl
|
---|
| 41 | ```
|
---|
| 42 |
|
---|
| 43 | ### Browser
|
---|
| 44 |
|
---|
| 45 | Download [psl.min.js](https://raw.githubusercontent.com/lupomontero/psl/master/dist/psl.min.js)
|
---|
| 46 | and include it in a script tag.
|
---|
| 47 |
|
---|
| 48 | ```html
|
---|
| 49 | <script src="psl.min.js"></script>
|
---|
| 50 | ```
|
---|
| 51 |
|
---|
| 52 | This script is browserified and wrapped in a [umd](https://github.com/umdjs/umd)
|
---|
| 53 | wrapper so you should be able to use it standalone or together with a module
|
---|
| 54 | loader.
|
---|
| 55 |
|
---|
| 56 | ## API
|
---|
| 57 |
|
---|
| 58 | ### `psl.parse(domain)`
|
---|
| 59 |
|
---|
| 60 | Parse domain based on Public Suffix List. Returns an `Object` with the following
|
---|
| 61 | properties:
|
---|
| 62 |
|
---|
| 63 | * `tld`: Top level domain (this is the _public suffix_).
|
---|
| 64 | * `sld`: Second level domain (the first private part of the domain name).
|
---|
| 65 | * `domain`: The domain name is the `sld` + `tld`.
|
---|
| 66 | * `subdomain`: Optional parts left of the domain.
|
---|
| 67 |
|
---|
| 68 | #### Example:
|
---|
| 69 |
|
---|
| 70 | ```js
|
---|
| 71 | var psl = require('psl');
|
---|
| 72 |
|
---|
| 73 | // Parse domain without subdomain
|
---|
| 74 | var parsed = psl.parse('google.com');
|
---|
| 75 | console.log(parsed.tld); // 'com'
|
---|
| 76 | console.log(parsed.sld); // 'google'
|
---|
| 77 | console.log(parsed.domain); // 'google.com'
|
---|
| 78 | console.log(parsed.subdomain); // null
|
---|
| 79 |
|
---|
| 80 | // Parse domain with subdomain
|
---|
| 81 | var parsed = psl.parse('www.google.com');
|
---|
| 82 | console.log(parsed.tld); // 'com'
|
---|
| 83 | console.log(parsed.sld); // 'google'
|
---|
| 84 | console.log(parsed.domain); // 'google.com'
|
---|
| 85 | console.log(parsed.subdomain); // 'www'
|
---|
| 86 |
|
---|
| 87 | // Parse domain with nested subdomains
|
---|
| 88 | var parsed = psl.parse('a.b.c.d.foo.com');
|
---|
| 89 | console.log(parsed.tld); // 'com'
|
---|
| 90 | console.log(parsed.sld); // 'foo'
|
---|
| 91 | console.log(parsed.domain); // 'foo.com'
|
---|
| 92 | console.log(parsed.subdomain); // 'a.b.c.d'
|
---|
| 93 | ```
|
---|
| 94 |
|
---|
| 95 | ### `psl.get(domain)`
|
---|
| 96 |
|
---|
| 97 | Get domain name, `sld` + `tld`. Returns `null` if not valid.
|
---|
| 98 |
|
---|
| 99 | #### Example:
|
---|
| 100 |
|
---|
| 101 | ```js
|
---|
| 102 | var psl = require('psl');
|
---|
| 103 |
|
---|
| 104 | // null input.
|
---|
| 105 | psl.get(null); // null
|
---|
| 106 |
|
---|
| 107 | // Mixed case.
|
---|
| 108 | psl.get('COM'); // null
|
---|
| 109 | psl.get('example.COM'); // 'example.com'
|
---|
| 110 | psl.get('WwW.example.COM'); // 'example.com'
|
---|
| 111 |
|
---|
| 112 | // Unlisted TLD.
|
---|
| 113 | psl.get('example'); // null
|
---|
| 114 | psl.get('example.example'); // 'example.example'
|
---|
| 115 | psl.get('b.example.example'); // 'example.example'
|
---|
| 116 | psl.get('a.b.example.example'); // 'example.example'
|
---|
| 117 |
|
---|
| 118 | // TLD with only 1 rule.
|
---|
| 119 | psl.get('biz'); // null
|
---|
| 120 | psl.get('domain.biz'); // 'domain.biz'
|
---|
| 121 | psl.get('b.domain.biz'); // 'domain.biz'
|
---|
| 122 | psl.get('a.b.domain.biz'); // 'domain.biz'
|
---|
| 123 |
|
---|
| 124 | // TLD with some 2-level rules.
|
---|
| 125 | psl.get('uk.com'); // null);
|
---|
| 126 | psl.get('example.uk.com'); // 'example.uk.com');
|
---|
| 127 | psl.get('b.example.uk.com'); // 'example.uk.com');
|
---|
| 128 |
|
---|
| 129 | // More complex TLD.
|
---|
| 130 | psl.get('c.kobe.jp'); // null
|
---|
| 131 | psl.get('b.c.kobe.jp'); // 'b.c.kobe.jp'
|
---|
| 132 | psl.get('a.b.c.kobe.jp'); // 'b.c.kobe.jp'
|
---|
| 133 | psl.get('city.kobe.jp'); // 'city.kobe.jp'
|
---|
| 134 | psl.get('www.city.kobe.jp'); // 'city.kobe.jp'
|
---|
| 135 |
|
---|
| 136 | // IDN labels.
|
---|
| 137 | psl.get('食狮.com.cn'); // '食狮.com.cn'
|
---|
| 138 | psl.get('食狮.公司.cn'); // '食狮.公司.cn'
|
---|
| 139 | psl.get('www.食狮.公司.cn'); // '食狮.公司.cn'
|
---|
| 140 |
|
---|
| 141 | // Same as above, but punycoded.
|
---|
| 142 | psl.get('xn--85x722f.com.cn'); // 'xn--85x722f.com.cn'
|
---|
| 143 | psl.get('xn--85x722f.xn--55qx5d.cn'); // 'xn--85x722f.xn--55qx5d.cn'
|
---|
| 144 | psl.get('www.xn--85x722f.xn--55qx5d.cn'); // 'xn--85x722f.xn--55qx5d.cn'
|
---|
| 145 | ```
|
---|
| 146 |
|
---|
| 147 | ### `psl.isValid(domain)`
|
---|
| 148 |
|
---|
| 149 | Check whether a domain has a valid Public Suffix. Returns a `Boolean` indicating
|
---|
| 150 | whether the domain has a valid Public Suffix.
|
---|
| 151 |
|
---|
| 152 | #### Example
|
---|
| 153 |
|
---|
| 154 | ```js
|
---|
| 155 | var psl = require('psl');
|
---|
| 156 |
|
---|
| 157 | psl.isValid('google.com'); // true
|
---|
| 158 | psl.isValid('www.google.com'); // true
|
---|
| 159 | psl.isValid('x.yz'); // false
|
---|
| 160 | ```
|
---|
| 161 |
|
---|
| 162 |
|
---|
| 163 | ## Testing and Building
|
---|
| 164 |
|
---|
| 165 | Test are written using [`mocha`](https://mochajs.org/) and can be
|
---|
| 166 | run in two different environments: `node` and `phantomjs`.
|
---|
| 167 |
|
---|
| 168 | ```sh
|
---|
| 169 | # This will run `eslint`, `mocha` and `karma`.
|
---|
| 170 | npm test
|
---|
| 171 |
|
---|
| 172 | # Individual test environments
|
---|
| 173 | # Run tests in node only.
|
---|
| 174 | ./node_modules/.bin/mocha test
|
---|
| 175 | # Run tests in phantomjs only.
|
---|
| 176 | ./node_modules/.bin/karma start ./karma.conf.js --single-run
|
---|
| 177 |
|
---|
| 178 | # Build data (parse raw list) and create dist files
|
---|
| 179 | npm run build
|
---|
| 180 | ```
|
---|
| 181 |
|
---|
| 182 | Feel free to fork if you see possible improvements!
|
---|
| 183 |
|
---|
| 184 |
|
---|
| 185 | ## Acknowledgements
|
---|
| 186 |
|
---|
| 187 | * Mozilla Foundation's [Public Suffix List](https://publicsuffix.org/)
|
---|
| 188 | * Thanks to Rob Stradling of [Comodo](https://www.comodo.com/) for providing
|
---|
| 189 | test data.
|
---|
| 190 | * Inspired by [weppos/publicsuffix-ruby](https://github.com/weppos/publicsuffix-ruby)
|
---|
| 191 |
|
---|
| 192 |
|
---|
| 193 | ## License
|
---|
| 194 |
|
---|
| 195 | The MIT License (MIT)
|
---|
| 196 |
|
---|
| 197 | Copyright (c) 2017 Lupo Montero <lupomontero@gmail.com>
|
---|
| 198 |
|
---|
| 199 | Permission is hereby granted, free of charge, to any person obtaining a copy
|
---|
| 200 | of this software and associated documentation files (the "Software"), to deal
|
---|
| 201 | in the Software without restriction, including without limitation the rights
|
---|
| 202 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
---|
| 203 | copies of the Software, and to permit persons to whom the Software is
|
---|
| 204 | furnished to do so, subject to the following conditions:
|
---|
| 205 |
|
---|
| 206 | The above copyright notice and this permission notice shall be included in
|
---|
| 207 | all copies or substantial portions of the Software.
|
---|
| 208 |
|
---|
| 209 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
---|
| 210 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
---|
| 211 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
---|
| 212 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
---|
| 213 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
---|
| 214 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
---|
| 215 | THE SOFTWARE.
|
---|