@pactflow/openapi-pact-comparator 1.5.1 → 1.6.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/cli.cjs CHANGED
@@ -11835,6 +11835,15 @@ const convertExclusiveMinMax = (s) => {
11835
11835
  delete s.exclusiveMinimum;
11836
11836
  }
11837
11837
  };
11838
+ const cleanupDiscriminators = (s) => {
11839
+ // no-op from a validation perspective
11840
+ if (s.discriminator?.mapping) {
11841
+ delete s.discriminator.mapping;
11842
+ }
11843
+ if (s.discriminator && !s.oneOf) {
11844
+ delete s.discriminator;
11845
+ }
11846
+ };
11838
11847
  const minimumSchema = (originalSchema, oas) => {
11839
11848
  const refToAdd = [];
11840
11849
  const refAdded = [];
@@ -11842,10 +11851,6 @@ const minimumSchema = (originalSchema, oas) => {
11842
11851
  if (s.$ref && !refToAdd.includes(s.$ref) && !refAdded.includes(s.$ref)) {
11843
11852
  refToAdd.push(s.$ref);
11844
11853
  }
11845
- // no-op from a validation perspective
11846
- if (s.discriminator?.mapping) {
11847
- delete s.discriminator.mapping;
11848
- }
11849
11854
  };
11850
11855
  const handleNullableSchema = (s) => {
11851
11856
  if (s.$ref) {
@@ -11864,6 +11869,7 @@ const minimumSchema = (originalSchema, oas) => {
11864
11869
  const schema = cloneDeep(originalSchema);
11865
11870
  delete schema.description;
11866
11871
  delete schema.example;
11872
+ traverse(schema, cleanupDiscriminators);
11867
11873
  traverse(schema, collectReferences);
11868
11874
  traverse(schema, handleNullableSchema);
11869
11875
  traverse(schema, convertExclusiveMinMax);
@@ -11874,6 +11880,7 @@ const minimumSchema = (originalSchema, oas) => {
11874
11880
  const subschema = cloneDeep(get$1(oas, path, {}));
11875
11881
  delete subschema.description;
11876
11882
  delete subschema.example;
11883
+ traverse(schema, cleanupDiscriminators);
11877
11884
  traverse(subschema, collectReferences);
11878
11885
  traverse(subschema, handleNullableSchema);
11879
11886
  traverse(subschema, convertExclusiveMinMax);
@@ -15923,6 +15930,8 @@ function* compareReqSecurity(ajv, route, interaction, index, config) {
15923
15930
  }
15924
15931
  }
15925
15932
 
15933
+ const patternedStatus = (status) => `${Math.floor(status / 100)}XX`;
15934
+
15926
15935
  const canValidate = (contentType = "") => {
15927
15936
  return !!findMatchingType(contentType, ["application/json"]);
15928
15937
  };
@@ -15932,9 +15941,9 @@ function* compareResBody(ajv, route, interaction, index, config) {
15932
15941
  const { body, status } = interaction.response;
15933
15942
  const requestHeaders = new Headers(interaction.request.headers);
15934
15943
  const statusResponse = operation.responses?.[status];
15935
- const defaultResponse = operation.responses
15936
- ?.default;
15937
- const response = statusResponse || defaultResponse;
15944
+ const patternedResponse = operation.responses?.[patternedStatus(status)];
15945
+ const defaultResponse = operation.responses?.["default"];
15946
+ const response = statusResponse || patternedResponse || defaultResponse;
15938
15947
  if (!response) {
15939
15948
  yield {
15940
15949
  code: "response.status.unknown",
@@ -15962,7 +15971,7 @@ function* compareResBody(ajv, route, interaction, index, config) {
15962
15971
  const schema = dereferencedResponse?.schema ||
15963
15972
  getByContentType(dereferencedResponse.content || {}, contentType)?.schema;
15964
15973
  const value = body;
15965
- if (!statusResponse) {
15974
+ if (!statusResponse && !patternedResponse) {
15966
15975
  yield {
15967
15976
  code: "response.status.default",
15968
15977
  message: `Response status code matched default response in spec file: ${status}`,
@@ -16029,7 +16038,9 @@ function* compareResBody(ajv, route, interaction, index, config) {
16029
16038
 
16030
16039
  function* compareResHeader(ajv, route, interaction, index, _config) {
16031
16040
  const { method, oas, operation, path } = route.store;
16032
- const response = operation.responses[interaction.response.status] ||
16041
+ const { status } = interaction.response;
16042
+ const response = operation.responses[status] ||
16043
+ operation.responses[patternedStatus(status)] ||
16033
16044
  operation.responses["default"];
16034
16045
  // no response found
16035
16046
  // -----------------
@@ -23316,44 +23327,6 @@ var uri = {};
23316
23327
 
23317
23328
  var fastUri = {exports: {}};
23318
23329
 
23319
- var scopedChars;
23320
- var hasRequiredScopedChars;
23321
-
23322
- function requireScopedChars () {
23323
- if (hasRequiredScopedChars) return scopedChars;
23324
- hasRequiredScopedChars = 1;
23325
-
23326
- const HEX = {
23327
- 0: 0,
23328
- 1: 1,
23329
- 2: 2,
23330
- 3: 3,
23331
- 4: 4,
23332
- 5: 5,
23333
- 6: 6,
23334
- 7: 7,
23335
- 8: 8,
23336
- 9: 9,
23337
- a: 10,
23338
- A: 10,
23339
- b: 11,
23340
- B: 11,
23341
- c: 12,
23342
- C: 12,
23343
- d: 13,
23344
- D: 13,
23345
- e: 14,
23346
- E: 14,
23347
- f: 15,
23348
- F: 15
23349
- };
23350
-
23351
- scopedChars = {
23352
- HEX
23353
- };
23354
- return scopedChars;
23355
- }
23356
-
23357
23330
  var utils;
23358
23331
  var hasRequiredUtils;
23359
23332
 
@@ -23361,62 +23334,100 @@ function requireUtils () {
23361
23334
  if (hasRequiredUtils) return utils;
23362
23335
  hasRequiredUtils = 1;
23363
23336
 
23364
- const { HEX } = requireScopedChars();
23337
+ /** @type {(value: string) => boolean} */
23338
+ const isUUID = RegExp.prototype.test.bind(/^[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}$/iu);
23365
23339
 
23366
- const IPV4_REG = /^(?:(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)$/u;
23340
+ /** @type {(value: string) => boolean} */
23341
+ const isIPv4 = RegExp.prototype.test.bind(/^(?:(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)$/u);
23367
23342
 
23368
- function normalizeIPv4 (host) {
23369
- if (findToken(host, '.') < 3) { return { host, isIPV4: false } }
23370
- const matches = host.match(IPV4_REG) || [];
23371
- const [address] = matches;
23372
- if (address) {
23373
- return { host: stripLeadingZeros(address, '.'), isIPV4: true }
23374
- } else {
23375
- return { host, isIPV4: false }
23343
+ /**
23344
+ * @param {Array<string>} input
23345
+ * @returns {string}
23346
+ */
23347
+ function stringArrayToHexStripped (input) {
23348
+ let acc = '';
23349
+ let code = 0;
23350
+ let i = 0;
23351
+
23352
+ for (i = 0; i < input.length; i++) {
23353
+ code = input[i].charCodeAt(0);
23354
+ if (code === 48) {
23355
+ continue
23356
+ }
23357
+ if (!((code >= 48 && code <= 57) || (code >= 65 && code <= 70) || (code >= 97 && code <= 102))) {
23358
+ return ''
23359
+ }
23360
+ acc += input[i];
23361
+ break
23362
+ }
23363
+
23364
+ for (i += 1; i < input.length; i++) {
23365
+ code = input[i].charCodeAt(0);
23366
+ if (!((code >= 48 && code <= 57) || (code >= 65 && code <= 70) || (code >= 97 && code <= 102))) {
23367
+ return ''
23368
+ }
23369
+ acc += input[i];
23376
23370
  }
23371
+ return acc
23377
23372
  }
23378
23373
 
23379
23374
  /**
23380
- * @param {string[]} input
23381
- * @param {boolean} [keepZero=false]
23382
- * @returns {string|undefined}
23375
+ * @typedef {Object} GetIPV6Result
23376
+ * @property {boolean} error - Indicates if there was an error parsing the IPv6 address.
23377
+ * @property {string} address - The parsed IPv6 address.
23378
+ * @property {string} [zone] - The zone identifier, if present.
23383
23379
  */
23384
- function stringArrayToHexStripped (input, keepZero = false) {
23385
- let acc = '';
23386
- let strip = true;
23387
- for (const c of input) {
23388
- if (HEX[c] === undefined) return undefined
23389
- if (c !== '0' && strip === true) strip = false;
23390
- if (!strip) acc += c;
23380
+
23381
+ /**
23382
+ * @param {string} value
23383
+ * @returns {boolean}
23384
+ */
23385
+ const nonSimpleDomain = RegExp.prototype.test.bind(/[^!"$&'()*+,\-.;=_`a-z{}~]/u);
23386
+
23387
+ /**
23388
+ * @param {Array<string>} buffer
23389
+ * @returns {boolean}
23390
+ */
23391
+ function consumeIsZone (buffer) {
23392
+ buffer.length = 0;
23393
+ return true
23394
+ }
23395
+
23396
+ /**
23397
+ * @param {Array<string>} buffer
23398
+ * @param {Array<string>} address
23399
+ * @param {GetIPV6Result} output
23400
+ * @returns {boolean}
23401
+ */
23402
+ function consumeHextets (buffer, address, output) {
23403
+ if (buffer.length) {
23404
+ const hex = stringArrayToHexStripped(buffer);
23405
+ if (hex !== '') {
23406
+ address.push(hex);
23407
+ } else {
23408
+ output.error = true;
23409
+ return false
23410
+ }
23411
+ buffer.length = 0;
23391
23412
  }
23392
- if (keepZero && acc.length === 0) acc = '0';
23393
- return acc
23413
+ return true
23394
23414
  }
23395
23415
 
23416
+ /**
23417
+ * @param {string} input
23418
+ * @returns {GetIPV6Result}
23419
+ */
23396
23420
  function getIPV6 (input) {
23397
23421
  let tokenCount = 0;
23398
23422
  const output = { error: false, address: '', zone: '' };
23423
+ /** @type {Array<string>} */
23399
23424
  const address = [];
23425
+ /** @type {Array<string>} */
23400
23426
  const buffer = [];
23401
- let isZone = false;
23402
23427
  let endipv6Encountered = false;
23403
23428
  let endIpv6 = false;
23404
23429
 
23405
- function consume () {
23406
- if (buffer.length) {
23407
- if (isZone === false) {
23408
- const hex = stringArrayToHexStripped(buffer);
23409
- if (hex !== undefined) {
23410
- address.push(hex);
23411
- } else {
23412
- output.error = true;
23413
- return false
23414
- }
23415
- }
23416
- buffer.length = 0;
23417
- }
23418
- return true
23419
- }
23430
+ let consume = consumeHextets;
23420
23431
 
23421
23432
  for (let i = 0; i < input.length; i++) {
23422
23433
  const cursor = input[i];
@@ -23425,29 +23436,28 @@ function requireUtils () {
23425
23436
  if (endipv6Encountered === true) {
23426
23437
  endIpv6 = true;
23427
23438
  }
23428
- if (!consume()) { break }
23429
- tokenCount++;
23430
- address.push(':');
23431
- if (tokenCount > 7) {
23439
+ if (!consume(buffer, address, output)) { break }
23440
+ if (++tokenCount > 7) {
23432
23441
  // not valid
23433
23442
  output.error = true;
23434
23443
  break
23435
23444
  }
23436
- if (i - 1 >= 0 && input[i - 1] === ':') {
23445
+ if (i > 0 && input[i - 1] === ':') {
23437
23446
  endipv6Encountered = true;
23438
23447
  }
23448
+ address.push(':');
23439
23449
  continue
23440
23450
  } else if (cursor === '%') {
23441
- if (!consume()) { break }
23451
+ if (!consume(buffer, address, output)) { break }
23442
23452
  // switch to zone detection
23443
- isZone = true;
23453
+ consume = consumeIsZone;
23444
23454
  } else {
23445
23455
  buffer.push(cursor);
23446
23456
  continue
23447
23457
  }
23448
23458
  }
23449
23459
  if (buffer.length) {
23450
- if (isZone) {
23460
+ if (consume === consumeIsZone) {
23451
23461
  output.zone = buffer.join('');
23452
23462
  } else if (endIpv6) {
23453
23463
  address.push(buffer.join(''));
@@ -23459,6 +23469,17 @@ function requireUtils () {
23459
23469
  return output
23460
23470
  }
23461
23471
 
23472
+ /**
23473
+ * @typedef {Object} NormalizeIPv6Result
23474
+ * @property {string} host - The normalized host.
23475
+ * @property {string} [escapedHost] - The escaped host.
23476
+ * @property {boolean} isIPV6 - Indicates if the host is an IPv6 address.
23477
+ */
23478
+
23479
+ /**
23480
+ * @param {string} host
23481
+ * @returns {NormalizeIPv6Result}
23482
+ */
23462
23483
  function normalizeIPv6 (host) {
23463
23484
  if (findToken(host, ':') < 2) { return { host, isIPV6: false } }
23464
23485
  const ipv6 = getIPV6(host);
@@ -23470,35 +23491,17 @@ function requireUtils () {
23470
23491
  newHost += '%' + ipv6.zone;
23471
23492
  escapedHost += '%25' + ipv6.zone;
23472
23493
  }
23473
- return { host: newHost, escapedHost, isIPV6: true }
23494
+ return { host: newHost, isIPV6: true, escapedHost }
23474
23495
  } else {
23475
23496
  return { host, isIPV6: false }
23476
23497
  }
23477
23498
  }
23478
23499
 
23479
- function stripLeadingZeros (str, token) {
23480
- let out = '';
23481
- let skip = true;
23482
- const l = str.length;
23483
- for (let i = 0; i < l; i++) {
23484
- const c = str[i];
23485
- if (c === '0' && skip) {
23486
- if ((i + 1 <= l && str[i + 1] === token) || i + 1 === l) {
23487
- out += c;
23488
- skip = false;
23489
- }
23490
- } else {
23491
- if (c === token) {
23492
- skip = true;
23493
- } else {
23494
- skip = false;
23495
- }
23496
- out += c;
23497
- }
23498
- }
23499
- return out
23500
- }
23501
-
23500
+ /**
23501
+ * @param {string} str
23502
+ * @param {string} token
23503
+ * @returns {number}
23504
+ */
23502
23505
  function findToken (str, token) {
23503
23506
  let ind = 0;
23504
23507
  for (let i = 0; i < str.length; i++) {
@@ -23507,98 +23510,160 @@ function requireUtils () {
23507
23510
  return ind
23508
23511
  }
23509
23512
 
23510
- const RDS1 = /^\.\.?\//u;
23511
- const RDS2 = /^\/\.(?:\/|$)/u;
23512
- const RDS3 = /^\/\.\.(?:\/|$)/u;
23513
- const RDS5 = /^\/?(?:.|\n)*?(?=\/|$)/u;
23514
-
23515
- function removeDotSegments (input) {
23513
+ /**
23514
+ * @param {string} path
23515
+ * @returns {string}
23516
+ *
23517
+ * @see https://datatracker.ietf.org/doc/html/rfc3986#section-5.2.4
23518
+ */
23519
+ function removeDotSegments (path) {
23520
+ let input = path;
23516
23521
  const output = [];
23522
+ let nextSlash = -1;
23523
+ let len = 0;
23517
23524
 
23518
- while (input.length) {
23519
- if (input.match(RDS1)) {
23520
- input = input.replace(RDS1, '');
23521
- } else if (input.match(RDS2)) {
23522
- input = input.replace(RDS2, '/');
23523
- } else if (input.match(RDS3)) {
23524
- input = input.replace(RDS3, '/');
23525
- output.pop();
23526
- } else if (input === '.' || input === '..') {
23527
- input = '';
23528
- } else {
23529
- const im = input.match(RDS5);
23530
- if (im) {
23531
- const s = im[0];
23532
- input = input.slice(s.length);
23533
- output.push(s);
23525
+ // eslint-disable-next-line no-cond-assign
23526
+ while (len = input.length) {
23527
+ if (len === 1) {
23528
+ if (input === '.') {
23529
+ break
23530
+ } else if (input === '/') {
23531
+ output.push('/');
23532
+ break
23534
23533
  } else {
23535
- throw new Error('Unexpected dot segment condition')
23534
+ output.push(input);
23535
+ break
23536
+ }
23537
+ } else if (len === 2) {
23538
+ if (input[0] === '.') {
23539
+ if (input[1] === '.') {
23540
+ break
23541
+ } else if (input[1] === '/') {
23542
+ input = input.slice(2);
23543
+ continue
23544
+ }
23545
+ } else if (input[0] === '/') {
23546
+ if (input[1] === '.' || input[1] === '/') {
23547
+ output.push('/');
23548
+ break
23549
+ }
23550
+ }
23551
+ } else if (len === 3) {
23552
+ if (input === '/..') {
23553
+ if (output.length !== 0) {
23554
+ output.pop();
23555
+ }
23556
+ output.push('/');
23557
+ break
23536
23558
  }
23537
23559
  }
23560
+ if (input[0] === '.') {
23561
+ if (input[1] === '.') {
23562
+ if (input[2] === '/') {
23563
+ input = input.slice(3);
23564
+ continue
23565
+ }
23566
+ } else if (input[1] === '/') {
23567
+ input = input.slice(2);
23568
+ continue
23569
+ }
23570
+ } else if (input[0] === '/') {
23571
+ if (input[1] === '.') {
23572
+ if (input[2] === '/') {
23573
+ input = input.slice(2);
23574
+ continue
23575
+ } else if (input[2] === '.') {
23576
+ if (input[3] === '/') {
23577
+ input = input.slice(3);
23578
+ if (output.length !== 0) {
23579
+ output.pop();
23580
+ }
23581
+ continue
23582
+ }
23583
+ }
23584
+ }
23585
+ }
23586
+
23587
+ // Rule 2E: Move normal path segment to output
23588
+ if ((nextSlash = input.indexOf('/', 1)) === -1) {
23589
+ output.push(input);
23590
+ break
23591
+ } else {
23592
+ output.push(input.slice(0, nextSlash));
23593
+ input = input.slice(nextSlash);
23594
+ }
23538
23595
  }
23596
+
23539
23597
  return output.join('')
23540
23598
  }
23541
23599
 
23542
- function normalizeComponentEncoding (components, esc) {
23600
+ /**
23601
+ * @param {import('../types/index').URIComponent} component
23602
+ * @param {boolean} esc
23603
+ * @returns {import('../types/index').URIComponent}
23604
+ */
23605
+ function normalizeComponentEncoding (component, esc) {
23543
23606
  const func = esc !== true ? escape : unescape;
23544
- if (components.scheme !== undefined) {
23545
- components.scheme = func(components.scheme);
23607
+ if (component.scheme !== undefined) {
23608
+ component.scheme = func(component.scheme);
23546
23609
  }
23547
- if (components.userinfo !== undefined) {
23548
- components.userinfo = func(components.userinfo);
23610
+ if (component.userinfo !== undefined) {
23611
+ component.userinfo = func(component.userinfo);
23549
23612
  }
23550
- if (components.host !== undefined) {
23551
- components.host = func(components.host);
23613
+ if (component.host !== undefined) {
23614
+ component.host = func(component.host);
23552
23615
  }
23553
- if (components.path !== undefined) {
23554
- components.path = func(components.path);
23616
+ if (component.path !== undefined) {
23617
+ component.path = func(component.path);
23555
23618
  }
23556
- if (components.query !== undefined) {
23557
- components.query = func(components.query);
23619
+ if (component.query !== undefined) {
23620
+ component.query = func(component.query);
23558
23621
  }
23559
- if (components.fragment !== undefined) {
23560
- components.fragment = func(components.fragment);
23622
+ if (component.fragment !== undefined) {
23623
+ component.fragment = func(component.fragment);
23561
23624
  }
23562
- return components
23625
+ return component
23563
23626
  }
23564
23627
 
23565
- function recomposeAuthority (components) {
23628
+ /**
23629
+ * @param {import('../types/index').URIComponent} component
23630
+ * @returns {string|undefined}
23631
+ */
23632
+ function recomposeAuthority (component) {
23566
23633
  const uriTokens = [];
23567
23634
 
23568
- if (components.userinfo !== undefined) {
23569
- uriTokens.push(components.userinfo);
23635
+ if (component.userinfo !== undefined) {
23636
+ uriTokens.push(component.userinfo);
23570
23637
  uriTokens.push('@');
23571
23638
  }
23572
23639
 
23573
- if (components.host !== undefined) {
23574
- let host = unescape(components.host);
23575
- const ipV4res = normalizeIPv4(host);
23576
-
23577
- if (ipV4res.isIPV4) {
23578
- host = ipV4res.host;
23579
- } else {
23580
- const ipV6res = normalizeIPv6(ipV4res.host);
23640
+ if (component.host !== undefined) {
23641
+ let host = unescape(component.host);
23642
+ if (!isIPv4(host)) {
23643
+ const ipV6res = normalizeIPv6(host);
23581
23644
  if (ipV6res.isIPV6 === true) {
23582
23645
  host = `[${ipV6res.escapedHost}]`;
23583
23646
  } else {
23584
- host = components.host;
23647
+ host = component.host;
23585
23648
  }
23586
23649
  }
23587
23650
  uriTokens.push(host);
23588
23651
  }
23589
23652
 
23590
- if (typeof components.port === 'number' || typeof components.port === 'string') {
23653
+ if (typeof component.port === 'number' || typeof component.port === 'string') {
23591
23654
  uriTokens.push(':');
23592
- uriTokens.push(String(components.port));
23655
+ uriTokens.push(String(component.port));
23593
23656
  }
23594
23657
 
23595
23658
  return uriTokens.length ? uriTokens.join('') : undefined
23596
23659
  }
23597
23660
  utils = {
23661
+ nonSimpleDomain,
23598
23662
  recomposeAuthority,
23599
23663
  normalizeComponentEncoding,
23600
23664
  removeDotSegments,
23601
- normalizeIPv4,
23665
+ isIPv4,
23666
+ isUUID,
23602
23667
  normalizeIPv6,
23603
23668
  stringArrayToHexStripped
23604
23669
  };
@@ -23612,192 +23677,271 @@ function requireSchemes () {
23612
23677
  if (hasRequiredSchemes) return schemes;
23613
23678
  hasRequiredSchemes = 1;
23614
23679
 
23615
- const UUID_REG = /^[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}$/iu;
23680
+ const { isUUID } = requireUtils();
23616
23681
  const URN_REG = /([\da-z][\d\-a-z]{0,31}):((?:[\w!$'()*+,\-.:;=@]|%[\da-f]{2})+)/iu;
23617
23682
 
23618
- function isSecure (wsComponents) {
23619
- return typeof wsComponents.secure === 'boolean' ? wsComponents.secure : String(wsComponents.scheme).toLowerCase() === 'wss'
23683
+ const supportedSchemeNames = /** @type {const} */ (['http', 'https', 'ws',
23684
+ 'wss', 'urn', 'urn:uuid']);
23685
+
23686
+ /** @typedef {supportedSchemeNames[number]} SchemeName */
23687
+
23688
+ /**
23689
+ * @param {string} name
23690
+ * @returns {name is SchemeName}
23691
+ */
23692
+ function isValidSchemeName (name) {
23693
+ return supportedSchemeNames.indexOf(/** @type {*} */ (name)) !== -1
23694
+ }
23695
+
23696
+ /**
23697
+ * @callback SchemeFn
23698
+ * @param {import('../types/index').URIComponent} component
23699
+ * @param {import('../types/index').Options} options
23700
+ * @returns {import('../types/index').URIComponent}
23701
+ */
23702
+
23703
+ /**
23704
+ * @typedef {Object} SchemeHandler
23705
+ * @property {SchemeName} scheme - The scheme name.
23706
+ * @property {boolean} [domainHost] - Indicates if the scheme supports domain hosts.
23707
+ * @property {SchemeFn} parse - Function to parse the URI component for this scheme.
23708
+ * @property {SchemeFn} serialize - Function to serialize the URI component for this scheme.
23709
+ * @property {boolean} [skipNormalize] - Indicates if normalization should be skipped for this scheme.
23710
+ * @property {boolean} [absolutePath] - Indicates if the scheme uses absolute paths.
23711
+ * @property {boolean} [unicodeSupport] - Indicates if the scheme supports Unicode.
23712
+ */
23713
+
23714
+ /**
23715
+ * @param {import('../types/index').URIComponent} wsComponent
23716
+ * @returns {boolean}
23717
+ */
23718
+ function wsIsSecure (wsComponent) {
23719
+ if (wsComponent.secure === true) {
23720
+ return true
23721
+ } else if (wsComponent.secure === false) {
23722
+ return false
23723
+ } else if (wsComponent.scheme) {
23724
+ return (
23725
+ wsComponent.scheme.length === 3 &&
23726
+ (wsComponent.scheme[0] === 'w' || wsComponent.scheme[0] === 'W') &&
23727
+ (wsComponent.scheme[1] === 's' || wsComponent.scheme[1] === 'S') &&
23728
+ (wsComponent.scheme[2] === 's' || wsComponent.scheme[2] === 'S')
23729
+ )
23730
+ } else {
23731
+ return false
23732
+ }
23620
23733
  }
23621
23734
 
23622
- function httpParse (components) {
23623
- if (!components.host) {
23624
- components.error = components.error || 'HTTP URIs must have a host.';
23735
+ /** @type {SchemeFn} */
23736
+ function httpParse (component) {
23737
+ if (!component.host) {
23738
+ component.error = component.error || 'HTTP URIs must have a host.';
23625
23739
  }
23626
23740
 
23627
- return components
23741
+ return component
23628
23742
  }
23629
23743
 
23630
- function httpSerialize (components) {
23631
- const secure = String(components.scheme).toLowerCase() === 'https';
23744
+ /** @type {SchemeFn} */
23745
+ function httpSerialize (component) {
23746
+ const secure = String(component.scheme).toLowerCase() === 'https';
23632
23747
 
23633
23748
  // normalize the default port
23634
- if (components.port === (secure ? 443 : 80) || components.port === '') {
23635
- components.port = undefined;
23749
+ if (component.port === (secure ? 443 : 80) || component.port === '') {
23750
+ component.port = undefined;
23636
23751
  }
23637
23752
 
23638
23753
  // normalize the empty path
23639
- if (!components.path) {
23640
- components.path = '/';
23754
+ if (!component.path) {
23755
+ component.path = '/';
23641
23756
  }
23642
23757
 
23643
23758
  // NOTE: We do not parse query strings for HTTP URIs
23644
23759
  // as WWW Form Url Encoded query strings are part of the HTML4+ spec,
23645
23760
  // and not the HTTP spec.
23646
23761
 
23647
- return components
23762
+ return component
23648
23763
  }
23649
23764
 
23650
- function wsParse (wsComponents) {
23765
+ /** @type {SchemeFn} */
23766
+ function wsParse (wsComponent) {
23651
23767
  // indicate if the secure flag is set
23652
- wsComponents.secure = isSecure(wsComponents);
23768
+ wsComponent.secure = wsIsSecure(wsComponent);
23653
23769
 
23654
23770
  // construct resouce name
23655
- wsComponents.resourceName = (wsComponents.path || '/') + (wsComponents.query ? '?' + wsComponents.query : '');
23656
- wsComponents.path = undefined;
23657
- wsComponents.query = undefined;
23771
+ wsComponent.resourceName = (wsComponent.path || '/') + (wsComponent.query ? '?' + wsComponent.query : '');
23772
+ wsComponent.path = undefined;
23773
+ wsComponent.query = undefined;
23658
23774
 
23659
- return wsComponents
23775
+ return wsComponent
23660
23776
  }
23661
23777
 
23662
- function wsSerialize (wsComponents) {
23778
+ /** @type {SchemeFn} */
23779
+ function wsSerialize (wsComponent) {
23663
23780
  // normalize the default port
23664
- if (wsComponents.port === (isSecure(wsComponents) ? 443 : 80) || wsComponents.port === '') {
23665
- wsComponents.port = undefined;
23781
+ if (wsComponent.port === (wsIsSecure(wsComponent) ? 443 : 80) || wsComponent.port === '') {
23782
+ wsComponent.port = undefined;
23666
23783
  }
23667
23784
 
23668
23785
  // ensure scheme matches secure flag
23669
- if (typeof wsComponents.secure === 'boolean') {
23670
- wsComponents.scheme = (wsComponents.secure ? 'wss' : 'ws');
23671
- wsComponents.secure = undefined;
23786
+ if (typeof wsComponent.secure === 'boolean') {
23787
+ wsComponent.scheme = (wsComponent.secure ? 'wss' : 'ws');
23788
+ wsComponent.secure = undefined;
23672
23789
  }
23673
23790
 
23674
23791
  // reconstruct path from resource name
23675
- if (wsComponents.resourceName) {
23676
- const [path, query] = wsComponents.resourceName.split('?');
23677
- wsComponents.path = (path && path !== '/' ? path : undefined);
23678
- wsComponents.query = query;
23679
- wsComponents.resourceName = undefined;
23792
+ if (wsComponent.resourceName) {
23793
+ const [path, query] = wsComponent.resourceName.split('?');
23794
+ wsComponent.path = (path && path !== '/' ? path : undefined);
23795
+ wsComponent.query = query;
23796
+ wsComponent.resourceName = undefined;
23680
23797
  }
23681
23798
 
23682
23799
  // forbid fragment component
23683
- wsComponents.fragment = undefined;
23800
+ wsComponent.fragment = undefined;
23684
23801
 
23685
- return wsComponents
23802
+ return wsComponent
23686
23803
  }
23687
23804
 
23688
- function urnParse (urnComponents, options) {
23689
- if (!urnComponents.path) {
23690
- urnComponents.error = 'URN can not be parsed';
23691
- return urnComponents
23805
+ /** @type {SchemeFn} */
23806
+ function urnParse (urnComponent, options) {
23807
+ if (!urnComponent.path) {
23808
+ urnComponent.error = 'URN can not be parsed';
23809
+ return urnComponent
23692
23810
  }
23693
- const matches = urnComponents.path.match(URN_REG);
23811
+ const matches = urnComponent.path.match(URN_REG);
23694
23812
  if (matches) {
23695
- const scheme = options.scheme || urnComponents.scheme || 'urn';
23696
- urnComponents.nid = matches[1].toLowerCase();
23697
- urnComponents.nss = matches[2];
23698
- const urnScheme = `${scheme}:${options.nid || urnComponents.nid}`;
23699
- const schemeHandler = SCHEMES[urnScheme];
23700
- urnComponents.path = undefined;
23813
+ const scheme = options.scheme || urnComponent.scheme || 'urn';
23814
+ urnComponent.nid = matches[1].toLowerCase();
23815
+ urnComponent.nss = matches[2];
23816
+ const urnScheme = `${scheme}:${options.nid || urnComponent.nid}`;
23817
+ const schemeHandler = getSchemeHandler(urnScheme);
23818
+ urnComponent.path = undefined;
23701
23819
 
23702
23820
  if (schemeHandler) {
23703
- urnComponents = schemeHandler.parse(urnComponents, options);
23821
+ urnComponent = schemeHandler.parse(urnComponent, options);
23704
23822
  }
23705
23823
  } else {
23706
- urnComponents.error = urnComponents.error || 'URN can not be parsed.';
23824
+ urnComponent.error = urnComponent.error || 'URN can not be parsed.';
23707
23825
  }
23708
23826
 
23709
- return urnComponents
23827
+ return urnComponent
23710
23828
  }
23711
23829
 
23712
- function urnSerialize (urnComponents, options) {
23713
- const scheme = options.scheme || urnComponents.scheme || 'urn';
23714
- const nid = urnComponents.nid.toLowerCase();
23830
+ /** @type {SchemeFn} */
23831
+ function urnSerialize (urnComponent, options) {
23832
+ if (urnComponent.nid === undefined) {
23833
+ throw new Error('URN without nid cannot be serialized')
23834
+ }
23835
+ const scheme = options.scheme || urnComponent.scheme || 'urn';
23836
+ const nid = urnComponent.nid.toLowerCase();
23715
23837
  const urnScheme = `${scheme}:${options.nid || nid}`;
23716
- const schemeHandler = SCHEMES[urnScheme];
23838
+ const schemeHandler = getSchemeHandler(urnScheme);
23717
23839
 
23718
23840
  if (schemeHandler) {
23719
- urnComponents = schemeHandler.serialize(urnComponents, options);
23841
+ urnComponent = schemeHandler.serialize(urnComponent, options);
23720
23842
  }
23721
23843
 
23722
- const uriComponents = urnComponents;
23723
- const nss = urnComponents.nss;
23724
- uriComponents.path = `${nid || options.nid}:${nss}`;
23844
+ const uriComponent = urnComponent;
23845
+ const nss = urnComponent.nss;
23846
+ uriComponent.path = `${nid || options.nid}:${nss}`;
23725
23847
 
23726
23848
  options.skipEscape = true;
23727
- return uriComponents
23849
+ return uriComponent
23728
23850
  }
23729
23851
 
23730
- function urnuuidParse (urnComponents, options) {
23731
- const uuidComponents = urnComponents;
23732
- uuidComponents.uuid = uuidComponents.nss;
23733
- uuidComponents.nss = undefined;
23852
+ /** @type {SchemeFn} */
23853
+ function urnuuidParse (urnComponent, options) {
23854
+ const uuidComponent = urnComponent;
23855
+ uuidComponent.uuid = uuidComponent.nss;
23856
+ uuidComponent.nss = undefined;
23734
23857
 
23735
- if (!options.tolerant && (!uuidComponents.uuid || !UUID_REG.test(uuidComponents.uuid))) {
23736
- uuidComponents.error = uuidComponents.error || 'UUID is not valid.';
23858
+ if (!options.tolerant && (!uuidComponent.uuid || !isUUID(uuidComponent.uuid))) {
23859
+ uuidComponent.error = uuidComponent.error || 'UUID is not valid.';
23737
23860
  }
23738
23861
 
23739
- return uuidComponents
23862
+ return uuidComponent
23740
23863
  }
23741
23864
 
23742
- function urnuuidSerialize (uuidComponents) {
23743
- const urnComponents = uuidComponents;
23865
+ /** @type {SchemeFn} */
23866
+ function urnuuidSerialize (uuidComponent) {
23867
+ const urnComponent = uuidComponent;
23744
23868
  // normalize UUID
23745
- urnComponents.nss = (uuidComponents.uuid || '').toLowerCase();
23746
- return urnComponents
23869
+ urnComponent.nss = (uuidComponent.uuid || '').toLowerCase();
23870
+ return urnComponent
23747
23871
  }
23748
23872
 
23749
- const http = {
23873
+ const http = /** @type {SchemeHandler} */ ({
23750
23874
  scheme: 'http',
23751
23875
  domainHost: true,
23752
23876
  parse: httpParse,
23753
23877
  serialize: httpSerialize
23754
- };
23878
+ });
23755
23879
 
23756
- const https = {
23880
+ const https = /** @type {SchemeHandler} */ ({
23757
23881
  scheme: 'https',
23758
23882
  domainHost: http.domainHost,
23759
23883
  parse: httpParse,
23760
23884
  serialize: httpSerialize
23761
- };
23885
+ });
23762
23886
 
23763
- const ws = {
23887
+ const ws = /** @type {SchemeHandler} */ ({
23764
23888
  scheme: 'ws',
23765
23889
  domainHost: true,
23766
23890
  parse: wsParse,
23767
23891
  serialize: wsSerialize
23768
- };
23892
+ });
23769
23893
 
23770
- const wss = {
23894
+ const wss = /** @type {SchemeHandler} */ ({
23771
23895
  scheme: 'wss',
23772
23896
  domainHost: ws.domainHost,
23773
23897
  parse: ws.parse,
23774
23898
  serialize: ws.serialize
23775
- };
23899
+ });
23776
23900
 
23777
- const urn = {
23901
+ const urn = /** @type {SchemeHandler} */ ({
23778
23902
  scheme: 'urn',
23779
23903
  parse: urnParse,
23780
23904
  serialize: urnSerialize,
23781
23905
  skipNormalize: true
23782
- };
23906
+ });
23783
23907
 
23784
- const urnuuid = {
23908
+ const urnuuid = /** @type {SchemeHandler} */ ({
23785
23909
  scheme: 'urn:uuid',
23786
23910
  parse: urnuuidParse,
23787
23911
  serialize: urnuuidSerialize,
23788
23912
  skipNormalize: true
23789
- };
23913
+ });
23790
23914
 
23791
- const SCHEMES = {
23915
+ const SCHEMES = /** @type {Record<SchemeName, SchemeHandler>} */ ({
23792
23916
  http,
23793
23917
  https,
23794
23918
  ws,
23795
23919
  wss,
23796
23920
  urn,
23797
23921
  'urn:uuid': urnuuid
23798
- };
23922
+ });
23923
+
23924
+ Object.setPrototypeOf(SCHEMES, null);
23925
+
23926
+ /**
23927
+ * @param {string|undefined} scheme
23928
+ * @returns {SchemeHandler|undefined}
23929
+ */
23930
+ function getSchemeHandler (scheme) {
23931
+ return (
23932
+ scheme && (
23933
+ SCHEMES[/** @type {SchemeName} */ (scheme)] ||
23934
+ SCHEMES[/** @type {SchemeName} */(scheme.toLowerCase())])
23935
+ ) ||
23936
+ undefined
23937
+ }
23799
23938
 
23800
- schemes = SCHEMES;
23939
+ schemes = {
23940
+ wsIsSecure,
23941
+ SCHEMES,
23942
+ isValidSchemeName,
23943
+ getSchemeHandler,
23944
+ };
23801
23945
  return schemes;
23802
23946
  }
23803
23947
 
@@ -23807,29 +23951,50 @@ function requireFastUri () {
23807
23951
  if (hasRequiredFastUri) return fastUri.exports;
23808
23952
  hasRequiredFastUri = 1;
23809
23953
 
23810
- const { normalizeIPv6, normalizeIPv4, removeDotSegments, recomposeAuthority, normalizeComponentEncoding } = requireUtils();
23811
- const SCHEMES = requireSchemes();
23954
+ const { normalizeIPv6, removeDotSegments, recomposeAuthority, normalizeComponentEncoding, isIPv4, nonSimpleDomain } = requireUtils();
23955
+ const { SCHEMES, getSchemeHandler } = requireSchemes();
23812
23956
 
23957
+ /**
23958
+ * @template {import('./types/index').URIComponent|string} T
23959
+ * @param {T} uri
23960
+ * @param {import('./types/index').Options} [options]
23961
+ * @returns {T}
23962
+ */
23813
23963
  function normalize (uri, options) {
23814
23964
  if (typeof uri === 'string') {
23815
- uri = serialize(parse(uri, options), options);
23965
+ uri = /** @type {T} */ (serialize(parse(uri, options), options));
23816
23966
  } else if (typeof uri === 'object') {
23817
- uri = parse(serialize(uri, options), options);
23967
+ uri = /** @type {T} */ (parse(serialize(uri, options), options));
23818
23968
  }
23819
23969
  return uri
23820
23970
  }
23821
23971
 
23972
+ /**
23973
+ * @param {string} baseURI
23974
+ * @param {string} relativeURI
23975
+ * @param {import('./types/index').Options} [options]
23976
+ * @returns {string}
23977
+ */
23822
23978
  function resolve (baseURI, relativeURI, options) {
23823
- const schemelessOptions = Object.assign({ scheme: 'null' }, options);
23824
- const resolved = resolveComponents(parse(baseURI, schemelessOptions), parse(relativeURI, schemelessOptions), schemelessOptions, true);
23825
- return serialize(resolved, { ...schemelessOptions, skipEscape: true })
23979
+ const schemelessOptions = options ? Object.assign({ scheme: 'null' }, options) : { scheme: 'null' };
23980
+ const resolved = resolveComponent(parse(baseURI, schemelessOptions), parse(relativeURI, schemelessOptions), schemelessOptions, true);
23981
+ schemelessOptions.skipEscape = true;
23982
+ return serialize(resolved, schemelessOptions)
23826
23983
  }
23827
23984
 
23828
- function resolveComponents (base, relative, options, skipNormalization) {
23985
+ /**
23986
+ * @param {import ('./types/index').URIComponent} base
23987
+ * @param {import ('./types/index').URIComponent} relative
23988
+ * @param {import('./types/index').Options} [options]
23989
+ * @param {boolean} [skipNormalization=false]
23990
+ * @returns {import ('./types/index').URIComponent}
23991
+ */
23992
+ function resolveComponent (base, relative, options, skipNormalization) {
23993
+ /** @type {import('./types/index').URIComponent} */
23829
23994
  const target = {};
23830
23995
  if (!skipNormalization) {
23831
- base = parse(serialize(base, options), options); // normalize base components
23832
- relative = parse(serialize(relative, options), options); // normalize relative components
23996
+ base = parse(serialize(base, options), options); // normalize base component
23997
+ relative = parse(serialize(relative, options), options); // normalize relative component
23833
23998
  }
23834
23999
  options = options || {};
23835
24000
 
@@ -23858,7 +24023,7 @@ function requireFastUri () {
23858
24023
  target.query = base.query;
23859
24024
  }
23860
24025
  } else {
23861
- if (relative.path.charAt(0) === '/') {
24026
+ if (relative.path[0] === '/') {
23862
24027
  target.path = removeDotSegments(relative.path);
23863
24028
  } else {
23864
24029
  if ((base.userinfo !== undefined || base.host !== undefined || base.port !== undefined) && !base.path) {
@@ -23885,6 +24050,12 @@ function requireFastUri () {
23885
24050
  return target
23886
24051
  }
23887
24052
 
24053
+ /**
24054
+ * @param {import ('./types/index').URIComponent|string} uriA
24055
+ * @param {import ('./types/index').URIComponent|string} uriB
24056
+ * @param {import ('./types/index').Options} options
24057
+ * @returns {boolean}
24058
+ */
23888
24059
  function equal (uriA, uriB, options) {
23889
24060
  if (typeof uriA === 'string') {
23890
24061
  uriA = unescape(uriA);
@@ -23903,8 +24074,13 @@ function requireFastUri () {
23903
24074
  return uriA.toLowerCase() === uriB.toLowerCase()
23904
24075
  }
23905
24076
 
24077
+ /**
24078
+ * @param {Readonly<import('./types/index').URIComponent>} cmpts
24079
+ * @param {import('./types/index').Options} [opts]
24080
+ * @returns {string}
24081
+ */
23906
24082
  function serialize (cmpts, opts) {
23907
- const components = {
24083
+ const component = {
23908
24084
  host: cmpts.host,
23909
24085
  scheme: cmpts.scheme,
23910
24086
  userinfo: cmpts.userinfo,
@@ -23924,28 +24100,28 @@ function requireFastUri () {
23924
24100
  const uriTokens = [];
23925
24101
 
23926
24102
  // find scheme handler
23927
- const schemeHandler = SCHEMES[(options.scheme || components.scheme || '').toLowerCase()];
24103
+ const schemeHandler = getSchemeHandler(options.scheme || component.scheme);
23928
24104
 
23929
24105
  // perform scheme specific serialization
23930
- if (schemeHandler && schemeHandler.serialize) schemeHandler.serialize(components, options);
24106
+ if (schemeHandler && schemeHandler.serialize) schemeHandler.serialize(component, options);
23931
24107
 
23932
- if (components.path !== undefined) {
24108
+ if (component.path !== undefined) {
23933
24109
  if (!options.skipEscape) {
23934
- components.path = escape(components.path);
24110
+ component.path = escape(component.path);
23935
24111
 
23936
- if (components.scheme !== undefined) {
23937
- components.path = components.path.split('%3A').join(':');
24112
+ if (component.scheme !== undefined) {
24113
+ component.path = component.path.split('%3A').join(':');
23938
24114
  }
23939
24115
  } else {
23940
- components.path = unescape(components.path);
24116
+ component.path = unescape(component.path);
23941
24117
  }
23942
24118
  }
23943
24119
 
23944
- if (options.reference !== 'suffix' && components.scheme) {
23945
- uriTokens.push(components.scheme, ':');
24120
+ if (options.reference !== 'suffix' && component.scheme) {
24121
+ uriTokens.push(component.scheme, ':');
23946
24122
  }
23947
24123
 
23948
- const authority = recomposeAuthority(components);
24124
+ const authority = recomposeAuthority(component);
23949
24125
  if (authority !== undefined) {
23950
24126
  if (options.reference !== 'suffix') {
23951
24127
  uriTokens.push('//');
@@ -23953,51 +24129,49 @@ function requireFastUri () {
23953
24129
 
23954
24130
  uriTokens.push(authority);
23955
24131
 
23956
- if (components.path && components.path.charAt(0) !== '/') {
24132
+ if (component.path && component.path[0] !== '/') {
23957
24133
  uriTokens.push('/');
23958
24134
  }
23959
24135
  }
23960
- if (components.path !== undefined) {
23961
- let s = components.path;
24136
+ if (component.path !== undefined) {
24137
+ let s = component.path;
23962
24138
 
23963
24139
  if (!options.absolutePath && (!schemeHandler || !schemeHandler.absolutePath)) {
23964
24140
  s = removeDotSegments(s);
23965
24141
  }
23966
24142
 
23967
- if (authority === undefined) {
23968
- s = s.replace(/^\/\//u, '/%2F'); // don't allow the path to start with "//"
24143
+ if (
24144
+ authority === undefined &&
24145
+ s[0] === '/' &&
24146
+ s[1] === '/'
24147
+ ) {
24148
+ // don't allow the path to start with "//"
24149
+ s = '/%2F' + s.slice(2);
23969
24150
  }
23970
24151
 
23971
24152
  uriTokens.push(s);
23972
24153
  }
23973
24154
 
23974
- if (components.query !== undefined) {
23975
- uriTokens.push('?', components.query);
24155
+ if (component.query !== undefined) {
24156
+ uriTokens.push('?', component.query);
23976
24157
  }
23977
24158
 
23978
- if (components.fragment !== undefined) {
23979
- uriTokens.push('#', components.fragment);
24159
+ if (component.fragment !== undefined) {
24160
+ uriTokens.push('#', component.fragment);
23980
24161
  }
23981
24162
  return uriTokens.join('')
23982
24163
  }
23983
24164
 
23984
- const hexLookUp = Array.from({ length: 127 }, (_v, k) => /[^!"$&'()*+,\-.;=_`a-z{}~]/u.test(String.fromCharCode(k)));
23985
-
23986
- function nonSimpleDomain (value) {
23987
- let code = 0;
23988
- for (let i = 0, len = value.length; i < len; ++i) {
23989
- code = value.charCodeAt(i);
23990
- if (code > 126 || hexLookUp[code]) {
23991
- return true
23992
- }
23993
- }
23994
- return false
23995
- }
23996
-
23997
24165
  const URI_PARSE = /^(?:([^#/:?]+):)?(?:\/\/((?:([^#/?@]*)@)?(\[[^#/?\]]+\]|[^#/:?]*)(?::(\d*))?))?([^#?]*)(?:\?([^#]*))?(?:#((?:.|[\n\r])*))?/u;
23998
24166
 
24167
+ /**
24168
+ * @param {string} uri
24169
+ * @param {import('./types/index').Options} [opts]
24170
+ * @returns
24171
+ */
23999
24172
  function parse (uri, opts) {
24000
24173
  const options = Object.assign({}, opts);
24174
+ /** @type {import('./types/index').URIComponent} */
24001
24175
  const parsed = {
24002
24176
  scheme: undefined,
24003
24177
  userinfo: undefined,
@@ -24007,9 +24181,15 @@ function requireFastUri () {
24007
24181
  query: undefined,
24008
24182
  fragment: undefined
24009
24183
  };
24010
- const gotEncoding = uri.indexOf('%') !== -1;
24184
+
24011
24185
  let isIP = false;
24012
- if (options.reference === 'suffix') uri = (options.scheme ? options.scheme + ':' : '') + '//' + uri;
24186
+ if (options.reference === 'suffix') {
24187
+ if (options.scheme) {
24188
+ uri = options.scheme + ':' + uri;
24189
+ } else {
24190
+ uri = '//' + uri;
24191
+ }
24192
+ }
24013
24193
 
24014
24194
  const matches = uri.match(URI_PARSE);
24015
24195
 
@@ -24028,13 +24208,12 @@ function requireFastUri () {
24028
24208
  parsed.port = matches[5];
24029
24209
  }
24030
24210
  if (parsed.host) {
24031
- const ipv4result = normalizeIPv4(parsed.host);
24032
- if (ipv4result.isIPV4 === false) {
24033
- const ipv6result = normalizeIPv6(ipv4result.host);
24211
+ const ipv4result = isIPv4(parsed.host);
24212
+ if (ipv4result === false) {
24213
+ const ipv6result = normalizeIPv6(parsed.host);
24034
24214
  parsed.host = ipv6result.host.toLowerCase();
24035
24215
  isIP = ipv6result.isIPV6;
24036
24216
  } else {
24037
- parsed.host = ipv4result.host;
24038
24217
  isIP = true;
24039
24218
  }
24040
24219
  }
@@ -24054,7 +24233,7 @@ function requireFastUri () {
24054
24233
  }
24055
24234
 
24056
24235
  // find scheme handler
24057
- const schemeHandler = SCHEMES[(options.scheme || parsed.scheme || '').toLowerCase()];
24236
+ const schemeHandler = getSchemeHandler(options.scheme || parsed.scheme);
24058
24237
 
24059
24238
  // check if scheme can't handle IRIs
24060
24239
  if (!options.unicodeSupport && (!schemeHandler || !schemeHandler.unicodeSupport)) {
@@ -24071,11 +24250,13 @@ function requireFastUri () {
24071
24250
  }
24072
24251
 
24073
24252
  if (!schemeHandler || (schemeHandler && !schemeHandler.skipNormalize)) {
24074
- if (gotEncoding && parsed.scheme !== undefined) {
24075
- parsed.scheme = unescape(parsed.scheme);
24076
- }
24077
- if (gotEncoding && parsed.host !== undefined) {
24078
- parsed.host = unescape(parsed.host);
24253
+ if (uri.indexOf('%') !== -1) {
24254
+ if (parsed.scheme !== undefined) {
24255
+ parsed.scheme = unescape(parsed.scheme);
24256
+ }
24257
+ if (parsed.host !== undefined) {
24258
+ parsed.host = unescape(parsed.host);
24259
+ }
24079
24260
  }
24080
24261
  if (parsed.path) {
24081
24262
  parsed.path = escape(unescape(parsed.path));
@@ -24099,7 +24280,7 @@ function requireFastUri () {
24099
24280
  SCHEMES,
24100
24281
  normalize,
24101
24282
  resolve,
24102
- resolveComponents,
24283
+ resolveComponent,
24103
24284
  equal,
24104
24285
  serialize,
24105
24286
  parse
@@ -32047,7 +32228,7 @@ class Comparator {
32047
32228
  }
32048
32229
  }
32049
32230
 
32050
- var version = "1.5.1";
32231
+ var version = "1.6.1";
32051
32232
  var packageJson = {
32052
32233
  version: version};
32053
32234