tldts-tests 7.1.2 → 7.2.1
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/dist/cjs/src/tldts-tests.js +86 -0
- package/dist/cjs/src/tldts-tests.js.map +1 -1
- package/dist/cjs/tsconfig.tsbuildinfo +1 -1
- package/dist/es6/src/tldts-tests.js +86 -0
- package/dist/es6/src/tldts-tests.js.map +1 -1
- package/dist/es6/tsconfig.bundle.tsbuildinfo +1 -1
- package/dist/types/src/tldts-tests.d.ts +2 -0
- package/package.json +3 -3
- package/src/tldts-tests.ts +109 -0
package/src/tldts-tests.ts
CHANGED
|
@@ -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
|
},
|
|
@@ -888,6 +896,27 @@ export default function test(
|
|
|
888
896
|
).to.deep.equal(mockResponse('1080::8:800:200c:417a'));
|
|
889
897
|
});
|
|
890
898
|
|
|
899
|
+
it('handles bare, unbracketed ipv6 addresses (issue #2288)', () => {
|
|
900
|
+
// Bare and scheme-prefixed unbracketed IPv6 are kept whole and detected,
|
|
901
|
+
// instead of being dropped or truncated to "2a01:e35:2f22:e3d0:". A
|
|
902
|
+
// documented deviation from `new URL`, which rejects unbracketed IPv6.
|
|
903
|
+
expect(tldts.parse('2a01:e35:2f22:e3d0::1')).to.deep.equal(
|
|
904
|
+
mockResponse('2a01:e35:2f22:e3d0::1'),
|
|
905
|
+
);
|
|
906
|
+
expect(tldts.parse('http://2a01:e35:2f22:e3d0::1')).to.deep.equal(
|
|
907
|
+
mockResponse('2a01:e35:2f22:e3d0::1'),
|
|
908
|
+
);
|
|
909
|
+
expect(tldts.parse('fe80::1')).to.deep.equal(mockResponse('fe80::1'));
|
|
910
|
+
expect(tldts.getHostname('http://2a01:e35:2f22:e3d0::1')).to.equal(
|
|
911
|
+
'2a01:e35:2f22:e3d0::1',
|
|
912
|
+
);
|
|
913
|
+
// A trailing group that looks like a port is part of the address (an
|
|
914
|
+
// unbracketed IPv6 cannot carry a port), so it is kept and still an IP.
|
|
915
|
+
expect(tldts.parse('2a01::1:8080')).to.deep.equal(
|
|
916
|
+
mockResponse('2a01::1:8080'),
|
|
917
|
+
);
|
|
918
|
+
});
|
|
919
|
+
|
|
891
920
|
it('handles ipv6 address when extractHostname is false', () => {
|
|
892
921
|
const hostname = '1080::8:800:200C:417A';
|
|
893
922
|
expect(tldts.parse(hostname, { extractHostname: false })).to.deep.equal({
|
|
@@ -897,6 +926,7 @@ export default function test(
|
|
|
897
926
|
isIcann: null,
|
|
898
927
|
isIp: true,
|
|
899
928
|
isPrivate: null,
|
|
929
|
+
isSpecialUse: null,
|
|
900
930
|
publicSuffix: null,
|
|
901
931
|
subdomain: null,
|
|
902
932
|
});
|
|
@@ -911,6 +941,7 @@ export default function test(
|
|
|
911
941
|
isIcann: null,
|
|
912
942
|
isIp: true,
|
|
913
943
|
isPrivate: null,
|
|
944
|
+
isSpecialUse: null,
|
|
914
945
|
publicSuffix: null,
|
|
915
946
|
subdomain: null,
|
|
916
947
|
});
|
|
@@ -934,6 +965,7 @@ export default function test(
|
|
|
934
965
|
isIcann: false,
|
|
935
966
|
isIp: null,
|
|
936
967
|
isPrivate: false,
|
|
968
|
+
isSpecialUse: null,
|
|
937
969
|
publicSuffix: '1',
|
|
938
970
|
subdomain: '192.168',
|
|
939
971
|
}
|
|
@@ -944,6 +976,7 @@ export default function test(
|
|
|
944
976
|
isIcann: null,
|
|
945
977
|
isIp: null,
|
|
946
978
|
isPrivate: null,
|
|
979
|
+
isSpecialUse: null,
|
|
947
980
|
publicSuffix: '1',
|
|
948
981
|
subdomain: '192.168',
|
|
949
982
|
},
|
|
@@ -951,6 +984,73 @@ export default function test(
|
|
|
951
984
|
});
|
|
952
985
|
});
|
|
953
986
|
|
|
987
|
+
describe('special-use domains (IANA registry)', () => {
|
|
988
|
+
const special = (url: string) =>
|
|
989
|
+
tldts.parse(url, { detectSpecialUse: true }).isSpecialUse;
|
|
990
|
+
|
|
991
|
+
it('flags special-use names and their sub-domains', () => {
|
|
992
|
+
for (const hostname of [
|
|
993
|
+
// RFC 6761
|
|
994
|
+
'test',
|
|
995
|
+
'a.b.test',
|
|
996
|
+
'localhost',
|
|
997
|
+
'foo.localhost',
|
|
998
|
+
'invalid',
|
|
999
|
+
'something.invalid',
|
|
1000
|
+
'example',
|
|
1001
|
+
'sub.example',
|
|
1002
|
+
'example.com',
|
|
1003
|
+
'example.net',
|
|
1004
|
+
'www.example.org',
|
|
1005
|
+
// RFC 6762 / 7686 / 9476
|
|
1006
|
+
'local',
|
|
1007
|
+
'printer.local',
|
|
1008
|
+
'onion',
|
|
1009
|
+
'facebookcorewwwwi.onion',
|
|
1010
|
+
'alt',
|
|
1011
|
+
'x.alt',
|
|
1012
|
+
// named .arpa entries (RFC 8375 / 8880 / 9462 / 9665 / 9031 / 9965)
|
|
1013
|
+
'home.arpa',
|
|
1014
|
+
'router.home.arpa',
|
|
1015
|
+
'ipv4only.arpa',
|
|
1016
|
+
'resolver.arpa',
|
|
1017
|
+
'service.arpa',
|
|
1018
|
+
'6tisch.arpa',
|
|
1019
|
+
'eap.arpa',
|
|
1020
|
+
// normalization contract: extractHostname lower-cases the host and
|
|
1021
|
+
// strips a trailing dot before isSpecialUse sees it (is-special-use.ts).
|
|
1022
|
+
'LocalHost',
|
|
1023
|
+
'a.b.test.',
|
|
1024
|
+
]) {
|
|
1025
|
+
expect(special(hostname), hostname).to.equal(true);
|
|
1026
|
+
}
|
|
1027
|
+
});
|
|
1028
|
+
|
|
1029
|
+
it('does not flag ordinary domains, partial matches, or excluded entries', () => {
|
|
1030
|
+
for (const hostname of [
|
|
1031
|
+
'google.com',
|
|
1032
|
+
'foo.bar.com',
|
|
1033
|
+
'example.fr', // not a reserved name
|
|
1034
|
+
'latest', // label boundary vs `test`
|
|
1035
|
+
'notlocalhost', // label boundary vs `localhost`
|
|
1036
|
+
'badexample.com', // label boundary vs `example.com`
|
|
1037
|
+
'arpa', // only specific .arpa names are reserved
|
|
1038
|
+
'foo.arpa',
|
|
1039
|
+
'eap-noob.arpa', // deprecated registry entry, intentionally excluded
|
|
1040
|
+
]) {
|
|
1041
|
+
expect(special(hostname), hostname).to.equal(false);
|
|
1042
|
+
}
|
|
1043
|
+
});
|
|
1044
|
+
|
|
1045
|
+
it('is null unless detectSpecialUse is enabled', () => {
|
|
1046
|
+
expect(tldts.parse('localhost').isSpecialUse).to.equal(null);
|
|
1047
|
+
expect(
|
|
1048
|
+
tldts.parse('localhost', { detectSpecialUse: false }).isSpecialUse,
|
|
1049
|
+
).to.equal(null);
|
|
1050
|
+
expect(tldts.parse('google.com').isSpecialUse).to.equal(null);
|
|
1051
|
+
});
|
|
1052
|
+
});
|
|
1053
|
+
|
|
954
1054
|
describe('validHosts', () => {
|
|
955
1055
|
describe('non-empty array', () => {
|
|
956
1056
|
const options: Options = {
|
|
@@ -1244,6 +1344,15 @@ export default function test(
|
|
|
1244
1344
|
);
|
|
1245
1345
|
});
|
|
1246
1346
|
|
|
1347
|
+
it('accepts unbracketed IPv6 (WHATWG/`new URL` rejects)', () => {
|
|
1348
|
+
expect(tldts.getHostname('2a01:e35:2f22:e3d0::1')).to.equal(
|
|
1349
|
+
'2a01:e35:2f22:e3d0::1',
|
|
1350
|
+
);
|
|
1351
|
+
expect(tldts.getHostname('http://2a01:e35:2f22:e3d0::1')).to.equal(
|
|
1352
|
+
'2a01:e35:2f22:e3d0::1',
|
|
1353
|
+
);
|
|
1354
|
+
});
|
|
1355
|
+
|
|
1247
1356
|
it('strips trailing dots', () => {
|
|
1248
1357
|
expect(tldts.getHostname('http://example.com./')).to.equal(
|
|
1249
1358
|
'example.com',
|