README.md
  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.