summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ext/fetch/23_response.js119
-rw-r--r--ext/web/00_infra.js34
-rw-r--r--ext/web/internal.d.ts1
m---------test_util/wpt0
-rw-r--r--tools/wpt/expectation.json4
5 files changed, 115 insertions, 43 deletions
diff --git a/ext/fetch/23_response.js b/ext/fetch/23_response.js
index f1f6fe1dd..8d87944b6 100644
--- a/ext/fetch/23_response.js
+++ b/ext/fetch/23_response.js
@@ -15,7 +15,8 @@
const { isProxy } = Deno.core;
const webidl = window.__bootstrap.webidl;
const consoleInternal = window.__bootstrap.console;
- const { HTTP_TAB_OR_SPACE, regexMatcher } = window.__bootstrap.infra;
+ const { HTTP_TAB_OR_SPACE, regexMatcher, serializeJSValueToJSONString } =
+ window.__bootstrap.infra;
const { extractBody, mixinBody } = window.__bootstrap.fetchBody;
const { getLocationHref } = window.__bootstrap.location;
const { extractMimeType } = window.__bootstrap.mimesniff;
@@ -157,6 +158,56 @@
return resp;
}
+ /**
+ * https://fetch.spec.whatwg.org#initialize-a-response
+ * @param {Response} response
+ * @param {ResponseInit} init
+ * @param {{ body: __bootstrap.fetchBody.InnerBody, contentType: string | null } | null} bodyWithType
+ */
+ function initializeAResponse(response, init, bodyWithType) {
+ // 1.
+ if ((init.status < 200 || init.status > 599) && init.status != 101) {
+ throw new RangeError(
+ `The status provided (${init.status}) is not equal to 101 and outside the range [200, 599].`,
+ );
+ }
+
+ // 2.
+ if (
+ init.statusText &&
+ !RegExpPrototypeTest(REASON_PHRASE_RE, init.statusText)
+ ) {
+ throw new TypeError("Status text is not valid.");
+ }
+
+ // 3.
+ response[_response].status = init.status;
+
+ // 4.
+ response[_response].statusMessage = init.statusText;
+
+ // 5.
+ /** @type {__bootstrap.headers.Headers} */
+ const headers = response[_headers];
+ if (init.headers) {
+ fillHeaders(headers, init.headers);
+ }
+
+ // 6.
+ if (bodyWithType !== null) {
+ if (nullBodyStatus(response[_response].status)) {
+ throw new TypeError(
+ "Response with null body status cannot have body",
+ );
+ }
+ const { body, contentType } = bodyWithType;
+ response[_response].body = body;
+ if (contentType !== null && !headers.has("content-type")) {
+ headers.append("Content-Type", contentType);
+ }
+ }
+ }
+
class Response {
get [_mimeType]() {
const values = getDecodeSplitHeader(
@@ -218,6 +269,32 @@
}
/**
+ * @param {any} data
+ * @param {ResponseInit} init
+ * @returns {Response}
+ */
+ static json(data, init = {}) {
+ const prefix = "Failed to call 'Response.json'";
+ data = webidl.converters.any(data);
+ init = webidl.converters["ResponseInit_fast"](init, {
+ prefix,
+ context: "Argument 2",
+ });
+
+ const str = serializeJSValueToJSONString(data);
+ const res = extractBody(str);
+ res.contentType = "application/json";
+ const response = webidl.createBranded(Response);
+ response[_response] = newInnerResponse();
+ response[_headers] = headersFromHeaderList(
+ response[_response].headerList,
+ "response",
+ );
+ initializeAResponse(response, init, res);
+ return response;
+ }
+
+ /**
* @param {BodyInit | null} body
* @param {ResponseInit} init
*/
@@ -232,40 +309,18 @@
context: "Argument 2",
});
- if ((init.status < 200 || init.status > 599) && init.status != 101) {
- throw new RangeError(
- `The status provided (${init.status}) is not equal to 101 and outside the range [200, 599].`,
- );
- }
-
- if (
- init.statusText &&
- !RegExpPrototypeTest(REASON_PHRASE_RE, init.statusText)
- ) {
- throw new TypeError("Status text is not valid.");
- }
+ this[_response] = newInnerResponse();
+ this[_headers] = headersFromHeaderList(
+ this[_response].headerList,
+ "response",
+ );
- this[webidl.brand] = webidl.brand;
- const response = newInnerResponse(init.status, init.statusText);
- /** @type {InnerResponse} */
- this[_response] = response;
- /** @type {Headers} */
- this[_headers] = headersFromHeaderList(response.headerList, "response");
- if (init.headers) {
- fillHeaders(this[_headers], init.headers);
- }
+ let bodyWithType = null;
if (body !== null) {
- if (nullBodyStatus(response.status)) {
- throw new TypeError(
- "Response with null body status cannot have body",
- );
- }
- const res = extractBody(body);
- response.body = res.body;
- if (res.contentType !== null && !this[_headers].has("content-type")) {
- this[_headers].append("Content-Type", res.contentType);
- }
+ bodyWithType = extractBody(body);
}
+ initializeAResponse(this, init, bodyWithType);
+ this[webidl.brand] = webidl.brand;
}
/**
diff --git a/ext/web/00_infra.js b/ext/web/00_infra.js
index f46316bfe..bf931f8c7 100644
--- a/ext/web/00_infra.js
+++ b/ext/web/00_infra.js
@@ -11,23 +11,24 @@
((window) => {
const core = Deno.core;
const {
- Error,
- RegExp,
+ ArrayPrototypeJoin,
ArrayPrototypeMap,
- StringPrototypeCharCodeAt,
+ Error,
+ JSONStringify,
NumberPrototypeToString,
- StringPrototypePadStart,
- TypeError,
- ArrayPrototypeJoin,
+ RegExp,
SafeArrayIterator,
+ String,
StringPrototypeCharAt,
+ StringPrototypeCharCodeAt,
StringPrototypeMatch,
- StringPrototypeSlice,
- String,
+ StringPrototypePadStart,
StringPrototypeReplace,
- StringPrototypeToUpperCase,
- StringPrototypeToLowerCase,
+ StringPrototypeSlice,
StringPrototypeSubstring,
+ StringPrototypeToLowerCase,
+ StringPrototypeToUpperCase,
+ TypeError,
} = window.__bootstrap.primordials;
const ASCII_DIGIT = ["\u0030-\u0039"];
@@ -294,6 +295,18 @@
}
}
+ /**
+ * @param {unknown} value
+ * @returns {string}
+ */
+ function serializeJSValueToJSONString(value) {
+ const result = JSONStringify(value);
+ if (result === undefined) {
+ throw new TypeError("Value is not JSON serializable.");
+ }
+ return result;
+ }
+
window.__bootstrap.infra = {
collectSequenceOfCodepoints,
ASCII_DIGIT,
@@ -320,5 +333,6 @@
forgivingBase64Decode,
AssertionError,
assert,
+ serializeJSValueToJSONString,
};
})(globalThis);
diff --git a/ext/web/internal.d.ts b/ext/web/internal.d.ts
index 8e580495b..04309a77e 100644
--- a/ext/web/internal.d.ts
+++ b/ext/web/internal.d.ts
@@ -45,6 +45,7 @@ declare namespace globalThis {
};
forgivingBase64Encode(data: Uint8Array): string;
forgivingBase64Decode(data: string): Uint8Array;
+ serializeJSValueToJSONString(value: unknown): string;
};
declare var domException: {
diff --git a/test_util/wpt b/test_util/wpt
-Subproject 114d0fd7e438e64905a5673550385dd690ccb76
+Subproject 1a8281d7aa0eed050c6d8c151a602ce43dd5540
diff --git a/tools/wpt/expectation.json b/tools/wpt/expectation.json
index a5859d0aa..e71a48e2f 100644
--- a/tools/wpt/expectation.json
+++ b/tools/wpt/expectation.json
@@ -3215,7 +3215,9 @@
"response-consume-stream.any.html": true,
"response-consume-stream.any.worker.html": true,
"response-init-contenttype.any.html": true,
- "response-init-contenttype.any.worker.html": true
+ "response-init-contenttype.any.worker.html": true,
+ "response-static-json.any.html": true,
+ "response-static-json.any.worker.html": true
},
"body": {
"formdata.any.html": [