psl ๐ŸŽƒ๐ŸŒถ๏ธโ˜•

Package Version Hex Docs

A Gleam package for parsing domain names into their component parts using the Public Suffix List.

Installation

Add psl to your Gleam project:

gleam add psl@2

Usage

import gleam/option.{None}
import psl

pub fn main() {
  // Load the public suffix list (include private domains)
  let list = psl.load_suffix_list(True, None)

  // Parse a simple domain
  let assert Ok(parts) = psl.parse("https://gleam.run", list)
  // parts.transit_routing_domain -> ""
  // parts.second_level_domain -> "gleam"
  // parts.top_level_domain -> "run"
  // parts.subdomain_parts -> []

  // Parse a domain with a subdomain
  let assert Ok(parts) = psl.parse("https://packages.gleam.run", list)
  // parts.transit_routing_domain -> "packages"
  // parts.second_level_domain -> "gleam"
  // parts.top_level_domain -> "run"
  // parts.subdomain_parts -> ["packages"]

  let assert Ok(parts) = psl.parse("https://fun.packages.gleam.run", list)
  // parts.transit_routing_domain -> "fun.packages"
  // parts.second_level_domain -> "gleam"
  // parts.top_level_domain -> "run"
  // parts.subdomain_parts -> ["fun", "packages"]

  // Parse UTF-8
  let assert Ok(parts) = psl.parse("https://gleam.ู…ู„ูŠุณูŠุง", list)
  // parts.transit_routing_domain -> ""
  // parts.second_level_domain -> "gleam"
  // parts.top_level_domain -> "ู…ู„ูŠุณูŠุง"  (decoded from punycode)
  // parts.subdomain_parts -> []

  // Parse punycode domains
  // Punycode domains (xn--) are decoded to UTF-8
  let assert Ok(parts) = psl.parse("https://gleam.xn--mgbx4cd0ab", list)
  // parts.transit_routing_domain -> ""
  // parts.second_level_domain -> "gleam"
  // parts.top_level_domain -> "ู…ู„ูŠุณูŠุง"  (decoded from punycode)
  // parts.subdomain_parts -> []
}

Using Your Own List

You can provide your own public suffix list file instead of using the bundled one:

import gleam/option.{Some}
import psl

pub fn main() {
  // Load a custom suffix list
  let list = psl.load_suffix_list(True, Some("path/to/list.dat"))

  let assert Ok(parts) = psl.parse("https://gleam.run", list)
}

Adding Custom Rules

You can add your own rules for private DNS domains that are not on the Public Suffix List:

import gleam/option.{None}
import psl

pub fn main() {
  // Load the standard list
  let list = psl.load_suffix_list(True, None)

  // Add a custom rule for your private domain
  // Normal domains: mysuffix"
  // Wildcards: "*mysuffix"
  // Exceptions: "!www.mysuffix"
  let list = psl.add_rule(list, "mysuffix", False)


  let assert Ok(parts) = psl.parse("https://neat.gleam.mysuffix", list)
  // parts.second_level_domain -> "gleam"
  // parts.top_level_domain -> "mysuffix"
}

Credits

Licence

Apache-2.0

โœจ Search Document