@andersbakken/fisk 4.0.0 → 4.0.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.
@@ -4300,6 +4300,750 @@ class Compile extends Client {
4300
4300
  }
4301
4301
  }
4302
4302
 
4303
+ /**
4304
+ * Check if we're required to add a port number.
4305
+ *
4306
+ * @see https://url.spec.whatwg.org/#default-port
4307
+ * @param {Number|String} port Port number we need to check
4308
+ * @param {String} protocol Protocol we need to check against.
4309
+ * @returns {Boolean} Is it a default port for the given protocol
4310
+ * @api private
4311
+ */
4312
+ var requiresPort = function required(port, protocol) {
4313
+ protocol = protocol.split(':')[0];
4314
+ port = +port;
4315
+
4316
+ if (!port) return false;
4317
+
4318
+ switch (protocol) {
4319
+ case 'http':
4320
+ case 'ws':
4321
+ return port !== 80;
4322
+
4323
+ case 'https':
4324
+ case 'wss':
4325
+ return port !== 443;
4326
+
4327
+ case 'ftp':
4328
+ return port !== 21;
4329
+
4330
+ case 'gopher':
4331
+ return port !== 70;
4332
+
4333
+ case 'file':
4334
+ return false;
4335
+ }
4336
+
4337
+ return port !== 0;
4338
+ };
4339
+
4340
+ var querystringify$1 = {};
4341
+
4342
+ var has$4 = Object.prototype.hasOwnProperty
4343
+ , undef;
4344
+
4345
+ /**
4346
+ * Decode a URI encoded string.
4347
+ *
4348
+ * @param {String} input The URI encoded string.
4349
+ * @returns {String|Null} The decoded string.
4350
+ * @api private
4351
+ */
4352
+ function decode$3(input) {
4353
+ try {
4354
+ return decodeURIComponent(input.replace(/\+/g, ' '));
4355
+ } catch (e) {
4356
+ return null;
4357
+ }
4358
+ }
4359
+
4360
+ /**
4361
+ * Attempts to encode a given input.
4362
+ *
4363
+ * @param {String} input The string that needs to be encoded.
4364
+ * @returns {String|Null} The encoded string.
4365
+ * @api private
4366
+ */
4367
+ function encode$2(input) {
4368
+ try {
4369
+ return encodeURIComponent(input);
4370
+ } catch (e) {
4371
+ return null;
4372
+ }
4373
+ }
4374
+
4375
+ /**
4376
+ * Simple query string parser.
4377
+ *
4378
+ * @param {String} query The query string that needs to be parsed.
4379
+ * @returns {Object}
4380
+ * @api public
4381
+ */
4382
+ function querystring(query) {
4383
+ var parser = /([^=?#&]+)=?([^&]*)/g
4384
+ , result = {}
4385
+ , part;
4386
+
4387
+ while (part = parser.exec(query)) {
4388
+ var key = decode$3(part[1])
4389
+ , value = decode$3(part[2]);
4390
+
4391
+ //
4392
+ // Prevent overriding of existing properties. This ensures that build-in
4393
+ // methods like `toString` or __proto__ are not overriden by malicious
4394
+ // querystrings.
4395
+ //
4396
+ // In the case if failed decoding, we want to omit the key/value pairs
4397
+ // from the result.
4398
+ //
4399
+ if (key === null || value === null || key in result) continue;
4400
+ result[key] = value;
4401
+ }
4402
+
4403
+ return result;
4404
+ }
4405
+
4406
+ /**
4407
+ * Transform a query string to an object.
4408
+ *
4409
+ * @param {Object} obj Object that should be transformed.
4410
+ * @param {String} prefix Optional prefix.
4411
+ * @returns {String}
4412
+ * @api public
4413
+ */
4414
+ function querystringify(obj, prefix) {
4415
+ prefix = prefix || '';
4416
+
4417
+ var pairs = []
4418
+ , value
4419
+ , key;
4420
+
4421
+ //
4422
+ // Optionally prefix with a '?' if needed
4423
+ //
4424
+ if ('string' !== typeof prefix) prefix = '?';
4425
+
4426
+ for (key in obj) {
4427
+ if (has$4.call(obj, key)) {
4428
+ value = obj[key];
4429
+
4430
+ //
4431
+ // Edge cases where we actually want to encode the value to an empty
4432
+ // string instead of the stringified value.
4433
+ //
4434
+ if (!value && (value === null || value === undef || isNaN(value))) {
4435
+ value = '';
4436
+ }
4437
+
4438
+ key = encode$2(key);
4439
+ value = encode$2(value);
4440
+
4441
+ //
4442
+ // If we failed to encode the strings, we should bail out as we don't
4443
+ // want to add invalid strings to the query.
4444
+ //
4445
+ if (key === null || value === null) continue;
4446
+ pairs.push(key +'='+ value);
4447
+ }
4448
+ }
4449
+
4450
+ return pairs.length ? prefix + pairs.join('&') : '';
4451
+ }
4452
+
4453
+ //
4454
+ // Expose the module.
4455
+ //
4456
+ querystringify$1.stringify = querystringify;
4457
+ querystringify$1.parse = querystring;
4458
+
4459
+ var required = requiresPort
4460
+ , qs = querystringify$1
4461
+ , controlOrWhitespace = /^[\x00-\x20\u00a0\u1680\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff]+/
4462
+ , CRHTLF = /[\n\r\t]/g
4463
+ , slashes = /^[A-Za-z][A-Za-z0-9+-.]*:\/\//
4464
+ , port = /:\d+$/
4465
+ , protocolre = /^([a-z][a-z0-9.+-]*:)?(\/\/)?([\\/]+)?([\S\s]*)/i
4466
+ , windowsDriveLetter = /^[a-zA-Z]:/;
4467
+
4468
+ /**
4469
+ * Remove control characters and whitespace from the beginning of a string.
4470
+ *
4471
+ * @param {Object|String} str String to trim.
4472
+ * @returns {String} A new string representing `str` stripped of control
4473
+ * characters and whitespace from its beginning.
4474
+ * @public
4475
+ */
4476
+ function trimLeft(str) {
4477
+ return (str ? str : '').toString().replace(controlOrWhitespace, '');
4478
+ }
4479
+
4480
+ /**
4481
+ * These are the parse rules for the URL parser, it informs the parser
4482
+ * about:
4483
+ *
4484
+ * 0. The char it Needs to parse, if it's a string it should be done using
4485
+ * indexOf, RegExp using exec and NaN means set as current value.
4486
+ * 1. The property we should set when parsing this value.
4487
+ * 2. Indication if it's backwards or forward parsing, when set as number it's
4488
+ * the value of extra chars that should be split off.
4489
+ * 3. Inherit from location if non existing in the parser.
4490
+ * 4. `toLowerCase` the resulting value.
4491
+ */
4492
+ var rules = [
4493
+ ['#', 'hash'], // Extract from the back.
4494
+ ['?', 'query'], // Extract from the back.
4495
+ function sanitize(address, url) { // Sanitize what is left of the address
4496
+ return isSpecial(url.protocol) ? address.replace(/\\/g, '/') : address;
4497
+ },
4498
+ ['/', 'pathname'], // Extract from the back.
4499
+ ['@', 'auth', 1], // Extract from the front.
4500
+ [NaN, 'host', undefined, 1, 1], // Set left over value.
4501
+ [/:(\d*)$/, 'port', undefined, 1], // RegExp the back.
4502
+ [NaN, 'hostname', undefined, 1, 1] // Set left over.
4503
+ ];
4504
+
4505
+ /**
4506
+ * These properties should not be copied or inherited from. This is only needed
4507
+ * for all non blob URL's as a blob URL does not include a hash, only the
4508
+ * origin.
4509
+ *
4510
+ * @type {Object}
4511
+ * @private
4512
+ */
4513
+ var ignore = { hash: 1, query: 1 };
4514
+
4515
+ /**
4516
+ * The location object differs when your code is loaded through a normal page,
4517
+ * Worker or through a worker using a blob. And with the blobble begins the
4518
+ * trouble as the location object will contain the URL of the blob, not the
4519
+ * location of the page where our code is loaded in. The actual origin is
4520
+ * encoded in the `pathname` so we can thankfully generate a good "default"
4521
+ * location from it so we can generate proper relative URL's again.
4522
+ *
4523
+ * @param {Object|String} loc Optional default location object.
4524
+ * @returns {Object} lolcation object.
4525
+ * @public
4526
+ */
4527
+ function lolcation(loc) {
4528
+ var globalVar;
4529
+
4530
+ if (typeof window !== 'undefined') globalVar = window;
4531
+ else if (typeof commonjsGlobal !== 'undefined') globalVar = commonjsGlobal;
4532
+ else if (typeof self !== 'undefined') globalVar = self;
4533
+ else globalVar = {};
4534
+
4535
+ var location = globalVar.location || {};
4536
+ loc = loc || location;
4537
+
4538
+ var finaldestination = {}
4539
+ , type = typeof loc
4540
+ , key;
4541
+
4542
+ if ('blob:' === loc.protocol) {
4543
+ finaldestination = new Url$1(unescape(loc.pathname), {});
4544
+ } else if ('string' === type) {
4545
+ finaldestination = new Url$1(loc, {});
4546
+ for (key in ignore) delete finaldestination[key];
4547
+ } else if ('object' === type) {
4548
+ for (key in loc) {
4549
+ if (key in ignore) continue;
4550
+ finaldestination[key] = loc[key];
4551
+ }
4552
+
4553
+ if (finaldestination.slashes === undefined) {
4554
+ finaldestination.slashes = slashes.test(loc.href);
4555
+ }
4556
+ }
4557
+
4558
+ return finaldestination;
4559
+ }
4560
+
4561
+ /**
4562
+ * Check whether a protocol scheme is special.
4563
+ *
4564
+ * @param {String} The protocol scheme of the URL
4565
+ * @return {Boolean} `true` if the protocol scheme is special, else `false`
4566
+ * @private
4567
+ */
4568
+ function isSpecial(scheme) {
4569
+ return (
4570
+ scheme === 'file:' ||
4571
+ scheme === 'ftp:' ||
4572
+ scheme === 'http:' ||
4573
+ scheme === 'https:' ||
4574
+ scheme === 'ws:' ||
4575
+ scheme === 'wss:'
4576
+ );
4577
+ }
4578
+
4579
+ /**
4580
+ * @typedef ProtocolExtract
4581
+ * @type Object
4582
+ * @property {String} protocol Protocol matched in the URL, in lowercase.
4583
+ * @property {Boolean} slashes `true` if protocol is followed by "//", else `false`.
4584
+ * @property {String} rest Rest of the URL that is not part of the protocol.
4585
+ */
4586
+
4587
+ /**
4588
+ * Extract protocol information from a URL with/without double slash ("//").
4589
+ *
4590
+ * @param {String} address URL we want to extract from.
4591
+ * @param {Object} location
4592
+ * @return {ProtocolExtract} Extracted information.
4593
+ * @private
4594
+ */
4595
+ function extractProtocol(address, location) {
4596
+ address = trimLeft(address);
4597
+ address = address.replace(CRHTLF, '');
4598
+ location = location || {};
4599
+
4600
+ var match = protocolre.exec(address);
4601
+ var protocol = match[1] ? match[1].toLowerCase() : '';
4602
+ var forwardSlashes = !!match[2];
4603
+ var otherSlashes = !!match[3];
4604
+ var slashesCount = 0;
4605
+ var rest;
4606
+
4607
+ if (forwardSlashes) {
4608
+ if (otherSlashes) {
4609
+ rest = match[2] + match[3] + match[4];
4610
+ slashesCount = match[2].length + match[3].length;
4611
+ } else {
4612
+ rest = match[2] + match[4];
4613
+ slashesCount = match[2].length;
4614
+ }
4615
+ } else {
4616
+ if (otherSlashes) {
4617
+ rest = match[3] + match[4];
4618
+ slashesCount = match[3].length;
4619
+ } else {
4620
+ rest = match[4];
4621
+ }
4622
+ }
4623
+
4624
+ if (protocol === 'file:') {
4625
+ if (slashesCount >= 2) {
4626
+ rest = rest.slice(2);
4627
+ }
4628
+ } else if (isSpecial(protocol)) {
4629
+ rest = match[4];
4630
+ } else if (protocol) {
4631
+ if (forwardSlashes) {
4632
+ rest = rest.slice(2);
4633
+ }
4634
+ } else if (slashesCount >= 2 && isSpecial(location.protocol)) {
4635
+ rest = match[4];
4636
+ }
4637
+
4638
+ return {
4639
+ protocol: protocol,
4640
+ slashes: forwardSlashes || isSpecial(protocol),
4641
+ slashesCount: slashesCount,
4642
+ rest: rest
4643
+ };
4644
+ }
4645
+
4646
+ /**
4647
+ * Resolve a relative URL pathname against a base URL pathname.
4648
+ *
4649
+ * @param {String} relative Pathname of the relative URL.
4650
+ * @param {String} base Pathname of the base URL.
4651
+ * @return {String} Resolved pathname.
4652
+ * @private
4653
+ */
4654
+ function resolve$4(relative, base) {
4655
+ if (relative === '') return base;
4656
+
4657
+ var path = (base || '/').split('/').slice(0, -1).concat(relative.split('/'))
4658
+ , i = path.length
4659
+ , last = path[i - 1]
4660
+ , unshift = false
4661
+ , up = 0;
4662
+
4663
+ while (i--) {
4664
+ if (path[i] === '.') {
4665
+ path.splice(i, 1);
4666
+ } else if (path[i] === '..') {
4667
+ path.splice(i, 1);
4668
+ up++;
4669
+ } else if (up) {
4670
+ if (i === 0) unshift = true;
4671
+ path.splice(i, 1);
4672
+ up--;
4673
+ }
4674
+ }
4675
+
4676
+ if (unshift) path.unshift('');
4677
+ if (last === '.' || last === '..') path.push('');
4678
+
4679
+ return path.join('/');
4680
+ }
4681
+
4682
+ /**
4683
+ * The actual URL instance. Instead of returning an object we've opted-in to
4684
+ * create an actual constructor as it's much more memory efficient and
4685
+ * faster and it pleases my OCD.
4686
+ *
4687
+ * It is worth noting that we should not use `URL` as class name to prevent
4688
+ * clashes with the global URL instance that got introduced in browsers.
4689
+ *
4690
+ * @constructor
4691
+ * @param {String} address URL we want to parse.
4692
+ * @param {Object|String} [location] Location defaults for relative paths.
4693
+ * @param {Boolean|Function} [parser] Parser for the query string.
4694
+ * @private
4695
+ */
4696
+ function Url$1(address, location, parser) {
4697
+ address = trimLeft(address);
4698
+ address = address.replace(CRHTLF, '');
4699
+
4700
+ if (!(this instanceof Url$1)) {
4701
+ return new Url$1(address, location, parser);
4702
+ }
4703
+
4704
+ var relative, extracted, parse, instruction, index, key
4705
+ , instructions = rules.slice()
4706
+ , type = typeof location
4707
+ , url = this
4708
+ , i = 0;
4709
+
4710
+ //
4711
+ // The following if statements allows this module two have compatibility with
4712
+ // 2 different API:
4713
+ //
4714
+ // 1. Node.js's `url.parse` api which accepts a URL, boolean as arguments
4715
+ // where the boolean indicates that the query string should also be parsed.
4716
+ //
4717
+ // 2. The `URL` interface of the browser which accepts a URL, object as
4718
+ // arguments. The supplied object will be used as default values / fall-back
4719
+ // for relative paths.
4720
+ //
4721
+ if ('object' !== type && 'string' !== type) {
4722
+ parser = location;
4723
+ location = null;
4724
+ }
4725
+
4726
+ if (parser && 'function' !== typeof parser) parser = qs.parse;
4727
+
4728
+ location = lolcation(location);
4729
+
4730
+ //
4731
+ // Extract protocol information before running the instructions.
4732
+ //
4733
+ extracted = extractProtocol(address || '', location);
4734
+ relative = !extracted.protocol && !extracted.slashes;
4735
+ url.slashes = extracted.slashes || relative && location.slashes;
4736
+ url.protocol = extracted.protocol || location.protocol || '';
4737
+ address = extracted.rest;
4738
+
4739
+ //
4740
+ // When the authority component is absent the URL starts with a path
4741
+ // component.
4742
+ //
4743
+ if (
4744
+ extracted.protocol === 'file:' && (
4745
+ extracted.slashesCount !== 2 || windowsDriveLetter.test(address)) ||
4746
+ (!extracted.slashes &&
4747
+ (extracted.protocol ||
4748
+ extracted.slashesCount < 2 ||
4749
+ !isSpecial(url.protocol)))
4750
+ ) {
4751
+ instructions[3] = [/(.*)/, 'pathname'];
4752
+ }
4753
+
4754
+ for (; i < instructions.length; i++) {
4755
+ instruction = instructions[i];
4756
+
4757
+ if (typeof instruction === 'function') {
4758
+ address = instruction(address, url);
4759
+ continue;
4760
+ }
4761
+
4762
+ parse = instruction[0];
4763
+ key = instruction[1];
4764
+
4765
+ if (parse !== parse) {
4766
+ url[key] = address;
4767
+ } else if ('string' === typeof parse) {
4768
+ index = parse === '@'
4769
+ ? address.lastIndexOf(parse)
4770
+ : address.indexOf(parse);
4771
+
4772
+ if (~index) {
4773
+ if ('number' === typeof instruction[2]) {
4774
+ url[key] = address.slice(0, index);
4775
+ address = address.slice(index + instruction[2]);
4776
+ } else {
4777
+ url[key] = address.slice(index);
4778
+ address = address.slice(0, index);
4779
+ }
4780
+ }
4781
+ } else if ((index = parse.exec(address))) {
4782
+ url[key] = index[1];
4783
+ address = address.slice(0, index.index);
4784
+ }
4785
+
4786
+ url[key] = url[key] || (
4787
+ relative && instruction[3] ? location[key] || '' : ''
4788
+ );
4789
+
4790
+ //
4791
+ // Hostname, host and protocol should be lowercased so they can be used to
4792
+ // create a proper `origin`.
4793
+ //
4794
+ if (instruction[4]) url[key] = url[key].toLowerCase();
4795
+ }
4796
+
4797
+ //
4798
+ // Also parse the supplied query string in to an object. If we're supplied
4799
+ // with a custom parser as function use that instead of the default build-in
4800
+ // parser.
4801
+ //
4802
+ if (parser) url.query = parser(url.query);
4803
+
4804
+ //
4805
+ // If the URL is relative, resolve the pathname against the base URL.
4806
+ //
4807
+ if (
4808
+ relative
4809
+ && location.slashes
4810
+ && url.pathname.charAt(0) !== '/'
4811
+ && (url.pathname !== '' || location.pathname !== '')
4812
+ ) {
4813
+ url.pathname = resolve$4(url.pathname, location.pathname);
4814
+ }
4815
+
4816
+ //
4817
+ // Default to a / for pathname if none exists. This normalizes the URL
4818
+ // to always have a /
4819
+ //
4820
+ if (url.pathname.charAt(0) !== '/' && isSpecial(url.protocol)) {
4821
+ url.pathname = '/' + url.pathname;
4822
+ }
4823
+
4824
+ //
4825
+ // We should not add port numbers if they are already the default port number
4826
+ // for a given protocol. As the host also contains the port number we're going
4827
+ // override it with the hostname which contains no port number.
4828
+ //
4829
+ if (!required(url.port, url.protocol)) {
4830
+ url.host = url.hostname;
4831
+ url.port = '';
4832
+ }
4833
+
4834
+ //
4835
+ // Parse down the `auth` for the username and password.
4836
+ //
4837
+ url.username = url.password = '';
4838
+
4839
+ if (url.auth) {
4840
+ index = url.auth.indexOf(':');
4841
+
4842
+ if (~index) {
4843
+ url.username = url.auth.slice(0, index);
4844
+ url.username = encodeURIComponent(decodeURIComponent(url.username));
4845
+
4846
+ url.password = url.auth.slice(index + 1);
4847
+ url.password = encodeURIComponent(decodeURIComponent(url.password));
4848
+ } else {
4849
+ url.username = encodeURIComponent(decodeURIComponent(url.auth));
4850
+ }
4851
+
4852
+ url.auth = url.password ? url.username +':'+ url.password : url.username;
4853
+ }
4854
+
4855
+ url.origin = url.protocol !== 'file:' && isSpecial(url.protocol) && url.host
4856
+ ? url.protocol +'//'+ url.host
4857
+ : 'null';
4858
+
4859
+ //
4860
+ // The href is just the compiled result.
4861
+ //
4862
+ url.href = url.toString();
4863
+ }
4864
+
4865
+ /**
4866
+ * This is convenience method for changing properties in the URL instance to
4867
+ * insure that they all propagate correctly.
4868
+ *
4869
+ * @param {String} part Property we need to adjust.
4870
+ * @param {Mixed} value The newly assigned value.
4871
+ * @param {Boolean|Function} fn When setting the query, it will be the function
4872
+ * used to parse the query.
4873
+ * When setting the protocol, double slash will be
4874
+ * removed from the final url if it is true.
4875
+ * @returns {URL} URL instance for chaining.
4876
+ * @public
4877
+ */
4878
+ function set(part, value, fn) {
4879
+ var url = this;
4880
+
4881
+ switch (part) {
4882
+ case 'query':
4883
+ if ('string' === typeof value && value.length) {
4884
+ value = (fn || qs.parse)(value);
4885
+ }
4886
+
4887
+ url[part] = value;
4888
+ break;
4889
+
4890
+ case 'port':
4891
+ url[part] = value;
4892
+
4893
+ if (!required(value, url.protocol)) {
4894
+ url.host = url.hostname;
4895
+ url[part] = '';
4896
+ } else if (value) {
4897
+ url.host = url.hostname +':'+ value;
4898
+ }
4899
+
4900
+ break;
4901
+
4902
+ case 'hostname':
4903
+ url[part] = value;
4904
+
4905
+ if (url.port) value += ':'+ url.port;
4906
+ url.host = value;
4907
+ break;
4908
+
4909
+ case 'host':
4910
+ url[part] = value;
4911
+
4912
+ if (port.test(value)) {
4913
+ value = value.split(':');
4914
+ url.port = value.pop();
4915
+ url.hostname = value.join(':');
4916
+ } else {
4917
+ url.hostname = value;
4918
+ url.port = '';
4919
+ }
4920
+
4921
+ break;
4922
+
4923
+ case 'protocol':
4924
+ url.protocol = value.toLowerCase();
4925
+ url.slashes = !fn;
4926
+ break;
4927
+
4928
+ case 'pathname':
4929
+ case 'hash':
4930
+ if (value) {
4931
+ var char = part === 'pathname' ? '/' : '#';
4932
+ url[part] = value.charAt(0) !== char ? char + value : value;
4933
+ } else {
4934
+ url[part] = value;
4935
+ }
4936
+ break;
4937
+
4938
+ case 'username':
4939
+ case 'password':
4940
+ url[part] = encodeURIComponent(value);
4941
+ break;
4942
+
4943
+ case 'auth':
4944
+ var index = value.indexOf(':');
4945
+
4946
+ if (~index) {
4947
+ url.username = value.slice(0, index);
4948
+ url.username = encodeURIComponent(decodeURIComponent(url.username));
4949
+
4950
+ url.password = value.slice(index + 1);
4951
+ url.password = encodeURIComponent(decodeURIComponent(url.password));
4952
+ } else {
4953
+ url.username = encodeURIComponent(decodeURIComponent(value));
4954
+ }
4955
+ }
4956
+
4957
+ for (var i = 0; i < rules.length; i++) {
4958
+ var ins = rules[i];
4959
+
4960
+ if (ins[4]) url[ins[1]] = url[ins[1]].toLowerCase();
4961
+ }
4962
+
4963
+ url.auth = url.password ? url.username +':'+ url.password : url.username;
4964
+
4965
+ url.origin = url.protocol !== 'file:' && isSpecial(url.protocol) && url.host
4966
+ ? url.protocol +'//'+ url.host
4967
+ : 'null';
4968
+
4969
+ url.href = url.toString();
4970
+
4971
+ return url;
4972
+ }
4973
+
4974
+ /**
4975
+ * Transform the properties back in to a valid and full URL string.
4976
+ *
4977
+ * @param {Function} stringify Optional query stringify function.
4978
+ * @returns {String} Compiled version of the URL.
4979
+ * @public
4980
+ */
4981
+ function toString$3(stringify) {
4982
+ if (!stringify || 'function' !== typeof stringify) stringify = qs.stringify;
4983
+
4984
+ var query
4985
+ , url = this
4986
+ , host = url.host
4987
+ , protocol = url.protocol;
4988
+
4989
+ if (protocol && protocol.charAt(protocol.length - 1) !== ':') protocol += ':';
4990
+
4991
+ var result =
4992
+ protocol +
4993
+ ((url.protocol && url.slashes) || isSpecial(url.protocol) ? '//' : '');
4994
+
4995
+ if (url.username) {
4996
+ result += url.username;
4997
+ if (url.password) result += ':'+ url.password;
4998
+ result += '@';
4999
+ } else if (url.password) {
5000
+ result += ':'+ url.password;
5001
+ result += '@';
5002
+ } else if (
5003
+ url.protocol !== 'file:' &&
5004
+ isSpecial(url.protocol) &&
5005
+ !host &&
5006
+ url.pathname !== '/'
5007
+ ) {
5008
+ //
5009
+ // Add back the empty userinfo, otherwise the original invalid URL
5010
+ // might be transformed into a valid one with `url.pathname` as host.
5011
+ //
5012
+ result += '@';
5013
+ }
5014
+
5015
+ //
5016
+ // Trailing colon is removed from `url.host` when it is parsed. If it still
5017
+ // ends with a colon, then add back the trailing colon that was removed. This
5018
+ // prevents an invalid URL from being transformed into a valid one.
5019
+ //
5020
+ if (host[host.length - 1] === ':' || (port.test(url.hostname) && !url.port)) {
5021
+ host += ':';
5022
+ }
5023
+
5024
+ result += host + url.pathname;
5025
+
5026
+ query = 'object' === typeof url.query ? stringify(url.query) : url.query;
5027
+ if (query) result += '?' !== query.charAt(0) ? '?'+ query : query;
5028
+
5029
+ if (url.hash) result += url.hash;
5030
+
5031
+ return result;
5032
+ }
5033
+
5034
+ Url$1.prototype = { set: set, toString: toString$3 };
5035
+
5036
+ //
5037
+ // Expose the URL parser and some additional properties that might be useful for
5038
+ // others or testing.
5039
+ //
5040
+ Url$1.extractProtocol = extractProtocol;
5041
+ Url$1.location = lolcation;
5042
+ Url$1.trimLeft = trimLeft;
5043
+ Url$1.qs = qs;
5044
+
5045
+ var urlParse = Url$1;
5046
+
4303
5047
  var bufferUtilExports = {};
4304
5048
  var bufferUtil$1 = {
4305
5049
  get exports(){ return bufferUtilExports; },
@@ -6836,7 +7580,7 @@ const http$3 = require$$2__default["default"];
6836
7580
  const net = require$$3__default["default"];
6837
7581
  const tls = require$$4__default$1["default"];
6838
7582
  const { randomBytes: randomBytes$1, createHash: createHash$1 } = crypto__default["default"];
6839
- const { URL: URL$1 } = require$$6__default["default"];
7583
+ const { URL } = require$$6__default["default"];
6840
7584
 
6841
7585
  const PerMessageDeflate$1 = permessageDeflate;
6842
7586
  const Receiver = receiver;
@@ -7325,11 +8069,11 @@ function initAsClient(websocket, address, protocols, options) {
7325
8069
 
7326
8070
  let parsedUrl;
7327
8071
 
7328
- if (address instanceof URL$1) {
8072
+ if (address instanceof URL) {
7329
8073
  parsedUrl = address;
7330
8074
  websocket._url = address.href;
7331
8075
  } else {
7332
- parsedUrl = new URL$1(address);
8076
+ parsedUrl = new URL(address);
7333
8077
  websocket._url = address;
7334
8078
  }
7335
8079
 
@@ -7427,7 +8171,7 @@ function initAsClient(websocket, address, protocols, options) {
7427
8171
 
7428
8172
  req.abort();
7429
8173
 
7430
- const addr = new URL$1(location, address);
8174
+ const addr = new URL(location, address);
7431
8175
 
7432
8176
  initAsClient(websocket, addr, protocols, options);
7433
8177
  } else if (!websocket.emit('unexpected-response', req, res)) {
@@ -50798,7 +51542,7 @@ class Server extends require$$0__default$2["default"] {
50798
51542
  });
50799
51543
  });
50800
51544
  this.ws.on("headers", (headers, request) => {
50801
- const url = new URL(request.url, this.baseUrl);
51545
+ const url = new urlParse(request.url, this.baseUrl);
50802
51546
  headers.push("x-fisk-object-cache: " + (this.objectCache ? "true" : "false"));
50803
51547
  if (url.pathname === "/monitor") {
50804
51548
  const nonce = crypto__default["default"].randomBytes(256).toString("base64");
@@ -51076,7 +51820,7 @@ class Server extends require$$0__default$2["default"] {
51076
51820
  if (ip.substr(0, 7) === "::ffff:") {
51077
51821
  ip = ip.substr(7);
51078
51822
  }
51079
- const url = new URL(req.url, this.baseUrl);
51823
+ const url = new urlParse(req.url, this.baseUrl);
51080
51824
  switch (url.pathname) {
51081
51825
  case "/compile":
51082
51826
  this._handleCompile(req, ws, ip);