Giter Site home page Giter Site logo

peerigon / parse-domain Goto Github PK

View Code? Open in Web Editor NEW
494.0 15.0 68.0 1.99 MB

Splits a hostname into subdomains, domain and (effective) top-level domains.

License: MIT License

JavaScript 1.30% TypeScript 98.63% Shell 0.07%
javascript parse domain tld url publicsuffix typescript

parse-domain's Introduction

parse-domain

Splits a hostname into subdomains, domain and (effective) top-level domains.

Version on NPM Semantically released Monthly downloads on NPM
NPM Bundle size minified NPM Bundle size minified and gzipped
License

Since domain name registrars organize their namespaces in different ways, it's not straight-forward to split a hostname into subdomains, the domain and top-level domains. In order to do that parse-domain uses a large list of known top-level domains from publicsuffix.org:

import { parseDomain, ParseResultType } from "parse-domain";

const parseResult = parseDomain(
  // This should be a string with basic latin letters only.
  // More information below.
  "www.some.example.co.uk"
);

// Check if the domain is listed in the public suffix list
if (parseResult.type === ParseResultType.Listed) {
  const { subDomains, domain, topLevelDomains } = parseResult;

  console.log(subDomains); // ["www", "some"]
  console.log(domain); // "example"
  console.log(topLevelDomains); // ["co", "uk"]
} else {
  // Read more about other parseResult types below...
}

This package has been designed for modern Node and browser environments with ECMAScript modules support. It assumes an ES2015 environment with Symbol(), URL() and TextDecoder() globally available. You need to transpile it down to ES5 (e.g. by using Babel) if you need to support older environments.

The list of top-level domains is stored in a trie data structure and serialization format to ensure the fastest lookup and the smallest possible library size.


Installation

npm install parse-domain

Updates

๐Ÿ’ก Please note: publicsuffix.org is updated several times per month. This package comes with a prebuilt list that has been downloaded at the time of npm publish. In order to get an up-to-date list, you should run npx parse-domain-update everytime you start or build your application. This will download the latest list from https://publicsuffix.org/list/public_suffix_list.dat.


Expected input

โš ๏ธ parseDomain does not parse whole URLs. You should only pass the puny-encoded hostname section of the URL:

โŒ Wrong โœ… Correct
https://[email protected]:8080/path?query www.example.com
mรผnchen.de xn--mnchen-3ya.de
้ฃŸ็‹ฎ.com.cn?query xn--85x722f.com.cn

There is the utility function fromUrl which tries to extract the hostname from a (partial) URL and puny-encodes it:

import { parseDomain, fromUrl } from "parse-domain";

const { subDomains, domain, topLevelDomains } = parseDomain(
  fromUrl("https://www.mรผnchen.de?query")
);

console.log(subDomains); // ["www"]
console.log(domain); // "xn--mnchen-3ya"
console.log(topLevelDomains); // ["de"]

// You can use the 'punycode' NPM package to decode the domain again
import { toUnicode } from "punycode";

console.log(toUnicode(domain)); // "mรผnchen"

fromUrl parses the URL using new URL(). Depending on your target environments you need to make sure that there is a polyfill for it. It's globally available in all modern browsers (no IE) and in Node v10.

Expected output

When parsing a hostname there are 5 possible results:

  • invalid
  • it is an ip address
  • it is formally correct and the domain is
    • reserved
    • not listed in the public suffix list
    • listed in the public suffix list

parseDomain returns a ParseResult with a type property that allows to distinguish these cases.

๐Ÿ‘‰ Invalid domains

The given input is first validated against RFC 3696 (the domain labels are limited to basic latin letters, numbers and hyphens). If the validation fails, parseResult.type will be ParseResultType.Invalid:

import { parseDomain, ParseResultType } from "parse-domain";

const parseResult = parseDomain("mรผnchen.de");

console.log(parseResult.type === ParseResultType.Invalid); // true

Check out the API if you need more information about the validation error.

If you don't want the characters to be validated (e.g. because you need to allow underscores in hostnames), there's also a more relaxed validation mode (according to RFC 2181).

import { parseDomain, ParseResultType, Validation } from "parse-domain";

const parseResult = parseDomain("_jabber._tcp.gmail.com", {
  validation: Validation.Lax,
});

console.log(parseResult.type === ParseResultType.Listed); // true

See also #134 for the discussion.

๐Ÿ‘‰ IP addresses

If the given input is an IP address, parseResult.type will be ParseResultType.Ip:

import { parseDomain, ParseResultType } from "parse-domain";

const parseResult = parseDomain("192.168.2.1");

console.log(parseResult.type === ParseResultType.Ip); // true
console.log(parseResult.ipVersion); // 4

It's debatable if a library for parsing domains should also accept IP addresses. In fact, you could argue that parseDomain should reject an IP address as invalid. While this is true from a technical point of view, we decided to report IP addresses in a special way because we assume that a lot of people are using this library to make sense from an arbitrary hostname (see #102).

๐Ÿ‘‰ Reserved domains

There are 5 top-level domains that are not listed in the public suffix list but reserved according to RFC 6761 and RFC 6762:

  • localhost
  • local
  • example
  • invalid
  • test

In these cases, parseResult.type will be ParseResultType.Reserved:

import { parseDomain, ParseResultType } from "parse-domain";

const parseResult = parseDomain("pecorino.local");

console.log(parseResult.type === ParseResultType.Reserved); // true
console.log(parseResult.labels); // ["pecorino", "local"]

๐Ÿ‘‰ Domains that are not listed

If the given hostname is valid, but not listed in the downloaded public suffix list, parseResult.type will be ParseResultType.NotListed:

import { parseDomain, ParseResultType } from "parse-domain";

const parseResult = parseDomain("this.is.not-listed");

console.log(parseResult.type === ParseResultType.NotListed); // true
console.log(parseResult.labels); // ["this", "is", "not-listed"]

If a domain is not listed, it can be caused by an outdated list. Make sure to update the list once in a while.

โš ๏ธ Do not treat parseDomain as authoritative answer. It cannot replace a real DNS lookup to validate if a given domain is known in a certain network.

๐Ÿ‘‰ Effective top-level domains

Technically, the term top-level domain describes the very last domain in a hostname (uk in example.co.uk). Most people, however, use the term top-level domain for the public suffix which is a namespace "under which Internet users can directly register names".

Some examples for public suffixes:

  • com in example.com
  • co.uk in example.co.uk
  • co in example.co
  • but also com.co in example.com.co

If the hostname is listed in the public suffix list, the parseResult.type will be ParseResultType.Listed:

import { parseDomain, ParseResultType } from "parse-domain";

const parseResult = parseDomain("example.co.uk");

console.log(parseResult.type === ParseResultType.Listed); // true
console.log(parseResult.labels); // ["example", "co", "uk"]

Now parseResult will also provide a subDomains, domain and topLevelDomains property:

const { subDomains, domain, topLevelDomains } = parseResult;

console.log(subDomains); // []
console.log(domain); // "example"
console.log(topLevelDomains); // ["co", "uk"]

๐Ÿ‘‰ Switch over parseResult.type to distinguish between different parse results

We recommend switching over the parseResult.type:

switch (parseResult.type) {
  case ParseResultType.Listed: {
    const { hostname, topLevelDomains } = parseResult;

    console.log(`${hostname} belongs to ${topLevelDomains.join(".")}`);
    break;
  }
  case ParseResultType.Reserved:
  case ParseResultType.NotListed: {
    const { hostname } = parseResult;

    console.log(`${hostname} is a reserved or unknown domain`);
    break;
  }
  default:
    throw new Error(`${hostname} is an ip address or invalid domain`);
}

โš ๏ธ Effective TLDs !== TLDs acknowledged by ICANN

What's surprising to a lot of people is that the definition of public suffix means that regular user domains can become effective top-level domains:

const { subDomains, domain, topLevelDomains } = parseDomain(
  "parse-domain.github.io"
);

console.log(subDomains); // []
console.log(domain); // "parse-domain"
console.log(topLevelDomains); // ["github", "io"] ๐Ÿคฏ

In this case, github.io is nothing else than a private domain name registrar. github.io is the effective top-level domain and browsers are treating it like that (e.g. for setting document.domain).

If you want to deviate from the browser's understanding of a top-level domain and you're only interested in top-level domains acknowledged by ICANN, there's an icann property:

const parseResult = parseDomain("parse-domain.github.io");
const { subDomains, domain, topLevelDomains } = parseResult.icann;

console.log(subDomains); // ["parse-domain"]
console.log(domain); // "github"
console.log(topLevelDomains); // ["io"]

โš ๏ธ domain can also be undefined

const { subDomains, domain, topLevelDomains } = parseDomain("co.uk");

console.log(subDomains); // []
console.log(domain); // undefined
console.log(topLevelDomains); // ["co", "uk"]

โš ๏ธ "" is a valid (but reserved) domain

The empty string "" represents the DNS root and is considered to be valid. parseResult.type will be ParseResultType.Reserved in that case:

const { type, subDomains, domain, topLevelDomains } = parseDomain("");

console.log(type === ParseResultType.Reserved); // true
console.log(subDomains); // []
console.log(domain); // undefined
console.log(topLevelDomains); // []

API

๐Ÿงฉ = JavaScript export
๐Ÿงฌ = TypeScript export

๐Ÿงฉ export parseDomain(hostname: string | typeof NO_HOSTNAME, options?: ParseDomainOptions): ParseResult

Takes a hostname (e.g. "www.example.com") and returns a ParseResult. The hostname must only contain basic latin letters, digits, hyphens and dots. International hostnames must be puny-encoded. Does not throw an error, even with invalid input.

import { parseDomain } from "parse-domain";

const parseResult = parseDomain("www.example.com");

Use Validation.Lax if you want to allow all characters:

import { parseDomain, Validation } from "parse-domain";

const parseResult = parseDomain("_jabber._tcp.gmail.com", {
  validation: Validation.Lax,
});

๐Ÿงฉ export fromUrl(input: string): string | typeof NO_HOSTNAME

Takes a URL-like string and tries to extract the hostname. Requires the global URL constructor to be available on the platform. Returns the NO_HOSTNAME symbol if the input was not a string or the hostname could not be extracted. Take a look at the test suite for some examples. Does not throw an error, even with invalid input.

๐Ÿงฉ export NO_HOSTNAME: unique symbol

NO_HOSTNAME is a symbol that is returned by fromUrl when it was not able to extract a hostname from the given string. When passed to parseDomain, it will always yield a ParseResultInvalid.

๐Ÿงฌ export type ParseDomainOptions

export type ParseDomainOptions = {
  /**
   * If no validation is specified, Validation.Strict will be used.
   **/
  validation?: Validation;
};

๐Ÿงฉ export Validation

An object that holds all possible Validation validation values:

export const Validation = {
  /**
   * Allows any octets as labels
   * but still restricts the length of labels and the overall domain.
   *
   * @see https://www.rfc-editor.org/rfc/rfc2181#section-11
   **/
  Lax: "LAX",

  /**
   * Only allows ASCII letters, digits and hyphens (aka LDH),
   * forbids hyphens at the beginning or end of a label
   * and requires top-level domain names not to be all-numeric.
   *
   * This is the default if no validation is configured.
   *
   * @see https://datatracker.ietf.org/doc/html/rfc3696#section-2
   */
  Strict: "STRICT",
};

๐Ÿงฌ export Validation

This type represents all possible validation values.

๐Ÿงฌ export ParseResult

A ParseResult is either a ParseResultInvalid, ParseResultIp, ParseResultReserved, ParseResultNotListed or ParseResultListed.

All parse results have a type property that is either "INVALID", "IP","RESERVED","NOT_LISTED"or"LISTED". Use the exported ParseResultType to check for the type instead of checking against string literals.

All parse results also have a hostname property that provides access to the sanitized hostname that was passed to parseDomain.

๐Ÿงฉ export ParseResultType

An object that holds all possible ParseResult type values:

const ParseResultType = {
  Invalid: "INVALID",
  Ip: "IP",
  Reserved: "RESERVED",
  NotListed: "NOT_LISTED",
  Listed: "LISTED",
};

๐Ÿงฌ export ParseResultType

This type represents all possible ParseResult type values.

๐Ÿงฌ export ParseResultInvalid

Describes the shape of the parse result that is returned when the given hostname does not adhere to RFC 1034:

  • The hostname is not a string
  • The hostname is longer than 253 characters
  • A domain label is shorter than 1 character
  • A domain label is longer than 63 characters
  • A domain label contains a character that is not a basic latin character, digit or hyphen
type ParseResultInvalid = {
  type: ParseResultType.INVALID;
  hostname: string | typeof NO_HOSTNAME;
  errors: Array<ValidationError>;
};

// Example

{
  type: "INVALID",
  hostname: ".com",
  errors: [...]
}

๐Ÿงฌ export ValidationError

Describes the shape of a validation error as returned by parseDomain

type ValidationError = {
  type: ValidationErrorType;
  message: string;
  column: number;
};

// Example

{
  type: "LABEL_MIN_LENGTH",
  message: `Label "" is too short. Label is 0 octets long but should be at least 1.`,
  column: 1,
}

๐Ÿงฉ export ValidationErrorType

An object that holds all possible ValidationError type values:

const ValidationErrorType = {
  NoHostname: "NO_HOSTNAME",
  DomainMaxLength: "DOMAIN_MAX_LENGTH",
  LabelMinLength: "LABEL_MIN_LENGTH",
  LabelMaxLength: "LABEL_MAX_LENGTH",
  LabelInvalidCharacter: "LABEL_INVALID_CHARACTER",
  LastLabelInvalid: "LAST_LABEL_INVALID",
};

๐Ÿงฌ export ValidationErrorType

This type represents all possible type values of a ValidationError.

๐Ÿงฌ export ParseResultIp

This type describes the shape of the parse result that is returned when the given hostname was an IPv4 or IPv6 address.

type ParseResultIp = {
  type: ParseResultType.Ip;
  hostname: string;
  ipVersion: 4 | 6;
};

// Example

{
  type: "IP",
  hostname: "192.168.0.1",
  ipVersion: 4
}

According to RFC 3986, IPv6 addresses need to be surrounded by [ and ] in URLs. parseDomain accepts both IPv6 address with and without square brackets:

// Recognized as IPv4 address
parseDomain("192.168.0.1");
// Both are recognized as proper IPv6 addresses
parseDomain("::");
parseDomain("[::]");

๐Ÿงฌ export ParseResultReserved

This type describes the shape of the parse result that is returned when the given hostname

  • is the root domain (the empty string "")
  • belongs to the top-level domain localhost, local, example, invalid or test
type ParseResultReserved = {
  type: ParseResultType.Reserved;
  hostname: string;
  labels: Array<string>;
};

// Example

{
  type: "RESERVED",
  hostname: "pecorino.local",
  labels: ["pecorino", "local"]
}

โš ๏ธ Reserved IPs, such as 127.0.0.1, will not be reported as reserved, but as ParseResultIp. See #117.

๐Ÿงฌ export ParseResultNotListed

Describes the shape of the parse result that is returned when the given hostname is valid and does not belong to a reserved top-level domain, but is not listed in the downloaded public suffix list.

type ParseResultNotListed = {
  type: ParseResultType.NotListed;
  hostname: string;
  labels: Array<string>;
};

// Example

{
  type: "NOT_LISTED",
  hostname: "this.is.not-listed",
  labels: ["this", "is", "not-listed"]
}

๐Ÿงฌ export ParseResultListed

Describes the shape of the parse result that is returned when the given hostname belongs to a top-level domain that is listed in the public suffix list.

type ParseResultListed = {
  type: ParseResultType.Listed;
  hostname: string;
  labels: Array<string>;
  subDomains: Array<string>;
  domain: string | undefined;
  topLevelDomains: Array<string>;
  icann: {
    subDomains: Array<string>;
    domain: string | undefined;
    topLevelDomains: Array<string>;
  };
};

// Example

{
  type: "LISTED",
  hostname: "parse-domain.github.io",
  labels: ["parse-domain", "github", "io"]
  subDomains: [],
  domain: "parse-domain",
  topLevelDomains: ["github", "io"],
  icann: {
    subDomains: ["parse-domain"],
    domain: "github",
    topLevelDomains: ["io"]
  }
}

License

MIT

Sponsors

parse-domain's People

Contributors

acidicx avatar adityapatadia avatar akost avatar alsotang avatar benshu avatar dependabot[bot] avatar dydeepak97 avatar hughns avatar igorfv avatar ivangoncharov avatar jhnns avatar jpstevens avatar kucukharf avatar mattlubner avatar meaku avatar mitsuruog avatar moritzjacobs avatar oiyouyeahyou avatar pvdlg avatar realdolos avatar selfish avatar semantic-release-bot avatar shahor avatar skarbovskiy avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

parse-domain's Issues

updatedAt timestamp breaks bundle caching

Every time I install the same version of this package the output changes because of the updatedAt timestamp changes. Unfortunately, this causes the contenthash to change in my webpack bundle so every time I deploy users have to re-download the whole bundle again.

Would it be possible to create some sort of hash of the results from the public suffix service instead of a timestamp? That way the built contents would be identical between installs until the suffixes change.

several parsing issues

While working with live squid logs and parsing i came across following issues:

ftp://mapasamazonsa.com.ve/ > null  ## maybe problem with ftp ?
http://y399.3466633.be:4/235222/399.html > null ## maybe problem with the port 4 ?
this%20file%20was% > crash with 'TypeError: Cannot read property '3' of null'

i wanted give you valid and should-be-working data.

node scripts/build-tries.js fails on Ubuntu 16.04.5 LTS (GNU/Linux 4.4.0-131-generic x86_64)

I receive this message trying to install parse-domain. I have installed the latest versions of node.js and npm.

[email protected] postinstall /usr/local/bin/auspice/node_modules/parse-domain
node scripts/build-tries.js

sh: 1: node: not found
npm WARN optional Skipping failed optional dependency /chokidar/fsevents:
npm WARN notsup Not compatible with your operating system or architecture: [email protected]
npm WARN optional Skipping failed optional dependency /watchpack/chokidar/fsevents:
npm WARN notsup Not compatible with your operating system or architecture: [email protected]
npm WARN [email protected] requires a peer of react@^15.4.2 but none was installed.
npm WARN [email protected] requires a peer of react@^16.0.0-0 < 16.4.0 but none was installed.
npm WARN [email protected] requires a peer of react-dom@^16.0.0-0 < 16.4.0 but none was installed.
npm WARN [email protected] No repository field.
npm WARN [email protected] license should be a valid SPDX license expression
npm ERR! Linux 4.4.0-131-generic
npm ERR! argv "/usr/bin/nodejs" "/usr/bin/npm" "install" "parse-domain"
npm ERR! node v4.2.6
npm ERR! npm v3.5.2
npm ERR! file sh
npm ERR! code ELIFECYCLE
npm ERR! errno ENOENT
npm ERR! syscall spawn

npm ERR! [email protected] postinstall: node scripts/build-tries.js
npm ERR! spawn ENOENT
npm ERR!
npm ERR! Failed at the [email protected] postinstall script 'node scripts/build-tries.js'.
npm ERR! Make sure you have the latest version of node.js and npm installed.
npm ERR! If you do, this is most likely a problem with the parse-domain package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR! node scripts/build-tries.js
npm ERR! You can get information on how to open an issue for this project with:
npm ERR! npm bugs parse-domain
npm ERR! Or if that isn't available, you can get their info via:
npm ERR! npm owner ls parse-domain
npm ERR! There is likely additional logging output above.

npm ERR! Please include the following file with any support request:
npm ERR! /usr/local/bin/auspice/npm-debug.log

Does not work on Internet explorer

Internet explorer does not allow const in for loops. As soon as I add

import parseDomain from 'parse-domain';
to the top of my file, my application no longer works in internet explorer (11). I get the following error:

SCRIPT1053: Const must be initialized

The problem looks like it is on this line:

for (const trie of tries) {

In fact, according to this, Internet Explorer doesn't even support the for..of syntax at all.

I can't be the only one having this issue?

parsing fonts.googleapis.com incorrect

parsing fonts.googleapis.com isn't work correctly. the subdomain should be fonts the domain should be googleapis and the tld should be com.
this is what I got while parsing the domain
{ tld: 'googleapis.com', domain: 'fonts', subdomain: '' }

Remove `jest` from dependencies

Is a testing framework really needed as a dependency or should it maybe have been in devDependencies? Noticed it because of these deprecations:

parse-domain > jest > jest-cli > @jest/core > jest-haste-map > [email protected]: One of your dependencies needs to upgrade to fsevents v2: 1) Proper nodejs v10+ support 2) No more fetching binaries from AWS, smaller package size
parse-domain > jest > jest-cli > jest-config > jest-environment-jsdom > jsdom > [email protected]: use String.prototype.padStart()

remove jest

Remove JEST from package dependencies, it should be in devDependencies - is unsafe and dangerous to install jest and all its dependencies in a production server - this package cannot be used in production.

Can't use parse-domain with uglifyjs?

It always popup "Unexpected token: keyword (const)" error.

function matchTld(domain, options) {
    // for potentially unrecognized tlds, try matching against custom tlds
    if (options.customTlds) {
        // try matching against a built regexp of custom tlds
        const tld = domain.match(options.customTlds);

        if (tld !== null) {
            return tld[0];
        }
    }

    const tries = (options.privateTlds ? [privateTrie] : emptyArr).concat(icannTrie);

    for (const trie of tries) {
        const tld = lookUp(trie, domain);

        if (tld !== null) {
            return "." + tld;
        }
    }

    return null;
}

The reason is that there are some ES6 keyword (such as 'const') and so on.

Support for .test domains

Currently, there is no support for .test domains. You can look at the following examples:

screen shot 2018-01-31 at 3 16 21 pm

It would be a good thing to add support for this since people use this during development.

Downloading public suffix list is is not deterministic.

Is there to any way please to not have the module download public suffix lists at install time and instead have it default to something that could be maintained in a config file or part of the package?

As it stands this module results in non-deterministic builds. With the same version, the library can have different behaviours depending on the content of the downloaded files.

Adding this feature would also help avoid issues such as #35 in the future.

Dependence on npm?

More of an FYI really. In version 2.1.5, you added a dependence on npm: d9d782b - the build scripts now call npm run

My setup didn't have npm installed (I'm using yarn for package management), so this broke for me.

I realise that we're a long way off from removing dependence on npm altogether, so I've installed it for now, but I just thought you'd like to be aware that this may become more of an issue in the future.

How Do I update the TLD list?

If any new TLD's are introduced or added, how do I indicate the library to Update the dat file?
Is there a way to indicate the Library to always fetch & cache the TLD list from publicsufix.

There is nothing documented in this direction. Pls help

Cannot parse URLs that contain `@`

I've been using your lib quite successfully until I came across a link with an @ in it.

More specifically, this is a users profile on https://medium.com/. These are formatted like: https://medium.com/@username/.

Is this something you could fix easily, or is this intended (I assume it's something to do with emails)?

โš ๏ธ dev-dependencies were added as dependencies in 2.1.1

In 2.1.1 package.json

  "dependencies": {
    "chai": "^4.1.2",
    "fs-copy-file-sync": "^1.1.1",
    "got": "^8.0.1",
    "mkdirp": "^0.5.1",
    "mocha": "^4.0.1"
  },
  "devDependencies": {
    "eslint": "^4.12.1",
    "eslint-config-peerigon": "^12.0.1",
    "eslint-plugin-import": "^2.8.0",
    "eslint-plugin-jsdoc": "^3.2.0",
    "nyc": "^11.3.0",
    "standard-version": "^4.2.0"
  }

I noticed it because I have a max size limit for dependencies ๐Ÿ˜‰

Running sanity check... Could not update list of known top-level domains

On NPM install this error message is consistently present

environment

  • Windows 10
  • npm version 6.13.3
  • node version 10.9.0

we also see this when performing the npm install on a node:10-alpine docker container

package.json

dependencies
"parse-domain": "^2.3.4",

dev-dependencies
"jest": "^23.6.0",

output from npm install

> [email protected] postinstall /webapp/node_modules/parse-domain
> run-s build:tries


> [email protected] build:tries /webapp/node_modules/parse-domain
> node scripts/build-tries.js

Downloading public suffix list from https://publicsuffix.org/list/public_suffix_list.dat... ok
Writing /webapp/node_modules/parse-domain/build/tries/icann.complete.json... ok
Writing /webapp/node_modules/parse-domain/build/tries/icann.light.json... ok
Writing /webapp/node_modules/parse-domain/build/tries/private.complete.json... ok
Running sanity check... 
Could not update list of known top-level domains for parse-domain because of "Command failed: /usr/local/bin/node /webapp/node_modules/parse-domain/node_modules/jest/bin/jest.js"
Using possibly outdated prebuilt list from Sat Nov 02 2019

Security vulnerabilities in latest version 2.3.4

I am running latest version 2.3.4 and npm audit is showing security vulnerabilities:

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ Moderate      โ”‚ Denial of Service                                            โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ Package       โ”‚ handlebars                                                   โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ Dependency of โ”‚ parse-domain                                                 โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ Path          โ”‚ parse-domain > jest > jest-cli > @jest/core >                โ”‚
โ”‚               โ”‚ @jest/reporters > istanbul-reports > handlebars              โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ More info     โ”‚ https://npmjs.com/advisories/1300                            โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜


โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ High          โ”‚ Arbitrary Code Execution                                     โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ Package       โ”‚ handlebars                                                   โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ Dependency of โ”‚ parse-domain                                                 โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ Path          โ”‚ parse-domain > jest > jest-cli > @jest/core >                โ”‚
โ”‚               โ”‚ @jest/reporters > istanbul-reports > handlebars              โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ More info     โ”‚ https://npmjs.com/advisories/1316                            โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜


โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ High          โ”‚ Arbitrary Code Execution                                     โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ Package       โ”‚ handlebars                                                   โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ Dependency of โ”‚ parse-domain                                                 โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ Path          โ”‚ parse-domain > jest > jest-cli > @jest/core >                โ”‚
โ”‚               โ”‚ @jest/reporters > istanbul-reports > handlebars              โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ More info     โ”‚ https://npmjs.com/advisories/1324                            โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜


โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ High          โ”‚ Prototype Pollution                                          โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ Package       โ”‚ handlebars                                                   โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ Dependency of โ”‚ parse-domain                                                 โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ Path          โ”‚ parse-domain > jest > jest-cli > @jest/core >                โ”‚
โ”‚               โ”‚ @jest/reporters > istanbul-reports > handlebars              โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ More info     โ”‚ https://npmjs.com/advisories/1325                            โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Spaces in URL

Should spaces in the URL cause the parser to return null to indicate a bad URL? Right now, the parser attempts to pull the domain and doesn't return null.

Error: Cannot find module '../build/tries/current/icann.complete.json'

Hello, everything is working well in local.
But when I try to clone and npm install my project, this error appears for parse-domain, in the line where I require it.

Do you know what may be the problem ?
In node_modules/parse-domain/build/tries when renaming folder pre/ to current/ it works, but what a quick fix ! And why is that folder absent locally ?

Locally:
NPM version: v5.6.0
Node.js version: v8.9.4

Production:
NPM version: v3.8.9
Node.js version: v6.2.0

parse-domain: 2.1.1

Thank you ! :)

Typings for Typescript

Any chance of including "typings" flag in your package.json pointing a typings.d.ts file with the following?

Would be helpful for Typescript.

"typings": "lib/typings.d.ts"
export interface IParsedDomain {
    domain?: string;
    subdomain?: string;
    tld?: string;
}
export declare type ParsedDomain = (url: string, customTlds?: RegExp | string[], privateTlds?: boolean) => IParsedDomain;

very slow performance

I've noticed this when i built a webapp that runs on mobiles as a webview (inside chrome).
the method performed really slow and was blocking the UI for a long time when had to parse multiple urls.
it wasnt noticable on desktops but it did on mobile.

after looking at the source code i beleive the issue is the lookup of TLD using regex.
regex are very slow, you have to build the regex on every call to "new Regex".
a match faster approach would be to use object lookup keys.
for example
var tlds = []
tlds['com'] = 1
tlds['co.uk'] = 2
....
then check if tlds[domain] exists.

Incorrectly pick up cdn.blah.com.s3.amazonaws.com

Parsing s3 domain urls seems to be incorrect:

For example: cdn.blah.com.s3.amazonaws.com
{ tld: 's3.amazonaws.com',
domain: 'com',
subdomain: 'cdn.blah' }

In this case, it should pick up .com from the right hand side (obviously), then amazonaws as the domain, with: cdn.blah.com.s3 as the subdomain

Create-react-app won't compile package, es5 precompilation step missing

My application won't compile the package currently because of a pre-compilation step in es5 missing.

$ NODE_PATH=src/ PUBLIC_URL=/boarding react-scripts build
Creating an optimized production build...
Failed to compile.

Failed to minify the code from this file:

 	/tmp/node_modules/parse-domain/lib/parseDomain.js:10

Read more here: http://bit.ly/2tRViJ9

Solution

Add a precompilation step before publication

`gouv.fr`, `co.uk`, `com.sg`, other public suffixes are not being resolved as TLDs

We're running in to an issue (cypress-io/cypress#3717) caused by an update to parse-domain causing public suffixes to not be resolved as TLDs. gouv.fr, co.uk, com.sg, and other public suffixes are not being resolved as TLDs ever since 2.1.0.

const parseDomain = require('parse-domain')

console.log(
  parseDomain('dev.classea12.beta.gouv.fr', {
    privateTlds: true,
    customTlds: /^[\d\.]+$/
  })
)

With [email protected], this results in:

{ tld: 'gouv.fr', domain: 'beta', subdomain: 'dev.classea12' }

With [email protected], this results in:

{ tld: 'fr', domain: 'gouv', subdomain: 'dev.classea12.beta' }

Potentially related: #64, #65

Large angular 5.1 project, IE11 hangs at load. Without parse-domain, loads fine.

We have a large-ish angular 5.1 project. When parseDomain is included like this:

// top of .ts component file
let parseDomain = require('parse-domain');
...

// used someplace in a class method:
let domain = parseDomain( this.company.web_addr );
domain = domain ? (domain.domain + '.' + domain.tld).toLocaleLowerCase() : '';

Then IE11 (11.64.16299.0 with update version 11.0.48) will not load our app.
Instead the app sits at the loading spinner we have for it.
No console output, and no breakpoint (Break on Unhandled Exceptions is chosen)

If I comment out this, then IE11 can load our app.
This code is not even run at startup, but on a button click, so I expect it's causing Angular-cli to suck in the parse-domain library

// used someplace in a class method:
let domain;  // = parseDomain( this.company.web_addr );
//domain = domain ? (domain.domain + '.' + domain.tld).toLocaleLowerCase() : '';

Any ideas? Do you know an alternate way to strip a host/subdomain, or to match a tld? (it's not simple, as you no doubt know).
I need to make the following kind of transformation:

www.mydomain.com ==> mydomain.com
host.mydomain.com ==> mydomain.com
host.mydomain.co.uk ==> mydomain.co.uk
host.mydomain.health ==> mydomain.health
... and etc ...
...

angular-cli

    _                      _                 ____ _     ___
   / \   _ __   __ _ _   _| | __ _ _ __     / ___| |   |_ _|
  / โ–ณ \ | '_ \ / _` | | | | |/ _` | '__|   | |   | |    | |
 / ___ \| | | | (_| | |_| | | (_| | |      | |___| |___ | |
/_/   \_\_| |_|\__, |\__,_|_|\__,_|_|       \____|_____|___|
               |___/

Angular CLI: 1.6.4
Node: 7.5.0
OS: darwin x64
Angular: 5.1.0
... animations, common, compiler, compiler-cli, core, forms
... http, language-service, platform-browser
... platform-browser-dynamic, router

@angular/cli: 1.6.4
@angular-devkit/build-optimizer: 0.0.42
@angular-devkit/core: 0.0.28
@angular-devkit/schematics: 0.0.52
@ngtools/json-schema: 1.1.0
@ngtools/webpack: 1.9.4
@schematics/angular: 0.1.17
typescript: 2.5.3
webpack: 3.10.0

package.json has:

"dependencies": {
    "@angular/animations": "5.1.0",
    "@angular/common": "5.1.0",
    "@angular/compiler": "5.1.0",
    "@angular/core": "5.1.0",
    "@angular/forms": "5.1.0",
    "@angular/http": "5.1.0",
    "@angular/platform-browser": "5.1.0",
    "@angular/platform-browser-dynamic": "5.1.0",
    "@angular/router": "5.1.0",
    "@ng-bootstrap/ng-bootstrap": "1.0.0-beta.5",
    "angular2-medium-editor": "1.0.6",
    "angular2-uuid": "1.1.1",
    "blueimp-canvas-to-blob": "3.11.0",
    "bootstrap": "4.0.0-beta",
    "core-js": "2.4.1",
    "intl": "1.2.5",
    "jquery": "3.2.1",
    "lodash": "4.17.4",
    "marked": "0.3.6",
    "medium-editor": "5.23.2",
    "medium-editor-markdown": "2.6.0",
    "moment": "2.18.1",
    "ng-autosize": "1.1.0",
    "ng-click-outside": "2.0.2",
    "ng2-device-detector": "1.0.0",
    "ng2-img-cropper": "0.9.0",
    "ng2-select2": "1.0.0-beta.10",
    "parse-domain": "2.0.0",
    "remove-markdown": "0.1.0",
    "rxjs": "5.5.6",
    "select2": "4.0.3",
    "semaphore": "1.0.5",
    "stacktrace-js": "2.0.0",
    "sweetalert2": "7.0.6",
    "three": "0.86.0",
    "ts-helpers": "1.1.1",
    "web-animations-js": "2.3.1",
    "zone.js": "0.8.19"
  },
  "devDependencies": {
    "@angular-devkit/core": "0.0.28",
    "@angular/cli": "1.6.4",
    "@angular/compiler-cli": "5.1.0",
    "@angular/language-service": "5.1.0",
    "@types/jasmine": "2.8.3",
    "@types/jasminewd2": "2.0.2",
    "@types/lodash": "4.14.83",
    "@types/medium-editor": "5.0.2",
    "@types/mixpanel": "2.13.1",
    "@types/node": "6.0.60",
    "@types/selenium-webdriver": "3.0.8",
    "@types/three": "0.84.29",
    "codelyzer": "4.0.1",
    "dotenv": "4.0.0",
    "http-server": "0.10.0",
    "jasmine-core": "~2.8.0",
    "jasmine-spec-reporter": "~4.2.1",
    "karma": "~2.0.0",
    "karma-chrome-launcher": "~2.2.0",
    "karma-cli": "~1.0.1",
    "karma-coverage-istanbul-reporter": "~1.2.1",
    "karma-env-preprocessor": "~0.1.1",
    "karma-jasmine": "~1.1.0",
    "karma-jasmine-html-reporter": "~0.2.2",
    "karma-phantomjs-launcher": "1.0.0",
    "karma-remap-istanbul": "0.2.1",
    "karma-spec-reporter": "0.0.26",
    "karma-verbose-reporter": "0.0.3",
    "node-sass": "3.13.0",
    "phantomjs-polyfill": "0.0.2",
    "phantomjs-prebuilt": "2.1.7",
    "protractor": "~5.1.2",
    "raw-loader": "0.5.1",
    "sass-loader": "4.0.2",
    "ts-node": "3.2.0",
    "tslint": "5.9.1",
    "typescript": "2.5.3",
    "webdriver-manager": "10.2.5"
  }

polyfills.ts is

/**
 * This file includes polyfills needed by Angular and is loaded before the app.
 * You can add your own extra polyfills to this file.
 *
 * This file is divided into 2 sections:
 *   1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers.
 *   2. Application imports. Files imported after ZoneJS that should be loaded before your main
 *      file.
 *
 * The current setup is for so-called "evergreen" browsers; the last versions of browsers that
 * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera),
 * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile.
 *
 * Learn more in https://angular.io/docs/ts/latest/guide/browser-support.html
 */

/***************************************************************************************************
 * BROWSER POLYFILLS
 */

/** IE9, IE10 and IE11 requires all of the following polyfills. **/
import 'core-js/es6/symbol';
import 'core-js/es6/object';
import 'core-js/es6/function';
import 'core-js/es6/parse-int';
import 'core-js/es6/parse-float';
import 'core-js/es6/number';
import 'core-js/es6/math';
import 'core-js/es6/string';
import 'core-js/es6/date';
import 'core-js/es6/array';
import 'core-js/es6/regexp';
import 'core-js/es6/map';
import 'core-js/es6/weak-map';
import 'core-js/es6/set';

import 'core-js/es7/array'
//import 'core-js/es7/global'
import 'core-js/es7/string'
import 'core-js/es7/map'
import 'core-js/es7/set'
import 'core-js/es7/error'
import 'core-js/es7/math'
import 'core-js/es7/system'
import 'core-js/es7/symbol'
import 'core-js/es7/reflect'
import 'core-js/es7/observable'

/** IE10 and IE11 requires the following for NgClass support on SVG elements */
// import 'classlist.js';  // Run `npm install --save classlist.js`.

/** IE10 and IE11 requires the following for the Reflect API. */
import 'core-js/es6/reflect';

/** Evergreen browsers require these. **/
// Used for reflect-metadata in JIT. If you use AOT (and only Angular decorators), you can remove.
import 'core-js/es7/reflect';


/**
 * Required to support Web Animations `@angular/platform-browser/animations`.
 * Needed for: All but Chrome, Firefox and Opera. http://caniuse.com/#feat=web-animation
 **/
import 'web-animations-js';  // Run `npm install --save web-animations-js`.



/***************************************************************************************************
 * Zone JS is required by Angular itself.
 */
import 'zone.js/dist/zone';  // Included with Angular CLI.



/***************************************************************************************************
 * APPLICATION IMPORTS
 */

/**
 * Date, currency, decimal and percent pipes.
 * Needed for: All but Chrome, Firefox, Edge, IE11 and Safari 10
 */
import 'intl';  // Run `npm install --save intl`.
/**
 * Need to import at least one locale-data with intl.
 */
import 'intl/locale-data/jsonp/en';

Mocha and Chai as devdeps?

Stoked about this project, just what we're looking for. However, we're on a strict module size budget, and happened to notice Mocha and Chai are in main deps.

I assume these can be safely moved to dev dependencies โ€“ is that the case? If so, happy to PR.

Thanks!

Update the list of TLD

Seems like the last update was Dec 2017 (df15b19), but could we update the list to up-to-date one?
Would be nice if there was any "how to update" guide or some update script, which could be used to make PR by anyone. Thanks!

Can't seem to npm install

Seems like #72 resurfaced ?
`npm i

[email protected] postinstall /xxx/node_modules/parse-domain
run-s build:tries
sh: run-s: command not found
npm ERR! file sh
npm ERR! code ELIFECYCLE
npm ERR! errno ENOENT
npm ERR! syscall spawn
npm ERR! [email protected] postinstall: run-s build:tries
npm ERR! spawn ENOENT
npm ERR!
npm ERR! Failed at the [email protected] postinstall script.`

IDNA support?

there's no mention of such nor any tests that I could find with a quick search

2nd level domain as custom TLD?

Is it possible to pass a second level domain as a custom TLD? Looks like it does not work.

e.g. I have foo.example.com and I want to get 'foo' as domain and 'example.com' as TLD.

Sample code:

var parseDomain = require('parse-domain');
var url = "foo.example.com";
var parsed_domain = parseDomain(url, { customTlds:[ "example.com"] });

console.log(parsed_domain);

Output

{ tld: 'com', domain: 'example', subdomain: 'foo' }

Expected Output

{ tld: 'example.com', domain: 'foo', subdomain: '' }

Thank you!

Big bundle size

Hi guys,

my team and I already integrated your package into our multi-domain application and we are very happy with it, but recently we noticed that bundle size is increased a lot. Actually, parse-domain is the biggest package we have, even bigger than segment and moment, that are notoriously huge.

screen shot 2017-07-21 at 12 21 59

I see there are a custom TLD option, that could be ok for use, but I guess if there are a solution to remove or prevent to include original objects and use only a custom file.

And, in any case, we can maybe reduce code here
https://github.com/peerigon/parse-domain/blob/master/lib/tld.js
since we can define a big set only once and not twice (once in the first row, once in the second)

Thanks guys and keep on working on this great package.
[the only one I see could recognise tld like .co.uk]

Failed to minify the code from this file

I have a project which is running fine with local development mode when I try to build for production mode with npm run build getting following error, any guidance will be appreciated.

Development Environment :

  • npm --version : 5.6.0
  • node -v : v8.11.1

.babelrc as below

{
  "presets": ["es2015", "stage-2", "react", "env"],
  "plugins": [
    ["babel-plugin-root-import",
     "babel-plugin-transform-decorators-legacy",
     "transform-object-rest-spread",
     "transform-class-properties"]
  ],
  "env": {
    "debug": true
  }
}

react-scripts build

Creating an optimized production build...
Failed to compile.

Failed to minify the code from this file:

./node_modules/parse-domain/lib/parseDomain.js:25 

Read more here: http://bit.ly/2tRViJ9

Let me know if more details are required.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.