tldts 7.3.0 → 7.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -68,6 +68,7 @@ Alternatively, you can try it _directly in your browser_ here: https://npm.runki
68
68
  - `tldts.parse(url | hostname, options)`
69
69
  - `tldts.getHostname(url | hostname, options)`
70
70
  - `tldts.getDomain(url | hostname, options)`
71
+ - `tldts.getFullDomain(url | hostname, options)`
71
72
  - `tldts.getPublicSuffix(url | hostname, options)`
72
73
  - `tldts.getSubdomain(url, | hostname, options)`
73
74
  - `tldts.getDomainWithoutSuffix(url | hostname, options)`
@@ -240,6 +241,27 @@ getDomain('fr.t.co'); // returns `t.co`
240
241
  getDomain('https://user:password@example.co.uk:8080/some/path?and&query#hash'); // returns `example.co.uk`
241
242
  ```
242
243
 
244
+ ### getFullDomain(url | hostname, options?)
245
+
246
+ Returns the full domain — the subdomain together with the registrable domain (as
247
+ returned by `getDomain(...)`), i.e. the whole hostname _including_ any subdomain —
248
+ or `null` when the input has no registrable domain (IP address, single label,
249
+ bare public suffix, …). The result is the normalized hostname (lower-cased,
250
+ trailing dot stripped); it is not a DNS-absolute name (no trailing root dot) and
251
+ no IDNA/punycode conversion is performed.
252
+
253
+ ```javascript
254
+ const { getFullDomain } = require('tldts');
255
+
256
+ getFullDomain('google.com'); // returns `google.com`
257
+ getFullDomain('fr.google.com'); // returns `fr.google.com`
258
+ getFullDomain('foo.google.co.uk'); // returns `foo.google.co.uk`
259
+ getFullDomain('t.co'); // returns `t.co`
260
+ getFullDomain('fr.t.co'); // returns `fr.t.co`
261
+ getFullDomain('1.2.3.4'); // returns null (no registrable domain)
262
+ getFullDomain('localhost'); // returns null
263
+ ```
264
+
243
265
  ### getDomainWithoutSuffix(url | hostname, options?)
244
266
 
245
267
  Returns the domain (as returned by `getDomain(...)`) without the public suffix part.
package/dist/cjs/index.js CHANGED
@@ -431,7 +431,10 @@ function extractHostname(url, urlIsValidHostname, validate = false) {
431
431
  else if (code < 48 || code > 57) {
432
432
  // < 64 and not a delimiter/dot/digit => only '-' (45) is a valid
433
433
  // host char here; everything else (space, %, !, etc.) is invalid.
434
- if (code !== 45) {
434
+ // A '-' must also not START a label (the byte right after a '.')
435
+ // mirrors is-valid.ts; the first label is covered by the first-char
436
+ // rule above. (RFC 1034 §3.5 / RFC 1035 §2.3.1 LDH.)
437
+ if (code !== 45 || vLastCode === 46 /* label-leading '-' */) {
435
438
  vValid = false;
436
439
  }
437
440
  }
@@ -711,8 +714,14 @@ function isValidHostname (hostname) {
711
714
  }
712
715
  lastDotIndex = i;
713
716
  }
714
- else if (!( /*@__INLINE__*/(isValidAscii(code) || code === 45 || code === 95))) {
715
- // Check if there is a forbidden character in the label
717
+ else if (
718
+ // A forbidden character in the label...
719
+ !( /*@__INLINE__*/(isValidAscii(code) || code === 45 || code === 95)) ||
720
+ // ...or a '-' starting a label (the byte right after a '.'). A label must
721
+ // not begin with a hyphen (RFC 1034 §3.5 / RFC 1035 §2.3.1 LDH, as amended
722
+ // by RFC 1123 §2.1; cf. UTS #46 CheckHyphens). The first label is covered by
723
+ // the leading-character guard above; mirrors the trailing-'-' rule below.
724
+ (code === 45 && lastCharCode === 46)) {
716
725
  return false;
717
726
  }
718
727
  lastCharCode = code;
@@ -1132,6 +1141,14 @@ function getDomain(url, options) {
1132
1141
  /*@__INLINE__*/ resetResult(RESULT);
1133
1142
  return parseImpl(url, 3 /* FLAG.DOMAIN */, suffixLookup, options, RESULT).domain;
1134
1143
  }
1144
+ function getFullDomain(url, options) {
1145
+ /*@__INLINE__*/ resetResult(RESULT);
1146
+ const result = parseImpl(url, 3 /* FLAG.DOMAIN */, suffixLookup, options, RESULT);
1147
+ // The hostname *is* the full domain (subdomain + domain) whenever a
1148
+ // registrable domain exists; gate on `domain` so non-registrable inputs
1149
+ // (IPs, suffix-less or invalid hostnames) return `null` like `getDomain`.
1150
+ return result.domain === null ? null : result.hostname;
1151
+ }
1135
1152
  function getSubdomain(url, options) {
1136
1153
  /*@__INLINE__*/ resetResult(RESULT);
1137
1154
  return parseImpl(url, 4 /* FLAG.SUB_DOMAIN */, suffixLookup, options, RESULT)
@@ -1145,6 +1162,7 @@ function getDomainWithoutSuffix(url, options) {
1145
1162
 
1146
1163
  exports.getDomain = getDomain;
1147
1164
  exports.getDomainWithoutSuffix = getDomainWithoutSuffix;
1165
+ exports.getFullDomain = getFullDomain;
1148
1166
  exports.getHostname = getHostname;
1149
1167
  exports.getPublicSuffix = getPublicSuffix;
1150
1168
  exports.getSubdomain = getSubdomain;