summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSatya Rohith <me@satyarohith.com>2021-07-06 15:02:59 +0530
committerGitHub <noreply@github.com>2021-07-06 11:32:59 +0200
commitab6b0cefd36f4a2530267c03683e1db1a1b81838 (patch)
treeb625b0bc87148830e266e640a29142402a9b934c
parente8258e0210c4690a1fbbcefe0e6a859da8efc19b (diff)
refactor: use primordials in extensions/fetch (#11266)
-rw-r--r--extensions/fetch/01_fetch_util.js1
-rw-r--r--extensions/fetch/20_headers.js102
-rw-r--r--extensions/fetch/21_formdata.js116
-rw-r--r--extensions/fetch/22_body.js36
-rw-r--r--extensions/fetch/23_request.js41
-rw-r--r--extensions/fetch/23_response.js35
-rw-r--r--extensions/fetch/26_fetch.js110
7 files changed, 307 insertions, 134 deletions
diff --git a/extensions/fetch/01_fetch_util.js b/extensions/fetch/01_fetch_util.js
index ff76421a1..9cf19588b 100644
--- a/extensions/fetch/01_fetch_util.js
+++ b/extensions/fetch/01_fetch_util.js
@@ -2,6 +2,7 @@
"use strict";
((window) => {
+ const { TypeError } = window.__bootstrap.primordials;
function requiredArguments(
name,
length,
diff --git a/extensions/fetch/20_headers.js b/extensions/fetch/20_headers.js
index 59f81a8ff..91154d958 100644
--- a/extensions/fetch/20_headers.js
+++ b/extensions/fetch/20_headers.js
@@ -22,6 +22,25 @@
collectSequenceOfCodepoints,
collectHttpQuotedString,
} = window.__bootstrap.infra;
+ const {
+ ArrayIsArray,
+ ArrayPrototypeMap,
+ ArrayPrototypePush,
+ ArrayPrototypeSort,
+ ArrayPrototypeJoin,
+ ArrayPrototypeSplice,
+ ArrayPrototypeFilter,
+ ObjectKeys,
+ ObjectEntries,
+ RegExpPrototypeTest,
+ Symbol,
+ SymbolFor,
+ SymbolIterator,
+ SymbolToStringTag,
+ StringPrototypeReplaceAll,
+ StringPrototypeIncludes,
+ TypeError,
+ } = window.__bootstrap.primordials;
const _headerList = Symbol("header list");
const _iterableHeaders = Symbol("iterable headers");
@@ -42,8 +61,16 @@
* @returns {string}
*/
function normalizeHeaderValue(potentialValue) {
- potentialValue = potentialValue.replaceAll(HTTP_WHITESPACE_PREFIX_RE, "");
- potentialValue = potentialValue.replaceAll(HTTP_WHITESPACE_SUFFIX_RE, "");
+ potentialValue = StringPrototypeReplaceAll(
+ potentialValue,
+ HTTP_WHITESPACE_PREFIX_RE,
+ "",
+ );
+ potentialValue = StringPrototypeReplaceAll(
+ potentialValue,
+ HTTP_WHITESPACE_SUFFIX_RE,
+ "",
+ );
return potentialValue;
}
@@ -52,7 +79,7 @@
* @param {HeadersInit} object
*/
function fillHeaders(headers, object) {
- if (Array.isArray(object)) {
+ if (ArrayIsArray(object)) {
for (const header of object) {
if (header.length !== 2) {
throw new TypeError(
@@ -62,7 +89,7 @@
appendHeader(headers, header[0], header[1]);
}
} else {
- for (const key of Object.keys(object)) {
+ for (const key of ObjectKeys(object)) {
appendHeader(headers, key, object[key]);
}
}
@@ -79,11 +106,13 @@
value = normalizeHeaderValue(value);
// 2.
- if (!HTTP_TOKEN_CODE_POINT_RE.test(name)) {
+ if (!RegExpPrototypeTest(HTTP_TOKEN_CODE_POINT_RE, name)) {
throw new TypeError("Header name is not valid.");
}
if (
- value.includes("\x00") || value.includes("\x0A") || value.includes("\x0D")
+ StringPrototypeIncludes(value, "\x00") ||
+ StringPrototypeIncludes(value, "\x0A") ||
+ StringPrototypeIncludes(value, "\x0D")
) {
throw new TypeError("Header value is not valid.");
}
@@ -96,7 +125,7 @@
// 7.
const list = headers[_headerList];
name = byteLowerCase(name);
- list.push([name, value]);
+ ArrayPrototypePush(list, [name, value]);
}
/**
@@ -106,13 +135,14 @@
*/
function getHeader(list, name) {
const lowercaseName = byteLowerCase(name);
- const entries = list
- .filter((entry) => entry[0] === lowercaseName)
- .map((entry) => entry[1]);
+ const entries = ArrayPrototypeMap(
+ ArrayPrototypeFilter(list, (entry) => entry[0] === lowercaseName),
+ (entry) => entry[1],
+ );
if (entries.length === 0) {
return null;
} else {
- return entries.join("\x2C\x20");
+ return ArrayPrototypeJoin(entries, "\x2C\x20");
}
}
@@ -153,10 +183,10 @@
}
}
- value = value.replaceAll(HTTP_TAB_OR_SPACE_PREFIX_RE, "");
- value = value.replaceAll(HTTP_TAB_OR_SPACE_SUFFIX_RE, "");
+ value = StringPrototypeReplaceAll(value, HTTP_TAB_OR_SPACE_PREFIX_RE, "");
+ value = StringPrototypeReplaceAll(value, HTTP_TAB_OR_SPACE_SUFFIX_RE, "");
- values.push(value);
+ ArrayPrototypePush(values, value);
value = "";
}
return values;
@@ -184,7 +214,7 @@
// so must be given to the user as multiple headers.
// The else block of the if statement is spec compliant again.
if (name === "set-cookie") {
- cookies.push([name, value]);
+ ArrayPrototypePush(cookies, [name, value]);
} else {
// The following code has the same behaviour as getHeader()
// at the end of loop. But it avoids looping through the entire
@@ -200,13 +230,16 @@
}
}
- return [...Object.entries(headers), ...cookies].sort((a, b) => {
- const akey = a[0];
- const bkey = b[0];
- if (akey > bkey) return 1;
- if (akey < bkey) return -1;
- return 0;
- });
+ return ArrayPrototypeSort(
+ [...ObjectEntries(headers), ...cookies],
+ (a, b) => {
+ const akey = a[0];
+ const bkey = b[0];
+ if (akey > bkey) return 1;
+ if (akey < bkey) return -1;
+ return 0;
+ },
+ );
}
/** @param {HeadersInit} [init] */
@@ -256,7 +289,7 @@
context: "Argument 1",
});
- if (!HTTP_TOKEN_CODE_POINT_RE.test(name)) {
+ if (!RegExpPrototypeTest(HTTP_TOKEN_CODE_POINT_RE, name)) {
throw new TypeError("Header name is not valid.");
}
if (this[_guard] == "immutable") {
@@ -267,7 +300,7 @@
name = byteLowerCase(name);
for (let i = 0; i < list.length; i++) {
if (list[i][0] === name) {
- list.splice(i, 1);
+ ArrayPrototypeSplice(list, i, 1);
i--;
}
}
@@ -284,7 +317,7 @@
context: "Argument 1",
});
- if (!HTTP_TOKEN_CODE_POINT_RE.test(name)) {
+ if (!RegExpPrototypeTest(HTTP_TOKEN_CODE_POINT_RE, name)) {
throw new TypeError("Header name is not valid.");
}
@@ -303,7 +336,7 @@
context: "Argument 1",
});
- if (!HTTP_TOKEN_CODE_POINT_RE.test(name)) {
+ if (!RegExpPrototypeTest(HTTP_TOKEN_CODE_POINT_RE, name)) {
throw new TypeError("Header name is not valid.");
}
@@ -337,12 +370,13 @@
value = normalizeHeaderValue(value);
// 2.
- if (!HTTP_TOKEN_CODE_POINT_RE.test(name)) {
+ if (!RegExpPrototypeTest(HTTP_TOKEN_CODE_POINT_RE, name)) {
throw new TypeError("Header name is not valid.");
}
if (
- value.includes("\x00") || value.includes("\x0A") ||
- value.includes("\x0D")
+ StringPrototypeIncludes(value, "\x00") ||
+ StringPrototypeIncludes(value, "\x0A") ||
+ StringPrototypeIncludes(value, "\x0D")
) {
throw new TypeError("Header value is not valid.");
}
@@ -360,17 +394,17 @@
list[i][1] = value;
added = true;
} else {
- list.splice(i, 1);
+ ArrayPrototypeSplice(list, i, 1);
i--;
}
}
}
if (!added) {
- list.push([name, value]);
+ ArrayPrototypePush(list, [name, value]);
}
}
- [Symbol.for("Deno.privateCustomInspect")](inspect) {
+ [SymbolFor("Deno.privateCustomInspect")](inspect) {
const headers = {};
for (const header of this) {
headers[header[0]] = header[1];
@@ -378,7 +412,7 @@
return `Headers ${inspect(headers)}`;
}
- get [Symbol.toStringTag]() {
+ get [SymbolToStringTag]() {
return "Headers";
}
}
@@ -390,7 +424,7 @@
webidl.converters["HeadersInit"] = (V, opts) => {
// Union for (sequence<sequence<ByteString>> or record<ByteString, ByteString>)
if (webidl.type(V) === "Object" && V !== null) {
- if (V[Symbol.iterator] !== undefined) {
+ if (V[SymbolIterator] !== undefined) {
return webidl.converters["sequence<sequence<ByteString>>"](V, opts);
}
return webidl.converters["record<ByteString, ByteString>"](V, opts);
diff --git a/extensions/fetch/21_formdata.js b/extensions/fetch/21_formdata.js
index f0033a332..25ed32c2d 100644
--- a/extensions/fetch/21_formdata.js
+++ b/extensions/fetch/21_formdata.js
@@ -14,6 +14,31 @@
const core = window.Deno.core;
const webidl = globalThis.__bootstrap.webidl;
const { Blob, File } = globalThis.__bootstrap.file;
+ const {
+ ArrayPrototypeMap,
+ ArrayPrototypePush,
+ ArrayPrototypeSlice,
+ ArrayPrototypeSplice,
+ ArrayPrototypeFilter,
+ ArrayPrototypeForEach,
+ Map,
+ MapPrototypeGet,
+ MapPrototypeSet,
+ MathRandom,
+ Symbol,
+ SymbolToStringTag,
+ StringFromCharCode,
+ StringPrototypeTrim,
+ StringPrototypeSlice,
+ StringPrototypeSplit,
+ StringPrototypeReplace,
+ StringPrototypeIndexOf,
+ StringPrototypePadStart,
+ StringPrototypeCodePointAt,
+ StringPrototypeReplaceAll,
+ TypeError,
+ TypedArrayPrototypeSubarray,
+ } = window.__bootstrap.primordials;
const entryList = Symbol("entry list");
@@ -47,7 +72,7 @@
*/
class FormData {
- get [Symbol.toStringTag]() {
+ get [SymbolToStringTag]() {
return "FormData";
}
@@ -97,7 +122,7 @@
const entry = createEntry(name, valueOrBlobValue, filename);
- this[entryList].push(entry);
+ ArrayPrototypePush(this[entryList], entry);
}
/**
@@ -117,7 +142,7 @@
const list = this[entryList];
for (let i = 0; i < list.length; i++) {
if (list[i].name === name) {
- list.splice(i, 1);
+ ArrayPrototypeSplice(list, i, 1);
i--;
}
}
@@ -159,7 +184,7 @@
const returnList = [];
for (const entry of this[entryList]) {
- if (entry.name === name) returnList.push(entry.value);
+ if (entry.name === name) ArrayPrototypePush(returnList, entry.value);
}
return returnList;
}
@@ -227,13 +252,13 @@
list[i] = entry;
added = true;
} else {
- list.splice(i, 1);
+ ArrayPrototypeSplice(list, i, 1);
i--;
}
}
}
if (!added) {
- list.push(entry);
+ ArrayPrototypePush(list, entry);
}
}
}
@@ -243,29 +268,46 @@
webidl.configurePrototype(FormData);
const escape = (str, isFilename) =>
- (isFilename ? str : str.replace(/\r?\n|\r/g, "\r\n"))
- .replace(/\n/g, "%0A")
- .replace(/\r/g, "%0D")
- .replace(/"/g, "%22");
+ StringPrototypeReplace(
+ StringPrototypeReplace(
+ StringPrototypeReplace(
+ (isFilename ? str : StringPrototypeReplace(str, /\r?\n|\r/g, "\r\n")),
+ /\n/g,
+ "%0A",
+ ),
+ /\r/g,
+ "%0D",
+ ),
+ /"/g,
+ "%22",
+ );
/**
* convert FormData to a Blob synchronous without reading all of the files
* @param {globalThis.FormData} formData
*/
function formDataToBlob(formData) {
- const boundary = `${Math.random()}${Math.random()}`
- .replaceAll(".", "").slice(-28).padStart(32, "-");
+ const boundary = StringPrototypePadStart(
+ StringPrototypeSlice(
+ StringPrototypeReplaceAll(`${MathRandom()}${MathRandom()}`, ".", ""),
+ -28,
+ ),
+ 32,
+ "-",
+ );
const chunks = [];
const prefix = `--${boundary}\r\nContent-Disposition: form-data; name="`;
for (const [name, value] of formData) {
if (typeof value === "string") {
- chunks.push(
+ ArrayPrototypePush(
+ chunks,
prefix + escape(name) + '"' + CRLF + CRLF +
- value.replace(/\r(?!\n)|(?<!\r)\n/g, CRLF) + CRLF,
+ StringPrototypeReplace(value, /\r(?!\n)|(?<!\r)\n/g, CRLF) + CRLF,
);
} else {
- chunks.push(
+ ArrayPrototypePush(
+ chunks,
prefix + escape(name) + `"; filename="${escape(value.name, true)}"` +
CRLF +
`Content-Type: ${value.type || "application/octet-stream"}\r\n\r\n`,
@@ -275,7 +317,7 @@
}
}
- chunks.push(`--${boundary}--`);
+ ArrayPrototypePush(chunks, `--${boundary}--`);
return new Blob(chunks, {
type: "multipart/form-data; boundary=" + boundary,
@@ -290,19 +332,26 @@
/** @type {Map<string, string>} */
const params = new Map();
// Forced to do so for some Map constructor param mismatch
- value
- .split(";")
- .slice(1)
- .map((s) => s.trim().split("="))
- .filter((arr) => arr.length > 1)
- .map(([k, v]) => [k, v.replace(/^"([^"]*)"$/, "$1")])
- .forEach(([k, v]) => params.set(k, v));
+ ArrayPrototypeForEach(
+ ArrayPrototypeMap(
+ ArrayPrototypeFilter(
+ ArrayPrototypeMap(
+ ArrayPrototypeSlice(StringPrototypeSplit(value, ";"), 1),
+ (s) => StringPrototypeSplit(StringPrototypeTrim(s), "="),
+ ),
+ (arr) => arr.length > 1,
+ ),
+ ([k, v]) => [k, StringPrototypeReplace(v, /^"([^"]*)"$/, "$1")],
+ ),
+ ([k, v]) => MapPrototypeSet(params, k, v),
+ );
+
return params;
}
const CRLF = "\r\n";
- const LF = CRLF.codePointAt(1);
- const CR = CRLF.codePointAt(0);
+ const LF = StringPrototypeCodePointAt(CRLF, 1);
+ const CR = StringPrototypeCodePointAt(CRLF, 0);
class MultipartParser {
/**
@@ -325,14 +374,14 @@
*/
#parseHeaders(headersText) {
const headers = new Headers();
- const rawHeaders = headersText.split("\r\n");
+ const rawHeaders = StringPrototypeSplit(headersText, "\r\n");
for (const rawHeader of rawHeaders) {
- const sepIndex = rawHeader.indexOf(":");
+ const sepIndex = StringPrototypeIndexOf(rawHeader, ":");
if (sepIndex < 0) {
continue; // Skip this header
}
- const key = rawHeader.slice(0, sepIndex);
- const value = rawHeader.slice(sepIndex + 1);
+ const key = StringPrototypeSlice(rawHeader, 0, sepIndex);
+ const value = StringPrototypeSlice(rawHeader, sepIndex + 1);
headers.set(key, value);
}
@@ -364,7 +413,7 @@
const isNewLine = byte === LF && prevByte === CR;
if (state === 1 || state === 2 || state == 3) {
- headerText += String.fromCharCode(byte);
+ headerText += StringFromCharCode(byte);
}
if (state === 0 && isNewLine) {
state = 1;
@@ -390,13 +439,14 @@
if (boundaryIndex >= this.boundary.length) {
const { headers, disposition } = this.#parseHeaders(headerText);
- const content = this.body.subarray(
+ const content = TypedArrayPrototypeSubarray(
+ this.body,
fileStart,
i - boundaryIndex - 1,
);
// https://fetch.spec.whatwg.org/#ref-for-dom-body-formdata
- const filename = disposition.get("filename");
- const name = disposition.get("name");
+ const filename = MapPrototypeGet(disposition, "filename");
+ const name = MapPrototypeGet(disposition, "name");
state = 5;
// Reset
diff --git a/extensions/fetch/22_body.js b/extensions/fetch/22_body.js
index c683ca14f..2a1a91159 100644
--- a/extensions/fetch/22_body.js
+++ b/extensions/fetch/22_body.js
@@ -21,6 +21,18 @@
const mimesniff = globalThis.__bootstrap.mimesniff;
const { isReadableStreamDisturbed, errorReadableStream, createProxy } =
globalThis.__bootstrap.streams;
+ const {
+ ArrayBufferIsView,
+ ArrayPrototypePush,
+ ArrayPrototypeMap,
+ JSONParse,
+ ObjectDefineProperties,
+ PromiseResolve,
+ TypedArrayPrototypeSet,
+ TypedArrayPrototypeSlice,
+ TypeError,
+ Uint8Array,
+ } = window.__bootstrap.primordials;
class InnerBody {
/** @type {ReadableStream<Uint8Array> | { body: Uint8Array, consumed: boolean }} */
@@ -92,13 +104,13 @@
while (true) {
const { value: chunk, done } = await reader.read();
if (done) break;
- chunks.push(chunk);
+ ArrayPrototypePush(chunks, chunk);
totalLength += chunk.byteLength;
}
const finalBuffer = new Uint8Array(totalLength);
let i = 0;
for (const chunk of chunks) {
- finalBuffer.set(chunk, i);
+ TypedArrayPrototypeSet(finalBuffer, chunk, i);
i += chunk.byteLength;
}
return finalBuffer;
@@ -165,7 +177,7 @@
if (object[bodySymbol] !== null) {
return object[bodySymbol].consume();
}
- return Promise.resolve(new Uint8Array());
+ return PromiseResolve(new Uint8Array());
}
/** @type {PropertyDescriptorMap} */
@@ -255,7 +267,7 @@
enumerable: true,
},
};
- return Object.defineProperties(prototype.prototype, mixin);
+ return ObjectDefineProperties(prototype.prototype, mixin);
}
/**
@@ -287,7 +299,10 @@
} else if (essence === "application/x-www-form-urlencoded") {
const entries = parseUrlEncoded(bytes);
return formDataFromEntries(
- entries.map((x) => ({ name: x[0], value: x[1] })),
+ ArrayPrototypeMap(
+ entries,
+ (x) => ({ name: x[0], value: x[1] }),
+ ),
);
}
}
@@ -296,7 +311,7 @@
throw new TypeError("Missing content type");
}
case "JSON":
- return JSON.parse(core.decode(bytes));
+ return JSONParse(core.decode(bytes));
case "text":
return core.decode(bytes);
}
@@ -319,15 +334,15 @@
if (object.type.length !== 0) {
contentType = object.type;
}
- } else if (ArrayBuffer.isView(object) || object instanceof ArrayBuffer) {
- const u8 = ArrayBuffer.isView(object)
+ } else if (ArrayBufferIsView(object) || object instanceof ArrayBuffer) {
+ const u8 = ArrayBufferIsView(object)
? new Uint8Array(
object.buffer,
object.byteOffset,
object.byteLength,
)
: new Uint8Array(object);
- const copy = u8.slice(0, u8.byteLength);
+ const copy = TypedArrayPrototypeSlice(u8, 0, u8.byteLength);
source = copy;
} else if (object instanceof FormData) {
const res = formDataToBlob(object);
@@ -336,6 +351,7 @@
length = res.size;
contentType = res.type;
} else if (object instanceof URLSearchParams) {
+ // TODO(@satyarohith): not sure what primordial here.
source = core.encode(object.toString());
contentType = "application/x-www-form-urlencoded;charset=UTF-8";
} else if (typeof object === "string") {
@@ -374,7 +390,7 @@
if (V instanceof ArrayBuffer || V instanceof SharedArrayBuffer) {
return webidl.converters["ArrayBuffer"](V, opts);
}
- if (ArrayBuffer.isView(V)) {
+ if (ArrayBufferIsView(V)) {
return webidl.converters["ArrayBufferView"](V, opts);
}
}
diff --git a/extensions/fetch/23_request.js b/extensions/fetch/23_request.js
index 93d13e8d8..829f7e6dc 100644
--- a/extensions/fetch/23_request.js
+++ b/extensions/fetch/23_request.js
@@ -26,6 +26,20 @@
} = window.__bootstrap.headers;
const { HttpClient } = window.__bootstrap.fetch;
const abortSignal = window.__bootstrap.abortSignal;
+ const {
+ ArrayPrototypeMap,
+ ArrayPrototypeSlice,
+ ArrayPrototypeSplice,
+ MapPrototypeHas,
+ MapPrototypeGet,
+ MapPrototypeSet,
+ ObjectKeys,
+ RegExpPrototypeTest,
+ Symbol,
+ SymbolFor,
+ SymbolToStringTag,
+ TypeError,
+ } = window.__bootstrap.primordials;
const _request = Symbol("request");
const _headers = Symbol("headers");
@@ -81,7 +95,9 @@
* @returns {InnerRequest}
*/
function cloneInnerRequest(request) {
- const headerList = [...request.headerList.map((x) => [x[0], x[1]])];
+ const headerList = [
+ ...ArrayPrototypeMap(request.headerList, (x) => [x[0], x[1]]),
+ ];
let body = null;
if (request.body !== null) {
body = request.body.clone();
@@ -129,7 +145,7 @@
}
// Regular path
- if (!HTTP_TOKEN_CODE_POINT_RE.test(m)) {
+ if (!RegExpPrototypeTest(HTTP_TOKEN_CODE_POINT_RE, m)) {
throw new TypeError("Method is not valid.");
}
const upperCase = byteUpperCase(m);
@@ -166,14 +182,17 @@
mimeType = temporaryMimeType;
if (mimesniff.essence(mimeType) !== essence) {
charset = null;
- const newCharset = mimeType.parameters.get("charset");
+ const newCharset = MapPrototypeGet(mimeType.parameters, "charset");
if (newCharset !== undefined) {
charset = newCharset;
}
essence = mimesniff.essence(mimeType);
} else {
- if (mimeType.parameters.has("charset") === null && charset !== null) {
- mimeType.parameters.set("charset", charset);
+ if (
+ MapPrototypeHas(mimeType.parameters, "charset") === null &&
+ charset !== null
+ ) {
+ MapPrototypeSet(mimeType.parameters, "charset", charset);
}
}
}
@@ -267,15 +286,17 @@
this[_headers] = headersFromHeaderList(request.headerList, "request");
// 32.
- if (Object.keys(init).length > 0) {
- let headers = headerListFromHeaders(this[_headers]).slice(
+ if (ObjectKeys(init).length > 0) {
+ let headers = ArrayPrototypeSlice(
+ headerListFromHeaders(this[_headers]),
0,
headerListFromHeaders(this[_headers]).length,
);
if (init.headers !== undefined) {
headers = init.headers;
}
- headerListFromHeaders(this[_headers]).splice(
+ ArrayPrototypeSplice(
+ headerListFromHeaders(this[_headers]),
0,
headerListFromHeaders(this[_headers]).length,
);
@@ -367,11 +388,11 @@
);
}
- get [Symbol.toStringTag]() {
+ get [SymbolToStringTag]() {
return "Request";
}
- [Symbol.for("Deno.customInspect")](inspect) {
+ [SymbolFor("Deno.customInspect")](inspect) {
const inner = {
bodyUsed: this.bodyUsed,
headers: this.headers,
diff --git a/extensions/fetch/23_response.js b/extensions/fetch/23_response.js
index 5d22b2457..32a9b466c 100644
--- a/extensions/fetch/23_response.js
+++ b/extensions/fetch/23_response.js
@@ -25,6 +25,20 @@
guardFromHeaders,
fillHeaders,
} = window.__bootstrap.headers;
+ const {
+ ArrayPrototypeMap,
+ ArrayPrototypePush,
+ MapPrototypeHas,
+ MapPrototypeGet,
+ MapPrototypeSet,
+ RangeError,
+ RegExp,
+ RegExpPrototypeTest,
+ Symbol,
+ SymbolFor,
+ SymbolToStringTag,
+ TypeError,
+ } = window.__bootstrap.primordials;
const VCHAR = ["\x21-\x7E"];
const OBS_TEXT = ["\x80-\xFF"];
@@ -75,7 +89,9 @@
*/
function cloneInnerResponse(response) {
const urlList = [...response.urlList];
- const headerList = [...response.headerList.map((x) => [x[0], x[1]])];
+ const headerList = [
+ ...ArrayPrototypeMap(response.headerList, (x) => [x[0], x[1]]),
+ ];
let body = null;
if (response.body !== null) {
body = response.body.clone();
@@ -162,14 +178,17 @@
mimeType = temporaryMimeType;
if (mimesniff.essence(mimeType) !== essence) {
charset = null;
- const newCharset = mimeType.parameters.get("charset");
+ const newCharset = MapPrototypeGet(mimeType.parameters, "charset");
if (newCharset !== undefined) {
charset = newCharset;
}
essence = mimesniff.essence(mimeType);
} else {
- if (mimeType.parameters.has("charset") === null && charset !== null) {
- mimeType.parameters.set("charset", charset);
+ if (
+ MapPrototypeHas(mimeType.parameters, "charset") === null &&
+ charset !== null
+ ) {
+ MapPrototypeSet(mimeType.parameters, "charset", charset);
}
}
}
@@ -218,7 +237,7 @@
}
const inner = newInnerResponse(status);
inner.type = "default";
- inner.headerList.push(["location", parsedURL.href]);
+ ArrayPrototypePush(inner.headerList, ["location", parsedURL.href]);
const response = webidl.createBranded(Response);
response[_response] = inner;
response[_headers] = headersFromHeaderList(
@@ -249,7 +268,7 @@
);
}
- if (!REASON_PHRASE_RE.test(init.statusText)) {
+ if (!RegExpPrototypeTest(REASON_PHRASE_RE, init.statusText)) {
throw new TypeError("Status text is not valid.");
}
@@ -353,11 +372,11 @@
return second;
}
- get [Symbol.toStringTag]() {
+ get [SymbolToStringTag]() {
return "Response";
}
- [Symbol.for("Deno.customInspect")](inspect) {
+ [SymbolFor("Deno.customInspect")](inspect) {
const inner = {
body: this.body,
bodyUsed: this.bodyUsed,
diff --git a/extensions/fetch/26_fetch.js b/extensions/fetch/26_fetch.js
index a33187344..a0256b2bd 100644
--- a/extensions/fetch/26_fetch.js
+++ b/extensions/fetch/26_fetch.js
@@ -27,6 +27,19 @@
} = window.__bootstrap.fetch;
const abortSignal = window.__bootstrap.abortSignal;
const { DOMException } = window.__bootstrap.domException;
+ const {
+ ArrayPrototypePush,
+ ArrayPrototypeSplice,
+ ArrayPrototypeFilter,
+ ArrayPrototypeIncludes,
+ Promise,
+ PromisePrototypeThen,
+ PromisePrototypeCatch,
+ StringPrototypeToLowerCase,
+ TypedArrayPrototypeSubarray,
+ TypeError,
+ Uint8Array,
+ } = window.__bootstrap.primordials;
const REQUEST_BODY_HEADER_NAMES = [
"content-encoding",
@@ -104,7 +117,7 @@
);
if (read > 0) {
// We read some data. Enqueue it onto the stream.
- controller.enqueue(chunk.subarray(0, read));
+ controller.enqueue(TypedArrayPrototypeSubarray(chunk, 0, read));
} else {
// We have reached the end of the body, so we close the stream.
controller.close();
@@ -201,20 +214,26 @@
const reader = reqBody.getReader();
(async () => {
while (true) {
- const { value, done } = await reader.read().catch((err) => {
- if (terminator.aborted) return { done: true, value: undefined };
- throw err;
- });
+ const { value, done } = await PromisePrototypeCatch(
+ reader.read(),
+ (err) => {
+ if (terminator.aborted) return { done: true, value: undefined };
+ throw err;
+ },
+ );
if (done) break;
if (!(value instanceof Uint8Array)) {
await reader.cancel("value not a Uint8Array");
break;
}
try {
- await opFetchRequestWrite(requestBodyRid, value).catch((err) => {
- if (terminator.aborted) return;
- throw err;
- });
+ await PromisePrototypeCatch(
+ opFetchRequestWrite(requestBodyRid, value),
+ (err) => {
+ if (terminator.aborted) return;
+ throw err;
+ },
+ );
if (terminator.aborted) break;
} catch (err) {
await reader.cancel(err);
@@ -231,7 +250,7 @@
let resp;
try {
- resp = await opFetchSend(requestRid).catch((err) => {
+ resp = await PromisePrototypeCatch(opFetchSend(requestRid), (err) => {
if (terminator.aborted) return;
throw err;
});
@@ -300,7 +319,8 @@
* @returns {Promise<InnerResponse>}
*/
function httpRedirectFetch(request, response, terminator) {
- const locationHeaders = response.headerList.filter(
+ const locationHeaders = ArrayPrototypeFilter(
+ response.headerList,
(entry) => entry[0] === "location",
);
if (locationHeaders.length === 0) {
@@ -339,8 +359,13 @@
request.method = "GET";
request.body = null;
for (let i = 0; i < request.headerList.length; i++) {
- if (REQUEST_BODY_HEADER_NAMES.includes(request.headerList[i][0])) {
- request.headerList.splice(i, 1);
+ if (
+ ArrayPrototypeIncludes(
+ REQUEST_BODY_HEADER_NAMES,
+ request.headerList[i][0],
+ )
+ ) {
+ ArrayPrototypeSplice(request.headerList, i, 1);
i--;
}
}
@@ -349,7 +374,7 @@
const res = extractBody(request.body.source);
request.body = res.body;
}
- request.urlList.push(locationURL.href);
+ ArrayPrototypePush(request.urlList, locationURL.href);
return mainFetch(request, true, terminator);
}
@@ -393,35 +418,41 @@
requestObject.signal[abortSignal.add](onabort);
if (!requestObject.headers.has("accept")) {
- request.headerList.push(["accept", "*/*"]);
+ ArrayPrototypePush(request.headerList, ["accept", "*/*"]);
}
// 12.
- mainFetch(request, false, requestObject.signal).then((response) => {
- // 12.1.
- if (locallyAborted) return;
- // 12.2.
- if (response.aborted) {
- reject(request, responseObject);
- requestObject.signal[abortSignal.remove](onabort);
- return;
- }
- // 12.3.
- if (response.type === "error") {
- const err = new TypeError(
- "Fetch failed: " + (response.error ?? "unknown error"),
- );
+ PromisePrototypeCatch(
+ PromisePrototypeThen(
+ mainFetch(request, false, requestObject.signal),
+ (response) => {
+ // 12.1.
+ if (locallyAborted) return;
+ // 12.2.
+ if (response.aborted) {
+ reject(request, responseObject);
+ requestObject.signal[abortSignal.remove](onabort);
+ return;
+ }
+ // 12.3.
+ if (response.type === "error") {
+ const err = new TypeError(
+ "Fetch failed: " + (response.error ?? "unknown error"),
+ );
+ reject(err);
+ requestObject.signal[abortSignal.remove](onabort);
+ return;
+ }
+ responseObject = fromInnerResponse(response, "immutable");
+ resolve(responseObject);
+ requestObject.signal[abortSignal.remove](onabort);
+ },
+ ),
+ (err) => {
reject(err);
requestObject.signal[abortSignal.remove](onabort);
- return;
- }
- responseObject = fromInnerResponse(response, "immutable");
- resolve(responseObject);
- requestObject.signal[abortSignal.remove](onabort);
- }).catch((err) => {
- reject(err);
- requestObject.signal[abortSignal.remove](onabort);
- });
+ },
+ );
});
return p;
}
@@ -461,7 +492,8 @@
// https://github.com/WebAssembly/spec/issues/1138. The WPT tests
// expect the raw value of the Content-Type attribute lowercased.
if (
- res.headers.get("Content-Type")?.toLowerCase() !== "application/wasm"
+ StringPrototypeToLowerCase(res.headers.get("Content-Type")) !==
+ "application/wasm"
) {
throw new TypeError("Invalid WebAssembly content type.");
}