whatwg-url 15.1.0 → 16.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.
package/README.md CHANGED
@@ -4,12 +4,10 @@ whatwg-url is a full implementation of the WHATWG [URL Standard](https://url.spe
4
4
 
5
5
  ## Specification conformance
6
6
 
7
- whatwg-url is currently up to date with the URL spec up to commit [05a5d83](https://github.com/whatwg/url/commit/05a5d834deba31622390ee05a3dcbc22496b7bb5).
7
+ whatwg-url is currently up to date with the URL spec up to commit [b6b3251](https://github.com/whatwg/url/commit/b6b3251fe911ab33d68fb051efe0e4d39ae4145e).
8
8
 
9
9
  For `file:` URLs, whose [origin is left unspecified](https://url.spec.whatwg.org/#concept-url-origin), whatwg-url chooses to use a new opaque origin (which serializes to `"null"`).
10
10
 
11
- whatwg-url does not yet implement any encoding handling beyond UTF-8. That is, the _encoding override_ parameter does not exist in our API.
12
-
13
11
  ## API
14
12
 
15
13
  ### The `URL` and `URLSearchParams` classes
@@ -20,8 +18,8 @@ The main API is provided by the [`URL`](https://url.spec.whatwg.org/#url-class)
20
18
 
21
19
  The following methods are exported for use by places like jsdom that need to implement things like [`HTMLHyperlinkElementUtils`](https://html.spec.whatwg.org/#htmlhyperlinkelementutils). They mostly operate on or return an "internal URL" or ["URL record"](https://url.spec.whatwg.org/#concept-url) type.
22
20
 
23
- - [URL parser](https://url.spec.whatwg.org/#concept-url-parser): `parseURL(input, { baseURL })`
24
- - [Basic URL parser](https://url.spec.whatwg.org/#concept-basic-url-parser): `basicURLParse(input, { baseURL, url, stateOverride })`
21
+ - [URL parser](https://url.spec.whatwg.org/#concept-url-parser): `parseURL(input, { baseURL, encoding = "UTF-8" })`
22
+ - [Basic URL parser](https://url.spec.whatwg.org/#concept-basic-url-parser): `basicURLParse(input, { baseURL, url, stateOverride, encoding = "UTF-8" })`
25
23
  - [URL serializer](https://url.spec.whatwg.org/#concept-url-serializer): `serializeURL(urlRecord, excludeFragment)`
26
24
  - [Host serializer](https://url.spec.whatwg.org/#concept-host-serializer): `serializeHost(hostFromURLRecord)`
27
25
  - [URL path serializer](https://url.spec.whatwg.org/#url-path-serializer): `serializePath(urlRecord)`
package/lib/URL-impl.js CHANGED
@@ -2,6 +2,7 @@
2
2
  const usm = require("./url-state-machine");
3
3
  const urlencoded = require("./urlencoded");
4
4
  const URLSearchParams = require("./URLSearchParams");
5
+ const URL = require("./URL");
5
6
 
6
7
  exports.implementation = class URLImpl {
7
8
  // Unlike the spec, we duplicate some code between the constructor and canParse, because we want to give useful error
@@ -32,7 +33,7 @@ exports.implementation = class URLImpl {
32
33
 
33
34
  static parse(globalObject, input, base) {
34
35
  try {
35
- return new URLImpl(globalObject, [input, base]);
36
+ return URL.createImpl(globalObject, [input, base]);
36
37
  } catch {
37
38
  return null;
38
39
  }
@@ -55,13 +55,16 @@ function isFragmentPercentEncode(c) {
55
55
 
56
56
  // https://url.spec.whatwg.org/#query-percent-encode-set
57
57
  const extraQueryPercentEncodeSet = new Set([p(" "), p("\""), p("#"), p("<"), p(">")]);
58
+ const extraQueryPercentEncodeChars = String.fromCodePoint(...[...extraQueryPercentEncodeSet].sort());
58
59
  function isQueryPercentEncode(c) {
59
60
  return isC0ControlPercentEncode(c) || extraQueryPercentEncodeSet.has(c);
60
61
  }
61
62
 
62
63
  // https://url.spec.whatwg.org/#special-query-percent-encode-set
64
+ const extraSpecialQueryPercentEncodeSet = new Set([...extraQueryPercentEncodeSet, p("'")]);
65
+ const extraSpecialQueryPercentEncodeChars = String.fromCodePoint(...[...extraSpecialQueryPercentEncodeSet].sort());
63
66
  function isSpecialQueryPercentEncode(c) {
64
- return isQueryPercentEncode(c) || c === p("'");
67
+ return isC0ControlPercentEncode(c) || extraSpecialQueryPercentEncodeSet.has(c);
65
68
  }
66
69
 
67
70
  // https://url.spec.whatwg.org/#path-percent-encode-set
@@ -135,6 +138,8 @@ module.exports = {
135
138
  isPathPercentEncode,
136
139
  isUserinfoPercentEncode,
137
140
  isURLEncodedPercentEncode,
141
+ extraQueryPercentEncodeChars,
142
+ extraSpecialQueryPercentEncodeChars,
138
143
  percentDecodeString,
139
144
  percentDecodeBytes,
140
145
  utf8PercentEncodeString,
@@ -1,11 +1,14 @@
1
1
  "use strict";
2
+ require("@exodus/bytes/encoding.js"); // for legacy multi-byte encodings
3
+ const { percentEncodeAfterEncoding } = require("@exodus/bytes/whatwg.js");
2
4
  const tr46 = require("tr46");
3
5
 
4
6
  const infra = require("./infra");
5
7
  const { utf8DecodeWithoutBOM } = require("./encoding");
6
- const { percentDecodeString, utf8PercentEncodeCodePoint, utf8PercentEncodeString, isC0ControlPercentEncode,
7
- isFragmentPercentEncode, isQueryPercentEncode, isSpecialQueryPercentEncode, isPathPercentEncode,
8
- isUserinfoPercentEncode } = require("./percent-encoding");
8
+ const { percentDecodeString, utf8PercentEncodeCodePoint, utf8PercentEncodeString,
9
+ isC0ControlPercentEncode, isFragmentPercentEncode,
10
+ extraQueryPercentEncodeChars, extraSpecialQueryPercentEncodeChars,
11
+ isPathPercentEncode, isUserinfoPercentEncode } = require("./percent-encoding");
9
12
 
10
13
  function p(char) {
11
14
  return char.codePointAt(0);
@@ -498,11 +501,11 @@ function isNormalizedWindowsDriveLetter(string) {
498
501
  return /^[A-Za-z]:$/u.test(string);
499
502
  }
500
503
 
501
- function URLStateMachine(input, base, encodingOverride, url, stateOverride) {
504
+ function URLStateMachine(input, base, encoding, url, stateOverride) {
502
505
  this.pointer = 0;
503
506
  this.input = input;
504
507
  this.base = base || null;
505
- this.encodingOverride = encodingOverride || "utf-8";
508
+ this.encoding = encoding || "utf-8";
506
509
  this.stateOverride = stateOverride;
507
510
  this.url = url;
508
511
  this.failure = false;
@@ -1092,12 +1095,16 @@ URLStateMachine.prototype["parse opaque path"] = function parseOpaquePath(c) {
1092
1095
 
1093
1096
  URLStateMachine.prototype["parse query"] = function parseQuery(c, cStr) {
1094
1097
  if (!isSpecial(this.url) || this.url.scheme === "ws" || this.url.scheme === "wss") {
1095
- this.encodingOverride = "utf-8";
1098
+ this.encoding = "utf-8";
1096
1099
  }
1097
1100
 
1098
1101
  if ((!this.stateOverride && c === p("#")) || isNaN(c)) {
1099
- const queryPercentEncodePredicate = isSpecial(this.url) ? isSpecialQueryPercentEncode : isQueryPercentEncode;
1100
- this.url.query += utf8PercentEncodeString(this.buffer, queryPercentEncodePredicate);
1102
+ const percentEncodeSet = isSpecial(this.url) ? extraSpecialQueryPercentEncodeChars : extraQueryPercentEncodeChars;
1103
+ this.url.query += percentEncodeAfterEncoding(
1104
+ this.encoding,
1105
+ this.buffer,
1106
+ percentEncodeSet
1107
+ );
1101
1108
 
1102
1109
  this.buffer = "";
1103
1110
 
@@ -1241,7 +1248,7 @@ module.exports.basicURLParse = function (input, options) {
1241
1248
  options = {};
1242
1249
  }
1243
1250
 
1244
- const usm = new URLStateMachine(input, options.baseURL, options.encodingOverride, options.url, options.stateOverride);
1251
+ const usm = new URLStateMachine(input, options.baseURL, options.encoding, options.url, options.stateOverride);
1245
1252
  if (usm.failure) {
1246
1253
  return null;
1247
1254
  }
@@ -1273,5 +1280,5 @@ module.exports.parseURL = function (input, options) {
1273
1280
  }
1274
1281
 
1275
1282
  // We don't handle blobs, so this just delegates:
1276
- return module.exports.basicURLParse(input, { baseURL: options.baseURL, encodingOverride: options.encodingOverride });
1283
+ return module.exports.basicURLParse(input, { baseURL: options.baseURL, encoding: options.encoding });
1277
1284
  };
package/lib/utils.js CHANGED
@@ -110,11 +110,22 @@ function isArrayIndexPropName(P) {
110
110
  return true;
111
111
  }
112
112
 
113
- const byteLengthGetter =
113
+ const arrayBufferByteLengthGetter =
114
114
  Object.getOwnPropertyDescriptor(ArrayBuffer.prototype, "byteLength").get;
115
115
  function isArrayBuffer(value) {
116
116
  try {
117
- byteLengthGetter.call(value);
117
+ arrayBufferByteLengthGetter.call(value);
118
+ return true;
119
+ } catch {
120
+ return false;
121
+ }
122
+ }
123
+
124
+ const sharedArrayBufferByteLengthGetter =
125
+ Object.getOwnPropertyDescriptor(SharedArrayBuffer.prototype, "byteLength").get;
126
+ function isSharedArrayBuffer(value) {
127
+ try {
128
+ sharedArrayBufferByteLengthGetter.call(value);
118
129
  return true;
119
130
  } catch {
120
131
  return false;
@@ -219,6 +230,7 @@ module.exports = exports = {
219
230
  tryImplForWrapper,
220
231
  iterInternalSymbol,
221
232
  isArrayBuffer,
233
+ isSharedArrayBuffer,
222
234
  isArrayIndexPropName,
223
235
  supportsPropertyIndex,
224
236
  supportedPropertyIndices,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "whatwg-url",
3
- "version": "15.1.0",
3
+ "version": "16.0.1",
4
4
  "description": "An implementation of the WHATWG URL Standard's URL API and parsing machinery",
5
5
  "main": "index.js",
6
6
  "files": [
@@ -15,20 +15,21 @@
15
15
  "url": "git+https://github.com/jsdom/whatwg-url.git"
16
16
  },
17
17
  "dependencies": {
18
+ "@exodus/bytes": "^1.11.0",
18
19
  "tr46": "^6.0.0",
19
- "webidl-conversions": "^8.0.0"
20
+ "webidl-conversions": "^8.0.1"
20
21
  },
21
22
  "devDependencies": {
22
- "@domenic/eslint-config": "^4.0.1",
23
- "benchmark": "^2.1.4",
23
+ "@domenic/eslint-config": "^4.1.0",
24
+ "tinybench": "^6.0.0",
24
25
  "c8": "^10.1.3",
25
- "esbuild": "^0.25.9",
26
- "eslint": "^9.35.0",
27
- "globals": "^16.4.0",
28
- "webidl2js": "^19.0.0"
26
+ "esbuild": "^0.27.2",
27
+ "eslint": "^9.39.2",
28
+ "globals": "^17.3.0",
29
+ "webidl2js": "^19.1.0"
29
30
  },
30
31
  "engines": {
31
- "node": ">=20"
32
+ "node": "^20.19.0 || ^22.12.0 || >=24.0.0"
32
33
  },
33
34
  "scripts": {
34
35
  "coverage": "c8 node --test --experimental-test-coverage test/*.js",