tldts-tests 7.1.1 → 7.2.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.
@@ -6,6 +6,7 @@ interface Options {
6
6
  validateHostname?: boolean;
7
7
  mixedInputs?: boolean;
8
8
  detectIp?: boolean;
9
+ detectSpecialUse?: boolean;
9
10
  validHosts?: string[];
10
11
  }
11
12
  export default function test(tldts: {
@@ -18,6 +19,7 @@ export default function test(tldts: {
18
19
  domain: string | null;
19
20
  hostname: string | null;
20
21
  publicSuffix: string | null;
22
+ isSpecialUse?: boolean | null;
21
23
  };
22
24
  }, { includePrivate }: {
23
25
  includePrivate: boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tldts-tests",
3
- "version": "7.1.1",
3
+ "version": "7.2.0",
4
4
  "description": "tests for different tldts implementations",
5
5
  "author": {
6
6
  "name": "Rémi Berson"
@@ -52,7 +52,7 @@
52
52
  "devDependencies": {
53
53
  "@types/node": "^25.1.0",
54
54
  "rimraf": "^6.1.2",
55
- "tldts-utils": "^7.1.1",
55
+ "tldts-utils": "^7.2.0",
56
56
  "ts-node": "^10.9.2",
57
57
  "typescript": "^5.9.3"
58
58
  },
@@ -62,5 +62,5 @@
62
62
  "chai": "^6.2.2",
63
63
  "mocha": "^11.7.5"
64
64
  },
65
- "gitHead": "54cf9e31f5632d60e766684108ba50c6ddf60b61"
65
+ "gitHead": "ad2b935aa926d0a9df5420dd2bb55734c929b11a"
66
66
  }
@@ -55,6 +55,7 @@ interface Options {
55
55
  validateHostname?: boolean;
56
56
  mixedInputs?: boolean;
57
57
  detectIp?: boolean;
58
+ detectSpecialUse?: boolean;
58
59
  validHosts?: string[];
59
60
  }
60
61
 
@@ -72,6 +73,7 @@ export default function test(
72
73
  domain: string | null;
73
74
  hostname: string | null;
74
75
  publicSuffix: string | null;
76
+ isSpecialUse?: boolean | null;
75
77
  };
76
78
  },
77
79
  { includePrivate }: { includePrivate: boolean },
@@ -328,6 +330,7 @@ export default function test(
328
330
  isIcann: true,
329
331
  isIp: false,
330
332
  isPrivate: false,
333
+ isSpecialUse: null,
331
334
  publicSuffix: 'com',
332
335
  subdomain: '_0f6879f07aa61fc09d9645cce98b30e3.bsg-1418',
333
336
  });
@@ -339,6 +342,7 @@ export default function test(
339
342
  isIcann: true,
340
343
  isIp: false,
341
344
  isPrivate: false,
345
+ isSpecialUse: null,
342
346
  publicSuffix: 'com',
343
347
  subdomain: '_bsg-1418',
344
348
  });
@@ -350,6 +354,7 @@ export default function test(
350
354
  isIcann: true,
351
355
  isIp: false,
352
356
  isPrivate: false,
357
+ isSpecialUse: null,
353
358
  publicSuffix: 'com',
354
359
  subdomain: '',
355
360
  });
@@ -834,6 +839,7 @@ export default function test(
834
839
  isIcann: null,
835
840
  isIp: true,
836
841
  isPrivate: null,
842
+ isSpecialUse: null,
837
843
  publicSuffix: null,
838
844
  subdomain: null,
839
845
  };
@@ -849,6 +855,7 @@ export default function test(
849
855
  isIcann: false,
850
856
  isIp: false,
851
857
  isPrivate: false,
858
+ isSpecialUse: null,
852
859
  publicSuffix: 'badasdasdada',
853
860
  subdomain: 'foo',
854
861
  }
@@ -859,6 +866,7 @@ export default function test(
859
866
  isIcann: null,
860
867
  isIp: false,
861
868
  isPrivate: null,
869
+ isSpecialUse: null,
862
870
  publicSuffix: 'badasdasdada',
863
871
  subdomain: 'foo',
864
872
  },
@@ -897,6 +905,7 @@ export default function test(
897
905
  isIcann: null,
898
906
  isIp: true,
899
907
  isPrivate: null,
908
+ isSpecialUse: null,
900
909
  publicSuffix: null,
901
910
  subdomain: null,
902
911
  });
@@ -911,6 +920,7 @@ export default function test(
911
920
  isIcann: null,
912
921
  isIp: true,
913
922
  isPrivate: null,
923
+ isSpecialUse: null,
914
924
  publicSuffix: null,
915
925
  subdomain: null,
916
926
  });
@@ -934,6 +944,7 @@ export default function test(
934
944
  isIcann: false,
935
945
  isIp: null,
936
946
  isPrivate: false,
947
+ isSpecialUse: null,
937
948
  publicSuffix: '1',
938
949
  subdomain: '192.168',
939
950
  }
@@ -944,6 +955,7 @@ export default function test(
944
955
  isIcann: null,
945
956
  isIp: null,
946
957
  isPrivate: null,
958
+ isSpecialUse: null,
947
959
  publicSuffix: '1',
948
960
  subdomain: '192.168',
949
961
  },
@@ -951,6 +963,73 @@ export default function test(
951
963
  });
952
964
  });
953
965
 
966
+ describe('special-use domains (IANA registry)', () => {
967
+ const special = (url: string) =>
968
+ tldts.parse(url, { detectSpecialUse: true }).isSpecialUse;
969
+
970
+ it('flags special-use names and their sub-domains', () => {
971
+ for (const hostname of [
972
+ // RFC 6761
973
+ 'test',
974
+ 'a.b.test',
975
+ 'localhost',
976
+ 'foo.localhost',
977
+ 'invalid',
978
+ 'something.invalid',
979
+ 'example',
980
+ 'sub.example',
981
+ 'example.com',
982
+ 'example.net',
983
+ 'www.example.org',
984
+ // RFC 6762 / 7686 / 9476
985
+ 'local',
986
+ 'printer.local',
987
+ 'onion',
988
+ 'facebookcorewwwwi.onion',
989
+ 'alt',
990
+ 'x.alt',
991
+ // named .arpa entries (RFC 8375 / 8880 / 9462 / 9665 / 9031 / 9965)
992
+ 'home.arpa',
993
+ 'router.home.arpa',
994
+ 'ipv4only.arpa',
995
+ 'resolver.arpa',
996
+ 'service.arpa',
997
+ '6tisch.arpa',
998
+ 'eap.arpa',
999
+ // normalization contract: extractHostname lower-cases the host and
1000
+ // strips a trailing dot before isSpecialUse sees it (is-special-use.ts).
1001
+ 'LocalHost',
1002
+ 'a.b.test.',
1003
+ ]) {
1004
+ expect(special(hostname), hostname).to.equal(true);
1005
+ }
1006
+ });
1007
+
1008
+ it('does not flag ordinary domains, partial matches, or excluded entries', () => {
1009
+ for (const hostname of [
1010
+ 'google.com',
1011
+ 'foo.bar.com',
1012
+ 'example.fr', // not a reserved name
1013
+ 'latest', // label boundary vs `test`
1014
+ 'notlocalhost', // label boundary vs `localhost`
1015
+ 'badexample.com', // label boundary vs `example.com`
1016
+ 'arpa', // only specific .arpa names are reserved
1017
+ 'foo.arpa',
1018
+ 'eap-noob.arpa', // deprecated registry entry, intentionally excluded
1019
+ ]) {
1020
+ expect(special(hostname), hostname).to.equal(false);
1021
+ }
1022
+ });
1023
+
1024
+ it('is null unless detectSpecialUse is enabled', () => {
1025
+ expect(tldts.parse('localhost').isSpecialUse).to.equal(null);
1026
+ expect(
1027
+ tldts.parse('localhost', { detectSpecialUse: false }).isSpecialUse,
1028
+ ).to.equal(null);
1029
+ expect(tldts.parse('google.com').isSpecialUse).to.equal(null);
1030
+ });
1031
+ });
1032
+
954
1033
  describe('validHosts', () => {
955
1034
  describe('non-empty array', () => {
956
1035
  const options: Options = {