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